forked from OSchip/llvm-project
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:
parent
8277838cf8
commit
60b11f6dfd
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
Loading…
Reference in New Issue