From: Douglas Gregor Date: Mon, 27 Apr 2009 22:23:34 +0000 (+0000) Subject: Add a header containing the Clang version; make the driver use this X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ab41e63821dc60ad144d0684df8d79a9eef86b75;p=clang Add a header containing the Clang version; make the driver use this Clang version value rather than hard-coding "1.0". Add PCH and Clang version information into the PCH file. Reject PCH files with the wrong version information. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70264 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td index 55d1dfacb8..64a1777924 100644 --- a/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/include/clang/Basic/DiagnosticFrontendKinds.td @@ -115,4 +115,8 @@ def warn_pch_preprocessor : Warning< "current translation unit">; def note_predef_in_pch : Note< "preprocessor definitions in PCH file">; +def warn_pch_version_too_old : Warning< + "PCH file uses an older PCH format that is no longer supported">; +def warn_pch_version_too_new : Warning< + "PCH file uses a newer PCH format that cannot be read">; } diff --git a/include/clang/Basic/Version.h b/include/clang/Basic/Version.h new file mode 100644 index 0000000000..f0e1aa7db2 --- /dev/null +++ b/include/clang/Basic/Version.h @@ -0,0 +1,35 @@ +//===- Version.h - Clang Version Number -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header defines version macros for Clang. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_VERSION_H +#define LLVM_CLANG_BASIC_VERSION_H + +/// \brief Clang major version +#define CLANG_VERSION_MAJOR 1 + +/// \brief Clang minor version +#define CLANG_VERSION_MINOR 0 + +/// \brief Helper macro for CLANG_VERSION_STRING. +#define CLANG_MAKE_VERSION_STRING2(X) #X + +/// \brief Helper macro for CLANG_VERSION_STRING. +#define CLANG_MAKE_VERSION_STRING(X,Y) CLANG_MAKE_VERSION_STRING2(X.Y) + +/// \brief A string that describes the Clang version number, e.g., +/// "1.0". +#define CLANG_VERSION_STRING \ + CLANG_MAKE_VERSION_STRING(CLANG_VERSION_MAJOR,CLANG_VERSION_MINOR) + + +#endif // LLVM_CLANG_BASIC_VERSION_H diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index 7f5e7c500f..a4da704386 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -22,6 +22,25 @@ namespace clang { namespace pch { + /// \brief PCH major version number supported by this version of + /// Clang. + /// + /// Whenever the PCH format changes in a way that makes it + /// 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 = 1; + + /// \brief PCH minor version number supported by this version of + /// Clang. + /// + /// Whenever the PCH format changes in a way that is still + /// compatible with previous versions (such that a reader designed + /// for the previous version could still support reading the new + /// version by ignoring new kinds of subblocks), this number + /// should be increased. + const unsigned VERSION_MINOR = 0; + /// \brief An ID number that refers to a declaration in a PCH file. /// /// The ID numbers of types are consecutive (in order of @@ -108,9 +127,9 @@ namespace clang { /// actually important to check. LANGUAGE_OPTIONS = 3, - /// \brief Record code for the target triple used to build the - /// PCH file. - TARGET_TRIPLE = 4, + /// \brief PCH metadata, including the PCH file version number + /// and the target triple used to build the PCH file. + METADATA = 4, /// \brief Record code for the table of offsets of each /// identifier ID. diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h index b16058c154..3c2d5ff1af 100644 --- a/include/clang/Frontend/PCHWriter.h +++ b/include/clang/Frontend/PCHWriter.h @@ -160,7 +160,7 @@ private: unsigned NumVisibleDeclContexts; void WriteBlockInfoBlock(); - void WriteTargetTriple(const TargetInfo &Target); + void WriteMetadata(const TargetInfo &Target); void WriteLanguageOptions(const LangOptions &LangOpts); void WriteStatCache(MemorizeStatCalls &StatCalls); void WriteSourceManagerBlock(SourceManager &SourceMgr, diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index d88f1b3598..d6a046e9c3 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -22,6 +22,8 @@ #include "clang/Driver/ToolChain.h" #include "clang/Driver/Types.h" +#include "clang/Basic/Version.h" + #include "llvm/ADT/StringSet.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/raw_ostream.h" @@ -353,8 +355,8 @@ void Driver::PrintVersion(const Compilation &C) const { // FIXME: The following handlers should use a callback mechanism, we // don't know what the client would like to do. - // FIXME: Do not hardcode clang version. - llvm::errs() << "clang version 1.0 (" << vers << " " << revision << ")" << "\n"; + llvm::errs() << "clang version " CLANG_VERSION_STRING " (" + << vers << " " << revision << ")" << "\n"; const ToolChain &TC = C.getDefaultToolChain(); llvm::errs() << "Target: " << TC.getTripleString() << '\n'; @@ -366,8 +368,7 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { // in practice. if (C.getArgs().hasArg(options::OPT_dumpversion)) { - // FIXME: Do not hardcode clang version. - llvm::outs() << "1.0\n"; + llvm::outs() << CLANG_VERSION_STRING "\n"; return false; } diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 24e4e2b02f..c1cb87bc16 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -928,7 +928,13 @@ PCHReader::ReadPCHBlock() { return IgnorePCH; break; - case pch::TARGET_TRIPLE: { + case pch::METADATA: { + if (Record[0] != pch::VERSION_MAJOR) { + Diag(Record[0] < pch::VERSION_MAJOR? diag::warn_pch_version_too_old + : diag::warn_pch_version_too_new); + return IgnorePCH; + } + std::string TargetTriple(BlobStart, BlobLen); if (TargetTriple != PP.getTargetInfo().getTargetTriple()) { Diag(diag::warn_pch_target_triple) diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 817893448a..6b58e25092 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -27,6 +27,7 @@ #include "clang/Basic/SourceManager.h" #include "clang/Basic/SourceManagerInternals.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Basic/Version.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/Bitcode/BitstreamWriter.h" @@ -341,7 +342,7 @@ void PCHWriter::WriteBlockInfoBlock() { RECORD(TYPE_OFFSET); RECORD(DECL_OFFSET); RECORD(LANGUAGE_OPTIONS); - RECORD(TARGET_TRIPLE); + RECORD(METADATA); RECORD(IDENTIFIER_OFFSET); RECORD(IDENTIFIER_TABLE); RECORD(EXTERNAL_DEFINITIONS); @@ -440,18 +441,26 @@ void PCHWriter::WriteBlockInfoBlock() { } -/// \brief Write the target triple (e.g., i686-apple-darwin9). -void PCHWriter::WriteTargetTriple(const TargetInfo &Target) { +/// \brief Write the PCH metadata (e.g., i686-apple-darwin9). +void PCHWriter::WriteMetadata(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 = Stream.EmitAbbrev(Abbrev); + Abbrev->Add(BitCodeAbbrevOp(pch::METADATA)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // PCH major + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // PCH minor + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang major + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang minor + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Target triple + unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev); RecordData Record; - Record.push_back(pch::TARGET_TRIPLE); + Record.push_back(pch::METADATA); + Record.push_back(pch::VERSION_MAJOR); + Record.push_back(pch::VERSION_MINOR); + Record.push_back(CLANG_VERSION_MAJOR); + Record.push_back(CLANG_VERSION_MINOR); const char *Triple = Target.getTargetTriple(); - Stream.EmitRecordWithBlob(TripleAbbrev, Record, Triple, strlen(Triple)); + Stream.EmitRecordWithBlob(AbbrevCode, Record, Triple, strlen(Triple)); } /// \brief Write the LangOptions structure. @@ -1672,7 +1681,7 @@ void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls) { // Write the remaining PCH contents. RecordData Record; Stream.EnterSubblock(pch::PCH_BLOCK_ID, 4); - WriteTargetTriple(Context.Target); + WriteMetadata(Context.Target); WriteLanguageOptions(Context.getLangOptions()); if (StatCalls) WriteStatCache(*StatCalls);