aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-01-30 06:01:29 +0000
committerDouglas Gregor <dgregor@apple.com>2012-01-30 06:01:29 +0000
commitdc58aa71026cce539ca9b5c2c52cc4efc7bd77fe (patch)
tree6ced169a86aa0072e25c83227aa56b7dc75199e1
parentadd5adb9aa5facc1cd170fc9dacbd58cde028025 (diff)
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
-rw-r--r--include/clang/Basic/Module.h13
-rw-r--r--include/clang/Lex/HeaderSearch.h6
-rw-r--r--include/clang/Lex/ModuleMap.h12
-rw-r--r--lib/Basic/Module.cpp13
-rw-r--r--lib/Frontend/ASTUnit.cpp3
-rw-r--r--lib/Frontend/CompilerInstance.cpp5
-rw-r--r--lib/Frontend/FrontendActions.cpp2
-rw-r--r--lib/Lex/HeaderSearch.cpp9
-rw-r--r--lib/Lex/ModuleMap.cpp13
-rw-r--r--lib/Lex/Preprocessor.cpp4
-rw-r--r--lib/Serialization/ASTReader.cpp3
-rw-r--r--unittests/Basic/SourceManagerTest.cpp4
-rw-r--r--unittests/Lex/LexerTest.cpp2
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<std::pair<std::string, SourceLocation>, 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 <foo> 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<DiagnosticsEngine> 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<bool>(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<const DirectoryEntry *>();
}
-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<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
Diags = llvm::IntrusiveRefCntPtr<DiagnosticsEngine>(
@@ -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<const FileEntry *, Module *>::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,