Skip to content

Commit fedb8a0

Browse files
committed
C++ interop: add a simple unit test for "using enum"
This unit test uses "using UEnum = Enum;" and imports that into Carbon.
1 parent 93b79f1 commit fedb8a0

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
2+
// Exceptions. See /LICENSE for license information.
3+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
//
5+
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/uint.carbon
6+
//
7+
// AUTOUPDATE
8+
// TIP: To test this file alone, run:
9+
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interop/cpp/enum/using.carbon
10+
// TIP: To dump output, run:
11+
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interop/cpp/enum/using.carbon
12+
13+
// --- enum.h
14+
15+
enum Enum { a, b, c };
16+
using UEnum = Enum;
17+
18+
enum Other { d };
19+
20+
// --- import_enum.carbon
21+
22+
library "[[@TEST_NAME]]";
23+
24+
import Cpp library "enum.h";
25+
26+
//@dump-sem-ir-begin
27+
fn F() {
28+
let a: Cpp.Enum = Cpp.Enum.a;
29+
let b: Cpp.UEnum = Cpp.UEnum.b;
30+
var c: Cpp.UEnum = Cpp.UEnum.c;
31+
c = b;
32+
}
33+
//@dump-sem-ir-end
34+
35+
// --- fail_wrong_enum.carbon
36+
37+
library "[[@TEST_NAME]]";
38+
39+
import Cpp library "enum.h";
40+
41+
fn F() {
42+
// CHECK:STDERR: fail_wrong_enum.carbon:[[@LINE+7]]:22: error: cannot implicitly convert expression of type `Cpp.Enum` to `Cpp.Other` [ConversionFailure]
43+
// CHECK:STDERR: let c: Cpp.Other = Cpp.UEnum.a;
44+
// CHECK:STDERR: ^~~~~~~~~~~
45+
// CHECK:STDERR: fail_wrong_enum.carbon:[[@LINE+4]]:22: note: type `Cpp.Enum` does not implement interface `Core.ImplicitAs(Cpp.Other)` [MissingImplInMemberAccessNote]
46+
// CHECK:STDERR: let c: Cpp.Other = Cpp.UEnum.a;
47+
// CHECK:STDERR: ^~~~~~~~~~~
48+
// CHECK:STDERR:
49+
let c: Cpp.Other = Cpp.UEnum.a;
50+
51+
}
52+
53+
// CHECK:STDOUT: --- import_enum.carbon
54+
// CHECK:STDOUT:
55+
// CHECK:STDOUT: constants {
56+
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
57+
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
58+
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
59+
// CHECK:STDOUT: %Enum: type = class_type @Enum [concrete]
60+
// CHECK:STDOUT: %pattern_type.ebf: type = pattern_type %Enum [concrete]
61+
// CHECK:STDOUT: %int_0: %Enum = int_value 0 [concrete]
62+
// CHECK:STDOUT: %int_1: %Enum = int_value 1 [concrete]
63+
// CHECK:STDOUT: %int_2: %Enum = int_value 2 [concrete]
64+
// CHECK:STDOUT: %type_where: type = facet_type <type where .Self impls <CanDestroy>> [concrete]
65+
// CHECK:STDOUT: %facet_value: %type_where = facet_value %Enum, () [concrete]
66+
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.cd9: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [concrete]
67+
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.0d9: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.cd9 = struct_value () [concrete]
68+
// CHECK:STDOUT: %ptr.47b: type = ptr_type %Enum [concrete]
69+
// CHECK:STDOUT: }
70+
// CHECK:STDOUT:
71+
// CHECK:STDOUT: imports {
72+
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
73+
// CHECK:STDOUT: .Enum = %Enum.decl
74+
// CHECK:STDOUT: .UEnum = %Enum.decl
75+
// CHECK:STDOUT: import Cpp//...
76+
// CHECK:STDOUT: }
77+
// CHECK:STDOUT: %Enum.decl: type = class_decl @Enum [concrete = constants.%Enum] {} {}
78+
// CHECK:STDOUT: %int_0: %Enum = int_value 0 [concrete = constants.%int_0]
79+
// CHECK:STDOUT: %int_1: %Enum = int_value 1 [concrete = constants.%int_1]
80+
// CHECK:STDOUT: %int_2: %Enum = int_value 2 [concrete = constants.%int_2]
81+
// CHECK:STDOUT: }
82+
// CHECK:STDOUT:
83+
// CHECK:STDOUT: file {
84+
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {}
85+
// CHECK:STDOUT: }
86+
// CHECK:STDOUT:
87+
// CHECK:STDOUT: fn @F() {
88+
// CHECK:STDOUT: !entry:
89+
// CHECK:STDOUT: name_binding_decl {
90+
// CHECK:STDOUT: %a.patt: %pattern_type.ebf = binding_pattern a [concrete]
91+
// CHECK:STDOUT: }
92+
// CHECK:STDOUT: %Cpp.ref.loc8_21: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
93+
// CHECK:STDOUT: %Enum.ref.loc8_24: type = name_ref Enum, imports.%Enum.decl [concrete = constants.%Enum]
94+
// CHECK:STDOUT: %a.ref: %Enum = name_ref a, imports.%int_0 [concrete = constants.%int_0]
95+
// CHECK:STDOUT: %.loc8: type = splice_block %Enum.ref.loc8_13 [concrete = constants.%Enum] {
96+
// CHECK:STDOUT: %Cpp.ref.loc8_10: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
97+
// CHECK:STDOUT: %Enum.ref.loc8_13: type = name_ref Enum, imports.%Enum.decl [concrete = constants.%Enum]
98+
// CHECK:STDOUT: }
99+
// CHECK:STDOUT: %a: %Enum = bind_name a, %a.ref
100+
// CHECK:STDOUT: name_binding_decl {
101+
// CHECK:STDOUT: %b.patt: %pattern_type.ebf = binding_pattern b [concrete]
102+
// CHECK:STDOUT: }
103+
// CHECK:STDOUT: %Cpp.ref.loc9_22: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
104+
// CHECK:STDOUT: %UEnum.ref.loc9_25: type = name_ref UEnum, imports.%Enum.decl [concrete = constants.%Enum]
105+
// CHECK:STDOUT: %b.ref.loc9: %Enum = name_ref b, imports.%int_1 [concrete = constants.%int_1]
106+
// CHECK:STDOUT: %.loc9: type = splice_block %UEnum.ref.loc9_13 [concrete = constants.%Enum] {
107+
// CHECK:STDOUT: %Cpp.ref.loc9_10: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
108+
// CHECK:STDOUT: %UEnum.ref.loc9_13: type = name_ref UEnum, imports.%Enum.decl [concrete = constants.%Enum]
109+
// CHECK:STDOUT: }
110+
// CHECK:STDOUT: %b: %Enum = bind_name b, %b.ref.loc9
111+
// CHECK:STDOUT: name_binding_decl {
112+
// CHECK:STDOUT: %c.patt: %pattern_type.ebf = binding_pattern c [concrete]
113+
// CHECK:STDOUT: %c.var_patt: %pattern_type.ebf = var_pattern %c.patt [concrete]
114+
// CHECK:STDOUT: }
115+
// CHECK:STDOUT: %c.var: ref %Enum = var %c.var_patt
116+
// CHECK:STDOUT: %Cpp.ref.loc10_22: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
117+
// CHECK:STDOUT: %UEnum.ref.loc10_25: type = name_ref UEnum, imports.%Enum.decl [concrete = constants.%Enum]
118+
// CHECK:STDOUT: %c.ref.loc10: %Enum = name_ref c, imports.%int_2 [concrete = constants.%int_2]
119+
// CHECK:STDOUT: assign %c.var, %c.ref.loc10
120+
// CHECK:STDOUT: %.loc10_13: type = splice_block %UEnum.ref.loc10_13 [concrete = constants.%Enum] {
121+
// CHECK:STDOUT: %Cpp.ref.loc10_10: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
122+
// CHECK:STDOUT: %UEnum.ref.loc10_13: type = name_ref UEnum, imports.%Enum.decl [concrete = constants.%Enum]
123+
// CHECK:STDOUT: }
124+
// CHECK:STDOUT: %c: ref %Enum = bind_name c, %c.var
125+
// CHECK:STDOUT: %c.ref.loc11: ref %Enum = name_ref c, %c
126+
// CHECK:STDOUT: %b.ref.loc11: %Enum = name_ref b, %b
127+
// CHECK:STDOUT: assign %c.ref.loc11, %b.ref.loc11
128+
// CHECK:STDOUT: %facet_value: %type_where = facet_value constants.%Enum, () [concrete = constants.%facet_value]
129+
// CHECK:STDOUT: %.loc10_3: %type_where = converted constants.%Enum, %facet_value [concrete = constants.%facet_value]
130+
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound: <bound method> = bound_method %c.var, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.0d9
131+
// CHECK:STDOUT: <elided>
132+
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %c.var, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn
133+
// CHECK:STDOUT: %addr: %ptr.47b = addr_of %c.var
134+
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr)
135+
// CHECK:STDOUT: return
136+
// CHECK:STDOUT: }
137+
// CHECK:STDOUT:

0 commit comments

Comments
 (0)