[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.

llvm-svn: 236300
This commit is contained in:
Richard Smith
2015-05-01 01:53:09 +00:00
parent 65ace9daa3
commit a7e2cc684f
23 changed files with 175 additions and 96 deletions

View File

@@ -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});
}