From 3d3589db579f7695667b913c5043dd264ebe546f Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 30 Nov 2011 00:36:36 +0000 Subject: [PATCH] Switch the module-loading interfaces and parser from a simple 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 | 4 +-- include/clang/Frontend/CompilerInstance.h | 6 ++--- include/clang/Lex/ModuleLoader.h | 13 ++++++---- include/clang/Sema/Sema.h | 9 +++---- lib/Frontend/CompilerInstance.cpp | 24 ++++++++++-------- lib/Lex/PPDirectives.cpp | 18 ++++++++----- lib/Lex/Preprocessor.cpp | 8 +++--- lib/Parse/Parser.cpp | 31 ++++++++++++++++------- lib/Sema/SemaDecl.cpp | 7 ++--- 9 files changed, 69 insertions(+), 51 deletions(-) diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index 3ccd04dfb2..c29b07440f 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -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; } diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h index 639c2f68d3..9f982c9265 100644 --- a/include/clang/Frontend/CompilerInstance.h +++ b/include/clang/Frontend/CompilerInstance.h @@ -12,12 +12,14 @@ #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 #include #include +#include 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 diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h index 72ec0e3ebc..42071080f7 100644 --- a/include/clang/Lex/ModuleLoader.h +++ b/include/clang/Lex/ModuleLoader.h @@ -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 > 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; }; } diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index da17b248a1..66d0baf73b 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -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. diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index 35f82174b2..a72370312d 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -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 &ModuleBuildPath = getPreprocessorOpts().ModuleBuildPath; SmallVectorImpl::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; } diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index 88d9429f00..140f793234 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -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, 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; } diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp index 798244c3d2..aeba32f96a 100644 --- a/lib/Lex/Preprocessor.cpp +++ b/lib/Lex/Preprocessor.cpp @@ -575,9 +575,11 @@ void Preprocessor::LexAfterModuleImport(Token &Result) { return; // Load the module. - (void)TheModuleLoader.loadModule(ModuleImportLoc, - *Result.getIdentifierInfo(), - Result.getLocation()); + llvm::SmallVector, 2> Path; + Path.push_back(std::make_pair(Result.getIdentifierInfo(), + Result.getLocation())); + + (void)TheModuleLoader.loadModule(ModuleImportLoc, Path); } void Preprocessor::AddCommentHandler(CommentHandler *Handler) { diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 834e741e30..eb6dc443c9 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -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, 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(); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index eaf778d130..0659a0f6f3 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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; -- 2.40.0