summaryrefslogtreecommitdiffstats
path: root/clang/lib/Lex
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Lex')
-rw-r--r--clang/lib/Lex/MacroInfo.cpp4
-rw-r--r--clang/lib/Lex/PPDirectives.cpp2
-rw-r--r--clang/lib/Lex/PPLexerChange.cpp63
-rw-r--r--clang/lib/Lex/PPMacroExpansion.cpp73
-rw-r--r--clang/lib/Lex/Preprocessor.cpp2
5 files changed, 124 insertions, 20 deletions
diff --git a/clang/lib/Lex/MacroInfo.cpp b/clang/lib/Lex/MacroInfo.cpp
index 55e0049e5e5..d7f483192f1 100644
--- a/clang/lib/Lex/MacroInfo.cpp
+++ b/clang/lib/Lex/MacroInfo.cpp
@@ -235,11 +235,11 @@ void MacroDirective::dump() const {
Out << "\n";
}
-ModuleMacro *ModuleMacro::create(Preprocessor &PP, unsigned OwningModuleID,
+ModuleMacro *ModuleMacro::create(Preprocessor &PP, Module *OwningModule,
IdentifierInfo *II, MacroInfo *Macro,
ArrayRef<ModuleMacro *> Overrides) {
void *Mem = PP.getPreprocessorAllocator().Allocate(
sizeof(ModuleMacro) + sizeof(ModuleMacro *) * Overrides.size(),
llvm::alignOf<ModuleMacro>());
- return new (Mem) ModuleMacro(OwningModuleID, II, Macro, Overrides);
+ return new (Mem) ModuleMacro(OwningModule, II, Macro, Overrides);
}
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index a50c8a82935..c22b0592218 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -1787,6 +1787,8 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
assert(!CurSubmodule && "should not have marked this as a module yet");
CurSubmodule = BuildingModule.getModule();
+ EnterSubmodule(CurSubmodule);
+
EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_begin,
CurSubmodule);
}
diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp
index fb5e2b05808..33f5ff07f03 100644
--- a/clang/lib/Lex/PPLexerChange.cpp
+++ b/clang/lib/Lex/PPLexerChange.cpp
@@ -400,6 +400,9 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end);
Result.setAnnotationEndLoc(Result.getLocation());
Result.setAnnotationValue(CurSubmodule);
+
+ // We're done with this submodule.
+ LeaveSubmodule();
}
// We're done with the #included file.
@@ -605,3 +608,63 @@ void Preprocessor::HandleMicrosoftCommentPaste(Token &Tok) {
// preprocessor directive mode), so just return EOF as our token.
assert(!FoundLexer && "Lexer should return EOD before EOF in PP mode");
}
+
+void Preprocessor::EnterSubmodule(Module *M) {
+ // Save the current state for future imports.
+ BuildingSubmoduleStack.push_back(BuildingSubmoduleInfo(M));
+
+ auto &Info = BuildingSubmoduleStack.back();
+ // Copy across our macros and start the submodule with the current state.
+ // FIXME: We should start each submodule with just the predefined macros.
+ Info.Macros = Macros;
+}
+
+void Preprocessor::LeaveSubmodule() {
+ auto &Info = BuildingSubmoduleStack.back();
+
+ // Create ModuleMacros for any macros defined in this submodule.
+ for (auto &Macro : Macros) {
+ auto *II = const_cast<IdentifierInfo*>(Macro.first);
+ MacroState State = Info.Macros.lookup(II);
+
+ // This module may have exported a new macro. If so, create a ModuleMacro
+ // representing that fact.
+ bool ExplicitlyPublic = false;
+ for (auto *MD = Macro.second.getLatest(); MD != State.getLatest();
+ MD = MD->getPrevious()) {
+ // Skip macros defined in other submodules we #included along the way.
+ Module *Mod = getModuleForLocation(MD->getLocation());
+ if (Mod != Info.M)
+ continue;
+
+ if (auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {
+ // The latest visibility directive for a name in a submodule affects
+ // all the directives that come before it.
+ if (VisMD->isPublic())
+ ExplicitlyPublic = true;
+ else if (!ExplicitlyPublic)
+ // Private with no following public directive: not exported.
+ break;
+ } else {
+ MacroInfo *Def = nullptr;
+ if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD))
+ Def = DefMD->getInfo();
+
+ // FIXME: Issue a warning if multiple headers for the same submodule
+ // define a macro, rather than silently ignoring all but the first.
+ bool IsNew;
+ addModuleMacro(Info.M, II, Def, Macro.second.getOverriddenMacros(),
+ IsNew);
+ break;
+ }
+ }
+
+ // Update the macro to refer to the latest directive in the chain.
+ State.setLatest(Macro.second.getLatest());
+
+ // Restore the old macro state.
+ Macro.second = State;
+ }
+
+ BuildingSubmoduleStack.pop_back();
+}
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 6753bf3fff1..883f2d5ff3b 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -37,33 +37,73 @@ MacroDirective *
Preprocessor::getMacroDirectiveHistory(const IdentifierInfo *II) const {
assert(II->hadMacroDefinition() && "Identifier has not been not a macro!");
- macro_iterator Pos = Macros.find(II);
+ auto Pos = Macros.find(II);
assert(Pos != Macros.end() && "Identifier macro info is missing!");
- return Pos->second;
+ return Pos->second.getLatest();
}
void Preprocessor::appendMacroDirective(IdentifierInfo *II, MacroDirective *MD){
assert(MD && "MacroDirective should be non-zero!");
assert(!MD->getPrevious() && "Already attached to a MacroDirective history.");
- MacroDirective *&StoredMD = Macros[II];
- MD->setPrevious(StoredMD);
- StoredMD = MD;
- // Setup the identifier as having associated macro history.
+ MacroState &StoredMD = Macros[II];
+ auto *OldMD = StoredMD.getLatest();
+ MD->setPrevious(OldMD);
+ StoredMD.setLatest(MD);
+
+ // Set up the identifier as having associated macro history.
II->setHasMacroDefinition(true);
if (!MD->isDefined())
II->setHasMacroDefinition(false);
- bool isImportedMacro = isa<DefMacroDirective>(MD) &&
- cast<DefMacroDirective>(MD)->isImported();
- if (II->isFromAST() && !isImportedMacro)
+ if (II->isFromAST() && !MD->isImported())
II->setChangedSinceDeserialization();
+
+ // Accumulate any overridden imported macros.
+ if (!MD->isImported() && getCurrentModule()) {
+ Module *OwningMod = getModuleForLocation(MD->getLocation());
+ if (!OwningMod)
+ return;
+
+ for (auto *PrevMD = OldMD; PrevMD; PrevMD = PrevMD->getPrevious()) {
+ // FIXME: Store a ModuleMacro * on an imported directive.
+ Module *DirectiveMod = getModuleForLocation(PrevMD->getLocation());
+ Module *PrevOwningMod =
+ PrevMD->isImported()
+ ? getExternalSource()->getModule(PrevMD->getOwningModuleID())
+ : DirectiveMod;
+ auto *MM = getModuleMacro(PrevOwningMod, II);
+ if (!MM) {
+ // We're still within the module defining the previous macro. We don't
+ // override it.
+ assert(!PrevMD->isImported() &&
+ "imported macro with no corresponding ModuleMacro");
+ break;
+ }
+ StoredMD.addOverriddenMacro(*this, MM);
+
+ // Stop once we leave the original macro's submodule.
+ //
+ // Either this submodule #included another submodule of the same
+ // module or it just happened to be built after the other module.
+ // In the former case, we override the submodule's macro.
+ //
+ // FIXME: In the latter case, we shouldn't do so, but we can't tell
+ // these cases apart.
+ //
+ // FIXME: We can leave this submodule and re-enter it if it #includes a
+ // header within a different submodule of the same module. In such cases
+ // the overrides list will be incomplete.
+ if (DirectiveMod != OwningMod || !PrevMD->isImported())
+ break;
+ }
+ }
}
void Preprocessor::setLoadedMacroDirective(IdentifierInfo *II,
MacroDirective *MD) {
assert(II && MD);
- MacroDirective *&StoredMD = Macros[II];
- assert(!StoredMD &&
+ MacroState &StoredMD = Macros[II];
+ assert(!StoredMD.getLatest() &&
"the macro history was modified before initializing it from a pch");
StoredMD = MD;
// Setup the identifier as having associated macro history.
@@ -72,12 +112,12 @@ void Preprocessor::setLoadedMacroDirective(IdentifierInfo *II,
II->setHasMacroDefinition(false);
}
-ModuleMacro *Preprocessor::addModuleMacro(unsigned ModuleID, IdentifierInfo *II,
+ModuleMacro *Preprocessor::addModuleMacro(Module *Mod, IdentifierInfo *II,
MacroInfo *Macro,
ArrayRef<ModuleMacro *> Overrides,
bool &New) {
llvm::FoldingSetNodeID ID;
- ModuleMacro::Profile(ID, ModuleID, II);
+ ModuleMacro::Profile(ID, Mod, II);
void *InsertPos;
if (auto *MM = ModuleMacros.FindNodeOrInsertPos(ID, InsertPos)) {
@@ -85,7 +125,7 @@ ModuleMacro *Preprocessor::addModuleMacro(unsigned ModuleID, IdentifierInfo *II,
return MM;
}
- auto *MM = ModuleMacro::create(*this, ModuleID, II, Macro, Overrides);
+ auto *MM = ModuleMacro::create(*this, Mod, II, Macro, Overrides);
ModuleMacros.InsertNode(MM, InsertPos);
// Each overridden macro is now overridden by one more macro.
@@ -112,10 +152,9 @@ ModuleMacro *Preprocessor::addModuleMacro(unsigned ModuleID, IdentifierInfo *II,
return MM;
}
-ModuleMacro *Preprocessor::getModuleMacro(unsigned ModuleID,
- IdentifierInfo *II) {
+ModuleMacro *Preprocessor::getModuleMacro(Module *Mod, IdentifierInfo *II) {
llvm::FoldingSetNodeID ID;
- ModuleMacro::Profile(ID, ModuleID, II);
+ ModuleMacro::Profile(ID, Mod, II);
void *InsertPos;
return ModuleMacros.FindNodeOrInsertPos(ID, InsertPos);
diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp
index 51a038ac728..6f2e390fc03 100644
--- a/clang/lib/Lex/Preprocessor.cpp
+++ b/clang/lib/Lex/Preprocessor.cpp
@@ -322,7 +322,7 @@ StringRef Preprocessor::getLastMacroWithSpelling(
for (Preprocessor::macro_iterator I = macro_begin(), E = macro_end();
I != E; ++I) {
const MacroDirective::DefInfo
- Def = I->second->findDirectiveAtLoc(Loc, SourceMgr);
+ Def = I->second.findDirectiveAtLoc(Loc, SourceMgr);
if (!Def || !Def.getMacroInfo())
continue;
if (!Def.getMacroInfo()->isObjectLike())
OpenPOWER on IntegriCloud