aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-12-01 17:11:21 +0000
committerDouglas Gregor <dgregor@apple.com>2011-12-01 17:11:21 +0000
commit5e35693721364673f8196e4f5a370f56b92e6053 (patch)
tree7de6955b4b607db6fb559ced4e3c710c2318ef75 /lib
parentee5a21fda5efce750c21db5a1d635c9742f5859b (diff)
Introduce the notion of name visibility into modules. For a given
(sub)module, all of the names may be hidden, just the macro names may be exposed (for example, after the preprocessor has seen the import of the module but the parser has not), or all of the names may be exposed. Importing a module makes its names, and the names in any of its non-explicit submodules, visible to name lookup (transitively). This commit only introduces the notion of name visible and marks modules and submodules as visible when they are imported. The actual name-hiding logic in the AST reader will follow (along with test cases). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145586 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Frontend/CompilerInstance.cpp13
-rw-r--r--lib/Lex/PPDirectives.cpp6
-rw-r--r--lib/Lex/Preprocessor.cpp3
-rw-r--r--lib/Sema/SemaDecl.cpp3
-rw-r--r--lib/Serialization/ASTReader.cpp32
5 files changed, 50 insertions, 7 deletions
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index 743a447c32..746c00a361 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -1069,12 +1069,17 @@ static void compileModule(CompilerInstance &ImportingInstance,
}
Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
- ModuleIdPath Path) {
+ ModuleIdPath Path,
+ Module::NameVisibilityKind Visibility) {
// If we've already handled this import, just return the cached result.
// This one-element cache is important to eliminate redundant diagnostics
// when both the preprocessor and parser see the same import declaration.
- if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc)
+ if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc) {
+ // Make the named module visible.
+ if (LastModuleImportResult)
+ ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility);
return LastModuleImportResult;
+ }
// Determine what file we're searching from.
SourceManager &SourceMgr = getSourceManager();
@@ -1253,7 +1258,9 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
}
}
- // FIXME: Tell the AST reader to make the named submodule visible.
+ // Make the named module visible.
+ if (Module)
+ ModuleManager->makeModuleVisible(Module, Visibility);
LastModuleImportLoc = ImportLoc;
LastModuleImportResult = Module;
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 81cb526209..836d21b204 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -1360,8 +1360,10 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
"__import_module__ " + PathString.str().str() + ";");
// Load the module.
- // FIXME: Deal with __include_macros here.
- TheModuleLoader.loadModule(IncludeTok.getLocation(), Path);
+ // If this was an #__include_macros directive, only make macros visible.
+ Module::NameVisibilityKind Visibility
+ = (IncludeKind == 3)? Module::MacrosVisible : Module::AllVisible;
+ TheModuleLoader.loadModule(IncludeTok.getLocation(), Path, Visibility);
return;
}
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index b01113041e..180e1e2c25 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -593,7 +593,8 @@ void Preprocessor::LexAfterModuleImport(Token &Result) {
// If we have a non-empty module path, load the named module.
if (!ModuleImportPath.empty())
- (void)TheModuleLoader.loadModule(ModuleImportLoc, ModuleImportPath);
+ (void)TheModuleLoader.loadModule(ModuleImportLoc, ModuleImportPath,
+ Module::MacrosVisible);
}
void Preprocessor::AddCommentHandler(CommentHandler *Handler) {
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 48f4c4f0cb..1e57a00f1f 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -9892,7 +9892,8 @@ Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr,
}
DeclResult Sema::ActOnModuleImport(SourceLocation ImportLoc, ModuleIdPath Path) {
- Module *Mod = PP.getModuleLoader().loadModule(ImportLoc, Path);
+ Module *Mod = PP.getModuleLoader().loadModule(ImportLoc, Path,
+ Module::AllVisible);
if (!Mod)
return true;
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index d43f8c1f45..258baebc05 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -2439,6 +2439,38 @@ ASTReader::ASTReadResult ASTReader::validateFileEntries(ModuleFile &M) {
return Success;
}
+void ASTReader::makeModuleVisible(Module *Mod,
+ Module::NameVisibilityKind NameVisibility) {
+ llvm::SmallPtrSet<Module *, 4> Visited;
+ llvm::SmallVector<Module *, 4> Stack;
+ Stack.push_back(Mod);
+ while (!Stack.empty()) {
+ Mod = Stack.back();
+ Stack.pop_back();
+
+ if (NameVisibility <= Mod->NameVisibility) {
+ // This module already has this level of visibility (or greater), so
+ // there is nothing more to do.
+ continue;
+ }
+
+ // Update the module's name visibility.
+ Mod->NameVisibility = NameVisibility;
+
+ // FIXME: If we've already deserialized any names from this module,
+ // mark them as visible.
+
+ // Push any non-explicit submodules onto the stack to be marked as
+ // visible.
+ for (llvm::StringMap<Module *>::iterator Sub = Mod->SubModules.begin(),
+ SubEnd = Mod->SubModules.end();
+ Sub != SubEnd; ++Sub) {
+ if (!Sub->getValue()->IsExplicit && Visited.insert(Sub->getValue()))
+ Stack.push_back(Sub->getValue());
+ }
+ }
+}
+
ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,
ModuleKind Type) {
switch(ReadASTCore(FileName, Type, /*ImportedBy=*/0)) {