When printing diagnostics in c-index-test, also print source ranges

and fix-it information, so we can see everything in one place. Along
the way, fix a few bugs with deserialization and query of diagnostics
in CIndex.

llvm-svn: 94768
This commit is contained in:
Douglas Gregor 2010-01-29 00:41:11 +00:00
parent 8277838cf8
commit 60b11f6dfd
4 changed files with 107 additions and 12 deletions

View File

@ -482,7 +482,7 @@ private:
/// DiagRanges - The list of ranges added to this diagnostic. It currently
/// only support 10 ranges, could easily be extended if needed.
const SourceRange *DiagRanges[10];
SourceRange DiagRanges[10];
enum { MaxCodeModificationHints = 3 };
@ -609,7 +609,7 @@ public:
sizeof(DiagObj->DiagRanges)/sizeof(DiagObj->DiagRanges[0]) &&
"Too many arguments to diagnostic!");
if (DiagObj)
DiagObj->DiagRanges[NumRanges++] = &R;
DiagObj->DiagRanges[NumRanges++] = R;
}
void AddCodeModificationHint(const CodeModificationHint &Hint) const {
@ -772,9 +772,9 @@ public:
return DiagObj->NumDiagRanges;
}
const SourceRange &getRange(unsigned Idx) const {
SourceRange getRange(unsigned Idx) const {
assert(Idx < DiagObj->NumDiagRanges && "Invalid diagnostic range index!");
return *DiagObj->DiagRanges[Idx];
return DiagObj->DiagRanges[Idx];
}
unsigned getNumCodeModificationHints() const {

View File

@ -1,16 +1,16 @@
_Complex cd; // CHECK: code-complete-errors.c:1:1: warning: plain '_Complex' requires a type specifier; assuming '_Complex double'
// CHECK: FIX-IT: Insert " double" at 1:9
struct s {
int x, y;;
};
int x, y;; // CHECK: code-complete-errors.c:4:12: warning: extra ';' inside a struct or union
}; // CHECK: FIX-IT: Remove 4:12-4:13
struct s s0 = { y: 5 }; // CHECK: code-complete-errors.c:7:20: warning: use of GNU old-style field designator extension
// CHECK: FIX-IT: Replace 7:17-7:19 with ".y = "
int f(int *ptr1, float *ptr2) {
return ptr1 != ptr2; // CHECK: code-complete-errors.c:10:15: warning: comparison of distinct pointer types ('int *' and 'float *')
return ptr1 != ptr2; // CHECK: code-complete-errors.c:10:15:{10:10-10:14}{10:18-10:22}: warning: comparison of distinct pointer types ('int *' and 'float *')
}
void g() { }
// RUN: c-index-test -code-completion-at=%s:13:12 %s 2> %t
// RUN: c-index-test -code-completion-at=%s:13:12 -pedantic %s 2> %t
// RUN: FileCheck -check-prefix=CHECK %s < %t

View File

@ -154,12 +154,21 @@ enum CXFixItKind clang_getDiagnosticFixItKind(CXDiagnostic Diag,
CXString clang_getDiagnosticFixItInsertion(CXDiagnostic Diag,
unsigned FixIt,
CXSourceLocation *Location) {
if (Location)
*Location = clang_getNullLocation();
CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
if (!StoredDiag || FixIt >= StoredDiag->Info.getNumCodeModificationHints())
return CIndexer::createCXString("");
const CodeModificationHint &Hint
= StoredDiag->Info.getCodeModificationHint(FixIt);
if (Location && StoredDiag->Info.getLocation().isValid())
*Location = translateSourceLocation(
StoredDiag->Info.getLocation().getManager(),
StoredDiag->LangOpts,
Hint.InsertionLoc);
return CIndexer::createCXString(Hint.CodeToInsert);
}
@ -180,6 +189,9 @@ CXSourceRange clang_getDiagnosticFixItRemoval(CXDiagnostic Diag,
CXString clang_getDiagnosticFixItReplacement(CXDiagnostic Diag,
unsigned FixIt,
CXSourceRange *Range) {
if (Range)
*Range = clang_getNullRange();
CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag);
if (!StoredDiag || FixIt >= StoredDiag->Info.getNumCodeModificationHints() ||
StoredDiag->Info.getLocation().isInvalid()) {

View File

@ -195,8 +195,36 @@ static void PrintDiagnosticCallback(CXDiagnostic Diagnostic,
/* Print file:line:column. */
clang_getInstantiationLocation(clang_getDiagnosticLocation(Diagnostic),
&file, &line, &column, 0);
if (file)
fprintf(out, "%s:%d:%d: ", clang_getFileName(file), line, column);
if (file) {
CXSourceRange *ranges = 0;
unsigned num_ranges;
unsigned i;
unsigned printed_any_ranges = 0;
fprintf(out, "%s:%d:%d:", clang_getFileName(file), line, column);
clang_getDiagnosticRanges(Diagnostic, &ranges, &num_ranges);
for (i = 0; i != num_ranges; ++i) {
CXFile start_file, end_file;
unsigned start_line, start_column, end_line, end_column;
clang_getInstantiationLocation(clang_getRangeStart(ranges[i]),
&start_file, &start_line, &start_column,0);
clang_getInstantiationLocation(clang_getRangeEnd(ranges[i]),
&end_file, &end_line, &end_column, 0);
if (start_file != end_file || start_file != file)
continue;
fprintf(out, "{%d:%d-%d:%d}", start_line, start_column, end_line,
end_column+1);
printed_any_ranges = 1;
}
clang_disposeDiagnosticRanges(ranges, num_ranges);
if (printed_any_ranges)
fprintf(out, ":");
fprintf(out, " ");
}
/* Print warning/error/etc. */
switch (severity) {
@ -213,6 +241,61 @@ static void PrintDiagnosticCallback(CXDiagnostic Diagnostic,
else
fprintf(out, "<no diagnostic text>\n");
clang_disposeString(text);
if (file) {
unsigned i, num_fixits = clang_getDiagnosticNumFixIts(Diagnostic);
for (i = 0; i != num_fixits; ++i) {
switch (clang_getDiagnosticFixItKind(Diagnostic, i)) {
case CXFixIt_Insertion: {
CXSourceLocation insertion_loc;
CXFile insertion_file;
unsigned insertion_line, insertion_column;
text = clang_getDiagnosticFixItInsertion(Diagnostic, i, &insertion_loc);
clang_getInstantiationLocation(insertion_loc, &insertion_file,
&insertion_line, &insertion_column, 0);
if (insertion_file == file)
fprintf(out, "FIX-IT: Insert \"%s\" at %d:%d\n",
clang_getCString(text), insertion_line, insertion_column);
clang_disposeString(text);
break;
}
case CXFixIt_Removal: {
CXFile start_file, end_file;
unsigned start_line, start_column, end_line, end_column;
CXSourceRange remove_range
= clang_getDiagnosticFixItRemoval(Diagnostic, i);
clang_getInstantiationLocation(clang_getRangeStart(remove_range),
&start_file, &start_line, &start_column,
0);
clang_getInstantiationLocation(clang_getRangeEnd(remove_range),
&end_file, &end_line, &end_column, 0);
if (start_file == file && end_file == file)
fprintf(out, "FIX-IT: Remove %d:%d-%d:%d\n",
start_line, start_column, end_line, end_column+1);
break;
}
case CXFixIt_Replacement: {
CXFile start_file, end_file;
unsigned start_line, start_column, end_line, end_column;
CXSourceRange remove_range;
text = clang_getDiagnosticFixItReplacement(Diagnostic, i,&remove_range);
clang_getInstantiationLocation(clang_getRangeStart(remove_range),
&start_file, &start_line, &start_column,
0);
clang_getInstantiationLocation(clang_getRangeEnd(remove_range),
&end_file, &end_line, &end_column, 0);
if (start_file == end_file)
fprintf(out, "FIX-IT: Replace %d:%d-%d:%d with \"%s\"\n",
start_line, start_column, end_line, end_column+1,
clang_getCString(text));
clang_disposeString(text);
break;
}
}
}
}
}
/******************************************************************************/