diff options
Diffstat (limited to 'clang/lib/Lex')
-rw-r--r-- | clang/lib/Lex/MacroInfo.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Lex/PPDirectives.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Lex/PPLexerChange.cpp | 63 | ||||
-rw-r--r-- | clang/lib/Lex/PPMacroExpansion.cpp | 73 | ||||
-rw-r--r-- | clang/lib/Lex/Preprocessor.cpp | 2 |
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()) |