diff options
author | Daniel Grumberg <dgrumberg@apple.com> | 2024-08-27 13:50:41 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-27 13:50:41 +0100 |
commit | b1b24d751776d5fd2218a5cb43a8d103bf59fa32 (patch) | |
tree | dfa423c9fa89ed70234ad103e9be191ee8800333 /clang/lib/ExtractAPI/ExtractAPIConsumer.cpp | |
parent | 4f33e7c683104ea72e013d4ddd104b711a25d620 (diff) | |
download | llvm-b1b24d751776d5fd2218a5cb43a8d103bf59fa32.zip llvm-b1b24d751776d5fd2218a5cb43a8d103bf59fa32.tar.gz llvm-b1b24d751776d5fd2218a5cb43a8d103bf59fa32.tar.bz2 |
[clang][ExtractAPI] Fix quirks in interaction with submodules (#105868)
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, and that only top level modules are considered as modules for emitting extension SGFs.
- Ensure we don't drop macro definitions that came from a submodule. To this end look at all defined macros in `PPCalbacks::EndOfMainFile` instead of relying on `PPCallbacks::MacroDefined` being called to detect a macro definition.
Diffstat (limited to 'clang/lib/ExtractAPI/ExtractAPIConsumer.cpp')
-rw-r--r-- | clang/lib/ExtractAPI/ExtractAPIConsumer.cpp | 90 |
1 files changed, 36 insertions, 54 deletions
diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp index d633585..0adc232 100644 --- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp +++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp @@ -286,78 +286,59 @@ public: 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 +347,10 @@ public: 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: |