diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-05-21 01:20:10 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-05-21 01:20:10 +0000 |
commit | e450a51e6598edd1a633100622a988f1576e7b16 (patch) | |
tree | 0098a2678f65c6649cec9d6c8ee953724f011f3f /include/clang/Lex/Preprocessor.h | |
parent | 57a4230de122a5f7e70c06ee5d005c345851bfc0 (diff) |
[modules] If we re-enter a submodule from within itself (when submodule
visibility is enabled) or leave and re-enter it, restore the macro and module
visibility state from last time we were in that submodule.
This allows mutually-#including header files to stand a chance at being
modularized with local visibility enabled.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@237871 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Lex/Preprocessor.h')
-rw-r--r-- | include/clang/Lex/Preprocessor.h | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 4562741658..ea15dbdf21 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -391,7 +391,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> { // FIXME: Find a spare bit on IdentifierInfo and store a // HasModuleMacros flag. if (!II->hasMacroDefinition() || !PP.getLangOpts().Modules || - !PP.VisibleModules.getGeneration()) + !PP.CurSubmoduleState->VisibleModules.getGeneration()) return nullptr; auto *Info = State.dyn_cast<ModuleMacroInfo*>(); @@ -401,7 +401,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> { State = Info; } - if (PP.VisibleModules.getGeneration() != + if (PP.CurSubmoduleState->VisibleModules.getGeneration() != Info->ActiveModuleMacrosGeneration) PP.updateModuleMacroInfo(II, *Info); return Info; @@ -483,33 +483,50 @@ class Preprocessor : public RefCountedBase<Preprocessor> { } }; - typedef llvm::DenseMap<const IdentifierInfo *, MacroState> MacroMap; - /// For each IdentifierInfo that was associated with a macro, we /// keep a mapping to the history of all macro definitions and #undefs in /// the reverse order (the latest one is in the head of the list). - MacroMap Macros; + /// + /// This mapping lives within the \p CurSubmoduleState. + typedef llvm::DenseMap<const IdentifierInfo *, MacroState> MacroMap; friend class ASTReader; + struct SubmoduleState; + /// \brief Information about a submodule that we're currently building. struct BuildingSubmoduleInfo { - BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc) - : M(M), ImportLoc(ImportLoc) {} + BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc, + SubmoduleState *OuterSubmoduleState) + : M(M), ImportLoc(ImportLoc), OuterSubmoduleState(OuterSubmoduleState) { + } /// The module that we are building. Module *M; /// The location at which the module was included. SourceLocation ImportLoc; - /// The macros that were visible before we entered the module. + /// The previous SubmoduleState. + SubmoduleState *OuterSubmoduleState; + }; + SmallVector<BuildingSubmoduleInfo, 8> BuildingSubmoduleStack; + + /// \brief Information about a submodule's preprocessor state. + struct SubmoduleState { + /// The macros for the submodule. MacroMap Macros; - /// The set of modules that was visible in the surrounding submodule. + /// The set of modules that are visible within the submodule. VisibleModuleSet VisibleModules; - // FIXME: CounterValue? // FIXME: PragmaPushMacroInfo? }; - SmallVector<BuildingSubmoduleInfo, 8> BuildingSubmoduleStack; + std::map<Module*, SubmoduleState> Submodules; + + /// The preprocessor state for preprocessing outside of any submodule. + SubmoduleState NullSubmoduleState; + + /// The current submodule state. Will be \p NullSubmoduleState if we're not + /// in a submodule. + SubmoduleState *CurSubmoduleState; /// The set of known macros exported from modules. llvm::FoldingSet<ModuleMacro> ModuleMacros; @@ -519,9 +536,6 @@ class Preprocessor : public RefCountedBase<Preprocessor> { llvm::DenseMap<const IdentifierInfo *, llvm::TinyPtrVector<ModuleMacro*>> LeafModuleMacros; - /// The current set of visible modules. - VisibleModuleSet VisibleModules; - /// \brief Macros that we want to warn because they are not used at the end /// of the translation unit. /// @@ -767,7 +781,7 @@ public: if (!II->hasMacroDefinition()) return MacroDefinition(); - MacroState &S = Macros[II]; + MacroState &S = CurSubmoduleState->Macros[II]; auto *MD = S.getLatest(); while (MD && isa<VisibilityMacroDirective>(MD)) MD = MD->getPrevious(); @@ -781,7 +795,7 @@ public: if (!II->hadMacroDefinition()) return MacroDefinition(); - MacroState &S = Macros[II]; + MacroState &S = CurSubmoduleState->Macros[II]; MacroDirective::DefInfo DI; if (auto *MD = S.getLatest()) DI = MD->findDirectiveAtLoc(Loc, getSourceManager()); @@ -1018,7 +1032,7 @@ public: void makeModuleVisible(Module *M, SourceLocation Loc); SourceLocation getModuleImportLoc(Module *M) const { - return VisibleModules.getImportLoc(M); + return CurSubmoduleState->VisibleModules.getImportLoc(M); } /// \brief Lex a string literal, which may be the concatenation of multiple |