1//===- Version.cpp - Clang Version Number -----------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines several version-related utility functions for Clang.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/Basic/Version.h"
14#include "clang/Basic/LLVM.h"
15#include "clang/Config/config.h"
16#include "llvm/Support/raw_ostream.h"
17#include <cstdlib>
18#include <cstring>
19
20#include "VCSVersion.inc"
21
22namespace clang {
23
24std::string getClangRepositoryPath() {
25#if defined(CLANG_REPOSITORY_STRING)
26  return CLANG_REPOSITORY_STRING;
27#else
28#ifdef CLANG_REPOSITORY
29  return CLANG_REPOSITORY;
30#else
31  return "";
32#endif
33#endif
34}
35
36std::string getLLVMRepositoryPath() {
37#ifdef LLVM_REPOSITORY
38  return LLVM_REPOSITORY;
39#else
40  return "";
41#endif
42}
43
44std::string getClangRevision() {
45#ifdef CLANG_REVISION
46  return CLANG_REVISION;
47#else
48  return "";
49#endif
50}
51
52std::string getLLVMRevision() {
53#ifdef LLVM_REVISION
54  return LLVM_REVISION;
55#else
56  return "";
57#endif
58}
59
60std::string getClangFullRepositoryVersion() {
61  std::string buf;
62  llvm::raw_string_ostream OS(buf);
63  std::string Path = getClangRepositoryPath();
64  std::string Revision = getClangRevision();
65  if (!Path.empty() || !Revision.empty()) {
66    OS << '(';
67    if (!Path.empty())
68      OS << Path;
69    if (!Revision.empty()) {
70      if (!Path.empty())
71        OS << ' ';
72      OS << Revision;
73    }
74    OS << ')';
75  }
76  // Support LLVM in a separate repository.
77  std::string LLVMRev = getLLVMRevision();
78  if (!LLVMRev.empty() && LLVMRev != Revision) {
79    OS << " (";
80    std::string LLVMRepo = getLLVMRepositoryPath();
81    if (!LLVMRepo.empty())
82      OS << LLVMRepo << ' ';
83    OS << LLVMRev << ')';
84  }
85  return OS.str();
86}
87
88std::string getClangFullVersion() {
89  return getClangToolFullVersion("clang");
90}
91
92std::string getClangToolFullVersion(StringRef ToolName) {
93  std::string buf;
94  llvm::raw_string_ostream OS(buf);
95#ifdef CLANG_VENDOR
96  OS << CLANG_VENDOR;
97#endif
98  OS << ToolName << " version " CLANG_VERSION_STRING;
99
100  std::string repo = getClangFullRepositoryVersion();
101  if (!repo.empty()) {
102    OS << " " << repo;
103  }
104
105  return OS.str();
106}
107
108std::string getClangFullCPPVersion() {
109  // The version string we report in __VERSION__ is just a compacted version of
110  // the one we report on the command line.
111  std::string buf;
112  llvm::raw_string_ostream OS(buf);
113#ifdef CLANG_VENDOR
114  OS << CLANG_VENDOR;
115#endif
116  OS << "Clang " CLANG_VERSION_STRING;
117
118  std::string repo = getClangFullRepositoryVersion();
119  if (!repo.empty()) {
120    OS << " " << repo;
121  }
122
123  return OS.str();
124}
125
126} // end namespace clang
127