Fixing distinct, typedef and bitstruct copying. Fix where global constants did not need to be constant. Bump to 0.2.26

This commit is contained in:
Christoffer Lerno
2022-07-27 16:49:46 +02:00
committed by Christoffer Lerno
parent 64d883cb99
commit 6f5f5feb97
16 changed files with 544 additions and 44 deletions

View File

@@ -86,7 +86,7 @@ fn void panic(char* message, char *file, char *function, uint line) @builtin
$$trap();
}
macro unreachable($string = "Unreachable statement reached.") @builtin @noreturn
macro void unreachable($string = "Unreachable statement reached.") @builtin @noreturn
{
panic($string, $$FILE, $$FUNC, $$LINE);
$$unreachable();

View File

@@ -12,35 +12,34 @@ private const uint UTF16_SURROGATE_HIGH_VALUE = 0xD800;
/**
* @param c `The utf32 codepoint to convert`
* @param [out] output `the resulting buffer`
* @param [inout] size `the size available`
* @param available `the size available`
**/
fn void! char32_to_utf8(Char32 c, char* output, usize *size)
fn usize! char32_to_utf8(Char32 c, char* output, usize available)
{
usize available = *size;
if (!available) return UnicodeResult.CONVERSION_FAILED!;
switch (true)
{
case c < 0x7f:
output[0] = (char)c;
*size = 1;
return 1;
case c < 0x7ff:
if (available < 2) return UnicodeResult.CONVERSION_FAILED!;
output[0] = (char)(0xC0 | c >> 6);
output[1] = (char)(0x80 | (c & 0x3F));
*size = 2;
return 2;
case c < 0xffff:
if (available < 3) return UnicodeResult.CONVERSION_FAILED!;
output[0] = (char)(0xE0 | c >> 12);
output[1] = (char)(0x80 | (c >> 6 & 0x3F));
output[2] = (char)(0x80 | (c & 0x3F));
*size = 3;
return 3;
default:
if (available < 4) return UnicodeResult.CONVERSION_FAILED!;
output[0] = (char)(0xF0 | c >> 18);
output[1] = (char)(0x80 | (c >> 12 & 0x3F));
output[2] = (char)(0x80 | (c >> 6 & 0x3F));
output[3] = (char)(0x80 | (c & 0x3F));
*size = 4;
return 4;
}
}
@@ -297,10 +296,9 @@ fn usize! utf32to8(Char32[] utf32, char[] utf8_buffer)
char* ptr = utf8_buffer.ptr;
foreach (Char32 uc : utf32)
{
usize size = len;
char32_to_utf8(uc, ptr, &size) @inline?;
len -= size;
ptr += size;
usize used = char32_to_utf8(uc, ptr, len) @inline?;
len -= used;
ptr += used;
}
return utf8_buffer.len - len;
}

View File

@@ -1,9 +1,6 @@
module std::core::types;
import libc;
macro bool kind_is_int(TypeKind kind)
{
return kind == TypeKind.SIGNED_INT || kind == TypeKind.UNSIGNED_INT;
}
fault ConversionResult
{
@@ -95,6 +92,11 @@ macro bool is_numerical($Type)
$endif;
}
fn bool TypeKind.is_int(TypeKind kind) @inline
{
return kind == TypeKind.SIGNED_INT || kind == TypeKind.UNSIGNED_INT;
}
macro bool is_comparable($Type)
{
var $kind = $Type.kind;
@@ -125,8 +127,6 @@ macro bool is_comparable_value(value)
$endif;
}
enum TypeKind : char
{
VOID,

View File

@@ -1,5 +1,5 @@
// TODO: ensure the type is an enum first.
module enumset<Enum>;
module std::enumset<Enum>;
$assert(Enum.elements < 64, "Maximum number of elements for an enum used as enum set is 63");
@@ -57,6 +57,11 @@ fn void EnumSet.retain_all(EnumSet *this, EnumSet s)
*this = (EnumSet)((EnumSetType)*this & (EnumSetType)s);
}
fn void EnumSet.remove_all(EnumSet* this, EnumSet s)
{
*this = (EnumSet)((EnumSetType)*this & ~(EnumSetType)s);
}
fn EnumSet EnumSet.and_of(EnumSet* this, EnumSet s)
{
return (EnumSet)((EnumSetType)*this & (EnumSetType)s);

View File

@@ -171,6 +171,16 @@ fn File stdout()
return { libc::stdout() };
}
fn File stderr()
{
return { libc::stderr() };
}
fn File stdin()
{
return { libc::stdin() };
}
/*

View File

@@ -194,7 +194,7 @@ private fn int! printf_parse_format_field(variant* args_ptr, usize args_len, usi
if (c != '*') return 0;
printf_advance_format(format_len, index_ptr)?;
variant val = next_variant(args_ptr, args_len, args_index_ptr)?;
if (!types::kind_is_int(val.type.kind)) return FormattingFault.INVALID_WIDTH_ARG!;
if (!val.type.kind.is_int()) return FormattingFault.INVALID_WIDTH_ARG!;
uint! intval = types::variant_to_int(val, int);
if (catch intval) return FormattingFault.INVALID_WIDTH_ARG!;
return intval;

View File

@@ -19,6 +19,7 @@ private fn void List.ensure_capacity(List *list) @inline
}
}
fn void List.push(List *list, Type element) @inline
{
list.append(element);

View File

@@ -556,6 +556,7 @@ static void copy_function_signature_deep(CopyStruct *c, FunctionSignature *signa
void copy_decl_type(Decl *decl)
{
Type *type = decl->type;
if (!type) return;
Type *copy = type_new(type->type_kind, type->name);
*copy = *type;
copy->type_cache = NULL;
@@ -608,8 +609,14 @@ Decl *copy_decl(CopyStruct *c, Decl *decl)
MACRO_COPY_DECL_LIST(copy->methods);
break;
case DECL_DECLARRAY:
case DECL_BITSTRUCT:
UNREACHABLE
case DECL_BITSTRUCT:
copy_decl_type(copy);
MACRO_COPY_DECL_LIST(copy->bitstruct.members);
MACRO_COPY_TYPE(copy->bitstruct.base_type);
MACRO_COPY_DECL_LIST(copy->methods);
MACRO_COPY_DECL_LIST(copy->methods);
break;
case DECL_ENUM:
case DECL_FAULT:
copy_decl_type(copy);
@@ -619,6 +626,7 @@ Decl *copy_decl(CopyStruct *c, Decl *decl)
MACRO_COPY_DECL_LIST(copy->enums.values);
break;
case DECL_FUNC:
copy_decl_type(copy);
MACRO_COPY_TYPEID(copy->func_decl.type_parent);
MACRO_COPY_ASTID(copy->func_decl.docs);
copy_function_signature_deep(c, &copy->func_decl.function_signature);
@@ -644,6 +652,7 @@ Decl *copy_decl(CopyStruct *c, Decl *decl)
case DECL_FAULTVALUE:
break;
case DECL_TYPEDEF:
copy_decl_type(copy);
if (copy->typedef_decl.is_func)
{
copy_function_signature_deep(c, &copy->typedef_decl.function_signature);
@@ -652,6 +661,7 @@ Decl *copy_decl(CopyStruct *c, Decl *decl)
MACRO_COPY_TYPE(copy->typedef_decl.type_info);
break;
case DECL_DISTINCT:
copy_decl_type(copy);
MACRO_COPY_DECL_LIST(copy->methods);
if (copy->distinct_decl.typedef_decl.is_func)
{

View File

@@ -2103,7 +2103,7 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local)
if (!sema_add_local(context, decl)) return decl_poison(decl);
}
// 1. Local constants: const int FOO = 123.
// 1. Local or global constants: const int FOO = 123.
if (decl->var.kind == VARDECL_CONST)
{
Expr *init_expr = decl->var.init_expr;
@@ -2117,6 +2117,11 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local)
if (!decl->var.type_info)
{
if (!sema_analyse_expr(context, init_expr)) return false;
if (is_global && !expr_is_constant_eval(init_expr, CONSTANT_EVAL_ANY))
{
SEMA_ERROR(init_expr, "This expression cannot be evaluated at compile time.");
return false;
}
decl->type = init_expr->type;
if (!decl->alignment) decl->alignment = type_alloca_alignment(decl->type);
if (!sema_analyse_decl_type(context, decl->type, init_expr->span)) return false;

View File

@@ -3796,7 +3796,7 @@ CHECK_DEEPER:
SEMA_ERROR(expr, "The method '%s' has private visibility.", kw);
return false;
}
SEMA_ERROR(expr, "There is no field or method '%s.%s'.", decl->name, kw);
SEMA_ERROR(expr, "There is no field or method '%s.%s'.", type_to_error_string(parent->type), kw);
return false;
}

View File

@@ -190,19 +190,19 @@ static void register_generic_decls(Module *module, Decl **decls)
case DECL_ATTRIBUTE:
break;
case DECL_CT_CASE:
register_generic_decls(module, decl->ct_case_decl.body);
// register_generic_decls(module, decl->ct_case_decl.body);
continue;
case DECL_CT_ELIF:
register_generic_decls(module, decl->ct_elif_decl.then);
// register_generic_decls(module, decl->ct_elif_decl.then);
continue;
case DECL_CT_ELSE:
register_generic_decls(module, decl->ct_else_decl);
// register_generic_decls(module, decl->ct_else_decl);
continue;
case DECL_CT_IF:
register_generic_decls(module, decl->ct_if_decl.then);
// register_generic_decls(module, decl->ct_if_decl.then);
continue;
case DECL_CT_SWITCH:
register_generic_decls(module, decl->ct_switch_decl.cases);
// register_generic_decls(module, decl->ct_switch_decl.cases);
continue;
case DECL_MACRO:
case DECL_DEFINE:

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.2.25"
#define COMPILER_VERSION "0.2.26"

View File

@@ -0,0 +1,25 @@
// #target: macos-x64
module test;
macro foo()
{
$if ($defined(A)):
return A + 1;
$else:
return 1;
$endif;
}
const Z = foo();
$if (!$defined(A) && Z == 1):
const A = 222;
$endif;
const B = foo();
/* #expect: test.ll
@test_Z = local_unnamed_addr constant i32 1, align 4
@test_B = local_unnamed_addr constant i32 223, align 4
@test_A = local_unnamed_addr constant i32 222, align 4

View File

@@ -0,0 +1,218 @@
// #target: macos-x64
module test;
import std::io;
import std::enumset;
define AbcEnumSet = EnumSet<Abc>;
enum Abc
{
HELLO,
WORLD
}
fn void main()
{
AbcEnumSet set;
io::printf("Has WORLD: %s\n", set.has(Abc.WORLD));
set.add(Abc.HELLO);
io::printf("Has WORLD: %s\n", set.has(Abc.WORLD));
set.add(Abc.WORLD);
io::printf("Has WORLD: %s\n", set.has(Abc.WORLD));
AbcEnumSet set2;
set2.add_all(set);
io::printf("Has WORLD: %s\n", set2.has(Abc.WORLD));
set.remove_all(set2);
io::printf("Has WORLD: %s\n", set.has(Abc.WORLD));
}
/* #expect: test.ll
define void @test_main() #0 {
entry:
%set = alloca i32, align 4
%retparam = alloca i64, align 8
%taddr = alloca %"char[]", align 8
%vararg = alloca %"variant[]", align 8
%varargslots = alloca [1 x %variant], align 16
%taddr1 = alloca i8, align 1
%retparam4 = alloca i64, align 8
%taddr5 = alloca %"char[]", align 8
%vararg8 = alloca %"variant[]", align 8
%varargslots9 = alloca [1 x %variant], align 16
%taddr10 = alloca i8, align 1
%retparam16 = alloca i64, align 8
%taddr17 = alloca %"char[]", align 8
%vararg20 = alloca %"variant[]", align 8
%varargslots21 = alloca [1 x %variant], align 16
%taddr22 = alloca i8, align 1
%set2 = alloca i32, align 4
%retparam28 = alloca i64, align 8
%taddr29 = alloca %"char[]", align 8
%vararg32 = alloca %"variant[]", align 8
%varargslots33 = alloca [1 x %variant], align 16
%taddr34 = alloca i8, align 1
%retparam40 = alloca i64, align 8
%taddr41 = alloca %"char[]", align 8
%vararg44 = alloca %"variant[]", align 8
%varargslots45 = alloca [1 x %variant], align 16
%taddr46 = alloca i8, align 1
store i32 0, i32* %set, align 4
store %"char[]" { i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i32 0, i32 0), i64 14 }, %"char[]"* %taddr, align 8
%0 = bitcast %"char[]"* %taddr to { i8*, i64 }*
%1 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %0, i32 0, i32 0
%lo = load i8*, i8** %1, align 8
%2 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %0, i32 0, i32 1
%hi = load i64, i64* %2, align 8
%3 = call i8 @"std_enumset$$test_Abc_EnumSet_has"(i32* %set, i32 1)
store i8 %3, i8* %taddr1, align 1
%4 = insertvalue %variant undef, i8* %taddr1, 0
%5 = insertvalue %variant %4, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1
%6 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots, i64 0, i64 0
store %variant %5, %variant* %6, align 16
%7 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg, i32 0, i32 1
store i64 1, i64* %7, align 8
%8 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg, i32 0, i32 0
%9 = bitcast [1 x %variant]* %varargslots to %variant*
store %variant* %9, %variant** %8, align 8
%10 = bitcast %"variant[]"* %vararg to { i8*, i64 }*
%11 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %10, i32 0, i32 0
%lo2 = load i8*, i8** %11, align 8
%12 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %10, i32 0, i32 1
%hi3 = load i64, i64* %12, align 8
%13 = call i64 @std_io_printf(i64* %retparam, i8* %lo, i64 %hi, i8* %lo2, i64 %hi3)
%not_err = icmp eq i64 %13, 0
br i1 %not_err, label %after.errcheck, label %voiderr
after.errcheck: ; preds = %entry
br label %voiderr
voiderr: ; preds = %after.errcheck, %entry
call void @"std_enumset$$test_Abc_EnumSet_add"(i32* %set, i32 0)
store %"char[]" { i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.1, i32 0, i32 0), i64 14 }, %"char[]"* %taddr5, align 8
%14 = bitcast %"char[]"* %taddr5 to { i8*, i64 }*
%15 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %14, i32 0, i32 0
%lo6 = load i8*, i8** %15, align 8
%16 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %14, i32 0, i32 1
%hi7 = load i64, i64* %16, align 8
%17 = call i8 @"std_enumset$$test_Abc_EnumSet_has"(i32* %set, i32 1)
store i8 %17, i8* %taddr10, align 1
%18 = insertvalue %variant undef, i8* %taddr10, 0
%19 = insertvalue %variant %18, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1
%20 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots9, i64 0, i64 0
store %variant %19, %variant* %20, align 16
%21 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg8, i32 0, i32 1
store i64 1, i64* %21, align 8
%22 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg8, i32 0, i32 0
%23 = bitcast [1 x %variant]* %varargslots9 to %variant*
store %variant* %23, %variant** %22, align 8
%24 = bitcast %"variant[]"* %vararg8 to { i8*, i64 }*
%25 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %24, i32 0, i32 0
%lo11 = load i8*, i8** %25, align 8
%26 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %24, i32 0, i32 1
%hi12 = load i64, i64* %26, align 8
%27 = call i64 @std_io_printf(i64* %retparam4, i8* %lo6, i64 %hi7, i8* %lo11, i64 %hi12)
%not_err13 = icmp eq i64 %27, 0
br i1 %not_err13, label %after.errcheck14, label %voiderr15
after.errcheck14: ; preds = %voiderr
br label %voiderr15
voiderr15: ; preds = %after.errcheck14, %voiderr
call void @"std_enumset$$test_Abc_EnumSet_add"(i32* %set, i32 1)
store %"char[]" { i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.2, i32 0, i32 0), i64 14 }, %"char[]"* %taddr17, align 8
%28 = bitcast %"char[]"* %taddr17 to { i8*, i64 }*
%29 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %28, i32 0, i32 0
%lo18 = load i8*, i8** %29, align 8
%30 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %28, i32 0, i32 1
%hi19 = load i64, i64* %30, align 8
%31 = call i8 @"std_enumset$$test_Abc_EnumSet_has"(i32* %set, i32 1)
store i8 %31, i8* %taddr22, align 1
%32 = insertvalue %variant undef, i8* %taddr22, 0
%33 = insertvalue %variant %32, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1
%34 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots21, i64 0, i64 0
store %variant %33, %variant* %34, align 16
%35 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg20, i32 0, i32 1
store i64 1, i64* %35, align 8
%36 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg20, i32 0, i32 0
%37 = bitcast [1 x %variant]* %varargslots21 to %variant*
store %variant* %37, %variant** %36, align 8
%38 = bitcast %"variant[]"* %vararg20 to { i8*, i64 }*
%39 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %38, i32 0, i32 0
%lo23 = load i8*, i8** %39, align 8
%40 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %38, i32 0, i32 1
%hi24 = load i64, i64* %40, align 8
%41 = call i64 @std_io_printf(i64* %retparam16, i8* %lo18, i64 %hi19, i8* %lo23, i64 %hi24)
%not_err25 = icmp eq i64 %41, 0
br i1 %not_err25, label %after.errcheck26, label %voiderr27
after.errcheck26: ; preds = %voiderr15
br label %voiderr27
voiderr27: ; preds = %after.errcheck26, %voiderr15
store i32 0, i32* %set2, align 4
%42 = load i32, i32* %set, align 4
call void @"std_enumset$$test_Abc_EnumSet_add_all"(i32* %set2, i32 %42)
store %"char[]" { i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.3, i32 0, i32 0), i64 14 }, %"char[]"* %taddr29, align 8
%43 = bitcast %"char[]"* %taddr29 to { i8*, i64 }*
%44 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %43, i32 0, i32 0
%lo30 = load i8*, i8** %44, align 8
%45 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %43, i32 0, i32 1
%hi31 = load i64, i64* %45, align 8
%46 = call i8 @"std_enumset$$test_Abc_EnumSet_has"(i32* %set2, i32 1)
store i8 %46, i8* %taddr34, align 1
%47 = insertvalue %variant undef, i8* %taddr34, 0
%48 = insertvalue %variant %47, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1
%49 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots33, i64 0, i64 0
store %variant %48, %variant* %49, align 16
%50 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg32, i32 0, i32 1
store i64 1, i64* %50, align 8
%51 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg32, i32 0, i32 0
%52 = bitcast [1 x %variant]* %varargslots33 to %variant*
store %variant* %52, %variant** %51, align 8
%53 = bitcast %"variant[]"* %vararg32 to { i8*, i64 }*
%54 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %53, i32 0, i32 0
%lo35 = load i8*, i8** %54, align 8
%55 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %53, i32 0, i32 1
%hi36 = load i64, i64* %55, align 8
%56 = call i64 @std_io_printf(i64* %retparam28, i8* %lo30, i64 %hi31, i8* %lo35, i64 %hi36)
%not_err37 = icmp eq i64 %56, 0
br i1 %not_err37, label %after.errcheck38, label %voiderr39
after.errcheck38: ; preds = %voiderr27
br label %voiderr39
voiderr39: ; preds = %after.errcheck38, %voiderr27
%57 = load i32, i32* %set2, align 4
call void @"std_enumset$$test_Abc_EnumSet_remove_all"(i32* %set, i32 %57)
store %"char[]" { i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.4, i32 0, i32 0), i64 14 }, %"char[]"* %taddr41, align 8
%58 = bitcast %"char[]"* %taddr41 to { i8*, i64 }*
%59 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %58, i32 0, i32 0
%lo42 = load i8*, i8** %59, align 8
%60 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %58, i32 0, i32 1
%hi43 = load i64, i64* %60, align 8
%61 = call i8 @"std_enumset$$test_Abc_EnumSet_has"(i32* %set, i32 1)
store i8 %61, i8* %taddr46, align 1
%62 = insertvalue %variant undef, i8* %taddr46, 0
%63 = insertvalue %variant %62, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1
%64 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots45, i64 0, i64 0
store %variant %63, %variant* %64, align 16
%65 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg44, i32 0, i32 1
store i64 1, i64* %65, align 8
%66 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg44, i32 0, i32 0
%67 = bitcast [1 x %variant]* %varargslots45 to %variant*
store %variant* %67, %variant** %66, align 8
%68 = bitcast %"variant[]"* %vararg44 to { i8*, i64 }*
%69 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %68, i32 0, i32 0
%lo47 = load i8*, i8** %69, align 8
%70 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %68, i32 0, i32 1
%hi48 = load i64, i64* %70, align 8
%71 = call i64 @std_io_printf(i64* %retparam40, i8* %lo42, i64 %hi43, i8* %lo47, i64 %hi48)
%not_err49 = icmp eq i64 %71, 0
br i1 %not_err49, label %after.errcheck50, label %voiderr51
after.errcheck50: ; preds = %voiderr39
br label %voiderr51
voiderr51: ; preds = %after.errcheck50, %voiderr39
ret void
}

View File

@@ -0,0 +1,25 @@
// #target: macos-x64
module test;
macro foo()
{
$if ($defined(A)):
return A + 1;
$else:
return 1;
$endif;
}
const Z = foo();
$if (!$defined(A) && Z == 1):
const A = 222;
$endif;
const B = foo();
/* #expect: test.ll
@test_Z = local_unnamed_addr constant i32 1, align 4
@test_B = local_unnamed_addr constant i32 223, align 4
@test_A = local_unnamed_addr constant i32 222, align 4

View File

@@ -0,0 +1,203 @@
// #target: macos-x64
module test;
import std::io;
import std::enumset;
define AbcEnumSet = EnumSet<Abc>;
enum Abc
{
HELLO,
WORLD
}
fn void main()
{
AbcEnumSet set;
io::printf("Has WORLD: %s\n", set.has(Abc.WORLD));
set.add(Abc.HELLO);
io::printf("Has WORLD: %s\n", set.has(Abc.WORLD));
set.add(Abc.WORLD);
io::printf("Has WORLD: %s\n", set.has(Abc.WORLD));
AbcEnumSet set2;
set2.add_all(set);
io::printf("Has WORLD: %s\n", set2.has(Abc.WORLD));
set.remove_all(set2);
io::printf("Has WORLD: %s\n", set.has(Abc.WORLD));
}
/* #expect: test.ll
define void @test_main() #0 {
entry:
%set = alloca i32, align 4
%retparam = alloca i64, align 8
%taddr = alloca %"char[]", align 8
%vararg = alloca %"variant[]", align 8
%varargslots = alloca [1 x %variant], align 16
%taddr1 = alloca i8, align 1
%retparam4 = alloca i64, align 8
%taddr5 = alloca %"char[]", align 8
%vararg8 = alloca %"variant[]", align 8
%varargslots9 = alloca [1 x %variant], align 16
%taddr10 = alloca i8, align 1
%retparam16 = alloca i64, align 8
%taddr17 = alloca %"char[]", align 8
%vararg20 = alloca %"variant[]", align 8
%varargslots21 = alloca [1 x %variant], align 16
%taddr22 = alloca i8, align 1
%set2 = alloca i32, align 4
%retparam28 = alloca i64, align 8
%taddr29 = alloca %"char[]", align 8
%vararg32 = alloca %"variant[]", align 8
%varargslots33 = alloca [1 x %variant], align 16
%taddr34 = alloca i8, align 1
%retparam40 = alloca i64, align 8
%taddr41 = alloca %"char[]", align 8
%vararg44 = alloca %"variant[]", align 8
%varargslots45 = alloca [1 x %variant], align 16
%taddr46 = alloca i8, align 1
store i32 0, ptr %set, align 4
store %"char[]" { ptr @.str, i64 14 }, ptr %taddr, align 8
%0 = getelementptr inbounds { ptr, i64 }, ptr %taddr, i32 0, i32 0
%lo = load ptr, ptr %0, align 8
%1 = getelementptr inbounds { ptr, i64 }, ptr %taddr, i32 0, i32 1
%hi = load i64, ptr %1, align 8
%2 = call i8 @"std_enumset$$test_Abc_EnumSet_has"(ptr %set, i32 1)
store i8 %2, ptr %taddr1, align 1
%3 = insertvalue %variant undef, ptr %taddr1, 0
%4 = insertvalue %variant %3, i64 ptrtoint (ptr @"ct$bool" to i64), 1
%5 = getelementptr inbounds [1 x %variant], ptr %varargslots, i64 0, i64 0
store %variant %4, ptr %5, align 16
%6 = getelementptr inbounds %"variant[]", ptr %vararg, i32 0, i32 1
store i64 1, ptr %6, align 8
%7 = getelementptr inbounds %"variant[]", ptr %vararg, i32 0, i32 0
store ptr %varargslots, ptr %7, align 8
%8 = getelementptr inbounds { ptr, i64 }, ptr %vararg, i32 0, i32 0
%lo2 = load ptr, ptr %8, align 8
%9 = getelementptr inbounds { ptr, i64 }, ptr %vararg, i32 0, i32 1
%hi3 = load i64, ptr %9, align 8
%10 = call i64 @std_io_printf(ptr %retparam, ptr %lo, i64 %hi, ptr %lo2, i64 %hi3)
%not_err = icmp eq i64 %10, 0
br i1 %not_err, label %after.errcheck, label %voiderr
after.errcheck: ; preds = %entry
br label %voiderr
voiderr: ; preds = %after.errcheck, %entry
call void @"std_enumset$$test_Abc_EnumSet_add"(ptr %set, i32 0)
store %"char[]" { ptr @.str.1, i64 14 }, ptr %taddr5, align 8
%11 = getelementptr inbounds { ptr, i64 }, ptr %taddr5, i32 0, i32 0
%lo6 = load ptr, ptr %11, align 8
%12 = getelementptr inbounds { ptr, i64 }, ptr %taddr5, i32 0, i32 1
%hi7 = load i64, ptr %12, align 8
%13 = call i8 @"std_enumset$$test_Abc_EnumSet_has"(ptr %set, i32 1)
store i8 %13, ptr %taddr10, align 1
%14 = insertvalue %variant undef, ptr %taddr10, 0
%15 = insertvalue %variant %14, i64 ptrtoint (ptr @"ct$bool" to i64), 1
%16 = getelementptr inbounds [1 x %variant], ptr %varargslots9, i64 0, i64 0
store %variant %15, ptr %16, align 16
%17 = getelementptr inbounds %"variant[]", ptr %vararg8, i32 0, i32 1
store i64 1, ptr %17, align 8
%18 = getelementptr inbounds %"variant[]", ptr %vararg8, i32 0, i32 0
store ptr %varargslots9, ptr %18, align 8
%19 = getelementptr inbounds { ptr, i64 }, ptr %vararg8, i32 0, i32 0
%lo11 = load ptr, ptr %19, align 8
%20 = getelementptr inbounds { ptr, i64 }, ptr %vararg8, i32 0, i32 1
%hi12 = load i64, ptr %20, align 8
%21 = call i64 @std_io_printf(ptr %retparam4, ptr %lo6, i64 %hi7, ptr %lo11, i64 %hi12)
%not_err13 = icmp eq i64 %21, 0
br i1 %not_err13, label %after.errcheck14, label %voiderr15
after.errcheck14: ; preds = %voiderr
br label %voiderr15
voiderr15: ; preds = %after.errcheck14, %voiderr
call void @"std_enumset$$test_Abc_EnumSet_add"(ptr %set, i32 1)
store %"char[]" { ptr @.str.2, i64 14 }, ptr %taddr17, align 8
%22 = getelementptr inbounds { ptr, i64 }, ptr %taddr17, i32 0, i32 0
%lo18 = load ptr, ptr %22, align 8
%23 = getelementptr inbounds { ptr, i64 }, ptr %taddr17, i32 0, i32 1
%hi19 = load i64, ptr %23, align 8
%24 = call i8 @"std_enumset$$test_Abc_EnumSet_has"(ptr %set, i32 1)
store i8 %24, ptr %taddr22, align 1
%25 = insertvalue %variant undef, ptr %taddr22, 0
%26 = insertvalue %variant %25, i64 ptrtoint (ptr @"ct$bool" to i64), 1
%27 = getelementptr inbounds [1 x %variant], ptr %varargslots21, i64 0, i64 0
store %variant %26, ptr %27, align 16
%28 = getelementptr inbounds %"variant[]", ptr %vararg20, i32 0, i32 1
store i64 1, ptr %28, align 8
%29 = getelementptr inbounds %"variant[]", ptr %vararg20, i32 0, i32 0
store ptr %varargslots21, ptr %29, align 8
%30 = getelementptr inbounds { ptr, i64 }, ptr %vararg20, i32 0, i32 0
%lo23 = load ptr, ptr %30, align 8
%31 = getelementptr inbounds { ptr, i64 }, ptr %vararg20, i32 0, i32 1
%hi24 = load i64, ptr %31, align 8
%32 = call i64 @std_io_printf(ptr %retparam16, ptr %lo18, i64 %hi19, ptr %lo23, i64 %hi24)
%not_err25 = icmp eq i64 %32, 0
br i1 %not_err25, label %after.errcheck26, label %voiderr27
after.errcheck26: ; preds = %voiderr15
br label %voiderr27
voiderr27: ; preds = %after.errcheck26, %voiderr15
store i32 0, ptr %set2, align 4
%33 = load i32, ptr %set, align 4
call void @"std_enumset$$test_Abc_EnumSet_add_all"(ptr %set2, i32 %33)
store %"char[]" { ptr @.str.3, i64 14 }, ptr %taddr29, align 8
%34 = getelementptr inbounds { ptr, i64 }, ptr %taddr29, i32 0, i32 0
%lo30 = load ptr, ptr %34, align 8
%35 = getelementptr inbounds { ptr, i64 }, ptr %taddr29, i32 0, i32 1
%hi31 = load i64, ptr %35, align 8
%36 = call i8 @"std_enumset$$test_Abc_EnumSet_has"(ptr %set2, i32 1)
store i8 %36, ptr %taddr34, align 1
%37 = insertvalue %variant undef, ptr %taddr34, 0
%38 = insertvalue %variant %37, i64 ptrtoint (ptr @"ct$bool" to i64), 1
%39 = getelementptr inbounds [1 x %variant], ptr %varargslots33, i64 0, i64 0
store %variant %38, ptr %39, align 16
%40 = getelementptr inbounds %"variant[]", ptr %vararg32, i32 0, i32 1
store i64 1, ptr %40, align 8
%41 = getelementptr inbounds %"variant[]", ptr %vararg32, i32 0, i32 0
store ptr %varargslots33, ptr %41, align 8
%42 = getelementptr inbounds { ptr, i64 }, ptr %vararg32, i32 0, i32 0
%lo35 = load ptr, ptr %42, align 8
%43 = getelementptr inbounds { ptr, i64 }, ptr %vararg32, i32 0, i32 1
%hi36 = load i64, ptr %43, align 8
%44 = call i64 @std_io_printf(ptr %retparam28, ptr %lo30, i64 %hi31, ptr %lo35, i64 %hi36)
%not_err37 = icmp eq i64 %44, 0
br i1 %not_err37, label %after.errcheck38, label %voiderr39
after.errcheck38: ; preds = %voiderr27
br label %voiderr39
voiderr39: ; preds = %after.errcheck38, %voiderr27
%45 = load i32, ptr %set2, align 4
call void @"std_enumset$$test_Abc_EnumSet_remove_all"(ptr %set, i32 %45)
store %"char[]" { ptr @.str.4, i64 14 }, ptr %taddr41, align 8
%46 = getelementptr inbounds { ptr, i64 }, ptr %taddr41, i32 0, i32 0
%lo42 = load ptr, ptr %46, align 8
%47 = getelementptr inbounds { ptr, i64 }, ptr %taddr41, i32 0, i32 1
%hi43 = load i64, ptr %47, align 8
%48 = call i8 @"std_enumset$$test_Abc_EnumSet_has"(ptr %set, i32 1)
store i8 %48, ptr %taddr46, align 1
%49 = insertvalue %variant undef, ptr %taddr46, 0
%50 = insertvalue %variant %49, i64 ptrtoint (ptr @"ct$bool" to i64), 1
%51 = getelementptr inbounds [1 x %variant], ptr %varargslots45, i64 0, i64 0
store %variant %50, ptr %51, align 16
%52 = getelementptr inbounds %"variant[]", ptr %vararg44, i32 0, i32 1
store i64 1, ptr %52, align 8
%53 = getelementptr inbounds %"variant[]", ptr %vararg44, i32 0, i32 0
store ptr %varargslots45, ptr %53, align 8
%54 = getelementptr inbounds { ptr, i64 }, ptr %vararg44, i32 0, i32 0
%lo47 = load ptr, ptr %54, align 8
%55 = getelementptr inbounds { ptr, i64 }, ptr %vararg44, i32 0, i32 1
%hi48 = load i64, ptr %55, align 8
%56 = call i64 @std_io_printf(ptr %retparam40, ptr %lo42, i64 %hi43, ptr %lo47, i64 %hi48)
%not_err49 = icmp eq i64 %56, 0
br i1 %not_err49, label %after.errcheck50, label %voiderr51
after.errcheck50: ; preds = %voiderr39
br label %voiderr51
voiderr51: ; preds = %after.errcheck50, %voiderr39
ret void
}