From bfbde53ce12cc14ccfc743b9a796f8d9d4458538 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 10 Apr 2009 21:16:55 +0000 Subject: [PATCH] Encode the target triple in the PCH file, and check that target triple when using the PCH file llvm-svn: 68824 --- .../clang/Basic/DiagnosticFrontendKinds.td | 15 +++++++----- clang/include/clang/Frontend/PCHBitCodes.h | 6 ++++- clang/include/clang/Frontend/PCHWriter.h | 6 +++-- clang/lib/Frontend/PCHReader.cpp | 23 +++++++++++++++---- clang/lib/Frontend/PCHWriter.cpp | 19 ++++++++++++++- 5 files changed, 54 insertions(+), 15 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 47a873148df6..9db74e251802 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -24,24 +24,27 @@ def warn_fixit_no_changes : Note< "FIX-IT detected errors it could not fix; no output will be generated">; // PCH reader +def warn_pch_target_triple : Warning< + "PCH file was compiled for the target '%0' but the current translation " + "unit is being compiled for target '%1'">; def note_ignoring_pch : Note< "ignoring precompiled header '%0'">; -def warn_pch_c99 : Error< +def warn_pch_c99 : Warning< "C99 support was %select{disabled|enabled}0 in PCH file but is " "currently %select{disabled|enabled}1">; -def warn_pch_cplusplus : Error< +def warn_pch_cplusplus : Warning< "C++ support was %select{disabled|enabled}0 in PCH file but is " "currently %select{disabled|enabled}1">; -def warn_pch_cplusplus0x : Error< +def warn_pch_cplusplus0x : Warning< "C++0x support was %select{disabled|enabled}0 in PCH file but is " "currently %select{disabled|enabled}1">; -def warn_pch_objective_c : Error< +def warn_pch_objective_c : Warning< "Objective-C support was %select{disabled|enabled}0 in PCH file but is " "currently %select{disabled|enabled}1">; -def warn_pch_objective_c2 : Error< +def warn_pch_objective_c2 : Warning< "Objective-C 2.0 support was %select{disabled|enabled}0 in PCH file but " "is currently %select{disabled|enabled}1">; -def warn_pch_nonfragile_abi : Error< +def warn_pch_nonfragile_abi : Warning< "PCH file was compiled with the %select{32-bit|non-fragile}0 Objective-C " "ABI but the %select{32-bit|non-fragile}1 Objective-C ABI is selected">; def warn_pch_extensions : Warning< diff --git a/clang/include/clang/Frontend/PCHBitCodes.h b/clang/include/clang/Frontend/PCHBitCodes.h index 624c5e4875b9..f60f65dfe730 100644 --- a/clang/include/clang/Frontend/PCHBitCodes.h +++ b/clang/include/clang/Frontend/PCHBitCodes.h @@ -100,7 +100,11 @@ namespace clang { /// LangOptions structure. We serialize the entire contents of /// the structure, and let the reader decide which options are /// actually important to check. - LANGUAGE_OPTIONS = 3 + LANGUAGE_OPTIONS = 3, + + /// \brief Record code for the target triple used to build the + /// PCH file. + TARGET_TRIPLE = 4 }; /// \brief Record types used within a source manager block. diff --git a/clang/include/clang/Frontend/PCHWriter.h b/clang/include/clang/Frontend/PCHWriter.h index df5175159dc9..d1e2a715449d 100644 --- a/clang/include/clang/Frontend/PCHWriter.h +++ b/clang/include/clang/Frontend/PCHWriter.h @@ -29,9 +29,10 @@ namespace llvm { namespace clang { -class SourceManager; -class Preprocessor; class ASTContext; +class Preprocessor; +class SourceManager; +class TargetInfo; /// \brief Writes a precompiled header containing the contents of a /// translation unit. @@ -76,6 +77,7 @@ class PCHWriter { /// \brief The type ID that will be assigned to the next new type. pch::TypeID NextTypeID; + void WriteTargetTriple(const TargetInfo &Target); void WriteLanguageOptions(const LangOptions &LangOpts); void WriteSourceManagerBlock(SourceManager &SourceMgr); void WritePreprocessor(const Preprocessor &PP); diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index a00fee27fbb5..9eb881ce0f44 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -18,6 +18,7 @@ #include "clang/Lex/Preprocessor.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/FileManager.h" +#include "clang/Basic/TargetInfo.h" #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/MemoryBuffer.h" @@ -238,7 +239,10 @@ PCHReader::PCHReadResult PCHReader::ReadPCHBlock() { // Read and process a record. Record.clear(); - switch ((pch::PCHRecordTypes)Stream.ReadRecord(Code, Record)) { + const char *BlobStart = 0; + unsigned BlobLen = 0; + switch ((pch::PCHRecordTypes)Stream.ReadRecord(Code, Record, + &BlobStart, &BlobLen)) { default: // Default behavior: ignore. break; @@ -264,6 +268,16 @@ PCHReader::PCHReadResult PCHReader::ReadPCHBlock() { if (ParseLanguageOptions(Record)) return IgnorePCH; break; + + case pch::TARGET_TRIPLE: + std::string TargetTriple(BlobStart, BlobLen); + if (TargetTriple != Context.Target.getTargetTriple()) { + Diag(diag::warn_pch_target_triple) + << TargetTriple << Context.Target.getTargetTriple(); + Diag(diag::note_ignoring_pch) << FileName; + return IgnorePCH; + } + break; } } @@ -319,10 +333,9 @@ bool PCHReader::ReadPCH(const std::string &FileName) { return true; case IgnorePCH: - if (Stream.SkipBlock()) { - Error("Malformed block record"); - return true; - } + // FIXME: We could consider reading through to the end of this + // PCH block, skipping subblocks, to see if there are other + // PCH blocks elsewhere. return false; } break; diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index 6feb726b4282..a31c0c79855a 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -21,6 +21,7 @@ #include "clang/Lex/Preprocessor.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" +#include "clang/Basic/TargetInfo.h" #include "llvm/Bitcode/BitstreamWriter.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/MemoryBuffer.h" @@ -328,6 +329,21 @@ void PCHDeclWriter::VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset, // PCHWriter Implementation //===----------------------------------------------------------------------===// +/// \brief Write the target triple (e.g., i686-apple-darwin9). +void PCHWriter::WriteTargetTriple(const TargetInfo &Target) { + using namespace llvm; + BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); + Abbrev->Add(BitCodeAbbrevOp(pch::TARGET_TRIPLE)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Triple name + unsigned TripleAbbrev = S.EmitAbbrev(Abbrev); + + RecordData Record; + Record.push_back(pch::TARGET_TRIPLE); + const char *Triple = Target.getTargetTriple(); + S.EmitRecordWithBlob(TripleAbbrev, Record, Triple, strlen(Triple)); +} + +/// \brief Write the LangOptions structure. void PCHWriter::WriteLanguageOptions(const LangOptions &LangOpts) { RecordData Record; Record.push_back(LangOpts.Trigraphs); @@ -815,7 +831,8 @@ void PCHWriter::WritePCH(ASTContext &Context, const Preprocessor &PP) { DeclsToEmit.push(Context.getTranslationUnitDecl()); // Write the remaining PCH contents. - S.EnterSubblock(pch::PCH_BLOCK_ID, 2); + S.EnterSubblock(pch::PCH_BLOCK_ID, 3); + WriteTargetTriple(Context.Target); WriteLanguageOptions(Context.getLangOptions()); WriteSourceManagerBlock(Context.getSourceManager()); WritePreprocessor(PP);