]> granicus.if.org Git - clang/commitdiff
Thread a TargetInfo through to the module map; we'll need it for
authorDouglas Gregor <dgregor@apple.com>
Mon, 30 Jan 2012 06:01:29 +0000 (06:01 +0000)
committerDouglas Gregor <dgregor@apple.com>
Mon, 30 Jan 2012 06:01:29 +0000 (06:01 +0000)
target-specific module requirements.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149224 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
include/clang/Basic/Module.h
include/clang/Lex/HeaderSearch.h
include/clang/Lex/ModuleMap.h
lib/Basic/Module.cpp
lib/Frontend/ASTUnit.cpp
lib/Frontend/CompilerInstance.cpp
lib/Frontend/FrontendActions.cpp
lib/Lex/HeaderSearch.cpp
lib/Lex/ModuleMap.cpp
lib/Lex/Preprocessor.cpp
lib/Serialization/ASTReader.cpp
unittests/Basic/SourceManagerTest.cpp
unittests/Lex/LexerTest.cpp

index e75f43e0e94e20c9b61831178ae04e4835a24e09..82dbd5b0c02d65e574457bbbfb946cddee55839d 100644 (file)
@@ -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.
   ///
index c5969489f51d5604c4094f11e4421dff2509b423..84bb37da3a485b39a9668a52382832e8250d5d85 100644 (file)
@@ -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.
   ///
index 3e794f5c0094ef1147c3da06077dd49aa0aa71b7..6176ed8c30aa71f72bd28e357eb4d15d0c198863 100644 (file)
@@ -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.
index 015f421f9db65d56d2f276aa1046a730ee33ab10..3052532650ea6fc8683273956fc9f757b71c3c3f 100644 (file)
@@ -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)
index abeb3174bd39c4c99101f6f69f85807b56400885..ff75e3a4f25715a8fd26befaf2b0609f1d8989d7 100644 (file)
@@ -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;
index e8afe6dba1f4cda378d9dda9051c0942d0448a66..1501da4ff4c607f290024a3b1ac0978bb0d4358f 100644 (file)
@@ -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
index 669fe4acb372ac14cb614da8c66dfbcbdaf1528b..c0302329c1e290fae2cb29a95e30b70ab31b9ed5 100644 (file)
@@ -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;
index e56eb6c915ca3a1222ad5745e7409f31587a3e2d..e3a6c52ff4debc5caf55b12d6ce03ecf5e1c9ddf 100644 (file)
@@ -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.
index 708da94585604e57ab50b44b0a977959745ca4e0..3583b034d53873393b0ca993d8526d43f6bb2b1a 100644 (file)
@@ -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)
index 05cbffdfd129b4a98b258a79371f34132df8d673..fc6efb606890d41fca5b802e5a50c4a509d8a3a1 100644 (file)
@@ -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) {
index 71734027bfb17aa76f04efc6b1b89e4fa9a3fad6..0bf1da75be4ccf82b371216ab3f9a6bef5d16f5b 100644 (file)
@@ -3307,7 +3307,8 @@ ASTReader::ASTReadResult ASTReader::ReadSubmoduleBlock(ModuleFile &F) {
         break;
 
       CurrentModule->addRequirement(StringRef(BlobStart, BlobLen), 
-                                    Context.getLangOptions());
+                                    Context.getLangOptions(),
+                                    Context.getTargetInfo());
       break;
     }
     }
index 2dd64f9ac69af7cec113dcef110f0a27f80fa9f2..1b067b0d0bfa26674134ad659c92d9bd9c464ba8 100644 (file)
@@ -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,
index de94d1d0164eaf12f4e14233bfd275578066eae2..2742f66663bd8756b8d1e80e02d5a9bb22254896 100644 (file)
@@ -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,