From c9b889044c8e1e2d6ab194e34e8b74f6998094fa Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 4 May 2010 21:13:21 +0000 Subject: [PATCH] When -fdiagnostics-print-source-range-info is specified, print the diagnostic category number in the [] at the end of the line. For example: $ cat t.c #include void foo() { printf("%s", 4); } $ clang t.c -fsyntax-only -fdiagnostics-print-source-range-info t.c:3:11:{3:10-3:12}{3:15-3:16}: warning: conversion specifies type 'char *' but the argument has type 'int' [-Wformat,1] printf("%s", 4); ~^ ~ 1 warning generated. Clients that want category information can now pick the number out of the output, rdar://7928231. More coming. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103053 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/Diagnostic.h | 8 +++++++ lib/Basic/Diagnostic.cpp | 29 ++++++++++++++++++++++ lib/Frontend/TextDiagnosticPrinter.cpp | 33 ++++++++++++++++++++++---- 3 files changed, 66 insertions(+), 4 deletions(-) diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h index 6b2912e2e8..62f06edb77 100644 --- a/include/clang/Basic/Diagnostic.h +++ b/include/clang/Basic/Diagnostic.h @@ -423,6 +423,14 @@ public: /// the diagnostic, this returns null. static const char *getWarningOptionForDiag(unsigned DiagID); + /// getWarningOptionForDiag - Return the category number that a specified + /// DiagID belongs to, or 0 if no category. + static unsigned getCategoryNumberForDiag(unsigned DiagID); + + /// getCategoryNameFromID - Given a category ID, return the name of the + /// category. + static const char *getCategoryNameFromID(unsigned CategoryID); + /// \brief Enumeration describing how the the emission of a diagnostic should /// be treated when it occurs during C++ template argument deduction. enum SFINAEResponse { diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp index 9e6f168f17..f48758b3be 100644 --- a/lib/Basic/Diagnostic.cpp +++ b/lib/Basic/Diagnostic.cpp @@ -127,6 +127,35 @@ const char *Diagnostic::getWarningOptionForDiag(unsigned DiagID) { return 0; } +/// getWarningOptionForDiag - Return the category number that a specified +/// DiagID belongs to, or 0 if no category. +unsigned Diagnostic::getCategoryNumberForDiag(unsigned DiagID) { + if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) + return Info->Category; + return 0; +} + +/// getCategoryNameFromID - Given a category ID, return the name of the +/// category, an empty string if CategoryID is zero, or null if CategoryID is +/// invalid. +const char *Diagnostic::getCategoryNameFromID(unsigned CategoryID) { + // Second the table of options, sorted by name for fast binary lookup. + static const char *CategoryNameTable[] = { +#define GET_CATEGORY_TABLE +#define CATEGORY(X) X, +#include "clang/Basic/DiagnosticGroups.inc" +#undef GET_CATEGORY_TABLE + "<>" + }; + static const size_t CategoryNameTableSize = + sizeof(CategoryNameTable) / sizeof(CategoryNameTable[0])-1; + + if (CategoryID >= CategoryNameTableSize) return 0; + return CategoryNameTable[CategoryID]; +} + + + Diagnostic::SFINAEResponse Diagnostic::getDiagnosticSFINAEResponse(unsigned DiagID) { if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) { diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp index 66ed956a22..46bdd75a0e 100644 --- a/lib/Frontend/TextDiagnosticPrinter.cpp +++ b/lib/Frontend/TextDiagnosticPrinter.cpp @@ -18,6 +18,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" #include using namespace clang; @@ -819,21 +820,45 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, llvm::SmallString<100> OutStr; Info.FormatDiagnostic(OutStr); + std::string OptionName; if (DiagOpts->ShowOptionNames) { if (const char *Opt = Diagnostic::getWarningOptionForDiag(Info.getID())) { - OutStr += " [-W"; - OutStr += Opt; - OutStr += ']'; + OptionName = "-W"; + OptionName += Opt; } else { // If the diagnostic is an extension diagnostic and not enabled by default // then it must have been turned on with -pedantic. bool EnabledByDefault; if (Diagnostic::isBuiltinExtensionDiag(Info.getID(), EnabledByDefault) && !EnabledByDefault) - OutStr += " [-pedantic]"; + OptionName = "-pedantic"; } } + + // If the user wants to see category information, include it too. + unsigned DiagCategory = 0; + if (DiagOpts->ShowSourceRanges) + DiagCategory = Diagnostic::getCategoryNumberForDiag(Info.getID()); + + // If there is any categorization information, include it. + if (!OptionName.empty() || DiagCategory != 0) { + bool NeedsComma = false; + OutStr += " ["; + + if (!OptionName.empty()) { + OutStr += OptionName; + NeedsComma = true; + } + + if (DiagCategory) { + if (NeedsComma) OutStr += ','; + OutStr += llvm::utostr(DiagCategory); + } + + OutStr += "]"; + } + if (DiagOpts->ShowColors) { // Print warnings, errors and fatal errors in bold, no color switch (Level) { -- 2.40.0