diff options
-rw-r--r-- | clang/include/clang/Lex/MacroInfo.h | 67 | ||||
-rw-r--r-- | clang/include/clang/Lex/Preprocessor.h | 18 | ||||
-rw-r--r-- | clang/include/clang/Serialization/ASTReader.h | 2 | ||||
-rw-r--r-- | clang/lib/Lex/MacroInfo.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Lex/PPMacroExpansion.cpp | 40 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 64 |
6 files changed, 167 insertions, 31 deletions
diff --git a/clang/include/clang/Lex/MacroInfo.h b/clang/include/clang/Lex/MacroInfo.h index 253e6625866..0dde8f2fdff 100644 --- a/clang/include/clang/Lex/MacroInfo.h +++ b/clang/include/clang/Lex/MacroInfo.h @@ -17,6 +17,7 @@ #include "clang/Lex/Token.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Allocator.h" #include <cassert> @@ -577,6 +578,72 @@ MacroDirective::DefInfo::getPreviousDefinition() { return DefDirective->getPrevious()->getDefinition(); } +/// \brief Represents a macro directive exported by a module. +/// +/// There's an instance of this class for every macro #define or #undef that is +/// the final directive for a macro name within a module. These entities also +/// represent the macro override graph. +/// +/// These are stored in a FoldingSet in the preprocessor. +class ModuleMacro : public llvm::FoldingSetNode { + /// The name defined by the macro. + IdentifierInfo *II; + /// The body of the #define, or nullptr if this is a #undef. + MacroInfo *Macro; + /// The ID of the module that exports this macro. + unsigned OwningModuleID; + /// The number of module macros that override this one. + unsigned NumOverriddenBy; + /// The number of modules whose macros are directly overridden by this one. + unsigned NumOverrides; + //ModuleMacro *OverriddenMacros[NumOverrides]; + + friend class Preprocessor; + + ModuleMacro(unsigned OwningModuleID, IdentifierInfo *II, MacroInfo *Macro, + ArrayRef<ModuleMacro *> Overrides) + : II(II), Macro(Macro), OwningModuleID(OwningModuleID), + NumOverriddenBy(0), NumOverrides(Overrides.size()) { + std::copy(Overrides.begin(), Overrides.end(), + reinterpret_cast<ModuleMacro **>(this + 1)); + } + +public: + static ModuleMacro *create(Preprocessor &PP, unsigned OwningModuleID, + IdentifierInfo *II, MacroInfo *Macro, + ArrayRef<ModuleMacro *> Overrides); + + void Profile(llvm::FoldingSetNodeID &ID) const { + return Profile(ID, OwningModuleID, II); + } + static void Profile(llvm::FoldingSetNodeID &ID, unsigned OwningModuleID, + IdentifierInfo *II) { + ID.AddInteger(OwningModuleID); + ID.AddPointer(II); + } + + /// Get the ID of the module that exports this macro. + unsigned getOwningModuleID() const { return OwningModuleID; } + + /// Get definition for this exported #define, or nullptr if this + /// represents a #undef. + MacroInfo *getMacroInfo() const { return Macro; } + + /// Iterators over the overridden module IDs. + /// \{ + typedef ModuleMacro *const *overrides_iterator; + overrides_iterator overrides_begin() const { + return reinterpret_cast<overrides_iterator>(this + 1); + } + overrides_iterator overrides_end() const { + return overrides_begin() + NumOverrides; + } + llvm::iterator_range<overrides_iterator> overrides() const { + return llvm::make_range(overrides_begin(), overrides_end()); + } + /// \} +}; + } // end namespace clang #endif diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 326f519e914..496f2791b35 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -31,6 +31,7 @@ #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/TinyPtrVector.h" #include "llvm/Support/Allocator.h" #include <memory> #include <vector> @@ -368,7 +369,15 @@ class Preprocessor : public RefCountedBase<Preprocessor> { /// the reverse order (the latest one is in the head of the list). llvm::DenseMap<const IdentifierInfo*, MacroDirective*> Macros; friend class ASTReader; - + + /// The set of known macros exported from modules. + llvm::FoldingSet<ModuleMacro> ModuleMacros; + + /// The list of module macros, for each identifier, that are not overridden by + /// any other module macro. + llvm::DenseMap<const IdentifierInfo *, llvm::TinyPtrVector<ModuleMacro*>> + LeafModuleMacros; + /// \brief Macros that we want to warn because they are not used at the end /// of the translation unit. /// @@ -427,7 +436,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> { /// \c createPreprocessingRecord() prior to preprocessing. PreprocessingRecord *Record; -private: // Cached tokens state. + /// Cached tokens state. typedef SmallVector<Token, 1> CachedTokensTy; /// \brief Cached tokens are stored here when we do backtracking or @@ -646,6 +655,11 @@ public: /// \brief Set a MacroDirective that was loaded from a PCH file. void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD); + /// \brief Register an exported macro for a module and identifier. + ModuleMacro *addModuleMacro(unsigned ModuleID, IdentifierInfo *II, + MacroInfo *Macro, + ArrayRef<ModuleMacro *> Overrides, bool &IsNew); + /// \{ /// Iterators for the macro history table. Currently defined macros have /// IdentifierInfo::hasMacroDefinition() set and an empty diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 3c30717716c..330fc5b294d 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -1850,7 +1850,7 @@ public: void resolvePendingMacro(IdentifierInfo *II, const PendingMacroInfo &PMInfo); - void installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI, + void installImportedMacro(IdentifierInfo *II, ModuleMacroInfo &MMI, Module *Owner); typedef llvm::TinyPtrVector<DefMacroDirective *> AmbiguousMacros; diff --git a/clang/lib/Lex/MacroInfo.cpp b/clang/lib/Lex/MacroInfo.cpp index 5416886cc9f..046948397fd 100644 --- a/clang/lib/Lex/MacroInfo.cpp +++ b/clang/lib/Lex/MacroInfo.cpp @@ -234,3 +234,10 @@ void MacroDirective::dump() const { } Out << "\n"; } + +ModuleMacro *ModuleMacro::create(Preprocessor &PP, unsigned OwningModuleID, + IdentifierInfo *II, MacroInfo *Macro, + ArrayRef<ModuleMacro*> Overrides) { + return new (PP.getPreprocessorAllocator()) + ModuleMacro(OwningModuleID, II, Macro, Overrides); +} diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 3ceba05401a..4c6aa4e45ac 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -72,6 +72,46 @@ void Preprocessor::setLoadedMacroDirective(IdentifierInfo *II, II->setHasMacroDefinition(false); } +ModuleMacro *Preprocessor::addModuleMacro(unsigned ModuleID, IdentifierInfo *II, + MacroInfo *Macro, + ArrayRef<ModuleMacro *> Overrides, + bool &New) { + llvm::FoldingSetNodeID ID; + ModuleMacro::Profile(ID, ModuleID, II); + + void *InsertPos; + if (auto *MM = ModuleMacros.FindNodeOrInsertPos(ID, InsertPos)) { + New = false; + return MM; + } + + auto *MM = ModuleMacro::create(*this, ModuleID, II, Macro, Overrides); + ModuleMacros.InsertNode(MM, InsertPos); + + // Each overridden macro is now overridden by one more macro. + bool HidAny = false; + for (auto *O : Overrides) { + HidAny |= (O->NumOverriddenBy == 0); + ++O->NumOverriddenBy; + } + + // If we were the first overrider for any macro, it's no longer a leaf. + auto &LeafMacros = LeafModuleMacros[II]; + if (HidAny) { + LeafMacros.erase(std::remove_if(LeafMacros.begin(), LeafMacros.end(), + [](ModuleMacro *MM) { + return MM->NumOverriddenBy != 0; + }), + LeafMacros.end()); + } + + // The new macro is always a leaf macro. + LeafMacros.push_back(MM); + + New = true; + return MM; +} + /// RegisterBuiltinMacro - Register the specified identifier in the identifier /// table and mark it as a builtin macro to be expanded. static IdentifierInfo *RegisterBuiltinMacro(Preprocessor &PP, const char *Name){ diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 248e10d598b..0e45a2f6fa7 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1753,7 +1753,7 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II, SavedStreamPosition SavedPosition(Cursor); Cursor.JumpToBit(PMInfo.MacroDirectivesOffset); - llvm::SmallVector<ModuleMacroInfo *, 8> ModuleMacros; + llvm::SmallVector<ModuleMacroInfo, 8> ModuleMacros; // We expect to see a sequence of PP_MODULE_MACRO records listing exported // macros, followed by a PP_MACRO_DIRECTIVE_HISTORY record with the complete @@ -1774,19 +1774,9 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II, break; case PP_MODULE_MACRO: { - auto SubModID = getGlobalSubmoduleID(M, Record[0]); - auto MacID = getGlobalMacroID(M, Record[1]); - - // Check whether we've already loaded this module macro. - // FIXME: The MacrosLoaded check is wrong: multiple macro definitions can - // have the same MacroInfo (and the same MacID) due to #pragma pop_macro. - if (MacID ? (bool)MacrosLoaded[MacID - NUM_PREDEF_MACRO_IDS] - : !LoadedUndefs.insert(std::make_pair(II, SubModID)).second) - continue; - ModuleMacroInfo Info; - Info.SubModID = SubModID; - Info.MI = getMacro(MacID); + Info.SubModID = getGlobalSubmoduleID(M, Record[0]); + Info.MI = getMacro(getGlobalMacroID(M, Record[1])); Info.F = &M; if (Record.size() > 2) { @@ -1797,7 +1787,7 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II, llvm::makeArrayRef(Overrides, Overrides + Record.size() - 2); } - ModuleMacros.push_back(new (Context) ModuleMacroInfo(Info)); + ModuleMacros.push_back(Info); continue; } @@ -1812,15 +1802,33 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II, } // Module macros are listed in reverse dependency order. - std::reverse(ModuleMacros.begin(), ModuleMacros.end()); - for (auto *MMI : ModuleMacros) { - Module *Owner = getSubmodule(MMI->getSubmoduleID()); - if (Owner && Owner->NameVisibility == Module::Hidden) { - // Macros in the owning module are hidden. Just remember this macro to - // install if we make this module visible. - HiddenNamesMap[Owner].HiddenMacros.insert(std::make_pair(II, MMI)); - } else { - installImportedMacro(II, MMI, Owner); + { + std::reverse(ModuleMacros.begin(), ModuleMacros.end()); + llvm::SmallDenseMap<unsigned, ModuleMacro*> Macros; + llvm::SmallVector<ModuleMacro*, 8> Overrides; + for (auto &MMI : ModuleMacros) { + Overrides.clear(); + for (unsigned ModID : MMI.Overrides) { + auto *Macro = Macros.lookup(ModID); + assert(Macro && "missing definition for overridden macro"); + Overrides.push_back(Macros.lookup(ModID)); + } + + bool Inserted = false; + Macros[MMI.SubModID] = + PP.addModuleMacro(MMI.SubModID, II, MMI.MI, Overrides, Inserted); + if (!Inserted) + continue; + + Module *Owner = getSubmodule(MMI.getSubmoduleID()); + if (Owner->NameVisibility == Module::Hidden) { + // Macros in the owning module are hidden. Just remember this macro to + // install if we make this module visible. + HiddenNamesMap[Owner].HiddenMacros.insert( + std::make_pair(II, new ModuleMacroInfo(MMI))); + } else { + installImportedMacro(II, MMI, Owner); + } } } @@ -1976,7 +1984,7 @@ ASTReader::removeOverriddenMacros(IdentifierInfo *II, return nullptr; } -void ASTReader::installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI, +void ASTReader::installImportedMacro(IdentifierInfo *II, ModuleMacroInfo &MMI, Module *Owner) { assert(II && Owner); @@ -1986,16 +1994,16 @@ void ASTReader::installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI, // source location for the import, we don't have a location for the macro. // Use the location at which the containing module file was first imported // for now. - ImportLoc = MMI->F->DirectImportLoc; + ImportLoc = MMI.F->DirectImportLoc; assert(ImportLoc.isValid() && "no import location for a visible macro?"); } AmbiguousMacros *Prev = - removeOverriddenMacros(II, ImportLoc, MMI->getOverriddenSubmodules()); + removeOverriddenMacros(II, ImportLoc, MMI.getOverriddenSubmodules()); // Create a synthetic macro definition corresponding to the import (or null // if this was an undefinition of the macro). - MacroDirective *Imported = MMI->import(PP, ImportLoc); + MacroDirective *Imported = MMI.import(PP, ImportLoc); DefMacroDirective *MD = dyn_cast<DefMacroDirective>(Imported); // If there's no ambiguity, just install the macro. @@ -3463,7 +3471,7 @@ void ASTReader::makeNamesVisible(const HiddenNames &Names, Module *Owner, PP.appendMacroDirective(Macro.first, Macro.second->import(PP, SourceLocation())); else - installImportedMacro(Macro.first, Macro.second, Owner); + installImportedMacro(Macro.first, *Macro.second, Owner); } } |