forked from OSchip/llvm-project
Extend the libclang diagnostic API to provide information about the
option name, category ID, and category name corresponding to a diagnostic. llvm-svn: 119802
This commit is contained in:
parent
336021f758
commit
a750e8e6d8
|
@ -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
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -529,10 +556,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.
|
||||
*/
|
||||
|
@ -552,6 +575,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.
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue