From c69c42e939e6bdaa56d162cc36da4f6b6c53e8db Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 17 Nov 2011 22:44:56 +0000 Subject: [PATCH] When making a suggestion regarding which module to load rather than preprocess/parse a header, report back with an actual module (which may be a submodule) rather than just the name of the module. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144925 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Lex/DirectoryLookup.h | 9 +++++---- include/clang/Lex/HeaderSearch.h | 10 ++++------ include/clang/Lex/Preprocessor.h | 2 +- lib/Lex/HeaderSearch.cpp | 22 +++++++++++----------- lib/Lex/PPDirectives.cpp | 12 ++++++++---- 5 files changed, 29 insertions(+), 26 deletions(-) diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h index f7da61b0ed..d2764e7edd 100644 --- a/include/clang/Lex/DirectoryLookup.h +++ b/include/clang/Lex/DirectoryLookup.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_LEX_DIRECTORYLOOKUP_H #define LLVM_CLANG_LEX_DIRECTORYLOOKUP_H +#include "clang/Lex/ModuleMap.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceManager.h" @@ -144,13 +145,13 @@ public: /// \param BuildingModule The name of the module we're currently building. /// /// \param SuggestedModule If non-null, and the file found is semantically - /// part of a known module, this will be set to the name of the module that - /// could be imported instead of preprocessing/parsing the file found. + /// part of a known module, this will be set to the module that should + /// be imported instead of preprocessing/parsing the file found. const FileEntry *LookupFile(StringRef Filename, HeaderSearch &HS, SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, StringRef BuildingModule, - StringRef *SuggestedModule) const; + ModuleMap::Module **SuggestedModule) const; private: const FileEntry *DoFrameworkLookup( @@ -158,7 +159,7 @@ private: SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, StringRef BuildingModule, - StringRef *SuggestedModule) const; + ModuleMap::Module **SuggestedModule) const; }; diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index 21654c16cc..b56fba538a 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -258,15 +258,15 @@ public: /// Filename for framework includes. /// /// \param SuggestedModule If non-null, and the file found is semantically - /// part of a known module, this will be set to the name of the module that - /// could be imported instead of preprocessing/parsing the file found. + /// part of a known module, this will be set to the module that should + /// be imported instead of preprocessing/parsing the file found. const FileEntry *LookupFile(StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, const FileEntry *CurFileEnt, SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, - StringRef *SuggestedModule); + ModuleMap::Module **SuggestedModule); /// LookupSubframeworkHeader - Look up a subframework for the specified /// #include file. For example, if #include'ing from @@ -366,9 +366,7 @@ public: bool hasModuleMap(StringRef Filename, const DirectoryEntry *Root); /// \brief Retrieve the module that corresponds to the given file, if any. - /// - /// FIXME: This will need to be generalized for submodules. - StringRef findModuleForHeader(const FileEntry *File); + ModuleMap::Module *findModuleForHeader(const FileEntry *File); /// \brief Read the contents of the given module map file. diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index bcd3c4b274..90f64c4554 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -1008,7 +1008,7 @@ public: const DirectoryLookup *&CurDir, SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, - StringRef *SuggestedModule); + ModuleMap::Module **SuggestedModule); /// GetCurLookup - The DirectoryLookup structure used to find the current /// FileEntry, if CurLexer is non-null and if applicable. This allows us to diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp index cc9c8c16f7..4deba60b9d 100644 --- a/lib/Lex/HeaderSearch.cpp +++ b/lib/Lex/HeaderSearch.cpp @@ -219,7 +219,7 @@ const FileEntry *DirectoryLookup::LookupFile( SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, StringRef BuildingModule, - StringRef *SuggestedModule) const { + ModuleMap::Module **SuggestedModule) const { llvm::SmallString<1024> TmpDir; if (isNormalDir()) { // Concatenate the requested file onto the directory. @@ -245,8 +245,8 @@ const FileEntry *DirectoryLookup::LookupFile( // If there is a module that corresponds to this header, // suggest it. - StringRef Module = HS.findModuleForHeader(File); - if (!Module.empty() && Module != BuildingModule) + ModuleMap::Module *Module = HS.findModuleForHeader(File); + if (Module && Module->getTopLevelModuleName() != BuildingModule) *SuggestedModule = Module; return File; @@ -285,7 +285,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup( SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, StringRef BuildingModule, - StringRef *SuggestedModule) const + ModuleMap::Module **SuggestedModule) const { FileManager &FileMgr = HS.getFileMgr(); @@ -370,7 +370,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup( if (const FileEntry *FE = FileMgr.getFile(FrameworkName.str(), /*openFile=*/!AutomaticImport)) { if (AutomaticImport) - *SuggestedModule = Module->Name; + *SuggestedModule = Module; return FE; } @@ -385,7 +385,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup( const FileEntry *FE = FileMgr.getFile(FrameworkName.str(), /*openFile=*/!AutomaticImport); if (FE && AutomaticImport) - *SuggestedModule = Module->Name; + *SuggestedModule = Module; return FE; } @@ -408,10 +408,10 @@ const FileEntry *HeaderSearch::LookupFile( const FileEntry *CurFileEnt, SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, - StringRef *SuggestedModule) + ModuleMap::Module **SuggestedModule) { if (SuggestedModule) - *SuggestedModule = StringRef(); + *SuggestedModule = 0; // If 'Filename' is absolute, check to see if it exists and no searching. if (llvm::sys::path::is_absolute(Filename)) { @@ -806,11 +806,11 @@ bool HeaderSearch::hasModuleMap(StringRef FileName, return false; } -StringRef HeaderSearch::findModuleForHeader(const FileEntry *File) { +ModuleMap::Module *HeaderSearch::findModuleForHeader(const FileEntry *File) { if (ModuleMap::Module *Module = ModMap.findModuleForHeader(File)) - return Module->getTopLevelModuleName(); + return Module; - return StringRef(); + return 0; } bool HeaderSearch::loadModuleMapFile(const FileEntry *File) { diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index 9446d51f9d..2444364f35 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -486,7 +486,7 @@ const FileEntry *Preprocessor::LookupFile( const DirectoryLookup *&CurDir, SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, - StringRef *SuggestedModule) { + ModuleMap::Module **SuggestedModule) { // If the header lookup mechanism may be relative to the current file, pass in // info about where the current file is. const FileEntry *CurFileEnt = 0; @@ -1269,7 +1269,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, llvm::SmallString<1024> RelativePath; // We get the raw path only if we have 'Callbacks' to which we later pass // the path. - StringRef SuggestedModule; + ModuleMap::Module *SuggestedModule = 0; const FileEntry *File = LookupFile( Filename, isAngled, LookupFrom, CurDir, Callbacks ? &SearchPath : NULL, Callbacks ? &RelativePath : NULL, @@ -1277,9 +1277,13 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc, // If we are supposed to import a module rather than including the header, // do so now. - if (!SuggestedModule.empty()) { + if (SuggestedModule) { + // FIXME: Actually load the submodule that we were given. + while (SuggestedModule->Parent) + SuggestedModule = SuggestedModule->Parent; + TheModuleLoader.loadModule(IncludeTok.getLocation(), - Identifiers.get(SuggestedModule), + Identifiers.get(SuggestedModule->Name), FilenameTok.getLocation()); return; }