Compilation: check if there is anything in the clang error bundle

As far as I can tell, clang emits empty diagnostics for hand-crafted
assembly files, however the diagnostics bundle is still well-formed,
it just does not contain any block beyond META comprising VERSION
record. This is most unfortunate as any errors in assembly source files
will not be caught and lead to panics down the line. The solution seems
to be to check for the number of parsed diagnostics before returning
back to the frontend. I based this on the existence of a similar
C exposed function in libclang.

For more context, here's what we see for some malformed C source file
in terms of serialized diagnostics:

```
* magic is fine
* Item{  .start_block=Block{ .name=Meta, .id=8, .len=2 } }
* Item{  .record=Rec{ .name=Version, .id=1, .operands={ 2 }, .blob= } }
* Item{  .end_block=Block{ .name=Meta, .id=8, .len=0 } }
* Item{  .start_block=Block{ .name=Diag, .id=9, .len=34 } }
* Item{  .record=Rec{ .name=FileName, .id=6, .operands={ 1, 0, 0, 7 }, .blob=68656c6c6f2e63 } }
* Item{  .record=Rec{ .name=CatName, .id=5, .operands={ 1, 29 }, .blob=4c65786963616c206f722050726570726f636573736f72204973737565 } }
* Item{  .record=Rec{ .name=DiagInfo, .id=2, .operands={ 4, 1, 1, 10, 9, 1, 0, 24 }, .blob=27737464696f2e68272066696c65206e6f7420666f756e64 } }
* Item{  .record=Rec{ .name=SrcRange, .id=3, .operands={ 1, 1, 10, 9, 1, 1, 19, 18 }, .blob= } }
* Item{  .end_block=Block{ .name=Diag, .id=9, .len=0 } }
Number of diagnostics: 1
```

And here's what we see for malformed ASM source file:

```
* magic is fine
* Item{  .start_block=Block{ .name=Meta, .id=8, .len=2 } }
* Item{  .record=Rec{ .name=Version, .id=1, .operands={ 2 }, .blob= } }
* Item{  .end_block=Block{ .name=Meta, .id=8, .len=0 } }
Number of diagnostics: 0
```
This commit is contained in:
Jakub Konka 2024-05-21 11:45:33 +02:00
parent 6a65561e3e
commit 2d481c9c88

View File

@ -621,8 +621,10 @@ pub const CObject = struct {
},
};
const bundle = try gpa.create(Bundle);
assert(stack.items.len == 1);
if (stack.items[0].sub_diags.items.len == 0) return error.EmptyDiagnosticsBundle;
const bundle = try gpa.create(Bundle);
bundle.* = .{
.file_names = file_names,
.category_names = category_names,