|  | //===- Version.cpp - Clang Version Number -----------------------*- C++ -*-===// | 
|  | // | 
|  | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | // See https://llvm.org/LICENSE.txt for license information. | 
|  | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // This file defines several version-related utility functions for Clang. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "clang/Basic/Version.h" | 
|  | #include "clang/Basic/LLVM.h" | 
|  | #include "clang/Config/config.h" | 
|  | #include "llvm/Support/raw_ostream.h" | 
|  | #include <cstdlib> | 
|  | #include <cstring> | 
|  |  | 
|  | #ifdef HAVE_VCS_VERSION_INC | 
|  | #include "VCSVersion.inc" | 
|  | #endif | 
|  |  | 
|  | namespace clang { | 
|  |  | 
|  | std::string getClangRepositoryPath() { | 
|  | #if defined(CLANG_REPOSITORY_STRING) | 
|  | return CLANG_REPOSITORY_STRING; | 
|  | #else | 
|  | #ifdef CLANG_REPOSITORY | 
|  | StringRef URL(CLANG_REPOSITORY); | 
|  | #else | 
|  | StringRef URL(""); | 
|  | #endif | 
|  |  | 
|  | // If the CLANG_REPOSITORY is empty, try to use the SVN keyword. This helps us | 
|  | // pick up a tag in an SVN export, for example. | 
|  | StringRef SVNRepository("$URL$"); | 
|  | if (URL.empty()) { | 
|  | URL = SVNRepository.slice(SVNRepository.find(':'), | 
|  | SVNRepository.find("/lib/Basic")); | 
|  | } | 
|  |  | 
|  | // Strip off version from a build from an integration branch. | 
|  | URL = URL.slice(0, URL.find("/src/tools/clang")); | 
|  |  | 
|  | // Trim path prefix off, assuming path came from standard cfe path. | 
|  | size_t Start = URL.find("cfe/"); | 
|  | if (Start != StringRef::npos) | 
|  | URL = URL.substr(Start + 4); | 
|  |  | 
|  | return URL; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | std::string getLLVMRepositoryPath() { | 
|  | #ifdef LLVM_REPOSITORY | 
|  | StringRef URL(LLVM_REPOSITORY); | 
|  | #else | 
|  | StringRef URL(""); | 
|  | #endif | 
|  |  | 
|  | // Trim path prefix off, assuming path came from standard llvm path. | 
|  | // Leave "llvm/" prefix to distinguish the following llvm revision from the | 
|  | // clang revision. | 
|  | size_t Start = URL.find("llvm/"); | 
|  | if (Start != StringRef::npos) | 
|  | URL = URL.substr(Start); | 
|  |  | 
|  | return URL; | 
|  | } | 
|  |  | 
|  | std::string getClangRevision() { | 
|  | #ifdef CLANG_REVISION | 
|  | return CLANG_REVISION; | 
|  | #else | 
|  | return ""; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | std::string getLLVMRevision() { | 
|  | #ifdef LLVM_REVISION | 
|  | return LLVM_REVISION; | 
|  | #else | 
|  | return ""; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | std::string getClangFullRepositoryVersion() { | 
|  | std::string buf; | 
|  | llvm::raw_string_ostream OS(buf); | 
|  | std::string Path = getClangRepositoryPath(); | 
|  | std::string Revision = getClangRevision(); | 
|  | if (!Path.empty() || !Revision.empty()) { | 
|  | OS << '('; | 
|  | if (!Path.empty()) | 
|  | OS << Path; | 
|  | if (!Revision.empty()) { | 
|  | if (!Path.empty()) | 
|  | OS << ' '; | 
|  | OS << Revision; | 
|  | } | 
|  | OS << ')'; | 
|  | } | 
|  | // Support LLVM in a separate repository. | 
|  | std::string LLVMRev = getLLVMRevision(); | 
|  | if (!LLVMRev.empty() && LLVMRev != Revision) { | 
|  | OS << " ("; | 
|  | std::string LLVMRepo = getLLVMRepositoryPath(); | 
|  | if (!LLVMRepo.empty()) | 
|  | OS << LLVMRepo << ' '; | 
|  | OS << LLVMRev << ')'; | 
|  | } | 
|  | return OS.str(); | 
|  | } | 
|  |  | 
|  | std::string getClangFullVersion() { | 
|  | return getClangToolFullVersion("clang"); | 
|  | } | 
|  |  | 
|  | std::string getClangToolFullVersion(StringRef ToolName) { | 
|  | std::string buf; | 
|  | llvm::raw_string_ostream OS(buf); | 
|  | #ifdef CLANG_VENDOR | 
|  | OS << CLANG_VENDOR; | 
|  | #endif | 
|  | OS << ToolName << " version " CLANG_VERSION_STRING " " | 
|  | << getClangFullRepositoryVersion(); | 
|  |  | 
|  | // If vendor supplied, include the base LLVM version as well. | 
|  | #ifdef CLANG_VENDOR | 
|  | OS << " (based on " << BACKEND_PACKAGE_STRING << ")"; | 
|  | #endif | 
|  |  | 
|  | return OS.str(); | 
|  | } | 
|  |  | 
|  | std::string getClangFullCPPVersion() { | 
|  | // The version string we report in __VERSION__ is just a compacted version of | 
|  | // the one we report on the command line. | 
|  | std::string buf; | 
|  | llvm::raw_string_ostream OS(buf); | 
|  | #ifdef CLANG_VENDOR | 
|  | OS << CLANG_VENDOR; | 
|  | #endif | 
|  | OS << "Clang " CLANG_VERSION_STRING " " << getClangFullRepositoryVersion(); | 
|  | return OS.str(); | 
|  | } | 
|  |  | 
|  | } // end namespace clang |