diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-05-01 01:53:09 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-05-01 01:53:09 +0000 |
commit | e48ab7f6b5d4eb4f547c26234e52fbd4c22b7342 (patch) | |
tree | 4ee12096f086442728215f66c117e8fcdde99b96 /lib/Basic/Module.cpp | |
parent | 0700563a9e918970857397016c48a547cff517e6 (diff) |
[modules] Start moving the module visibility information off the Module itself.
It has no place there; it's not a property of the Module, and it makes
restoring the visibility set when we leave a submodule more difficult.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@236300 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Basic/Module.cpp')
-rw-r--r-- | lib/Basic/Module.cpp | 57 |
1 files changed, 50 insertions, 7 deletions
diff --git a/lib/Basic/Module.cpp b/lib/Basic/Module.cpp index 5fad1a9b22..97f0a035b0 100644 --- a/lib/Basic/Module.cpp +++ b/lib/Basic/Module.cpp @@ -25,14 +25,14 @@ using namespace clang; Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, - bool IsFramework, bool IsExplicit) + bool IsFramework, bool IsExplicit, unsigned VisibilityID) : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), Directory(), - Umbrella(), ASTFile(nullptr), IsMissingRequirement(false), - IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework), - IsExplicit(IsExplicit), IsSystem(false), IsExternC(false), - IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false), - InferExportWildcard(false), ConfigMacrosExhaustive(false), - NameVisibility(Hidden) { + Umbrella(), ASTFile(nullptr), VisibilityID(VisibilityID), + IsMissingRequirement(false), IsAvailable(true), IsFromModuleFile(false), + IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false), + IsExternC(false), IsInferred(false), InferSubmodules(false), + InferExplicitSubmodules(false), InferExportWildcard(false), + ConfigMacrosExhaustive(false), NameVisibility(Hidden) { if (Parent) { if (!Parent->isAvailable()) IsAvailable = false; @@ -475,4 +475,47 @@ void Module::dump() const { print(llvm::errs()); } +void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, + VisibleCallback Vis, ConflictCallback Cb) { + if (isVisible(M)) + return; + ++Generation; + + struct Visiting { + Module *M; + Visiting *ExportedBy; + }; + + std::function<void(Visiting)> VisitModule = [&](Visiting V) { + // Modules that aren't available cannot be made visible. + if (!V.M->isAvailable()) + return; + + // Nothing to do for a module that's already visible. + unsigned ID = V.M->getVisibilityID(); + if (ImportLocs.size() <= ID) + ImportLocs.resize(ID + 1); + else if (ImportLocs[ID].isValid()) + return; + + ImportLocs[ID] = Loc; + Vis(M); + + // Make any exported modules visible. + SmallVector<Module *, 16> Exports; + V.M->getExportedModules(Exports); + for (Module *E : Exports) + VisitModule({E, &V}); + + for (auto &C : V.M->Conflicts) { + if (isVisible(C.Other)) { + llvm::SmallVector<Module*, 8> Path; + for (Visiting *I = &V; I; I = I->ExportedBy) + Path.push_back(I->M); + Cb(Path, C.Other, C.Message); + } + } + }; + VisitModule({M, nullptr}); +} |