|
|
@@ -520,6 +520,32 @@ fn F() {
|
|
|
let or_result: Cpp.C = operator||(c1, c2);
|
|
|
}
|
|
|
|
|
|
+// ============================================================================
|
|
|
+// Operand is an inner class
|
|
|
+// ============================================================================
|
|
|
+
|
|
|
+// --- inner_class.h
|
|
|
+
|
|
|
+class O {
|
|
|
+ public:
|
|
|
+ class C {};
|
|
|
+};
|
|
|
+auto operator+(O::C lhs, O::C rhs) -> O::C;
|
|
|
+
|
|
|
+// --- import_inner_class.carbon
|
|
|
+
|
|
|
+library "[[@TEST_NAME]]";
|
|
|
+
|
|
|
+import Cpp library "inner_class.h";
|
|
|
+
|
|
|
+fn F() {
|
|
|
+ //@dump-sem-ir-begin
|
|
|
+ let c1: Cpp.O.C = Cpp.O.C.C();
|
|
|
+ let c2: Cpp.O.C = Cpp.O.C.C();
|
|
|
+ let c3: Cpp.O.C = c1 + c2;
|
|
|
+ //@dump-sem-ir-end
|
|
|
+}
|
|
|
+
|
|
|
// ============================================================================
|
|
|
// Member operator
|
|
|
// ============================================================================
|
|
|
@@ -1765,6 +1791,127 @@ fn F() {
|
|
|
// CHECK:STDOUT: <elided>
|
|
|
// CHECK:STDOUT: }
|
|
|
// CHECK:STDOUT:
|
|
|
+// CHECK:STDOUT: --- import_inner_class.carbon
|
|
|
+// CHECK:STDOUT:
|
|
|
+// CHECK:STDOUT: constants {
|
|
|
+// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
|
|
+// CHECK:STDOUT: %O: type = class_type @O [concrete]
|
|
|
+// CHECK:STDOUT: %C: type = class_type @C [concrete]
|
|
|
+// CHECK:STDOUT: %pattern_type.b28: 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: %ptr.de2: 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: %operator+__carbon_thunk.type: type = fn_type @operator+__carbon_thunk [concrete]
|
|
|
+// CHECK:STDOUT: %operator+__carbon_thunk: %operator+__carbon_thunk.type = struct_value () [concrete]
|
|
|
+// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.ac8: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete]
|
|
|
+// CHECK:STDOUT: %T.as.Destroy.impl.Op.362: %T.as.Destroy.impl.Op.type.ac8 = struct_value () [concrete]
|
|
|
+// CHECK:STDOUT: }
|
|
|
+// CHECK:STDOUT:
|
|
|
+// CHECK:STDOUT: imports {
|
|
|
+// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
|
|
|
+// CHECK:STDOUT: .O = %O.decl
|
|
|
+// CHECK:STDOUT: import Cpp//...
|
|
|
+// CHECK:STDOUT: }
|
|
|
+// CHECK:STDOUT: %O.decl: type = class_decl @O [concrete = constants.%O] {} {}
|
|
|
+// 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: %C__carbon_thunk.decl: %C__carbon_thunk.type = fn_decl @C__carbon_thunk [concrete = constants.%C__carbon_thunk] {
|
|
|
+// CHECK:STDOUT: <elided>
|
|
|
+// CHECK:STDOUT: } {
|
|
|
+// CHECK:STDOUT: <elided>
|
|
|
+// CHECK:STDOUT: }
|
|
|
+// CHECK:STDOUT: %operator+__carbon_thunk.decl: %operator+__carbon_thunk.type = fn_decl @operator+__carbon_thunk [concrete = constants.%operator+__carbon_thunk] {
|
|
|
+// CHECK:STDOUT: <elided>
|
|
|
+// CHECK:STDOUT: } {
|
|
|
+// CHECK:STDOUT: <elided>
|
|
|
+// CHECK:STDOUT: }
|
|
|
+// CHECK:STDOUT: }
|
|
|
+// CHECK:STDOUT:
|
|
|
+// CHECK:STDOUT: fn @F() {
|
|
|
+// CHECK:STDOUT: !entry:
|
|
|
+// CHECK:STDOUT: name_binding_decl {
|
|
|
+// CHECK:STDOUT: %c1.patt: %pattern_type.b28 = binding_pattern c1 [concrete]
|
|
|
+// CHECK:STDOUT: }
|
|
|
+// CHECK:STDOUT: %Cpp.ref.loc8_21: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
|
|
+// CHECK:STDOUT: %O.ref.loc8_24: type = name_ref O, imports.%O.decl [concrete = constants.%O]
|
|
|
+// CHECK:STDOUT: %C.ref.loc8_26: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
|
|
+// CHECK:STDOUT: %C.ref.loc8_28: %C.C.type = name_ref C, imports.%C.C.decl [concrete = constants.%C.C]
|
|
|
+// CHECK:STDOUT: %.loc8_31.1: ref %C = temporary_storage
|
|
|
+// CHECK:STDOUT: %addr.loc8_31.1: %ptr.de2 = addr_of %.loc8_31.1
|
|
|
+// CHECK:STDOUT: %C__carbon_thunk.call.loc8: init %empty_tuple.type = call imports.%C__carbon_thunk.decl(%addr.loc8_31.1)
|
|
|
+// CHECK:STDOUT: %.loc8_31.2: init %C = in_place_init %C__carbon_thunk.call.loc8, %.loc8_31.1
|
|
|
+// CHECK:STDOUT: %.loc8_16: type = splice_block %C.ref.loc8_16 [concrete = constants.%C] {
|
|
|
+// CHECK:STDOUT: %Cpp.ref.loc8_11: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
|
|
+// CHECK:STDOUT: %O.ref.loc8_14: type = name_ref O, imports.%O.decl [concrete = constants.%O]
|
|
|
+// CHECK:STDOUT: %C.ref.loc8_16: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
|
|
+// CHECK:STDOUT: }
|
|
|
+// CHECK:STDOUT: %.loc8_31.3: ref %C = temporary %.loc8_31.1, %.loc8_31.2
|
|
|
+// CHECK:STDOUT: %.loc8_31.4: %C = bind_value %.loc8_31.3
|
|
|
+// CHECK:STDOUT: %c1: %C = bind_name c1, %.loc8_31.4
|
|
|
+// CHECK:STDOUT: name_binding_decl {
|
|
|
+// CHECK:STDOUT: %c2.patt: %pattern_type.b28 = binding_pattern c2 [concrete]
|
|
|
+// CHECK:STDOUT: }
|
|
|
+// CHECK:STDOUT: %Cpp.ref.loc9_21: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
|
|
+// CHECK:STDOUT: %O.ref.loc9_24: type = name_ref O, imports.%O.decl [concrete = constants.%O]
|
|
|
+// CHECK:STDOUT: %C.ref.loc9_26: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
|
|
+// CHECK:STDOUT: %C.ref.loc9_28: %C.C.type = name_ref C, imports.%C.C.decl [concrete = constants.%C.C]
|
|
|
+// CHECK:STDOUT: %.loc9_31.1: ref %C = temporary_storage
|
|
|
+// CHECK:STDOUT: %addr.loc9_31.1: %ptr.de2 = addr_of %.loc9_31.1
|
|
|
+// CHECK:STDOUT: %C__carbon_thunk.call.loc9: init %empty_tuple.type = call imports.%C__carbon_thunk.decl(%addr.loc9_31.1)
|
|
|
+// CHECK:STDOUT: %.loc9_31.2: init %C = in_place_init %C__carbon_thunk.call.loc9, %.loc9_31.1
|
|
|
+// CHECK:STDOUT: %.loc9_16: type = splice_block %C.ref.loc9_16 [concrete = constants.%C] {
|
|
|
+// CHECK:STDOUT: %Cpp.ref.loc9_11: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
|
|
+// CHECK:STDOUT: %O.ref.loc9_14: type = name_ref O, imports.%O.decl [concrete = constants.%O]
|
|
|
+// CHECK:STDOUT: %C.ref.loc9_16: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
|
|
+// CHECK:STDOUT: }
|
|
|
+// CHECK:STDOUT: %.loc9_31.3: ref %C = temporary %.loc9_31.1, %.loc9_31.2
|
|
|
+// CHECK:STDOUT: %.loc9_31.4: %C = bind_value %.loc9_31.3
|
|
|
+// CHECK:STDOUT: %c2: %C = bind_name c2, %.loc9_31.4
|
|
|
+// CHECK:STDOUT: name_binding_decl {
|
|
|
+// CHECK:STDOUT: %c3.patt: %pattern_type.b28 = binding_pattern c3 [concrete]
|
|
|
+// CHECK:STDOUT: }
|
|
|
+// CHECK:STDOUT: %c1.ref: %C = name_ref c1, %c1
|
|
|
+// CHECK:STDOUT: %c2.ref: %C = name_ref c2, %c2
|
|
|
+// CHECK:STDOUT: %.loc10_24.1: ref %C = temporary_storage
|
|
|
+// CHECK:STDOUT: %.loc10_21: ref %C = value_as_ref %c1.ref
|
|
|
+// CHECK:STDOUT: %addr.loc10_24.1: %ptr.de2 = addr_of %.loc10_21
|
|
|
+// CHECK:STDOUT: %.loc10_26: ref %C = value_as_ref %c2.ref
|
|
|
+// CHECK:STDOUT: %addr.loc10_24.2: %ptr.de2 = addr_of %.loc10_26
|
|
|
+// CHECK:STDOUT: %addr.loc10_24.3: %ptr.de2 = addr_of %.loc10_24.1
|
|
|
+// CHECK:STDOUT: %operator+__carbon_thunk.call: init %empty_tuple.type = call imports.%operator+__carbon_thunk.decl(%addr.loc10_24.1, %addr.loc10_24.2, %addr.loc10_24.3)
|
|
|
+// CHECK:STDOUT: %.loc10_24.2: init %C = in_place_init %operator+__carbon_thunk.call, %.loc10_24.1
|
|
|
+// CHECK:STDOUT: %.loc10_16: type = splice_block %C.ref.loc10 [concrete = constants.%C] {
|
|
|
+// CHECK:STDOUT: %Cpp.ref.loc10: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
|
|
+// CHECK:STDOUT: %O.ref.loc10: type = name_ref O, imports.%O.decl [concrete = constants.%O]
|
|
|
+// CHECK:STDOUT: %C.ref.loc10: type = name_ref C, imports.%C.decl [concrete = constants.%C]
|
|
|
+// CHECK:STDOUT: }
|
|
|
+// CHECK:STDOUT: %.loc10_24.3: ref %C = temporary %.loc10_24.1, %.loc10_24.2
|
|
|
+// CHECK:STDOUT: %.loc10_24.4: %C = bind_value %.loc10_24.3
|
|
|
+// CHECK:STDOUT: %c3: %C = bind_name c3, %.loc10_24.4
|
|
|
+// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10: <bound method> = bound_method %.loc10_24.3, constants.%T.as.Destroy.impl.Op.362
|
|
|
+// CHECK:STDOUT: <elided>
|
|
|
+// CHECK:STDOUT: %bound_method.loc10: <bound method> = bound_method %.loc10_24.3, %T.as.Destroy.impl.Op.specific_fn.1
|
|
|
+// CHECK:STDOUT: %addr.loc10_24.4: %ptr.de2 = addr_of %.loc10_24.3
|
|
|
+// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc10: init %empty_tuple.type = call %bound_method.loc10(%addr.loc10_24.4)
|
|
|
+// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9: <bound method> = bound_method %.loc9_31.3, constants.%T.as.Destroy.impl.Op.362
|
|
|
+// CHECK:STDOUT: <elided>
|
|
|
+// CHECK:STDOUT: %bound_method.loc9: <bound method> = bound_method %.loc9_31.3, %T.as.Destroy.impl.Op.specific_fn.2
|
|
|
+// CHECK:STDOUT: %addr.loc9_31.2: %ptr.de2 = addr_of %.loc9_31.3
|
|
|
+// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc9: init %empty_tuple.type = call %bound_method.loc9(%addr.loc9_31.2)
|
|
|
+// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8: <bound method> = bound_method %.loc8_31.3, constants.%T.as.Destroy.impl.Op.362
|
|
|
+// CHECK:STDOUT: <elided>
|
|
|
+// CHECK:STDOUT: %bound_method.loc8: <bound method> = bound_method %.loc8_31.3, %T.as.Destroy.impl.Op.specific_fn.3
|
|
|
+// CHECK:STDOUT: %addr.loc8_31.2: %ptr.de2 = addr_of %.loc8_31.3
|
|
|
+// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8: init %empty_tuple.type = call %bound_method.loc8(%addr.loc8_31.2)
|
|
|
+// CHECK:STDOUT: <elided>
|
|
|
+// CHECK:STDOUT: }
|
|
|
+// CHECK:STDOUT:
|
|
|
// CHECK:STDOUT: --- fail_todo_import_member__add_with.carbon
|
|
|
// CHECK:STDOUT:
|
|
|
// CHECK:STDOUT: constants {
|