forked from OSchip/llvm-project
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. llvm-svn: 139860
This commit is contained in:
parent
112ec17e1b
commit
97eec24b0b
|
@ -607,6 +607,9 @@ def fmodule_cache_path : Separate<"-fmodule-cache-path">,
|
||||||
HelpText<"Specify the module cache path">;
|
HelpText<"Specify the module cache path">;
|
||||||
def fdisable_module_hash : Flag<"-fdisable-module-hash">,
|
def fdisable_module_hash : Flag<"-fdisable-module-hash">,
|
||||||
HelpText<"Disable the module hash">;
|
HelpText<"Disable the module hash">;
|
||||||
|
def fauto_module_import : Flag<"-fauto-module-import">,
|
||||||
|
HelpText<"Automatically translate #include/#import into module imports "
|
||||||
|
"when possible">;
|
||||||
|
|
||||||
def F : JoinedOrSeparate<"-F">, MetaVarName<"<directory>">,
|
def F : JoinedOrSeparate<"-F">, MetaVarName<"<directory>">,
|
||||||
HelpText<"Add directory to framework include search path">;
|
HelpText<"Add directory to framework include search path">;
|
||||||
|
|
|
@ -344,6 +344,9 @@ def fmsc_version : Joined<"-fmsc-version=">, Group<f_Group>;
|
||||||
def fdelayed_template_parsing : Flag<"-fdelayed-template-parsing">, Group<f_Group>;
|
def fdelayed_template_parsing : Flag<"-fdelayed-template-parsing">, Group<f_Group>;
|
||||||
def fmodule_cache_path : Separate<"-fmodule-cache-path">, Group<i_Group>,
|
def fmodule_cache_path : Separate<"-fmodule-cache-path">, Group<i_Group>,
|
||||||
Flags<[NoForward]>;
|
Flags<[NoForward]>;
|
||||||
|
def fauto_module_import : Flag <"-fauto-module-import">, Group<f_Group>,
|
||||||
|
Flags<[NoForward]>;
|
||||||
|
|
||||||
def fmudflapth : Flag<"-fmudflapth">, Group<f_Group>;
|
def fmudflapth : Flag<"-fmudflapth">, Group<f_Group>;
|
||||||
def fmudflap : Flag<"-fmudflap">, Group<f_Group>;
|
def fmudflap : Flag<"-fmudflap">, Group<f_Group>;
|
||||||
def fnested_functions : Flag<"-fnested-functions">, Group<f_Group>;
|
def fnested_functions : Flag<"-fnested-functions">, Group<f_Group>;
|
||||||
|
|
|
@ -50,6 +50,10 @@ public:
|
||||||
/// record of all macro definitions and
|
/// record of all macro definitions and
|
||||||
/// expansions.
|
/// expansions.
|
||||||
|
|
||||||
|
/// \brief Whether we should automatically translate #include or #import
|
||||||
|
/// operations into module imports when possible.
|
||||||
|
unsigned AutoModuleImport : 1;
|
||||||
|
|
||||||
/// \brief Whether the detailed preprocessing record includes nested macro
|
/// \brief Whether the detailed preprocessing record includes nested macro
|
||||||
/// expansions.
|
/// expansions.
|
||||||
unsigned DetailedRecordIncludesNestedMacroExpansions : 1;
|
unsigned DetailedRecordIncludesNestedMacroExpansions : 1;
|
||||||
|
@ -162,6 +166,7 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PreprocessorOptions() : UsePredefines(true), DetailedRecord(false),
|
PreprocessorOptions() : UsePredefines(true), DetailedRecord(false),
|
||||||
|
AutoModuleImport(false),
|
||||||
DetailedRecordIncludesNestedMacroExpansions(true),
|
DetailedRecordIncludesNestedMacroExpansions(true),
|
||||||
DisablePCHValidation(false), DisableStatCache(false),
|
DisablePCHValidation(false), DisableStatCache(false),
|
||||||
DumpDeserializedPCHDecls(false),
|
DumpDeserializedPCHDecls(false),
|
||||||
|
|
|
@ -140,15 +140,25 @@ public:
|
||||||
/// \param RelativePath If not NULL, will be set to the path relative to
|
/// \param RelativePath If not NULL, will be set to the path relative to
|
||||||
/// SearchPath at which the file was found. This only differs from the
|
/// SearchPath at which the file was found. This only differs from the
|
||||||
/// Filename for framework includes.
|
/// Filename for framework includes.
|
||||||
|
///
|
||||||
|
/// \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.
|
||||||
const FileEntry *LookupFile(StringRef Filename, HeaderSearch &HS,
|
const FileEntry *LookupFile(StringRef Filename, HeaderSearch &HS,
|
||||||
SmallVectorImpl<char> *SearchPath,
|
SmallVectorImpl<char> *SearchPath,
|
||||||
SmallVectorImpl<char> *RelativePath) const;
|
SmallVectorImpl<char> *RelativePath,
|
||||||
|
StringRef BuildingModule,
|
||||||
|
StringRef *SuggestedModule) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const FileEntry *DoFrameworkLookup(
|
const FileEntry *DoFrameworkLookup(
|
||||||
StringRef Filename, HeaderSearch &HS,
|
StringRef Filename, HeaderSearch &HS,
|
||||||
SmallVectorImpl<char> *SearchPath,
|
SmallVectorImpl<char> *SearchPath,
|
||||||
SmallVectorImpl<char> *RelativePath) const;
|
SmallVectorImpl<char> *RelativePath,
|
||||||
|
StringRef BuildingModule,
|
||||||
|
StringRef *SuggestedModule) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,9 @@ class HeaderSearch {
|
||||||
/// \brief The path to the module cache.
|
/// \brief The path to the module cache.
|
||||||
std::string ModuleCachePath;
|
std::string ModuleCachePath;
|
||||||
|
|
||||||
|
/// \brief The name of the module we're building.
|
||||||
|
std::string BuildingModule;
|
||||||
|
|
||||||
/// FileInfo - This contains all of the preprocessor-specific data about files
|
/// FileInfo - This contains all of the preprocessor-specific data about files
|
||||||
/// that are included. The vector is indexed by the FileEntry's UID.
|
/// that are included. The vector is indexed by the FileEntry's UID.
|
||||||
///
|
///
|
||||||
|
@ -196,9 +199,11 @@ public:
|
||||||
//LookupFileCache.clear();
|
//LookupFileCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Set the path to the module cache.
|
/// \brief Set the path to the module cache and the name of the module
|
||||||
void setModuleCachePath(StringRef Path) {
|
/// we're building
|
||||||
ModuleCachePath = Path;
|
void configureModules(StringRef CachePath, StringRef BuildingModule) {
|
||||||
|
ModuleCachePath = CachePath;
|
||||||
|
this->BuildingModule = BuildingModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ClearFileInfo - Forget everything we know about headers so far.
|
/// ClearFileInfo - Forget everything we know about headers so far.
|
||||||
|
@ -240,12 +245,17 @@ public:
|
||||||
/// \param RelativePath If non-null, will be set to the path relative to
|
/// \param RelativePath If non-null, will be set to the path relative to
|
||||||
/// SearchPath at which the file was found. This only differs from the
|
/// SearchPath at which the file was found. This only differs from the
|
||||||
/// Filename for framework includes.
|
/// 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.
|
||||||
const FileEntry *LookupFile(StringRef Filename, bool isAngled,
|
const FileEntry *LookupFile(StringRef Filename, bool isAngled,
|
||||||
const DirectoryLookup *FromDir,
|
const DirectoryLookup *FromDir,
|
||||||
const DirectoryLookup *&CurDir,
|
const DirectoryLookup *&CurDir,
|
||||||
const FileEntry *CurFileEnt,
|
const FileEntry *CurFileEnt,
|
||||||
SmallVectorImpl<char> *SearchPath,
|
SmallVectorImpl<char> *SearchPath,
|
||||||
SmallVectorImpl<char> *RelativePath);
|
SmallVectorImpl<char> *RelativePath,
|
||||||
|
StringRef *SuggestedModule);
|
||||||
|
|
||||||
/// LookupSubframeworkHeader - Look up a subframework for the specified
|
/// LookupSubframeworkHeader - Look up a subframework for the specified
|
||||||
/// #include file. For example, if #include'ing <HIToolbox/HIToolbox.h> from
|
/// #include file. For example, if #include'ing <HIToolbox/HIToolbox.h> from
|
||||||
|
|
|
@ -106,6 +106,7 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
|
||||||
bool KeepComments : 1;
|
bool KeepComments : 1;
|
||||||
bool KeepMacroComments : 1;
|
bool KeepMacroComments : 1;
|
||||||
bool SuppressIncludeNotFoundError : 1;
|
bool SuppressIncludeNotFoundError : 1;
|
||||||
|
bool AutoModuleImport : 1;
|
||||||
|
|
||||||
// State that changes while the preprocessor runs:
|
// State that changes while the preprocessor runs:
|
||||||
bool InMacroArgs : 1; // True if parsing fn macro invocation args.
|
bool InMacroArgs : 1; // True if parsing fn macro invocation args.
|
||||||
|
@ -383,6 +384,11 @@ public:
|
||||||
return SuppressIncludeNotFoundError;
|
return SuppressIncludeNotFoundError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Specify whether automatic module imports are enabled.
|
||||||
|
void setAutoModuleImport(bool AutoModuleImport = true) {
|
||||||
|
this->AutoModuleImport = AutoModuleImport;
|
||||||
|
}
|
||||||
|
|
||||||
/// isCurrentLexer - Return true if we are lexing directly from the specified
|
/// isCurrentLexer - Return true if we are lexing directly from the specified
|
||||||
/// lexer.
|
/// lexer.
|
||||||
bool isCurrentLexer(const PreprocessorLexer *L) const {
|
bool isCurrentLexer(const PreprocessorLexer *L) const {
|
||||||
|
@ -973,7 +979,8 @@ public:
|
||||||
bool isAngled, const DirectoryLookup *FromDir,
|
bool isAngled, const DirectoryLookup *FromDir,
|
||||||
const DirectoryLookup *&CurDir,
|
const DirectoryLookup *&CurDir,
|
||||||
SmallVectorImpl<char> *SearchPath,
|
SmallVectorImpl<char> *SearchPath,
|
||||||
SmallVectorImpl<char> *RelativePath);
|
SmallVectorImpl<char> *RelativePath,
|
||||||
|
StringRef *SuggestedModule);
|
||||||
|
|
||||||
/// GetCurLookup - The DirectoryLookup structure used to find the current
|
/// GetCurLookup - The DirectoryLookup structure used to find the current
|
||||||
/// FileEntry, if CurLexer is non-null and if applicable. This allows us to
|
/// FileEntry, if CurLexer is non-null and if applicable. This allows us to
|
||||||
|
|
|
@ -390,6 +390,8 @@ void Clang::AddPreprocessingOptions(const Driver &D,
|
||||||
CmdArgs.push_back("-fmodule-cache-path");
|
CmdArgs.push_back("-fmodule-cache-path");
|
||||||
CmdArgs.push_back(Args.MakeArgString(DefaultModuleCache));
|
CmdArgs.push_back(Args.MakeArgString(DefaultModuleCache));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Args.AddAllArgs(CmdArgs, options::OPT_fauto_module_import);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
|
/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
|
||||||
|
|
|
@ -228,7 +228,10 @@ void CompilerInstance::createPreprocessor() {
|
||||||
if (!getHeaderSearchOpts().DisableModuleHash)
|
if (!getHeaderSearchOpts().DisableModuleHash)
|
||||||
llvm::sys::path::append(SpecificModuleCache,
|
llvm::sys::path::append(SpecificModuleCache,
|
||||||
getInvocation().getModuleHash());
|
getInvocation().getModuleHash());
|
||||||
PP->getHeaderSearchInfo().setModuleCachePath(SpecificModuleCache);
|
PP->getHeaderSearchInfo().configureModules(SpecificModuleCache,
|
||||||
|
getPreprocessorOpts().ModuleBuildPath.empty()
|
||||||
|
? std::string()
|
||||||
|
: getPreprocessorOpts().ModuleBuildPath.back());
|
||||||
|
|
||||||
// Handle generating dependencies, if requested.
|
// Handle generating dependencies, if requested.
|
||||||
const DependencyOutputOptions &DepOpts = getDependencyOutputOpts();
|
const DependencyOutputOptions &DepOpts = getDependencyOutputOpts();
|
||||||
|
|
|
@ -1753,6 +1753,7 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
|
||||||
Opts.TokenCache = Opts.ImplicitPTHInclude;
|
Opts.TokenCache = Opts.ImplicitPTHInclude;
|
||||||
Opts.UsePredefines = !Args.hasArg(OPT_undef);
|
Opts.UsePredefines = !Args.hasArg(OPT_undef);
|
||||||
Opts.DetailedRecord = Args.hasArg(OPT_detailed_preprocessing_record);
|
Opts.DetailedRecord = Args.hasArg(OPT_detailed_preprocessing_record);
|
||||||
|
Opts.AutoModuleImport = Args.hasArg(OPT_fauto_module_import);
|
||||||
Opts.DisablePCHValidation = Args.hasArg(OPT_fno_validate_pch);
|
Opts.DisablePCHValidation = Args.hasArg(OPT_fno_validate_pch);
|
||||||
|
|
||||||
Opts.DumpDeserializedPCHDecls = Args.hasArg(OPT_dump_deserialized_pch_decls);
|
Opts.DumpDeserializedPCHDecls = Args.hasArg(OPT_dump_deserialized_pch_decls);
|
||||||
|
|
|
@ -710,6 +710,10 @@ void clang::InitializePreprocessor(Preprocessor &PP,
|
||||||
InitializeFileRemapping(PP.getDiagnostics(), PP.getSourceManager(),
|
InitializeFileRemapping(PP.getDiagnostics(), PP.getSourceManager(),
|
||||||
PP.getFileManager(), InitOpts);
|
PP.getFileManager(), InitOpts);
|
||||||
|
|
||||||
|
// Specify whether the preprocessor should replace #include/#import with
|
||||||
|
// module imports when plausible.
|
||||||
|
PP.setAutoModuleImport(InitOpts.AutoModuleImport);
|
||||||
|
|
||||||
// Emit line markers for various builtin sections of the file. We don't do
|
// Emit line markers for various builtin sections of the file. We don't do
|
||||||
// this in asm preprocessor mode, because "# 4" is not a line marker directive
|
// this in asm preprocessor mode, because "# 4" is not a line marker directive
|
||||||
// in this mode.
|
// in this mode.
|
||||||
|
|
|
@ -139,7 +139,8 @@ const FileEntry *HeaderSearch::lookupModule(StringRef ModuleName,
|
||||||
|
|
||||||
// Look for the umbrella header in this directory.
|
// Look for the umbrella header in this directory.
|
||||||
if (const FileEntry *HeaderFile
|
if (const FileEntry *HeaderFile
|
||||||
= SearchDirs[Idx].LookupFile(UmbrellaHeaderName, *this, 0, 0)) {
|
= SearchDirs[Idx].LookupFile(UmbrellaHeaderName, *this, 0, 0,
|
||||||
|
StringRef(), 0)) {
|
||||||
*UmbrellaHeader = HeaderFile->getName();
|
*UmbrellaHeader = HeaderFile->getName();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -173,7 +174,9 @@ const FileEntry *DirectoryLookup::LookupFile(
|
||||||
StringRef Filename,
|
StringRef Filename,
|
||||||
HeaderSearch &HS,
|
HeaderSearch &HS,
|
||||||
SmallVectorImpl<char> *SearchPath,
|
SmallVectorImpl<char> *SearchPath,
|
||||||
SmallVectorImpl<char> *RelativePath) const {
|
SmallVectorImpl<char> *RelativePath,
|
||||||
|
StringRef BuildingModule,
|
||||||
|
StringRef *SuggestedModule) const {
|
||||||
llvm::SmallString<1024> TmpDir;
|
llvm::SmallString<1024> TmpDir;
|
||||||
if (isNormalDir()) {
|
if (isNormalDir()) {
|
||||||
// Concatenate the requested file onto the directory.
|
// Concatenate the requested file onto the directory.
|
||||||
|
@ -192,7 +195,8 @@ const FileEntry *DirectoryLookup::LookupFile(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFramework())
|
if (isFramework())
|
||||||
return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath);
|
return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
|
||||||
|
BuildingModule, SuggestedModule);
|
||||||
|
|
||||||
assert(isHeaderMap() && "Unknown directory lookup");
|
assert(isHeaderMap() && "Unknown directory lookup");
|
||||||
const FileEntry * const Result = getHeaderMap()->LookupFile(
|
const FileEntry * const Result = getHeaderMap()->LookupFile(
|
||||||
|
@ -218,7 +222,10 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(
|
||||||
StringRef Filename,
|
StringRef Filename,
|
||||||
HeaderSearch &HS,
|
HeaderSearch &HS,
|
||||||
SmallVectorImpl<char> *SearchPath,
|
SmallVectorImpl<char> *SearchPath,
|
||||||
SmallVectorImpl<char> *RelativePath) const {
|
SmallVectorImpl<char> *RelativePath,
|
||||||
|
StringRef BuildingModule,
|
||||||
|
StringRef *SuggestedModule) const
|
||||||
|
{
|
||||||
FileManager &FileMgr = HS.getFileMgr();
|
FileManager &FileMgr = HS.getFileMgr();
|
||||||
|
|
||||||
// Framework names must have a '/' in the filename.
|
// Framework names must have a '/' in the filename.
|
||||||
|
@ -280,9 +287,15 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(
|
||||||
SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
|
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());
|
FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
|
||||||
if (const FileEntry *FE = FileMgr.getFile(FrameworkName.str(),
|
if (const FileEntry *FE = FileMgr.getFile(FrameworkName.str(),
|
||||||
/*openFile=*/true)) {
|
/*openFile=*/!AutomaticImport)) {
|
||||||
|
if (AutomaticImport)
|
||||||
|
*SuggestedModule = StringRef(Filename.begin(), SlashPos);
|
||||||
return FE;
|
return FE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,7 +307,11 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(
|
||||||
SearchPath->insert(SearchPath->begin()+OrigSize, Private,
|
SearchPath->insert(SearchPath->begin()+OrigSize, Private,
|
||||||
Private+strlen(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 FileEntry *HeaderSearch::LookupFile(
|
||||||
const DirectoryLookup *&CurDir,
|
const DirectoryLookup *&CurDir,
|
||||||
const FileEntry *CurFileEnt,
|
const FileEntry *CurFileEnt,
|
||||||
SmallVectorImpl<char> *SearchPath,
|
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 'Filename' is absolute, check to see if it exists and no searching.
|
||||||
if (llvm::sys::path::is_absolute(Filename)) {
|
if (llvm::sys::path::is_absolute(Filename)) {
|
||||||
CurDir = 0;
|
CurDir = 0;
|
||||||
|
@ -400,7 +422,8 @@ const FileEntry *HeaderSearch::LookupFile(
|
||||||
// Check each directory in sequence to see if it contains this file.
|
// Check each directory in sequence to see if it contains this file.
|
||||||
for (; i != SearchDirs.size(); ++i) {
|
for (; i != SearchDirs.size(); ++i) {
|
||||||
const FileEntry *FE =
|
const FileEntry *FE =
|
||||||
SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath);
|
SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath,
|
||||||
|
BuildingModule, SuggestedModule);
|
||||||
if (!FE) continue;
|
if (!FE) continue;
|
||||||
|
|
||||||
CurDir = &SearchDirs[i];
|
CurDir = &SearchDirs[i];
|
||||||
|
@ -439,7 +462,8 @@ const FileEntry *HeaderSearch::LookupFile(
|
||||||
|
|
||||||
const FileEntry *Result = LookupFile(ScratchFilename, /*isAngled=*/true,
|
const FileEntry *Result = LookupFile(ScratchFilename, /*isAngled=*/true,
|
||||||
FromDir, CurDir, CurFileEnt,
|
FromDir, CurDir, CurFileEnt,
|
||||||
SearchPath, RelativePath);
|
SearchPath, RelativePath,
|
||||||
|
SuggestedModule);
|
||||||
std::pair<unsigned, unsigned> &CacheLookup
|
std::pair<unsigned, unsigned> &CacheLookup
|
||||||
= LookupFileCache.GetOrCreateValue(Filename).getValue();
|
= LookupFileCache.GetOrCreateValue(Filename).getValue();
|
||||||
CacheLookup.second
|
CacheLookup.second
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "clang/Lex/MacroInfo.h"
|
#include "clang/Lex/MacroInfo.h"
|
||||||
#include "clang/Lex/LexDiagnostic.h"
|
#include "clang/Lex/LexDiagnostic.h"
|
||||||
#include "clang/Lex/CodeCompletionHandler.h"
|
#include "clang/Lex/CodeCompletionHandler.h"
|
||||||
|
#include "clang/Lex/ModuleLoader.h"
|
||||||
#include "clang/Lex/Pragma.h"
|
#include "clang/Lex/Pragma.h"
|
||||||
#include "clang/Basic/FileManager.h"
|
#include "clang/Basic/FileManager.h"
|
||||||
#include "clang/Basic/SourceManager.h"
|
#include "clang/Basic/SourceManager.h"
|
||||||
|
@ -478,7 +479,8 @@ const FileEntry *Preprocessor::LookupFile(
|
||||||
const DirectoryLookup *FromDir,
|
const DirectoryLookup *FromDir,
|
||||||
const DirectoryLookup *&CurDir,
|
const DirectoryLookup *&CurDir,
|
||||||
SmallVectorImpl<char> *SearchPath,
|
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
|
// If the header lookup mechanism may be relative to the current file, pass in
|
||||||
// info about where the current file is.
|
// info about where the current file is.
|
||||||
const FileEntry *CurFileEnt = 0;
|
const FileEntry *CurFileEnt = 0;
|
||||||
|
@ -502,12 +504,13 @@ const FileEntry *Preprocessor::LookupFile(
|
||||||
CurDir = CurDirLookup;
|
CurDir = CurDirLookup;
|
||||||
const FileEntry *FE = HeaderInfo.LookupFile(
|
const FileEntry *FE = HeaderInfo.LookupFile(
|
||||||
Filename, isAngled, FromDir, CurDir, CurFileEnt,
|
Filename, isAngled, FromDir, CurDir, CurFileEnt,
|
||||||
SearchPath, RelativePath);
|
SearchPath, RelativePath, SuggestedModule);
|
||||||
if (FE) return FE;
|
if (FE) return FE;
|
||||||
|
|
||||||
// Otherwise, see if this is a subframework header. If so, this is relative
|
// 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
|
// 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.
|
// headers on the #include stack and pass them to HeaderInfo.
|
||||||
|
// FIXME: SuggestedModule!
|
||||||
if (IsFileLexer()) {
|
if (IsFileLexer()) {
|
||||||
if ((CurFileEnt = SourceMgr.getFileEntryForID(CurPPLexer->getFileID())))
|
if ((CurFileEnt = SourceMgr.getFileEntryForID(CurPPLexer->getFileID())))
|
||||||
if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt,
|
if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt,
|
||||||
|
@ -1214,9 +1217,20 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
|
||||||
llvm::SmallString<1024> RelativePath;
|
llvm::SmallString<1024> RelativePath;
|
||||||
// We get the raw path only if we have 'Callbacks' to which we later pass
|
// We get the raw path only if we have 'Callbacks' to which we later pass
|
||||||
// the path.
|
// the path.
|
||||||
|
StringRef SuggestedModule;
|
||||||
const FileEntry *File = LookupFile(
|
const FileEntry *File = LookupFile(
|
||||||
Filename, isAngled, LookupFrom, CurDir,
|
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.
|
// Notify the callback object that we've seen an inclusion directive.
|
||||||
if (Callbacks)
|
if (Callbacks)
|
||||||
|
|
|
@ -785,7 +785,7 @@ static bool EvaluateHasIncludeCommon(Token &Tok,
|
||||||
// Search include directories.
|
// Search include directories.
|
||||||
const DirectoryLookup *CurDir;
|
const DirectoryLookup *CurDir;
|
||||||
const FileEntry *File =
|
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.
|
// Get the result value. Result = true means the file exists.
|
||||||
bool Result = File != 0;
|
bool Result = File != 0;
|
||||||
|
|
|
@ -366,7 +366,8 @@ void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
|
||||||
|
|
||||||
// Search include directories for this file.
|
// Search include directories for this file.
|
||||||
const DirectoryLookup *CurDir;
|
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 (File == 0) {
|
||||||
if (!SuppressIncludeNotFoundError)
|
if (!SuppressIncludeNotFoundError)
|
||||||
Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
|
Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
|
||||||
|
|
|
@ -133,6 +133,7 @@ void Preprocessor::Initialize(const TargetInfo &Target) {
|
||||||
KeepComments = false;
|
KeepComments = false;
|
||||||
KeepMacroComments = false;
|
KeepMacroComments = false;
|
||||||
SuppressIncludeNotFoundError = false;
|
SuppressIncludeNotFoundError = false;
|
||||||
|
AutoModuleImport = false;
|
||||||
|
|
||||||
// Macro expansion is enabled.
|
// Macro expansion is enabled.
|
||||||
DisableMacroExpansion = false;
|
DisableMacroExpansion = false;
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
#include <Module/Module.h>
|
||||||
|
|
||||||
|
#define DEPENDS_ON_MODULE 1
|
|
@ -9,3 +9,4 @@ const char *getModuleVersion(void);
|
||||||
+alloc;
|
+alloc;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
#define MODULE_H_MACRO 1
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
// RUN: rm -rf %t
|
||||||
|
// RUN: %clang_cc1 -x objective-c -fmodule-cache-path %t -fauto-module-import -F %S/Inputs -verify %s
|
||||||
|
|
||||||
|
#include <DependsOnModule/DependsOnModule.h>
|
||||||
|
|
||||||
|
#ifdef MODULE_H_MACRO
|
||||||
|
# error MODULE_H_MACRO should have been hidden
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEPENDS_ON_MODULE
|
||||||
|
# error DEPENDS_ON_MODULE should have been hidden
|
||||||
|
#endif
|
Loading…
Reference in New Issue