mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Add foreach_r tests
This commit is contained in:
committed by
Christoffer Lerno
parent
9a3e7fd34b
commit
15586b3076
@@ -1,6 +1,6 @@
|
||||
// #target: macos-x64
|
||||
|
||||
module foo;
|
||||
module test;
|
||||
struct Foo
|
||||
{
|
||||
int[] x;
|
||||
@@ -31,10 +31,10 @@ fn void main()
|
||||
|
||||
extern fn int printf(char *fmt, ...);
|
||||
|
||||
/* #expect: foo.ll
|
||||
/* #expect: test.ll
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @foo_main() #0 {
|
||||
define void @test_main() #0 {
|
||||
entry:
|
||||
%i = alloca [3 x i32], align 4
|
||||
%x = alloca %Foo, align 8
|
||||
@@ -81,4 +81,14 @@ loop.body2: ; preds = %loop.body
|
||||
|
||||
loop.exit: ; preds = %loop.body2, %loop.cond
|
||||
ret void
|
||||
}
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i32 @printf(i8*, ...) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i32 @main(i32 %0, i8** %1) #0 {
|
||||
entry:
|
||||
call void @test_main()
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
72
test/test_suite/statements/foreach_r_break.c3t
Normal file
72
test/test_suite/statements/foreach_r_break.c3t
Normal file
@@ -0,0 +1,72 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
|
||||
fn void test()
|
||||
{
|
||||
int[3] x;
|
||||
int g = 0;
|
||||
foreach_r (z : x)
|
||||
{
|
||||
if (z > 0) break;
|
||||
if (z == 1) continue;
|
||||
g += z;
|
||||
}
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @test_test() #0 {
|
||||
entry:
|
||||
%x = alloca [3 x i32], align 4
|
||||
%g = alloca i32, align 4
|
||||
%.anon = alloca i64, align 8
|
||||
%z = alloca i32, align 4
|
||||
%0 = getelementptr inbounds [3 x i32], [3 x i32]* %x, i64 0, i64 0
|
||||
store i32 0, i32* %0, align 4
|
||||
%1 = getelementptr inbounds [3 x i32], [3 x i32]* %x, i64 0, i64 1
|
||||
store i32 0, i32* %1, align 4
|
||||
%2 = getelementptr inbounds [3 x i32], [3 x i32]* %x, i64 0, i64 2
|
||||
store i32 0, i32* %2, align 4
|
||||
store i32 0, i32* %g, align 4
|
||||
store i64 3, i64* %.anon, align 8
|
||||
br label %loop.cond
|
||||
|
||||
loop.cond: ; preds = %if.exit3, %if.then2, %entry
|
||||
%3 = load i64, i64* %.anon, align 8
|
||||
%gt = icmp ugt i64 %3, 0
|
||||
br i1 %gt, label %loop.body, label %loop.exit
|
||||
|
||||
loop.body: ; preds = %loop.cond
|
||||
%4 = load i64, i64* %.anon, align 8
|
||||
%sub = sub i64 %4, 1
|
||||
store i64 %sub, i64* %.anon, align 8
|
||||
%5 = load i64, i64* %.anon, align 8
|
||||
%6 = getelementptr inbounds [3 x i32], [3 x i32]* %x, i64 0, i64 %5
|
||||
%7 = load i32, i32* %6, align 4
|
||||
store i32 %7, i32* %z, align 4
|
||||
%8 = load i32, i32* %z, align 4
|
||||
%gt1 = icmp sgt i32 %8, 0
|
||||
br i1 %gt1, label %if.then, label %if.exit
|
||||
|
||||
if.then: ; preds = %loop.body
|
||||
br label %loop.exit
|
||||
|
||||
if.exit: ; preds = %loop.body
|
||||
%9 = load i32, i32* %z, align 4
|
||||
%eq = icmp eq i32 %9, 1
|
||||
br i1 %eq, label %if.then2, label %if.exit3
|
||||
|
||||
if.then2: ; preds = %if.exit
|
||||
br label %loop.cond
|
||||
|
||||
if.exit3: ; preds = %if.exit
|
||||
%10 = load i32, i32* %g, align 4
|
||||
%11 = load i32, i32* %z, align 4
|
||||
%add = add i32 %10, %11
|
||||
store i32 %add, i32* %g, align 4
|
||||
br label %loop.cond
|
||||
|
||||
loop.exit: ; preds = %if.then, %loop.cond
|
||||
ret void
|
||||
}
|
||||
353
test/test_suite/statements/foreach_r_common.c3t
Normal file
353
test/test_suite/statements/foreach_r_common.c3t
Normal file
@@ -0,0 +1,353 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
|
||||
extern fn void printf(char*, ...);
|
||||
|
||||
fn void main()
|
||||
{
|
||||
float[3] foo = { 2, 4.5, 8 };
|
||||
float[<3>] foo2 = { 2, 4.5, 8 };
|
||||
foreach_r (a : foo)
|
||||
{
|
||||
printf("Value: %f\n", a);
|
||||
}
|
||||
foreach_r (float* &a : foo)
|
||||
{
|
||||
*a *= 2;
|
||||
printf("Value: %f\n", *a);
|
||||
}
|
||||
foreach_r (void* &a : foo)
|
||||
{
|
||||
printf("Value: %f\n", *((float*)(a)));
|
||||
}
|
||||
foreach_r (i, a : foo)
|
||||
{
|
||||
printf("Value[%d]: %f\n", i, a);
|
||||
}
|
||||
foreach_r (char i, double a : foo)
|
||||
{
|
||||
printf("Value2[%d]: %f\n", i, a);
|
||||
}
|
||||
foreach_r (double a : foo)
|
||||
{
|
||||
printf("Value3: %f\n", a);
|
||||
}
|
||||
|
||||
foreach_r (a : foo2)
|
||||
{
|
||||
printf("Value: %f\n", a);
|
||||
}
|
||||
foreach_r (i, a : foo2)
|
||||
{
|
||||
printf("Value[%d]: %f\n", i, a);
|
||||
}
|
||||
foreach_r (char i, double a : foo2)
|
||||
{
|
||||
printf("Value2[%d]: %f\n", i, a);
|
||||
}
|
||||
foreach_r (double a : foo2)
|
||||
{
|
||||
printf("Value3: %f\n", a);
|
||||
}
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
@.__const = private unnamed_addr constant [3 x float] [float 2.000000e+00, float 4.500000e+00, float 8.000000e+00], align 4
|
||||
@.str = private unnamed_addr constant [11 x i8] c"Value: %f\0A\00", align 1
|
||||
@.str.1 = private unnamed_addr constant [11 x i8] c"Value: %f\0A\00", align 1
|
||||
@.str.2 = private unnamed_addr constant [11 x i8] c"Value: %f\0A\00", align 1
|
||||
@.str.3 = private unnamed_addr constant [15 x i8] c"Value[%d]: %f\0A\00", align 1
|
||||
@.str.4 = private unnamed_addr constant [16 x i8] c"Value2[%d]: %f\0A\00", align 1
|
||||
@.str.5 = private unnamed_addr constant [12 x i8] c"Value3: %f\0A\00", align 1
|
||||
@.str.6 = private unnamed_addr constant [11 x i8] c"Value: %f\0A\00", align 1
|
||||
@.str.7 = private unnamed_addr constant [15 x i8] c"Value[%d]: %f\0A\00", align 1
|
||||
@.str.8 = private unnamed_addr constant [16 x i8] c"Value2[%d]: %f\0A\00", align 1
|
||||
@.str.9 = private unnamed_addr constant [12 x i8] c"Value3: %f\0A\00", align 1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @printf(i8*, ...) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @test_main() #0 {
|
||||
entry:
|
||||
%foo = alloca [3 x float], align 4
|
||||
%foo2 = alloca <3 x float>, align 16
|
||||
%.anon = alloca i64, align 8
|
||||
%a = alloca float, align 4
|
||||
%.anon1 = alloca i64, align 8
|
||||
%a6 = alloca float*, align 8
|
||||
%.anon9 = alloca i64, align 8
|
||||
%a14 = alloca i8*, align 8
|
||||
%.anon18 = alloca i64, align 8
|
||||
%i = alloca i64, align 8
|
||||
%a23 = alloca float, align 4
|
||||
%.anon26 = alloca i64, align 8
|
||||
%i31 = alloca i8, align 1
|
||||
%a32 = alloca double, align 8
|
||||
%.anon35 = alloca i64, align 8
|
||||
%a40 = alloca double, align 8
|
||||
%.anon43 = alloca i64, align 8
|
||||
%a48 = alloca float, align 4
|
||||
%.anon51 = alloca i64, align 8
|
||||
%i56 = alloca i64, align 8
|
||||
%a57 = alloca float, align 4
|
||||
%.anon60 = alloca i64, align 8
|
||||
%i65 = alloca i8, align 1
|
||||
%a67 = alloca double, align 8
|
||||
%.anon71 = alloca i64, align 8
|
||||
%a76 = alloca double, align 8
|
||||
%0 = bitcast [3 x float]* %foo to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %0, i8* align 4 bitcast ([3 x float]* @.__const to i8*), i32 12, i1 false)
|
||||
store <3 x float> <float 2.000000e+00, float 4.500000e+00, float 8.000000e+00>, <3 x float>* %foo2, align 16
|
||||
store i64 3, i64* %.anon, align 8
|
||||
br label %loop.cond
|
||||
|
||||
loop.cond: ; preds = %loop.body, %entry
|
||||
%1 = load i64, i64* %.anon, align 8
|
||||
%gt = icmp ugt i64 %1, 0
|
||||
br i1 %gt, label %loop.body, label %loop.exit
|
||||
|
||||
loop.body: ; preds = %loop.cond
|
||||
%2 = load i64, i64* %.anon, align 8
|
||||
%sub = sub i64 %2, 1
|
||||
store i64 %sub, i64* %.anon, align 8
|
||||
%3 = load i64, i64* %.anon, align 8
|
||||
%4 = getelementptr inbounds [3 x float], [3 x float]* %foo, i64 0, i64 %3
|
||||
%5 = load float, float* %4, align 4
|
||||
store float %5, float* %a, align 4
|
||||
%6 = load float, float* %a, align 4
|
||||
%fpfpext = fpext float %6 to double
|
||||
call void (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i32 0, i32 0), double %fpfpext)
|
||||
br label %loop.cond
|
||||
|
||||
loop.exit: ; preds = %loop.cond
|
||||
store i64 3, i64* %.anon1, align 8
|
||||
br label %loop.cond2
|
||||
|
||||
loop.cond2: ; preds = %loop.body4, %loop.exit
|
||||
%7 = load i64, i64* %.anon1, align 8
|
||||
%gt3 = icmp ugt i64 %7, 0
|
||||
br i1 %gt3, label %loop.body4, label %loop.exit8
|
||||
|
||||
loop.body4: ; preds = %loop.cond2
|
||||
%8 = load i64, i64* %.anon1, align 8
|
||||
%sub5 = sub i64 %8, 1
|
||||
store i64 %sub5, i64* %.anon1, align 8
|
||||
%9 = load i64, i64* %.anon1, align 8
|
||||
%10 = getelementptr inbounds [3 x float], [3 x float]* %foo, i64 0, i64 %9
|
||||
store float* %10, float** %a6, align 8
|
||||
%11 = load float*, float** %a6, align 8
|
||||
%12 = load float, float* %11, align 8
|
||||
%fmul = fmul float %12, 2.000000e+00
|
||||
store float %fmul, float* %11, align 8
|
||||
%13 = load float*, float** %a6, align 8
|
||||
%14 = load float, float* %13, align 8
|
||||
%fpfpext7 = fpext float %14 to double
|
||||
call void (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.1, i32 0, i32 0), double %fpfpext7)
|
||||
br label %loop.cond2
|
||||
|
||||
loop.exit8: ; preds = %loop.cond2
|
||||
store i64 3, i64* %.anon9, align 8
|
||||
br label %loop.cond10
|
||||
|
||||
loop.cond10: ; preds = %loop.body12, %loop.exit8
|
||||
%15 = load i64, i64* %.anon9, align 8
|
||||
%gt11 = icmp ugt i64 %15, 0
|
||||
br i1 %gt11, label %loop.body12, label %loop.exit17
|
||||
|
||||
loop.body12: ; preds = %loop.cond10
|
||||
%16 = load i64, i64* %.anon9, align 8
|
||||
%sub13 = sub i64 %16, 1
|
||||
store i64 %sub13, i64* %.anon9, align 8
|
||||
%17 = load i64, i64* %.anon9, align 8
|
||||
%18 = getelementptr inbounds [3 x float], [3 x float]* %foo, i64 0, i64 %17
|
||||
%ptrptr = bitcast float* %18 to i8*
|
||||
store i8* %ptrptr, i8** %a14, align 8
|
||||
%19 = load i8*, i8** %a14, align 8
|
||||
%ptrptr15 = bitcast i8* %19 to float*
|
||||
%20 = load float, float* %ptrptr15, align 8
|
||||
%fpfpext16 = fpext float %20 to double
|
||||
call void (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.2, i32 0, i32 0), double %fpfpext16)
|
||||
br label %loop.cond10
|
||||
|
||||
loop.exit17: ; preds = %loop.cond10
|
||||
store i64 3, i64* %.anon18, align 8
|
||||
br label %loop.cond19
|
||||
|
||||
loop.cond19: ; preds = %loop.body21, %loop.exit17
|
||||
%21 = load i64, i64* %.anon18, align 8
|
||||
%gt20 = icmp ugt i64 %21, 0
|
||||
br i1 %gt20, label %loop.body21, label %loop.exit25
|
||||
|
||||
loop.body21: ; preds = %loop.cond19
|
||||
%22 = load i64, i64* %.anon18, align 8
|
||||
%sub22 = sub i64 %22, 1
|
||||
store i64 %sub22, i64* %.anon18, align 8
|
||||
%23 = load i64, i64* %.anon18, align 8
|
||||
store i64 %23, i64* %i, align 8
|
||||
%24 = load i64, i64* %.anon18, align 8
|
||||
%25 = getelementptr inbounds [3 x float], [3 x float]* %foo, i64 0, i64 %24
|
||||
%26 = load float, float* %25, align 4
|
||||
store float %26, float* %a23, align 4
|
||||
%27 = load i64, i64* %i, align 8
|
||||
%28 = load float, float* %a23, align 4
|
||||
%fpfpext24 = fpext float %28 to double
|
||||
call void (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.3, i32 0, i32 0), i64 %27, double %fpfpext24)
|
||||
br label %loop.cond19
|
||||
|
||||
loop.exit25: ; preds = %loop.cond19
|
||||
store i64 3, i64* %.anon26, align 8
|
||||
br label %loop.cond27
|
||||
|
||||
loop.cond27: ; preds = %loop.body29, %loop.exit25
|
||||
%29 = load i64, i64* %.anon26, align 8
|
||||
%gt28 = icmp ugt i64 %29, 0
|
||||
br i1 %gt28, label %loop.body29, label %loop.exit34
|
||||
|
||||
loop.body29: ; preds = %loop.cond27
|
||||
%30 = load i64, i64* %.anon26, align 8
|
||||
%sub30 = sub i64 %30, 1
|
||||
store i64 %sub30, i64* %.anon26, align 8
|
||||
%31 = load i64, i64* %.anon26, align 8
|
||||
%ztrunc = trunc i64 %31 to i8
|
||||
store i8 %ztrunc, i8* %i31, align 1
|
||||
%32 = load i64, i64* %.anon26, align 8
|
||||
%33 = getelementptr inbounds [3 x float], [3 x float]* %foo, i64 0, i64 %32
|
||||
%34 = load float, float* %33, align 4
|
||||
%fpfpext33 = fpext float %34 to double
|
||||
store double %fpfpext33, double* %a32, align 8
|
||||
%35 = load i8, i8* %i31, align 1
|
||||
%uisiext = zext i8 %35 to i32
|
||||
%36 = load double, double* %a32, align 8
|
||||
call void (i8*, ...) @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.4, i32 0, i32 0), i32 %uisiext, double %36)
|
||||
br label %loop.cond27
|
||||
|
||||
loop.exit34: ; preds = %loop.cond27
|
||||
store i64 3, i64* %.anon35, align 8
|
||||
br label %loop.cond36
|
||||
|
||||
loop.cond36: ; preds = %loop.body38, %loop.exit34
|
||||
%37 = load i64, i64* %.anon35, align 8
|
||||
%gt37 = icmp ugt i64 %37, 0
|
||||
br i1 %gt37, label %loop.body38, label %loop.exit42
|
||||
|
||||
loop.body38: ; preds = %loop.cond36
|
||||
%38 = load i64, i64* %.anon35, align 8
|
||||
%sub39 = sub i64 %38, 1
|
||||
store i64 %sub39, i64* %.anon35, align 8
|
||||
%39 = load i64, i64* %.anon35, align 8
|
||||
%40 = getelementptr inbounds [3 x float], [3 x float]* %foo, i64 0, i64 %39
|
||||
%41 = load float, float* %40, align 4
|
||||
%fpfpext41 = fpext float %41 to double
|
||||
store double %fpfpext41, double* %a40, align 8
|
||||
%42 = load double, double* %a40, align 8
|
||||
call void (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.5, i32 0, i32 0), double %42)
|
||||
br label %loop.cond36
|
||||
|
||||
loop.exit42: ; preds = %loop.cond36
|
||||
store i64 3, i64* %.anon43, align 8
|
||||
br label %loop.cond44
|
||||
|
||||
loop.cond44: ; preds = %loop.body46, %loop.exit42
|
||||
%43 = load i64, i64* %.anon43, align 8
|
||||
%gt45 = icmp ugt i64 %43, 0
|
||||
br i1 %gt45, label %loop.body46, label %loop.exit50
|
||||
|
||||
loop.body46: ; preds = %loop.cond44
|
||||
%44 = load i64, i64* %.anon43, align 8
|
||||
%sub47 = sub i64 %44, 1
|
||||
store i64 %sub47, i64* %.anon43, align 8
|
||||
%45 = load <3 x float>, <3 x float>* %foo2, align 16
|
||||
%46 = load i64, i64* %.anon43, align 8
|
||||
%47 = extractelement <3 x float> %45, i64 %46
|
||||
store float %47, float* %a48, align 4
|
||||
%48 = load float, float* %a48, align 4
|
||||
%fpfpext49 = fpext float %48 to double
|
||||
call void (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.6, i32 0, i32 0), double %fpfpext49)
|
||||
br label %loop.cond44
|
||||
|
||||
loop.exit50: ; preds = %loop.cond44
|
||||
store i64 3, i64* %.anon51, align 8
|
||||
br label %loop.cond52
|
||||
|
||||
loop.cond52: ; preds = %loop.body54, %loop.exit50
|
||||
%49 = load i64, i64* %.anon51, align 8
|
||||
%gt53 = icmp ugt i64 %49, 0
|
||||
br i1 %gt53, label %loop.body54, label %loop.exit59
|
||||
|
||||
loop.body54: ; preds = %loop.cond52
|
||||
%50 = load i64, i64* %.anon51, align 8
|
||||
%sub55 = sub i64 %50, 1
|
||||
store i64 %sub55, i64* %.anon51, align 8
|
||||
%51 = load i64, i64* %.anon51, align 8
|
||||
store i64 %51, i64* %i56, align 8
|
||||
%52 = load <3 x float>, <3 x float>* %foo2, align 16
|
||||
%53 = load i64, i64* %.anon51, align 8
|
||||
%54 = extractelement <3 x float> %52, i64 %53
|
||||
store float %54, float* %a57, align 4
|
||||
%55 = load i64, i64* %i56, align 8
|
||||
%56 = load float, float* %a57, align 4
|
||||
%fpfpext58 = fpext float %56 to double
|
||||
call void (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.7, i32 0, i32 0), i64 %55, double %fpfpext58)
|
||||
br label %loop.cond52
|
||||
|
||||
loop.exit59: ; preds = %loop.cond52
|
||||
store i64 3, i64* %.anon60, align 8
|
||||
br label %loop.cond61
|
||||
|
||||
loop.cond61: ; preds = %loop.body63, %loop.exit59
|
||||
%57 = load i64, i64* %.anon60, align 8
|
||||
%gt62 = icmp ugt i64 %57, 0
|
||||
br i1 %gt62, label %loop.body63, label %loop.exit70
|
||||
|
||||
loop.body63: ; preds = %loop.cond61
|
||||
%58 = load i64, i64* %.anon60, align 8
|
||||
%sub64 = sub i64 %58, 1
|
||||
store i64 %sub64, i64* %.anon60, align 8
|
||||
%59 = load i64, i64* %.anon60, align 8
|
||||
%ztrunc66 = trunc i64 %59 to i8
|
||||
store i8 %ztrunc66, i8* %i65, align 1
|
||||
%60 = load <3 x float>, <3 x float>* %foo2, align 16
|
||||
%61 = load i64, i64* %.anon60, align 8
|
||||
%62 = extractelement <3 x float> %60, i64 %61
|
||||
%fpfpext68 = fpext float %62 to double
|
||||
store double %fpfpext68, double* %a67, align 8
|
||||
%63 = load i8, i8* %i65, align 1
|
||||
%uisiext69 = zext i8 %63 to i32
|
||||
%64 = load double, double* %a67, align 8
|
||||
call void (i8*, ...) @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.8, i32 0, i32 0), i32 %uisiext69, double %64)
|
||||
br label %loop.cond61
|
||||
|
||||
loop.exit70: ; preds = %loop.cond61
|
||||
store i64 3, i64* %.anon71, align 8
|
||||
br label %loop.cond72
|
||||
|
||||
loop.cond72: ; preds = %loop.body74, %loop.exit70
|
||||
%65 = load i64, i64* %.anon71, align 8
|
||||
%gt73 = icmp ugt i64 %65, 0
|
||||
br i1 %gt73, label %loop.body74, label %loop.exit78
|
||||
|
||||
loop.body74: ; preds = %loop.cond72
|
||||
%66 = load i64, i64* %.anon71, align 8
|
||||
%sub75 = sub i64 %66, 1
|
||||
store i64 %sub75, i64* %.anon71, align 8
|
||||
%67 = load <3 x float>, <3 x float>* %foo2, align 16
|
||||
%68 = load i64, i64* %.anon71, align 8
|
||||
%69 = extractelement <3 x float> %67, i64 %68
|
||||
%fpfpext77 = fpext float %69 to double
|
||||
store double %fpfpext77, double* %a76, align 8
|
||||
%70 = load double, double* %a76, align 8
|
||||
call void (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.9, i32 0, i32 0), double %70)
|
||||
br label %loop.cond72
|
||||
|
||||
loop.exit78: ; preds = %loop.cond72
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i32 @main(i32 %0, i8** %1) #0 {
|
||||
entry:
|
||||
call void @test_main()
|
||||
ret i32 0
|
||||
}
|
||||
94
test/test_suite/statements/foreach_r_custom.c3t
Normal file
94
test/test_suite/statements/foreach_r_custom.c3t
Normal file
@@ -0,0 +1,94 @@
|
||||
// #target: macos-x64
|
||||
|
||||
module test;
|
||||
struct Foo
|
||||
{
|
||||
int[] x;
|
||||
}
|
||||
|
||||
macro int Foo.@operator_element_at(Foo &foo, usize index) @operator(elementat)
|
||||
{
|
||||
return foo.x[index];
|
||||
}
|
||||
|
||||
macro usize Foo.@operator_len(Foo &foo) @operator(len)
|
||||
{
|
||||
return foo.x.len;
|
||||
}
|
||||
|
||||
fn void main()
|
||||
{
|
||||
int[*] i = { 1, 3, 10 };
|
||||
Foo x = { &i };
|
||||
foreach_r FOO: (int f : x) {
|
||||
printf("%d\n", f);
|
||||
while (1)
|
||||
{
|
||||
break FOO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern fn int printf(char *fmt, ...);
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @test_main() #0 {
|
||||
entry:
|
||||
%i = alloca [3 x i32], align 4
|
||||
%x = alloca %Foo, align 8
|
||||
%.anon = alloca i64, align 8
|
||||
%f = alloca i32, align 4
|
||||
%index = alloca i64, align 8
|
||||
%0 = bitcast [3 x i32]* %i to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %0, i8* align 4 bitcast ([3 x i32]* @.__const to i8*), i32 12, i1 false)
|
||||
%1 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
|
||||
%2 = bitcast [3 x i32]* %i to i32*
|
||||
%3 = insertvalue %"int[]" undef, i32* %2, 0
|
||||
%4 = insertvalue %"int[]" %3, i64 3, 1
|
||||
store %"int[]" %4, %"int[]"* %1, align 8
|
||||
%5 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
|
||||
%6 = getelementptr inbounds %"int[]", %"int[]"* %5, i32 0, i32 1
|
||||
%7 = load i64, i64* %6, align 8
|
||||
store i64 %7, i64* %.anon, align 8
|
||||
br label %loop.cond
|
||||
|
||||
loop.cond: ; preds = %entry
|
||||
%8 = load i64, i64* %.anon, align 8
|
||||
%gt = icmp ugt i64 %8, 0
|
||||
br i1 %gt, label %loop.body, label %loop.exit
|
||||
|
||||
loop.body: ; preds = %loop.cond
|
||||
%9 = load i64, i64* %.anon, align 8
|
||||
%sub = sub i64 %9, 1
|
||||
store i64 %sub, i64* %.anon, align 8
|
||||
%10 = load i64, i64* %.anon, align 8
|
||||
store i64 %10, i64* %index, align 8
|
||||
%11 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
|
||||
%12 = getelementptr inbounds %"int[]", %"int[]"* %11, i32 0, i32 0
|
||||
%13 = load i32*, i32** %12, align 8
|
||||
%14 = load i64, i64* %index, align 8
|
||||
%ptroffset = getelementptr inbounds i32, i32* %13, i64 %14
|
||||
%15 = load i32, i32* %ptroffset, align 4
|
||||
store i32 %15, i32* %f, align 4
|
||||
%16 = load i32, i32* %f, align 4
|
||||
%17 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %16)
|
||||
br label %loop.body1
|
||||
|
||||
loop.body1: ; preds = %loop.body
|
||||
br label %loop.exit
|
||||
|
||||
loop.exit: ; preds = %loop.body1, %loop.cond
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i32 @printf(i8*, ...) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i32 @main(i32 %0, i8** %1) #0 {
|
||||
entry:
|
||||
call void @test_main()
|
||||
ret i32 0
|
||||
}
|
||||
15
test/test_suite/statements/foreach_r_custom_errors.c3
Normal file
15
test/test_suite/statements/foreach_r_custom_errors.c3
Normal file
@@ -0,0 +1,15 @@
|
||||
fn void test1()
|
||||
{
|
||||
int x;
|
||||
foreach_r (a : x) { }; // #error: It's not possible to enumerate an expression of type 'int'
|
||||
}
|
||||
|
||||
define Test1 = distinct int;
|
||||
|
||||
fn void test2()
|
||||
{
|
||||
Test1 x;
|
||||
foreach_r (a : x) { }; // #error: It's not possible to enumerate an expression of type 'Test1'
|
||||
}
|
||||
|
||||
|
||||
93
test/test_suite/statements/foreach_r_custom_macro.c3t
Normal file
93
test/test_suite/statements/foreach_r_custom_macro.c3t
Normal file
@@ -0,0 +1,93 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
struct Foo
|
||||
{
|
||||
int[] x;
|
||||
}
|
||||
|
||||
macro int Foo.@operator_element_at(Foo &foo, usize index) @operator(elementat)
|
||||
{
|
||||
return foo.x[index];
|
||||
}
|
||||
|
||||
macro usize Foo.@operator_len(Foo &foo) @operator(len)
|
||||
{
|
||||
return foo.x.len;
|
||||
}
|
||||
|
||||
fn void main()
|
||||
{
|
||||
int[*] i = { 1, 3, 10 };
|
||||
Foo x = { &i };
|
||||
foreach_r FOO: (int f : x) {
|
||||
printf("%d\n", f);
|
||||
while (1)
|
||||
{
|
||||
break FOO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern fn int printf(char *fmt, ...);
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @test_main() #0 {
|
||||
entry:
|
||||
%i = alloca [3 x i32], align 4
|
||||
%x = alloca %Foo, align 8
|
||||
%.anon = alloca i64, align 8
|
||||
%f = alloca i32, align 4
|
||||
%index = alloca i64, align 8
|
||||
%0 = bitcast [3 x i32]* %i to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %0, i8* align 4 bitcast ([3 x i32]* @.__const to i8*), i32 12, i1 false)
|
||||
%1 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
|
||||
%2 = bitcast [3 x i32]* %i to i32*
|
||||
%3 = insertvalue %"int[]" undef, i32* %2, 0
|
||||
%4 = insertvalue %"int[]" %3, i64 3, 1
|
||||
store %"int[]" %4, %"int[]"* %1, align 8
|
||||
%5 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
|
||||
%6 = getelementptr inbounds %"int[]", %"int[]"* %5, i32 0, i32 1
|
||||
%7 = load i64, i64* %6, align 8
|
||||
store i64 %7, i64* %.anon, align 8
|
||||
br label %loop.cond
|
||||
|
||||
loop.cond: ; preds = %entry
|
||||
%8 = load i64, i64* %.anon, align 8
|
||||
%gt = icmp ugt i64 %8, 0
|
||||
br i1 %gt, label %loop.body, label %loop.exit
|
||||
|
||||
loop.body: ; preds = %loop.cond
|
||||
%9 = load i64, i64* %.anon, align 8
|
||||
%sub = sub i64 %9, 1
|
||||
store i64 %sub, i64* %.anon, align 8
|
||||
%10 = load i64, i64* %.anon, align 8
|
||||
store i64 %10, i64* %index, align 8
|
||||
%11 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0
|
||||
%12 = getelementptr inbounds %"int[]", %"int[]"* %11, i32 0, i32 0
|
||||
%13 = load i32*, i32** %12, align 8
|
||||
%14 = load i64, i64* %index, align 8
|
||||
%ptroffset = getelementptr inbounds i32, i32* %13, i64 %14
|
||||
%15 = load i32, i32* %ptroffset, align 4
|
||||
store i32 %15, i32* %f, align 4
|
||||
%16 = load i32, i32* %f, align 4
|
||||
%17 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 %16)
|
||||
br label %loop.body1
|
||||
|
||||
loop.body1: ; preds = %loop.body
|
||||
br label %loop.exit
|
||||
|
||||
loop.exit: ; preds = %loop.body1, %loop.cond
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i32 @printf(i8*, ...) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i32 @main(i32 %0, i8** %1) #0 {
|
||||
entry:
|
||||
call void @test_main()
|
||||
ret i32 0
|
||||
}
|
||||
54
test/test_suite/statements/foreach_r_errors.c3
Normal file
54
test/test_suite/statements/foreach_r_errors.c3
Normal file
@@ -0,0 +1,54 @@
|
||||
module test;
|
||||
|
||||
extern fn void foo();
|
||||
int[3] z;
|
||||
|
||||
fn void test1()
|
||||
{
|
||||
int x;
|
||||
foreach_r (a : x) // #error: It's not possible to enumerate an expression of type 'int'.
|
||||
{
|
||||
foo();
|
||||
}
|
||||
}
|
||||
|
||||
fn void test2()
|
||||
{
|
||||
foreach_r (a : z) foo();
|
||||
foreach_r (i, a : z) foo();
|
||||
foreach_r (double i, a : z); // #error: Index must be an integer type, 'double' is not valid.
|
||||
}
|
||||
|
||||
fn void test3()
|
||||
{
|
||||
foreach_r (&a : z) foo();
|
||||
foreach_r (&i, &a : z) foo(); // #error: The index cannot be held by reference, did you accidentally add a '&'?
|
||||
}
|
||||
|
||||
fn void test4()
|
||||
{
|
||||
foreach_r (&a : z) foo();
|
||||
foreach_r (&i, a : z) foo(); // #error: The index cannot be held by reference, did you accidentally add a '&'?
|
||||
}
|
||||
|
||||
fn void test5()
|
||||
{
|
||||
foreach_r (int! y : z) foo(); // #error: The variable may not be a failable.
|
||||
}
|
||||
|
||||
fn void test6()
|
||||
{
|
||||
foreach_r (int! i, y : z) foo(); // #error: The index may not be a failable.
|
||||
}
|
||||
|
||||
fn void test7()
|
||||
{
|
||||
foreach_r (int a : { 1, 2, 3 }) foo();
|
||||
foreach_r (a : { 1, 2, 3 }) foo(); // #error: Add the type of your variable here if you want to iterate over
|
||||
}
|
||||
|
||||
fn void test8()
|
||||
{
|
||||
foreach_r (int a : { z }) foo(); // #error: 'int[3]' into 'int'
|
||||
}
|
||||
|
||||
5
test/test_suite/statements/foreach_r_parse_error.c3
Normal file
5
test/test_suite/statements/foreach_r_parse_error.c3
Normal file
@@ -0,0 +1,5 @@
|
||||
fn void test9()
|
||||
{
|
||||
foreach_r (int a : { [2] = 1 }) foo();
|
||||
foreach_r (int a : { [2] = 2, 1 }) foo(); // #error: Normal initialization cannot be mixed with designated initialization.
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
import std::io;
|
||||
|
||||
fn void main()
|
||||
{
|
||||
int[*] x = { 1, 5, 10 };
|
||||
int[] y = &x;
|
||||
foreach_r (int i, val : y)
|
||||
{
|
||||
io::printfln("%d: %d", i, val);
|
||||
}
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
entry:
|
||||
%x = alloca [3 x i32], align 4
|
||||
%y = alloca %"int[]", align 8
|
||||
%.anon = alloca i64, align 8
|
||||
%i = alloca i32, align 4
|
||||
%val = alloca i32, align 4
|
||||
%retparam = alloca i64, align 8
|
||||
%taddr = alloca %"char[]", align 8
|
||||
%vararg = alloca %"variant[]", align 8
|
||||
%varargslots = alloca [2 x %variant], align 16
|
||||
%0 = bitcast [3 x i32]* %x to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %0, i8* align 4 bitcast ([3 x i32]* @.__const to i8*), i32 12, i1 false)
|
||||
%1 = bitcast [3 x i32]* %x to i32*
|
||||
%2 = insertvalue %"int[]" undef, i32* %1, 0
|
||||
%3 = insertvalue %"int[]" %2, i64 3, 1
|
||||
store %"int[]" %3, %"int[]"* %y, align 8
|
||||
%4 = getelementptr inbounds %"int[]", %"int[]"* %y, i32 0, i32 1
|
||||
%5 = load i64, i64* %4, align 8
|
||||
store i64 %5, i64* %.anon, align 8
|
||||
br label %loop.cond
|
||||
|
||||
loop.cond: ; preds = %voiderr, %entry
|
||||
%6 = load i64, i64* %.anon, align 8
|
||||
%gt = icmp ugt i64 %6, 0
|
||||
br i1 %gt, label %loop.body, label %loop.exit
|
||||
|
||||
loop.body: ; preds = %loop.cond
|
||||
%7 = load i64, i64* %.anon, align 8
|
||||
%sub = sub i64 %7, 1
|
||||
store i64 %sub, i64* %.anon, align 8
|
||||
%8 = load i64, i64* %.anon, align 8
|
||||
%uisitrunc = trunc i64 %8 to i32
|
||||
store i32 %uisitrunc, i32* %i, align 4
|
||||
%9 = getelementptr inbounds %"int[]", %"int[]"* %y, i32 0, i32 0
|
||||
%10 = load i32*, i32** %9, align 8
|
||||
%11 = load i64, i64* %.anon, align 8
|
||||
%ptroffset = getelementptr inbounds i32, i32* %10, i64 %11
|
||||
%12 = load i32, i32* %ptroffset, align 4
|
||||
store i32 %12, i32* %val, align 4
|
||||
store %"char[]" { i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i32 0, i32 0), i64 6 }, %"char[]"* %taddr, align 8
|
||||
%13 = bitcast %"char[]"* %taddr to { i8*, i64 }*
|
||||
%14 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %13, i32 0, i32 0
|
||||
%lo = load i8*, i8** %14, align 8
|
||||
%15 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %13, i32 0, i32 1
|
||||
%hi = load i64, i64* %15, align 8
|
||||
%16 = bitcast i32* %i to i8*
|
||||
%17 = insertvalue %variant undef, i8* %16, 0
|
||||
%18 = insertvalue %variant %17, i64 ptrtoint (%.introspect* @"ct$int" to i64), 1
|
||||
%19 = getelementptr inbounds [2 x %variant], [2 x %variant]* %varargslots, i64 0, i64 0
|
||||
store %variant %18, %variant* %19, align 16
|
||||
%20 = bitcast i32* %val to i8*
|
||||
%21 = insertvalue %variant undef, i8* %20, 0
|
||||
%22 = insertvalue %variant %21, i64 ptrtoint (%.introspect* @"ct$int" to i64), 1
|
||||
%23 = getelementptr inbounds [2 x %variant], [2 x %variant]* %varargslots, i64 0, i64 1
|
||||
store %variant %22, %variant* %23, align 16
|
||||
%24 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg, i32 0, i32 1
|
||||
store i64 2, i64* %24, align 8
|
||||
%25 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg, i32 0, i32 0
|
||||
%26 = bitcast [2 x %variant]* %varargslots to %variant*
|
||||
store %variant* %26, %variant** %25, align 8
|
||||
%27 = bitcast %"variant[]"* %vararg to { i8*, i64 }*
|
||||
%28 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %27, i32 0, i32 0
|
||||
%lo1 = load i8*, i8** %28, align 8
|
||||
%29 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %27, i32 0, i32 1
|
||||
%hi2 = load i64, i64* %29, align 8
|
||||
%30 = call i64 @std_io_printfln(i64* %retparam, i8* %lo, i64 %hi, i8* %lo1, i64 %hi2)
|
||||
%not_err = icmp eq i64 %30, 0
|
||||
br i1 %not_err, label %after_check, label %voiderr
|
||||
|
||||
after_check: ; preds = %loop.body
|
||||
br label %voiderr
|
||||
|
||||
voiderr: ; preds = %after_check, %loop.body
|
||||
br label %loop.cond
|
||||
|
||||
loop.exit: ; preds = %loop.cond
|
||||
ret void
|
||||
}
|
||||
12
test/test_suite/statements/foreach_r_with_error.c3
Normal file
12
test/test_suite/statements/foreach_r_with_error.c3
Normal file
@@ -0,0 +1,12 @@
|
||||
module test;
|
||||
|
||||
fn void test()
|
||||
{
|
||||
int[3]! x;
|
||||
int g;
|
||||
foreach_r (z : x) // #error: The expression may not be failable.
|
||||
{
|
||||
g += z;
|
||||
x[0] = 1;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// #target: macos-x64
|
||||
|
||||
module foo;
|
||||
module test;
|
||||
struct Foo
|
||||
{
|
||||
int[] x;
|
||||
@@ -31,10 +31,10 @@ fn void main()
|
||||
|
||||
extern fn int printf(char *fmt, ...);
|
||||
|
||||
/* #expect: foo.ll
|
||||
/* #expect: test.ll
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @foo_main() #0 {
|
||||
define void @test_main() #0 {
|
||||
entry:
|
||||
%i = alloca [3 x i32], align 4
|
||||
%x = alloca %Foo, align 8
|
||||
@@ -79,4 +79,14 @@ loop.body2: ; preds = %loop.body
|
||||
|
||||
loop.exit: ; preds = %loop.body2, %loop.cond
|
||||
ret void
|
||||
}
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i32 @printf(ptr, ...) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i32 @main(i32 %0, ptr %1) #0 {
|
||||
entry:
|
||||
call void @test_main()
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
72
test/test_suite2/statements/foreach_r_break.c3t
Normal file
72
test/test_suite2/statements/foreach_r_break.c3t
Normal file
@@ -0,0 +1,72 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
|
||||
fn void test()
|
||||
{
|
||||
int[3] x;
|
||||
int g = 0;
|
||||
foreach_r (z : x)
|
||||
{
|
||||
if (z > 0) break;
|
||||
if (z == 1) continue;
|
||||
g += z;
|
||||
}
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @test_test() #0 {
|
||||
entry:
|
||||
%x = alloca [3 x i32], align 4
|
||||
%g = alloca i32, align 4
|
||||
%.anon = alloca i64, align 8
|
||||
%z = alloca i32, align 4
|
||||
%0 = getelementptr inbounds [3 x i32], ptr %x, i64 0, i64 0
|
||||
store i32 0, ptr %0, align 4
|
||||
%1 = getelementptr inbounds [3 x i32], ptr %x, i64 0, i64 1
|
||||
store i32 0, ptr %1, align 4
|
||||
%2 = getelementptr inbounds [3 x i32], ptr %x, i64 0, i64 2
|
||||
store i32 0, ptr %2, align 4
|
||||
store i32 0, ptr %g, align 4
|
||||
store i64 3, ptr %.anon, align 8
|
||||
br label %loop.cond
|
||||
|
||||
loop.cond: ; preds = %if.exit3, %if.then2, %entry
|
||||
%3 = load i64, ptr %.anon, align 8
|
||||
%gt = icmp ugt i64 %3, 0
|
||||
br i1 %gt, label %loop.body, label %loop.exit
|
||||
|
||||
loop.body: ; preds = %loop.cond
|
||||
%4 = load i64, ptr %.anon, align 8
|
||||
%sub = sub i64 %4, 1
|
||||
store i64 %sub, ptr %.anon, align 8
|
||||
%5 = load i64, ptr %.anon, align 8
|
||||
%6 = getelementptr inbounds [3 x i32], ptr %x, i64 0, i64 %5
|
||||
%7 = load i32, ptr %6, align 4
|
||||
store i32 %7, ptr %z, align 4
|
||||
%8 = load i32, ptr %z, align 4
|
||||
%gt1 = icmp sgt i32 %8, 0
|
||||
br i1 %gt1, label %if.then, label %if.exit
|
||||
|
||||
if.then: ; preds = %loop.body
|
||||
br label %loop.exit
|
||||
|
||||
if.exit: ; preds = %loop.body
|
||||
%9 = load i32, ptr %z, align 4
|
||||
%eq = icmp eq i32 %9, 1
|
||||
br i1 %eq, label %if.then2, label %if.exit3
|
||||
|
||||
if.then2: ; preds = %if.exit
|
||||
br label %loop.cond
|
||||
|
||||
if.exit3: ; preds = %if.exit
|
||||
%10 = load i32, ptr %g, align 4
|
||||
%11 = load i32, ptr %z, align 4
|
||||
%add = add i32 %10, %11
|
||||
store i32 %add, ptr %g, align 4
|
||||
br label %loop.cond
|
||||
|
||||
loop.exit: ; preds = %if.then, %loop.cond
|
||||
ret void
|
||||
}
|
||||
350
test/test_suite2/statements/foreach_r_common.c3t
Normal file
350
test/test_suite2/statements/foreach_r_common.c3t
Normal file
@@ -0,0 +1,350 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
|
||||
extern fn void printf(char*, ...);
|
||||
|
||||
fn void main()
|
||||
{
|
||||
float[3] foo = { 2, 4.5, 8 };
|
||||
float[<3>] foo2 = { 2, 4.5, 8 };
|
||||
foreach_r (a : foo)
|
||||
{
|
||||
printf("Value: %f\n", a);
|
||||
}
|
||||
foreach_r (float* &a : foo)
|
||||
{
|
||||
*a *= 2;
|
||||
printf("Value: %f\n", *a);
|
||||
}
|
||||
foreach_r (void* &a : foo)
|
||||
{
|
||||
printf("Value: %f\n", *((float*)(a)));
|
||||
}
|
||||
foreach_r (i, a : foo)
|
||||
{
|
||||
printf("Value[%d]: %f\n", i, a);
|
||||
}
|
||||
foreach_r (char i, double a : foo)
|
||||
{
|
||||
printf("Value2[%d]: %f\n", i, a);
|
||||
}
|
||||
foreach_r (double a : foo)
|
||||
{
|
||||
printf("Value3: %f\n", a);
|
||||
}
|
||||
|
||||
foreach_r (a : foo2)
|
||||
{
|
||||
printf("Value: %f\n", a);
|
||||
}
|
||||
foreach_r (i, a : foo2)
|
||||
{
|
||||
printf("Value[%d]: %f\n", i, a);
|
||||
}
|
||||
foreach_r (char i, double a : foo2)
|
||||
{
|
||||
printf("Value2[%d]: %f\n", i, a);
|
||||
}
|
||||
foreach_r (double a : foo2)
|
||||
{
|
||||
printf("Value3: %f\n", a);
|
||||
}
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
@.__const = private unnamed_addr constant [3 x float] [float 2.000000e+00, float 4.500000e+00, float 8.000000e+00], align 4
|
||||
@.str = private unnamed_addr constant [11 x i8] c"Value: %f\0A\00", align 1
|
||||
@.str.1 = private unnamed_addr constant [11 x i8] c"Value: %f\0A\00", align 1
|
||||
@.str.2 = private unnamed_addr constant [11 x i8] c"Value: %f\0A\00", align 1
|
||||
@.str.3 = private unnamed_addr constant [15 x i8] c"Value[%d]: %f\0A\00", align 1
|
||||
@.str.4 = private unnamed_addr constant [16 x i8] c"Value2[%d]: %f\0A\00", align 1
|
||||
@.str.5 = private unnamed_addr constant [12 x i8] c"Value3: %f\0A\00", align 1
|
||||
@.str.6 = private unnamed_addr constant [11 x i8] c"Value: %f\0A\00", align 1
|
||||
@.str.7 = private unnamed_addr constant [15 x i8] c"Value[%d]: %f\0A\00", align 1
|
||||
@.str.8 = private unnamed_addr constant [16 x i8] c"Value2[%d]: %f\0A\00", align 1
|
||||
@.str.9 = private unnamed_addr constant [12 x i8] c"Value3: %f\0A\00", align 1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @printf(ptr, ...) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @test_main() #0 {
|
||||
entry:
|
||||
%foo = alloca [3 x float], align 4
|
||||
%foo2 = alloca <3 x float>, align 16
|
||||
%.anon = alloca i64, align 8
|
||||
%a = alloca float, align 4
|
||||
%.anon1 = alloca i64, align 8
|
||||
%a6 = alloca ptr, align 8
|
||||
%.anon9 = alloca i64, align 8
|
||||
%a14 = alloca ptr, align 8
|
||||
%.anon17 = alloca i64, align 8
|
||||
%i = alloca i64, align 8
|
||||
%a22 = alloca float, align 4
|
||||
%.anon25 = alloca i64, align 8
|
||||
%i30 = alloca i8, align 1
|
||||
%a31 = alloca double, align 8
|
||||
%.anon34 = alloca i64, align 8
|
||||
%a39 = alloca double, align 8
|
||||
%.anon42 = alloca i64, align 8
|
||||
%a47 = alloca float, align 4
|
||||
%.anon50 = alloca i64, align 8
|
||||
%i55 = alloca i64, align 8
|
||||
%a56 = alloca float, align 4
|
||||
%.anon59 = alloca i64, align 8
|
||||
%i64 = alloca i8, align 1
|
||||
%a66 = alloca double, align 8
|
||||
%.anon70 = alloca i64, align 8
|
||||
%a75 = alloca double, align 8
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %foo, ptr align 4 @.__const, i32 12, i1 false)
|
||||
store <3 x float> <float 2.000000e+00, float 4.500000e+00, float 8.000000e+00>, ptr %foo2, align 16
|
||||
store i64 3, ptr %.anon, align 8
|
||||
br label %loop.cond
|
||||
|
||||
loop.cond: ; preds = %loop.body, %entry
|
||||
%0 = load i64, ptr %.anon, align 8
|
||||
%gt = icmp ugt i64 %0, 0
|
||||
br i1 %gt, label %loop.body, label %loop.exit
|
||||
|
||||
loop.body: ; preds = %loop.cond
|
||||
%1 = load i64, ptr %.anon, align 8
|
||||
%sub = sub i64 %1, 1
|
||||
store i64 %sub, ptr %.anon, align 8
|
||||
%2 = load i64, ptr %.anon, align 8
|
||||
%3 = getelementptr inbounds [3 x float], ptr %foo, i64 0, i64 %2
|
||||
%4 = load float, ptr %3, align 4
|
||||
store float %4, ptr %a, align 4
|
||||
%5 = load float, ptr %a, align 4
|
||||
%fpfpext = fpext float %5 to double
|
||||
call void (ptr, ...) @printf(ptr @.str, double %fpfpext)
|
||||
br label %loop.cond
|
||||
|
||||
loop.exit: ; preds = %loop.cond
|
||||
store i64 3, ptr %.anon1, align 8
|
||||
br label %loop.cond2
|
||||
|
||||
loop.cond2: ; preds = %loop.body4, %loop.exit
|
||||
%6 = load i64, ptr %.anon1, align 8
|
||||
%gt3 = icmp ugt i64 %6, 0
|
||||
br i1 %gt3, label %loop.body4, label %loop.exit8
|
||||
|
||||
loop.body4: ; preds = %loop.cond2
|
||||
%7 = load i64, ptr %.anon1, align 8
|
||||
%sub5 = sub i64 %7, 1
|
||||
store i64 %sub5, ptr %.anon1, align 8
|
||||
%8 = load i64, ptr %.anon1, align 8
|
||||
%9 = getelementptr inbounds [3 x float], ptr %foo, i64 0, i64 %8
|
||||
store ptr %9, ptr %a6, align 8
|
||||
%10 = load ptr, ptr %a6, align 8
|
||||
%11 = load float, ptr %10, align 8
|
||||
%fmul = fmul float %11, 2.000000e+00
|
||||
store float %fmul, ptr %10, align 8
|
||||
%12 = load ptr, ptr %a6, align 8
|
||||
%13 = load float, ptr %12, align 8
|
||||
%fpfpext7 = fpext float %13 to double
|
||||
call void (ptr, ...) @printf(ptr @.str.1, double %fpfpext7)
|
||||
br label %loop.cond2
|
||||
|
||||
loop.exit8: ; preds = %loop.cond2
|
||||
store i64 3, ptr %.anon9, align 8
|
||||
br label %loop.cond10
|
||||
|
||||
loop.cond10: ; preds = %loop.body12, %loop.exit8
|
||||
%14 = load i64, ptr %.anon9, align 8
|
||||
%gt11 = icmp ugt i64 %14, 0
|
||||
br i1 %gt11, label %loop.body12, label %loop.exit16
|
||||
|
||||
loop.body12: ; preds = %loop.cond10
|
||||
%15 = load i64, ptr %.anon9, align 8
|
||||
%sub13 = sub i64 %15, 1
|
||||
store i64 %sub13, ptr %.anon9, align 8
|
||||
%16 = load i64, ptr %.anon9, align 8
|
||||
%17 = getelementptr inbounds [3 x float], ptr %foo, i64 0, i64 %16
|
||||
store ptr %17, ptr %a14, align 8
|
||||
%18 = load ptr, ptr %a14, align 8
|
||||
%19 = load float, ptr %18, align 8
|
||||
%fpfpext15 = fpext float %19 to double
|
||||
call void (ptr, ...) @printf(ptr @.str.2, double %fpfpext15)
|
||||
br label %loop.cond10
|
||||
|
||||
loop.exit16: ; preds = %loop.cond10
|
||||
store i64 3, ptr %.anon17, align 8
|
||||
br label %loop.cond18
|
||||
|
||||
loop.cond18: ; preds = %loop.body20, %loop.exit16
|
||||
%20 = load i64, ptr %.anon17, align 8
|
||||
%gt19 = icmp ugt i64 %20, 0
|
||||
br i1 %gt19, label %loop.body20, label %loop.exit24
|
||||
|
||||
loop.body20: ; preds = %loop.cond18
|
||||
%21 = load i64, ptr %.anon17, align 8
|
||||
%sub21 = sub i64 %21, 1
|
||||
store i64 %sub21, ptr %.anon17, align 8
|
||||
%22 = load i64, ptr %.anon17, align 8
|
||||
store i64 %22, ptr %i, align 8
|
||||
%23 = load i64, ptr %.anon17, align 8
|
||||
%24 = getelementptr inbounds [3 x float], ptr %foo, i64 0, i64 %23
|
||||
%25 = load float, ptr %24, align 4
|
||||
store float %25, ptr %a22, align 4
|
||||
%26 = load i64, ptr %i, align 8
|
||||
%27 = load float, ptr %a22, align 4
|
||||
%fpfpext23 = fpext float %27 to double
|
||||
call void (ptr, ...) @printf(ptr @.str.3, i64 %26, double %fpfpext23)
|
||||
br label %loop.cond18
|
||||
|
||||
loop.exit24: ; preds = %loop.cond18
|
||||
store i64 3, ptr %.anon25, align 8
|
||||
br label %loop.cond26
|
||||
|
||||
loop.cond26: ; preds = %loop.body28, %loop.exit24
|
||||
%28 = load i64, ptr %.anon25, align 8
|
||||
%gt27 = icmp ugt i64 %28, 0
|
||||
br i1 %gt27, label %loop.body28, label %loop.exit33
|
||||
|
||||
loop.body28: ; preds = %loop.cond26
|
||||
%29 = load i64, ptr %.anon25, align 8
|
||||
%sub29 = sub i64 %29, 1
|
||||
store i64 %sub29, ptr %.anon25, align 8
|
||||
%30 = load i64, ptr %.anon25, align 8
|
||||
%ztrunc = trunc i64 %30 to i8
|
||||
store i8 %ztrunc, ptr %i30, align 1
|
||||
%31 = load i64, ptr %.anon25, align 8
|
||||
%32 = getelementptr inbounds [3 x float], ptr %foo, i64 0, i64 %31
|
||||
%33 = load float, ptr %32, align 4
|
||||
%fpfpext32 = fpext float %33 to double
|
||||
store double %fpfpext32, ptr %a31, align 8
|
||||
%34 = load i8, ptr %i30, align 1
|
||||
%uisiext = zext i8 %34 to i32
|
||||
%35 = load double, ptr %a31, align 8
|
||||
call void (ptr, ...) @printf(ptr @.str.4, i32 %uisiext, double %35)
|
||||
br label %loop.cond26
|
||||
|
||||
loop.exit33: ; preds = %loop.cond26
|
||||
store i64 3, ptr %.anon34, align 8
|
||||
br label %loop.cond35
|
||||
|
||||
loop.cond35: ; preds = %loop.body37, %loop.exit33
|
||||
%36 = load i64, ptr %.anon34, align 8
|
||||
%gt36 = icmp ugt i64 %36, 0
|
||||
br i1 %gt36, label %loop.body37, label %loop.exit41
|
||||
|
||||
loop.body37: ; preds = %loop.cond35
|
||||
%37 = load i64, ptr %.anon34, align 8
|
||||
%sub38 = sub i64 %37, 1
|
||||
store i64 %sub38, ptr %.anon34, align 8
|
||||
%38 = load i64, ptr %.anon34, align 8
|
||||
%39 = getelementptr inbounds [3 x float], ptr %foo, i64 0, i64 %38
|
||||
%40 = load float, ptr %39, align 4
|
||||
%fpfpext40 = fpext float %40 to double
|
||||
store double %fpfpext40, ptr %a39, align 8
|
||||
%41 = load double, ptr %a39, align 8
|
||||
call void (ptr, ...) @printf(ptr @.str.5, double %41)
|
||||
br label %loop.cond35
|
||||
|
||||
loop.exit41: ; preds = %loop.cond35
|
||||
store i64 3, ptr %.anon42, align 8
|
||||
br label %loop.cond43
|
||||
|
||||
loop.cond43: ; preds = %loop.body45, %loop.exit41
|
||||
%42 = load i64, ptr %.anon42, align 8
|
||||
%gt44 = icmp ugt i64 %42, 0
|
||||
br i1 %gt44, label %loop.body45, label %loop.exit49
|
||||
|
||||
loop.body45: ; preds = %loop.cond43
|
||||
%43 = load i64, ptr %.anon42, align 8
|
||||
%sub46 = sub i64 %43, 1
|
||||
store i64 %sub46, ptr %.anon42, align 8
|
||||
%44 = load <3 x float>, ptr %foo2, align 16
|
||||
%45 = load i64, ptr %.anon42, align 8
|
||||
%46 = extractelement <3 x float> %44, i64 %45
|
||||
store float %46, ptr %a47, align 4
|
||||
%47 = load float, ptr %a47, align 4
|
||||
%fpfpext48 = fpext float %47 to double
|
||||
call void (ptr, ...) @printf(ptr @.str.6, double %fpfpext48)
|
||||
br label %loop.cond43
|
||||
|
||||
loop.exit49: ; preds = %loop.cond43
|
||||
store i64 3, ptr %.anon50, align 8
|
||||
br label %loop.cond51
|
||||
|
||||
loop.cond51: ; preds = %loop.body53, %loop.exit49
|
||||
%48 = load i64, ptr %.anon50, align 8
|
||||
%gt52 = icmp ugt i64 %48, 0
|
||||
br i1 %gt52, label %loop.body53, label %loop.exit58
|
||||
|
||||
loop.body53: ; preds = %loop.cond51
|
||||
%49 = load i64, ptr %.anon50, align 8
|
||||
%sub54 = sub i64 %49, 1
|
||||
store i64 %sub54, ptr %.anon50, align 8
|
||||
%50 = load i64, ptr %.anon50, align 8
|
||||
store i64 %50, ptr %i55, align 8
|
||||
%51 = load <3 x float>, ptr %foo2, align 16
|
||||
%52 = load i64, ptr %.anon50, align 8
|
||||
%53 = extractelement <3 x float> %51, i64 %52
|
||||
store float %53, ptr %a56, align 4
|
||||
%54 = load i64, ptr %i55, align 8
|
||||
%55 = load float, ptr %a56, align 4
|
||||
%fpfpext57 = fpext float %55 to double
|
||||
call void (ptr, ...) @printf(ptr @.str.7, i64 %54, double %fpfpext57)
|
||||
br label %loop.cond51
|
||||
|
||||
loop.exit58: ; preds = %loop.cond51
|
||||
store i64 3, ptr %.anon59, align 8
|
||||
br label %loop.cond60
|
||||
|
||||
loop.cond60: ; preds = %loop.body62, %loop.exit58
|
||||
%56 = load i64, ptr %.anon59, align 8
|
||||
%gt61 = icmp ugt i64 %56, 0
|
||||
br i1 %gt61, label %loop.body62, label %loop.exit69
|
||||
|
||||
loop.body62: ; preds = %loop.cond60
|
||||
%57 = load i64, ptr %.anon59, align 8
|
||||
%sub63 = sub i64 %57, 1
|
||||
store i64 %sub63, ptr %.anon59, align 8
|
||||
%58 = load i64, ptr %.anon59, align 8
|
||||
%ztrunc65 = trunc i64 %58 to i8
|
||||
store i8 %ztrunc65, ptr %i64, align 1
|
||||
%59 = load <3 x float>, ptr %foo2, align 16
|
||||
%60 = load i64, ptr %.anon59, align 8
|
||||
%61 = extractelement <3 x float> %59, i64 %60
|
||||
%fpfpext67 = fpext float %61 to double
|
||||
store double %fpfpext67, ptr %a66, align 8
|
||||
%62 = load i8, ptr %i64, align 1
|
||||
%uisiext68 = zext i8 %62 to i32
|
||||
%63 = load double, ptr %a66, align 8
|
||||
call void (ptr, ...) @printf(ptr @.str.8, i32 %uisiext68, double %63)
|
||||
br label %loop.cond60
|
||||
|
||||
loop.exit69: ; preds = %loop.cond60
|
||||
store i64 3, ptr %.anon70, align 8
|
||||
br label %loop.cond71
|
||||
|
||||
loop.cond71: ; preds = %loop.body73, %loop.exit69
|
||||
%64 = load i64, ptr %.anon70, align 8
|
||||
%gt72 = icmp ugt i64 %64, 0
|
||||
br i1 %gt72, label %loop.body73, label %loop.exit77
|
||||
|
||||
loop.body73: ; preds = %loop.cond71
|
||||
%65 = load i64, ptr %.anon70, align 8
|
||||
%sub74 = sub i64 %65, 1
|
||||
store i64 %sub74, ptr %.anon70, align 8
|
||||
%66 = load <3 x float>, ptr %foo2, align 16
|
||||
%67 = load i64, ptr %.anon70, align 8
|
||||
%68 = extractelement <3 x float> %66, i64 %67
|
||||
%fpfpext76 = fpext float %68 to double
|
||||
store double %fpfpext76, ptr %a75, align 8
|
||||
%69 = load double, ptr %a75, align 8
|
||||
call void (ptr, ...) @printf(ptr @.str.9, double %69)
|
||||
br label %loop.cond71
|
||||
|
||||
loop.exit77: ; preds = %loop.cond71
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i32 @main(i32 %0, ptr %1) #0 {
|
||||
entry:
|
||||
call void @test_main()
|
||||
ret i32 0
|
||||
}
|
||||
92
test/test_suite2/statements/foreach_r_custom.c3t
Normal file
92
test/test_suite2/statements/foreach_r_custom.c3t
Normal file
@@ -0,0 +1,92 @@
|
||||
// #target: macos-x64
|
||||
|
||||
module test;
|
||||
struct Foo
|
||||
{
|
||||
int[] x;
|
||||
}
|
||||
|
||||
macro int Foo.@operator_element_at(Foo &foo, usize index) @operator(elementat)
|
||||
{
|
||||
return foo.x[index];
|
||||
}
|
||||
|
||||
macro usize Foo.@operator_len(Foo &foo) @operator(len)
|
||||
{
|
||||
return foo.x.len;
|
||||
}
|
||||
|
||||
fn void main()
|
||||
{
|
||||
int[*] i = { 1, 3, 10 };
|
||||
Foo x = { &i };
|
||||
foreach_r FOO: (int f : x) {
|
||||
printf("%d\n", f);
|
||||
while (1)
|
||||
{
|
||||
break FOO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern fn int printf(char *fmt, ...);
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @test_main() #0 {
|
||||
entry:
|
||||
%i = alloca [3 x i32], align 4
|
||||
%x = alloca %Foo, align 8
|
||||
%.anon = alloca i64, align 8
|
||||
%f = alloca i32, align 4
|
||||
%index = alloca i64, align 8
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %i, ptr align 4 @.__const, i32 12, i1 false)
|
||||
%0 = getelementptr inbounds %Foo, ptr %x, i32 0, i32 0
|
||||
%1 = insertvalue %"int[]" undef, ptr %i, 0
|
||||
%2 = insertvalue %"int[]" %1, i64 3, 1
|
||||
store %"int[]" %2, ptr %0, align 8
|
||||
%3 = getelementptr inbounds %Foo, ptr %x, i32 0, i32 0
|
||||
%4 = getelementptr inbounds %"int[]", ptr %3, i32 0, i32 1
|
||||
%5 = load i64, ptr %4, align 8
|
||||
store i64 %5, ptr %.anon, align 8
|
||||
br label %loop.cond
|
||||
|
||||
loop.cond: ; preds = %entry
|
||||
%6 = load i64, ptr %.anon, align 8
|
||||
%gt = icmp ugt i64 %6, 0
|
||||
br i1 %gt, label %loop.body, label %loop.exit
|
||||
|
||||
loop.body: ; preds = %loop.cond
|
||||
%7 = load i64, ptr %.anon, align 8
|
||||
%sub = sub i64 %7, 1
|
||||
store i64 %sub, ptr %.anon, align 8
|
||||
%8 = load i64, ptr %.anon, align 8
|
||||
store i64 %8, ptr %index, align 8
|
||||
%9 = getelementptr inbounds %Foo, ptr %x, i32 0, i32 0
|
||||
%10 = getelementptr inbounds %"int[]", ptr %9, i32 0, i32 0
|
||||
%11 = load ptr, ptr %10, align 8
|
||||
%12 = load i64, ptr %index, align 8
|
||||
%ptroffset = getelementptr inbounds i32, ptr %11, i64 %12
|
||||
%13 = load i32, ptr %ptroffset, align 4
|
||||
store i32 %13, ptr %f, align 4
|
||||
%14 = load i32, ptr %f, align 4
|
||||
%15 = call i32 (ptr, ...) @printf(ptr @.str, i32 %14)
|
||||
br label %loop.body1
|
||||
|
||||
loop.body1: ; preds = %loop.body
|
||||
br label %loop.exit
|
||||
|
||||
loop.exit: ; preds = %loop.body1, %loop.cond
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i32 @printf(ptr, ...) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i32 @main(i32 %0, ptr %1) #0 {
|
||||
entry:
|
||||
call void @test_main()
|
||||
ret i32 0
|
||||
}
|
||||
15
test/test_suite2/statements/foreach_r_custom_errors.c3
Normal file
15
test/test_suite2/statements/foreach_r_custom_errors.c3
Normal file
@@ -0,0 +1,15 @@
|
||||
fn void test1()
|
||||
{
|
||||
int x;
|
||||
foreach_r (a : x) { }; // #error: It's not possible to enumerate an expression of type 'int'
|
||||
}
|
||||
|
||||
define Test1 = distinct int;
|
||||
|
||||
fn void test2()
|
||||
{
|
||||
Test1 x;
|
||||
foreach_r (a : x) { }; // #error: It's not possible to enumerate an expression of type 'Test1'
|
||||
}
|
||||
|
||||
|
||||
91
test/test_suite2/statements/foreach_r_custom_macro.c3t
Normal file
91
test/test_suite2/statements/foreach_r_custom_macro.c3t
Normal file
@@ -0,0 +1,91 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
struct Foo
|
||||
{
|
||||
int[] x;
|
||||
}
|
||||
|
||||
macro int Foo.@operator_element_at(Foo &foo, usize index) @operator(elementat)
|
||||
{
|
||||
return foo.x[index];
|
||||
}
|
||||
|
||||
macro usize Foo.@operator_len(Foo &foo) @operator(len)
|
||||
{
|
||||
return foo.x.len;
|
||||
}
|
||||
|
||||
fn void main()
|
||||
{
|
||||
int[*] i = { 1, 3, 10 };
|
||||
Foo x = { &i };
|
||||
foreach_r FOO: (int f : x) {
|
||||
printf("%d\n", f);
|
||||
while (1)
|
||||
{
|
||||
break FOO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern fn int printf(char *fmt, ...);
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @test_main() #0 {
|
||||
entry:
|
||||
%i = alloca [3 x i32], align 4
|
||||
%x = alloca %Foo, align 8
|
||||
%.anon = alloca i64, align 8
|
||||
%f = alloca i32, align 4
|
||||
%index = alloca i64, align 8
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %i, ptr align 4 @.__const, i32 12, i1 false)
|
||||
%0 = getelementptr inbounds %Foo, ptr %x, i32 0, i32 0
|
||||
%1 = insertvalue %"int[]" undef, ptr %i, 0
|
||||
%2 = insertvalue %"int[]" %1, i64 3, 1
|
||||
store %"int[]" %2, ptr %0, align 8
|
||||
%3 = getelementptr inbounds %Foo, ptr %x, i32 0, i32 0
|
||||
%4 = getelementptr inbounds %"int[]", ptr %3, i32 0, i32 1
|
||||
%5 = load i64, ptr %4, align 8
|
||||
store i64 %5, ptr %.anon, align 8
|
||||
br label %loop.cond
|
||||
|
||||
loop.cond: ; preds = %entry
|
||||
%6 = load i64, ptr %.anon, align 8
|
||||
%gt = icmp ugt i64 %6, 0
|
||||
br i1 %gt, label %loop.body, label %loop.exit
|
||||
|
||||
loop.body: ; preds = %loop.cond
|
||||
%7 = load i64, ptr %.anon, align 8
|
||||
%sub = sub i64 %7, 1
|
||||
store i64 %sub, ptr %.anon, align 8
|
||||
%8 = load i64, ptr %.anon, align 8
|
||||
store i64 %8, ptr %index, align 8
|
||||
%9 = getelementptr inbounds %Foo, ptr %x, i32 0, i32 0
|
||||
%10 = getelementptr inbounds %"int[]", ptr %9, i32 0, i32 0
|
||||
%11 = load ptr, ptr %10, align 8
|
||||
%12 = load i64, ptr %index, align 8
|
||||
%ptroffset = getelementptr inbounds i32, ptr %11, i64 %12
|
||||
%13 = load i32, ptr %ptroffset, align 4
|
||||
store i32 %13, ptr %f, align 4
|
||||
%14 = load i32, ptr %f, align 4
|
||||
%15 = call i32 (ptr, ...) @printf(ptr @.str, i32 %14)
|
||||
br label %loop.body1
|
||||
|
||||
loop.body1: ; preds = %loop.body
|
||||
br label %loop.exit
|
||||
|
||||
loop.exit: ; preds = %loop.body1, %loop.cond
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i32 @printf(ptr, ...) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define i32 @main(i32 %0, ptr %1) #0 {
|
||||
entry:
|
||||
call void @test_main()
|
||||
ret i32 0
|
||||
}
|
||||
54
test/test_suite2/statements/foreach_r_errors.c3
Normal file
54
test/test_suite2/statements/foreach_r_errors.c3
Normal file
@@ -0,0 +1,54 @@
|
||||
module test;
|
||||
|
||||
extern fn void foo();
|
||||
int[3] z;
|
||||
|
||||
fn void test1()
|
||||
{
|
||||
int x;
|
||||
foreach_r (a : x) // #error: It's not possible to enumerate an expression of type 'int'.
|
||||
{
|
||||
foo();
|
||||
}
|
||||
}
|
||||
|
||||
fn void test2()
|
||||
{
|
||||
foreach_r (a : z) foo();
|
||||
foreach_r (i, a : z) foo();
|
||||
foreach_r (double i, a : z); // #error: Index must be an integer type, 'double' is not valid.
|
||||
}
|
||||
|
||||
fn void test3()
|
||||
{
|
||||
foreach_r (&a : z) foo();
|
||||
foreach_r (&i, &a : z) foo(); // #error: The index cannot be held by reference, did you accidentally add a '&'?
|
||||
}
|
||||
|
||||
fn void test4()
|
||||
{
|
||||
foreach_r (&a : z) foo();
|
||||
foreach_r (&i, a : z) foo(); // #error: The index cannot be held by reference, did you accidentally add a '&'?
|
||||
}
|
||||
|
||||
fn void test5()
|
||||
{
|
||||
foreach_r (int! y : z) foo(); // #error: The variable may not be a failable.
|
||||
}
|
||||
|
||||
fn void test6()
|
||||
{
|
||||
foreach_r (int! i, y : z) foo(); // #error: The index may not be a failable.
|
||||
}
|
||||
|
||||
fn void test7()
|
||||
{
|
||||
foreach_r (int a : { 1, 2, 3 }) foo();
|
||||
foreach_r (a : { 1, 2, 3 }) foo(); // #error: Add the type of your variable here if you want to iterate over
|
||||
}
|
||||
|
||||
fn void test8()
|
||||
{
|
||||
foreach_r (int a : { z }) foo(); // #error: 'int[3]' into 'int'
|
||||
}
|
||||
|
||||
5
test/test_suite2/statements/foreach_r_parse_error.c3
Normal file
5
test/test_suite2/statements/foreach_r_parse_error.c3
Normal file
@@ -0,0 +1,5 @@
|
||||
fn void test9()
|
||||
{
|
||||
foreach_r (int a : { [2] = 1 }) foo();
|
||||
foreach_r (int a : { [2] = 2, 1 }) foo(); // #error: Normal initialization cannot be mixed with designated initialization.
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
import std::io;
|
||||
|
||||
fn void main()
|
||||
{
|
||||
int[*] x = { 1, 5, 10 };
|
||||
int[] y = &x;
|
||||
foreach_r (int i, val : y)
|
||||
{
|
||||
io::printfln("%d: %d", i, val);
|
||||
}
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
entry:
|
||||
%x = alloca [3 x i32], align 4
|
||||
%y = alloca %"int[]", align 8
|
||||
%.anon = alloca i64, align 8
|
||||
%i = alloca i32, align 4
|
||||
%val = alloca i32, align 4
|
||||
%retparam = alloca i64, align 8
|
||||
%taddr = alloca %"char[]", align 8
|
||||
%vararg = alloca %"variant[]", align 8
|
||||
%varargslots = alloca [2 x %variant], align 16
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x, ptr align 4 @.__const, i32 12, i1 false)
|
||||
%0 = insertvalue %"int[]" undef, ptr %x, 0
|
||||
%1 = insertvalue %"int[]" %0, i64 3, 1
|
||||
store %"int[]" %1, ptr %y, align 8
|
||||
%2 = getelementptr inbounds %"int[]", ptr %y, i32 0, i32 1
|
||||
%3 = load i64, ptr %2, align 8
|
||||
store i64 %3, ptr %.anon, align 8
|
||||
br label %loop.cond
|
||||
|
||||
loop.cond: ; preds = %voiderr, %entry
|
||||
%4 = load i64, ptr %.anon, align 8
|
||||
%gt = icmp ugt i64 %4, 0
|
||||
br i1 %gt, label %loop.body, label %loop.exit
|
||||
|
||||
loop.body: ; preds = %loop.cond
|
||||
%5 = load i64, ptr %.anon, align 8
|
||||
%sub = sub i64 %5, 1
|
||||
store i64 %sub, ptr %.anon, align 8
|
||||
%6 = load i64, ptr %.anon, align 8
|
||||
%uisitrunc = trunc i64 %6 to i32
|
||||
store i32 %uisitrunc, ptr %i, align 4
|
||||
%7 = getelementptr inbounds %"int[]", ptr %y, i32 0, i32 0
|
||||
%8 = load ptr, ptr %7, align 8
|
||||
%9 = load i64, ptr %.anon, align 8
|
||||
%ptroffset = getelementptr inbounds i32, ptr %8, i64 %9
|
||||
%10 = load i32, ptr %ptroffset, align 4
|
||||
store i32 %10, ptr %val, align 4
|
||||
store %"char[]" { ptr @.str, i64 6 }, ptr %taddr, align 8
|
||||
%11 = getelementptr inbounds { ptr, i64 }, ptr %taddr, i32 0, i32 0
|
||||
%lo = load ptr, ptr %11, align 8
|
||||
%12 = getelementptr inbounds { ptr, i64 }, ptr %taddr, i32 0, i32 1
|
||||
%hi = load i64, ptr %12, align 8
|
||||
%13 = insertvalue %variant undef, ptr %i, 0
|
||||
%14 = insertvalue %variant %13, i64 ptrtoint (ptr @"ct$int" to i64), 1
|
||||
%15 = getelementptr inbounds [2 x %variant], ptr %varargslots, i64 0, i64 0
|
||||
store %variant %14, ptr %15, align 16
|
||||
%16 = insertvalue %variant undef, ptr %val, 0
|
||||
%17 = insertvalue %variant %16, i64 ptrtoint (ptr @"ct$int" to i64), 1
|
||||
%18 = getelementptr inbounds [2 x %variant], ptr %varargslots, i64 0, i64 1
|
||||
store %variant %17, ptr %18, align 16
|
||||
%19 = getelementptr inbounds %"variant[]", ptr %vararg, i32 0, i32 1
|
||||
store i64 2, ptr %19, align 8
|
||||
%20 = getelementptr inbounds %"variant[]", ptr %vararg, i32 0, i32 0
|
||||
store ptr %varargslots, ptr %20, align 8
|
||||
%21 = getelementptr inbounds { ptr, i64 }, ptr %vararg, i32 0, i32 0
|
||||
%lo1 = load ptr, ptr %21, align 8
|
||||
%22 = getelementptr inbounds { ptr, i64 }, ptr %vararg, i32 0, i32 1
|
||||
%hi2 = load i64, ptr %22, align 8
|
||||
%23 = call i64 @std_io_printfln(ptr %retparam, ptr %lo, i64 %hi, ptr %lo1, i64 %hi2)
|
||||
%not_err = icmp eq i64 %23, 0
|
||||
br i1 %not_err, label %after_check, label %voiderr
|
||||
|
||||
after_check: ; preds = %loop.body
|
||||
br label %voiderr
|
||||
|
||||
voiderr: ; preds = %after_check, %loop.body
|
||||
br label %loop.cond
|
||||
|
||||
loop.exit: ; preds = %loop.cond
|
||||
ret void
|
||||
}
|
||||
12
test/test_suite2/statements/foreach_r_with_error.c3
Normal file
12
test/test_suite2/statements/foreach_r_with_error.c3
Normal file
@@ -0,0 +1,12 @@
|
||||
module test;
|
||||
|
||||
fn void test()
|
||||
{
|
||||
int[3]! x;
|
||||
int g;
|
||||
foreach_r (z : x) // #error: The expression may not be failable.
|
||||
{
|
||||
g += z;
|
||||
x[0] = 1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user