mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
356 lines
14 KiB
Plaintext
356 lines
14 KiB
Plaintext
// #target: macos-x64
|
|
module foo;
|
|
extern fn void printf(char*, ...);
|
|
|
|
fn void test(any x)
|
|
{
|
|
switch (x.type)
|
|
{
|
|
case int:
|
|
printf("Was int\n");
|
|
case double:
|
|
printf("Was double\n");
|
|
case any:
|
|
printf("Was variant\n");
|
|
case int*:
|
|
printf("Was int*\n");
|
|
default:
|
|
printf("Unknown type\n");
|
|
}
|
|
}
|
|
|
|
fn void test_all(any... y)
|
|
{
|
|
foreach (element : y)
|
|
{
|
|
test(element);
|
|
}
|
|
}
|
|
|
|
fn void main()
|
|
{
|
|
any x = &&1;
|
|
int z;
|
|
any y = &z;
|
|
typeid g = y.type;
|
|
typeid h = x.type;
|
|
if (y.type == int.typeid)
|
|
{
|
|
printf("y int match\n");
|
|
}
|
|
if (x.type == int.typeid)
|
|
{
|
|
printf("x int match\n");
|
|
}
|
|
y = &&1.0;
|
|
x = &x;
|
|
if (y.type == int.typeid)
|
|
{
|
|
printf("y int match\n");
|
|
}
|
|
if (x.type == int.typeid)
|
|
{
|
|
printf("x int match\n");
|
|
}
|
|
test(x);
|
|
test(&&1.0);
|
|
test(&&1);
|
|
test(&&true);
|
|
printf("----\n");
|
|
int* df = null;
|
|
test_all(x, x, &&1.0, &x, &df);
|
|
}
|
|
|
|
/* #expect: foo.ll
|
|
|
|
%any = type { ptr, i64 }
|
|
%"any[]" = type { ptr, i64 }
|
|
@"$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.any$" = linkonce global %.introspect { i8 7, i64 0, ptr null, i64 16, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8
|
|
@"$ct.p$int" = linkonce global %.introspect { i8 19, i64 0, ptr null, i64 8, i64 ptrtoint (ptr @"$ct.int" to i64), 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:
|
|
%x = alloca %any, align 8
|
|
%switch = alloca i64, align 8
|
|
store i64 %0, ptr %x, align 8
|
|
%ptradd = getelementptr inbounds i8, ptr %x, i64 8
|
|
store ptr %1, ptr %ptradd, align 8
|
|
%ptradd1 = getelementptr inbounds i8, ptr %x, 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
|
|
call void (ptr, ...) @printf(ptr @.str)
|
|
br label %switch.exit
|
|
|
|
next_if: ; preds = %result_block
|
|
br label %check_subtype3
|
|
|
|
check_subtype3: ; preds = %parent_type_block5, %next_if
|
|
%8 = phi i64 [ %3, %next_if ], [ %typeid.parent7, %parent_type_block5 ]
|
|
%eq4 = icmp eq i64 ptrtoint (ptr @"$ct.double" to i64), %8
|
|
br i1 %eq4, label %result_block8, label %parent_type_block5
|
|
|
|
parent_type_block5: ; preds = %check_subtype3
|
|
%9 = inttoptr i64 %8 to ptr
|
|
%ptradd6 = getelementptr inbounds i8, ptr %9, i64 8
|
|
%typeid.parent7 = load i64, ptr %ptradd6, align 8
|
|
%10 = icmp eq i64 %typeid.parent7, 0
|
|
br i1 %10, label %result_block8, label %check_subtype3
|
|
|
|
result_block8: ; preds = %parent_type_block5, %check_subtype3
|
|
%11 = phi i1 [ false, %parent_type_block5 ], [ true, %check_subtype3 ]
|
|
br i1 %11, label %switch.case9, label %next_if10
|
|
|
|
switch.case9: ; preds = %result_block8
|
|
call void (ptr, ...) @printf(ptr @.str.1)
|
|
br label %switch.exit
|
|
|
|
next_if10: ; preds = %result_block8
|
|
br label %check_subtype11
|
|
|
|
check_subtype11: ; preds = %parent_type_block13, %next_if10
|
|
%12 = phi i64 [ %3, %next_if10 ], [ %typeid.parent15, %parent_type_block13 ]
|
|
%eq12 = icmp eq i64 ptrtoint (ptr @"$ct.any$" to i64), %12
|
|
br i1 %eq12, label %result_block16, label %parent_type_block13
|
|
|
|
parent_type_block13: ; preds = %check_subtype11
|
|
%13 = inttoptr i64 %12 to ptr
|
|
%ptradd14 = getelementptr inbounds i8, ptr %13, i64 8
|
|
%typeid.parent15 = load i64, ptr %ptradd14, align 8
|
|
%14 = icmp eq i64 %typeid.parent15, 0
|
|
br i1 %14, label %result_block16, label %check_subtype11
|
|
|
|
result_block16: ; preds = %parent_type_block13, %check_subtype11
|
|
%15 = phi i1 [ false, %parent_type_block13 ], [ true, %check_subtype11 ]
|
|
br i1 %15, label %switch.case17, label %next_if18
|
|
|
|
switch.case17: ; preds = %result_block16
|
|
call void (ptr, ...) @printf(ptr @.str.2)
|
|
br label %switch.exit
|
|
|
|
next_if18: ; preds = %result_block16
|
|
br label %check_subtype19
|
|
|
|
check_subtype19: ; preds = %parent_type_block21, %next_if18
|
|
%16 = phi i64 [ %3, %next_if18 ], [ %typeid.parent23, %parent_type_block21 ]
|
|
%eq20 = icmp eq i64 ptrtoint (ptr @"$ct.p$int" to i64), %16
|
|
br i1 %eq20, label %result_block24, label %parent_type_block21
|
|
|
|
parent_type_block21: ; preds = %check_subtype19
|
|
%17 = inttoptr i64 %16 to ptr
|
|
%ptradd22 = getelementptr inbounds i8, ptr %17, i64 8
|
|
%typeid.parent23 = load i64, ptr %ptradd22, align 8
|
|
%18 = icmp eq i64 %typeid.parent23, 0
|
|
br i1 %18, label %result_block24, label %check_subtype19
|
|
|
|
result_block24: ; preds = %parent_type_block21, %check_subtype19
|
|
%19 = phi i1 [ false, %parent_type_block21 ], [ true, %check_subtype19 ]
|
|
br i1 %19, label %switch.case25, label %next_if26
|
|
|
|
switch.case25: ; preds = %result_block24
|
|
call void (ptr, ...) @printf(ptr @.str.3)
|
|
br label %switch.exit
|
|
|
|
next_if26: ; preds = %result_block24
|
|
br label %switch.default
|
|
|
|
switch.default: ; preds = %next_if26
|
|
call void (ptr, ...) @printf(ptr @.str.4)
|
|
br label %switch.exit
|
|
|
|
switch.exit: ; preds = %switch.default, %switch.case25, %switch.case17, %switch.case9, %switch.case
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs:
|
|
define void @foo.test_all(ptr %0, i64 %1) #0 {
|
|
entry:
|
|
%y = alloca %"any[]", align 8
|
|
%.anon = alloca i64, align 8
|
|
%element = alloca %any, align 8
|
|
store ptr %0, ptr %y, align 8
|
|
%ptradd = getelementptr inbounds i8, ptr %y, i64 8
|
|
store i64 %1, ptr %ptradd, align 8
|
|
%ptradd1 = getelementptr inbounds i8, ptr %y, i64 8
|
|
%2 = load i64, ptr %ptradd1, align 8
|
|
store i64 0, ptr %.anon, align 8
|
|
br label %loop.cond
|
|
|
|
loop.cond: ; preds = %loop.body, %entry
|
|
%3 = load i64, ptr %.anon, align 8
|
|
%lt = icmp ult i64 %3, %2
|
|
br i1 %lt, label %loop.body, label %loop.exit
|
|
|
|
loop.body: ; preds = %loop.cond
|
|
%4 = load ptr, ptr %y, align 8
|
|
%5 = load i64, ptr %.anon, align 8
|
|
%ptroffset = getelementptr inbounds [16 x i8], ptr %4, i64 %5
|
|
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %element, ptr align 8 %ptroffset, i32 16, i1 false)
|
|
%lo = load i64, ptr %element, align 8
|
|
%ptradd2 = getelementptr inbounds i8, ptr %element, i64 8
|
|
%hi = load ptr, ptr %ptradd2, align 8
|
|
call void @foo.test(i64 %lo, ptr %hi)
|
|
%6 = load i64, ptr %.anon, align 8
|
|
%addnuw = add nuw i64 %6, 1
|
|
store i64 %addnuw, ptr %.anon, align 8
|
|
br label %loop.cond
|
|
|
|
loop.exit: ; preds = %loop.cond
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs:
|
|
define void @foo.main() #0 {
|
|
entry:
|
|
%x = alloca %any, align 8
|
|
%taddr = alloca i32, align 4
|
|
%z = alloca i32, align 4
|
|
%y = alloca %any, align 8
|
|
%g = alloca i64, align 8
|
|
%h = alloca i64, align 8
|
|
%taddr7 = alloca double, align 8
|
|
%taddr17 = alloca double, align 8
|
|
%taddr18 = alloca %any, align 8
|
|
%taddr22 = alloca i32, align 4
|
|
%taddr23 = alloca %any, align 8
|
|
%taddr27 = alloca i8, align 1
|
|
%taddr28 = alloca %any, align 8
|
|
%df = alloca ptr, align 8
|
|
%varargslots = alloca [5 x %any], align 16
|
|
%taddr33 = alloca double, align 8
|
|
store i32 1, ptr %taddr, align 4
|
|
%0 = insertvalue %any undef, ptr %taddr, 0
|
|
%1 = insertvalue %any %0, i64 ptrtoint (ptr @"$ct.int" to i64), 1
|
|
store %any %1, ptr %x, align 8
|
|
store i32 0, ptr %z, align 4
|
|
%2 = insertvalue %any undef, ptr %z, 0
|
|
%3 = insertvalue %any %2, i64 ptrtoint (ptr @"$ct.int" to i64), 1
|
|
store %any %3, ptr %y, align 8
|
|
%ptradd = getelementptr inbounds i8, ptr %y, i64 8
|
|
%4 = load i64, ptr %ptradd, align 8
|
|
store i64 %4, ptr %g, align 8
|
|
%ptradd1 = getelementptr inbounds i8, ptr %x, i64 8
|
|
%5 = load i64, ptr %ptradd1, align 8
|
|
store i64 %5, ptr %h, align 8
|
|
%ptradd2 = getelementptr inbounds i8, ptr %y, i64 8
|
|
%6 = load i64, ptr %ptradd2, align 8
|
|
%eq = icmp eq i64 %6, ptrtoint (ptr @"$ct.int" to i64)
|
|
br i1 %eq, label %if.then, label %if.exit
|
|
|
|
if.then: ; preds = %entry
|
|
call void (ptr, ...) @printf(ptr @.str.5)
|
|
br label %if.exit
|
|
|
|
if.exit: ; preds = %if.then, %entry
|
|
%ptradd3 = getelementptr inbounds i8, ptr %x, i64 8
|
|
%7 = load i64, ptr %ptradd3, align 8
|
|
%eq4 = icmp eq i64 %7, ptrtoint (ptr @"$ct.int" to i64)
|
|
br i1 %eq4, label %if.then5, label %if.exit6
|
|
|
|
if.then5: ; preds = %if.exit
|
|
call void (ptr, ...) @printf(ptr @.str.6)
|
|
br label %if.exit6
|
|
|
|
if.exit6: ; preds = %if.then5, %if.exit
|
|
store double 1.000000e+00, ptr %taddr7, align 8
|
|
%8 = insertvalue %any undef, ptr %taddr7, 0
|
|
%9 = insertvalue %any %8, i64 ptrtoint (ptr @"$ct.double" to i64), 1
|
|
store %any %9, ptr %y, align 8
|
|
%10 = insertvalue %any undef, ptr %x, 0
|
|
%11 = insertvalue %any %10, i64 ptrtoint (ptr @"$ct.any$" to i64), 1
|
|
store %any %11, ptr %x, align 8
|
|
%ptradd8 = getelementptr inbounds i8, ptr %y, i64 8
|
|
%12 = load i64, ptr %ptradd8, align 8
|
|
%eq9 = icmp eq i64 %12, ptrtoint (ptr @"$ct.int" to i64)
|
|
br i1 %eq9, label %if.then10, label %if.exit11
|
|
|
|
if.then10: ; preds = %if.exit6
|
|
call void (ptr, ...) @printf(ptr @.str.7)
|
|
br label %if.exit11
|
|
|
|
if.exit11: ; preds = %if.then10, %if.exit6
|
|
%ptradd12 = getelementptr inbounds i8, ptr %x, i64 8
|
|
%13 = load i64, ptr %ptradd12, align 8
|
|
%eq13 = icmp eq i64 %13, ptrtoint (ptr @"$ct.int" to i64)
|
|
br i1 %eq13, label %if.then14, label %if.exit15
|
|
|
|
if.then14: ; preds = %if.exit11
|
|
call void (ptr, ...) @printf(ptr @.str.8)
|
|
br label %if.exit15
|
|
|
|
if.exit15: ; preds = %if.then14, %if.exit11
|
|
%lo = load i64, ptr %x, align 8
|
|
%ptradd16 = getelementptr inbounds i8, ptr %x, i64 8
|
|
%hi = load ptr, ptr %ptradd16, align 8
|
|
call void @foo.test(i64 %lo, ptr %hi)
|
|
store double 1.000000e+00, ptr %taddr17, align 8
|
|
%14 = insertvalue %any undef, ptr %taddr17, 0
|
|
%15 = insertvalue %any %14, i64 ptrtoint (ptr @"$ct.double" to i64), 1
|
|
store %any %15, ptr %taddr18, align 8
|
|
%lo19 = load i64, ptr %taddr18, align 8
|
|
%ptradd20 = getelementptr inbounds i8, ptr %taddr18, i64 8
|
|
%hi21 = load ptr, ptr %ptradd20, align 8
|
|
call void @foo.test(i64 %lo19, ptr %hi21)
|
|
store i32 1, ptr %taddr22, align 4
|
|
%16 = insertvalue %any undef, ptr %taddr22, 0
|
|
%17 = insertvalue %any %16, i64 ptrtoint (ptr @"$ct.int" to i64), 1
|
|
store %any %17, ptr %taddr23, align 8
|
|
%lo24 = load i64, ptr %taddr23, align 8
|
|
%ptradd25 = getelementptr inbounds i8, ptr %taddr23, i64 8
|
|
%hi26 = load ptr, ptr %ptradd25, align 8
|
|
call void @foo.test(i64 %lo24, ptr %hi26)
|
|
store i8 1, ptr %taddr27, align 1
|
|
%18 = insertvalue %any undef, ptr %taddr27, 0
|
|
%19 = insertvalue %any %18, i64 ptrtoint (ptr @"$ct.bool" to i64), 1
|
|
store %any %19, ptr %taddr28, align 8
|
|
%lo29 = load i64, ptr %taddr28, align 8
|
|
%ptradd30 = getelementptr inbounds i8, ptr %taddr28, i64 8
|
|
%hi31 = load ptr, ptr %ptradd30, align 8
|
|
call void @foo.test(i64 %lo29, ptr %hi31)
|
|
call void (ptr, ...) @printf(ptr @.str.9)
|
|
store ptr null, ptr %df, align 8
|
|
call void @llvm.memcpy.p0.p0.i32(ptr align 16 %varargslots, ptr align 8 %x, i32 16, i1 false)
|
|
%ptradd32 = getelementptr inbounds i8, ptr %varargslots, i64 16
|
|
call void @llvm.memcpy.p0.p0.i32(ptr align 16 %ptradd32, ptr align 8 %x, i32 16, i1 false)
|
|
store double 1.000000e+00, ptr %taddr33, align 8
|
|
%20 = insertvalue %any undef, ptr %taddr33, 0
|
|
%21 = insertvalue %any %20, i64 ptrtoint (ptr @"$ct.double" to i64), 1
|
|
%ptradd34 = getelementptr inbounds i8, ptr %varargslots, i64 32
|
|
store %any %21, ptr %ptradd34, align 16
|
|
%22 = insertvalue %any undef, ptr %x, 0
|
|
%23 = insertvalue %any %22, i64 ptrtoint (ptr @"$ct.any$" to i64), 1
|
|
%ptradd35 = getelementptr inbounds i8, ptr %varargslots, i64 48
|
|
store %any %23, ptr %ptradd35, align 16
|
|
%24 = insertvalue %any undef, ptr %df, 0
|
|
%25 = insertvalue %any %24, i64 ptrtoint (ptr @"$ct.p$int" to i64), 1
|
|
%ptradd36 = getelementptr inbounds i8, ptr %varargslots, i64 64
|
|
store %any %25, ptr %ptradd36, align 16
|
|
call void @foo.test_all(ptr %varargslots, i64 5)
|
|
ret void
|
|
}
|