diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Frontend/PrintPreprocessedOutput.cpp | 3 | ||||
-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 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCodeComplete.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 132 |
9 files changed, 155 insertions, 133 deletions
diff --git a/clang/lib/Frontend/PrintPreprocessedOutput.cpp b/clang/lib/Frontend/PrintPreprocessedOutput.cpp index 6507f8e4b66..a2737d5f370 100644 --- a/clang/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/clang/lib/Frontend/PrintPreprocessedOutput.cpp @@ -687,7 +687,8 @@ static void DoPrintMacros(Preprocessor &PP, raw_ostream *OS) { for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end(); I != E; ++I) { if (I->first->hasMacroDefinition()) - MacrosByID.push_back(id_macro_pair(I->first, I->second->getMacroInfo())); + MacrosByID.push_back( + id_macro_pair(I->first, I->second.getLatest()->getMacroInfo())); } llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), MacroIDCompare); 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()) diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index eeeb8511b21..eb029c18c33 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -3037,7 +3037,7 @@ static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results, MEnd = PP.macro_end(); M != MEnd; ++M) { if (IncludeUndefined || M->first->hasMacroDefinition()) { - if (MacroInfo *MI = M->second->getMacroInfo()) + if (MacroInfo *MI = M->second.getLatest()->getMacroInfo()) if (MI->isUsedForHeaderGuard()) continue; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 7d8ccbfdb7a..8b918326204 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1807,17 +1807,18 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II, for (auto &MMI : ModuleMacros) { Overrides.clear(); for (unsigned ModID : MMI.Overrides) { - auto *Macro = PP.getModuleMacro(ModID, II); + Module *Mod = getSubmodule(ModID); + auto *Macro = PP.getModuleMacro(Mod, II); assert(Macro && "missing definition for overridden macro"); Overrides.push_back(Macro); } bool Inserted = false; - PP.addModuleMacro(MMI.SubModID, II, MMI.MI, Overrides, Inserted); + Module *Owner = getSubmodule(MMI.getSubmoduleID()); + PP.addModuleMacro(Owner, 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. diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index bdeeae0a51c..59191f22e84 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -1993,69 +1993,6 @@ static bool shouldIgnoreMacro(MacroDirective *MD, bool IsModule, return false; } -static void addOverriddenSubmodules(ASTWriter &Writer, const Preprocessor &PP, - MacroDirective *MD, - SmallVectorImpl<uint64_t> &Result) { - assert(!isa<VisibilityMacroDirective>(MD) && - "only #define and #undef can override"); - - if (MD->isImported()) { - auto ModIDs = MD->getOverriddenModules(); - Result.insert(Result.end(), ModIDs.begin(), ModIDs.end()); - return; - } - - unsigned Start = Result.size(); - - SubmoduleID ModID = Writer.inferSubmoduleIDFromLocation(MD->getLocation()); - for (MD = MD->getPrevious(); MD; MD = MD->getPrevious()) { - if (shouldIgnoreMacro(MD, /*IsModule*/true, PP)) - break; - - // If this is a definition from a submodule import, that submodule's - // definition is overridden by the definition or undefinition that we - // started with. - if (MD->isImported()) { - if (auto *DefMD = dyn_cast<DefMacroDirective>(MD)) { - SubmoduleID DefModuleID = DefMD->getInfo()->getOwningModuleID(); - assert(DefModuleID && "imported macro has no owning module"); - Result.push_back(DefModuleID); - } else if (auto *UndefMD = dyn_cast<UndefMacroDirective>(MD)) { - // If we override a #undef, we override anything that #undef overrides. - // We don't need to override it, since an active #undef doesn't affect - // the meaning of a macro. - // FIXME: Overriding the #undef directly might be simpler. - auto Overrides = UndefMD->getOverriddenModules(); - Result.insert(Result.end(), Overrides.begin(), Overrides.end()); - } - } - - // 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. - SubmoduleID DirectiveModuleID = - Writer.inferSubmoduleIDFromLocation(MD->getLocation()); - if (DirectiveModuleID != ModID) { - if (DirectiveModuleID && !MD->isImported()) - Result.push_back(DirectiveModuleID); - break; - } - } - - // Weed out any duplicate overrides. - std::sort(Result.begin() + Start, Result.end()); - Result.erase(std::unique(Result.begin() + Start, Result.end()), Result.end()); -} - /// \brief Writes the block containing the serialized form of the /// preprocessor. /// @@ -2093,7 +2030,7 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { I = PP.macro_begin(/*IncludeExternalMacros=*/false), E = PP.macro_end(/*IncludeExternalMacros=*/false); I != E; ++I) { - MacroDirectives.push_back(std::make_pair(I->first, I->second)); + MacroDirectives.push_back(std::make_pair(I->first, I->second.getLatest())); } // Sort the set of macro definitions that need to be serialized by the @@ -2117,18 +2054,6 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { Name->isFromAST() && !Name->hasChangedSinceDeserialization()) continue; - // State of this macro within each submodule. - enum class SubmoduleMacroState { - /// We've seen nothing about this macro. - None, - /// We've seen a public visibility directive. - Public, - /// We've either exported a macro for this module or found that the - /// module's definition of this macro is private. - Done - }; - llvm::DenseMap<SubmoduleID, SubmoduleMacroState> State; - auto StartOffset = Stream.GetCurrentBitNo(); // Emit the macro directives in reverse source order. @@ -2157,39 +2082,30 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { Record.push_back(Overrides.size()); Record.append(Overrides.begin(), Overrides.end()); } + } - // If this is the final definition in some module, and it's not - // module-private, add a module macro record for it. - if (IsModule) { - SubmoduleID ModID = - MD->isImported() ? MD->getOwningModuleID() - : inferSubmoduleIDFromLocation(MD->getLocation()); - assert(ModID && "found macro in no submodule"); - - auto &S = State[ModID]; - if (S == SubmoduleMacroState::Done) { - // We've already handled the final macro from this submodule, or seen - // a private visibility directive. - } else 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 (S == SubmoduleMacroState::None) - S = VisMD->isPublic() ? SubmoduleMacroState::Public - : SubmoduleMacroState::Done; - } else { - S = SubmoduleMacroState::Done; - - // Emit a record indicating this submodule exports this macro. - ModuleMacroRecord.push_back(ModID); - if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) - ModuleMacroRecord.push_back(getMacroID(DefMD->getInfo())); - else - ModuleMacroRecord.push_back(0); - addOverriddenSubmodules(*this, PP, MD, ModuleMacroRecord); - - Stream.EmitRecord(PP_MODULE_MACRO, ModuleMacroRecord); - ModuleMacroRecord.clear(); - } + // Write out any exported module macros. + if (IsModule) { + auto Leafs = PP.getLeafModuleMacros(Name); + SmallVector<ModuleMacro*, 8> Worklist(Leafs.begin(), Leafs.end()); + llvm::DenseMap<ModuleMacro*, unsigned> Visits; + while (!Worklist.empty()) { + auto *Macro = Worklist.pop_back_val(); + + // Emit a record indicating this submodule exports this macro. + ModuleMacroRecord.push_back( + getSubmoduleID(Macro->getOwningModule())); + ModuleMacroRecord.push_back(getMacroID(Macro->getMacroInfo())); + for (auto *M : Macro->overrides()) + ModuleMacroRecord.push_back(getSubmoduleID(M->getOwningModule())); + + Stream.EmitRecord(PP_MODULE_MACRO, ModuleMacroRecord); + ModuleMacroRecord.clear(); + + // Enqueue overridden macros once we've visited all their ancestors. + for (auto *M : Macro->overrides()) + if (++Visits[M] == M->getNumOverridingMacros()) + Worklist.push_back(M); } } |