1*67e74705SXin Li //===- Version.cpp - Clang Version Number -----------------------*- C++ -*-===// 2*67e74705SXin Li // 3*67e74705SXin Li // The LLVM Compiler Infrastructure 4*67e74705SXin Li // 5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source 6*67e74705SXin Li // License. See LICENSE.TXT for details. 7*67e74705SXin Li // 8*67e74705SXin Li //===----------------------------------------------------------------------===// 9*67e74705SXin Li // 10*67e74705SXin Li // This file defines several version-related utility functions for Clang. 11*67e74705SXin Li // 12*67e74705SXin Li //===----------------------------------------------------------------------===// 13*67e74705SXin Li 14*67e74705SXin Li #include "clang/Basic/Version.h" 15*67e74705SXin Li #include "clang/Basic/LLVM.h" 16*67e74705SXin Li #include "clang/Config/config.h" 17*67e74705SXin Li #include "llvm/Support/raw_ostream.h" 18*67e74705SXin Li #include <cstdlib> 19*67e74705SXin Li #include <cstring> 20*67e74705SXin Li 21*67e74705SXin Li #ifdef HAVE_SVN_VERSION_INC 22*67e74705SXin Li # include "SVNVersion.inc" 23*67e74705SXin Li #endif 24*67e74705SXin Li 25*67e74705SXin Li namespace clang { 26*67e74705SXin Li getClangRepositoryPath()27*67e74705SXin Listd::string getClangRepositoryPath() { 28*67e74705SXin Li #if defined(CLANG_REPOSITORY_STRING) 29*67e74705SXin Li return CLANG_REPOSITORY_STRING; 30*67e74705SXin Li #else 31*67e74705SXin Li #ifdef SVN_REPOSITORY 32*67e74705SXin Li StringRef URL(SVN_REPOSITORY); 33*67e74705SXin Li #else 34*67e74705SXin Li StringRef URL(""); 35*67e74705SXin Li #endif 36*67e74705SXin Li 37*67e74705SXin Li // If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us 38*67e74705SXin Li // pick up a tag in an SVN export, for example. 39*67e74705SXin Li StringRef SVNRepository("$URL$"); 40*67e74705SXin Li if (URL.empty()) { 41*67e74705SXin Li URL = SVNRepository.slice(SVNRepository.find(':'), 42*67e74705SXin Li SVNRepository.find("/lib/Basic")); 43*67e74705SXin Li } 44*67e74705SXin Li 45*67e74705SXin Li // Strip off version from a build from an integration branch. 46*67e74705SXin Li URL = URL.slice(0, URL.find("/src/tools/clang")); 47*67e74705SXin Li 48*67e74705SXin Li // Trim path prefix off, assuming path came from standard cfe path. 49*67e74705SXin Li size_t Start = URL.find("cfe/"); 50*67e74705SXin Li if (Start != StringRef::npos) 51*67e74705SXin Li URL = URL.substr(Start + 4); 52*67e74705SXin Li 53*67e74705SXin Li return URL; 54*67e74705SXin Li #endif 55*67e74705SXin Li } 56*67e74705SXin Li getLLVMRepositoryPath()57*67e74705SXin Listd::string getLLVMRepositoryPath() { 58*67e74705SXin Li #ifdef LLVM_REPOSITORY 59*67e74705SXin Li StringRef URL(LLVM_REPOSITORY); 60*67e74705SXin Li #else 61*67e74705SXin Li StringRef URL(""); 62*67e74705SXin Li #endif 63*67e74705SXin Li 64*67e74705SXin Li // Trim path prefix off, assuming path came from standard llvm path. 65*67e74705SXin Li // Leave "llvm/" prefix to distinguish the following llvm revision from the 66*67e74705SXin Li // clang revision. 67*67e74705SXin Li size_t Start = URL.find("llvm/"); 68*67e74705SXin Li if (Start != StringRef::npos) 69*67e74705SXin Li URL = URL.substr(Start); 70*67e74705SXin Li 71*67e74705SXin Li return URL; 72*67e74705SXin Li } 73*67e74705SXin Li getClangRevision()74*67e74705SXin Listd::string getClangRevision() { 75*67e74705SXin Li #ifdef SVN_REVISION 76*67e74705SXin Li return SVN_REVISION; 77*67e74705SXin Li #else 78*67e74705SXin Li return ""; 79*67e74705SXin Li #endif 80*67e74705SXin Li } 81*67e74705SXin Li getLLVMRevision()82*67e74705SXin Listd::string getLLVMRevision() { 83*67e74705SXin Li #ifdef LLVM_REVISION 84*67e74705SXin Li return LLVM_REVISION; 85*67e74705SXin Li #else 86*67e74705SXin Li return ""; 87*67e74705SXin Li #endif 88*67e74705SXin Li } 89*67e74705SXin Li getClangFullRepositoryVersion()90*67e74705SXin Listd::string getClangFullRepositoryVersion() { 91*67e74705SXin Li std::string buf; 92*67e74705SXin Li llvm::raw_string_ostream OS(buf); 93*67e74705SXin Li std::string Path = getClangRepositoryPath(); 94*67e74705SXin Li std::string Revision = getClangRevision(); 95*67e74705SXin Li if (!Path.empty() || !Revision.empty()) { 96*67e74705SXin Li OS << '('; 97*67e74705SXin Li if (!Path.empty()) 98*67e74705SXin Li OS << Path; 99*67e74705SXin Li if (!Revision.empty()) { 100*67e74705SXin Li if (!Path.empty()) 101*67e74705SXin Li OS << ' '; 102*67e74705SXin Li OS << Revision; 103*67e74705SXin Li } 104*67e74705SXin Li OS << ')'; 105*67e74705SXin Li } 106*67e74705SXin Li // Support LLVM in a separate repository. 107*67e74705SXin Li std::string LLVMRev = getLLVMRevision(); 108*67e74705SXin Li if (!LLVMRev.empty() && LLVMRev != Revision) { 109*67e74705SXin Li OS << " ("; 110*67e74705SXin Li std::string LLVMRepo = getLLVMRepositoryPath(); 111*67e74705SXin Li if (!LLVMRepo.empty()) 112*67e74705SXin Li OS << LLVMRepo << ' '; 113*67e74705SXin Li OS << LLVMRev << ')'; 114*67e74705SXin Li } 115*67e74705SXin Li return OS.str(); 116*67e74705SXin Li } 117*67e74705SXin Li getClangFullVersion()118*67e74705SXin Listd::string getClangFullVersion() { 119*67e74705SXin Li return getClangToolFullVersion("clang"); 120*67e74705SXin Li } 121*67e74705SXin Li getClangToolFullVersion(StringRef ToolName)122*67e74705SXin Listd::string getClangToolFullVersion(StringRef ToolName) { 123*67e74705SXin Li std::string buf; 124*67e74705SXin Li llvm::raw_string_ostream OS(buf); 125*67e74705SXin Li #ifdef CLANG_VENDOR 126*67e74705SXin Li OS << CLANG_VENDOR; 127*67e74705SXin Li #endif 128*67e74705SXin Li OS << ToolName << " version " CLANG_VERSION_STRING " " 129*67e74705SXin Li << getClangFullRepositoryVersion(); 130*67e74705SXin Li 131*67e74705SXin Li // If vendor supplied, include the base LLVM version as well. 132*67e74705SXin Li #ifdef CLANG_VENDOR 133*67e74705SXin Li OS << " (based on " << BACKEND_PACKAGE_STRING << ")"; 134*67e74705SXin Li #endif 135*67e74705SXin Li 136*67e74705SXin Li return OS.str(); 137*67e74705SXin Li } 138*67e74705SXin Li getClangFullCPPVersion()139*67e74705SXin Listd::string getClangFullCPPVersion() { 140*67e74705SXin Li // The version string we report in __VERSION__ is just a compacted version of 141*67e74705SXin Li // the one we report on the command line. 142*67e74705SXin Li std::string buf; 143*67e74705SXin Li llvm::raw_string_ostream OS(buf); 144*67e74705SXin Li #ifdef CLANG_VENDOR 145*67e74705SXin Li OS << CLANG_VENDOR; 146*67e74705SXin Li #endif 147*67e74705SXin Li OS << "Clang " CLANG_VERSION_STRING " " << getClangFullRepositoryVersion(); 148*67e74705SXin Li return OS.str(); 149*67e74705SXin Li } 150*67e74705SXin Li 151*67e74705SXin Li } // end namespace clang 152