17550a6c1SDouglas Gregor //===- Version.cpp - Clang Version Number -----------------------*- C++ -*-===// 27550a6c1SDouglas Gregor // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 67550a6c1SDouglas Gregor // 77550a6c1SDouglas Gregor //===----------------------------------------------------------------------===// 87550a6c1SDouglas Gregor // 97550a6c1SDouglas Gregor // This file defines several version-related utility functions for Clang. 107550a6c1SDouglas Gregor // 117550a6c1SDouglas Gregor //===----------------------------------------------------------------------===// 122377a0e0STed Kremenek 1351b8bc93STed Kremenek #include "clang/Basic/Version.h" 140e62c1ccSChris Lattner #include "clang/Basic/LLVM.h" 15f988d006SAlp Toker #include "clang/Config/config.h" 163a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h" 177550a6c1SDouglas Gregor #include <cstdlib> 183a02247dSChandler Carruth #include <cstring> 192377a0e0STed Kremenek 2023fdd5a3SPetr Hosek #include "VCSVersion.inc" 2112062e06SPetr Hosek 227550a6c1SDouglas Gregor namespace clang { 237550a6c1SDouglas Gregor getClangRepositoryPath()24181ca580SDaniel Dunbarstd::string getClangRepositoryPath() { 25b1798f7bSDaniel Dunbar #if defined(CLANG_REPOSITORY_STRING) 26b1798f7bSDaniel Dunbar return CLANG_REPOSITORY_STRING; 27b1798f7bSDaniel Dunbar #else 2823fdd5a3SPetr Hosek #ifdef CLANG_REPOSITORY 29fb9413cbSNico Weber return CLANG_REPOSITORY; 30181ca580SDaniel Dunbar #else 31fb9413cbSNico Weber return ""; 32181ca580SDaniel Dunbar #endif 33b1798f7bSDaniel Dunbar #endif 34b800fdb0SDaniel Dunbar } 357550a6c1SDouglas Gregor getLLVMRepositoryPath()365c302484SJia Liustd::string getLLVMRepositoryPath() { 375c302484SJia Liu #ifdef LLVM_REPOSITORY 38fb9413cbSNico Weber return LLVM_REPOSITORY; 395c302484SJia Liu #else 40fb9413cbSNico Weber return ""; 415c302484SJia Liu #endif 425c302484SJia Liu } 435c302484SJia Liu getClangRevision()44181ca580SDaniel Dunbarstd::string getClangRevision() { 4523fdd5a3SPetr Hosek #ifdef CLANG_REVISION 4623fdd5a3SPetr Hosek return CLANG_REVISION; 47181ca580SDaniel Dunbar #else 4847307292STed Kremenek return ""; 49181ca580SDaniel Dunbar #endif 507550a6c1SDouglas Gregor } 517550a6c1SDouglas Gregor getLLVMRevision()525c302484SJia Liustd::string getLLVMRevision() { 535c302484SJia Liu #ifdef LLVM_REVISION 545c302484SJia Liu return LLVM_REVISION; 555c302484SJia Liu #else 565c302484SJia Liu return ""; 575c302484SJia Liu #endif 585c302484SJia Liu } 595c302484SJia Liu getClangFullRepositoryVersion()60a3e65706STed Kremenekstd::string getClangFullRepositoryVersion() { 61a3e65706STed Kremenek std::string buf; 6251b8bc93STed Kremenek llvm::raw_string_ostream OS(buf); 63181ca580SDaniel Dunbar std::string Path = getClangRepositoryPath(); 64181ca580SDaniel Dunbar std::string Revision = getClangRevision(); 659179e8a4SAndrew Trick if (!Path.empty() || !Revision.empty()) { 669179e8a4SAndrew Trick OS << '('; 67b800fdb0SDaniel Dunbar if (!Path.empty()) 68b800fdb0SDaniel Dunbar OS << Path; 69b800fdb0SDaniel Dunbar if (!Revision.empty()) { 70b800fdb0SDaniel Dunbar if (!Path.empty()) 71b800fdb0SDaniel Dunbar OS << ' '; 72b800fdb0SDaniel Dunbar OS << Revision; 73b800fdb0SDaniel Dunbar } 749179e8a4SAndrew Trick OS << ')'; 759179e8a4SAndrew Trick } 765c302484SJia Liu // Support LLVM in a separate repository. 775c302484SJia Liu std::string LLVMRev = getLLVMRevision(); 785c302484SJia Liu if (!LLVMRev.empty() && LLVMRev != Revision) { 799179e8a4SAndrew Trick OS << " ("; 805c302484SJia Liu std::string LLVMRepo = getLLVMRepositoryPath(); 815c302484SJia Liu if (!LLVMRepo.empty()) 829179e8a4SAndrew Trick OS << LLVMRepo << ' '; 839179e8a4SAndrew Trick OS << LLVMRev << ')'; 845c302484SJia Liu } 85*0cf6f7b1SLogan Smith return buf; 8651b8bc93STed Kremenek } 8751b8bc93STed Kremenek getClangFullVersion()88a3e65706STed Kremenekstd::string getClangFullVersion() { 89b00d66e6SNico Weber return getClangToolFullVersion("clang"); 90b00d66e6SNico Weber } 91b00d66e6SNico Weber getClangToolFullVersion(StringRef ToolName)92b00d66e6SNico Weberstd::string getClangToolFullVersion(StringRef ToolName) { 93a3e65706STed Kremenek std::string buf; 9451b8bc93STed Kremenek llvm::raw_string_ostream OS(buf); 9551b8bc93STed Kremenek #ifdef CLANG_VENDOR 9651b8bc93STed Kremenek OS << CLANG_VENDOR; 9751b8bc93STed Kremenek #endif 98bbea4d5eSSylvestre Ledru OS << ToolName << " version " CLANG_VERSION_STRING; 99bbea4d5eSSylvestre Ledru 100bbea4d5eSSylvestre Ledru std::string repo = getClangFullRepositoryVersion(); 101bbea4d5eSSylvestre Ledru if (!repo.empty()) { 102bbea4d5eSSylvestre Ledru OS << " " << repo; 103bbea4d5eSSylvestre Ledru } 1046036264fSDaniel Dunbar 105*0cf6f7b1SLogan Smith return buf; 10618e066f6STed Kremenek } 10718e066f6STed Kremenek getClangFullCPPVersion()1083b17a865SDaniel Dunbarstd::string getClangFullCPPVersion() { 10921a92a8aSSylvestre Ledru // The version string we report in __VERSION__ is just a compacted version of 11021a92a8aSSylvestre Ledru // the one we report on the command line. 1113b17a865SDaniel Dunbar std::string buf; 1123b17a865SDaniel Dunbar llvm::raw_string_ostream OS(buf); 1133b17a865SDaniel Dunbar #ifdef CLANG_VENDOR 1143b17a865SDaniel Dunbar OS << CLANG_VENDOR; 1153b17a865SDaniel Dunbar #endif 116bbea4d5eSSylvestre Ledru OS << "Clang " CLANG_VERSION_STRING; 117bbea4d5eSSylvestre Ledru 118bbea4d5eSSylvestre Ledru std::string repo = getClangFullRepositoryVersion(); 119bbea4d5eSSylvestre Ledru if (!repo.empty()) { 120bbea4d5eSSylvestre Ledru OS << " " << repo; 121bbea4d5eSSylvestre Ledru } 122bbea4d5eSSylvestre Ledru 123*0cf6f7b1SLogan Smith return buf; 1243b17a865SDaniel Dunbar } 1253b17a865SDaniel Dunbar 1267550a6c1SDouglas Gregor } // end namespace clang 127