[clang] 6ef978b - [clang][ExtractAPI] combine typedef records if the underlying type's name is underscored (#125964)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 7 12:23:16 PST 2025
Author: QuietMisdreavus
Date: 2025-02-07T13:23:10-07:00
New Revision: 6ef978b8c41a83378af3de1dceeea434715f80f4
URL: https://github.com/llvm/llvm-project/commit/6ef978b8c41a83378af3de1dceeea434715f80f4
DIFF: https://github.com/llvm/llvm-project/commit/6ef978b8c41a83378af3de1dceeea434715f80f4.diff
LOG: [clang][ExtractAPI] combine typedef records if the underlying type's name is underscored (#125964)
fixes rdar://137214218
When 'typedef struct' decls are encountered, the records are combined if
the underlying type is either anonymous or has the same name as the
typedef. Extend this behavior to also combine records when the
underlying type has an underscored name that is equivalent to the
typedef name when the leading underscores are removed.
Added:
clang/test/ExtractAPI/typedef_underscore.c
Modified:
clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
Removed:
################################################################################
diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
index aa86e4180671144..e60440e14a9fe40 100644
--- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
+++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
@@ -1146,11 +1146,29 @@ bool ExtractAPIVisitorBase<Derived>::VisitTypedefNameDecl(
StringRef Name = Decl->getName();
+ auto nameMatches = [&Name](TagDecl *TagDecl) {
+ StringRef TagName = TagDecl->getName();
+
+ if (TagName == Name)
+ return true;
+
+ // Also check whether the tag decl's name is the same as the typedef name
+ // with prefixed underscores
+ if (TagName.starts_with('_')) {
+ StringRef StrippedName = TagName.ltrim('_');
+
+ if (StrippedName == Name)
+ return true;
+ }
+
+ return false;
+ };
+
// If the underlying type was defined as part of the typedef modify it's
// fragments directly and pretend the typedef doesn't exist.
if (auto *TagDecl = Decl->getUnderlyingType()->getAsTagDecl()) {
if (TagDecl->isEmbeddedInDeclarator() && TagDecl->isCompleteDefinition() &&
- Decl->getName() == TagDecl->getName()) {
+ nameMatches(TagDecl)) {
SmallString<128> TagUSR;
index::generateUSRForDecl(TagDecl, TagUSR);
if (auto *Record = API.findRecordForUSR(TagUSR)) {
@@ -1164,6 +1182,11 @@ bool ExtractAPIVisitorBase<Derived>::VisitTypedefNameDecl(
.append(Name, DeclarationFragments::FragmentKind::Identifier)
.appendSemicolon();
+ // Replace the name and subheading in case it's underscored so we can
+ // use the non-underscored version
+ Record->Name = Name;
+ Record->SubHeading = DeclarationFragmentsBuilder::getSubHeading(Decl);
+
return true;
}
}
diff --git a/clang/test/ExtractAPI/typedef_underscore.c b/clang/test/ExtractAPI/typedef_underscore.c
new file mode 100644
index 000000000000000..a42046907b46de8
--- /dev/null
+++ b/clang/test/ExtractAPI/typedef_underscore.c
@@ -0,0 +1,69 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \
+// RUN: --product-name=TypedefChain -triple arm64-apple-macosx -x c-header %s -o %t/typedefchain-c.symbols.json -verify
+// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \
+// RUN: --product-name=TypedefChain -triple arm64-apple-macosx -x c++-header %s -o %t/typedefchain-cxx.symbols.json -verify
+
+// RUN: FileCheck %s --input-file %t/typedefchain-c.symbols.json --check-prefix MYSTRUCT
+// RUN: FileCheck %s --input-file %t/typedefchain-cxx.symbols.json --check-prefix MYSTRUCT
+typedef struct _MyStruct { } MyStruct;
+
+// MYSTRUCT-LABEL: "!testLabel": "c:@S at _MyStruct"
+// MYSTRUCT: "accessLevel": "public",
+// MYSTRUCT: "declarationFragments": [
+// MYSTRUCT-NEXT: {
+// MYSTRUCT-NEXT: "kind": "keyword",
+// MYSTRUCT-NEXT: "spelling": "typedef"
+// MYSTRUCT-NEXT: },
+// MYSTRUCT-NEXT: {
+// MYSTRUCT-NEXT: "kind": "text",
+// MYSTRUCT-NEXT: "spelling": " "
+// MYSTRUCT-NEXT: },
+// MYSTRUCT-NEXT: {
+// MYSTRUCT-NEXT: "kind": "keyword",
+// MYSTRUCT-NEXT: "spelling": "struct"
+// MYSTRUCT-NEXT: },
+// MYSTRUCT-NEXT: {
+// MYSTRUCT-NEXT: "kind": "text",
+// MYSTRUCT-NEXT: "spelling": " "
+// MYSTRUCT-NEXT: },
+// MYSTRUCT-NEXT: {
+// MYSTRUCT-NEXT: "kind": "identifier",
+// MYSTRUCT-NEXT: "spelling": "_MyStruct"
+// MYSTRUCT-NEXT: },
+// MYSTRUCT-NEXT: {
+// MYSTRUCT-NEXT: "kind": "text",
+// MYSTRUCT-NEXT: "spelling": " { ... } "
+// MYSTRUCT-NEXT: },
+// MYSTRUCT-NEXT: {
+// MYSTRUCT-NEXT: "kind": "identifier",
+// MYSTRUCT-NEXT: "spelling": "MyStruct"
+// MYSTRUCT-NEXT: },
+// MYSTRUCT-NEXT: {
+// MYSTRUCT-NEXT: "kind": "text",
+// MYSTRUCT-NEXT: "spelling": ";"
+// MYSTRUCT-NEXT: }
+// MYSTRUCT-NEXT: ],
+// MYSTRUCT: "kind": {
+// MYSTRUCT-NEXT: "displayName": "Structure",
+// MYSTRUCT-NEXT: "identifier": "c{{(\+\+)?}}.struct"
+// 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: ]
+
+// expected-no-diagnostics
More information about the cfe-commits
mailing list