mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
[Carbon/C++ interop] Add support for C++ overloaded functions (#5891)
As proposed in [Carbon: C++ interop for overloaded functions and function templates](https://docs.google.com/document/d/1KUxumZtNe3mY3TsjW2s_ZADOlAaFlrtsLKHVILtqIaM/edit?tab=t.0), Clang is used to perform the overload resolution using C++ rules, when an overloaded C++ set is called from Carbon. Once a function is selected, it's converted into a Carbon function and called using the Carbon rules including argument conversions. A single non-templated function is treated the same way as an overload set and the same rules apply for its call. Template functions are not supported yet. Demo: a) Non-templated function calls: ```c++ // --- overloads.h auto foo(int a, short b) -> void; auto foo(double a) -> void; auto foo(int a) -> void; ``` ```c++ // overloads.cpp #include "overloads.h" #include <cstdio> auto foo(int a, short b) -> void { printf("hello from foo_int_short(%d, %d) \n", a, b); } auto foo(double a) -> void { printf("hello from foo_double(%f) \n", a); } auto foo(int a) -> void { printf("hello from foo_int(%d) \n", a); } ``` ```c++ library "Main"; import Cpp library "overloads.h"; fn Run() -> i32 { Cpp.foo(1.1 as f64); return 0; } ``` ``` $ clang -c overloads.cpp $ bazel-bin/toolchain/carbon compile main.carbon $ bazel-bin/toolchain/carbon link overloads.o main.o --output=demo $ ./demo hello from foo_double(1.100000) ``` b) Constructors: ```c++ // --- constructor_overloads.h class C { public: C(); C(int a, int b); }; ``` ```c++ // constructor_overloads.cpp #include "constructor_overloads.h" #include <cstdio> C::C() { printf("hello from C() \n"); } C::C(int a, int b) { printf("hello from C(%d, %d) \n", a, b); } ``` ```c++ library "Main"; import Cpp library "constructor_overloads.h"; fn Run() -> i32 { let c1: Cpp.C = Cpp.C.C(); let c2: Cpp.C = Cpp.C.C(1, 2); return 0; } ``` ``` $ clang -c constructor_overloads.cpp $ bazel-bin/toolchain/carbon compile main.carbon $ bazel-bin/toolchain/carbon link constructor_overloads.o main.o \--output=demo $ ./demo hello from C() hello from C(1, 2) ``` Follow-ups: - `Cpp.foo({})` - proper handling of struct literals as call args. - Fix access for overloaded sets. - Fix tests: - Method calls: `error: missing object argument in method call [MissingObjectInMethodCall]` in tests. - Fix `toolchain/check/testdata/interop/cpp/import.carbon` test. - Fix `enums` support. - Fix `str` -> `std::string_view` mapping. Part of #5915
This commit is contained in:
+131
-83
@@ -68,7 +68,7 @@ class C {
|
||||
C(int x, int y);
|
||||
};
|
||||
|
||||
// --- fail_todo_import_multiple.carbon
|
||||
// --- import_multiple.carbon
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
@@ -76,13 +76,6 @@ import Cpp library "multiple.h";
|
||||
|
||||
fn F() {
|
||||
//@dump-sem-ir-begin
|
||||
// CHECK:STDERR: fail_todo_import_multiple.carbon:[[@LINE+7]]:19: error: semantics TODO: `Unsupported: Constructors lookup succeeded but couldn't find a single result; Found 2 constructors` [SemanticsTodo]
|
||||
// CHECK:STDERR: let c1: Cpp.C = Cpp.C.C();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_todo_import_multiple.carbon:[[@LINE+4]]:19: note: in `Cpp` name lookup for `C` [InCppNameLookup]
|
||||
// CHECK:STDERR: let c1: Cpp.C = Cpp.C.C();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
let c1: Cpp.C = Cpp.C.C();
|
||||
let c2: Cpp.C = Cpp.C.C(123, 456);
|
||||
//@dump-sem-ir-end
|
||||
@@ -135,10 +128,7 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "none.h";
|
||||
|
||||
fn F() {
|
||||
// CHECK:STDERR: fail_import_none.carbon:[[@LINE+7]]:18: error: semantics TODO: `Unsupported: Constructors lookup succeeded but couldn't find a single result; Found 0 constructors` [SemanticsTodo]
|
||||
// CHECK:STDERR: let c: Cpp.C = Cpp.C.C();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR: fail_import_none.carbon:[[@LINE+4]]:18: note: in `Cpp` name lookup for `C` [InCppNameLookup]
|
||||
// CHECK:STDERR: fail_import_none.carbon:[[@LINE+4]]:18: error: member name `C` not found in `Cpp.C` [MemberNameNotFoundInInstScope]
|
||||
// CHECK:STDERR: let c: Cpp.C = Cpp.C.C();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
@@ -219,8 +209,8 @@ fn F() {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %C: type = class_type @C [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.217: type = pattern_type %C [concrete]
|
||||
// CHECK:STDOUT: %C.C.type: type = fn_type @C.C [concrete]
|
||||
// CHECK:STDOUT: %C.C: %C.C.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %.d40: type = cpp_overload_set_type @C.C [concrete]
|
||||
// CHECK:STDOUT: %empty_struct: %.d40 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.d9e: type = ptr_type %C [concrete]
|
||||
// CHECK:STDOUT: %C__carbon_thunk.type: type = fn_type @C__carbon_thunk [concrete]
|
||||
// CHECK:STDOUT: %C__carbon_thunk: %C__carbon_thunk.type = struct_value () [concrete]
|
||||
@@ -234,11 +224,7 @@ fn F() {
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {}
|
||||
// CHECK:STDOUT: %C.C.decl: %C.C.type = fn_decl @C.C [concrete = constants.%C.C] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %.40b: %.d40 = cpp_overload_set_value @C.C [concrete = constants.%empty_struct]
|
||||
// CHECK:STDOUT: %C__carbon_thunk.decl: %C__carbon_thunk.type = fn_decl @C__carbon_thunk [concrete = constants.%C__carbon_thunk] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
@@ -253,7 +239,7 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8_18: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %C.ref.loc8_21: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
||||
// CHECK:STDOUT: %C.ref.loc8_23: %C.C.type = name_ref C, imports.%C.C.decl [concrete = constants.%C.C]
|
||||
// CHECK:STDOUT: %C.ref.loc8_23: %.d40 = name_ref C, imports.%.40b [concrete = constants.%empty_struct]
|
||||
// CHECK:STDOUT: %.loc8_26.1: ref %C = temporary_storage
|
||||
// CHECK:STDOUT: %addr.loc8_26.1: %ptr.d9e = addr_of %.loc8_26.1
|
||||
// CHECK:STDOUT: %C__carbon_thunk.call: init %empty_tuple.type = call imports.%C__carbon_thunk.decl(%addr.loc8_26.1)
|
||||
@@ -279,15 +265,15 @@ fn F() {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %C: type = class_type @C [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.217: type = pattern_type %C [concrete]
|
||||
// CHECK:STDOUT: %.d40: type = cpp_overload_set_type @C.C [concrete]
|
||||
// CHECK:STDOUT: %empty_struct: %.d40 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %int_123.fff: Core.IntLiteral = int_value 123 [concrete]
|
||||
// CHECK:STDOUT: %int_456.010: Core.IntLiteral = int_value 456 [concrete]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %C.C.type: type = fn_type @C.C [concrete]
|
||||
// CHECK:STDOUT: %C.C: %C.C.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.d9e: type = ptr_type %C [concrete]
|
||||
// CHECK:STDOUT: %C__carbon_thunk.type: type = fn_type @C__carbon_thunk [concrete]
|
||||
// CHECK:STDOUT: %C__carbon_thunk: %C__carbon_thunk.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %int_123.fff: Core.IntLiteral = int_value 123 [concrete]
|
||||
// CHECK:STDOUT: %int_456.010: Core.IntLiteral = int_value 456 [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.e8c: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete]
|
||||
// CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic]
|
||||
@@ -315,11 +301,7 @@ fn F() {
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {}
|
||||
// CHECK:STDOUT: %C.C.decl: %C.C.type = fn_decl @C.C [concrete = constants.%C.C] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %.40b: %.d40 = cpp_overload_set_value @C.C [concrete = constants.%empty_struct]
|
||||
// CHECK:STDOUT: %C__carbon_thunk.decl: %C__carbon_thunk.type = fn_decl @C__carbon_thunk [concrete = constants.%C__carbon_thunk] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
@@ -336,7 +318,7 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8_18: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %C.ref.loc8_21: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
||||
// CHECK:STDOUT: %C.ref.loc8_23: %C.C.type = name_ref C, imports.%C.C.decl [concrete = constants.%C.C]
|
||||
// CHECK:STDOUT: %C.ref.loc8_23: %.d40 = name_ref C, imports.%.40b [concrete = constants.%empty_struct]
|
||||
// CHECK:STDOUT: %int_123: Core.IntLiteral = int_value 123 [concrete = constants.%int_123.fff]
|
||||
// CHECK:STDOUT: %int_456: Core.IntLiteral = int_value 456 [concrete = constants.%int_456.010]
|
||||
// CHECK:STDOUT: %.loc8_34.1: ref %C = temporary_storage
|
||||
@@ -372,13 +354,42 @@ fn F() {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_import_multiple.carbon
|
||||
// CHECK:STDOUT: --- import_multiple.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %C: type = class_type @C [concrete]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %C [concrete]
|
||||
// CHECK:STDOUT: %int_123: Core.IntLiteral = int_value 123 [concrete]
|
||||
// CHECK:STDOUT: %int_456: Core.IntLiteral = int_value 456 [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.217: type = pattern_type %C [concrete]
|
||||
// CHECK:STDOUT: %.d40: type = cpp_overload_set_type @C.C.1 [concrete]
|
||||
// CHECK:STDOUT: %empty_struct: %.d40 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.d9e: type = ptr_type %C [concrete]
|
||||
// CHECK:STDOUT: %C__carbon_thunk.type.65f120.1: type = fn_type @C__carbon_thunk.1 [concrete]
|
||||
// CHECK:STDOUT: %C__carbon_thunk.d98342.1: %C__carbon_thunk.type.65f120.1 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %int_123.fff: Core.IntLiteral = int_value 123 [concrete]
|
||||
// CHECK:STDOUT: %int_456.010: Core.IntLiteral = int_value 456 [concrete]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %C__carbon_thunk.type.65f120.2: type = fn_type @C__carbon_thunk.2 [concrete]
|
||||
// CHECK:STDOUT: %C__carbon_thunk.d98342.2: %C__carbon_thunk.type.65f120.2 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.e8c: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete]
|
||||
// CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.49e: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f01: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.49e = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.impl_witness.acc: <witness> = impl_witness imports.%ImplicitAs.impl_witness_table.b6b, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.9ec: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.592: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.9ec = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.e8c = facet_value Core.IntLiteral, (%ImplicitAs.impl_witness.acc) [concrete]
|
||||
// CHECK:STDOUT: %.7ea: type = fn_type_with_self_type %ImplicitAs.Convert.type.1b6, %ImplicitAs.facet [concrete]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.88d: <bound method> = bound_method %int_123.fff, %Core.IntLiteral.as.ImplicitAs.impl.Convert.592 [concrete]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.592, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %bound_method.6ab: <bound method> = bound_method %int_123.fff, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
|
||||
// CHECK:STDOUT: %int_123.f7f: %i32 = int_value 123 [concrete]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.5f2: <bound method> = bound_method %int_456.010, %Core.IntLiteral.as.ImplicitAs.impl.Convert.592 [concrete]
|
||||
// CHECK:STDOUT: %bound_method.098: <bound method> = bound_method %int_456.010, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
|
||||
// CHECK:STDOUT: %int_456.d17: %i32 = int_value 456 [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.140: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete]
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.d4e: %T.as.Destroy.impl.Op.type.140 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
@@ -387,34 +398,83 @@ fn F() {
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {}
|
||||
// CHECK:STDOUT: %.40b: %.d40 = cpp_overload_set_value @C.C.1 [concrete = constants.%empty_struct]
|
||||
// CHECK:STDOUT: %C__carbon_thunk.decl.8acdfe.1: %C__carbon_thunk.type.65f120.1 = fn_decl @C__carbon_thunk.1 [concrete = constants.%C__carbon_thunk.d98342.1] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %C__carbon_thunk.decl.8acdfe.2: %C__carbon_thunk.type.65f120.2 = fn_decl @C__carbon_thunk.2 [concrete = constants.%C__carbon_thunk.d98342.2] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import_ref.428: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.49e) = import_ref Core//prelude/parts/int, loc23_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f01)]
|
||||
// CHECK:STDOUT: %ImplicitAs.impl_witness_table.b6b = impl_witness_table (%Core.import_ref.428), @Core.IntLiteral.as.ImplicitAs.impl [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %c1.patt: %pattern_type = binding_pattern c1 [concrete]
|
||||
// CHECK:STDOUT: %c1.patt: %pattern_type.217 = binding_pattern c1 [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc15_19: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %C.ref.loc15_22: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
||||
// CHECK:STDOUT: %C.ref.loc15_24: <error> = name_ref C, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %.loc15: type = splice_block %C.ref.loc15_14 [concrete = constants.%C] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc15_11: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %C.ref.loc15_14: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8_19: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %C.ref.loc8_22: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
||||
// CHECK:STDOUT: %C.ref.loc8_24: %.d40 = name_ref C, imports.%.40b [concrete = constants.%empty_struct]
|
||||
// CHECK:STDOUT: %.loc8_27.1: ref %C = temporary_storage
|
||||
// CHECK:STDOUT: %addr.loc8_27.1: %ptr.d9e = addr_of %.loc8_27.1
|
||||
// CHECK:STDOUT: %C__carbon_thunk.call.loc8: init %empty_tuple.type = call imports.%C__carbon_thunk.decl.8acdfe.1(%addr.loc8_27.1)
|
||||
// CHECK:STDOUT: %.loc8_27.2: init %C = in_place_init %C__carbon_thunk.call.loc8, %.loc8_27.1
|
||||
// CHECK:STDOUT: %.loc8_14: type = splice_block %C.ref.loc8_14 [concrete = constants.%C] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8_11: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %C.ref.loc8_14: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %c1: %C = bind_name c1, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %.loc8_27.3: ref %C = temporary %.loc8_27.1, %.loc8_27.2
|
||||
// CHECK:STDOUT: %.loc8_27.4: %C = bind_value %.loc8_27.3
|
||||
// CHECK:STDOUT: %c1: %C = bind_name c1, %.loc8_27.4
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %c2.patt: %pattern_type = binding_pattern c2 [concrete]
|
||||
// CHECK:STDOUT: %c2.patt: %pattern_type.217 = binding_pattern c2 [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc16_19: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %C.ref.loc16_22: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
||||
// CHECK:STDOUT: %C.ref.loc16_24: <error> = name_ref C, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %int_123: Core.IntLiteral = int_value 123 [concrete = constants.%int_123]
|
||||
// CHECK:STDOUT: %int_456: Core.IntLiteral = int_value 456 [concrete = constants.%int_456]
|
||||
// CHECK:STDOUT: %.loc16: type = splice_block %C.ref.loc16_14 [concrete = constants.%C] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc16_11: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %C.ref.loc16_14: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
||||
// CHECK:STDOUT: %Cpp.ref.loc9_19: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %C.ref.loc9_22: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
||||
// CHECK:STDOUT: %C.ref.loc9_24: %.d40 = name_ref C, imports.%.40b [concrete = constants.%empty_struct]
|
||||
// CHECK:STDOUT: %int_123: Core.IntLiteral = int_value 123 [concrete = constants.%int_123.fff]
|
||||
// CHECK:STDOUT: %int_456: Core.IntLiteral = int_value 456 [concrete = constants.%int_456.010]
|
||||
// CHECK:STDOUT: %.loc9_35.1: ref %C = temporary_storage
|
||||
// CHECK:STDOUT: %impl.elem0.loc9_27: %.7ea = impl_witness_access constants.%ImplicitAs.impl_witness.acc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.592]
|
||||
// CHECK:STDOUT: %bound_method.loc9_27.1: <bound method> = bound_method %int_123, %impl.elem0.loc9_27 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.88d]
|
||||
// CHECK:STDOUT: %specific_fn.loc9_27: <specific function> = specific_function %impl.elem0.loc9_27, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc9_27.2: <bound method> = bound_method %int_123, %specific_fn.loc9_27 [concrete = constants.%bound_method.6ab]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc9_27: init %i32 = call %bound_method.loc9_27.2(%int_123) [concrete = constants.%int_123.f7f]
|
||||
// CHECK:STDOUT: %.loc9_27.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc9_27 [concrete = constants.%int_123.f7f]
|
||||
// CHECK:STDOUT: %.loc9_27.2: %i32 = converted %int_123, %.loc9_27.1 [concrete = constants.%int_123.f7f]
|
||||
// CHECK:STDOUT: %impl.elem0.loc9_32: %.7ea = impl_witness_access constants.%ImplicitAs.impl_witness.acc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.592]
|
||||
// CHECK:STDOUT: %bound_method.loc9_32.1: <bound method> = bound_method %int_456, %impl.elem0.loc9_32 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.5f2]
|
||||
// CHECK:STDOUT: %specific_fn.loc9_32: <specific function> = specific_function %impl.elem0.loc9_32, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc9_32.2: <bound method> = bound_method %int_456, %specific_fn.loc9_32 [concrete = constants.%bound_method.098]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc9_32: init %i32 = call %bound_method.loc9_32.2(%int_456) [concrete = constants.%int_456.d17]
|
||||
// CHECK:STDOUT: %.loc9_32.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc9_32 [concrete = constants.%int_456.d17]
|
||||
// CHECK:STDOUT: %.loc9_32.2: %i32 = converted %int_456, %.loc9_32.1 [concrete = constants.%int_456.d17]
|
||||
// CHECK:STDOUT: %addr.loc9_35.1: %ptr.d9e = addr_of %.loc9_35.1
|
||||
// CHECK:STDOUT: %C__carbon_thunk.call.loc9: init %empty_tuple.type = call imports.%C__carbon_thunk.decl.8acdfe.2(%.loc9_27.2, %.loc9_32.2, %addr.loc9_35.1)
|
||||
// CHECK:STDOUT: %.loc9_35.2: init %C = in_place_init %C__carbon_thunk.call.loc9, %.loc9_35.1
|
||||
// CHECK:STDOUT: %.loc9_14: type = splice_block %C.ref.loc9_14 [concrete = constants.%C] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc9_11: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %C.ref.loc9_14: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %c2: %C = bind_name c2, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %.loc9_35.3: ref %C = temporary %.loc9_35.1, %.loc9_35.2
|
||||
// CHECK:STDOUT: %.loc9_35.4: %C = bind_value %.loc9_35.3
|
||||
// CHECK:STDOUT: %c2: %C = bind_name c2, %.loc9_35.4
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9: <bound method> = bound_method %.loc9_35.3, constants.%T.as.Destroy.impl.Op.d4e
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %bound_method.loc9_35: <bound method> = bound_method %.loc9_35.3, %T.as.Destroy.impl.Op.specific_fn.1
|
||||
// CHECK:STDOUT: %addr.loc9_35.2: %ptr.d9e = addr_of %.loc9_35.3
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc9: init %empty_tuple.type = call %bound_method.loc9_35(%addr.loc9_35.2)
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8: <bound method> = bound_method %.loc8_27.3, constants.%T.as.Destroy.impl.Op.d4e
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: %bound_method.loc8: <bound method> = bound_method %.loc8_27.3, %T.as.Destroy.impl.Op.specific_fn.2
|
||||
// CHECK:STDOUT: %addr.loc8_27.2: %ptr.d9e = addr_of %.loc8_27.3
|
||||
// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8: init %empty_tuple.type = call %bound_method.loc8(%addr.loc8_27.2)
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -424,15 +484,15 @@ fn F() {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %C: type = class_type @C [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.217: type = pattern_type %C [concrete]
|
||||
// CHECK:STDOUT: %.d40: type = cpp_overload_set_type @C.C [concrete]
|
||||
// CHECK:STDOUT: %empty_struct: %.d40 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %int_8.b85: Core.IntLiteral = int_value 8 [concrete]
|
||||
// CHECK:STDOUT: %int_9.988: Core.IntLiteral = int_value 9 [concrete]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %C.C.type: type = fn_type @C.C [concrete]
|
||||
// CHECK:STDOUT: %C.C: %C.C.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.d9e: type = ptr_type %C [concrete]
|
||||
// CHECK:STDOUT: %C__carbon_thunk.type: type = fn_type @C__carbon_thunk [concrete]
|
||||
// CHECK:STDOUT: %C__carbon_thunk: %C__carbon_thunk.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %int_8.b85: Core.IntLiteral = int_value 8 [concrete]
|
||||
// CHECK:STDOUT: %int_9.988: Core.IntLiteral = int_value 9 [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.e8c: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete]
|
||||
// CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic]
|
||||
@@ -460,11 +520,7 @@ fn F() {
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {}
|
||||
// CHECK:STDOUT: %C.C.decl: %C.C.type = fn_decl @C.C [concrete = constants.%C.C] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %.40b: %.d40 = cpp_overload_set_value @C.C [concrete = constants.%empty_struct]
|
||||
// CHECK:STDOUT: %C__carbon_thunk.decl: %C__carbon_thunk.type = fn_decl @C__carbon_thunk [concrete = constants.%C__carbon_thunk] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
@@ -481,7 +537,7 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8_19: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %C.ref.loc8_22: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
||||
// CHECK:STDOUT: %C.ref.loc8_24: %C.C.type = name_ref C, imports.%C.C.decl [concrete = constants.%C.C]
|
||||
// CHECK:STDOUT: %C.ref.loc8_24: %.d40 = name_ref C, imports.%.40b [concrete = constants.%empty_struct]
|
||||
// CHECK:STDOUT: %int_8.loc8: Core.IntLiteral = int_value 8 [concrete = constants.%int_8.b85]
|
||||
// CHECK:STDOUT: %int_9: Core.IntLiteral = int_value 9 [concrete = constants.%int_9.988]
|
||||
// CHECK:STDOUT: %.loc8_31.1: ref %C = temporary_storage
|
||||
@@ -514,7 +570,7 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc14_19: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %C.ref.loc14_22: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
||||
// CHECK:STDOUT: %C.ref.loc14_24: %C.C.type = name_ref C, imports.%C.C.decl [concrete = constants.%C.C]
|
||||
// CHECK:STDOUT: %C.ref.loc14_24: %.d40 = name_ref C, imports.%.40b [concrete = constants.%empty_struct]
|
||||
// CHECK:STDOUT: %int_8.loc14: Core.IntLiteral = int_value 8 [concrete = constants.%int_8.b85]
|
||||
// CHECK:STDOUT: %.loc14: type = splice_block %C.ref.loc14_14 [concrete = constants.%C] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc14_11: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
@@ -535,14 +591,14 @@ fn F() {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %C: type = class_type @C [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.217: type = pattern_type %C [concrete]
|
||||
// CHECK:STDOUT: %.d40: type = cpp_overload_set_type @C.C [concrete]
|
||||
// CHECK:STDOUT: %empty_struct: %.d40 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %int_8.b85: Core.IntLiteral = int_value 8 [concrete]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %C.C.type: type = fn_type @C.C [concrete]
|
||||
// CHECK:STDOUT: %C.C: %C.C.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.d9e: type = ptr_type %C [concrete]
|
||||
// CHECK:STDOUT: %C__carbon_thunk.type: type = fn_type @C__carbon_thunk [concrete]
|
||||
// CHECK:STDOUT: %C__carbon_thunk: %C__carbon_thunk.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %int_8.b85: Core.IntLiteral = int_value 8 [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.e8c: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete]
|
||||
// CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic]
|
||||
@@ -579,11 +635,7 @@ fn F() {
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {}
|
||||
// CHECK:STDOUT: %C.C.decl: %C.C.type = fn_decl @C.C [concrete = constants.%C.C] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %.40b: %.d40 = cpp_overload_set_value @C.C [concrete = constants.%empty_struct]
|
||||
// CHECK:STDOUT: %C__carbon_thunk.decl: %C__carbon_thunk.type = fn_decl @C__carbon_thunk [concrete = constants.%C__carbon_thunk] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
@@ -602,7 +654,7 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8_19: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %C.ref.loc8_22: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
||||
// CHECK:STDOUT: %C.ref.loc8_24: %C.C.type = name_ref C, imports.%C.C.decl [concrete = constants.%C.C]
|
||||
// CHECK:STDOUT: %C.ref.loc8_24: %.d40 = name_ref C, imports.%.40b [concrete = constants.%empty_struct]
|
||||
// CHECK:STDOUT: %int_8.loc8: Core.IntLiteral = int_value 8 [concrete = constants.%int_8.b85]
|
||||
// CHECK:STDOUT: %.loc8_28.1: ref %C = temporary_storage
|
||||
// CHECK:STDOUT: %impl.elem0.loc8: %.7ea = impl_witness_access constants.%ImplicitAs.impl_witness.acc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.592]
|
||||
@@ -655,15 +707,15 @@ fn F() {
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %C: type = class_type @C [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.217: type = pattern_type %C [concrete]
|
||||
// CHECK:STDOUT: %.d40: type = cpp_overload_set_type @C.C [concrete]
|
||||
// CHECK:STDOUT: %empty_struct: %.d40 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %int_8.b85: Core.IntLiteral = int_value 8 [concrete]
|
||||
// CHECK:STDOUT: %int_9.988: Core.IntLiteral = int_value 9 [concrete]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %C.C.type: type = fn_type @C.C [concrete]
|
||||
// CHECK:STDOUT: %C.C: %C.C.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ptr.d9e: type = ptr_type %C [concrete]
|
||||
// CHECK:STDOUT: %C__carbon_thunk.type: type = fn_type @C__carbon_thunk [concrete]
|
||||
// CHECK:STDOUT: %C__carbon_thunk: %C__carbon_thunk.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %int_8.b85: Core.IntLiteral = int_value 8 [concrete]
|
||||
// CHECK:STDOUT: %int_9.988: Core.IntLiteral = int_value 9 [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.e8c: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete]
|
||||
// CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic]
|
||||
@@ -703,11 +755,7 @@ fn F() {
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {}
|
||||
// CHECK:STDOUT: %C.C.decl: %C.C.type = fn_decl @C.C [concrete = constants.%C.C] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %.40b: %.d40 = cpp_overload_set_value @C.C [concrete = constants.%empty_struct]
|
||||
// CHECK:STDOUT: %C__carbon_thunk.decl: %C__carbon_thunk.type = fn_decl @C__carbon_thunk [concrete = constants.%C__carbon_thunk] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
@@ -726,7 +774,7 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8_19: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %C.ref.loc8_22: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
||||
// CHECK:STDOUT: %C.ref.loc8_24: %C.C.type = name_ref C, imports.%C.C.decl [concrete = constants.%C.C]
|
||||
// CHECK:STDOUT: %C.ref.loc8_24: %.d40 = name_ref C, imports.%.40b [concrete = constants.%empty_struct]
|
||||
// CHECK:STDOUT: %int_8.loc8: Core.IntLiteral = int_value 8 [concrete = constants.%int_8.b85]
|
||||
// CHECK:STDOUT: %int_9: Core.IntLiteral = int_value 9 [concrete = constants.%int_9.988]
|
||||
// CHECK:STDOUT: %.loc8_31.1: ref %C = temporary_storage
|
||||
@@ -759,7 +807,7 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc14_19: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %C.ref.loc14_22: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
||||
// CHECK:STDOUT: %C.ref.loc14_24: %C.C.type = name_ref C, imports.%C.C.decl [concrete = constants.%C.C]
|
||||
// CHECK:STDOUT: %C.ref.loc14_24: %.d40 = name_ref C, imports.%.40b [concrete = constants.%empty_struct]
|
||||
// CHECK:STDOUT: %int_8.loc14: Core.IntLiteral = int_value 8 [concrete = constants.%int_8.b85]
|
||||
// CHECK:STDOUT: %.loc14: type = splice_block %C.ref.loc14_14 [concrete = constants.%C] {
|
||||
// CHECK:STDOUT: %Cpp.ref.loc14_11: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
|
||||
Reference in New Issue
Block a user