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