diff options
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSerializationKinds.td | 10 | ||||
-rw-r--r-- | clang/include/clang/Basic/TargetInfo.h | 4 | ||||
-rw-r--r-- | clang/include/clang/Basic/TargetOptions.h | 6 | ||||
-rw-r--r-- | clang/include/clang/Frontend/ASTUnit.h | 9 | ||||
-rw-r--r-- | clang/include/clang/Frontend/CompilerInvocation.h | 16 | ||||
-rw-r--r-- | clang/include/clang/Serialization/ASTReader.h | 14 | ||||
-rw-r--r-- | clang/lib/Basic/Targets.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Frontend/ASTUnit.cpp | 32 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 85 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 30 | ||||
-rw-r--r-- | clang/test/PCH/target-options.c | 5 | ||||
-rw-r--r-- | clang/test/PCH/target-options.h | 2 |
13 files changed, 156 insertions, 83 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/clang/include/clang/Basic/DiagnosticSerializationKinds.td index a440e806d73..435760bb878 100644 --- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td +++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td @@ -25,9 +25,13 @@ def err_fe_pch_file_modified : Error< def err_fe_pch_file_overridden : Error< "file '%0' from the precompiled header has been overridden">; -def warn_pch_target_triple : Error< - "PCH file was compiled for the target '%0' but the current translation " - "unit is being compiled for target '%1'">; +def err_pch_targetopt_mismatch : Error< + "PCH file was compiled for the %0 '%1' but the current translation " + "unit is being compiled for target '%2'">; +def err_pch_targetopt_feature_mismatch : Error< + "%select{AST file|current translation unit}0 was compiled with the target " + "feature'%1' but the %select{current translation unit is|AST file was}0 " + "not">; def err_pch_langopt_mismatch : Error<"%0 was %select{disabled|enabled}1 in " "PCH file but is currently %select{disabled|enabled}2">; def err_pch_langopt_value_mismatch : Error< diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 3e63505dfa6..ea520e8f828 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -23,6 +23,7 @@ #include "llvm/ADT/Triple.h" #include "llvm/Support/DataTypes.h" #include "clang/Basic/AddressSpaces.h" +#include "clang/Basic/TargetOptions.h" #include "clang/Basic/VersionTuple.h" #include "clang/Basic/Specifiers.h" #include <cassert> @@ -39,7 +40,6 @@ class LangOptions; class MacroBuilder; class SourceLocation; class SourceManager; -class TargetOptions; namespace Builtin { struct Info; } @@ -62,7 +62,7 @@ enum TargetCXXABI { /// \brief Exposes information about the current target. /// class TargetInfo : public RefCountedBase<TargetInfo> { - TargetOptions *TargetOpts; + llvm::IntrusiveRefCntPtr<TargetOptions> TargetOpts; llvm::Triple Triple; protected: // Target values set by the ctor of the actual target implementation. Default diff --git a/clang/include/clang/Basic/TargetOptions.h b/clang/include/clang/Basic/TargetOptions.h index 15ececd1df5..d6deb0244d9 100644 --- a/clang/include/clang/Basic/TargetOptions.h +++ b/clang/include/clang/Basic/TargetOptions.h @@ -15,13 +15,14 @@ #ifndef LLVM_CLANG_FRONTEND_TARGETOPTIONS_H #define LLVM_CLANG_FRONTEND_TARGETOPTIONS_H +#include "llvm/ADT/IntrusiveRefCntPtr.h" #include <string> #include <vector> namespace clang { /// \brief Options for controlling the target. -class TargetOptions { +class TargetOptions : public RefCountedBase<TargetOptions> { public: /// If given, the name of the target triple to compile for. If not given the /// target will be selected to match the host. @@ -40,6 +41,9 @@ public: /// If given, the version string of the linker in use. std::string LinkerVersion; + /// \brief The list of target specific features to enable or disable, as written on the command line. + std::vector<std::string> FeaturesAsWritten; + /// The list of target specific features to enable or disable -- this should /// be a list of strings starting with by '+' or '-'. std::vector<std::string> Features; diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h index 0b02afa19d1..c2bde120a03 100644 --- a/clang/include/clang/Frontend/ASTUnit.h +++ b/clang/include/clang/Frontend/ASTUnit.h @@ -71,8 +71,8 @@ private: IntrusiveRefCntPtr<TargetInfo> Target; IntrusiveRefCntPtr<Preprocessor> PP; IntrusiveRefCntPtr<ASTContext> Ctx; + IntrusiveRefCntPtr<TargetOptions> TargetOpts; ASTReader *Reader; - TargetOptions TargetOpts; struct ASTWriterData; OwningPtr<ASTWriterData> WriterData; @@ -91,13 +91,6 @@ private: /// LoadFromCommandLine available. IntrusiveRefCntPtr<CompilerInvocation> Invocation; - /// \brief The set of target features. - /// - /// FIXME: each time we reparse, we need to restore the set of target - /// features from this vector, because TargetInfo::CreateTargetInfo() - /// mangles the target options in place. Yuck! - std::vector<std::string> TargetFeatures; - // OnlyLocalDecls - when true, walking this AST should only visit declarations // that come from the AST itself, not from included precompiled headers. // FIXME: This is temporary; eventually, CIndex will always do this. diff --git a/clang/include/clang/Frontend/CompilerInvocation.h b/clang/include/clang/Frontend/CompilerInvocation.h index 30c96cbb339..a58fef1f4b6 100644 --- a/clang/include/clang/Frontend/CompilerInvocation.h +++ b/clang/include/clang/Frontend/CompilerInvocation.h @@ -52,6 +52,9 @@ class CompilerInvocationBase : public RefCountedBase<CompilerInvocation> { protected: /// Options controlling the language variant. IntrusiveRefCntPtr<LangOptions> LangOpts; + + /// Options controlling the target. + IntrusiveRefCntPtr<TargetOptions> TargetOpts; public: CompilerInvocationBase(); @@ -59,6 +62,11 @@ public: LangOptions *getLangOpts() { return LangOpts.getPtr(); } const LangOptions *getLangOpts() const { return LangOpts.getPtr(); } + + TargetOptions &getTargetOpts() { return *TargetOpts.getPtr(); } + const TargetOptions &getTargetOpts() const { + return *TargetOpts.getPtr(); + } }; /// \brief Helper class for holding the data necessary to invoke the compiler. @@ -96,9 +104,6 @@ class CompilerInvocation : public CompilerInvocationBase { /// Options controlling preprocessed output. PreprocessorOutputOptions PreprocessorOutputOpts; - /// Options controlling the target. - TargetOptions TargetOpts; - public: CompilerInvocation() : AnalyzerOpts(new AnalyzerOptions()) {} @@ -199,11 +204,6 @@ public: return PreprocessorOutputOpts; } - TargetOptions &getTargetOpts() { return TargetOpts; } - const TargetOptions &getTargetOpts() const { - return TargetOpts; - } - /// @} }; diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index d23e7c5bf43..02e9927dbea 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -82,6 +82,7 @@ class ASTStmtReader; class TypeLocReader; struct HeaderFileInfo; class VersionTuple; +class TargetOptions; struct PCHPredefinesBlock { /// \brief The file ID for this predefines buffer in a PCH file. @@ -110,11 +111,12 @@ public: return false; } - /// \brief Receives the target triple. + /// \brief Receives the target options. /// - /// \returns true to indicate the target triple is invalid or false otherwise. - virtual bool ReadTargetTriple(const serialization::ModuleFile &M, - StringRef Triple) { + /// \returns true to indicate the target options are invalid, or false + /// otherwise. + virtual bool ReadTargetOptions(const serialization::ModuleFile &M, + const TargetOptions &TargetOpts) { return false; } @@ -158,8 +160,8 @@ public: virtual bool ReadLanguageOptions(const serialization::ModuleFile &M, const LangOptions &LangOpts); - virtual bool ReadTargetTriple(const serialization::ModuleFile &M, - StringRef Triple); + virtual bool ReadTargetOptions(const serialization::ModuleFile &M, + const TargetOptions &TargetOpts); virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, StringRef OriginalFileName, std::string &SuggestedPredefines, diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 2e6678bb898..cd835023ab2 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -4635,8 +4635,10 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, // Apply the user specified deltas. // First the enables. - for (std::vector<std::string>::const_iterator it = Opts.Features.begin(), - ie = Opts.Features.end(); it != ie; ++it) { + for (std::vector<std::string>::const_iterator + it = Opts.FeaturesAsWritten.begin(), + ie = Opts.FeaturesAsWritten.end(); + it != ie; ++it) { const char *Name = it->c_str(); if (Name[0] != '+') @@ -4650,8 +4652,10 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, } // Then the disables. - for (std::vector<std::string>::const_iterator it = Opts.Features.begin(), - ie = Opts.Features.end(); it != ie; ++it) { + for (std::vector<std::string>::const_iterator + it = Opts.FeaturesAsWritten.begin(), + ie = Opts.FeaturesAsWritten.end(); + it != ie; ++it) { const char *Name = it->c_str(); if (Name[0] == '+') diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index e602d30374b..bf78ac51ec6 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -503,7 +503,7 @@ class ASTInfoCollector : public ASTReaderListener { ASTContext &Context; LangOptions &LangOpt; HeaderSearch &HSI; - TargetOptions &TargetOpts; + IntrusiveRefCntPtr<TargetOptions> &TargetOpts; IntrusiveRefCntPtr<TargetInfo> &Target; std::string &Predefines; unsigned &Counter; @@ -513,7 +513,8 @@ class ASTInfoCollector : public ASTReaderListener { bool InitializedLanguage; public: ASTInfoCollector(Preprocessor &PP, ASTContext &Context, LangOptions &LangOpt, - HeaderSearch &HSI, TargetOptions &TargetOpts, + HeaderSearch &HSI, + IntrusiveRefCntPtr<TargetOptions> &TargetOpts, IntrusiveRefCntPtr<TargetInfo> &Target, std::string &Predefines, unsigned &Counter) @@ -536,21 +537,18 @@ public: return false; } - virtual bool ReadTargetTriple(const serialization::ModuleFile &M, - StringRef Triple) { + virtual bool ReadTargetOptions(const serialization::ModuleFile &M, + const TargetOptions &TargetOpts) { // If we've already initialized the target, don't do it again. if (Target) return false; assert(M.Kind == serialization::MK_MainFile); - // FIXME: This is broken, we should store the TargetOptions in the AST file. - TargetOpts.ABI = ""; - TargetOpts.CXXABI = ""; - TargetOpts.CPU = ""; - TargetOpts.Features.clear(); - TargetOpts.Triple = Triple; - Target = TargetInfo::CreateTargetInfo(PP.getDiagnostics(), TargetOpts); + + this->TargetOpts = new TargetOptions(TargetOpts); + Target = TargetInfo::CreateTargetInfo(PP.getDiagnostics(), + *this->TargetOpts); updated(); return false; @@ -1098,7 +1096,6 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { Clang->setDiagnostics(&getDiagnostics()); // Create the target instance. - Clang->getTargetOpts().Features = TargetFeatures; Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), Clang->getTargetOpts())); if (!Clang->hasTarget()) { @@ -1568,9 +1565,8 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( Clang->setDiagnostics(&getDiagnostics()); // Create the target instance. - Clang->getTargetOpts().Features = TargetFeatures; Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), - Clang->getTargetOpts())); + Clang->getTargetOpts())); if (!Clang->hasTarget()) { llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); Preamble.clear(); @@ -1777,9 +1773,6 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI, CI->getFrontendOpts().DisableFree = false; ProcessWarningOptions(AST->getDiagnostics(), CI->getDiagnosticOpts()); - // Save the target features. - AST->TargetFeatures = CI->getTargetOpts().Features; - // Create the compiler instance to use for building the AST. OwningPtr<CompilerInstance> Clang(new CompilerInstance()); @@ -1795,7 +1788,6 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI, Clang->setDiagnostics(&AST->getDiagnostics()); // Create the target instance. - Clang->getTargetOpts().Features = AST->TargetFeatures; Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), Clang->getTargetOpts())); if (!Clang->hasTarget()) @@ -1884,9 +1876,6 @@ bool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) { Invocation->getFrontendOpts().DisableFree = false; ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts()); - // Save the target features. - TargetFeatures = Invocation->getTargetOpts().Features; - llvm::MemoryBuffer *OverrideMainBuffer = 0; if (PrecompilePreamble) { PreambleRebuildCounter = 2; @@ -2396,7 +2385,6 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column, StoredDiagnostics); // Create the target instance. - Clang->getTargetOpts().Features = TargetFeatures; Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), Clang->getTargetOpts())); if (!Clang->hasTarget()) { diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 6d34425e130..5fc3f1bd187 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -35,11 +35,12 @@ using namespace clang; //===----------------------------------------------------------------------===// CompilerInvocationBase::CompilerInvocationBase() - : LangOpts(new LangOptions()) {} + : LangOpts(new LangOptions()), TargetOpts(new TargetOptions()) {} CompilerInvocationBase::CompilerInvocationBase(const CompilerInvocationBase &X) : RefCountedBase<CompilerInvocation>(), - LangOpts(new LangOptions(*X.getLangOpts())) {} + LangOpts(new LangOptions(*X.getLangOpts())), + TargetOpts(new TargetOptions(X.getTargetOpts())) {} //===----------------------------------------------------------------------===// // Utility functions. @@ -927,8 +928,8 @@ static void TargetOptsToArgs(const TargetOptions &Opts, Res.push_back("-target-linker-version", Opts.LinkerVersion); if (!Opts.CXXABI.empty()) Res.push_back("-cxx-abi", Opts.CXXABI); - for (unsigned i = 0, e = Opts.Features.size(); i != e; ++i) - Res.push_back("-target-feature", Opts.Features[i]); + for (unsigned i = 0, e = Opts.FeaturesAsWritten.size(); i != e; ++i) + Res.push_back("-target-feature", Opts.FeaturesAsWritten[i]); } void CompilerInvocation::toArgs(std::vector<std::string> &Res) const { @@ -2285,7 +2286,7 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) { Opts.ABI = Args.getLastArgValue(OPT_target_abi); Opts.CXXABI = Args.getLastArgValue(OPT_cxx_abi); Opts.CPU = Args.getLastArgValue(OPT_target_cpu); - Opts.Features = Args.getAllArgValues(OPT_target_feature); + Opts.FeaturesAsWritten = Args.getAllArgValues(OPT_target_feature); Opts.LinkerVersion = Args.getLastArgValue(OPT_target_linker_version); Opts.Triple = llvm::Triple::normalize(Args.getLastArgValue(OPT_triple)); @@ -2431,7 +2432,8 @@ std::string CompilerInvocation::getModuleHash() const { #include "clang/Basic/LangOptions.def" // Extend the signature with the target triple - llvm::Triple T(TargetOpts.Triple); + // FIXME: Add target options. + llvm::Triple T(TargetOpts->Triple); Signature.add((unsigned)T.getArch(), 5); Signature.add((unsigned)T.getVendor(), 4); Signature.add((unsigned)T.getOS(), 5); diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index a62f2578e9b..67a54caf644 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -37,6 +37,7 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/FileSystemStatCache.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Basic/TargetOptions.h" #include "clang/Basic/Version.h" #include "clang/Basic/VersionTuple.h" #include "llvm/ADT/StringExtras.h" @@ -101,13 +102,66 @@ PCHValidator::ReadLanguageOptions(const ModuleFile &M, return false; } -bool PCHValidator::ReadTargetTriple(const ModuleFile &M, StringRef Triple) { - if (Triple == PP.getTargetInfo().getTriple().str()) - return false; +bool PCHValidator::ReadTargetOptions(const ModuleFile &M, + const TargetOptions &TargetOpts) { + const TargetOptions &ExistingTargetOpts = PP.getTargetInfo().getTargetOpts(); + +#define CHECK_TARGET_OPT(Field, Name) \ + if (TargetOpts.Field != ExistingTargetOpts.Field) { \ + Reader.Diag(diag::err_pch_targetopt_mismatch) \ + << Name << TargetOpts.Field << ExistingTargetOpts.Field; \ + return true; \ + } + + CHECK_TARGET_OPT(Triple, "target"); + CHECK_TARGET_OPT(CPU, "target CPU"); + CHECK_TARGET_OPT(ABI, "target ABI"); + CHECK_TARGET_OPT(CXXABI, "target C++ ABI"); + CHECK_TARGET_OPT(LinkerVersion, "target linker version"); +#undef CHECK_TARGET_OPT + + // Compare feature sets. + SmallVector<StringRef, 4> ExistingFeatures( + ExistingTargetOpts.FeaturesAsWritten.begin(), + ExistingTargetOpts.FeaturesAsWritten.end()); + SmallVector<StringRef, 4> ReadFeatures(TargetOpts.FeaturesAsWritten.begin(), + TargetOpts.FeaturesAsWritten.end()); + std::sort(ExistingFeatures.begin(), ExistingFeatures.end()); + std::sort(ReadFeatures.begin(), ReadFeatures.end()); + + unsigned ExistingIdx = 0, ExistingN = ExistingFeatures.size(); + unsigned ReadIdx = 0, ReadN = ReadFeatures.size(); + while (ExistingIdx < ExistingN && ReadIdx < ReadN) { + if (ExistingFeatures[ExistingIdx] == ReadFeatures[ReadIdx]) { + ++ExistingIdx; + ++ReadIdx; + continue; + } + + if (ReadFeatures[ReadIdx] < ExistingFeatures[ExistingIdx]) { + Reader.Diag(diag::err_pch_targetopt_feature_mismatch) + << false << ReadFeatures[ReadIdx]; + return true; + } - Reader.Diag(diag::warn_pch_target_triple) - << Triple << PP.getTargetInfo().getTriple().str(); - return true; + Reader.Diag(diag::err_pch_targetopt_feature_mismatch) + << true << ExistingFeatures[ExistingIdx]; + return true; + } + + if (ExistingIdx < ExistingN) { + Reader.Diag(diag::err_pch_targetopt_feature_mismatch) + << true << ExistingFeatures[ExistingIdx]; + return true; + } + + if (ReadIdx < ReadN) { + Reader.Diag(diag::err_pch_targetopt_feature_mismatch) + << false << ReadFeatures[ReadIdx]; + return true; + } + + return false; } namespace { @@ -1834,7 +1888,7 @@ ASTReader::ReadASTBlock(ModuleFile &F) { case METADATA: { if (Record[0] != VERSION_MAJOR && !DisableValidation) { Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old - : diag::warn_pch_version_too_new); + : diag::warn_pch_version_too_new); return IgnorePCH; } @@ -1846,8 +1900,21 @@ ASTReader::ReadASTBlock(ModuleFile &F) { RelocatablePCH = Record[4]; if (Listener) { - std::string TargetTriple(BlobStart, BlobLen); - if (Listener->ReadTargetTriple(F, TargetTriple)) + unsigned Idx = 6; + TargetOptions TargetOpts; + TargetOpts.Triple = ReadString(Record, Idx); + TargetOpts.CPU = ReadString(Record, Idx); + TargetOpts.ABI = ReadString(Record, Idx); + TargetOpts.CXXABI = ReadString(Record, Idx); + TargetOpts.LinkerVersion = ReadString(Record, Idx); + for (unsigned N = Record[Idx++]; N; --N) { + TargetOpts.FeaturesAsWritten.push_back(ReadString(Record, Idx)); + } + for (unsigned N = Record[Idx++]; N; --N) { + TargetOpts.Features.push_back(ReadString(Record, Idx)); + } + + if (Listener->ReadTargetOptions(F, TargetOpts)) return IgnorePCH; } break; diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index d04753a037d..c37f881d982 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -35,6 +35,7 @@ #include "clang/Basic/SourceManager.h" #include "clang/Basic/SourceManagerInternals.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Basic/TargetOptions.h" #include "clang/Basic/Version.h" #include "clang/Basic/VersionTuple.h" #include "llvm/ADT/APFloat.h" @@ -984,27 +985,28 @@ void ASTWriter::WriteMetadata(ASTContext &Context, StringRef isysroot, // Metadata const TargetInfo &Target = Context.getTargetInfo(); - BitCodeAbbrev *MetaAbbrev = new BitCodeAbbrev(); - MetaAbbrev->Add(BitCodeAbbrevOp(METADATA)); - MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // AST major - MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // AST minor - MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang major - MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang minor - MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Relocatable - MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Has errors - MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Target triple - unsigned MetaAbbrevCode = Stream.EmitAbbrev(MetaAbbrev); - + const TargetOptions &TargetOpts = Target.getTargetOpts(); RecordData Record; - Record.push_back(METADATA); Record.push_back(VERSION_MAJOR); Record.push_back(VERSION_MINOR); Record.push_back(CLANG_VERSION_MAJOR); Record.push_back(CLANG_VERSION_MINOR); Record.push_back(!isysroot.empty()); Record.push_back(ASTHasCompilerErrors); - const std::string &Triple = Target.getTriple().getTriple(); - Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, Triple); + AddString(TargetOpts.Triple, Record); + AddString(TargetOpts.CPU, Record); + AddString(TargetOpts.ABI, Record); + AddString(TargetOpts.CXXABI, Record); + AddString(TargetOpts.LinkerVersion, Record); + Record.push_back(TargetOpts.FeaturesAsWritten.size()); + for (unsigned I = 0, N = TargetOpts.FeaturesAsWritten.size(); I != N; ++I) { + AddString(TargetOpts.FeaturesAsWritten[I], Record); + } + Record.push_back(TargetOpts.Features.size()); + for (unsigned I = 0, N = TargetOpts.Features.size(); I != N; ++I) { + AddString(TargetOpts.Features[I], Record); + } + Stream.EmitRecord(METADATA, Record); if (Chain) { serialization::ModuleManager &Mgr = Chain->getModuleManager(); diff --git a/clang/test/PCH/target-options.c b/clang/test/PCH/target-options.c new file mode 100644 index 00000000000..2b85efe07ab --- /dev/null +++ b/clang/test/PCH/target-options.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -triple=x86_64-apple-darwin9 -emit-pch -o %t.pch %S/target-options.h +// RUN: not %clang_cc1 -triple=x86_64-unknown-freebsd7.0 -include-pch %t.pch %s -emit-llvm -o - > %t.err 2>&1 +// RUN: FileCheck %s < %t.err + +// CHECK: for the target diff --git a/clang/test/PCH/target-options.h b/clang/test/PCH/target-options.h new file mode 100644 index 00000000000..2c3edf6aa2e --- /dev/null +++ b/clang/test/PCH/target-options.h @@ -0,0 +1,2 @@ +enum { apple_cc = __APPLE_CC__ }; + |