@@ -70,8 +70,10 @@ extension SerializedDiagnostics {
7070 public var level : Level
7171 /// The location the diagnostic was emitted at in the source file.
7272 public var location : SourceLocation ?
73- /// The diagnostic category. Currently only Clang emits this.
73+ /// The diagnostic category.
7474 public var category : String ?
75+ /// The diagnostic category documentation URL.
76+ public var categoryURL : String ?
7577 /// The corresponding diagnostic command-line flag. Currently only Clang emits this.
7678 public var flag : String ?
7779 /// Ranges in the source file associated with the diagnostic.
@@ -82,11 +84,12 @@ extension SerializedDiagnostics {
8284 fileprivate init ( records: [ SerializedDiagnostics . OwnedRecord ] ,
8385 filenameMap: [ UInt64 : String ] ,
8486 flagMap: [ UInt64 : String ] ,
85- categoryMap: [ UInt64 : String ] ) throws {
87+ categoryMap: CategoryMap ) throws {
8688 var text : String ? = nil
8789 var level : Level ? = nil
8890 var location : SourceLocation ? = nil
8991 var category : String ? = nil
92+ var categoryURL : String ? = nil
9093 var flag : String ? = nil
9194 var ranges : [ ( SourceLocation , SourceLocation ) ] = [ ]
9295 var fixIts : [ FixIt ] = [ ]
@@ -103,7 +106,14 @@ extension SerializedDiagnostics {
103106 level = Level ( rawValue: record. fields [ 0 ] )
104107 location = SourceLocation ( fields: record. fields [ 1 ... 4 ] ,
105108 filenameMap: filenameMap)
106- category = categoryMap [ record. fields [ 5 ] ]
109+
110+ if let categoryEntry = categoryMap [ record. fields [ 5 ] ] {
111+ category = categoryEntry. text
112+ categoryURL = categoryEntry. url
113+ } else {
114+ category = nil
115+ categoryURL = nil
116+ }
107117 flag = flagMap [ record. fields [ 6 ] ]
108118
109119 case . sourceRange:
@@ -142,6 +152,7 @@ extension SerializedDiagnostics {
142152 self . level = level
143153 self . location = location
144154 self . category = category
155+ self . categoryURL = categoryURL
145156 self . flag = flag
146157 self . fixIts = fixIts
147158 self . ranges = ranges
@@ -185,6 +196,8 @@ extension SerializedDiagnostics.Diagnostic: UnsafeSendable {}
185196#endif
186197
187198extension SerializedDiagnostics {
199+ typealias CategoryMap = [ UInt64 : ( text: String , url: String ? ) ]
200+
188201 private struct Reader : BitstreamVisitor {
189202 var diagnosticRecords : [ [ OwnedRecord ] ] = [ ]
190203 var activeBlocks : [ BlockID ] = [ ]
@@ -194,7 +207,7 @@ extension SerializedDiagnostics {
194207 var versionNumber : Int ? = nil
195208 var filenameMap = [ UInt64: String] ( )
196209 var flagMap = [ UInt64: String] ( )
197- var categoryMap = [ UInt64 : String ] ( )
210+ var categoryMap = CategoryMap ( )
198211
199212 func validate( signature: Bitcode . Signature ) throws {
200213 guard signature == . init( string: " DIAG " ) else { throw Error . badMagic }
@@ -244,9 +257,28 @@ extension SerializedDiagnostics {
244257 case . blob( let categoryBlob) = record. payload
245258 else { throw Error . malformedRecord }
246259
247- let categoryText = String ( decoding: categoryBlob, as: UTF8 . self)
260+ let categoryTextBlob = String ( decoding: categoryBlob, as: UTF8 . self)
248261 let categoryID = record. fields [ 0 ]
249- categoryMap [ categoryID] = categoryText
262+
263+ let categoryTextLength = Int ( record. fields [ 1 ] )
264+ if categoryTextLength > categoryTextBlob. count {
265+ throw Error . malformedRecord
266+ }
267+
268+ let categoryText = String ( categoryTextBlob. prefix ( categoryTextLength) )
269+ let afterCategoryText = categoryTextBlob. index (
270+ categoryTextBlob. startIndex,
271+ offsetBy: categoryTextLength
272+ )
273+ let categoryURL : String ?
274+ if afterCategoryText < categoryTextBlob. endIndex &&
275+ categoryTextBlob [ afterCategoryText] == " @ " {
276+ categoryURL = String ( categoryTextBlob [ afterCategoryText... ] . dropFirst ( ) )
277+ } else {
278+ categoryURL = nil
279+ }
280+
281+ categoryMap [ categoryID] = ( categoryText, categoryURL)
250282 case . flag:
251283 guard record. fields. count == 2 ,
252284 case . blob( let flagBlob) = record. payload
0 commit comments