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 Dunbar std::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 Liu std::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 Dunbar std::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 Liu std::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 Kremenek std::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 Kremenek std::string getClangFullVersion() {
89b00d66e6SNico Weber   return getClangToolFullVersion("clang");
90b00d66e6SNico Weber }
91b00d66e6SNico Weber 
getClangToolFullVersion(StringRef ToolName)92b00d66e6SNico Weber std::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 Dunbar std::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