From 445e23e9b909ec8e21303c7dd82c90b72fc09ac4 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 5 Oct 2009 21:07:28 +0000 Subject: [PATCH] Encode the Clang branch and Subversion revision into a PCH file, and assume that PCH files from different Clang revisions are not compatible. Addresses . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83323 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../clang/Basic/DiagnosticFrontendKinds.td | 2 ++ include/clang/Frontend/PCHBitCodes.h | 12 ++++++++-- lib/Frontend/PCHReader.cpp | 22 ++++++++++++++++--- lib/Frontend/PCHWriter.cpp | 14 +++++++++++- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td index 385b1c2a0b..e5c73270fd 100644 --- a/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/include/clang/Basic/DiagnosticFrontendKinds.td @@ -136,6 +136,8 @@ def warn_pch_version_too_old : Error< "PCH file uses an older PCH format that is no longer supported">; def warn_pch_version_too_new : Error< "PCH file uses a newer PCH format that cannot be read">; +def warn_pch_different_branch : Error< + "PCH file built from a different branch (%0) than the compiler (%1)">; def warn_cmdline_conflicting_macro_def : Error< "definition of the macro '%0' conflicts with the definition used to " "build the precompiled header">; diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index 2655217a83..716780e68a 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -29,7 +29,11 @@ namespace clang { /// incompatible with previous versions (such that a reader /// designed for the previous version could not support reading /// the new version), this number should be increased. - const unsigned VERSION_MAJOR = 2; + /// + /// Version 3 of PCH files also requires that the Subversion branch and + /// revision match exactly, since there is no backward compatibility of + /// PCH files at this time. + const unsigned VERSION_MAJOR = 3; /// \brief PCH minor version number supported by this version of /// Clang. @@ -218,7 +222,11 @@ namespace clang { /// \brief Record code for the sorted array of source ranges where /// comments were encountered in the source code. - COMMENT_RANGES = 20 + COMMENT_RANGES = 20, + + /// \brief Record code for the Subversion branch and revision information + /// of the compiler used to build this PCH file. + SVN_BRANCH_REVISION = 21 }; /// \brief Record types used within a source manager block. diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index ead00ee75f..e61668dd31 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -26,6 +26,7 @@ #include "clang/Basic/SourceManagerInternals.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Basic/Version.h" #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/MemoryBuffer.h" @@ -1340,9 +1341,7 @@ PCHReader::ReadPCHBlock() { case pch::SOURCE_LOCATION_OFFSETS: SLocOffsets = (const uint32_t *)BlobStart; TotalNumSLocEntries = Record[0]; - SourceMgr.PreallocateSLocEntries(this, - TotalNumSLocEntries, - Record[1]); + SourceMgr.PreallocateSLocEntries(this, TotalNumSLocEntries, Record[1]); break; case pch::SOURCE_LOCATION_PRELOADS: @@ -1377,6 +1376,23 @@ PCHReader::ReadPCHBlock() { Comments = (SourceRange *)BlobStart; NumComments = BlobLen / sizeof(SourceRange); break; + + case pch::SVN_BRANCH_REVISION: { + unsigned CurRevision = getClangSubversionRevision(); + if (Record[0] && CurRevision && Record[0] != CurRevision) { + Diag(Record[0] < CurRevision? diag::warn_pch_version_too_old + : diag::warn_pch_version_too_new); + return IgnorePCH; + } + + const char *CurBranch = getClangSubversionPath(); + if (strncmp(CurBranch, BlobStart, BlobLen)) { + std::string PCHBranch(BlobStart, BlobLen); + Diag(diag::warn_pch_different_branch) << PCHBranch << CurBranch; + return IgnorePCH; + } + break; + } } } Error("premature end of bitstream in PCH file"); diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 08a1661e1d..64a678ea45 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -394,7 +394,8 @@ void PCHWriter::WriteBlockInfoBlock() { RECORD(STAT_CACHE); RECORD(EXT_VECTOR_DECLS); RECORD(COMMENT_RANGES); - + RECORD(SVN_BRANCH_REVISION); + // SourceManager Block. BLOCK(SOURCE_MANAGER_BLOCK); RECORD(SM_SLOC_FILE_ENTRY); @@ -564,6 +565,17 @@ void PCHWriter::WriteMetadata(ASTContext &Context, const char *isysroot) { Record.push_back(pch::ORIGINAL_FILE_NAME); Stream.EmitRecordWithBlob(FileAbbrevCode, Record, MainFileNameStr); } + + // Subversion branch/version information. + BitCodeAbbrev *SvnAbbrev = new BitCodeAbbrev(); + SvnAbbrev->Add(BitCodeAbbrevOp(pch::SVN_BRANCH_REVISION)); + SvnAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // SVN revision + SvnAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // SVN branch/tag + unsigned SvnAbbrevCode = Stream.EmitAbbrev(SvnAbbrev); + Record.clear(); + Record.push_back(pch::SVN_BRANCH_REVISION); + Record.push_back(getClangSubversionRevision()); + Stream.EmitRecordWithBlob(SvnAbbrevCode, Record, getClangSubversionPath()); } /// \brief Write the LangOptions structure. -- 2.40.0