mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 10:41:03 +01:00
Add return value support to C++ thunks. (#5976)
Based on #5948. A couple of tricky parts: * When generating the C++ side of the thunk, we are given a pointer to the location to emplace the return value. The only mechanism C++ provides to perform this emplacement is using placement `operator new`, which requires a library function in the `<new>` header. We handle this by declaring that library function ourselves, and rely on Clang not actually needing a definition for it (which the standard library owns). * On the Carbon side of the thunk, we want to form an initializing expression as the result of the call. We don't have a way of expressing in SemIR that an initializing expression performs its initialization by storing through a pointer, so this PR adds a new initializing instruction, `InPlaceInit`, to model an initialization that's performed opaquely in-place.
This commit is contained in:
+69
-12
@@ -1642,11 +1642,17 @@ fn F() {
|
||||
// CHECK:STDOUT: --- import_bool_return.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %Bool.type: type = fn_type @Bool [concrete]
|
||||
// CHECK:STDOUT: %Bool: %Bool.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.831: type = pattern_type bool [concrete]
|
||||
// CHECK:STDOUT: %foo_bool.type: type = fn_type @foo_bool [concrete]
|
||||
// CHECK:STDOUT: %foo_bool: %foo_bool.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.bb2: type = ptr_type bool [concrete]
|
||||
// CHECK:STDOUT: %foo_bool__carbon_thunk.type: type = fn_type @foo_bool__carbon_thunk [concrete]
|
||||
// CHECK:STDOUT: %foo_bool__carbon_thunk: %foo_bool__carbon_thunk.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.655: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(bool) [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.8b7: %T.as.Destroy.impl.Op.type.655 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -1659,6 +1665,11 @@ fn F() {
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %foo_bool__carbon_thunk.decl: %foo_bool__carbon_thunk.type = fn_decl @foo_bool__carbon_thunk [concrete = constants.%foo_bool__carbon_thunk] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
@@ -1668,26 +1679,40 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo_bool.ref: %foo_bool.type = name_ref foo_bool, imports.%foo_bool.decl [concrete = constants.%foo_bool]
|
||||
// CHECK:STDOUT: %foo_bool.call: init bool = call %foo_bool.ref()
|
||||
// CHECK:STDOUT: %.loc8_30.1: ref bool = temporary_storage
|
||||
// CHECK:STDOUT: %addr.loc8_30.1: %ptr.bb2 = addr_of %.loc8_30.1
|
||||
// CHECK:STDOUT: %foo_bool__carbon_thunk.call: init %empty_tuple.type = call imports.%foo_bool__carbon_thunk.decl(%addr.loc8_30.1)
|
||||
// CHECK:STDOUT: %.loc8_30.2: init bool = in_place_init %foo_bool__carbon_thunk.call, %.loc8_30.1
|
||||
// CHECK:STDOUT: %.loc8_10.1: type = splice_block %.loc8_10.3 [concrete = bool] {
|
||||
// CHECK:STDOUT: %Bool.call: init type = call constants.%Bool() [concrete = bool]
|
||||
// CHECK:STDOUT: %.loc8_10.2: type = value_of_initializer %Bool.call [concrete = bool]
|
||||
// CHECK:STDOUT: %.loc8_10.3: type = converted %Bool.call, %.loc8_10.2 [concrete = bool]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %.loc8_30.1: bool = value_of_initializer %foo_bool.call
|
||||
// CHECK:STDOUT: %.loc8_30.2: bool = converted %foo_bool.call, %.loc8_30.1
|
||||
// CHECK:STDOUT: %x: bool = bind_name x, %.loc8_30.2
|
||||
// CHECK:STDOUT: %.loc8_30.3: bool = value_of_initializer %.loc8_30.2
|
||||
// CHECK:STDOUT: %.loc8_30.4: bool = converted %.loc8_30.2, %.loc8_30.3
|
||||
// CHECK:STDOUT: %x: bool = bind_name x, %.loc8_30.4
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc8_30.1, constants.%T.as.Destroy.impl.Op.8b7
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc8_30.1, %T.as.Destroy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: %addr.loc8_30.2: %ptr.bb2 = addr_of %.loc8_30.1
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc8_30.2)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- import_short_return.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %int_16: Core.IntLiteral = int_value 16 [concrete]
|
||||
// CHECK:STDOUT: %i16: type = class_type @Int, @Int(%int_16) [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.2f8: type = pattern_type %i16 [concrete]
|
||||
// CHECK:STDOUT: %foo_short.type: type = fn_type @foo_short [concrete]
|
||||
// CHECK:STDOUT: %foo_short: %foo_short.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.251: type = ptr_type %i16 [concrete]
|
||||
// CHECK:STDOUT: %foo_short__carbon_thunk.type: type = fn_type @foo_short__carbon_thunk [concrete]
|
||||
// CHECK:STDOUT: %foo_short__carbon_thunk: %foo_short__carbon_thunk.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Destroy.impl.Op.type.613: type = fn_type @Int.as.Destroy.impl.Op, @Int.as.Destroy.impl(%int_16) [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Destroy.impl.Op.536: %Int.as.Destroy.impl.Op.type.613 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -1700,6 +1725,11 @@ fn F() {
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %foo_short__carbon_thunk.decl: %foo_short__carbon_thunk.type = fn_decl @foo_short__carbon_thunk [concrete = constants.%foo_short__carbon_thunk] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
@@ -1709,14 +1739,22 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo_short.ref: %foo_short.type = name_ref foo_short, imports.%foo_short.decl [concrete = constants.%foo_short]
|
||||
// CHECK:STDOUT: %foo_short.call: init %i16 = call %foo_short.ref()
|
||||
// CHECK:STDOUT: %.loc8_30.1: ref %i16 = temporary_storage
|
||||
// CHECK:STDOUT: %addr.loc8_30.1: %ptr.251 = addr_of %.loc8_30.1
|
||||
// CHECK:STDOUT: %foo_short__carbon_thunk.call: init %empty_tuple.type = call imports.%foo_short__carbon_thunk.decl(%addr.loc8_30.1)
|
||||
// CHECK:STDOUT: %.loc8_30.2: init %i16 = in_place_init %foo_short__carbon_thunk.call, %.loc8_30.1
|
||||
// CHECK:STDOUT: %.loc8_10: type = splice_block %i16 [concrete = constants.%i16] {
|
||||
// CHECK:STDOUT: %int_16: Core.IntLiteral = int_value 16 [concrete = constants.%int_16]
|
||||
// CHECK:STDOUT: %i16: type = class_type @Int, @Int(constants.%int_16) [concrete = constants.%i16]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %.loc8_30.1: %i16 = value_of_initializer %foo_short.call
|
||||
// CHECK:STDOUT: %.loc8_30.2: %i16 = converted %foo_short.call, %.loc8_30.1
|
||||
// CHECK:STDOUT: %x: %i16 = bind_name x, %.loc8_30.2
|
||||
// CHECK:STDOUT: %.loc8_30.3: %i16 = value_of_initializer %.loc8_30.2
|
||||
// CHECK:STDOUT: %.loc8_30.4: %i16 = converted %.loc8_30.2, %.loc8_30.3
|
||||
// CHECK:STDOUT: %x: %i16 = bind_name x, %.loc8_30.4
|
||||
// CHECK:STDOUT: %Int.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc8_30.1, constants.%Int.as.Destroy.impl.Op.536
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc8_30.1, %Int.as.Destroy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: %addr.loc8_30.2: %ptr.251 = addr_of %.loc8_30.1
|
||||
// CHECK:STDOUT: %Int.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc8_30.2)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -1744,11 +1782,17 @@ fn F() {
|
||||
// CHECK:STDOUT: --- import_double_return.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete]
|
||||
// CHECK:STDOUT: %f64.d77: type = class_type @Float, @Float(%int_64) [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.0ae: type = pattern_type %f64.d77 [concrete]
|
||||
// CHECK:STDOUT: %foo_double.type: type = fn_type @foo_double [concrete]
|
||||
// CHECK:STDOUT: %foo_double: %foo_double.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.bcc: type = ptr_type %f64.d77 [concrete]
|
||||
// CHECK:STDOUT: %foo_double__carbon_thunk.type: type = fn_type @foo_double__carbon_thunk [concrete]
|
||||
// CHECK:STDOUT: %foo_double__carbon_thunk: %foo_double__carbon_thunk.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Float.as.Destroy.impl.Op.type.cd5: type = fn_type @Float.as.Destroy.impl.Op, @Float.as.Destroy.impl(%int_64) [concrete]
|
||||
// CHECK:STDOUT: %Float.as.Destroy.impl.Op.b8c: %Float.as.Destroy.impl.Op.type.cd5 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -1761,6 +1805,11 @@ fn F() {
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %foo_double__carbon_thunk.decl: %foo_double__carbon_thunk.type = fn_decl @foo_double__carbon_thunk [concrete = constants.%foo_double__carbon_thunk] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
@@ -1770,14 +1819,22 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo_double.ref: %foo_double.type = name_ref foo_double, imports.%foo_double.decl [concrete = constants.%foo_double]
|
||||
// CHECK:STDOUT: %foo_double.call: init %f64.d77 = call %foo_double.ref()
|
||||
// CHECK:STDOUT: %.loc8_31.1: ref %f64.d77 = temporary_storage
|
||||
// CHECK:STDOUT: %addr.loc8_31.1: %ptr.bcc = addr_of %.loc8_31.1
|
||||
// CHECK:STDOUT: %foo_double__carbon_thunk.call: init %empty_tuple.type = call imports.%foo_double__carbon_thunk.decl(%addr.loc8_31.1)
|
||||
// CHECK:STDOUT: %.loc8_31.2: init %f64.d77 = in_place_init %foo_double__carbon_thunk.call, %.loc8_31.1
|
||||
// CHECK:STDOUT: %.loc8_10: type = splice_block %f64 [concrete = constants.%f64.d77] {
|
||||
// CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete = constants.%int_64]
|
||||
// CHECK:STDOUT: %f64: type = class_type @Float, @Float(constants.%int_64) [concrete = constants.%f64.d77]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %.loc8_31.1: %f64.d77 = value_of_initializer %foo_double.call
|
||||
// CHECK:STDOUT: %.loc8_31.2: %f64.d77 = converted %foo_double.call, %.loc8_31.1
|
||||
// CHECK:STDOUT: %x: %f64.d77 = bind_name x, %.loc8_31.2
|
||||
// CHECK:STDOUT: %.loc8_31.3: %f64.d77 = value_of_initializer %.loc8_31.2
|
||||
// CHECK:STDOUT: %.loc8_31.4: %f64.d77 = converted %.loc8_31.2, %.loc8_31.3
|
||||
// CHECK:STDOUT: %x: %f64.d77 = bind_name x, %.loc8_31.4
|
||||
// CHECK:STDOUT: %Float.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc8_31.1, constants.%Float.as.Destroy.impl.Op.b8c
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc8_31.1, %Float.as.Destroy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: %addr.loc8_31.2: %ptr.bcc = addr_of %.loc8_31.1
|
||||
// CHECK:STDOUT: %Float.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc8_31.2)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
+31
-6
@@ -447,13 +447,29 @@ auto foo() -> C;
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+12]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:4:6: error: calling 'foo' with incomplete return type 'C' [CppInteropParseError]
|
||||
// CHECK:STDERR: 4 | auto foo() -> C;
|
||||
// CHECK:STDERR: | ^~~
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+8]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:4:6: note: 'foo' declared here [CppInteropParseNote]
|
||||
// CHECK:STDERR: 4 | auto foo() -> C;
|
||||
// CHECK:STDERR: | ^
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+4]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:2:7: note: forward declaration of 'C' [CppInteropParseNote]
|
||||
// CHECK:STDERR: 2 | class C;
|
||||
// CHECK:STDERR: | ^
|
||||
import Cpp library "decl_value_return_type.h";
|
||||
|
||||
fn F() {
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+13]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
|
||||
// CHECK:STDERR: Cpp.foo();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+9]]:3: error: function returns incomplete type `Cpp.C` [IncompleteTypeInFunctionReturnType]
|
||||
// CHECK:STDERR: Cpp.foo();
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE-6]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE-10]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:2:7: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: class C;
|
||||
// CHECK:STDERR: ^
|
||||
@@ -1157,9 +1173,11 @@ fn F() {
|
||||
// CHECK:STDOUT: %C: type = class_type @C [concrete]
|
||||
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
|
||||
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.d9e: type = ptr_type %C [concrete]
|
||||
// CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete]
|
||||
// CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.1b3: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.21b: %T.as.Destroy.impl.Op.type.1b3 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.d9e: type = ptr_type %C [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -1172,6 +1190,11 @@ fn F() {
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
@@ -1179,13 +1202,15 @@ fn F() {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_11.1: ref %C = temporary_storage
|
||||
// CHECK:STDOUT: %foo.call: init %C = call %foo.ref() to %.loc8_11.1
|
||||
// CHECK:STDOUT: %.loc8_11.2: ref %C = temporary %.loc8_11.1, %foo.call
|
||||
// CHECK:STDOUT: %addr.loc8_11.1: %ptr.d9e = addr_of %.loc8_11.1
|
||||
// CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr.loc8_11.1)
|
||||
// CHECK:STDOUT: %.loc8_11.2: init %C = in_place_init %foo__carbon_thunk.call, %.loc8_11.1
|
||||
// CHECK:STDOUT: %.loc8_11.3: ref %C = temporary %.loc8_11.1, %.loc8_11.2
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc8_11.1, constants.%T.as.Destroy.impl.Op.21b
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc8_11.1, %T.as.Destroy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: %addr: %ptr.d9e = addr_of %.loc8_11.1
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr)
|
||||
// CHECK:STDOUT: %addr.loc8_11.2: %ptr.d9e = addr_of %.loc8_11.1
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc8_11.2)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
@@ -284,6 +284,7 @@ fn F() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %int_16: Core.IntLiteral = int_value 16 [concrete]
|
||||
// CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete]
|
||||
@@ -292,11 +293,20 @@ fn F() {
|
||||
// CHECK:STDOUT: %pattern_type.2f8: type = pattern_type %i16 [concrete]
|
||||
// CHECK:STDOUT: %foo_short.type: type = fn_type @foo_short [concrete]
|
||||
// CHECK:STDOUT: %foo_short: %foo_short.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.251: type = ptr_type %i16 [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.54c: type = pattern_type %ptr.251 [concrete]
|
||||
// CHECK:STDOUT: %foo_short__carbon_thunk.type: type = fn_type @foo_short__carbon_thunk [concrete]
|
||||
// CHECK:STDOUT: %foo_short__carbon_thunk: %foo_short__carbon_thunk.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Destroy.impl.Op.type.613: type = fn_type @Int.as.Destroy.impl.Op, @Int.as.Destroy.impl(%int_16) [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Destroy.impl.Op.536: %Int.as.Destroy.impl.Op.type.613 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Destroy.impl.Op.specific_fn: <specific function> = specific_function %Int.as.Destroy.impl.Op.536, @Int.as.Destroy.impl.Op(%int_16) [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [concrete] {
|
||||
// CHECK:STDOUT: .Int = %Core.Int
|
||||
// CHECK:STDOUT: .Destroy = %Core.Destroy
|
||||
// CHECK:STDOUT: import Core//prelude
|
||||
// CHECK:STDOUT: import Core//prelude/...
|
||||
// CHECK:STDOUT: }
|
||||
@@ -314,6 +324,18 @@ fn F() {
|
||||
// CHECK:STDOUT: %return.param: ref %i16 = out_param call_param0
|
||||
// CHECK:STDOUT: %return: ref %i16 = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %foo_short__carbon_thunk.decl: %foo_short__carbon_thunk.type = fn_decl @foo_short__carbon_thunk [concrete = constants.%foo_short__carbon_thunk] {
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.54c = binding_pattern r#return [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.54c = value_param_pattern %return.patt, call_param0 [concrete]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %return.param: %ptr.251 = value_param call_param0
|
||||
// CHECK:STDOUT: %.1: type = splice_block constants.%ptr.251 [concrete = constants.%ptr.251] {
|
||||
// CHECK:STDOUT: %int_16: Core.IntLiteral = int_value 16 [concrete = constants.%int_16]
|
||||
// CHECK:STDOUT: %i16: type = class_type @Int, @Int(constants.%int_16) [concrete = constants.%i16]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %return: %ptr.251 = bind_name r#return, %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
@@ -336,16 +358,26 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo_short.ref: %foo_short.type = name_ref foo_short, imports.%foo_short.decl [concrete = constants.%foo_short]
|
||||
// CHECK:STDOUT: %foo_short.call: init %i16 = call %foo_short.ref()
|
||||
// CHECK:STDOUT: %.loc7_30.1: ref %i16 = temporary_storage
|
||||
// CHECK:STDOUT: %addr.loc7_30.1: %ptr.251 = addr_of %.loc7_30.1
|
||||
// CHECK:STDOUT: %foo_short__carbon_thunk.call: init %empty_tuple.type = call imports.%foo_short__carbon_thunk.decl(%addr.loc7_30.1)
|
||||
// CHECK:STDOUT: %.loc7_30.2: init %i16 = in_place_init %foo_short__carbon_thunk.call, %.loc7_30.1
|
||||
// CHECK:STDOUT: %.loc7_10: type = splice_block %i16 [concrete = constants.%i16] {
|
||||
// CHECK:STDOUT: %int_16: Core.IntLiteral = int_value 16 [concrete = constants.%int_16]
|
||||
// CHECK:STDOUT: %i16: type = class_type @Int, @Int(constants.%int_16) [concrete = constants.%i16]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %.loc7_30.1: %i16 = value_of_initializer %foo_short.call
|
||||
// CHECK:STDOUT: %.loc7_30.2: %i16 = converted %foo_short.call, %.loc7_30.1
|
||||
// CHECK:STDOUT: %x: %i16 = bind_name x, %.loc7_30.2
|
||||
// CHECK:STDOUT: %.loc7_30.3: %i16 = value_of_initializer %.loc7_30.2
|
||||
// CHECK:STDOUT: %.loc7_30.4: %i16 = converted %.loc7_30.2, %.loc7_30.3
|
||||
// CHECK:STDOUT: %x: %i16 = bind_name x, %.loc7_30.4
|
||||
// CHECK:STDOUT: %Int.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc7_30.1, constants.%Int.as.Destroy.impl.Op.536
|
||||
// CHECK:STDOUT: %Int.as.Destroy.impl.Op.specific_fn: <specific function> = specific_function constants.%Int.as.Destroy.impl.Op.536, @Int.as.Destroy.impl.Op(constants.%int_16) [concrete = constants.%Int.as.Destroy.impl.Op.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc7_30.1, %Int.as.Destroy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: %addr.loc7_30.2: %ptr.251 = addr_of %.loc7_30.1
|
||||
// CHECK:STDOUT: %Int.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc7_30.2)
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @foo_short() -> %i16;
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @foo_short__carbon_thunk(%return.param: %ptr.251);
|
||||
// CHECK:STDOUT:
|
||||
|
||||
+22
-4
@@ -49,8 +49,13 @@ fn F() {
|
||||
// CHECK:STDOUT: %IngestI32: %IngestI32.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %foo1.type: type = fn_type @foo1 [concrete]
|
||||
// CHECK:STDOUT: %foo1: %foo1.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.251: type = ptr_type %i16 [concrete]
|
||||
// CHECK:STDOUT: %foo1__carbon_thunk.type: type = fn_type @foo1__carbon_thunk [concrete]
|
||||
// CHECK:STDOUT: %foo1__carbon_thunk: %foo1__carbon_thunk.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %foo2.type: type = fn_type @foo2 [concrete]
|
||||
// CHECK:STDOUT: %foo2: %foo2.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Destroy.impl.Op.type.613: type = fn_type @Int.as.Destroy.impl.Op, @Int.as.Destroy.impl(%int_16) [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Destroy.impl.Op.536: %Int.as.Destroy.impl.Op.type.613 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -64,6 +69,11 @@ fn F() {
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %foo1__carbon_thunk.decl: %foo1__carbon_thunk.type = fn_decl @foo1__carbon_thunk [concrete = constants.%foo1__carbon_thunk] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %foo2.decl: %foo2.type = fn_decl @foo2 [concrete = constants.%foo2] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
@@ -76,10 +86,13 @@ fn F() {
|
||||
// CHECK:STDOUT: %IngestI16.ref: %IngestI16.type = name_ref IngestI16, file.%IngestI16.decl [concrete = constants.%IngestI16]
|
||||
// CHECK:STDOUT: %Cpp.ref.loc11: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo1.ref: %foo1.type = name_ref foo1, imports.%foo1.decl [concrete = constants.%foo1]
|
||||
// CHECK:STDOUT: %foo1.call: init %i16 = call %foo1.ref()
|
||||
// CHECK:STDOUT: %.loc11_22.1: %i16 = value_of_initializer %foo1.call
|
||||
// CHECK:STDOUT: %.loc11_22.2: %i16 = converted %foo1.call, %.loc11_22.1
|
||||
// CHECK:STDOUT: %IngestI16.call: init %empty_tuple.type = call %IngestI16.ref(%.loc11_22.2)
|
||||
// CHECK:STDOUT: %.loc11_22.1: ref %i16 = temporary_storage
|
||||
// CHECK:STDOUT: %addr.loc11_22.1: %ptr.251 = addr_of %.loc11_22.1
|
||||
// CHECK:STDOUT: %foo1__carbon_thunk.call: init %empty_tuple.type = call imports.%foo1__carbon_thunk.decl(%addr.loc11_22.1)
|
||||
// CHECK:STDOUT: %.loc11_22.2: init %i16 = in_place_init %foo1__carbon_thunk.call, %.loc11_22.1
|
||||
// CHECK:STDOUT: %.loc11_22.3: %i16 = value_of_initializer %.loc11_22.2
|
||||
// CHECK:STDOUT: %.loc11_22.4: %i16 = converted %.loc11_22.2, %.loc11_22.3
|
||||
// CHECK:STDOUT: %IngestI16.call: init %empty_tuple.type = call %IngestI16.ref(%.loc11_22.4)
|
||||
// CHECK:STDOUT: %IngestI32.ref: %IngestI32.type = name_ref IngestI32, file.%IngestI32.decl [concrete = constants.%IngestI32]
|
||||
// CHECK:STDOUT: %Cpp.ref.loc12: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo2.ref: %foo2.type = name_ref foo2, imports.%foo2.decl [concrete = constants.%foo2]
|
||||
@@ -87,6 +100,11 @@ fn F() {
|
||||
// CHECK:STDOUT: %.loc12_22.1: %i32 = value_of_initializer %foo2.call
|
||||
// CHECK:STDOUT: %.loc12_22.2: %i32 = converted %foo2.call, %.loc12_22.1
|
||||
// CHECK:STDOUT: %IngestI32.call: init %empty_tuple.type = call %IngestI32.ref(%.loc12_22.2)
|
||||
// CHECK:STDOUT: %Int.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc11_22.1, constants.%Int.as.Destroy.impl.Op.536
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc11_22.1, %Int.as.Destroy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: %addr.loc11_22.2: %ptr.251 = addr_of %.loc11_22.1
|
||||
// CHECK:STDOUT: %Int.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc11_22.2)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
+32
-6
@@ -445,13 +445,30 @@ auto foo() -> S;
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
// TODO: We should only produce one error here.
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+12]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:4:6: error: calling 'foo' with incomplete return type 'S' [CppInteropParseError]
|
||||
// CHECK:STDERR: 4 | auto foo() -> S;
|
||||
// CHECK:STDERR: | ^~~
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+8]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:4:6: note: 'foo' declared here [CppInteropParseNote]
|
||||
// CHECK:STDERR: 4 | auto foo() -> S;
|
||||
// CHECK:STDERR: | ^
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+4]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:2:8: note: forward declaration of 'S' [CppInteropParseNote]
|
||||
// CHECK:STDERR: 2 | struct S;
|
||||
// CHECK:STDERR: | ^
|
||||
import Cpp library "decl_value_return_type.h";
|
||||
|
||||
fn F() {
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+13]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
|
||||
// CHECK:STDERR: Cpp.foo();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+9]]:3: error: function returns incomplete type `Cpp.S` [IncompleteTypeInFunctionReturnType]
|
||||
// CHECK:STDERR: Cpp.foo();
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE-6]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE-10]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:2:8: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: struct S;
|
||||
// CHECK:STDERR: ^
|
||||
@@ -1155,9 +1172,11 @@ fn F() {
|
||||
// CHECK:STDOUT: %S: type = class_type @S [concrete]
|
||||
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
|
||||
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete]
|
||||
// CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete]
|
||||
// CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.642: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%S) [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.ab5: %T.as.Destroy.impl.Op.type.642 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -1170,6 +1189,11 @@ fn F() {
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
@@ -1177,13 +1201,15 @@ fn F() {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_11.1: ref %S = temporary_storage
|
||||
// CHECK:STDOUT: %foo.call: init %S = call %foo.ref() to %.loc8_11.1
|
||||
// CHECK:STDOUT: %.loc8_11.2: ref %S = temporary %.loc8_11.1, %foo.call
|
||||
// CHECK:STDOUT: %addr.loc8_11.1: %ptr.5c7 = addr_of %.loc8_11.1
|
||||
// CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr.loc8_11.1)
|
||||
// CHECK:STDOUT: %.loc8_11.2: init %S = in_place_init %foo__carbon_thunk.call, %.loc8_11.1
|
||||
// CHECK:STDOUT: %.loc8_11.3: ref %S = temporary %.loc8_11.1, %.loc8_11.2
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc8_11.1, constants.%T.as.Destroy.impl.Op.ab5
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc8_11.1, %T.as.Destroy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %.loc8_11.1
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr)
|
||||
// CHECK:STDOUT: %addr.loc8_11.2: %ptr.5c7 = addr_of %.loc8_11.1
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc8_11.2)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/int.carbon
|
||||
// EXTRA-ARGS: --dump-cpp-ast
|
||||
// EXTRA-ARGS: --dump-cpp-ast --target=x86_64-linux-gnu
|
||||
// SET-CHECK-SUBSET
|
||||
//
|
||||
// AUTOUPDATE
|
||||
@@ -18,7 +18,55 @@
|
||||
auto foo(short a) -> void;
|
||||
// CHECK:STDOUT: |-FunctionDecl {{0x[a-f0-9]+}} <./thunk_required.h:[[@LINE-1]]:1, col:22> col:6 used foo 'auto (short) -> void'
|
||||
// CHECK:STDOUT: | `-ParmVarDecl {{0x[a-f0-9]+}} <col:10, col:16> col:16 a 'short'
|
||||
// CHECK:STDOUT: `-FunctionDecl {{0x[a-f0-9]+}} <col:6> col:6 foo__carbon_thunk 'void (short * _Nonnull)' extern
|
||||
// CHECK:STDOUT: |-NamespaceDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit std
|
||||
// CHECK:STDOUT: |-FunctionDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit operator new 'void *(__size_t)'
|
||||
// CHECK:STDOUT: | |-VisibilityAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit Default
|
||||
// CHECK:STDOUT: | |-ReturnsNonNullAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit
|
||||
// CHECK:STDOUT: | `-AllocSizeAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit 1
|
||||
// CHECK:STDOUT: |-FunctionDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit operator new 'void *(__size_t, std::align_val_t)'
|
||||
// CHECK:STDOUT: | |-ParmVarDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit 'std::align_val_t'
|
||||
// CHECK:STDOUT: | |-VisibilityAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit Default
|
||||
// CHECK:STDOUT: | |-ReturnsNonNullAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit
|
||||
// CHECK:STDOUT: | |-AllocSizeAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit 1
|
||||
// CHECK:STDOUT: | `-AllocAlignAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit 2
|
||||
// CHECK:STDOUT: |-FunctionDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit operator new[] 'void *(__size_t)'
|
||||
// CHECK:STDOUT: | |-VisibilityAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit Default
|
||||
// CHECK:STDOUT: | |-ReturnsNonNullAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit
|
||||
// CHECK:STDOUT: | `-AllocSizeAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit 1
|
||||
// CHECK:STDOUT: |-FunctionDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit operator new[] 'void *(__size_t, std::align_val_t)'
|
||||
// CHECK:STDOUT: | |-ParmVarDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit 'std::align_val_t'
|
||||
// CHECK:STDOUT: | |-VisibilityAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit Default
|
||||
// CHECK:STDOUT: | |-ReturnsNonNullAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit
|
||||
// CHECK:STDOUT: | |-AllocSizeAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit 1
|
||||
// CHECK:STDOUT: | `-AllocAlignAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit 2
|
||||
// CHECK:STDOUT: |-FunctionDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit operator delete 'void (void *) noexcept'
|
||||
// CHECK:STDOUT: | |-ParmVarDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit 'void *'
|
||||
// CHECK:STDOUT: | `-VisibilityAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit Default
|
||||
// CHECK:STDOUT: |-FunctionDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit operator delete 'void (void *, std::align_val_t) noexcept'
|
||||
// CHECK:STDOUT: | |-ParmVarDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit 'void *'
|
||||
// CHECK:STDOUT: | |-ParmVarDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit 'std::align_val_t'
|
||||
// CHECK:STDOUT: | `-VisibilityAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit Default
|
||||
// CHECK:STDOUT: | |-ParmVarDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit 'void *'
|
||||
// CHECK:STDOUT: | `-VisibilityAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit Default
|
||||
// CHECK:STDOUT: | |-ParmVarDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit 'void *'
|
||||
// CHECK:STDOUT: | |-ParmVarDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit 'std::align_val_t'
|
||||
// CHECK:STDOUT: | `-VisibilityAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit Default
|
||||
// CHECK:STDOUT: |-FunctionDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit operator delete[] 'void (void *) noexcept'
|
||||
// CHECK:STDOUT: | |-ParmVarDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit 'void *'
|
||||
// CHECK:STDOUT: | `-VisibilityAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit Default
|
||||
// CHECK:STDOUT: |-FunctionDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit operator delete[] 'void (void *, std::align_val_t) noexcept'
|
||||
// CHECK:STDOUT: | |-ParmVarDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit 'void *'
|
||||
// CHECK:STDOUT: | |-ParmVarDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit 'std::align_val_t'
|
||||
// CHECK:STDOUT: | `-VisibilityAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit Default
|
||||
// CHECK:STDOUT: | |-ParmVarDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit 'void *'
|
||||
// CHECK:STDOUT: | `-VisibilityAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit Default
|
||||
// CHECK:STDOUT: | |-ParmVarDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit 'void *'
|
||||
// CHECK:STDOUT: | |-ParmVarDecl {{0x[a-f0-9]+}} <<invalid sloc>> <invalid sloc> implicit 'std::align_val_t'
|
||||
// CHECK:STDOUT: | `-VisibilityAttr {{0x[a-f0-9]+}} <<invalid sloc>> Implicit Default
|
||||
// CHECK:STDOUT: |-FunctionDecl {{0x[a-f0-9]+}} <<carbon-internal>:8:1, line:14:1> line:8:7 operator new 'void *(unsigned long, void *) noexcept'
|
||||
// CHECK:STDOUT: | |-ParmVarDecl {{0x[a-f0-9]+}} <<built-in>:173:23, col:37> <carbon-internal>:8:33 'unsigned long'
|
||||
// CHECK:STDOUT: | `-ParmVarDecl {{0x[a-f0-9]+}} <col:35, col:39> col:40 'void *'
|
||||
// CHECK:STDOUT: `-FunctionDecl {{0x[a-f0-9]+}} <./thunk_required.h:[[@LINE-51]]:6> col:6 foo__carbon_thunk 'void (short * _Nonnull)' extern
|
||||
// CHECK:STDOUT: |-ParmVarDecl {{0x[a-f0-9]+}} <col:6> col:6 used a 'short * _Nonnull':'short *'
|
||||
// CHECK:STDOUT: |-ReturnStmt {{0x[a-f0-9]+}} <col:6>
|
||||
// CHECK:STDOUT: | `-CallExpr {{0x[a-f0-9]+}} <col:6> 'void'
|
||||
|
||||
+31
-6
@@ -408,13 +408,29 @@ auto foo() -> U;
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+12]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:4:6: error: calling 'foo' with incomplete return type 'U' [CppInteropParseError]
|
||||
// CHECK:STDERR: 4 | auto foo() -> U;
|
||||
// CHECK:STDERR: | ^~~
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+8]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:4:6: note: 'foo' declared here [CppInteropParseNote]
|
||||
// CHECK:STDERR: 4 | auto foo() -> U;
|
||||
// CHECK:STDERR: | ^
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+4]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:2:7: note: forward declaration of 'U' [CppInteropParseNote]
|
||||
// CHECK:STDERR: 2 | union U;
|
||||
// CHECK:STDERR: | ^
|
||||
import Cpp library "decl_value_return_type.h";
|
||||
|
||||
fn F() {
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+13]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
|
||||
// CHECK:STDERR: Cpp.foo();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+9]]:3: error: function returns incomplete type `Cpp.U` [IncompleteTypeInFunctionReturnType]
|
||||
// CHECK:STDERR: Cpp.foo();
|
||||
// CHECK:STDERR: ^~~~~~~~~
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE-6]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE-10]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:2:7: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: union U;
|
||||
// CHECK:STDERR: ^
|
||||
@@ -1104,9 +1120,11 @@ fn F() {
|
||||
// CHECK:STDOUT: %U: type = class_type @U [concrete]
|
||||
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
|
||||
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.86f: type = ptr_type %U [concrete]
|
||||
// CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete]
|
||||
// CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.0b7: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%U) [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.2fa: %T.as.Destroy.impl.Op.type.0b7 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.86f: type = ptr_type %U [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -1119,6 +1137,11 @@ fn F() {
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
@@ -1126,13 +1149,15 @@ fn F() {
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %.loc8_11.1: ref %U = temporary_storage
|
||||
// CHECK:STDOUT: %foo.call: init %U = call %foo.ref() to %.loc8_11.1
|
||||
// CHECK:STDOUT: %.loc8_11.2: ref %U = temporary %.loc8_11.1, %foo.call
|
||||
// CHECK:STDOUT: %addr.loc8_11.1: %ptr.86f = addr_of %.loc8_11.1
|
||||
// CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr.loc8_11.1)
|
||||
// CHECK:STDOUT: %.loc8_11.2: init %U = in_place_init %foo__carbon_thunk.call, %.loc8_11.1
|
||||
// CHECK:STDOUT: %.loc8_11.3: ref %U = temporary %.loc8_11.1, %.loc8_11.2
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: <bound method> = bound_method %.loc8_11.1, constants.%T.as.Destroy.impl.Op.2fa
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc8_11.1, %T.as.Destroy.impl.Op.specific_fn
|
||||
// CHECK:STDOUT: %addr: %ptr.86f = addr_of %.loc8_11.1
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr)
|
||||
// CHECK:STDOUT: %addr.loc8_11.2: %ptr.86f = addr_of %.loc8_11.1
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc8_11.2)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
Reference in New Issue
Block a user