[clang] [clang][ExtractAPI] Fix quirks in interaction with submodules (PR #105868)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 23 11:15:11 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Daniel Grumberg (daniel-grumberg)
<details>
<summary>Changes</summary>
Extension SGFs require the module system to be enabled in order to discover which module defines the extended external type.
This patch ensures the following:
- Associate symbols with their top level module name,
- Ensure we don't drop macro definitions that came from a submodule but that should be included in the SGF output.
---
Patch is 38.72 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/105868.diff
10 Files Affected:
- (modified) clang/include/clang/ExtractAPI/DeclarationFragments.h (+2-2)
- (modified) clang/include/clang/ExtractAPI/ExtractAPIVisitor.h (+1-1)
- (modified) clang/lib/ExtractAPI/DeclarationFragments.cpp (+1-3)
- (modified) clang/lib/ExtractAPI/ExtractAPIConsumer.cpp (+30-54)
- (modified) clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp (+2-2)
- (modified) clang/test/ExtractAPI/bool.c (+4-4)
- (modified) clang/test/ExtractAPI/emit-symbol-graph/multi_file.c (+4-207)
- (modified) clang/test/ExtractAPI/emit-symbol-graph/single_file.c (+1-104)
- (modified) clang/test/ExtractAPI/macros.c (+349-407)
- (added) clang/test/ExtractAPI/submodule-macro.m (+25)
``````````diff
diff --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h b/clang/include/clang/ExtractAPI/DeclarationFragments.h
index 535da90b98284b..4ac744459031eb 100644
--- a/clang/include/clang/ExtractAPI/DeclarationFragments.h
+++ b/clang/include/clang/ExtractAPI/DeclarationFragments.h
@@ -411,9 +411,9 @@ class DeclarationFragmentsBuilder {
/// Build DeclarationFragments for a macro.
///
/// \param Name name of the macro.
- /// \param MD the associated MacroDirective.
+ /// \param MI the associated MacroInfo.
static DeclarationFragments getFragmentsForMacro(StringRef Name,
- const MacroDirective *MD);
+ const MacroInfo *MI);
/// Build DeclarationFragments for a typedef \p TypedefNameDecl.
static DeclarationFragments
diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
index 67659f5a25037c..b09b8b44d9abaa 100644
--- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
+++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
@@ -213,7 +213,7 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor<Derived> {
StringRef getOwningModuleName(const Decl &D) {
if (auto *OwningModule = D.getImportedOwningModule())
- return OwningModule->Name;
+ return OwningModule->getTopLevelModule()->Name;
return {};
}
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 6b85c7db90349e..d77bb1d424f7cf 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -1327,14 +1327,12 @@ DeclarationFragmentsBuilder::getFragmentsForFunctionTemplateSpecialization(
DeclarationFragments
DeclarationFragmentsBuilder::getFragmentsForMacro(StringRef Name,
- const MacroDirective *MD) {
+ const MacroInfo *MI) {
DeclarationFragments Fragments;
Fragments.append("#define", DeclarationFragments::FragmentKind::Keyword)
.appendSpace();
Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier);
- auto *MI = MD->getMacroInfo();
-
if (MI->isFunctionLike()) {
Fragments.append("(", DeclarationFragments::FragmentKind::Text);
unsigned numParameters = MI->getNumParams();
diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
index d6335854cbf262..b23a62267651c8 100644
--- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
+++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
@@ -286,78 +286,54 @@ class MacroCallback : public PPCallbacks {
MacroCallback(const SourceManager &SM, APISet &API, Preprocessor &PP)
: SM(SM), API(API), PP(PP) {}
- void MacroDefined(const Token &MacroNameToken,
- const MacroDirective *MD) override {
- auto *MacroInfo = MD->getMacroInfo();
+ void EndOfMainFile() override {
+ for (const auto &M : PP.macros()) {
+ auto *II = M.getFirst();
+ auto MD = PP.getMacroDefinition(II);
+ auto *MI = MD.getMacroInfo();
- if (MacroInfo->isBuiltinMacro())
- return;
+ if (!MI)
+ continue;
- auto SourceLoc = MacroNameToken.getLocation();
- if (SM.isWrittenInBuiltinFile(SourceLoc) ||
- SM.isWrittenInCommandLineFile(SourceLoc))
- return;
+ // Ignore header guard macros
+ if (MI->isUsedForHeaderGuard())
+ continue;
- PendingMacros.emplace_back(MacroNameToken, MD);
- }
+ // Ignore builtin macros and ones defined via the command line.
+ if (MI->isBuiltinMacro())
+ continue;
- // If a macro gets undefined at some point during preprocessing of the inputs
- // it means that it isn't an exposed API and we should therefore not add a
- // macro definition for it.
- void MacroUndefined(const Token &MacroNameToken, const MacroDefinition &MD,
- const MacroDirective *Undef) override {
- // If this macro wasn't previously defined we don't need to do anything
- // here.
- if (!Undef)
- return;
-
- llvm::erase_if(PendingMacros, [&MD, this](const PendingMacro &PM) {
- return MD.getMacroInfo()->isIdenticalTo(*PM.MD->getMacroInfo(), PP,
- /*Syntactically*/ false);
- });
- }
+ auto DefLoc = MI->getDefinitionLoc();
- void EndOfMainFile() override {
- for (auto &PM : PendingMacros) {
- // `isUsedForHeaderGuard` is only set when the preprocessor leaves the
- // file so check for it here.
- if (PM.MD->getMacroInfo()->isUsedForHeaderGuard())
+ if (SM.isWrittenInBuiltinFile(DefLoc) || SM.isWrittenInCommandLineFile(DefLoc))
continue;
- if (!shouldMacroBeIncluded(PM))
+ auto AssociatedModuleMacros = MD.getModuleMacros();
+ StringRef OwningModuleName;
+ if (!AssociatedModuleMacros.empty())
+ OwningModuleName = AssociatedModuleMacros.back()->getOwningModule()->getTopLevelModuleName();
+
+ if (!shouldMacroBeIncluded(DefLoc, OwningModuleName))
continue;
- StringRef Name = PM.MacroNameToken.getIdentifierInfo()->getName();
- PresumedLoc Loc = SM.getPresumedLoc(PM.MacroNameToken.getLocation());
+ StringRef Name = II->getName();
+ PresumedLoc Loc = SM.getPresumedLoc(DefLoc);
SmallString<128> USR;
- index::generateUSRForMacro(Name, PM.MacroNameToken.getLocation(), SM,
- USR);
-
+ index::generateUSRForMacro(Name, DefLoc, SM, USR);
API.createRecord<extractapi::MacroDefinitionRecord>(
USR, Name, SymbolReference(), Loc,
- DeclarationFragmentsBuilder::getFragmentsForMacro(Name, PM.MD),
+ DeclarationFragmentsBuilder::getFragmentsForMacro(Name, MI),
DeclarationFragmentsBuilder::getSubHeadingForMacro(Name),
- SM.isInSystemHeader(PM.MacroNameToken.getLocation()));
- }
+ SM.isInSystemHeader(DefLoc));
- PendingMacros.clear();
+ }
}
-protected:
- struct PendingMacro {
- Token MacroNameToken;
- const MacroDirective *MD;
-
- PendingMacro(const Token &MacroNameToken, const MacroDirective *MD)
- : MacroNameToken(MacroNameToken), MD(MD) {}
- };
-
- virtual bool shouldMacroBeIncluded(const PendingMacro &PM) { return true; }
+ virtual bool shouldMacroBeIncluded(const SourceLocation &MacroLoc, StringRef ModuleName) { return true; }
const SourceManager &SM;
APISet &API;
Preprocessor &PP;
- llvm::SmallVector<PendingMacro> PendingMacros;
};
class APIMacroCallback : public MacroCallback {
@@ -366,9 +342,9 @@ class APIMacroCallback : public MacroCallback {
LocationFileChecker &LCF)
: MacroCallback(SM, API, PP), LCF(LCF) {}
- bool shouldMacroBeIncluded(const PendingMacro &PM) override {
+ bool shouldMacroBeIncluded(const SourceLocation &MacroLoc, StringRef ModuleName) override {
// Do not include macros from external files
- return LCF(PM.MacroNameToken.getLocation());
+ return LCF(MacroLoc) || API.ProductName == ModuleName;
}
private:
diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
index 1bce9c59b19791..54124ddbb2f58a 100644
--- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
+++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
@@ -928,8 +928,8 @@ bool SymbolGraphSerializer::traverseObjCCategoryRecord(
return true;
auto *CurrentModule = ModuleForCurrentSymbol;
- if (Record->isExtendingExternalModule())
- ModuleForCurrentSymbol = &ExtendedModules[Record->Interface.Source];
+ if (auto ModuleExtendedByRecord= Record->getExtendedExternalModule())
+ ModuleForCurrentSymbol = &ExtendedModules[*ModuleExtendedByRecord];
if (!walkUpFromObjCCategoryRecord(Record))
return false;
diff --git a/clang/test/ExtractAPI/bool.c b/clang/test/ExtractAPI/bool.c
index efab6dfeef03b2..7a4d34acb0d269 100644
--- a/clang/test/ExtractAPI/bool.c
+++ b/clang/test/ExtractAPI/bool.c
@@ -2,8 +2,8 @@
// RUN: split-file %s %t
// RUN: sed -e "s at INPUT_DIR@%{/t:regex_replacement}@g" \
// RUN: %t/reference.output.json.in >> %t/reference.output.json
-// RUN: %clang -extract-api --pretty-sgf -target arm64-apple-macosx \
-// RUN: %t/input.h -o %t/output.json
+// RUN: %clang_cc1 -extract-api --product-name=BoolTest --pretty-sgf -triple arm64-apple-macosx \
+// RUN: %t/input.h -o %t/output.json
// Generator version is not consistent across test runs, normalize it.
// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
@@ -15,7 +15,7 @@
bool Foo;
bool IsFoo(bool Bar);
-/// expected-no-diagnostics
+// expected-no-diagnostics
//--- reference.output.json.in
{
@@ -28,7 +28,7 @@ bool IsFoo(bool Bar);
"generator": "?"
},
"module": {
- "name": "",
+ "name": "BoolTest",
"platform": {
"architecture": "arm64",
"operatingSystem": {
diff --git a/clang/test/ExtractAPI/emit-symbol-graph/multi_file.c b/clang/test/ExtractAPI/emit-symbol-graph/multi_file.c
index e668f69bc7e05f..651e0df2cd93a0 100644
--- a/clang/test/ExtractAPI/emit-symbol-graph/multi_file.c
+++ b/clang/test/ExtractAPI/emit-symbol-graph/multi_file.c
@@ -27,9 +27,6 @@
#ifndef TEST_H
#define TEST_H
-#define testmarcro1 32
-#define testmacro2 42
-
int testfunc (int param1, int param2);
void testfunc2 ();
#endif /* TEST_H */
@@ -185,7 +182,7 @@ int main ()
"location": {
"position": {
"character": 4,
- "line": 6
+ "line": 3
},
"uri": "file://INPUT_DIR/test.h"
},
@@ -249,7 +246,7 @@ int main ()
"location": {
"position": {
"character": 5,
- "line": 7
+ "line": 4
},
"uri": "file://INPUT_DIR/test.h"
},
@@ -335,106 +332,6 @@ int main ()
"pathComponents": [
"main"
]
- },
- {
- "accessLevel": "public",
- "declarationFragments": [
- {
- "kind": "keyword",
- "spelling": "#define"
- },
- {
- "kind": "text",
- "spelling": " "
- },
- {
- "kind": "identifier",
- "spelling": "testmarcro1"
- }
- ],
- "identifier": {
- "interfaceLanguage": "c",
- "precise": "c:test.h at 39@macro at testmarcro1"
- },
- "kind": {
- "displayName": "Macro",
- "identifier": "c.macro"
- },
- "location": {
- "position": {
- "character": 8,
- "line": 3
- },
- "uri": "file://INPUT_DIR/test.h"
- },
- "names": {
- "navigator": [
- {
- "kind": "identifier",
- "spelling": "testmarcro1"
- }
- ],
- "subHeading": [
- {
- "kind": "identifier",
- "spelling": "testmarcro1"
- }
- ],
- "title": "testmarcro1"
- },
- "pathComponents": [
- "testmarcro1"
- ]
- },
- {
- "accessLevel": "public",
- "declarationFragments": [
- {
- "kind": "keyword",
- "spelling": "#define"
- },
- {
- "kind": "text",
- "spelling": " "
- },
- {
- "kind": "identifier",
- "spelling": "testmacro2"
- }
- ],
- "identifier": {
- "interfaceLanguage": "c",
- "precise": "c:test.h at 62@macro at testmacro2"
- },
- "kind": {
- "displayName": "Macro",
- "identifier": "c.macro"
- },
- "location": {
- "position": {
- "character": 8,
- "line": 4
- },
- "uri": "file://INPUT_DIR/test.h"
- },
- "names": {
- "navigator": [
- {
- "kind": "identifier",
- "spelling": "testmacro2"
- }
- ],
- "subHeading": [
- {
- "kind": "identifier",
- "spelling": "testmacro2"
- }
- ],
- "title": "testmacro2"
- },
- "pathComponents": [
- "testmacro2"
- ]
}
]
}
@@ -573,7 +470,7 @@ int main ()
"location": {
"position": {
"character": 4,
- "line": 6
+ "line": 3
},
"uri": "file://INPUT_DIR/test.h"
},
@@ -637,7 +534,7 @@ int main ()
"location": {
"position": {
"character": 5,
- "line": 7
+ "line": 4
},
"uri": "file://INPUT_DIR/test.h"
},
@@ -659,106 +556,6 @@ int main ()
"pathComponents": [
"testfunc2"
]
- },
- {
- "accessLevel": "public",
- "declarationFragments": [
- {
- "kind": "keyword",
- "spelling": "#define"
- },
- {
- "kind": "text",
- "spelling": " "
- },
- {
- "kind": "identifier",
- "spelling": "testmarcro1"
- }
- ],
- "identifier": {
- "interfaceLanguage": "c",
- "precise": "c:test.h at 39@macro at testmarcro1"
- },
- "kind": {
- "displayName": "Macro",
- "identifier": "c.macro"
- },
- "location": {
- "position": {
- "character": 8,
- "line": 3
- },
- "uri": "file://INPUT_DIR/test.h"
- },
- "names": {
- "navigator": [
- {
- "kind": "identifier",
- "spelling": "testmarcro1"
- }
- ],
- "subHeading": [
- {
- "kind": "identifier",
- "spelling": "testmarcro1"
- }
- ],
- "title": "testmarcro1"
- },
- "pathComponents": [
- "testmarcro1"
- ]
- },
- {
- "accessLevel": "public",
- "declarationFragments": [
- {
- "kind": "keyword",
- "spelling": "#define"
- },
- {
- "kind": "text",
- "spelling": " "
- },
- {
- "kind": "identifier",
- "spelling": "testmacro2"
- }
- ],
- "identifier": {
- "interfaceLanguage": "c",
- "precise": "c:test.h at 62@macro at testmacro2"
- },
- "kind": {
- "displayName": "Macro",
- "identifier": "c.macro"
- },
- "location": {
- "position": {
- "character": 8,
- "line": 4
- },
- "uri": "file://INPUT_DIR/test.h"
- },
- "names": {
- "navigator": [
- {
- "kind": "identifier",
- "spelling": "testmacro2"
- }
- ],
- "subHeading": [
- {
- "kind": "identifier",
- "spelling": "testmacro2"
- }
- ],
- "title": "testmacro2"
- },
- "pathComponents": [
- "testmacro2"
- ]
}
]
}
diff --git a/clang/test/ExtractAPI/emit-symbol-graph/single_file.c b/clang/test/ExtractAPI/emit-symbol-graph/single_file.c
index b00b5f5237c9a3..feb759f5947bc9 100644
--- a/clang/test/ExtractAPI/emit-symbol-graph/single_file.c
+++ b/clang/test/ExtractAPI/emit-symbol-graph/single_file.c
@@ -15,9 +15,6 @@
// CHECK-NOT: warning:
//--- main.c
-#define TESTMACRO1 2
-#define TESTMARCRO2 5
-
int main ()
{
return 0;
@@ -87,7 +84,7 @@ int main ()
"location": {
"position": {
"character": 4,
- "line": 3
+ "line": 0
},
"uri": "file://INPUT_DIR/main.c"
},
@@ -109,106 +106,6 @@ int main ()
"pathComponents": [
"main"
]
- },
- {
- "accessLevel": "public",
- "declarationFragments": [
- {
- "kind": "keyword",
- "spelling": "#define"
- },
- {
- "kind": "text",
- "spelling": " "
- },
- {
- "kind": "identifier",
- "spelling": "TESTMACRO1"
- }
- ],
- "identifier": {
- "interfaceLanguage": "c",
- "precise": "c:main.c at 8@macro at TESTMACRO1"
- },
- "kind": {
- "displayName": "Macro",
- "identifier": "c.macro"
- },
- "location": {
- "position": {
- "character": 8,
- "line": 0
- },
- "uri": "file://INPUT_DIR/main.c"
- },
- "names": {
- "navigator": [
- {
- "kind": "identifier",
- "spelling": "TESTMACRO1"
- }
- ],
- "subHeading": [
- {
- "kind": "identifier",
- "spelling": "TESTMACRO1"
- }
- ],
- "title": "TESTMACRO1"
- },
- "pathComponents": [
- "TESTMACRO1"
- ]
- },
- {
- "accessLevel": "public",
- "declarationFragments": [
- {
- "kind": "keyword",
- "spelling": "#define"
- },
- {
- "kind": "text",
- "spelling": " "
- },
- {
- "kind": "identifier",
- "spelling": "TESTMARCRO2"
- }
- ],
- "identifier": {
- "interfaceLanguage": "c",
- "precise": "c:main.c at 29@macro at TESTMARCRO2"
- },
- "kind": {
- "displayName": "Macro",
- "identifier": "c.macro"
- },
- "location": {
- "position": {
- "character": 8,
- "line": 1
- },
- "uri": "file://INPUT_DIR/main.c"
- },
- "names": {
- "navigator": [
- {
- "kind": "identifier",
- "spelling": "TESTMARCRO2"
- }
- ],
- "subHeading": [
- {
- "kind": "identifier",
- "spelling": "TESTMARCRO2"
- }
- ],
- "title": "TESTMARCRO2"
- },
- "pathComponents": [
- "TESTMARCRO2"
- ]
}
]
}
diff --git a/clang/test/ExtractAPI/macros.c b/clang/test/ExtractAPI/macros.c
index 10003fe6f6e40f..15eb5f6a7f66fe 100644
--- a/clang/test/ExtractAPI/macros.c
+++ b/clang/test/ExtractAPI/macros.c
@@ -1,416 +1,358 @@
// RUN: rm -rf %t
-// RUN: split-file %s %t
-// RUN: sed -e "s at INPUT_DIR@%{/t:regex_replacement}@g" \
-// RUN: %t/reference.output.json.in >> %t/reference.output.json
-// RUN: %clang -extract-api --pretty-sgf --product-name=Macros -target arm64-apple-macosx \
-// RUN: -x objective-c-header %t/input.h -o %t/output.json | FileCheck -allow-empty %s
+// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing --product-name=Macros -triple arm64-apple-macosx \
+// RUN: -isystem %S -x objective-c-header %s -o %t/output.symbols.json
-// Generator version is not consistent across test runs, normalize it.
-// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
-// RUN: %t/output.json >> %t/output-normalized.json
-// RUN: diff %t/reference.output.json %t/output-normalized.json
-
-// CHECK-NOT: error:
-// CHECK-NOT: warning:
-
-//--- input.h
+// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix HELLO
#define HELLO 1
+// HELLO-LABEL: "!testLabel": "c:@macro at HELLO"
+// HELLO: "accessLevel": "public",
+// HELLO-NEXT: "declarationFragments": [
+// HELLO-NEXT: {
+// HELLO-NEXT: "kind": "keyword",
+// HELLO-NEXT: "spelling": "#define"
+// HELLO-NEXT: },
+// HELLO-NEXT: {
+// HELLO-NEXT: "kind": "text",
+// HELLO-NEXT: "spelling": " "
+// HELLO-NEXT: },
+// HELLO-NEXT: {
+// HELLO-NEXT: "kind": "identifier",
+// HELLO-NEXT: "spelling": "HELLO"
+// HELLO-NEXT: }
+// HELLO-NEXT: ],
+// HELLO: "kind": {
+// HELLO-NEXT: "displayName": "Macro",
+// HELLO-NEXT: "identifier": "objective-c.macro"
+// HELLO-NEXT: },
+// HELLO-NEXT: "location": {
+// HELLO-NEXT: "position": {
+// HELLO-NEXT: "character": 8,
+// HELLO-NEXT: "line": [[# @LINE - 25]]
+// HELLO-NEXT: },
+// HELLO-NEXT: "uri": "file://{{.*}}/macros.c"
+// HELLO-NEXT: },
+// HELLO-NEXT: "names": {
+// HELLO-NEXT: "navigator": [
+// HELLO-NEXT: {
+// HELLO-NEXT: "kind": "identifier",
+// HELLO-NEXT: "spelling": "HELLO"
+// HELLO-NEXT: }
+// HELLO-NEXT: ],
+// HELLO-NEXT: "subHeading": [
+// HELLO-NEXT: {
+// HELLO-NEXT: "kind": "identifier",
+// HELLO-NEXT: "spelling": "HELLO"
+// HELLO-NEXT: }
+// HELLO-NEXT: ],
+// HELLO-NEXT: "title": "HELLO"
+// HELLO-NEXT: },
+// HELLO...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/105868
More information about the cfe-commits
mailing list