-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang][ExtractAPI] Generate subheading for typedef'd anonymous types #110689
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang Author: Daniel Grumberg (daniel-grumberg) ChangesWhen an anonymous type has a typedef we normally use the typedef's name in places where we expect a named identifier in the symbol graph. This extends this logic to apply to subheadings. rdar://136690614 Full diff: https://github.com/llvm/llvm-project/pull/110689.diff 2 Files Affected:
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 9cb45c8fbf9cbc..f2d4c905664560 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -1621,6 +1621,9 @@ DeclarationFragmentsBuilder::getSubHeading(const NamedDecl *Decl) {
cast<CXXMethodDecl>(Decl)->isOverloadedOperator()) {
Fragments.append(Decl->getNameAsString(),
DeclarationFragments::FragmentKind::Identifier);
+ } else if (dyn_cast<TagDecl>(Decl) &&
+ cast<TagDecl>(Decl)->getTypedefNameForAnonDecl()) {
+ return getSubHeading(cast<TagDecl>(Decl)->getTypedefNameForAnonDecl());
} else if (Decl->getIdentifier()) {
Fragments.append(Decl->getName(),
DeclarationFragments::FragmentKind::Identifier);
diff --git a/clang/test/ExtractAPI/typedef_anonymous_record.c b/clang/test/ExtractAPI/typedef_anonymous_record.c
index 9c03e9e190ed6b..8e298f8d9ce829 100644
--- a/clang/test/ExtractAPI/typedef_anonymous_record.c
+++ b/clang/test/ExtractAPI/typedef_anonymous_record.c
@@ -35,7 +35,21 @@ typedef struct { } MyStruct;
// MYSTRUCT: "kind": {
// MYSTRUCT-NEXT: "displayName": "Structure",
// MYSTRUCT-NEXT: "identifier": "c.struct"
-// MYSTRUCT: "title": "MyStruct"
+// MYSTRUCT: "names": {
+// MYSTRUCT-NEXT: "navigator": [
+// MYSTRUCT-NEXT: {
+// MYSTRUCT-NEXT: "kind": "identifier",
+// MYSTRUCT-NEXT: "spelling": "MyStruct"
+// MYSTRUCT-NEXT: }
+// MYSTRUCT-NEXT: ],
+// MYSTRUCT-NEXT: "subHeading": [
+// MYSTRUCT-NEXT: {
+// MYSTRUCT-NEXT: "kind": "identifier",
+// MYSTRUCT-NEXT: "spelling": "MyStruct"
+// MYSTRUCT-NEXT: }
+// MYSTRUCT-NEXT: ],
+// MYSTRUCT-NEXT: "title": "MyStruct"
+// MYSTRUCT-NEXT: },
// MYSTRUCT: "pathComponents": [
// MYSTRUCT-NEXT: "MyStruct"
// MYSTRUCT-NEXT: ]
@@ -111,7 +125,21 @@ typedef enum { Case } MyEnum;
// MYENUM: "kind": {
// MYENUM-NEXT: "displayName": "Enumeration",
// MYENUM-NEXT: "identifier": "c.enum"
-// MYENUM: "title": "MyEnum"
+// MYENUM: "names": {
+// MYENUM-NEXT: "navigator": [
+// MYENUM-NEXT: {
+// MYENUM-NEXT: "kind": "identifier",
+// MYENUM-NEXT: "spelling": "MyEnum"
+// MYENUM-NEXT: }
+// MYENUM-NEXT: ],
+// MYENUM-NEXT: "subHeading": [
+// MYENUM-NEXT: {
+// MYENUM-NEXT: "kind": "identifier",
+// MYENUM-NEXT: "spelling": "MyEnum"
+// MYENUM-NEXT: }
+// MYENUM-NEXT: ],
+// MYENUM-NEXT: "title": "MyEnum"
+// MYENUM-NEXT: },
// CASE-LABEL: "!testLabel": "c:@EA@MyEnum@Case"
// CASE: "pathComponents": [
|
@@ -1621,6 +1621,9 @@ DeclarationFragmentsBuilder::getSubHeading(const NamedDecl *Decl) { | |||
cast<CXXMethodDecl>(Decl)->isOverloadedOperator()) { | |||
Fragments.append(Decl->getNameAsString(), | |||
DeclarationFragments::FragmentKind::Identifier); | |||
} else if (dyn_cast<TagDecl>(Decl) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this use isa<TagDecl>
instead? The extraneous pointer cast is probably not a big deal in the broad scheme, but using dyn_cast
as a boolean check just feels weird to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
absolutely
When an anonymous type has a typedef we normally use the typedef's name in places where we expect a named identifier in the symbol graph. This extends this logic to apply to subheadings. rdar://136690614
03b7908
to
30e06be
Compare
…llvm#110689) When an anonymous type has a typedef we normally use the typedef's name in places where we expect a named identifier in the symbol graph. This extends this logic to apply to subheadings. rdar://136690614
…llvm#110689) (#9368) When an anonymous type has a typedef we normally use the typedef's name in places where we expect a named identifier in the symbol graph. This extends this logic to apply to subheadings. rdar://136690614
…llvm#110689) When an anonymous type has a typedef we normally use the typedef's name in places where we expect a named identifier in the symbol graph. This extends this logic to apply to subheadings. rdar://136690614
When an anonymous type has a typedef we normally use the typedef's name in places where we expect a named identifier in the symbol graph. This extends this logic to apply to subheadings.
rdar://136690614