aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-11-19 16:18:16 +0000
committerDouglas Gregor <dgregor@apple.com>2010-11-19 16:18:16 +0000
commitaa5f135f8db82b5e5fb1640fd51f8078e0b2d82d (patch)
treeab00b5c254a28d1098901e7f783eaee4c189d72f
parent3ffe6293123b8fe59bd9d6ed8e3ec755d68e7fac (diff)
Extend the libclang diagnostic API to provide information about the
option name, category ID, and category name corresponding to a diagnostic. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119802 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang-c/Index.h70
-rw-r--r--include/clang/Basic/Diagnostic.h5
-rw-r--r--lib/Basic/Diagnostic.cpp7
-rw-r--r--test/Index/code-complete-errors.c6
-rw-r--r--tools/c-index-test/c-index-test.c3
-rw-r--r--tools/libclang/CIndexDiagnostic.cpp93
-rw-r--r--tools/libclang/libclang.darwin.exports3
-rw-r--r--tools/libclang/libclang.exports3
8 files changed, 177 insertions, 13 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index e4edf3b944..2fc4089735 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -499,7 +499,34 @@ enum CXDiagnosticDisplayOptions {
* This option corresponds to the clang flag
* \c -fdiagnostics-print-source-range-info.
*/
- CXDiagnostic_DisplaySourceRanges = 0x04
+ CXDiagnostic_DisplaySourceRanges = 0x04,
+
+ /**
+ * \brief Display the option name associated with this diagnostic, if any.
+ *
+ * The option name displayed (e.g., -Wconversion) will be placed in brackets
+ * after the diagnostic text. This option corresponds to the clang flag
+ * \c -fdiagnostics-show-option.
+ */
+ CXDiagnostic_DisplayOption = 0x08,
+
+ /**
+ * \brief Display the category number associated with this diagnostic, if any.
+ *
+ * The category number is displayed within brackets after the diagnostic text.
+ * This option corresponds to the clang flag
+ * \c -fdiagnostics-show-category=id.
+ */
+ CXDiagnostic_DisplayCategoryId = 0x10,
+
+ /**
+ * \brief Display the category name associated with this diagnostic, if any.
+ *
+ * The category name is displayed within brackets after the diagnostic text.
+ * This option corresponds to the clang flag
+ * \c -fdiagnostics-show-category=name.
+ */
+ CXDiagnostic_DisplayCategoryName = 0x20
};
/**
@@ -530,10 +557,6 @@ CINDEX_LINKAGE CXString clang_formatDiagnostic(CXDiagnostic Diagnostic,
CINDEX_LINKAGE unsigned clang_defaultDiagnosticDisplayOptions(void);
/**
- * \brief Print a diagnostic to the given file.
- */
-
-/**
* \brief Determine the severity of the given diagnostic.
*/
CINDEX_LINKAGE enum CXDiagnosticSeverity
@@ -553,6 +576,43 @@ CINDEX_LINKAGE CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic);
CINDEX_LINKAGE CXString clang_getDiagnosticSpelling(CXDiagnostic);
/**
+ * \brief Retrieve the name of the command-line option that enabled this
+ * diagnostic.
+ *
+ * \param Diag The diagnostic to be queried.
+ *
+ * \param Disable If non-NULL, will be set to the option that disables this
+ * diagnostic (if any).
+ *
+ * \returns A string that contains the command-line option used to enable this
+ * warning, such as "-Wconversion" or "-pedantic".
+ */
+CINDEX_LINKAGE CXString clang_getDiagnosticOption(CXDiagnostic Diag,
+ CXString *Disable);
+
+/**
+ * \brief Retrieve the category number for this diagnostic.
+ *
+ * Diagnostics can be categorized into groups along with other, related
+ * diagnostics (e.g., diagnostics under the same warning flag). This routine
+ * retrieves the category number for the given diagnostic.
+ *
+ * \returns The number of the category that contains this diagnostic, or zero
+ * if this diagnostic is uncategorized.
+ */
+CINDEX_LINKAGE unsigned clang_getDiagnosticCategory(CXDiagnostic);
+
+/**
+ * \brief Retrieve the name of a particular diagnostic category.
+ *
+ * \param Category A diagnostic category number, as returned by
+ * \c clang_getDiagnosticCategory().
+ *
+ * \returns The name of the given diagnostic category.
+ */
+CINDEX_LINKAGE CXString clang_getDiagnosticCategoryName(unsigned Category);
+
+/**
* \brief Determine the number of source ranges associated with the given
* diagnostic.
*/
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index c4988e417d..b0ed3e1a17 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -876,6 +876,7 @@ public:
* corresponding source manager is destroyed.
*/
class StoredDiagnostic {
+ unsigned ID;
Diagnostic::Level Level;
FullSourceLoc Loc;
std::string Message;
@@ -885,12 +886,14 @@ class StoredDiagnostic {
public:
StoredDiagnostic();
StoredDiagnostic(Diagnostic::Level Level, const DiagnosticInfo &Info);
- StoredDiagnostic(Diagnostic::Level Level, llvm::StringRef Message);
+ StoredDiagnostic(Diagnostic::Level Level, unsigned ID,
+ llvm::StringRef Message);
~StoredDiagnostic();
/// \brief Evaluates true when this object stores a diagnostic.
operator bool() const { return Message.size() > 0; }
+ unsigned getID() const { return ID; }
Diagnostic::Level getLevel() const { return Level; }
const FullSourceLoc &getLocation() const { return Loc; }
llvm::StringRef getMessage() const { return Message; }
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp
index 858b70a712..83ae2c5187 100644
--- a/lib/Basic/Diagnostic.cpp
+++ b/lib/Basic/Diagnostic.cpp
@@ -547,13 +547,14 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
StoredDiagnostic::StoredDiagnostic() { }
-StoredDiagnostic::StoredDiagnostic(Diagnostic::Level Level,
+StoredDiagnostic::StoredDiagnostic(Diagnostic::Level Level, unsigned ID,
llvm::StringRef Message)
- : Level(Level), Loc(), Message(Message) { }
+ : Level(Level), ID(ID), Loc(), Message(Message) { }
StoredDiagnostic::StoredDiagnostic(Diagnostic::Level Level,
const DiagnosticInfo &Info)
- : Level(Level) {
+ : ID(Info.getID()), Level(Level)
+{
assert((Info.getLocation().isInvalid() || Info.hasSourceManager()) &&
"Valid source location without setting a source manager for diagnostic");
if (Info.getLocation().isValid())
diff --git a/test/Index/code-complete-errors.c b/test/Index/code-complete-errors.c
index 4fe213eca6..51cfb895e2 100644
--- a/test/Index/code-complete-errors.c
+++ b/test/Index/code-complete-errors.c
@@ -13,11 +13,13 @@ int f(int *ptr1, float *ptr2) {
#define expand_to_binary_function(ret, name, parm1, parm2, code) ret name(parm1, parm2) code
expand_to_binary_function(int, g, int *ip, float *fp, {
-// CHECK: code-complete-errors.c:17:15:{17:12-17:14}{17:18-17:20}: warning: comparison of distinct pointer types ('int *' and 'float *')
+ // CHECK: code-complete-errors.c:17:12:{17:9-17:24}: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
+ if (ip = (float*)fp) ;
+// CHECK: code-complete-errors.c:19:15:{19:12-19:14}{19:18-19:20}: warning: comparison of distinct pointer types ('int *' and 'float *')
return ip == fp;
})
void g() { }
-// RUN: c-index-test -code-completion-at=%s:19:12 -pedantic %s 2> %t
+// RUN: c-index-test -code-completion-at=%s:21:12 -pedantic %s 2> %t
// RUN: FileCheck -check-prefix=CHECK %s < %t
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index c13f0313f2..8e76dc0b8b 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -309,7 +309,8 @@ void PrintDiagnostic(CXDiagnostic Diagnostic) {
CXFile file;
CXString Msg;
unsigned display_opts = CXDiagnostic_DisplaySourceLocation
- | CXDiagnostic_DisplayColumn | CXDiagnostic_DisplaySourceRanges;
+ | CXDiagnostic_DisplayColumn | CXDiagnostic_DisplaySourceRanges
+ | CXDiagnostic_DisplayOption;
unsigned i, num_fixits;
if (clang_getDiagnosticSeverity(Diagnostic) == CXDiagnostic_Ignored)
diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp
index 35acd0da00..fa3b1cec7f 100644
--- a/tools/libclang/CIndexDiagnostic.cpp
+++ b/tools/libclang/CIndexDiagnostic.cpp
@@ -119,11 +119,61 @@ CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
else
Out << "<no diagnostic text>";
clang_disposeString(Text);
+
+ if (Options & (CXDiagnostic_DisplayOption | CXDiagnostic_DisplayCategoryId |
+ CXDiagnostic_DisplayCategoryName)) {
+ bool NeedBracket = true;
+ bool NeedComma = false;
+
+ if (Options & CXDiagnostic_DisplayOption) {
+ CXString OptionName = clang_getDiagnosticOption(Diagnostic, 0);
+ if (const char *OptionText = clang_getCString(OptionName)) {
+ if (OptionText[0]) {
+ Out << " [" << OptionText;
+ NeedBracket = false;
+ NeedComma = true;
+ }
+ }
+ clang_disposeString(OptionName);
+ }
+
+ if (Options & (CXDiagnostic_DisplayCategoryId |
+ CXDiagnostic_DisplayCategoryName)) {
+ if (unsigned CategoryID = clang_getDiagnosticCategory(Diagnostic)) {
+ if (Options & CXDiagnostic_DisplayCategoryId) {
+ if (NeedBracket)
+ Out << " [";
+ if (NeedComma)
+ Out << ", ";
+ Out << CategoryID;
+ NeedBracket = false;
+ NeedComma = true;
+ }
+
+ if (Options & CXDiagnostic_DisplayCategoryName) {
+ CXString CategoryName = clang_getDiagnosticCategoryName(CategoryID);
+ if (NeedBracket)
+ Out << " [";
+ if (NeedComma)
+ Out << ", ";
+ Out << clang_getCString(CategoryName);
+ NeedBracket = false;
+ NeedComma = true;
+ clang_disposeString(CategoryName);
+ }
+ }
+ }
+
+ if (!NeedBracket)
+ Out << "]";
+ }
+
return createCXString(Out.str(), true);
}
unsigned clang_defaultDiagnosticDisplayOptions() {
- return CXDiagnostic_DisplaySourceLocation | CXDiagnostic_DisplayColumn;
+ return CXDiagnostic_DisplaySourceLocation | CXDiagnostic_DisplayColumn |
+ CXDiagnostic_DisplayOption;
}
enum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) {
@@ -161,6 +211,47 @@ CXString clang_getDiagnosticSpelling(CXDiagnostic Diag) {
return createCXString(StoredDiag->Diag.getMessage(), false);
}
+CXString clang_getDiagnosticOption(CXDiagnostic Diag, CXString *Disable) {
+ if (Disable)
+ *Disable = createCXString("");
+
+ CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
+ if (!StoredDiag)
+ return createCXString("");
+
+ unsigned ID = StoredDiag->Diag.getID();
+ if (const char *Option = DiagnosticIDs::getWarningOptionForDiag(ID)) {
+ if (Disable)
+ *Disable = createCXString((llvm::Twine("-Wno-") + Option).str());
+ return createCXString((llvm::Twine("-W") + Option).str());
+ }
+
+ if (ID == diag::fatal_too_many_errors) {
+ if (Disable)
+ *Disable = createCXString("-ferror-limit=0");
+ return createCXString("-ferror-limit=");
+ }
+
+ bool EnabledByDefault;
+ if (DiagnosticIDs::isBuiltinExtensionDiag(ID, EnabledByDefault) &&
+ !EnabledByDefault)
+ return createCXString("-pedantic");
+
+ return createCXString("");
+}
+
+unsigned clang_getDiagnosticCategory(CXDiagnostic Diag) {
+ CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
+ if (!StoredDiag)
+ return 0;
+
+ return DiagnosticIDs::getCategoryNumberForDiag(StoredDiag->Diag.getID());
+}
+
+CXString clang_getDiagnosticCategoryName(unsigned Category) {
+ return createCXString(DiagnosticIDs::getCategoryNameFromID(Category));
+}
+
unsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) {
CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
if (!StoredDiag || StoredDiag->Diag.getLocation().isInvalid())
diff --git a/tools/libclang/libclang.darwin.exports b/tools/libclang/libclang.darwin.exports
index 09f3cf7d21..5e8abf2533 100644
--- a/tools/libclang/libclang.darwin.exports
+++ b/tools/libclang/libclang.darwin.exports
@@ -58,10 +58,13 @@ _clang_getCursorType
_clang_getCursorUSR
_clang_getDefinitionSpellingAndExtent
_clang_getDiagnostic
+_clang_getDiagnosticCategory
+_clang_getDiagnosticCategoryName
_clang_getDiagnosticFixIt
_clang_getDiagnosticLocation
_clang_getDiagnosticNumFixIts
_clang_getDiagnosticNumRanges
+_clang_getDiagnosticOption
_clang_getDiagnosticRange
_clang_getDiagnosticSeverity
_clang_getDiagnosticSpelling
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index 6cbd2c63b7..ca9a9d1016 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -58,10 +58,13 @@ clang_getCursorType
clang_getCursorUSR
clang_getDefinitionSpellingAndExtent
clang_getDiagnostic
+clang_getDiagnosticCategory
+clang_getDiagnosticCategoryName
clang_getDiagnosticFixIt
clang_getDiagnosticLocation
clang_getDiagnosticNumFixIts
clang_getDiagnosticNumRanges
+clang_getDiagnosticOption
clang_getDiagnosticRange
clang_getDiagnosticSeverity
clang_getDiagnosticSpelling