Add an experimental flag -fauto-module-import that automatically turns
#include or #import direcctives of framework headers into module
imports of the corresponding framework module.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139860 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
index bc18d0d..8a35080 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -139,7 +139,8 @@
// Look for the umbrella header in this directory.
if (const FileEntry *HeaderFile
- = SearchDirs[Idx].LookupFile(UmbrellaHeaderName, *this, 0, 0)) {
+ = SearchDirs[Idx].LookupFile(UmbrellaHeaderName, *this, 0, 0,
+ StringRef(), 0)) {
*UmbrellaHeader = HeaderFile->getName();
return 0;
}
@@ -173,7 +174,9 @@
StringRef Filename,
HeaderSearch &HS,
SmallVectorImpl<char> *SearchPath,
- SmallVectorImpl<char> *RelativePath) const {
+ SmallVectorImpl<char> *RelativePath,
+ StringRef BuildingModule,
+ StringRef *SuggestedModule) const {
llvm::SmallString<1024> TmpDir;
if (isNormalDir()) {
// Concatenate the requested file onto the directory.
@@ -192,7 +195,8 @@
}
if (isFramework())
- return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath);
+ return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
+ BuildingModule, SuggestedModule);
assert(isHeaderMap() && "Unknown directory lookup");
const FileEntry * const Result = getHeaderMap()->LookupFile(
@@ -218,7 +222,10 @@
StringRef Filename,
HeaderSearch &HS,
SmallVectorImpl<char> *SearchPath,
- SmallVectorImpl<char> *RelativePath) const {
+ SmallVectorImpl<char> *RelativePath,
+ StringRef BuildingModule,
+ StringRef *SuggestedModule) const
+{
FileManager &FileMgr = HS.getFileMgr();
// Framework names must have a '/' in the filename.
@@ -280,9 +287,15 @@
SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
}
+ /// Determine whether this is the module we're building or not.
+ bool AutomaticImport = SuggestedModule &&
+ (BuildingModule != StringRef(Filename.begin(), SlashPos));
+
FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
if (const FileEntry *FE = FileMgr.getFile(FrameworkName.str(),
- /*openFile=*/true)) {
+ /*openFile=*/!AutomaticImport)) {
+ if (AutomaticImport)
+ *SuggestedModule = StringRef(Filename.begin(), SlashPos);
return FE;
}
@@ -294,7 +307,11 @@
SearchPath->insert(SearchPath->begin()+OrigSize, Private,
Private+strlen(Private));
- return FileMgr.getFile(FrameworkName.str(), /*openFile=*/true);
+ const FileEntry *FE = FileMgr.getFile(FrameworkName.str(),
+ /*openFile=*/!AutomaticImport);
+ if (FE && AutomaticImport)
+ *SuggestedModule = StringRef(Filename.begin(), SlashPos);
+ return FE;
}
@@ -315,7 +332,12 @@
const DirectoryLookup *&CurDir,
const FileEntry *CurFileEnt,
SmallVectorImpl<char> *SearchPath,
- SmallVectorImpl<char> *RelativePath) {
+ SmallVectorImpl<char> *RelativePath,
+ StringRef *SuggestedModule)
+{
+ if (SuggestedModule)
+ *SuggestedModule = StringRef();
+
// If 'Filename' is absolute, check to see if it exists and no searching.
if (llvm::sys::path::is_absolute(Filename)) {
CurDir = 0;
@@ -400,7 +422,8 @@
// Check each directory in sequence to see if it contains this file.
for (; i != SearchDirs.size(); ++i) {
const FileEntry *FE =
- SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath);
+ SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath,
+ BuildingModule, SuggestedModule);
if (!FE) continue;
CurDir = &SearchDirs[i];
@@ -439,7 +462,8 @@
const FileEntry *Result = LookupFile(ScratchFilename, /*isAngled=*/true,
FromDir, CurDir, CurFileEnt,
- SearchPath, RelativePath);
+ SearchPath, RelativePath,
+ SuggestedModule);
std::pair<unsigned, unsigned> &CacheLookup
= LookupFileCache.GetOrCreateValue(Filename).getValue();
CacheLookup.second
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index be70cec..1f54ef5 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -17,6 +17,7 @@
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Lex/CodeCompletionHandler.h"
+#include "clang/Lex/ModuleLoader.h"
#include "clang/Lex/Pragma.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
@@ -478,7 +479,8 @@
const DirectoryLookup *FromDir,
const DirectoryLookup *&CurDir,
SmallVectorImpl<char> *SearchPath,
- SmallVectorImpl<char> *RelativePath) {
+ SmallVectorImpl<char> *RelativePath,
+ StringRef *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;
@@ -502,12 +504,13 @@
CurDir = CurDirLookup;
const FileEntry *FE = HeaderInfo.LookupFile(
Filename, isAngled, FromDir, CurDir, CurFileEnt,
- SearchPath, RelativePath);
+ SearchPath, RelativePath, SuggestedModule);
if (FE) return FE;
// Otherwise, see if this is a subframework header. If so, this is relative
// to one of the headers on the #include stack. Walk the list of the current
// headers on the #include stack and pass them to HeaderInfo.
+ // FIXME: SuggestedModule!
if (IsFileLexer()) {
if ((CurFileEnt = SourceMgr.getFileEntryForID(CurPPLexer->getFileID())))
if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt,
@@ -1214,10 +1217,21 @@
llvm::SmallString<1024> RelativePath;
// We get the raw path only if we have 'Callbacks' to which we later pass
// the path.
+ StringRef SuggestedModule;
const FileEntry *File = LookupFile(
Filename, isAngled, LookupFrom, CurDir,
- Callbacks ? &SearchPath : NULL, Callbacks ? &RelativePath : NULL);
+ Callbacks ? &SearchPath : NULL, Callbacks ? &RelativePath : NULL,
+ AutoModuleImport? &SuggestedModule : 0);
+ // If we are supposed to import a module rather than including the header,
+ // do so now.
+ if (!SuggestedModule.empty()) {
+ TheModuleLoader.loadModule(IncludeTok.getLocation(),
+ Identifiers.get(SuggestedModule),
+ FilenameTok.getLocation());
+ return;
+ }
+
// Notify the callback object that we've seen an inclusion directive.
if (Callbacks)
Callbacks->InclusionDirective(HashLoc, IncludeTok, Filename, isAngled, File,
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index c7b00ea..9923ae7 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -785,7 +785,7 @@
// Search include directories.
const DirectoryLookup *CurDir;
const FileEntry *File =
- PP.LookupFile(Filename, isAngled, LookupFrom, CurDir, NULL, NULL);
+ PP.LookupFile(Filename, isAngled, LookupFrom, CurDir, NULL, NULL, NULL);
// Get the result value. Result = true means the file exists.
bool Result = File != 0;
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index 92c0dd5..f738d1d 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -366,7 +366,8 @@
// Search include directories for this file.
const DirectoryLookup *CurDir;
- const FileEntry *File = LookupFile(Filename, isAngled, 0, CurDir, NULL, NULL);
+ const FileEntry *File = LookupFile(Filename, isAngled, 0, CurDir, NULL, NULL,
+ NULL);
if (File == 0) {
if (!SuppressIncludeNotFoundError)
Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index db3479e..cf63e27 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -133,6 +133,7 @@
KeepComments = false;
KeepMacroComments = false;
SuppressIncludeNotFoundError = false;
+ AutoModuleImport = false;
// Macro expansion is enabled.
DisableMacroExpansion = false;