1198092Srdivacky//===- Version.cpp - Clang Version Number -----------------------*- C++ -*-===// 2198092Srdivacky// 3198092Srdivacky// The LLVM Compiler Infrastructure 4198092Srdivacky// 5198092Srdivacky// This file is distributed under the University of Illinois Open Source 6198092Srdivacky// License. See LICENSE.TXT for details. 7198092Srdivacky// 8198092Srdivacky//===----------------------------------------------------------------------===// 9198092Srdivacky// 10198092Srdivacky// This file defines several version-related utility functions for Clang. 11198092Srdivacky// 12198092Srdivacky//===----------------------------------------------------------------------===// 13202879Srdivacky 14202879Srdivacky#include "clang/Basic/Version.h" 15226890Sdim#include "clang/Basic/LLVM.h" 16252723Sdim#include "llvm/Config/config.h" 17202879Srdivacky#include "llvm/Support/raw_ostream.h" 18252723Sdim#include <cstdlib> 19198092Srdivacky#include <cstring> 20202879Srdivacky 21252723Sdim#ifdef HAVE_SVN_VERSION_INC 22252723Sdim# include "SVNVersion.inc" 23252723Sdim#endif 24252723Sdim 25198092Srdivackynamespace clang { 26235633Sdim 27218893Sdimstd::string getClangRepositoryPath() { 28221345Sdim#if defined(CLANG_REPOSITORY_STRING) 29221345Sdim return CLANG_REPOSITORY_STRING; 30221345Sdim#else 31218893Sdim#ifdef SVN_REPOSITORY 32226890Sdim StringRef URL(SVN_REPOSITORY); 33218893Sdim#else 34226890Sdim StringRef URL(""); 35218893Sdim#endif 36203955Srdivacky 37218893Sdim // If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us 38218893Sdim // pick up a tag in an SVN export, for example. 39266759Sdim StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_34/dot1-final/lib/Basic/Version.cpp $"); 40218893Sdim if (URL.empty()) { 41218893Sdim URL = SVNRepository.slice(SVNRepository.find(':'), 42218893Sdim SVNRepository.find("/lib/Basic")); 43218893Sdim } 44203955Srdivacky 45208600Srdivacky // Strip off version from a build from an integration branch. 46218893Sdim URL = URL.slice(0, URL.find("/src/tools/clang")); 47203955Srdivacky 48218893Sdim // Trim path prefix off, assuming path came from standard cfe path. 49218893Sdim size_t Start = URL.find("cfe/"); 50226890Sdim if (Start != StringRef::npos) 51218893Sdim URL = URL.substr(Start + 4); 52203955Srdivacky 53218893Sdim return URL; 54221345Sdim#endif 55198092Srdivacky} 56198092Srdivacky 57235633Sdimstd::string getLLVMRepositoryPath() { 58235633Sdim#ifdef LLVM_REPOSITORY 59235633Sdim StringRef URL(LLVM_REPOSITORY); 60235633Sdim#else 61235633Sdim StringRef URL(""); 62235633Sdim#endif 63235633Sdim 64235633Sdim // Trim path prefix off, assuming path came from standard llvm path. 65235633Sdim // Leave "llvm/" prefix to distinguish the following llvm revision from the 66235633Sdim // clang revision. 67235633Sdim size_t Start = URL.find("llvm/"); 68235633Sdim if (Start != StringRef::npos) 69235633Sdim URL = URL.substr(Start); 70235633Sdim 71235633Sdim return URL; 72235633Sdim} 73235633Sdim 74203955Srdivackystd::string getClangRevision() { 75204643Srdivacky#ifdef SVN_REVISION 76218893Sdim return SVN_REVISION; 77218893Sdim#else 78218893Sdim return ""; 79204643Srdivacky#endif 80198092Srdivacky} 81198092Srdivacky 82235633Sdimstd::string getLLVMRevision() { 83235633Sdim#ifdef LLVM_REVISION 84235633Sdim return LLVM_REVISION; 85235633Sdim#else 86235633Sdim return ""; 87235633Sdim#endif 88235633Sdim} 89235633Sdim 90203955Srdivackystd::string getClangFullRepositoryVersion() { 91203955Srdivacky std::string buf; 92203955Srdivacky llvm::raw_string_ostream OS(buf); 93218893Sdim std::string Path = getClangRepositoryPath(); 94218893Sdim std::string Revision = getClangRevision(); 95235633Sdim if (!Path.empty() || !Revision.empty()) { 96235633Sdim OS << '('; 97218893Sdim if (!Path.empty()) 98235633Sdim OS << Path; 99235633Sdim if (!Revision.empty()) { 100235633Sdim if (!Path.empty()) 101235633Sdim OS << ' '; 102235633Sdim OS << Revision; 103235633Sdim } 104235633Sdim OS << ')'; 105235633Sdim } 106235633Sdim // Support LLVM in a separate repository. 107235633Sdim std::string LLVMRev = getLLVMRevision(); 108235633Sdim if (!LLVMRev.empty() && LLVMRev != Revision) { 109235633Sdim OS << " ("; 110235633Sdim std::string LLVMRepo = getLLVMRepositoryPath(); 111235633Sdim if (!LLVMRepo.empty()) 112235633Sdim OS << LLVMRepo << ' '; 113235633Sdim OS << LLVMRev << ')'; 114218893Sdim } 115204793Srdivacky return OS.str(); 116202879Srdivacky} 117235633Sdim 118203955Srdivackystd::string getClangFullVersion() { 119203955Srdivacky std::string buf; 120203955Srdivacky llvm::raw_string_ostream OS(buf); 121202879Srdivacky#ifdef CLANG_VENDOR 122203955Srdivacky OS << CLANG_VENDOR; 123202879Srdivacky#endif 124235633Sdim OS << "clang version " CLANG_VERSION_STRING " " 125235633Sdim << getClangFullRepositoryVersion(); 126218893Sdim 127209107Sed#ifdef CLANG_VENDOR_SUFFIX 128209107Sed OS << CLANG_VENDOR_SUFFIX; 129218893Sdim#elif defined(CLANG_VENDOR) 130218893Sdim // If vendor supplied, include the base LLVM version as well. 131218893Sdim OS << " (based on LLVM " << PACKAGE_VERSION << ")"; 132209107Sed#endif 133218893Sdim 134204793Srdivacky return OS.str(); 135202879Srdivacky} 136203955Srdivacky 137221345Sdimstd::string getClangFullCPPVersion() { 138221345Sdim // The version string we report in __VERSION__ is just a compacted version of 139221345Sdim // the one we report on the command line. 140221345Sdim std::string buf; 141221345Sdim llvm::raw_string_ostream OS(buf); 142221345Sdim#ifdef CLANG_VENDOR 143221345Sdim OS << CLANG_VENDOR; 144221345Sdim#endif 145245431Sdim OS << "Clang " CLANG_VERSION_STRING " " << getClangFullRepositoryVersion(); 146221345Sdim return OS.str(); 147221345Sdim} 148221345Sdim 149198092Srdivacky} // end namespace clang 150