xref: /llvm-project/clang/tools/diagtool/FindDiagnosticID.cpp (revision 6ad0788c332bb2043142954d300c49ac3e537f34)
1 //===- FindDiagnosticID.cpp - diagtool tool for finding diagnostic id -----===//
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 #include "DiagTool.h"
10 #include "DiagnosticNames.h"
11 #include "clang/Basic/AllDiagnostics.h"
12 #include "llvm/Support/CommandLine.h"
13 #include <optional>
14 
15 DEF_DIAGTOOL("find-diagnostic-id", "Print the id of the given diagnostic",
16              FindDiagnosticID)
17 
18 using namespace clang;
19 using namespace diagtool;
20 
getNameFromID(StringRef Name)21 static StringRef getNameFromID(StringRef Name) {
22   int DiagID;
23   if(!Name.getAsInteger(0, DiagID)) {
24     const DiagnosticRecord &Diag = getDiagnosticForID(DiagID);
25     return Diag.getName();
26   }
27   return StringRef();
28 }
29 
30 static std::optional<DiagnosticRecord>
findDiagnostic(ArrayRef<DiagnosticRecord> Diagnostics,StringRef Name)31 findDiagnostic(ArrayRef<DiagnosticRecord> Diagnostics, StringRef Name) {
32   for (const auto &Diag : Diagnostics) {
33     StringRef DiagName = Diag.getName();
34     if (DiagName == Name)
35       return Diag;
36   }
37   return std::nullopt;
38 }
39 
run(unsigned int argc,char ** argv,llvm::raw_ostream & OS)40 int FindDiagnosticID::run(unsigned int argc, char **argv,
41                           llvm::raw_ostream &OS) {
42   static llvm::cl::OptionCategory FindDiagnosticIDOptions(
43       "diagtool find-diagnostic-id options");
44 
45   static llvm::cl::opt<std::string> DiagnosticName(
46       llvm::cl::Positional, llvm::cl::desc("<diagnostic-name>"),
47       llvm::cl::Required, llvm::cl::cat(FindDiagnosticIDOptions));
48 
49   std::vector<const char *> Args;
50   Args.push_back("diagtool find-diagnostic-id");
51   for (const char *A : llvm::ArrayRef(argv, argc))
52     Args.push_back(A);
53 
54   llvm::cl::HideUnrelatedOptions(FindDiagnosticIDOptions);
55   llvm::cl::ParseCommandLineOptions((int)Args.size(), Args.data(),
56                                     "Diagnostic ID mapping utility");
57 
58   ArrayRef<DiagnosticRecord> AllDiagnostics = getBuiltinDiagnosticsByName();
59   std::optional<DiagnosticRecord> Diag =
60       findDiagnostic(AllDiagnostics, DiagnosticName);
61   if (!Diag) {
62     // Name to id failed, so try id to name.
63     auto Name = getNameFromID(DiagnosticName);
64     if (!Name.empty()) {
65       OS << Name << '\n';
66       return 0;
67     }
68 
69     llvm::errs() << "error: invalid diagnostic '" << DiagnosticName << "'\n";
70     return 1;
71   }
72   OS << Diag->DiagID << "\n";
73   return 0;
74 }
75