mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Improve mapping of Clang diagnostics into Carbon diagnostics (#5894)
Instead of taking the complete text of the Clang diagnostic and using it as the message portion of a Carbon diagnostic, generate the individual pieces separately and pass them into the Carbon diagnostic infrastructure. * Clang's context lines are generated by running a custom "diagnostic renderer" and tracking which lines it wants to print as context for a given source location. When mapping from a C++ source location back to a Carbon location, the Carbon `Loc` structure is now fully populated, including filling in the context line and the column number. * Clang's snippet is generated by running a custom diagnostic renderer that is a cut-down version of the full text diagnostic renderer that only prints a snippet. This is then attached to the Carbon diagnostic manually as an override for the snippet we'd usually create. We no longer repeat the file location twice on each diagnostic, and no longer produce a bogus "in import" line for all locations coming from clang that point arbitrarily to the first C++ import in the Carbon file. The `[diagnostic kind]` marker is now displayed at the end of the diagnostic message, not on a line of its own after the snippet.
This commit is contained in:
+10
-6
@@ -50,11 +50,13 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "non_function_member_protected.h";
|
||||
|
||||
fn F(c: Cpp.C) {
|
||||
// CHECK:STDERR: fail_import_non_function_member_protected.carbon:[[@LINE+6]]:16: error: cannot access protected member `x` of type `Cpp.C` [ClassInvalidMemberAccess]
|
||||
// CHECK:STDERR: fail_import_non_function_member_protected.carbon:[[@LINE+8]]:16: error: cannot access protected member `x` of type `Cpp.C` [ClassInvalidMemberAccess]
|
||||
// CHECK:STDERR: let x: i32 = c.x;
|
||||
// CHECK:STDERR: ^~~
|
||||
// CHECK:STDERR: fail_import_non_function_member_protected.carbon:[[@LINE-6]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./non_function_member_protected.h:2: note: declared here [ClassMemberDeclaration]
|
||||
// CHECK:STDERR: fail_import_non_function_member_protected.carbon:[[@LINE-6]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./non_function_member_protected.h:2:7: note: declared here [ClassMemberDeclaration]
|
||||
// CHECK:STDERR: class C {
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
let x: i32 = c.x;
|
||||
}
|
||||
@@ -76,11 +78,13 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "non_function_member_private.h";
|
||||
|
||||
fn F(c: Cpp.C) {
|
||||
// CHECK:STDERR: fail_import_non_function_member_private.carbon:[[@LINE+6]]:16: error: cannot access private member `x` of type `Cpp.C` [ClassInvalidMemberAccess]
|
||||
// CHECK:STDERR: fail_import_non_function_member_private.carbon:[[@LINE+8]]:16: error: cannot access private member `x` of type `Cpp.C` [ClassInvalidMemberAccess]
|
||||
// CHECK:STDERR: let x: i32 = c.x;
|
||||
// CHECK:STDERR: ^~~
|
||||
// CHECK:STDERR: fail_import_non_function_member_private.carbon:[[@LINE-6]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./non_function_member_private.h:2: note: declared here [ClassMemberDeclaration]
|
||||
// CHECK:STDERR: fail_import_non_function_member_private.carbon:[[@LINE-6]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./non_function_member_private.h:2:7: note: declared here [ClassMemberDeclaration]
|
||||
// CHECK:STDERR: class C {
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
let x: i32 = c.x;
|
||||
}
|
||||
|
||||
+5
-3
@@ -35,11 +35,13 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "declaration.h";
|
||||
|
||||
fn MyF() {
|
||||
// CHECK:STDERR: fail_use_declaration_as_definition.carbon:[[@LINE+6]]:12: error: binding pattern has incomplete type `Bar` in name binding declaration [IncompleteTypeInBindingDecl]
|
||||
// CHECK:STDERR: fail_use_declaration_as_definition.carbon:[[@LINE+8]]:12: error: binding pattern has incomplete type `Bar` in name binding declaration [IncompleteTypeInBindingDecl]
|
||||
// CHECK:STDERR: var bar: Cpp.Bar;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_use_declaration_as_definition.carbon:[[@LINE-6]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./declaration.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: fail_use_declaration_as_definition.carbon:[[@LINE-6]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./declaration.h:2:7: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: class Bar;
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
var bar: Cpp.Bar;
|
||||
}
|
||||
|
||||
@@ -35,11 +35,13 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "declaration.h";
|
||||
|
||||
fn MyF() {
|
||||
// CHECK:STDERR: fail_use_declaration_as_definition.carbon:[[@LINE+6]]:12: error: binding pattern has incomplete type `Bar` in name binding declaration [IncompleteTypeInBindingDecl]
|
||||
// CHECK:STDERR: fail_use_declaration_as_definition.carbon:[[@LINE+8]]:12: error: binding pattern has incomplete type `Bar` in name binding declaration [IncompleteTypeInBindingDecl]
|
||||
// CHECK:STDERR: var bar: Cpp.Bar;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_use_declaration_as_definition.carbon:[[@LINE-6]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./declaration.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: fail_use_declaration_as_definition.carbon:[[@LINE-6]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./declaration.h:2:8: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: struct Bar;
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
var bar: Cpp.Bar;
|
||||
}
|
||||
|
||||
+26
-29
@@ -60,17 +60,14 @@ using Xint = X<int>;
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
// CHECK:STDERR: fail_use_instantiation_error.carbon:[[@LINE+11]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./instantiation_error.h:3: error: In file included from fail_use_instantiation_error.carbon:[[@LINE+10]]:
|
||||
// CHECK:STDERR: ./instantiation_error.h:3:25: error: type 'int' cannot be used prior to '::' because it has no members
|
||||
// CHECK:STDERR: fail_use_instantiation_error.carbon:[[@LINE+8]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./instantiation_error.h:3:25: error: type 'int' cannot be used prior to '::' because it has no members [CppInteropParseError]
|
||||
// CHECK:STDERR: 3 | using type = typename T::member;
|
||||
// CHECK:STDERR: | ^
|
||||
// CHECK:STDERR: [CppInteropParseError]
|
||||
// CHECK:STDERR: fail_use_instantiation_error.carbon:[[@LINE+5]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./instantiation_error.h:2: note: ./instantiation_error.h:2:29: note: in instantiation of template class 'X<int>' requested here
|
||||
// CHECK:STDERR: fail_use_instantiation_error.carbon:[[@LINE+4]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./instantiation_error.h:2:29: note: in instantiation of template class 'X<int>' requested here [CppInteropParseNote]
|
||||
// CHECK:STDERR: 2 | template<typename T> struct X {
|
||||
// CHECK:STDERR: | ^
|
||||
// CHECK:STDERR: [CppInteropParseNote]
|
||||
import Cpp library "instantiation_error.h";
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
@@ -173,11 +170,11 @@ var y: Cpp.Xint.r#type = 0;
|
||||
// CHECK:STDOUT: %x.var_patt: %pattern_type.7ce = var_pattern %x.patt [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %x.var: ref %i32 = var %x.var_patt [concrete]
|
||||
// CHECK:STDOUT: %.loc18: type = splice_block %type.ref.loc18 [concrete = constants.%i32] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc18: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %.loc15: type = splice_block %type.ref.loc15 [concrete = constants.%i32] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc15: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %XY.ref: type = name_ref XY, imports.%X.decl.dec4cb.1 [concrete = constants.%X.32d59e.1]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %type.ref.loc18: type = name_ref r#type, %i32.2 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %type.ref.loc15: type = name_ref r#type, %i32.2 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %x: ref %i32 = bind_name x, %x.var [concrete = %x.var]
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
@@ -185,33 +182,33 @@ var y: Cpp.Xint.r#type = 0;
|
||||
// CHECK:STDOUT: %y.var_patt: %pattern_type.7ce = var_pattern %y.patt [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %y.var: ref %i32 = var %y.var_patt [concrete]
|
||||
// CHECK:STDOUT: %.loc24: type = splice_block %type.ref.loc24 [concrete = constants.%i32] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc24: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %.loc21: type = splice_block %type.ref.loc21 [concrete = constants.%i32] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc21: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Xint.ref: type = name_ref Xint, imports.%X.decl.dec4cb.2 [concrete = constants.%X.32d59e.2]
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %type.ref.loc24: type = name_ref r#type, %i32.1 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %type.ref.loc21: type = name_ref r#type, %i32.1 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %y: ref %i32 = bind_name y, %y.var [concrete = %y.var]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @__global_init() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %int_0.loc18: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6]
|
||||
// CHECK:STDOUT: %impl.elem0.loc18: %.9c3 = impl_witness_access constants.%ImplicitAs.impl_witness.c75, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.956]
|
||||
// CHECK:STDOUT: %bound_method.loc18_1.1: <bound method> = bound_method %int_0.loc18, %impl.elem0.loc18 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound]
|
||||
// CHECK:STDOUT: %specific_fn.loc18: <specific function> = specific_function %impl.elem0.loc18, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc18_1.2: <bound method> = bound_method %int_0.loc18, %specific_fn.loc18 [concrete = constants.%bound_method]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc18: init %i32 = call %bound_method.loc18_1.2(%int_0.loc18) [concrete = constants.%int_0.6a9]
|
||||
// CHECK:STDOUT: %.loc18: init %i32 = converted %int_0.loc18, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc18 [concrete = constants.%int_0.6a9]
|
||||
// CHECK:STDOUT: assign file.%x.var, %.loc18
|
||||
// CHECK:STDOUT: %int_0.loc24: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6]
|
||||
// CHECK:STDOUT: %impl.elem0.loc24: %.9c3 = impl_witness_access constants.%ImplicitAs.impl_witness.c75, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.956]
|
||||
// CHECK:STDOUT: %bound_method.loc24_1.1: <bound method> = bound_method %int_0.loc24, %impl.elem0.loc24 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound]
|
||||
// CHECK:STDOUT: %specific_fn.loc24: <specific function> = specific_function %impl.elem0.loc24, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc24_1.2: <bound method> = bound_method %int_0.loc24, %specific_fn.loc24 [concrete = constants.%bound_method]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc24: init %i32 = call %bound_method.loc24_1.2(%int_0.loc24) [concrete = constants.%int_0.6a9]
|
||||
// CHECK:STDOUT: %.loc24: init %i32 = converted %int_0.loc24, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc24 [concrete = constants.%int_0.6a9]
|
||||
// CHECK:STDOUT: assign file.%y.var, %.loc24
|
||||
// CHECK:STDOUT: %int_0.loc15: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6]
|
||||
// CHECK:STDOUT: %impl.elem0.loc15: %.9c3 = impl_witness_access constants.%ImplicitAs.impl_witness.c75, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.956]
|
||||
// CHECK:STDOUT: %bound_method.loc15_1.1: <bound method> = bound_method %int_0.loc15, %impl.elem0.loc15 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound]
|
||||
// CHECK:STDOUT: %specific_fn.loc15: <specific function> = specific_function %impl.elem0.loc15, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc15_1.2: <bound method> = bound_method %int_0.loc15, %specific_fn.loc15 [concrete = constants.%bound_method]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc15: init %i32 = call %bound_method.loc15_1.2(%int_0.loc15) [concrete = constants.%int_0.6a9]
|
||||
// CHECK:STDOUT: %.loc15: init %i32 = converted %int_0.loc15, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc15 [concrete = constants.%int_0.6a9]
|
||||
// CHECK:STDOUT: assign file.%x.var, %.loc15
|
||||
// CHECK:STDOUT: %int_0.loc21: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6]
|
||||
// CHECK:STDOUT: %impl.elem0.loc21: %.9c3 = impl_witness_access constants.%ImplicitAs.impl_witness.c75, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.956]
|
||||
// CHECK:STDOUT: %bound_method.loc21_1.1: <bound method> = bound_method %int_0.loc21, %impl.elem0.loc21 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound]
|
||||
// CHECK:STDOUT: %specific_fn.loc21: <specific function> = specific_function %impl.elem0.loc21, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc21_1.2: <bound method> = bound_method %int_0.loc21, %specific_fn.loc21 [concrete = constants.%bound_method]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc21: init %i32 = call %bound_method.loc21_1.2(%int_0.loc21) [concrete = constants.%int_0.6a9]
|
||||
// CHECK:STDOUT: %.loc21: init %i32 = converted %int_0.loc21, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc21 [concrete = constants.%int_0.6a9]
|
||||
// CHECK:STDOUT: assign file.%y.var, %.loc21
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
+5
-3
@@ -35,11 +35,13 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "declaration.h";
|
||||
|
||||
fn MyF() {
|
||||
// CHECK:STDERR: fail_use_declaration_as_definition.carbon:[[@LINE+6]]:12: error: binding pattern has incomplete type `Bar` in name binding declaration [IncompleteTypeInBindingDecl]
|
||||
// CHECK:STDERR: fail_use_declaration_as_definition.carbon:[[@LINE+8]]:12: error: binding pattern has incomplete type `Bar` in name binding declaration [IncompleteTypeInBindingDecl]
|
||||
// CHECK:STDERR: var bar: Cpp.Bar;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_use_declaration_as_definition.carbon:[[@LINE-6]]:1: in import [InImport]
|
||||
// CHECK:STDERR: ./declaration.h:2: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: fail_use_declaration_as_definition.carbon:[[@LINE-6]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./declaration.h:2:7: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: union Bar;
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
var bar: Cpp.Bar;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user