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 15DEF_DIAGTOOL("find-diagnostic-id", "Print the id of the given diagnostic", 16 FindDiagnosticID) 17 18using namespace clang; 19using namespace diagtool; 20 21static 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 30static std::optional<DiagnosticRecord> 31findDiagnostic(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 40int 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