diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-05-21 01:20:10 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-05-21 01:20:10 +0000 |
commit | 04765ae01e936a3f2bc980ebd8fc7ea8a4760636 (patch) | |
tree | b5a150687a94b1b7cf20fbad6067172a2013e341 /clang/lib/Lex | |
parent | de0aff3e9109ac9444b4408aa7619204344f54ed (diff) | |
download | bcm5719-llvm-04765ae01e936a3f2bc980ebd8fc7ea8a4760636.tar.gz bcm5719-llvm-04765ae01e936a3f2bc980ebd8fc7ea8a4760636.zip |
[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.
llvm-svn: 237871
Diffstat (limited to 'clang/lib/Lex')
-rw-r--r-- | clang/lib/Lex/PPLexerChange.cpp | 98 | ||||
-rw-r--r-- | clang/lib/Lex/PPMacroExpansion.cpp | 24 | ||||
-rw-r--r-- | clang/lib/Lex/Preprocessor.cpp | 17 |
3 files changed, 76 insertions, 63 deletions
diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp index f1d0593c8e1..027daae4bed 100644 --- a/clang/lib/Lex/PPLexerChange.cpp +++ b/clang/lib/Lex/PPLexerChange.cpp @@ -610,39 +610,51 @@ 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(); - Info.Macros.swap(Macros); - // Save our visible modules set. This is guaranteed to clear the set. - if (getLangOpts().ModulesLocalVisibility) { - Info.VisibleModules = std::move(VisibleModules); - - // Resolve as much of the module definition as we can now, before we enter - // one if its headers. - // FIXME: Can we enable Complain here? - ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap(); - ModMap.resolveExports(M, /*Complain=*/false); - ModMap.resolveUses(M, /*Complain=*/false); - ModMap.resolveConflicts(M, /*Complain=*/false); - - // This module is visible to itself. - makeModuleVisible(M, ImportLoc); + if (!getLangOpts().ModulesLocalVisibility) { + // Just track that we entered this submodule. + BuildingSubmoduleStack.push_back( + BuildingSubmoduleInfo(M, ImportLoc, CurSubmoduleState)); + return; } - // 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[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, Macro.second.getOverriddenMacros()); - Macros.insert(std::make_pair(Macro.first, std::move(MS))); + // Resolve as much of the module definition as we can now, before we enter + // one of its headers. + // FIXME: Can we enable Complain here? + // FIXME: Can we do this when local visibility is disabled? + ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap(); + ModMap.resolveExports(M, /*Complain=*/false); + ModMap.resolveUses(M, /*Complain=*/false); + ModMap.resolveConflicts(M, /*Complain=*/false); + + // If this is the first time we've entered this module, set up its state. + auto R = Submodules.emplace(std::piecewise_construct, std::make_tuple(M), + std::make_tuple()); + auto &State = R.first->second; + bool FirstTime = R.second; + if (FirstTime) { + // Determine the set of starting macros for this submodule; take these + // from the "null" module (the predefines buffer). + auto &StartingMacros = NullSubmoduleState.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, Macro.second.getOverriddenMacros()); + State.Macros.insert(std::make_pair(Macro.first, std::move(MS))); + } } + + // Track that we entered this module. + BuildingSubmoduleStack.push_back( + BuildingSubmoduleInfo(M, ImportLoc, CurSubmoduleState)); + + // Switch to this submodule as the current submodule. + CurSubmoduleState = &State; + + // This module is visible to itself. + if (FirstTime) + makeModuleVisible(M, ImportLoc); } void Preprocessor::LeaveSubmodule() { @@ -652,15 +664,15 @@ void Preprocessor::LeaveSubmodule() { SourceLocation ImportLoc = Info.ImportLoc; // Create ModuleMacros for any macros defined in this submodule. - for (auto &Macro : Macros) { + for (auto &Macro : CurSubmoduleState->Macros) { auto *II = const_cast<IdentifierInfo*>(Macro.first); - 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; + MacroDirective *OldMD = nullptr; + if (getLangOpts().ModulesLocalVisibility) { + // FIXME: It'd be better to start at the state from when we most recently + // entered this submodule, but it doesn't really matter. + auto &PredefMacros = NullSubmoduleState.Macros; auto PredefMacroIt = PredefMacros.find(Macro.first); if (PredefMacroIt == PredefMacros.end()) OldMD = nullptr; @@ -708,23 +720,15 @@ void Preprocessor::LeaveSubmodule() { break; } } - - // Maintain a single macro directive chain if we're not tracking - // per-submodule macro visibility. - if (!getLangOpts().ModulesLocalVisibility) - OuterInfo.setLatest(Macro.second.getLatest()); } - // Put back the old macros. - std::swap(Info.Macros, Macros); - + // Put back the outer module's state, if we're tracking it. if (getLangOpts().ModulesLocalVisibility) - VisibleModules = std::move(Info.VisibleModules); + CurSubmoduleState = Info.OuterSubmoduleState; BuildingSubmoduleStack.pop_back(); // A nested #include makes the included submodule visible. - if (!BuildingSubmoduleStack.empty() || - !getLangOpts().ModulesLocalVisibility) + if (!BuildingSubmoduleStack.empty() || !getLangOpts().ModulesLocalVisibility) makeModuleVisible(LeavingMod, ImportLoc); } diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index aa4e8b67644..9046ad51c14 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -37,15 +37,16 @@ MacroDirective * Preprocessor::getLocalMacroDirectiveHistory(const IdentifierInfo *II) const { if (!II->hadMacroDefinition()) return nullptr; - auto Pos = Macros.find(II); - return Pos == Macros.end() ? nullptr : Pos->second.getLatest(); + auto Pos = CurSubmoduleState->Macros.find(II); + return Pos == CurSubmoduleState->Macros.end() ? nullptr + : 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."); - MacroState &StoredMD = Macros[II]; + MacroState &StoredMD = CurSubmoduleState->Macros[II]; auto *OldMD = StoredMD.getLatest(); MD->setPrevious(OldMD); StoredMD.setLatest(MD); @@ -62,7 +63,7 @@ void Preprocessor::appendMacroDirective(IdentifierInfo *II, MacroDirective *MD){ void Preprocessor::setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD) { assert(II && MD); - MacroState &StoredMD = Macros[II]; + MacroState &StoredMD = CurSubmoduleState->Macros[II]; assert(!StoredMD.getLatest() && "the macro history was modified before initializing it from a pch"); StoredMD = MD; @@ -124,9 +125,11 @@ ModuleMacro *Preprocessor::getModuleMacro(Module *Mod, IdentifierInfo *II) { void Preprocessor::updateModuleMacroInfo(const IdentifierInfo *II, ModuleMacroInfo &Info) { - assert(Info.ActiveModuleMacrosGeneration != VisibleModules.getGeneration() && + assert(Info.ActiveModuleMacrosGeneration != + CurSubmoduleState->VisibleModules.getGeneration() && "don't need to update this macro name info"); - Info.ActiveModuleMacrosGeneration = VisibleModules.getGeneration(); + Info.ActiveModuleMacrosGeneration = + CurSubmoduleState->VisibleModules.getGeneration(); auto Leaf = LeafModuleMacros.find(II); if (Leaf == LeafModuleMacros.end()) { @@ -146,7 +149,7 @@ void Preprocessor::updateModuleMacroInfo(const IdentifierInfo *II, Leaf->second.end()); while (!Worklist.empty()) { auto *MM = Worklist.pop_back_val(); - if (VisibleModules.isVisible(MM->getOwningModule())) { + if (CurSubmoduleState->VisibleModules.isVisible(MM->getOwningModule())) { // We only care about collecting definitions; undefinitions only act // to override other definitions. if (MM->getMacroInfo()) @@ -200,8 +203,8 @@ void Preprocessor::dumpMacroInfo(const IdentifierInfo *II) { if (LeafIt != LeafModuleMacros.end()) Leaf = LeafIt->second; const MacroState *State = nullptr; - auto Pos = Macros.find(II); - if (Pos != Macros.end()) + auto Pos = CurSubmoduleState->Macros.find(II); + if (Pos != CurSubmoduleState->Macros.end()) State = &Pos->second; llvm::errs() << "MacroState " << State << " " << II->getNameStart(); @@ -236,7 +239,8 @@ void Preprocessor::dumpMacroInfo(const IdentifierInfo *II) { if (Active.count(MM)) llvm::errs() << " active"; - else if (!VisibleModules.isVisible(MM->getOwningModule())) + else if (!CurSubmoduleState->VisibleModules.isVisible( + MM->getOwningModule())) llvm::errs() << " hidden"; else if (MM->getMacroInfo()) llvm::errs() << " overridden"; diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index 9e89497597e..7e33f1ccb48 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -73,7 +73,8 @@ Preprocessor::Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts, ModuleImportExpectsIdentifier(false), CodeCompletionReached(0), MainFileDir(nullptr), SkipMainFilePreamble(0, true), CurPPLexer(nullptr), CurDirLookup(nullptr), CurLexerKind(CLK_Lexer), CurSubmodule(nullptr), - Callbacks(nullptr), MacroArgCache(nullptr), Record(nullptr), + Callbacks(nullptr), CurSubmoduleState(&NullSubmoduleState), + MacroArgCache(nullptr), Record(nullptr), MIChainHead(nullptr), DeserialMIChainHead(nullptr) { OwnsHeaderSearch = OwnsHeaders; @@ -266,7 +267,9 @@ void Preprocessor::PrintStats() { llvm::errs() << "\n Macro Expanded Tokens: " << llvm::capacity_in_bytes(MacroExpandedTokens); llvm::errs() << "\n Predefines Buffer: " << Predefines.capacity(); - llvm::errs() << "\n Macros: " << llvm::capacity_in_bytes(Macros); + // FIXME: List information for all submodules. + llvm::errs() << "\n Macros: " + << llvm::capacity_in_bytes(CurSubmoduleState->Macros); llvm::errs() << "\n #pragma push_macro Info: " << llvm::capacity_in_bytes(PragmaPushMacroInfo); llvm::errs() << "\n Poison Reasons: " @@ -283,14 +286,16 @@ Preprocessor::macro_begin(bool IncludeExternalMacros) const { ExternalSource->ReadDefinedMacros(); } - return Macros.begin(); + return CurSubmoduleState->Macros.begin(); } size_t Preprocessor::getTotalMemory() const { return BP.getTotalMemory() + llvm::capacity_in_bytes(MacroExpandedTokens) + Predefines.capacity() /* Predefines buffer. */ - + llvm::capacity_in_bytes(Macros) + // FIXME: Include sizes from all submodules, and include MacroInfo sizes, + // and ModuleMacros. + + llvm::capacity_in_bytes(CurSubmoduleState->Macros) + llvm::capacity_in_bytes(PragmaPushMacroInfo) + llvm::capacity_in_bytes(PoisonReasons) + llvm::capacity_in_bytes(CommentHandlers); @@ -304,7 +309,7 @@ Preprocessor::macro_end(bool IncludeExternalMacros) const { ExternalSource->ReadDefinedMacros(); } - return Macros.end(); + return CurSubmoduleState->Macros.end(); } /// \brief Compares macro tokens with a specified token value sequence. @@ -781,7 +786,7 @@ void Preprocessor::LexAfterModuleImport(Token &Result) { } void Preprocessor::makeModuleVisible(Module *M, SourceLocation Loc) { - VisibleModules.setVisible( + CurSubmoduleState->VisibleModules.setVisible( M, Loc, [](Module *) {}, [&](ArrayRef<Module *> Path, Module *Conflict, StringRef Message) { // FIXME: Include the path in the diagnostic. |