From dc58aa71026cce539ca9b5c2c52cc4efc7bd77fe Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 30 Jan 2012 06:01:29 +0000 Subject: [PATCH] Thread a TargetInfo through to the module map; we'll need it for target-specific module requirements. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149224 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/Module.h | 13 +++++++++++-- include/clang/Lex/HeaderSearch.h | 6 +++++- include/clang/Lex/ModuleMap.h | 12 +++++++++--- lib/Basic/Module.cpp | 13 ++++++++----- lib/Frontend/ASTUnit.cpp | 3 ++- lib/Frontend/CompilerInstance.cpp | 5 +++-- lib/Frontend/FrontendActions.cpp | 2 +- lib/Lex/HeaderSearch.cpp | 9 +++++++-- lib/Lex/ModuleMap.cpp | 13 ++++++++++--- lib/Lex/Preprocessor.cpp | 4 +++- lib/Serialization/ASTReader.cpp | 3 ++- unittests/Basic/SourceManagerTest.cpp | 4 ++-- unittests/Lex/LexerTest.cpp | 2 +- 13 files changed, 64 insertions(+), 25 deletions(-) diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h index e75f43e0e9..82dbd5b0c0 100644 --- a/include/clang/Basic/Module.h +++ b/include/clang/Basic/Module.h @@ -33,6 +33,7 @@ namespace clang { class DirectoryEntry; class FileEntry; class LangOptions; +class TargetInfo; /// \brief Describes the name of a module. typedef llvm::SmallVector, 2> @@ -178,10 +179,14 @@ public: /// \param LangOpts The language options used for the current /// translation unit. /// + /// \param Target The target options used for the current translation unit. + /// /// \param Feature If this module is unavailable, this parameter /// will be set to one of the features that is required for use of /// this module (but is not available). - bool isAvailable(const LangOptions &LangOpts, StringRef &Feature) const; + bool isAvailable(const LangOptions &LangOpts, + const TargetInfo &Target, + StringRef &Feature) const; /// \brief Determine whether this module is a submodule. bool isSubModule() const { return Parent != 0; } @@ -246,7 +251,11 @@ public: /// /// \param LangOpts The set of language options that will be used to /// evaluate the availability of this feature. - void addRequirement(StringRef Feature, const LangOptions &LangOpts); + /// + /// \param Target The target options that will be used to evaluate the + /// availability of this feature. + void addRequirement(StringRef Feature, const LangOptions &LangOpts, + const TargetInfo &Target); /// \brief Find the submodule with the given name. /// diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index c5969489f5..84bb37da3a 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -189,7 +189,7 @@ class HeaderSearch { public: HeaderSearch(FileManager &FM, DiagnosticsEngine &Diags, - const LangOptions &LangOpts); + const LangOptions &LangOpts, const TargetInfo *Target); ~HeaderSearch(); FileManager &getFileMgr() const { return FileMgr; } @@ -243,6 +243,10 @@ public: ExternalSource = ES; } + /// \brief Set the target information for the header search, if not + /// already known. + void setTarget(const TargetInfo &Target); + /// LookupFile - Given a "foo" or reference, look up the indicated file, /// return null on failure. /// diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h index 3e794f5c00..6176ed8c30 100644 --- a/include/clang/Lex/ModuleMap.h +++ b/include/clang/Lex/ModuleMap.h @@ -39,7 +39,8 @@ class ModuleMap { SourceManager *SourceMgr; llvm::IntrusiveRefCntPtr Diags; const LangOptions &LangOpts; - + const TargetInfo *Target; + /// \brief Language options used to parse the module map itself. /// /// These are always simple C language options. @@ -89,13 +90,18 @@ public: /// diagnostics. /// /// \param LangOpts Language options for this translation unit. + /// + /// \param Target The target for this translation unit. ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC, - const LangOptions &LangOpts); + const LangOptions &LangOpts, const TargetInfo *Target); /// \brief Destroy the module map. /// ~ModuleMap(); - + + /// \brief Set the target information. + void setTarget(const TargetInfo &Target); + /// \brief Retrieve the module that owns the given header file, if any. /// /// \param File The header file that is likely to be included. diff --git a/lib/Basic/Module.cpp b/lib/Basic/Module.cpp index 015f421f9d..3052532650 100644 --- a/lib/Basic/Module.cpp +++ b/lib/Basic/Module.cpp @@ -47,7 +47,8 @@ Module::~Module() { /// \brief Determine whether a translation unit built using the current /// language options has the given feature. -static bool hasFeature(StringRef Feature, const LangOptions &LangOpts) { +static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, + const TargetInfo &Target) { return llvm::StringSwitch(Feature) .Case("blocks", LangOpts.Blocks) .Case("cplusplus", LangOpts.CPlusPlus) @@ -58,13 +59,14 @@ static bool hasFeature(StringRef Feature, const LangOptions &LangOpts) { } bool -Module::isAvailable(const LangOptions &LangOpts, StringRef &Feature) const { +Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, + StringRef &Feature) const { if (IsAvailable) return true; for (const Module *Current = this; Current; Current = Current->Parent) { for (unsigned I = 0, N = Current->Requires.size(); I != N; ++I) { - if (!hasFeature(Current->Requires[I], LangOpts)) { + if (!hasFeature(Current->Requires[I], LangOpts, Target)) { Feature = Current->Requires[I]; return false; } @@ -121,11 +123,12 @@ const DirectoryEntry *Module::getUmbrellaDir() const { return Umbrella.dyn_cast(); } -void Module::addRequirement(StringRef Feature, const LangOptions &LangOpts) { +void Module::addRequirement(StringRef Feature, const LangOptions &LangOpts, + const TargetInfo &Target) { Requires.push_back(Feature); // If this feature is currently available, we're done. - if (hasFeature(Feature, LangOpts)) + if (hasFeature(Feature, LangOpts, Target)) return; if (!IsAvailable) diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index abeb3174bd..ff75e3a4f2 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -673,7 +673,8 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, AST->getFileManager()); AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager(), AST->getDiagnostics(), - AST->ASTFileLangOpts)); + AST->ASTFileLangOpts, + /*Target=*/0)); for (unsigned I = 0; I != NumRemappedFiles; ++I) { FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index e8afe6dba1..1501da4ff4 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -242,7 +242,8 @@ void CompilerInstance::createPreprocessor() { // Create the Preprocessor. HeaderSearch *HeaderInfo = new HeaderSearch(getFileManager(), getDiagnostics(), - getLangOpts()); + getLangOpts(), + &getTarget()); PP = new Preprocessor(getDiagnostics(), getLangOpts(), &getTarget(), getSourceManager(), *HeaderInfo, *this, PTHMgr, /*OwnsHeaderSearch=*/true); @@ -1045,7 +1046,7 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc, // Check whether this module is available. StringRef Feature; - if (!Module->isAvailable(getLangOpts(), Feature)) { + if (!Module->isAvailable(getLangOpts(), getTarget(), Feature)) { getDiagnostics().Report(ImportLoc, diag::err_module_unavailable) << Module->getFullModuleName() << Feature diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp index 669fe4acb3..c0302329c1 100644 --- a/lib/Frontend/FrontendActions.cpp +++ b/lib/Frontend/FrontendActions.cpp @@ -237,7 +237,7 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, // Check whether we can build this module at all. StringRef Feature; - if (!Module->isAvailable(CI.getLangOpts(), Feature)) { + if (!Module->isAvailable(CI.getLangOpts(), CI.getTarget(), Feature)) { CI.getDiagnostics().Report(diag::err_module_unavailable) << Module->getFullModuleName() << Feature; diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp index e56eb6c915..e3a6c52ff4 100644 --- a/lib/Lex/HeaderSearch.cpp +++ b/lib/Lex/HeaderSearch.cpp @@ -39,9 +39,10 @@ HeaderFileInfo::getControllingMacro(ExternalIdentifierLookup *External) { ExternalHeaderFileInfoSource::~ExternalHeaderFileInfoSource() {} HeaderSearch::HeaderSearch(FileManager &FM, DiagnosticsEngine &Diags, - const LangOptions &LangOpts) + const LangOptions &LangOpts, + const TargetInfo *Target) : FileMgr(FM), Diags(Diags), FrameworkMap(64), - ModMap(FileMgr, *Diags.getClient(), LangOpts) + ModMap(FileMgr, *Diags.getClient(), LangOpts, Target) { AngledDirIdx = 0; SystemDirIdx = 0; @@ -365,6 +366,10 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup( return FE; } +void HeaderSearch::setTarget(const TargetInfo &Target) { + ModMap.setTarget(Target); +} + //===----------------------------------------------------------------------===// // Header File Location. diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp index 708da94585..3583b034d5 100644 --- a/lib/Lex/ModuleMap.cpp +++ b/lib/Lex/ModuleMap.cpp @@ -70,8 +70,8 @@ ModuleMap::resolveExport(Module *Mod, } ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC, - const LangOptions &LangOpts) - : LangOpts(LangOpts) + const LangOptions &LangOpts, const TargetInfo *Target) + : LangOpts(LangOpts), Target(Target) { llvm::IntrusiveRefCntPtr DiagIDs(new DiagnosticIDs); Diags = llvm::IntrusiveRefCntPtr( @@ -90,6 +90,12 @@ ModuleMap::~ModuleMap() { delete SourceMgr; } +void ModuleMap::setTarget(const TargetInfo &Target) { + assert((!this->Target || this->Target == &Target) && + "Improper target override"); + this->Target = &Target; +} + Module *ModuleMap::findModuleForHeader(const FileEntry *File) { llvm::DenseMap::iterator Known = Headers.find(File); @@ -992,7 +998,7 @@ void ModuleMapParser::parseRequiresDecl() { consumeToken(); // Add this feature. - ActiveModule->addRequirement(Feature, Map.LangOpts); + ActiveModule->addRequirement(Feature, Map.LangOpts, *Map.Target); if (!Tok.is(MMToken::Comma)) break; @@ -1360,6 +1366,7 @@ bool ModuleMapParser::parseModuleMapFile() { } bool ModuleMap::parseModuleMapFile(const FileEntry *File) { + assert(Target != 0 && "Missing target information"); FileID ID = SourceMgr->createFileID(File, SourceLocation(), SrcMgr::C_User); const llvm::MemoryBuffer *Buffer = SourceMgr->getBuffer(ID); if (!Buffer) diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp index 05cbffdfd1..fc6efb6068 100644 --- a/lib/Lex/Preprocessor.cpp +++ b/lib/Lex/Preprocessor.cpp @@ -167,7 +167,9 @@ void Preprocessor::Initialize(const TargetInfo &Target) { Ident__exception_info = Ident__exception_code = Ident__abnormal_termination = 0; Ident___exception_info = Ident___exception_code = Ident___abnormal_termination = 0; Ident_GetExceptionInfo = Ident_GetExceptionCode = Ident_AbnormalTermination = 0; - } + } + + HeaderInfo.setTarget(Target); } void Preprocessor::setPTHManager(PTHManager* pm) { diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 71734027bf..0bf1da75be 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -3307,7 +3307,8 @@ ASTReader::ASTReadResult ASTReader::ReadSubmoduleBlock(ModuleFile &F) { break; CurrentModule->addRequirement(StringRef(BlobStart, BlobLen), - Context.getLangOptions()); + Context.getLangOptions(), + Context.getTargetInfo()); break; } } diff --git a/unittests/Basic/SourceManagerTest.cpp b/unittests/Basic/SourceManagerTest.cpp index 2dd64f9ac6..1b067b0d0b 100644 --- a/unittests/Basic/SourceManagerTest.cpp +++ b/unittests/Basic/SourceManagerTest.cpp @@ -63,7 +63,7 @@ TEST_F(SourceManagerTest, isBeforeInTranslationUnit) { FileID mainFileID = SourceMgr.createMainFileIDForMemBuffer(buf); VoidModuleLoader ModLoader; - HeaderSearch HeaderInfo(FileMgr, Diags, LangOpts); + HeaderSearch HeaderInfo(FileMgr, Diags, LangOpts, &*Target); Preprocessor PP(Diags, LangOpts, Target.getPtr(), SourceMgr, HeaderInfo, ModLoader, @@ -130,7 +130,7 @@ TEST_F(SourceManagerTest, getMacroArgExpandedLocation) { SourceMgr.overrideFileContents(headerFile, headerBuf); VoidModuleLoader ModLoader; - HeaderSearch HeaderInfo(FileMgr, Diags, LangOpts); + HeaderSearch HeaderInfo(FileMgr, Diags, LangOpts, &*Target); Preprocessor PP(Diags, LangOpts, Target.getPtr(), SourceMgr, HeaderInfo, ModLoader, diff --git a/unittests/Lex/LexerTest.cpp b/unittests/Lex/LexerTest.cpp index de94d1d016..2742f66663 100644 --- a/unittests/Lex/LexerTest.cpp +++ b/unittests/Lex/LexerTest.cpp @@ -69,7 +69,7 @@ TEST_F(LexerTest, LexAPI) { SourceMgr.createMainFileIDForMemBuffer(buf); VoidModuleLoader ModLoader; - HeaderSearch HeaderInfo(FileMgr, Diags, LangOpts); + HeaderSearch HeaderInfo(FileMgr, Diags, LangOpts, &*Target); Preprocessor PP(Diags, LangOpts, Target.getPtr(), SourceMgr, HeaderInfo, ModLoader, -- 2.40.0