summaryrefslogtreecommitdiffstats
path: root/include/clang/Lex/Preprocessor.h
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2015-05-21 01:20:10 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2015-05-21 01:20:10 +0000
commite450a51e6598edd1a633100622a988f1576e7b16 (patch)
tree0098a2678f65c6649cec9d6c8ee953724f011f3f /include/clang/Lex/Preprocessor.h
parent57a4230de122a5f7e70c06ee5d005c345851bfc0 (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.h48
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