Skip to content

Commit b0ef868

Browse files
authored
Merge pull request #10331 from DougGregor/serialized-diag-category-url-next
[Serialized diagnostics] Encode category documentation URL in existing record
2 parents cf371cd + 09eb522 commit b0ef868

10 files changed

+81
-7
lines changed

clang/include/clang-c/CXDiagnostic.h

+8
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,14 @@ clang_getDiagnosticCategoryName(unsigned Category);
338338
*/
339339
CINDEX_LINKAGE CXString clang_getDiagnosticCategoryText(CXDiagnostic);
340340

341+
/**
342+
* Retrieve the diagnostic category's URL for a given diagnostic.
343+
*
344+
* \returns The URL that provides additional documentation for the
345+
* category of this diagnostic.
346+
*/
347+
CINDEX_LINKAGE CXString clang_getDiagnosticCategoryURL(CXDiagnostic);
348+
341349
/**
342350
* Determine the number of source ranges associated with the given
343351
* diagnostic.

clang/include/clang/Frontend/SerializedDiagnosticReader.h

+11
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,21 @@ class SerializedDiagnosticReader {
8989
virtual std::error_code visitEndOfDiagnostic() { return {}; }
9090

9191
/// Visit a category. This associates the category \c ID to a \c Name.
92+
///
93+
/// This entrypoint has been superseded by the overload that follows, which
94+
/// also takes a (possibly-empty) URL providing additional documentation for
95+
/// the category.
9296
virtual std::error_code visitCategoryRecord(unsigned ID, StringRef Name) {
9397
return {};
9498
}
9599

100+
/// Visit a category. This associates the category \c ID to a \c Name with
101+
/// a (possibly empty) URL.
102+
virtual std::error_code visitCategoryRecord(unsigned ID, StringRef Name,
103+
StringRef URL) {
104+
return visitCategoryRecord(ID, Name);
105+
}
106+
96107
/// Visit a flag. This associates the flag's \c ID to a \c Name.
97108
virtual std::error_code visitDiagFlagRecord(unsigned ID, StringRef Name) {
98109
return {};

clang/lib/Frontend/SerializedDiagnosticReader.cpp

+17-2
Original file line numberDiff line numberDiff line change
@@ -266,13 +266,28 @@ SerializedDiagnosticReader::readDiagnosticBlock(llvm::BitstreamCursor &Stream) {
266266
continue;
267267

268268
switch ((RecordIDs)RecID) {
269-
case RECORD_CATEGORY:
269+
case RECORD_CATEGORY: {
270270
// A category has ID and name size.
271271
if (Record.size() != 2)
272272
return SDError::MalformedDiagnosticRecord;
273-
if ((EC = visitCategoryRecord(Record[0], Blob)))
273+
274+
// Make sure the name size makes sense.
275+
unsigned NameLen = Record[1];
276+
if (NameLen > Blob.size())
277+
return SDError::MalformedDiagnosticRecord;
278+
279+
StringRef Name = Blob.substr(0, NameLen);
280+
StringRef URL;
281+
282+
// If the name didn't take up the full blob, and the character that
283+
// follows it is an '@', the rest is the category URL.
284+
if (NameLen < Blob.size() && Blob[NameLen] == '@')
285+
URL = Blob.substr(NameLen + 1);
286+
287+
if ((EC = visitCategoryRecord(Record[0], Name, URL)))
274288
return EC;
275289
continue;
290+
}
276291
case RECORD_DIAG:
277292
// A diagnostic has severity, location (4), category, flag, and message
278293
// size.

clang/tools/c-index-test/c-index-test.c

+10-2
Original file line numberDiff line numberDiff line change
@@ -4823,9 +4823,10 @@ static void printDiagnosticSet(
48234823
CXSourceLocation DiagLoc;
48244824
CXDiagnostic D;
48254825
CXFile File;
4826-
CXString FileName, DiagSpelling, DiagOption, DiagCat;
4826+
CXString FileName, DiagSpelling, DiagOption, DiagCat, DiagCatURL;
48274827
unsigned line, column, offset;
4828-
const char *FileNameStr = 0, *DiagOptionStr = 0, *DiagCatStr = 0;
4828+
const char *FileNameStr = 0, *DiagOptionStr = 0, *DiagCatStr = 0,
4829+
*DiagCatURLStr = 0;
48294830
const char *FileContents = 0;
48304831

48314832
D = clang_getDiagnosticInSet(Diags, i);
@@ -4883,13 +4884,20 @@ static void printDiagnosticSet(
48834884
fprintf(stderr, "%s\nEND CONTENTS OF FILE\n", FileContents);
48844885
}
48854886

4887+
DiagCatURL = clang_getDiagnosticCategoryURL(D);
4888+
DiagCatURLStr = clang_getCString(DiagCatURL);
4889+
if (DiagCatURLStr && DiagCatStr && DiagCatURLStr[0]) {
4890+
fprintf(stderr, "[%s]: <%s>\n", DiagCatStr, DiagCatURLStr);
4891+
}
4892+
48864893
/* Print subdiagnostics. */
48874894
printDiagnosticSet(clang_getChildDiagnostics(D), indent+2, TopDiags);
48884895

48894896
clang_disposeString(FileName);
48904897
clang_disposeString(DiagSpelling);
48914898
clang_disposeString(DiagOption);
48924899
clang_disposeString(DiagCat);
4900+
clang_disposeString(DiagCatURL);
48934901
}
48944902
}
48954903

clang/tools/libclang/CIndexDiagnostic.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class CXDiagnosticCustomNoteImpl : public CXDiagnosticImpl {
7070

7171
unsigned getCategory() const override { return 0; }
7272
CXString getCategoryText() const override { return cxstring::createEmpty(); }
73+
CXString getCategoryURL() const override { return cxstring::createEmpty(); }
7374

7475
unsigned getNumRanges() const override { return 0; }
7576
CXSourceRange getRange(unsigned Range) const override {
@@ -431,7 +432,13 @@ CXString clang_getDiagnosticCategoryText(CXDiagnostic Diag) {
431432
return D->getCategoryText();
432433
return cxstring::createEmpty();
433434
}
434-
435+
436+
CXString clang_getDiagnosticCategoryURL(CXDiagnostic Diag) {
437+
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
438+
return D->getCategoryURL();
439+
return cxstring::createEmpty();
440+
}
441+
435442
unsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) {
436443
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
437444
return D->getNumRanges();

clang/tools/libclang/CIndexDiagnostic.h

+6
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ class CXDiagnosticImpl {
9999
/// Return the category string of the diagnostic.
100100
virtual CXString getCategoryText() const = 0;
101101

102+
/// Return the category URL of the diagnostic.
103+
virtual CXString getCategoryURL() const = 0;
104+
102105
/// Return the number of source ranges for the diagnostic.
103106
virtual unsigned getNumRanges() const = 0;
104107

@@ -160,6 +163,9 @@ struct CXStoredDiagnostic : public CXDiagnosticImpl {
160163
/// Return the category string of the diagnostic.
161164
CXString getCategoryText() const override;
162165

166+
/// Return the category URL of the diagnostic.
167+
CXString getCategoryURL() const override;
168+
163169
/// Return the number of source ranges for the diagnostic.
164170
unsigned getNumRanges() const override;
165171

clang/tools/libclang/CXLoadedDiagnostic.cpp

+11-2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class CXLoadedDiagnosticSetImpl : public CXDiagnosticSetImpl {
4141

4242
llvm::BumpPtrAllocator Alloc;
4343
Strings Categories;
44+
Strings CategoryURLs;
4445
Strings WarningFlags;
4546
Strings FileNames;
4647

@@ -126,6 +127,10 @@ CXString CXLoadedDiagnostic::getCategoryText() const {
126127
return cxstring::createDup(CategoryText);
127128
}
128129

130+
CXString CXLoadedDiagnostic::getCategoryURL() const {
131+
return cxstring::createDup(CategoryURL);
132+
}
133+
129134
unsigned CXLoadedDiagnostic::getNumRanges() const {
130135
return Ranges.size();
131136
}
@@ -215,7 +220,8 @@ class DiagLoader : serialized_diags::SerializedDiagnosticReader {
215220
std::error_code visitStartOfDiagnostic() override;
216221
std::error_code visitEndOfDiagnostic() override;
217222

218-
std::error_code visitCategoryRecord(unsigned ID, StringRef Name) override;
223+
std::error_code visitCategoryRecord(unsigned ID, StringRef Name,
224+
StringRef URL) override;
219225

220226
std::error_code visitDiagFlagRecord(unsigned ID, StringRef Name) override;
221227

@@ -345,11 +351,13 @@ std::error_code DiagLoader::visitEndOfDiagnostic() {
345351
return std::error_code();
346352
}
347353

348-
std::error_code DiagLoader::visitCategoryRecord(unsigned ID, StringRef Name) {
354+
std::error_code DiagLoader::visitCategoryRecord(unsigned ID, StringRef Name,
355+
StringRef URL) {
349356
// FIXME: Why do we care about long strings?
350357
if (Name.size() > 65536)
351358
return reportInvalidFile("Out-of-bounds string in category");
352359
TopDiags->Categories[ID] = TopDiags->copyString(Name);
360+
TopDiags->CategoryURLs[ID] = TopDiags->copyString(URL);
353361
return std::error_code();
354362
}
355363

@@ -431,6 +439,7 @@ std::error_code DiagLoader::visitDiagnosticRecord(
431439
D.category = Category;
432440
D.DiagOption = Flag ? TopDiags->WarningFlags[Flag] : "";
433441
D.CategoryText = Category ? TopDiags->Categories[Category] : "";
442+
D.CategoryURL = Category ? TopDiags->CategoryURLs[Category] : "";
434443
D.Spelling = TopDiags->copyString(Message);
435444
return std::error_code();
436445
}

clang/tools/libclang/CXLoadedDiagnostic.h

+4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ class CXLoadedDiagnostic : public CXDiagnosticImpl {
4949
/// Return the category string of the diagnostic.
5050
CXString getCategoryText() const override;
5151

52+
/// Return the category URL of the diagnostic.
53+
CXString getCategoryURL() const override;
54+
5255
/// Return the number of source ranges for the diagnostic.
5356
unsigned getNumRanges() const override;
5457

@@ -89,6 +92,7 @@ class CXLoadedDiagnostic : public CXDiagnosticImpl {
8992
const char *Spelling;
9093
llvm::StringRef DiagOption;
9194
llvm::StringRef CategoryText;
95+
llvm::StringRef CategoryURL;
9296
unsigned severity;
9397
unsigned category;
9498
};

clang/tools/libclang/CXStoredDiagnostic.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ CXString CXStoredDiagnostic::getCategoryText() const {
7878
return cxstring::createRef(DiagnosticIDs::getCategoryNameFromID(catID));
7979
}
8080

81+
CXString CXStoredDiagnostic::getCategoryURL() const {
82+
// Clang does not currently provide URLs for its own diagnostics.
83+
return cxstring::createEmpty();
84+
}
85+
8186
unsigned CXStoredDiagnostic::getNumRanges() const {
8287
if (Diag.getLocation().isInvalid())
8388
return 0;

clang/tools/libclang/libclang.map

+1
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ LLVM_13 {
339339
clang_getDiagnosticCategory;
340340
clang_getDiagnosticCategoryName;
341341
clang_getDiagnosticCategoryText;
342+
clang_getDiagnosticCategoryURL;
342343
clang_getDiagnosticFixIt;
343344
clang_getDiagnosticInSet;
344345
clang_getDiagnosticLocation;

0 commit comments

Comments
 (0)