mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
160 lines
5.8 KiB
Plaintext
160 lines
5.8 KiB
Plaintext
// #target: macos-x64
|
|
module foo;
|
|
|
|
extern fn void printf(char*, ...);
|
|
|
|
fn void test(any z)
|
|
{
|
|
switch (z.type)
|
|
{
|
|
case int:
|
|
printf("int: %d\n", *(int*)z);
|
|
*(int*)z = 3;
|
|
case double:
|
|
printf("double %f\n", *(double*)z);
|
|
default:
|
|
printf("Unknown type.\n");
|
|
}
|
|
if (z.type == int.typeid)
|
|
{
|
|
printf("int: %d\n", *(int*)(z));
|
|
}
|
|
}
|
|
fn int main()
|
|
{
|
|
test(&&123.0);
|
|
test(&&1);
|
|
test(&&true);
|
|
return 0;
|
|
}
|
|
|
|
/* #expect: foo.ll
|
|
|
|
@"$ct.int" = linkonce global %.introspect { i8 2, i64 0, ptr null, i64 4, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8
|
|
@"$ct.double" = linkonce global %.introspect { i8 4, i64 0, ptr null, i64 8, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8
|
|
@"$ct.bool" = linkonce global %.introspect { i8 1, i64 0, ptr null, i64 1, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8
|
|
|
|
define void @foo.test(i64 %0, ptr %1) #0 {
|
|
entry:
|
|
%z = alloca %any, align 8
|
|
%switch = alloca i64, align 8
|
|
store i64 %0, ptr %z, align 8
|
|
%ptradd = getelementptr inbounds i8, ptr %z, i64 8
|
|
store ptr %1, ptr %ptradd, align 8
|
|
%ptradd1 = getelementptr inbounds i8, ptr %z, i64 8
|
|
%2 = load i64, ptr %ptradd1, align 8
|
|
store i64 %2, ptr %switch, align 8
|
|
br label %switch.entry
|
|
|
|
switch.entry: ; preds = %entry
|
|
%3 = load i64, ptr %switch, align 8
|
|
br label %check_subtype
|
|
|
|
check_subtype: ; preds = %parent_type_block, %switch.entry
|
|
%4 = phi i64 [ %3, %switch.entry ], [ %typeid.parent, %parent_type_block ]
|
|
%eq = icmp eq i64 ptrtoint (ptr @"$ct.int" to i64), %4
|
|
br i1 %eq, label %result_block, label %parent_type_block
|
|
|
|
parent_type_block: ; preds = %check_subtype
|
|
%5 = inttoptr i64 %4 to ptr
|
|
%ptradd2 = getelementptr inbounds i8, ptr %5, i64 8
|
|
%typeid.parent = load i64, ptr %ptradd2, align 8
|
|
%6 = icmp eq i64 %typeid.parent, 0
|
|
br i1 %6, label %result_block, label %check_subtype
|
|
|
|
result_block: ; preds = %parent_type_block, %check_subtype
|
|
%7 = phi i1 [ false, %parent_type_block ], [ true, %check_subtype ]
|
|
br i1 %7, label %switch.case, label %next_if
|
|
|
|
switch.case: ; preds = %result_block
|
|
%8 = load ptr, ptr %z, align 8
|
|
%9 = load i32, ptr %8, align 4
|
|
call void (ptr, ...) @printf(ptr @.str, i32 %9)
|
|
%10 = load ptr, ptr %z, align 8
|
|
store i32 3, ptr %10, align 4
|
|
br label %switch.exit
|
|
|
|
next_if: ; preds = %result_block
|
|
br label %check_subtype3
|
|
|
|
check_subtype3: ; preds = %parent_type_block5, %next_if
|
|
%11 = phi i64 [ %3, %next_if ], [ %typeid.parent7, %parent_type_block5 ]
|
|
%eq4 = icmp eq i64 ptrtoint (ptr @"$ct.double" to i64), %11
|
|
br i1 %eq4, label %result_block8, label %parent_type_block5
|
|
|
|
parent_type_block5: ; preds = %check_subtype3
|
|
%12 = inttoptr i64 %11 to ptr
|
|
%ptradd6 = getelementptr inbounds i8, ptr %12, i64 8
|
|
%typeid.parent7 = load i64, ptr %ptradd6, align 8
|
|
%13 = icmp eq i64 %typeid.parent7, 0
|
|
br i1 %13, label %result_block8, label %check_subtype3
|
|
|
|
result_block8: ; preds = %parent_type_block5, %check_subtype3
|
|
%14 = phi i1 [ false, %parent_type_block5 ], [ true, %check_subtype3 ]
|
|
br i1 %14, label %switch.case9, label %next_if10
|
|
|
|
switch.case9: ; preds = %result_block8
|
|
%15 = load ptr, ptr %z, align 8
|
|
%16 = load double, ptr %15, align 8
|
|
call void (ptr, ...) @printf(ptr @.str.1, double %16)
|
|
br label %switch.exit
|
|
|
|
next_if10: ; preds = %result_block8
|
|
br label %switch.default
|
|
|
|
switch.default: ; preds = %next_if10
|
|
call void (ptr, ...) @printf(ptr @.str.2)
|
|
br label %switch.exit
|
|
|
|
switch.exit: ; preds = %switch.default, %switch.case9, %switch.case
|
|
%ptradd11 = getelementptr inbounds i8, ptr %z, i64 8
|
|
%17 = load i64, ptr %ptradd11, align 8
|
|
%eq12 = icmp eq i64 %17, ptrtoint (ptr @"$ct.int" to i64)
|
|
br i1 %eq12, label %if.then, label %if.exit
|
|
|
|
if.then: ; preds = %switch.exit
|
|
%18 = load ptr, ptr %z, align 8
|
|
%19 = load i32, ptr %18, align 4
|
|
call void (ptr, ...) @printf(ptr @.str.3, i32 %19)
|
|
br label %if.exit
|
|
|
|
if.exit: ; preds = %if.then, %switch.exit
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs:
|
|
define i32 @main() #0 {
|
|
entry:
|
|
%taddr = alloca double, align 8
|
|
%taddr1 = alloca %any, align 8
|
|
%taddr2 = alloca i32, align 4
|
|
%taddr3 = alloca %any, align 8
|
|
%taddr7 = alloca i8, align 1
|
|
%taddr8 = alloca %any, align 8
|
|
store double 1.230000e+02, ptr %taddr, align 8
|
|
%0 = insertvalue %any undef, ptr %taddr, 0
|
|
%1 = insertvalue %any %0, i64 ptrtoint (ptr @"$ct.double" to i64), 1
|
|
store %any %1, ptr %taddr1, align 8
|
|
%lo = load i64, ptr %taddr1, align 8
|
|
%ptradd = getelementptr inbounds i8, ptr %taddr1, i64 8
|
|
%hi = load ptr, ptr %ptradd, align 8
|
|
call void @foo.test(i64 %lo, ptr %hi)
|
|
store i32 1, ptr %taddr2, align 4
|
|
%2 = insertvalue %any undef, ptr %taddr2, 0
|
|
%3 = insertvalue %any %2, i64 ptrtoint (ptr @"$ct.int" to i64), 1
|
|
store %any %3, ptr %taddr3, align 8
|
|
%lo4 = load i64, ptr %taddr3, align 8
|
|
%ptradd5 = getelementptr inbounds i8, ptr %taddr3, i64 8
|
|
%hi6 = load ptr, ptr %ptradd5, align 8
|
|
call void @foo.test(i64 %lo4, ptr %hi6)
|
|
store i8 1, ptr %taddr7, align 1
|
|
%4 = insertvalue %any undef, ptr %taddr7, 0
|
|
%5 = insertvalue %any %4, i64 ptrtoint (ptr @"$ct.bool" to i64), 1
|
|
store %any %5, ptr %taddr8, align 8
|
|
%lo9 = load i64, ptr %taddr8, align 8
|
|
%ptradd10 = getelementptr inbounds i8, ptr %taddr8, i64 8
|
|
%hi11 = load ptr, ptr %ptradd10, align 8
|
|
call void @foo.test(i64 %lo9, ptr %hi11)
|
|
ret i32 0
|
|
}
|