[clang] fa649df - [clang][ExtractAPI] Flatten all enum cases from anonymous enums at top level (#93559)
via cfe-commits
cfe-commits at lists.llvm.org
Wed May 29 01:47:27 PDT 2024
Author: Daniel Grumberg
Date: 2024-05-29T09:47:23+01:00
New Revision: fa649df8e54c2aa8921a42ad8d10e1e45700e5d7
URL: https://github.com/llvm/llvm-project/commit/fa649df8e54c2aa8921a42ad8d10e1e45700e5d7
DIFF: https://github.com/llvm/llvm-project/commit/fa649df8e54c2aa8921a42ad8d10e1e45700e5d7.diff
LOG: [clang][ExtractAPI] Flatten all enum cases from anonymous enums at top level (#93559)
rdar://128863241
Added:
Modified:
clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
clang/test/ExtractAPI/anonymous_record_no_typedef.c
clang/test/ExtractAPI/enum.c
clang/tools/libclang/CXExtractAPI.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
index 8ccebe457ed53..76d7fd798bed3 100644
--- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
+++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
@@ -21,6 +21,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ParentMapContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Specifiers.h"
@@ -127,7 +128,7 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor<Derived> {
protected:
/// Collect API information for the enum constants and associate with the
/// parent enum.
- void recordEnumConstants(EnumRecord *EnumRecord,
+ void recordEnumConstants(SymbolReference Container,
const EnumDecl::enumerator_range Constants);
/// Collect API information for the Objective-C methods and associate with the
@@ -248,12 +249,8 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor<Derived> {
clang::index::generateUSRForDecl(Tag, TagUSR);
if (auto *Record = llvm::dyn_cast_if_present<TagRecord>(
API.findRecordForUSR(TagUSR))) {
- if (Record->IsEmbeddedInVarDeclarator) {
+ if (Record->IsEmbeddedInVarDeclarator)
NewRecordContext->stealRecordChain(*Record);
- auto *NewRecord = cast<APIRecord>(NewRecordContext);
- if (NewRecord->Comment.empty())
- NewRecord->Comment = Record->Comment;
- }
}
}
};
@@ -394,17 +391,6 @@ bool ExtractAPIVisitorBase<Derived>::VisitEnumDecl(const EnumDecl *Decl) {
if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
return true;
- SmallString<128> QualifiedNameBuffer;
- // Collect symbol information.
- StringRef Name = Decl->getName();
- if (Name.empty())
- Name = getTypedefName(Decl);
- if (Name.empty()) {
- llvm::raw_svector_ostream OS(QualifiedNameBuffer);
- Decl->printQualifiedName(OS);
- Name = QualifiedNameBuffer;
- }
-
SmallString<128> USR;
index::generateUSRForDecl(Decl, USR);
PresumedLoc Loc =
@@ -420,13 +406,29 @@ bool ExtractAPIVisitorBase<Derived>::VisitEnumDecl(const EnumDecl *Decl) {
DeclarationFragmentsBuilder::getFragmentsForEnum(Decl);
DeclarationFragments SubHeading =
DeclarationFragmentsBuilder::getSubHeading(Decl);
- auto *ER = API.createRecord<EnumRecord>(
- USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
- AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
- isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
+
+ // Collect symbol information.
+ SymbolReference ParentContainer;
+
+ if (Decl->hasNameForLinkage()) {
+ StringRef Name = Decl->getName();
+ if (Name.empty())
+ Name = getTypedefName(Decl);
+
+ auto *ER = API.createRecord<EnumRecord>(
+ USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
+ AvailabilityInfo::createFromDecl(Decl), Comment, Declaration,
+ SubHeading, isInSystemHeader(Decl), false);
+ ParentContainer = SymbolReference(ER);
+ } else {
+ // If this an anonymous enum then the parent scope of the constants is the
+ // top level namespace.
+ ParentContainer = {};
+ }
// Now collect information about the enumerators in this enum.
- getDerivedExtractAPIVisitor().recordEnumConstants(ER, Decl->enumerators());
+ getDerivedExtractAPIVisitor().recordEnumConstants(ParentContainer,
+ Decl->enumerators());
return true;
}
@@ -1197,7 +1199,7 @@ bool ExtractAPIVisitorBase<Derived>::VisitObjCCategoryDecl(
/// parent enum.
template <typename Derived>
void ExtractAPIVisitorBase<Derived>::recordEnumConstants(
- EnumRecord *EnumRecord, const EnumDecl::enumerator_range Constants) {
+ SymbolReference Container, const EnumDecl::enumerator_range Constants) {
for (const auto *Constant : Constants) {
// Collect symbol information.
StringRef Name = Constant->getName();
@@ -1218,9 +1220,8 @@ void ExtractAPIVisitorBase<Derived>::recordEnumConstants(
DeclarationFragmentsBuilder::getSubHeading(Constant);
API.createRecord<EnumConstantRecord>(
- USR, Name, createHierarchyInformationForDecl(*Constant), Loc,
- AvailabilityInfo::createFromDecl(Constant), Comment, Declaration,
- SubHeading, isInSystemHeader(Constant));
+ USR, Name, Container, Loc, AvailabilityInfo::createFromDecl(Constant),
+ Comment, Declaration, SubHeading, isInSystemHeader(Constant));
}
}
@@ -1469,7 +1470,17 @@ class ExtractAPIVisitor
bool shouldDeclBeIncluded(const Decl *D) const { return true; }
const RawComment *fetchRawCommentForDecl(const Decl *D) const {
- return this->Context.getRawCommentForDeclNoCache(D);
+ if (const auto *Comment = this->Context.getRawCommentForDeclNoCache(D))
+ return Comment;
+
+ if (const auto *Declarator = dyn_cast<DeclaratorDecl>(D)) {
+ const auto *TagTypeDecl = Declarator->getType()->getAsTagDecl();
+ if (TagTypeDecl && TagTypeDecl->isEmbeddedInDeclarator() &&
+ TagTypeDecl->isCompleteDefinition())
+ return this->Context.getRawCommentForDeclNoCache(TagTypeDecl);
+ }
+
+ return nullptr;
}
};
diff --git a/clang/test/ExtractAPI/anonymous_record_no_typedef.c b/clang/test/ExtractAPI/anonymous_record_no_typedef.c
index 71e460afb1283..789316ca8930b 100644
--- a/clang/test/ExtractAPI/anonymous_record_no_typedef.c
+++ b/clang/test/ExtractAPI/anonymous_record_no_typedef.c
@@ -84,21 +84,15 @@ struct Vehicle {
// TYPE: "text": "The type of vehicle."
// TYPE: "title": "type"
- // BICYCLE: "!testRelLabel": "memberOf $ c:@S at Vehicle@E at anonymous_record_no_typedef.c@{{[0-9]+}}@Bicycle $ c:@S at Vehicle@FI at type"
// BICYCLE-LABEL: "!testLabel": "c:@S at Vehicle@E at anonymous_record_no_typedef.c@{{[0-9]+}}@Bicycle"
// BICYCLE: "title": "Bicycle"
// BICYCLE: "pathComponents": [
- // BICYCLE-NEXT: "Vehicle",
- // BICYCLE-NEXT: "type",
// BICYCLE-NEXT: "Bicycle"
// BICYCLE-NEXT: ]
- // CAR: "!testRelLabel": "memberOf $ c:@S at Vehicle@E at anonymous_record_no_typedef.c@{{[0-9]+}}@Car $ c:@S at Vehicle@FI at type"
// CAR-LABEL: "!testLabel": "c:@S at Vehicle@E at anonymous_record_no_typedef.c@{{[0-9]+}}@Car"
// CAR: "title": "Car"
// CAR: "pathComponents": [
- // CAR-NEXT: "Vehicle",
- // CAR-NEXT: "type",
// CAR-NEXT: "Car"
// CAR-NEXT: ]
@@ -151,32 +145,22 @@ struct Vehicle {
// NAME-NEXT: ]
};
-// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix GLOBALENUM
+// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix GLOBALCASE
+// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix GLOBALOTHERCASE
enum {
GlobalCase,
GlobalOtherCase
};
-// GLOBALENUM-DAG: "!testRelLabel": "memberOf $ c:@Ea at GlobalCase@GlobalCase $ c:@Ea at GlobalCase"
-// GLOBALENUM-DAG: "!testRelLabel": "memberOf $ c:@Ea at GlobalCase@GlobalOtherCase $ c:@Ea at GlobalCase"
-// GLOBALENUM-LABEL: "!testLabel": "c:@Ea at GlobalCase"
-// GLOBALENUM: "declarationFragments": [
-// GLOBALENUM-NEXT: {
-// GLOBALENUM-NEXT: "kind": "keyword",
-// GLOBALENUM-NEXT: "spelling": "enum"
-// GLOBALENUM-NEXT: },
-// GLOBALENUM-NEXT: {
-// GLOBALENUM-NEXT: "kind": "text",
-// GLOBALENUM-NEXT: "spelling": " : "
-// GLOBALENUM-NEXT: },
-// GLOBALENUM-NEXT: {
-// GLOBALENUM-NEXT: "kind": "typeIdentifier",
-// GLOBALENUM-NEXT: "preciseIdentifier": "c:i",
-// GLOBALENUM-NEXT: "spelling": "unsigned int"
-// GLOBALENUM-NEXT: },
-// GLOBALENUM-NEXT: {
-// GLOBALENUM-NEXT: "kind": "text",
-// GLOBALENUM-NEXT: "spelling": " { ... };"
-// GLOBALENUM-NEXT: }
-// GLOBALENUM-NEXT: ]
+// GLOBALCASE-LABEL: "!testLabel": "c:@Ea at GlobalCase@GlobalCase"
+// GLOBALCASE: "title": "GlobalCase"
+// GLOBALCASE: "pathComponents": [
+// GLOBALCASE-NEXT: "GlobalCase"
+// GLOBALCASE-NEXT: ]
+
+// GLOBALOTHERCASE-LABEL: "!testLabel": "c:@Ea at GlobalCase@GlobalOtherCase"
+// GLOBALOTHERCASE: "title": "GlobalOtherCase"
+// GLOBALOTHERCASE: "pathComponents": [
+// GLOBALOTHERCASE-NEXT: "GlobalOtherCase"
+// GLOBALOTHERCASE-NEXT: ]
// expected-no-diagnostics
diff --git a/clang/test/ExtractAPI/enum.c b/clang/test/ExtractAPI/enum.c
index 67e003834a7d5..58170aa0e1d90 100644
--- a/clang/test/ExtractAPI/enum.c
+++ b/clang/test/ExtractAPI/enum.c
@@ -115,18 +115,6 @@ enum {
"source": "c:@E at Direction@West",
"target": "c:@E at Direction",
"targetFallback": "Direction"
- },
- {
- "kind": "memberOf",
- "source": "c:@Ea at Constant@Constant",
- "target": "c:@Ea at Constant",
- "targetFallback": "enum (unnamed)"
- },
- {
- "kind": "memberOf",
- "source": "c:@Ea at OtherConstant@OtherConstant",
- "target": "c:@Ea at OtherConstant",
- "targetFallback": "enum (unnamed)"
}
],
"symbols": [
@@ -677,55 +665,6 @@ enum {
"West"
]
},
- {
- "accessLevel": "public",
- "declarationFragments": [
- {
- "kind": "keyword",
- "spelling": "enum"
- },
- {
- "kind": "text",
- "spelling": " : "
- },
- {
- "kind": "typeIdentifier",
- "preciseIdentifier": "c:i",
- "spelling": "unsigned int"
- },
- {
- "kind": "text",
- "spelling": " { ... };"
- }
- ],
- "identifier": {
- "interfaceLanguage": "c",
- "precise": "c:@Ea at Constant"
- },
- "kind": {
- "displayName": "Enumeration",
- "identifier": "c.enum"
- },
- "location": {
- "position": {
- "character": 0,
- "line": 16
- },
- "uri": "file://INPUT_DIR/input.h"
- },
- "names": {
- "navigator": [
- {
- "kind": "identifier",
- "spelling": "enum (unnamed)"
- }
- ],
- "title": "enum (unnamed)"
- },
- "pathComponents": [
- "enum (unnamed)"
- ]
- },
{
"accessLevel": "public",
"declarationFragments": [
@@ -765,59 +704,9 @@ enum {
"title": "Constant"
},
"pathComponents": [
- "enum (unnamed)",
"Constant"
]
},
- {
- "accessLevel": "public",
- "declarationFragments": [
- {
- "kind": "keyword",
- "spelling": "enum"
- },
- {
- "kind": "text",
- "spelling": " : "
- },
- {
- "kind": "typeIdentifier",
- "preciseIdentifier": "c:i",
- "spelling": "unsigned int"
- },
- {
- "kind": "text",
- "spelling": " { ... };"
- }
- ],
- "identifier": {
- "interfaceLanguage": "c",
- "precise": "c:@Ea at OtherConstant"
- },
- "kind": {
- "displayName": "Enumeration",
- "identifier": "c.enum"
- },
- "location": {
- "position": {
- "character": 0,
- "line": 20
- },
- "uri": "file://INPUT_DIR/input.h"
- },
- "names": {
- "navigator": [
- {
- "kind": "identifier",
- "spelling": "enum (unnamed)"
- }
- ],
- "title": "enum (unnamed)"
- },
- "pathComponents": [
- "enum (unnamed)"
- ]
- },
{
"accessLevel": "public",
"declarationFragments": [
@@ -857,7 +746,6 @@ enum {
"title": "OtherConstant"
},
"pathComponents": [
- "enum (unnamed)",
"OtherConstant"
]
}
diff --git a/clang/tools/libclang/CXExtractAPI.cpp b/clang/tools/libclang/CXExtractAPI.cpp
index d74f3740406c5..c35558e66fcb9 100644
--- a/clang/tools/libclang/CXExtractAPI.cpp
+++ b/clang/tools/libclang/CXExtractAPI.cpp
@@ -45,6 +45,9 @@ struct LibClangExtractAPIVisitor
: ExtractAPIVisitor<LibClangExtractAPIVisitor>(Context, API) {}
const RawComment *fetchRawCommentForDecl(const Decl *D) const {
+ if (const auto *Comment = Base::fetchRawCommentForDecl(D))
+ return Comment;
+
return Context.getRawCommentForAnyRedecl(D);
}
More information about the cfe-commits
mailing list