Skip to content

Commit 779acb3

Browse files
committed
[Diagnostics] Record diagnostic groups in serialized diagnostics
The serialized diagnostic format has some extra fields that we can adopt for diagnostic groups. Specifically: * Category: store the diagnostic group name here * Flags: extend the hack used by educational notes of placing Markdown file paths here
1 parent c7f9f2e commit 779acb3

File tree

4 files changed

+48
-9
lines changed

4 files changed

+48
-9
lines changed

include/swift/AST/DiagnosticGroups.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ constexpr const auto DiagGroupsCount = [] {
4141
struct DiagGroupInfo {
4242
DiagGroupID id;
4343
std::string_view name;
44-
std::string_view version;
44+
std::string_view documentationFile;
4545
llvm::ArrayRef<DiagGroupID> supergroups;
4646
llvm::ArrayRef<DiagGroupID> subgroups;
4747
llvm::ArrayRef<DiagID> diagnostics;

lib/AST/DiagnosticEngine.cpp

+19-3
Original file line numberDiff line numberDiff line change
@@ -1330,13 +1330,16 @@ DiagnosticEngine::diagnosticInfoForDiagnostic(const Diagnostic &diagnostic,
13301330
}
13311331
}
13321332

1333+
auto groupID = diagnostic.getGroupID();
13331334
StringRef Category;
13341335
if (isAPIDigesterBreakageDiagnostic(diagnostic.getID()))
13351336
Category = "api-digester-breaking-change";
13361337
else if (isDeprecationDiagnostic(diagnostic.getID()))
13371338
Category = "deprecation";
13381339
else if (isNoUsageDiagnostic(diagnostic.getID()))
13391340
Category = "no-usage";
1341+
else if (groupID != DiagGroupID::no_group)
1342+
Category = getDiagGroupInfoByID(groupID).name;
13401343

13411344
auto fixIts = diagnostic.getFixIts();
13421345
if (loc.isValid()) {
@@ -1362,12 +1365,13 @@ DiagnosticEngine::diagnosticInfoForDiagnostic(const Diagnostic &diagnostic,
13621365
}
13631366

13641367
llvm::StringRef format;
1365-
if (includeDiagnosticName)
1368+
if (includeDiagnosticName) {
13661369
format =
1367-
diagnosticStringWithNameFor(diagnostic.getID(), diagnostic.getGroupID(),
1370+
diagnosticStringWithNameFor(diagnostic.getID(), groupID,
13681371
getPrintDiagnosticNamesMode());
1369-
else
1372+
} else {
13701373
format = diagnosticStringFor(diagnostic.getID());
1374+
}
13711375

13721376
return DiagnosticInfo(diagnostic.getID(), loc, toDiagnosticKind(behavior),
13731377
format, diagnostic.getArgs(), Category,
@@ -1523,6 +1527,18 @@ void DiagnosticEngine::emitDiagnostic(const Diagnostic &diagnostic) {
15231527
educationalNotePaths.push_back(notePath.str().str());
15241528
++associatedNotes;
15251529
}
1530+
1531+
// Capture information about the diagnostic group along with the remaining
1532+
// educational notes.
1533+
auto groupID = diagnostic.getGroupID();
1534+
if (groupID != DiagGroupID::no_group) {
1535+
const auto &diagGroup = getDiagGroupInfoByID(groupID);
1536+
1537+
SmallString<128> docPath(getDiagnosticDocumentationPath());
1538+
llvm::sys::path::append(docPath, diagGroup.documentationFile);
1539+
educationalNotePaths.push_back(docPath.str().str());
1540+
}
1541+
15261542
info->EducationalNotePaths = educationalNotePaths;
15271543

15281544
for (auto &consumer : Consumers) {

lib/AST/DiagnosticGroups.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ constexpr const auto diagnosticGroupConnections = [] {
6868
constexpr auto diagnosticsCount = std::get<2>(sizes);
6969

7070
// Declare all edges
71-
#define GROUP(Name, Version) \
71+
#define GROUP(Name, DocsFile) \
7272
std::array<DiagGroupID, supergroupsCount[(size_t)DiagGroupID::Name]> \
7373
Name##_supergroups{}; \
7474
std::array<DiagGroupID, subgroupsCount[(size_t)DiagGroupID::Name]> \
@@ -92,15 +92,15 @@ constexpr const auto diagnosticGroupConnections = [] {
9292
#include "swift/AST/DiagnosticsAll.def"
9393

9494
// Produce the resulting structure with all the edges
95-
#define GROUP(Name, Version) \
95+
#define GROUP(Name, DocsFile) \
9696
GroupConnections(Name##_supergroups, Name##_subgroups, Name##_diagnostics),
9797
return std::tuple{
9898
#include "swift/AST/DiagnosticGroups.def"
9999
};
100100
}();
101101

102102
std::unordered_map<std::string_view, DiagGroupID> nameToIDMap{
103-
#define GROUP(Name, Version) {#Name, DiagGroupID::Name},
103+
#define GROUP(Name, DocsFile) {#Name, DiagGroupID::Name},
104104
#include "swift/AST/DiagnosticGroups.def"
105105
};
106106

@@ -119,11 +119,11 @@ void traverseDepthFirst(DiagGroupID id,
119119
} // end anonymous namespace
120120

121121
constexpr const std::array<DiagGroupInfo, DiagGroupsCount> diagnosticGroupsInfo{
122-
#define GROUP(Name, Version) \
122+
#define GROUP(Name, DocsFile) \
123123
DiagGroupInfo{ \
124124
DiagGroupID::Name, \
125125
#Name, \
126-
#Version, \
126+
DocsFile, \
127127
llvm::ArrayRef<DiagGroupID>( \
128128
std::get<(size_t)DiagGroupID::Name>(diagnosticGroupConnections) \
129129
.supergroups), \
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// %target-swift-frontend -no-color-diagnostics -print-diagnostic-groups -diagnostic-documentation-path %S/test-docs/ -typecheck %s -strict-memory-safety
2+
3+
// RUN: %empty-directory(%t)
4+
// RUN: %target-swift-frontend -typecheck -no-color-diagnostics -print-diagnostic-groups -diagnostic-documentation-path %S/test-docs/ -serialize-diagnostics-path %t/serialized.dia %s -strict-memory-safety
5+
// RUN: c-index-test -read-diagnostics %t/serialized.dia > %t/serialized.txt 2>&1
6+
// RUN: %FileCheck %s < %t/serialized.txt
7+
8+
@available(*, deprecated, message: "please do not use")
9+
func f() { }
10+
11+
func g() {
12+
f()
13+
// CHECK: [[@LINE-1]]:3: warning: 'f()' is deprecated: please do not use [DeprecatedDeclaration] [-W{{.*}}deprecated-declaration.md] [deprecation]
14+
}
15+
16+
17+
@unsafe
18+
func beCareful() { }
19+
20+
func test() {
21+
beCareful()
22+
// CHECK: [[@LINE-1]]:3: warning: expression uses unsafe constructs but is not marked with 'unsafe' [StrictMemorySafety] [-W{{.*}}strict-memory-safety.md] [StrictMemorySafety]
23+
}

0 commit comments

Comments
 (0)