diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Lex/PPLexerChange.cpp | 69 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 45 |
3 files changed, 71 insertions, 45 deletions
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index a91e31e36c1..79f80d0df74 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1508,6 +1508,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.ModulesStrictDeclUse = Args.hasArg(OPT_fmodules_strict_decluse); Opts.ModulesDeclUse = Args.hasArg(OPT_fmodules_decluse) || Opts.ModulesStrictDeclUse; + Opts.ModulesLocalVisibility = + Args.hasArg(OPT_fmodules_local_submodule_visibility); Opts.ModulesSearchAll = Opts.Modules && !Args.hasArg(OPT_fno_modules_search_all) && Args.hasArg(OPT_fmodules_search_all); diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp index 6766fdfcd07..c506aa7f6f0 100644 --- a/clang/lib/Lex/PPLexerChange.cpp +++ b/clang/lib/Lex/PPLexerChange.cpp @@ -612,16 +612,25 @@ void Preprocessor::HandleMicrosoftCommentPaste(Token &Tok) { void Preprocessor::EnterSubmodule(Module *M, SourceLocation ImportLoc) { // Save the current state for future imports. BuildingSubmoduleStack.push_back(BuildingSubmoduleInfo(M, ImportLoc)); - 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. - for (auto &M : Macros) { - BuildingSubmoduleInfo::SavedMacroInfo SMI; - SMI.Latest = M.second.getLatest(); - auto O = M.second.getOverriddenMacros(); - SMI.Overridden.insert(SMI.Overridden.end(), O.begin(), O.end()); - Info.Macros.insert(std::make_pair(M.first, SMI)); + Info.Macros.swap(Macros); + // Save our visible modules set. This is guaranteed to clear the set. + if (getLangOpts().ModulesLocalVisibility) + Info.VisibleModules = std::move(VisibleModules); + + // Determine the set of starting macros for this submodule. + // FIXME: If we re-enter a submodule, should we restore its MacroDirectives? + auto &StartingMacros = (getLangOpts().ModulesLocalVisibility && + BuildingSubmoduleStack.size() > 1) + ? BuildingSubmoduleStack[0].Macros + : Info.Macros; + + // Restore to the starting state. + // FIXME: Do this lazily, when each macro name is first referenced. + for (auto &Macro : StartingMacros) { + MacroState MS(Macro.second.getLatest()); + MS.setOverriddenMacros(*this, MS.getOverriddenMacros()); + Macros.insert(std::make_pair(Macro.first, std::move(MS))); } } @@ -631,19 +640,35 @@ void Preprocessor::LeaveSubmodule() { // Create ModuleMacros for any macros defined in this submodule. for (auto &Macro : Macros) { auto *II = const_cast<IdentifierInfo*>(Macro.first); - auto SavedInfo = Info.Macros.lookup(II); + auto &OuterInfo = Info.Macros[II]; + + // Find the starting point for the MacroDirective chain in this submodule. + auto *OldMD = OuterInfo.getLatest(); + if (getLangOpts().ModulesLocalVisibility && + BuildingSubmoduleStack.size() > 1) { + auto &PredefMacros = BuildingSubmoduleStack[0].Macros; + auto PredefMacroIt = PredefMacros.find(Macro.first); + if (PredefMacroIt == PredefMacros.end()) + OldMD = nullptr; + else + OldMD = PredefMacroIt->second.getLatest(); + } // 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 != SavedInfo.Latest; + for (auto *MD = Macro.second.getLatest(); MD != OldMD; MD = MD->getPrevious()) { assert(MD && "broken macro directive chain"); // Skip macros defined in other submodules we #included along the way. - Module *Mod = getModuleContainingLocation(MD->getLocation()); - if (Mod != Info.M) - continue; + // There's no point doing this if we're tracking local submodule + // visibiltiy, since there can be no such directives in our list. + if (!getLangOpts().ModulesLocalVisibility) { + Module *Mod = getModuleContainingLocation(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 @@ -667,11 +692,21 @@ void Preprocessor::LeaveSubmodule() { } } - // Restore the macro's overrides list. - Macro.second.setOverriddenMacros(SavedInfo.Overridden); + // Maintain a single macro directive chain if we're not tracking + // per-submodule macro visibility. + if (!getLangOpts().ModulesLocalVisibility) + OuterInfo.setLatest(Macro.second.getLatest()); } - makeModuleVisible(Info.M, Info.ImportLoc); + // Put back the old macros. + std::swap(Info.Macros, Macros); + + if (getLangOpts().ModulesLocalVisibility) + VisibleModules = std::move(Info.VisibleModules); + + // A nested #include makes the included submodule visible. + if (BuildingSubmoduleStack.size() > 1) + makeModuleVisible(Info.M, Info.ImportLoc); BuildingSubmoduleStack.pop_back(); } diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 8a3b9d5163f..7ea50e5003f 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -2019,37 +2019,23 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { // Loop over all the macro directives that are live at the end of the file, // emitting each to the PP section. - // Construct the list of macro directives that need to be serialized. - typedef std::pair<const IdentifierInfo *, MacroDirective *> MacroChain; - SmallVector<MacroChain, 2> MacroDirectives; - for (Preprocessor::macro_iterator - 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.getLatest())); - } - + // Construct the list of identifiers with macro directives that need to be + // serialized. + SmallVector<const IdentifierInfo *, 128> MacroIdentifiers; + for (auto &Id : PP.getIdentifierTable()) + if (Id.second->hadMacroDefinition() && + (!Id.second->isFromAST() || + Id.second->hasChangedSinceDeserialization())) + MacroIdentifiers.push_back(Id.second); // Sort the set of macro definitions that need to be serialized by the // name of the macro, to provide a stable ordering. - int (*Cmp)(const MacroChain*, const MacroChain*) = - [](const MacroChain *A, const MacroChain *B) -> int { - return A->first->getName().compare(B->first->getName()); - }; - llvm::array_pod_sort(MacroDirectives.begin(), MacroDirectives.end(), Cmp); + std::sort(MacroIdentifiers.begin(), MacroIdentifiers.end(), + llvm::less_ptr<IdentifierInfo>()); // Emit the macro directives as a list and associate the offset with the // identifier they belong to. - for (auto &Chain : MacroDirectives) { - const IdentifierInfo *Name = Chain.first; - MacroDirective *MD = Chain.second; - - // If the macro or identifier need no updates, don't write the macro history - // for this one. - // FIXME: Chain the macro history instead of re-writing it. - if (MD && MD->isFromPCH() && - Name->isFromAST() && !Name->hasChangedSinceDeserialization()) - continue; - + for (const IdentifierInfo *Name : MacroIdentifiers) { + MacroDirective *MD = PP.getLocalMacroDirectiveHistory(Name); auto StartOffset = Stream.GetCurrentBitNo(); // Emit the macro directives in reverse source order. @@ -2069,6 +2055,7 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { } // Write out any exported module macros. + bool EmittedModuleMacros = false; if (IsModule) { auto Leafs = PP.getLeafModuleMacros(Name); SmallVector<ModuleMacro*, 8> Worklist(Leafs.begin(), Leafs.end()); @@ -2079,7 +2066,7 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { // Emit a record indicating this submodule exports this macro. ModuleMacroRecord.push_back( getSubmoduleID(Macro->getOwningModule())); - ModuleMacroRecord.push_back(getMacroID(Macro->getMacroInfo())); + ModuleMacroRecord.push_back(getMacroRef(Macro->getMacroInfo(), Name)); for (auto *M : Macro->overrides()) ModuleMacroRecord.push_back(getSubmoduleID(M->getOwningModule())); @@ -2090,10 +2077,12 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { for (auto *M : Macro->overrides()) if (++Visits[M] == M->getNumOverridingMacros()) Worklist.push_back(M); + + EmittedModuleMacros = true; } } - if (Record.empty()) + if (Record.empty() && !EmittedModuleMacros) continue; IdentMacroDirectivesOffsetMap[Name] = StartOffset; |