From: Douglas Gregor Date: Tue, 16 Oct 2012 23:40:58 +0000 (+0000) Subject: Serialize TargetOptions into an AST file, and make sure that we keep X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=57016dda61498294120b1a881d9e6606337b29d9;p=clang Serialize TargetOptions into an AST file, and make sure that we keep target options around so they can be accessed at any point (rather than keeping them transient). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166072 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td index a440e806d7..435760bb87 100644 --- a/include/clang/Basic/DiagnosticSerializationKinds.td +++ b/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/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index 3e63505dfa..ea520e8f82 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/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 @@ -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 { - TargetOptions *TargetOpts; + llvm::IntrusiveRefCntPtr TargetOpts; llvm::Triple Triple; protected: // Target values set by the ctor of the actual target implementation. Default diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h index 15ececd1df..d6deb0244d 100644 --- a/include/clang/Basic/TargetOptions.h +++ b/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 #include namespace clang { /// \brief Options for controlling the target. -class TargetOptions { +class TargetOptions : public RefCountedBase { 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 FeaturesAsWritten; + /// The list of target specific features to enable or disable -- this should /// be a list of strings starting with by '+' or '-'. std::vector Features; diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index 0b02afa19d..c2bde120a0 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -71,8 +71,8 @@ private: IntrusiveRefCntPtr Target; IntrusiveRefCntPtr PP; IntrusiveRefCntPtr Ctx; + IntrusiveRefCntPtr TargetOpts; ASTReader *Reader; - TargetOptions TargetOpts; struct ASTWriterData; OwningPtr WriterData; @@ -91,13 +91,6 @@ private: /// LoadFromCommandLine available. IntrusiveRefCntPtr 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 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/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h index 30c96cbb33..a58fef1f4b 100644 --- a/include/clang/Frontend/CompilerInvocation.h +++ b/include/clang/Frontend/CompilerInvocation.h @@ -52,6 +52,9 @@ class CompilerInvocationBase : public RefCountedBase { protected: /// Options controlling the language variant. IntrusiveRefCntPtr LangOpts; + + /// Options controlling the target. + IntrusiveRefCntPtr 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/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index d23e7c5bf4..02e9927dbe 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/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/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 2e6678bb89..cd835023ab 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -4635,8 +4635,10 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, // Apply the user specified deltas. // First the enables. - for (std::vector::const_iterator it = Opts.Features.begin(), - ie = Opts.Features.end(); it != ie; ++it) { + for (std::vector::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::const_iterator it = Opts.Features.begin(), - ie = Opts.Features.end(); it != ie; ++it) { + for (std::vector::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/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index e602d30374..bf78ac51ec 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -503,7 +503,7 @@ class ASTInfoCollector : public ASTReaderListener { ASTContext &Context; LangOptions &LangOpt; HeaderSearch &HSI; - TargetOptions &TargetOpts; + IntrusiveRefCntPtr &TargetOpts; IntrusiveRefCntPtr &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 &TargetOpts, IntrusiveRefCntPtr &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 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/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 6d34425e13..5fc3f1bd18 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/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(), - 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 &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/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index a62f2578e9..67a54caf64 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/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 ExistingFeatures( + ExistingTargetOpts.FeaturesAsWritten.begin(), + ExistingTargetOpts.FeaturesAsWritten.end()); + SmallVector 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/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index d04753a037..c37f881d98 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/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/test/PCH/target-options.c b/test/PCH/target-options.c new file mode 100644 index 0000000000..2b85efe07a --- /dev/null +++ b/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/test/PCH/target-options.h b/test/PCH/target-options.h new file mode 100644 index 0000000000..2c3edf6aa2 --- /dev/null +++ b/test/PCH/target-options.h @@ -0,0 +1,2 @@ +enum { apple_cc = __APPLE_CC__ }; +