]> granicus.if.org Git - clang/commitdiff
Switch the module-loading interfaces and parser from a simple
authorDouglas Gregor <dgregor@apple.com>
Wed, 30 Nov 2011 00:36:36 +0000 (00:36 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 30 Nov 2011 00:36:36 +0000 (00:36 +0000)
top-level module name to a module path (e.g., std.vector). We're still
missing a number of pieces for this actually to do something.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145462 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Frontend/ASTUnit.h
include/clang/Frontend/CompilerInstance.h
include/clang/Lex/ModuleLoader.h
include/clang/Sema/Sema.h
lib/Frontend/CompilerInstance.cpp
lib/Lex/PPDirectives.cpp
lib/Lex/Preprocessor.cpp
lib/Parse/Parser.cpp
lib/Sema/SemaDecl.cpp

index 3ccd04dfb29f938ddbc1a9ba6b2316c1495b2a2f..c29b07440ff92fbba421141a809eb68ccbf87e05 100644 (file)
@@ -781,9 +781,7 @@ public:
   /// \returns True if an error occurred, false otherwise.
   bool serialize(raw_ostream &OS);
   
-  virtual ModuleKey loadModule(SourceLocation ImportLoc, 
-                               IdentifierInfo &ModuleName,
-                               SourceLocation ModuleNameLoc) {
+  virtual ModuleKey loadModule(SourceLocation ImportLoc, ModuleIdPath Path) {
     // ASTUnit doesn't know how to load modules (not that this matters).
     return 0;
   }
index 639c2f68d31b4c5a93ab94a64cb24b2f26e178c0..9f982c92657018565da85c5017c1a2b3732d7665 100644 (file)
 
 #include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Lex/ModuleLoader.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/OwningPtr.h"
 #include <cassert>
 #include <list>
 #include <string>
+#include <utility>
 
 namespace llvm {
 class raw_fd_ostream;
@@ -624,9 +626,7 @@ public:
 
   /// }
   
-  virtual ModuleKey loadModule(SourceLocation ImportLoc, 
-                               IdentifierInfo &ModuleName,
-                               SourceLocation ModuleNameLoc);
+  virtual ModuleKey loadModule(SourceLocation ImportLoc, ModuleIdPath Path);
 };
 
 } // end namespace clang
index 72ec0e3ebc9f5d56266f927210f7b521e30207e1..42071080f7325db7a16743dc6b9f36e53870e00e 100644 (file)
@@ -15,6 +15,7 @@
 #define LLVM_CLANG_LEX_MODULE_LOADER_H
 
 #include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
 
 namespace clang {
 
@@ -24,6 +25,10 @@ class IdentifierInfo;
 /// interpreted by the module loader itself.
 typedef void *ModuleKey;
   
+/// \brief A sequence of identifier/location pairs used to describe a particular
+/// module or submodule, e.g., std.vector.
+typedef llvm::ArrayRef<std::pair<IdentifierInfo*, SourceLocation> > ModuleIdPath;
+  
 /// \brief Abstract interface for a module loader.
 ///
 /// This abstract interface describes a module loader, which is responsible
@@ -39,15 +44,13 @@ public:
   /// parameters.
   ///
   /// \param ImportLoc The location of the 'import' keyword.
-  /// \param ModuleName The name of the module to be loaded.
-  /// \param ModuleNameLoc The location of the module name.
+  /// \param Path The identifiers (and their locations) of the module
+  /// "path", e.g., "std.vector" would be split into "std" and "vector".
   ///
   /// \returns If successful, a non-NULL module key describing this module.
   /// Otherwise, returns NULL to indicate that the module could not be
   /// loaded.
-  virtual ModuleKey loadModule(SourceLocation ImportLoc, 
-                               IdentifierInfo &ModuleName,
-                               SourceLocation ModuleNameLoc) = 0;
+  virtual ModuleKey loadModule(SourceLocation ImportLoc, ModuleIdPath Path) = 0;
 };
   
 }
index da17b248a14817baa7bf26fa384ecd548f8e4803..66d0baf73b22dd05bd5de6dbeaa0db81625d4121 100644 (file)
@@ -29,6 +29,7 @@
 #include "clang/AST/DeclarationName.h"
 #include "clang/AST/ExternalASTSource.h"
 #include "clang/AST/TypeLoc.h"
+#include "clang/Lex/ModuleLoader.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Basic/TemplateKinds.h"
 #include "clang/Basic/TypeTraits.h"
@@ -1109,12 +1110,8 @@ public:
   ///
   /// \param ImportLoc The location of the '__import_module__' keyword.
   ///
-  /// \param ModuleName The name of the module.
-  ///
-  /// \param ModuleNameLoc The location of the module name.
-  DeclResult ActOnModuleImport(SourceLocation ImportLoc,
-                               IdentifierInfo &ModuleName,
-                               SourceLocation ModuleNameLoc);
+  /// \param Path The module access path.
+  DeclResult ActOnModuleImport(SourceLocation ImportLoc, ModuleIdPath Path);
 
   /// \brief Diagnose that \p New is a module-private redeclaration of
   /// \p Old.
index 35f82174b2ecf2818d35d3ca790b5d803e0a8b4b..a72370312db5ba3a7b0871ca2ef446fe5a672479 100644 (file)
@@ -1068,9 +1068,8 @@ static void compileModule(CompilerInstance &ImportingInstance,
     llvm::sys::Path(TempModuleMapFileName).eraseFromDisk();
 }
 
-ModuleKey CompilerInstance::loadModule(SourceLocation ImportLoc,
-                                       IdentifierInfo &ModuleName,
-                                       SourceLocation ModuleNameLoc) {
+ModuleKey CompilerInstance::loadModule(SourceLocation ImportLoc, 
+                                       ModuleIdPath Path) {
   // Determine what file we're searching from.
   SourceManager &SourceMgr = getSourceManager();
   SourceLocation ExpandedImportLoc = SourceMgr.getExpansionLoc(ImportLoc);
@@ -1079,13 +1078,19 @@ ModuleKey CompilerInstance::loadModule(SourceLocation ImportLoc,
   if (!CurFile)
     CurFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
 
+  StringRef ModuleName = Path[0].first->getName();
+  SourceLocation ModuleNameLoc = Path[0].second;
+  
   // Search for a module with the given name.
   ModuleMap::Module *Module = 0;
   std::string ModuleFileName;
   const FileEntry *ModuleFile
-    = PP->getHeaderSearchInfo().lookupModule(ModuleName.getName(), Module,
+    = PP->getHeaderSearchInfo().lookupModule(ModuleName, Module,
                                              &ModuleFileName);
 
+  // FIXME: Verify that the rest of the module path actually corresponds to
+  // a submodule, and pass that information through.
+  
   bool BuildingModule = false;
   if (!ModuleFile && Module) {
     // The module is not cached, but we have a module map from which we can
@@ -1095,23 +1100,22 @@ ModuleKey CompilerInstance::loadModule(SourceLocation ImportLoc,
     SmallVectorImpl<std::string> &ModuleBuildPath
       = getPreprocessorOpts().ModuleBuildPath;
     SmallVectorImpl<std::string>::iterator Pos
-      = std::find(ModuleBuildPath.begin(), ModuleBuildPath.end(),
-                  ModuleName.getName());
+      = std::find(ModuleBuildPath.begin(), ModuleBuildPath.end(), ModuleName);
     if (Pos != ModuleBuildPath.end()) {
       llvm::SmallString<256> CyclePath;
       for (; Pos != ModuleBuildPath.end(); ++Pos) {
         CyclePath += *Pos;
         CyclePath += " -> ";
       }
-      CyclePath += ModuleName.getName();
+      CyclePath += ModuleName;
 
       getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle)
-        << ModuleName.getName() << CyclePath;
+        << ModuleName << CyclePath;
       return 0;
     }
 
     getDiagnostics().Report(ModuleNameLoc, diag::warn_module_build)
-      << ModuleName.getName();
+      << ModuleName;
     BuildingModule = true;
     compileModule(*this, Module, ModuleFileName);
     ModuleFile = FileMgr->getFile(ModuleFileName);
@@ -1121,7 +1125,7 @@ ModuleKey CompilerInstance::loadModule(SourceLocation ImportLoc,
     getDiagnostics().Report(ModuleNameLoc,
                             BuildingModule? diag::err_module_not_built
                                           : diag::err_module_not_found)
-      << ModuleName.getName()
+      << ModuleName
       << SourceRange(ImportLoc, ModuleNameLoc);
     return 0;
   }
index 88d9429f0012a0661a184a71acee04d8af7023ca..140f793234af1e109b338c0f1f91fb1ed21d223c 100644 (file)
@@ -1279,13 +1279,17 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
   // If we are supposed to import a module rather than including the header,
   // do so now.
   if (SuggestedModule) {
-    // FIXME: Actually load the submodule that we were given.
-    while (SuggestedModule->Parent)
-      SuggestedModule = SuggestedModule->Parent;
-    
-    TheModuleLoader.loadModule(IncludeTok.getLocation(),
-                               Identifiers.get(SuggestedModule->Name),
-                               FilenameTok.getLocation());
+    // Compute the module access path corresponding to this module.
+    // FIXME: Should we have a second loadModule() overload to avoid this
+    // extra lookup step?
+    llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;
+    for (ModuleMap::Module *Mod = SuggestedModule; Mod; Mod = Mod->Parent)
+      Path.push_back(std::make_pair(getIdentifierInfo(Mod->Name),
+                                    FilenameTok.getLocation()));
+    std::reverse(Path.begin(), Path.end());
+
+    // Load the module.
+    TheModuleLoader.loadModule(IncludeTok.getLocation(), Path);
     return;
   }
   
index 798244c3d2dcf2761825a68708ea520dd0cf274e..aeba32f96a3c907cc7ff92cdf8711b03eefe8001 100644 (file)
@@ -575,9 +575,11 @@ void Preprocessor::LexAfterModuleImport(Token &Result) {
     return;
   
   // Load the module.
-  (void)TheModuleLoader.loadModule(ModuleImportLoc,
-                                   *Result.getIdentifierInfo(), 
-                                   Result.getLocation());
+  llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;
+  Path.push_back(std::make_pair(Result.getIdentifierInfo(), 
+                                Result.getLocation()));
+  
+  (void)TheModuleLoader.loadModule(ModuleImportLoc, Path);
 }
 
 void Preprocessor::AddCommentHandler(CommentHandler *Handler) {
index 834e741e3035ded16403fd7b0d807714605378db..eb6dc443c9df6fce83e32bf38862a1089fcd3b72 100644 (file)
@@ -1570,16 +1570,29 @@ Parser::DeclGroupPtrTy Parser::ParseModuleImport() {
          "Improper start to module import");
   SourceLocation ImportLoc = ConsumeToken();
   
-  // Parse the module name.
-  if (!Tok.is(tok::identifier)) {
-    Diag(Tok, diag::err_module_expected_ident);
-    SkipUntil(tok::semi);
-    return DeclGroupPtrTy();
-  }
+  llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;
+  
+  // Parse the module path.
+  do {
+    if (!Tok.is(tok::identifier)) {
+      Diag(Tok, diag::err_module_expected_ident);
+      SkipUntil(tok::semi);
+      return DeclGroupPtrTy();
+    }
+    
+    // Record this part of the module path.
+    Path.push_back(std::make_pair(Tok.getIdentifierInfo(), Tok.getLocation()));
+    ConsumeToken();
+    
+    if (Tok.is(tok::period)) {
+      ConsumeToken();
+      continue;
+    }
+    
+    break;
+  } while (true);
   
-  IdentifierInfo &ModuleName = *Tok.getIdentifierInfo();
-  SourceLocation ModuleNameLoc = ConsumeToken();
-  DeclResult Import = Actions.ActOnModuleImport(ImportLoc, ModuleName, ModuleNameLoc);
+  DeclResult Import = Actions.ActOnModuleImport(ImportLoc, Path);
   ExpectAndConsumeSemi(diag::err_module_expected_semi);
   if (Import.isInvalid())
     return DeclGroupPtrTy();
index eaf778d130066206001db0f669f5d9e18a043bf5..0659a0f6f3a60f8349ee992039bf203bae8ef1e1 100644 (file)
@@ -9891,11 +9891,8 @@ Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr,
   return New;
 }
 
-DeclResult Sema::ActOnModuleImport(SourceLocation ImportLoc,
-                                   IdentifierInfo &ModuleName,
-                                   SourceLocation ModuleNameLoc) {
-  ModuleKey Module = PP.getModuleLoader().loadModule(ImportLoc, 
-                                                     ModuleName, ModuleNameLoc);
+DeclResult Sema::ActOnModuleImport(SourceLocation ImportLoc, ModuleIdPath Path) {
+  ModuleKey Module = PP.getModuleLoader().loadModule(ImportLoc, Path);
   if (!Module)
     return true;