10b57cec5SDimitry Andric //===- Version.cpp - Clang Version Number -----------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines several version-related utility functions for Clang.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "clang/Basic/Version.h"
140b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
150b57cec5SDimitry Andric #include "clang/Config/config.h"
160b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
170b57cec5SDimitry Andric #include <cstdlib>
180b57cec5SDimitry Andric #include <cstring>
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric #include "VCSVersion.inc"
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric namespace clang {
230b57cec5SDimitry Andric 
getClangRepositoryPath()240b57cec5SDimitry Andric std::string getClangRepositoryPath() {
250b57cec5SDimitry Andric #if defined(CLANG_REPOSITORY_STRING)
260b57cec5SDimitry Andric   return CLANG_REPOSITORY_STRING;
270b57cec5SDimitry Andric #else
280b57cec5SDimitry Andric #ifdef CLANG_REPOSITORY
295ffd83dbSDimitry Andric   return CLANG_REPOSITORY;
300b57cec5SDimitry Andric #else
315ffd83dbSDimitry Andric   return "";
320b57cec5SDimitry Andric #endif
330b57cec5SDimitry Andric #endif
340b57cec5SDimitry Andric }
350b57cec5SDimitry Andric 
getLLVMRepositoryPath()360b57cec5SDimitry Andric std::string getLLVMRepositoryPath() {
370b57cec5SDimitry Andric #ifdef LLVM_REPOSITORY
385ffd83dbSDimitry Andric   return LLVM_REPOSITORY;
390b57cec5SDimitry Andric #else
405ffd83dbSDimitry Andric   return "";
410b57cec5SDimitry Andric #endif
420b57cec5SDimitry Andric }
430b57cec5SDimitry Andric 
getClangRevision()440b57cec5SDimitry Andric std::string getClangRevision() {
450b57cec5SDimitry Andric #ifdef CLANG_REVISION
460b57cec5SDimitry Andric   return CLANG_REVISION;
470b57cec5SDimitry Andric #else
480b57cec5SDimitry Andric   return "";
490b57cec5SDimitry Andric #endif
500b57cec5SDimitry Andric }
510b57cec5SDimitry Andric 
getLLVMRevision()520b57cec5SDimitry Andric std::string getLLVMRevision() {
530b57cec5SDimitry Andric #ifdef LLVM_REVISION
540b57cec5SDimitry Andric   return LLVM_REVISION;
550b57cec5SDimitry Andric #else
560b57cec5SDimitry Andric   return "";
570b57cec5SDimitry Andric #endif
580b57cec5SDimitry Andric }
590b57cec5SDimitry Andric 
getClangVendor()60cb14a3feSDimitry Andric std::string getClangVendor() {
61cb14a3feSDimitry Andric #ifdef CLANG_VENDOR
62cb14a3feSDimitry Andric   return CLANG_VENDOR;
63cb14a3feSDimitry Andric #else
64cb14a3feSDimitry Andric   return "";
65cb14a3feSDimitry Andric #endif
66cb14a3feSDimitry Andric }
67cb14a3feSDimitry Andric 
getClangFullRepositoryVersion()680b57cec5SDimitry Andric std::string getClangFullRepositoryVersion() {
690b57cec5SDimitry Andric   std::string buf;
700b57cec5SDimitry Andric   llvm::raw_string_ostream OS(buf);
710b57cec5SDimitry Andric   std::string Path = getClangRepositoryPath();
720b57cec5SDimitry Andric   std::string Revision = getClangRevision();
730b57cec5SDimitry Andric   if (!Path.empty() || !Revision.empty()) {
740b57cec5SDimitry Andric     OS << '(';
750b57cec5SDimitry Andric     if (!Path.empty())
760b57cec5SDimitry Andric       OS << Path;
770b57cec5SDimitry Andric     if (!Revision.empty()) {
780b57cec5SDimitry Andric       if (!Path.empty())
790b57cec5SDimitry Andric         OS << ' ';
800b57cec5SDimitry Andric       OS << Revision;
810b57cec5SDimitry Andric     }
820b57cec5SDimitry Andric     OS << ')';
830b57cec5SDimitry Andric   }
840b57cec5SDimitry Andric   // Support LLVM in a separate repository.
850b57cec5SDimitry Andric   std::string LLVMRev = getLLVMRevision();
860b57cec5SDimitry Andric   if (!LLVMRev.empty() && LLVMRev != Revision) {
870b57cec5SDimitry Andric     OS << " (";
880b57cec5SDimitry Andric     std::string LLVMRepo = getLLVMRepositoryPath();
890b57cec5SDimitry Andric     if (!LLVMRepo.empty())
900b57cec5SDimitry Andric       OS << LLVMRepo << ' ';
910b57cec5SDimitry Andric     OS << LLVMRev << ')';
920b57cec5SDimitry Andric   }
930eae32dcSDimitry Andric   return buf;
940b57cec5SDimitry Andric }
950b57cec5SDimitry Andric 
getClangFullVersion()960b57cec5SDimitry Andric std::string getClangFullVersion() {
970b57cec5SDimitry Andric   return getClangToolFullVersion("clang");
980b57cec5SDimitry Andric }
990b57cec5SDimitry Andric 
getClangToolFullVersion(StringRef ToolName)1000b57cec5SDimitry Andric std::string getClangToolFullVersion(StringRef ToolName) {
1010b57cec5SDimitry Andric   std::string buf;
1020b57cec5SDimitry Andric   llvm::raw_string_ostream OS(buf);
103cb14a3feSDimitry Andric   OS << getClangVendor() << ToolName << " version " CLANG_VERSION_STRING;
1045ffd83dbSDimitry Andric 
1055ffd83dbSDimitry Andric   std::string repo = getClangFullRepositoryVersion();
1065ffd83dbSDimitry Andric   if (!repo.empty()) {
1075ffd83dbSDimitry Andric     OS << " " << repo;
1085ffd83dbSDimitry Andric   }
1090b57cec5SDimitry Andric 
1100eae32dcSDimitry Andric   return buf;
1110b57cec5SDimitry Andric }
1120b57cec5SDimitry Andric 
getClangFullCPPVersion()1130b57cec5SDimitry Andric std::string getClangFullCPPVersion() {
1140b57cec5SDimitry Andric   // The version string we report in __VERSION__ is just a compacted version of
1150b57cec5SDimitry Andric   // the one we report on the command line.
1160b57cec5SDimitry Andric   std::string buf;
1170b57cec5SDimitry Andric   llvm::raw_string_ostream OS(buf);
118cb14a3feSDimitry Andric   OS << getClangVendor() << "Clang " CLANG_VERSION_STRING;
1195ffd83dbSDimitry Andric 
1205ffd83dbSDimitry Andric   std::string repo = getClangFullRepositoryVersion();
1215ffd83dbSDimitry Andric   if (!repo.empty()) {
1225ffd83dbSDimitry Andric     OS << " " << repo;
1235ffd83dbSDimitry Andric   }
1245ffd83dbSDimitry Andric 
1250eae32dcSDimitry Andric   return buf;
1260b57cec5SDimitry Andric }
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric } // end namespace clang
129