[cfe-commits] r145586 - in /cfe/trunk: include/clang/Basic/Module.h include/clang/Frontend/ASTUnit.h include/clang/Frontend/CompilerInstance.h include/clang/Lex/ModuleLoader.h include/clang/Serialization/ASTReader.h lib/Frontend/CompilerInstance.cpp lib/Lex/PPDirectives.cpp lib/Lex/Preprocessor.cpp lib/Sema/SemaDecl.cpp lib/Serialization/ASTReader.cpp

Douglas Gregor dgregor at apple.com
Thu Dec 1 09:11:21 PST 2011


Author: dgregor
Date: Thu Dec  1 11:11:21 2011
New Revision: 145586

URL: http://llvm.org/viewvc/llvm-project?rev=145586&view=rev
Log:
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).


Modified:
    cfe/trunk/include/clang/Basic/Module.h
    cfe/trunk/include/clang/Frontend/ASTUnit.h
    cfe/trunk/include/clang/Frontend/CompilerInstance.h
    cfe/trunk/include/clang/Lex/ModuleLoader.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/lib/Frontend/CompilerInstance.cpp
    cfe/trunk/lib/Lex/PPDirectives.cpp
    cfe/trunk/lib/Lex/Preprocessor.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp

Modified: cfe/trunk/include/clang/Basic/Module.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Module.h?rev=145586&r1=145585&r2=145586&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Module.h (original)
+++ cfe/trunk/include/clang/Basic/Module.h Thu Dec  1 11:11:21 2011
@@ -58,17 +58,33 @@
   /// \brief Whether this is an explicit submodule.
   bool IsExplicit;
   
+  /// \brief Describes the visibility of the various names within a
+  /// particular module.
+  enum NameVisibilityKind {
+    /// \brief All of the names in this module are hidden.
+    ///
+    Hidden,
+    /// \brief Only the macro names in this module are visible.
+    MacrosVisible,
+    /// \brief All of the names in this module are visible.
+    AllVisible
+  };  
+  
+  ///\ brief The visibility of names within this particular module.
+  NameVisibilityKind NameVisibility;
+  
   /// \brief Construct a top-level module.
   explicit Module(StringRef Name, SourceLocation DefinitionLoc,
                   bool IsFramework)
     : Name(Name), DefinitionLoc(DefinitionLoc), Parent(0), UmbrellaHeader(0),
-      IsFramework(IsFramework), IsExplicit(false) { }
+      IsFramework(IsFramework), IsExplicit(false), NameVisibility(Hidden) { }
   
   /// \brief Construct  a new module or submodule.
   Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, 
          bool IsFramework, bool IsExplicit)
     : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), 
-      UmbrellaHeader(0), IsFramework(IsFramework), IsExplicit(IsExplicit) { }
+      UmbrellaHeader(0), IsFramework(IsFramework), IsExplicit(IsExplicit), 
+      NameVisibility(Hidden) { }
   
   ~Module();
   

Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=145586&r1=145585&r2=145586&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTUnit.h Thu Dec  1 11:11:21 2011
@@ -781,7 +781,8 @@
   /// \returns True if an error occurred, false otherwise.
   bool serialize(raw_ostream &OS);
   
-  virtual Module *loadModule(SourceLocation ImportLoc, ModuleIdPath Path) {
+  virtual Module *loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
+                             Module::NameVisibilityKind Visibility) {
     // ASTUnit doesn't know how to load modules (not that this matters).
     return 0;
   }

Modified: cfe/trunk/include/clang/Frontend/CompilerInstance.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstance.h?rev=145586&r1=145585&r2=145586&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/CompilerInstance.h (original)
+++ cfe/trunk/include/clang/Frontend/CompilerInstance.h Thu Dec  1 11:11:21 2011
@@ -641,7 +641,8 @@
 
   /// }
   
-  virtual Module *loadModule(SourceLocation ImportLoc, ModuleIdPath Path);
+  virtual Module *loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
+                             Module::NameVisibilityKind Visibility);
 };
 
 } // end namespace clang

Modified: cfe/trunk/include/clang/Lex/ModuleLoader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/ModuleLoader.h?rev=145586&r1=145585&r2=145586&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/ModuleLoader.h (original)
+++ cfe/trunk/include/clang/Lex/ModuleLoader.h Thu Dec  1 11:11:21 2011
@@ -14,13 +14,13 @@
 #ifndef LLVM_CLANG_LEX_MODULE_LOADER_H
 #define LLVM_CLANG_LEX_MODULE_LOADER_H
 
+#include "clang/Basic/Module.h"
 #include "clang/Basic/SourceLocation.h"
 #include "llvm/ADT/ArrayRef.h"
 
 namespace clang {
 
 class IdentifierInfo;
-class Module;
   
 /// \brief A sequence of identifier/location pairs used to describe a particular
 /// module or submodule, e.g., std.vector.
@@ -41,12 +41,17 @@
   /// parameters.
   ///
   /// \param ImportLoc The location of the 'import' keyword.
+  ///
   /// \param Path The identifiers (and their locations) of the module
   /// "path", e.g., "std.vector" would be split into "std" and "vector".
+  /// 
+  /// \param Visibility The visibility provided for the names in the loaded
+  /// module.
   ///
   /// \returns If successful, returns the loaded module. Otherwise, returns 
   /// NULL to indicate that the module could not be loaded.
-  virtual Module *loadModule(SourceLocation ImportLoc, ModuleIdPath Path) = 0;
+  virtual Module *loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
+                             Module::NameVisibilityKind Visibility) = 0;
 };
   
 }

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=145586&r1=145585&r2=145586&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Thu Dec  1 11:11:21 2011
@@ -803,6 +803,16 @@
   /// the actual file in the file system.
   ASTReadResult validateFileEntries(ModuleFile &M);
 
+  /// \brief Make the entities in the given module and any of its (non-explicit)
+  /// submodules visible to name lookup.
+  ///
+  /// \param Mod The module whose names should be made visible.
+  ///
+  /// \param Visibility The level of visibility to give the names in the module.
+  /// Visibility can only be increased over time.
+  void makeModuleVisible(Module *Mod, 
+                         Module::NameVisibilityKind NameVisibility);
+  
   /// \brief Set the AST callbacks listener.
   void setListener(ASTReaderListener *listener) {
     Listener.reset(listener);

Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=145586&r1=145585&r2=145586&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Thu Dec  1 11:11:21 2011
@@ -1069,12 +1069,17 @@
 }
 
 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 @@
     }
   }
   
-  // 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;

Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=145586&r1=145585&r2=145586&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Thu Dec  1 11:11:21 2011
@@ -1360,8 +1360,10 @@
            "__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;
   }
   

Modified: cfe/trunk/lib/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=145586&r1=145585&r2=145586&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Thu Dec  1 11:11:21 2011
@@ -593,7 +593,8 @@
 
   // 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) {

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=145586&r1=145585&r2=145586&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Dec  1 11:11:21 2011
@@ -9892,7 +9892,8 @@
 }
 
 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;
   

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=145586&r1=145585&r2=145586&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Dec  1 11:11:21 2011
@@ -2439,6 +2439,38 @@
   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)) {





More information about the cfe-commits mailing list