diff --git a/lib/std/io.c3 b/lib/std/io.c3 index c8ed6459b..833d71e30 100644 --- a/lib/std/io.c3 +++ b/lib/std/io.c3 @@ -56,9 +56,9 @@ fn void! File.open(File* file, char[] filename, char[] mode) enum Seek { - SET = 0, - CURSOR = 1, - END = 2 + SET, + CURSOR, + END } fault IoError @@ -84,10 +84,10 @@ fn void! File.seek(File *file, long offset, Seek seekMode = Seek.SET) { switch (libc::errno()) { - case EBADF: return IoError.FILE_NOT_SEEKABLE!; - case EINVAL: return IoError.FILE_INVALID_POSITION!; - case EOVERFLOW: return IoError.FILE_OVERFLOW!; - case ESPIPE: return IoError.FILE_IS_PIPE!; + case errno::EBADF: return IoError.FILE_NOT_SEEKABLE!; + case errno::EINVAL: return IoError.FILE_INVALID_POSITION!; + case errno::EOVERFLOW: return IoError.FILE_OVERFLOW!; + case errno::ESPIPE: return IoError.FILE_IS_PIPE!; default: return IoError.UNKNOWN_ERROR!; } } @@ -110,17 +110,17 @@ fn void! File.close(File *file) @inline { switch (libc::errno()) { - case ECONNRESET: - case EBADF: return IoError.FILE_NOT_VALID!; - case EINTR: return IoError.INTERRUPTED!; - case EDQUOT: - case EFAULT: - case EAGAIN: - case EFBIG: - case ENETDOWN: - case ENETUNREACH: - case ENOSPC: - case EIO: return IoError.FILE_INCOMPLETE_WRITE!; + case errno::ECONNRESET: + case errno::EBADF: return IoError.FILE_NOT_VALID!; + case errno::EINTR: return IoError.INTERRUPTED!; + case errno::EDQUOT: + case errno::EFAULT: + case errno::EAGAIN: + case errno::EFBIG: + case errno::ENETDOWN: + case errno::ENETUNREACH: + case errno::ENOSPC: + case errno::EIO: return IoError.FILE_INCOMPLETE_WRITE!; default: return IoError.UNKNOWN_ERROR!; } } diff --git a/lib/std/libc.c3 b/lib/std/libc.c3 index df7498bd5..82727946f 100644 --- a/lib/std/libc.c3 +++ b/lib/std/libc.c3 @@ -27,142 +27,7 @@ struct LongDivResult long rem; } -enum Errno : ErrnoType -{ - EPERM = 1, /* Operation not permitted */ - ENOENT = 2, /* No such file or directory */ - ESRCH = 3, /* No such process */ - EINTR = 4, /* Interrupted system call */ - EIO = 5, /* I/O error */ - ENXIO = 6, /* No such device or address */ - E2BIG = 7, /* Argument list too long */ - ENOEXEC = 8, /* Exec format error */ - EBADF = 9, /* Bad file number */ - ECHILD = 10, /* No child processes */ - EAGAIN = 11, /* Try again */ - ENOMEM = 12, /* Out of memory */ - EACCES = 13, /* Permission denied */ - EFAULT = 14, /* Bad address */ - ENOTBLK = 15, /* Block device required */ - EBUSY = 16, /* Device or resource busy */ - EEXIST = 17, /* File exists */ - EXDEV = 18, /* Cross-device link */ - ENODEV = 19, /* No such device */ - ENOTDIR = 20, /* Not a directory */ - EISDIR = 21, /* Is a directory */ - EINVAL = 22, /* Invalid argument */ - ENFILE = 23, /* File table overflow */ - EMFILE = 24, /* Too many open files */ - ENOTTY = 25, /* Not a typewriter */ - ETXTBSY = 26, /* Text file busy */ - EFBIG = 27, /* File too large */ - ENOSPC = 28, /* No space left on device */ - ESPIPE = 29, /* Illegal seek */ - EROFS = 30, /* Read-only file system */ - EMLINK = 31, /* Too many links */ - EPIPE = 32, /* Broken pipe */ - EDOM = 33, /* Math argument out of domain of func */ - ERANGE = 34, /* Math result not representable */ - EDEADLK = 35, /* Resource deadlock would occur */ - ENAMETOOLONG = 36, /* File name too long */ - ENOLCK = 37, /* No record locks available */ - ENOSYS = 38, /* Function not implemented */ - ENOTEMPTY = 39, /* Directory not empty */ - ELOOP = 40, /* Too many symbolic links encountered */ - ENOMSG = 42, /* No message of desired type */ - EIDRM = 43, /* Identifier removed */ - ECHRNG = 44, /* Channel number out of range */ - EL2NSYNC = 45, /* Level 2 not synchronized */ - EL3HLT = 46, /* Level 3 halted */ - EL3RST = 47, /* Level 3 reset */ - ELNRNG = 48, /* Link number out of range */ - EUNATCH = 49, /* Protocol driver not attached */ - ENOCSI = 50, /* No CSI structure available */ - EL2HLT = 51, /* Level 2 halted */ - EBADE = 52, /* Invalid exchange */ - EBADR = 53, /* Invalid request descriptor */ - EXFULL = 54, /* Exchange full */ - ENOANO = 55, /* No anode */ - EBADRQC = 56, /* Invalid request code */ - EBADSLT = 57, /* Invalid slot */ - - EBFONT = 59, /* Bad font file format */ - ENOSTR = 60, /* Device not a stream */ - ENODATA = 61, /* No data available */ - ETIME = 62, /* Timer expired */ - ENOSR = 63, /* Out of streams resources */ - ENONET = 64, /* Machine is not on the network */ - ENOPKG = 65, /* Package not installed */ - EREMOTE = 66, /* Object is remote */ - ENOLINK = 67, /* Link has been severed */ - EADV = 68, /* Advertise error */ - ESRMNT = 69, /* Srmount error */ - ECOMM = 70, /* Communication error on send */ - EPROTO = 71, /* Protocol error */ - EMULTIHOP = 72, /* Multihop attempted */ - EDOTDOT = 73, /* RFS specific error */ - EBADMSG = 74, /* Not a data message */ - EOVERFLOW = 75, /* Value too large for defined data type */ - ENOTUNIQ = 76, /* Name not unique on network */ - EBADFD = 77, /* File descriptor in bad state */ - EREMCHG = 78, /* Remote address changed */ - ELIBACC = 79, /* Can not access a needed shared library */ - ELIBBAD = 80, /* Accessing a corrupted shared library */ - ELIBSCN = 81, /* .lib section in a.out corrupted */ - ELIBMAX = 82, /* Attempting to link in too many shared libraries */ - ELIBEXEC = 83, /* Cannot exec a shared library directly */ - EILSEQ = 84, /* Illegal byte sequence */ - ERESTART = 85, /* Interrupted system call should be restarted */ - ESTRPIPE = 86, /* Streams pipe error */ - EUSERS = 87, /* Too many users */ - ENOTSOCK = 88, /* Socket operation on non-socket */ - EDESTADDRREQ = 89, /* Destination address required */ - EMSGSIZE = 90, /* Message too long */ - EPROTOTYPE = 91, /* Protocol wrong type for socket */ - ENOPROTOOPT = 92, /* Protocol not available */ - EPROTONOSUPPORT = 93, /* Protocol not supported */ - ESOCKTNOSUPPORT = 94, /* Socket type not supported */ - EOPNOTSUPP = 95, /* Operation not supported on transport endpoint */ - EPFNOSUPPORT = 96, /* Protocol family not supported */ - EAFNOSUPPORT = 97, /* Address family not supported by protocol */ - EADDRINUSE = 98, /* Address already in use */ - EADDRNOTAVAIL = 99, /* Cannot assign requested address */ - ENETDOWN = 100, /* Network is down */ - ENETUNREACH = 101, /* Network is unreachable */ - ENETRESET = 102, /* Network dropped connection because of reset */ - ECONNABORTED = 103, /* Software caused connection abort */ - ECONNRESET = 104, /* Connection reset by peer */ - ENOBUFS = 105, /* No buffer space available */ - EISCONN = 106, /* Transport endpoint is already connected */ - ENOTCONN = 107, /* Transport endpoint is not connected */ - ESHUTDOWN = 108, /* Cannot send after transport endpoint shutdown */ - ETOOMANYREFS = 109, /* Too many references: cannot splice */ - ETIMEDOUT = 110, /* Connection timed out */ - ECONNREFUSED = 111, /* Connection refused */ - EHOSTDOWN = 112, /* Host is down */ - EHOSTUNREACH = 113, /* No route to host */ - EALREADY = 114, /* Operation already in progress */ - EINPROGRESS = 115, /* Operation now in progress */ - ESTALE = 116, /* Stale NFS file handle */ - EUCLEAN = 117, /* Structure needs cleaning */ - ENOTNAM = 118, /* Not a XENIX named type file */ - ENAVAIL = 119, /* No XENIX semaphores available */ - EISNAM = 120, /* Is a named type file */ - EREMOTEIO = 121, /* Remote I/O error */ - EDQUOT = 122, /* Quota exceeded */ - - ENOMEDIUM = 123, /* No medium found */ - EMEDIUMTYPE = 124, /* Wrong medium type */ - ECANCELED = 125, /* Operation Canceled */ - ENOKEY = 126, /* Required key not available */ - EKEYEXPIRED = 127, /* Key has expired */ - EKEYREVOKED = 128, /* Key has been revoked */ - EKEYREJECTED = 129, /* Key was rejected by service */ - - EOWNERDEAD = 130, /* Owner died */ - ENOTRECOVERABLE = 131, /* State not recoverable */ -} fn Errno errno() { @@ -173,7 +38,7 @@ fn Errno errno() $elif (env::OS_TYPE == OsType.LINUX): return (Errno)linux::errno(); $else: - return Errno.ENOTRECOVERABLE; + return errno::ENOTRECOVERABLE; $endif; } @@ -271,7 +136,7 @@ const int EOF = -1; const int FOPEN_MAX = 20; const int FILENAME_MAX = 1024; -define ErrnoType = CInt; +define Errno = distinct CInt; define SeekIndex = CLong; extern fn int fclose(CFile stream); @@ -352,4 +217,140 @@ extern fn Time time(Time *timer); // signal define SignalFunction = fn void(int); extern fn SignalFunction signal(int sig, SignalFunction function); -// Incomplete \ No newline at end of file +// Incomplete + +module libc::errno; + +const Errno EPERM = 1; /* Operation not permitted */ +const Errno ENOENT = 2; /* No such file or directory */ +const Errno ESRCH = 3; /* No such process */ +const Errno EINTR = 4; /* Interrupted system call */ +const Errno EIO = 5; /* I/O error */ +const Errno ENXIO = 6; /* No such device or address */ +const Errno E2BIG = 7; /* Argument list too long */ +const Errno ENOEXEC = 8; /* Exec format error */ +const Errno EBADF = 9; /* Bad file number */ +const Errno ECHILD = 10; /* No child processes */ +const Errno EAGAIN = 11; /* Try again */ +const Errno ENOMEM = 12; /* Out of memory */ +const Errno EACCES = 13; /* Permission denied */ +const Errno EFAULT = 14; /* Bad address */ +const Errno ENOTBLK = 15; /* Block device required */ +const Errno EBUSY = 16; /* Device or resource busy */ +const Errno EEXIST = 17; /* File exists */ +const Errno EXDEV = 18; /* Cross-device link */ +const Errno ENODEV = 19; /* No such device */ +const Errno ENOTDIR = 20; /* Not a directory */ +const Errno EISDIR = 21; /* Is a directory */ +const Errno EINVAL = 22; /* Invalid argument */ +const Errno ENFILE = 23; /* File table overflow */ +const Errno EMFILE = 24; /* Too many open files */ +const Errno ENOTTY = 25; /* Not a typewriter */ +const Errno ETXTBSY = 26; /* Text file busy */ +const Errno EFBIG = 27; /* File too large */ +const Errno ENOSPC = 28; /* No space left on device */ +const Errno ESPIPE = 29; /* Illegal seek */ +const Errno EROFS = 30; /* Read-only file system */ +const Errno EMLINK = 31; /* Too many links */ +const Errno EPIPE = 32; /* Broken pipe */ +const Errno EDOM = 33; /* Math argument out of domain of func */ +const Errno ERANGE = 34; /* Math result not representable */ +const Errno EDEADLK = 35; /* Resource deadlock would occur */ +const Errno ENAMETOOLONG = 36; /* File name too long */ +const Errno ENOLCK = 37; /* No record locks available */ +const Errno ENOSYS = 38; /* Function not implemented */ +const Errno ENOTEMPTY = 39; /* Directory not empty */ +const Errno ELOOP = 40; /* Too many symbolic links encountered */ + +const Errno ENOMSG = 42; /* No message of desired type */ +const Errno EIDRM = 43; /* Identifier removed */ +const Errno ECHRNG = 44; /* Channel number out of range */ +const Errno EL2NSYNC = 45; /* Level 2 not synchronized */ +const Errno EL3HLT = 46; /* Level 3 halted */ +const Errno EL3RST = 47; /* Level 3 reset */ +const Errno ELNRNG = 48; /* Link number out of range */ +const Errno EUNATCH = 49; /* Protocol driver not attached */ +const Errno ENOCSI = 50; /* No CSI structure available */ +const Errno EL2HLT = 51; /* Level 2 halted */ +const Errno EBADE = 52; /* Invalid exchange */ +const Errno EBADR = 53; /* Invalid request descriptor */ +const Errno EXFULL = 54; /* Exchange full */ +const Errno ENOANO = 55; /* No anode */ +const Errno EBADRQC = 56; /* Invalid request code */ +const Errno EBADSLT = 57; /* Invalid slot */ + +const Errno EBFONT = 59; /* Bad font file format */ +const Errno ENOSTR = 60; /* Device not a stream */ +const Errno ENODATA = 61; /* No data available */ +const Errno ETIME = 62; /* Timer expired */ +const Errno ENOSR = 63; /* Out of streams resources */ +const Errno ENONET = 64; /* Machine is not on the network */ +const Errno ENOPKG = 65; /* Package not installed */ +const Errno EREMOTE = 66; /* Object is remote */ +const Errno ENOLINK = 67; /* Link has been severed */ +const Errno EADV = 68; /* Advertise error */ +const Errno ESRMNT = 69; /* Srmount error */ +const Errno ECOMM = 70; /* Communication error on send */ +const Errno EPROTO = 71; /* Protocol error */ +const Errno EMULTIHOP = 72; /* Multihop attempted */ +const Errno EDOTDOT = 73; /* RFS specific error */ +const Errno EBADMSG = 74; /* Not a data message */ +const Errno EOVERFLOW = 75; /* Value too large for defined data type */ +const Errno ENOTUNIQ = 76; /* Name not unique on network */ +const Errno EBADFD = 77; /* File descriptor in bad state */ +const Errno EREMCHG = 78; /* Remote address changed */ +const Errno ELIBACC = 79; /* Can not access a needed shared library */ +const Errno ELIBBAD = 80; /* Accessing a corrupted shared library */ +const Errno ELIBSCN = 81; /* .lib section in a.out corrupted */ +const Errno ELIBMAX = 82; /* Attempting to link in too many shared libraries */ +const Errno ELIBEXEC = 83; /* Cannot exec a shared library directly */ +const Errno EILSEQ = 84; /* Illegal byte sequence */ +const Errno ERESTART = 85; /* Interrupted system call should be restarted */ +const Errno ESTRPIPE = 86; /* Streams pipe error */ +const Errno EUSERS = 87; /* Too many users */ +const Errno ENOTSOCK = 88; /* Socket operation on non-socket */ +const Errno EDESTADDRREQ = 89; /* Destination address required */ +const Errno EMSGSIZE = 90; /* Message too long */ +const Errno EPROTOTYPE = 91; /* Protocol wrong type for socket */ +const Errno ENOPROTOOPT = 92; /* Protocol not available */ +const Errno EPROTONOSUPPORT = 93; /* Protocol not supported */ +const Errno ESOCKTNOSUPPORT = 94; /* Socket type not supported */ +const Errno EOPNOTSUPP = 95; /* Operation not supported on transport endpoint */ +const Errno EPFNOSUPPORT = 96; /* Protocol family not supported */ +const Errno EAFNOSUPPORT = 97; /* Address family not supported by protocol */ +const Errno EADDRINUSE = 98; /* Address already in use */ +const Errno EADDRNOTAVAIL = 99; /* Cannot assign requested address */ +const Errno ENETDOWN = 100; /* Network is down */ +const Errno ENETUNREACH = 101; /* Network is unreachable */ +const Errno ENETRESET = 102; /* Network dropped connection because of reset */ +const Errno ECONNABORTED = 103; /* Software caused connection abort */ +const Errno ECONNRESET = 104; /* Connection reset by peer */ +const Errno ENOBUFS = 105; /* No buffer space available */ +const Errno EISCONN = 106; /* Transport endpoint is already connected */ +const Errno ENOTCONN = 107; /* Transport endpoint is not connected */ +const Errno ESHUTDOWN = 108; /* Cannot send after transport endpoint shutdown */ +const Errno ETOOMANYREFS = 109; /* Too many references: cannot splice */ +const Errno ETIMEDOUT = 110; /* Connection timed out */ +const Errno ECONNREFUSED = 111; /* Connection refused */ +const Errno EHOSTDOWN = 112; /* Host is down */ +const Errno EHOSTUNREACH = 113; /* No route to host */ +const Errno EALREADY = 114; /* Operation already in progress */ +const Errno EINPROGRESS = 115; /* Operation now in progress */ +const Errno ESTALE = 116; /* Stale NFS file handle */ +const Errno EUCLEAN = 117; /* Structure needs cleaning */ +const Errno ENOTNAM = 118; /* Not a XENIX named type file */ +const Errno ENAVAIL = 119; /* No XENIX semaphores available */ +const Errno EISNAM = 120; /* Is a named type file */ +const Errno EREMOTEIO = 121; /* Remote I/O error */ +const Errno EDQUOT = 122; /* Quota exceeded */ + +const Errno ENOMEDIUM = 123; /* No medium found */ +const Errno EMEDIUMTYPE = 124; /* Wrong medium type */ +const Errno ECANCELED = 125; /* Operation Canceled */ +const Errno ENOKEY = 126; /* Required key not available */ +const Errno EKEYEXPIRED = 127; /* Key has expired */ +const Errno EKEYREVOKED = 128; /* Key has been revoked */ +const Errno EKEYREJECTED = 129; /* Key was rejected by service */ + +const Errno EOWNERDEAD = 130; /* Owner died */ +const Errno ENOTRECOVERABLE = 131; /* State not recoverable */ diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 9b3cb1951..ae03c1abc 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -417,9 +417,8 @@ typedef struct typedef struct { - Expr *expr; Expr **args; - uint64_t ordinal; + uint32_t ordinal; DeclId parent; } EnumConstantDecl; diff --git a/src/compiler/copying.c b/src/compiler/copying.c index a92d2f56a..748f59dd1 100644 --- a/src/compiler/copying.c +++ b/src/compiler/copying.c @@ -628,12 +628,9 @@ Decl *copy_decl(CopyStruct *c, Decl *decl) // Note that the ast id should be patched by the parent. return copy; case DECL_ENUM_CONSTANT: - MACRO_COPY_EXPR(copy->enum_constant.expr); MACRO_COPY_EXPR_LIST(copy->enum_constant.args); break; case DECL_FAULTVALUE: - MACRO_COPY_EXPR(copy->enum_constant.expr); - MACRO_COPY_EXPR_LIST(copy->enum_constant.args); break; case DECL_TYPEDEF: if (copy->typedef_decl.is_func) diff --git a/src/compiler/llvm_codegen_debug_info.c b/src/compiler/llvm_codegen_debug_info.c index 81ac154f2..c19d116ae 100644 --- a/src/compiler/llvm_codegen_debug_info.c +++ b/src/compiler/llvm_codegen_debug_info.c @@ -309,11 +309,11 @@ static LLVMMetadataRef llvm_debug_enum_type(GenContext *c, Type *type, LLVMMetad VECEACH(enums, i) { Decl *enum_constant = enums[i]; - uint64_t val = int_to_u64(enum_constant->enum_constant.expr->const_expr.ixx); + int64_t val = enum_constant->enum_constant.ordinal; LLVMMetadataRef debug_info = LLVMDIBuilderCreateEnumerator( c->debug.builder, enum_constant->name, strlen(enum_constant->name), - (int64_t)val, + val, is_unsigned); vec_add(elements, debug_info); } diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index baaeda028..85aa9ffa8 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -4004,10 +4004,8 @@ static void llvm_emit_const_expr(GenContext *c, BEValue *be_value, Expr *expr) return; } case CONST_ENUM: - { - llvm_emit_const_expr(c, be_value, expr->const_expr.enum_val->enum_constant.expr); + llvm_value_set(be_value, llvm_const_int(c, type, expr->const_expr.enum_val->enum_constant.ordinal), type); return; - } default: UNREACHABLE } diff --git a/src/compiler/number.c b/src/compiler/number.c index 9e2470bff..ad6aeb9ce 100644 --- a/src/compiler/number.c +++ b/src/compiler/number.c @@ -82,10 +82,7 @@ bool expr_const_compare(const ExprConst *left, const ExprConst *right, BinaryOp case CONST_BOOL: return compare_bool(left->b, right->b, op); case CONST_INTEGER: - if (right->const_kind == CONST_ENUM) - { - return int_comp(left->ixx, right->enum_val->enum_constant.expr->const_expr.ixx, op); - } + assert(right->const_kind != CONST_ENUM); return int_comp(left->ixx, right->ixx, op); case CONST_FLOAT: return compare_fps(left->fxx.f, right->fxx.f, op); @@ -107,15 +104,15 @@ bool expr_const_compare(const ExprConst *left, const ExprConst *right, BinaryOp case CONST_TYPEID: return left->typeid == right->typeid; case CONST_ERR: + case CONST_ENUM: { Decl *left_decl = left->err_val; // The error case - uint64_t right_ordinal; - assert(right->const_kind == CONST_ERR); + assert(right->const_kind == left->const_kind); Decl *right_decl = right->err_val; // Non matching cannot be compared. if (right_decl->type != left_decl->type) return false; - right_ordinal = right->err_val->enum_constant.ordinal; + int64_t right_ordinal = right->err_val->enum_constant.ordinal; switch (op) { case BINARYOP_GT: @@ -134,20 +131,6 @@ bool expr_const_compare(const ExprConst *left, const ExprConst *right, BinaryOp UNREACHABLE } } - case CONST_ENUM: - { - Decl *left_decl = left->enum_val; - // The enum case - Expr *left_const = left_decl->enum_constant.expr; - assert(left_const->expr_kind == EXPR_CONST); - const ExprConst *right_const = right; - if (right->const_kind == CONST_ENUM) - { - assert(right->enum_val->enum_constant.expr->expr_kind == EXPR_CONST); - right_const = &right->enum_val->enum_constant.expr->const_expr; - } - return expr_const_compare(&left_const->const_expr, right_const, op); - } case CONST_BYTES: if (left->bytes.len != right->bytes.len) { diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index ad06c20c5..e25c60d8d 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -1881,9 +1881,7 @@ static inline bool parse_enum_spec(ParseContext *c, TypeInfo **type_ref, Decl*** * * enum_def * : CAPS_IDENT - * | CAPS_IDENT '=' const_expr * | CAPS_IDENT '(' expr_list ')' - * | CAPS_IDENT '(' expr_list ')' '=' const_expr * ; * */ @@ -1930,10 +1928,6 @@ static inline Decl *parse_enum_declaration(ParseContext *c, Visibility visibilit enum_const->enum_constant.args = result; CONSUME_OR_RET(TOKEN_RPAREN, poisoned_decl); } - if (try_consume(c, TOKEN_EQ)) - { - ASSIGN_EXPR_OR_RET(enum_const->enum_constant.expr, parse_expr(c), poisoned_decl); - } vec_add(decl->enums.values, enum_const); // Allow trailing ',' if (!try_consume(c, TOKEN_COMMA)) diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index eedab9f8d..e741d12da 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -232,8 +232,26 @@ static bool int_literal_to_int(Expr *expr, Type *canonical, Type *type) bool lit_integer_to_enum(Expr *expr, Type *canonical, Type *type) { assert(canonical->type_kind == TYPE_ENUM); - canonical = type_flatten(canonical->decl->enums.type_info->type); - return int_literal_to_int(expr, canonical, type); + unsigned max_enums = vec_size(canonical->decl->enums.values); + Int to_convert = expr->const_expr.ixx; + if (int_is_neg(to_convert)) + { + SEMA_ERROR(expr, "A negative number cannot be converted to an enum."); + return false; + } + Int max = { .i.low = max_enums, .type = TYPE_I32 }; + if (int_comp(to_convert, max, BINARYOP_GE)) + { + SEMA_ERROR(expr, "This value exceeds the number of enums in %s.", canonical->decl->name); + return false; + } + Decl *decl = canonical->decl->enums.values[to_convert.i.low]; + expr->const_expr = (ExprConst) { + .enum_val = decl, + .const_kind = CONST_ENUM + }; + expr->type = type; + return true; } @@ -315,40 +333,41 @@ static bool int_to_int(Expr *left, Type *from_canonical, Type *canonical, Type * } } -static Type *enum_lowering(Expr* expr, Type *from) +static Type *enum_to_int_cast(Expr* expr, Type *from) { + assert(from->type_kind == TYPE_ENUM); + Type *original = from->decl->enums.type_info->type; + expr->type = original; if (expr->expr_kind == EXPR_CONST && expr->const_expr.const_kind == CONST_ENUM) { - expr_replace(expr, expr->const_expr.enum_val->enum_constant.expr); - assert(!IS_FAILABLE(expr)); - return expr->type; + expr_const_set_int(&expr->const_expr, expr->const_expr.enum_val->enum_constant.ordinal, type_flatten(original)->type_kind); + return original; } - Type *result = from->decl->enums.type_info->type; - insert_cast(expr, CAST_ENUMLOW, type_get_opt_fail(result, IS_FAILABLE(expr))); - return result; + insert_cast(expr, CAST_ENUMLOW, type_get_opt_fail(original, IS_FAILABLE(expr))); + return original; } static bool enum_to_integer(Expr* expr, Type *from, Type *canonical, Type *type) { - Type *result = enum_lowering(expr, from); + Type *result = enum_to_int_cast(expr, from); return int_to_int(expr, result->canonical, canonical, type); } static bool enum_to_float(Expr* expr, Type *from, Type *canonical, Type *type) { - Type *result = enum_lowering(expr, from); + Type *result = enum_to_int_cast(expr, from); return int_to_float(expr, type_is_unsigned(result->canonical) ? CAST_UIFP : CAST_SIFP, canonical, type); } bool enum_to_bool(Expr* expr, Type *from, Type *type) { - enum_lowering(expr, from); + enum_to_int_cast(expr, from); return integer_to_bool(expr, type); } bool enum_to_pointer(Expr* expr, Type *from, Type *type) { - enum_lowering(expr, from); + enum_to_int_cast(expr, from); return int_to_pointer(expr, type); } @@ -462,12 +481,12 @@ bool cast_may_explicit(Type *from_type, Type *to_type, bool ignore_failability, case ALL_UNSIGNED_INTS: // We don't have to match pointer size if it's a constant. if (to_kind == TYPE_POINTER && is_const) return true; + if (to_kind == TYPE_POINTER && type_is_pointer_sized(from_type)) return true; + if (to_kind == TYPE_ENUM) return true; FALLTHROUGH; case TYPE_ENUM: - // Allow conversion int/enum -> float/bool/enum int/enum -> pointer is only allowed if the int/enum is pointer sized. - if (type_is_integer(to_type) || type_is_float(to_type) || to_type == type_bool || to_kind == TYPE_ENUM) return true; - // TODO think about this, maybe we should require a bitcast? - if (to_kind == TYPE_POINTER && type_is_pointer_sized(from_type)) return true; + // Allow conversion int/enum -> float/bool/int + if (type_is_integer(to_type) || type_is_float(to_type) || to_type == type_bool) return true; return false; case ALL_FLOATS: // Allow conversion float -> float/int/bool/enum @@ -1312,7 +1331,7 @@ bool cast(Expr *expr, Type *to_type) assert(!type_is_failable(to_type)); Type *from_type = expr->type; bool from_is_failable = false; - Type *to = type_flatten(to_type); + Type *to = type_flatten_distinct(to_type); // Special case *! => error if (to == type_anyerr || to->type_kind == TYPE_FAULTTYPE) @@ -1347,8 +1366,8 @@ bool cast(Expr *expr, Type *to_type) } return true; } - bool result = cast_inner(expr, from_type, to, to_type); - assert(result == true); + + if (!cast_inner(expr, from_type, to, to_type)) return false; Type *result_type = expr->type; if (from_is_failable && !type_is_failable(result_type)) diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 016ed2d74..d44e4b8e2 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -795,56 +795,22 @@ static inline bool sema_analyse_enum(SemaContext *context, Decl *decl) // Start evaluating the constant enum_value->resolve_status = RESOLVE_RUNNING; - Expr *expr = enum_value->enum_constant.expr; // Create a "fake" expression. // This will be evaluated later to catch the case - if (!expr) + Int val = (Int){ value, canonical->type_kind }; + if (!int_fits(val, canonical->type_kind)) { - expr = expr_new(EXPR_CONST, enum_value->span); - expr->type = type; - expr->resolve_status = RESOLVE_NOT_DONE; - expr->const_expr.ixx = (Int) { value, canonical->type_kind }; - if (expr_const_will_overflow(&expr->const_expr, canonical->type_kind)) - { - SEMA_ERROR(enum_value, - "The enum value would implicitly be %s which does not fit in %s.", - i128_to_string(value, 10, type_is_signed(canonical)), - type_quoted_error_string(type)); - return false; - } - expr->const_expr.const_kind = CONST_INTEGER; - expr->const_expr.narrowable = true; - expr->type = canonical; - enum_value->enum_constant.expr = expr; - } - - // We try to convert to the desired type. - if (!sema_analyse_expr_rhs(context, type, expr, false)) - { - success = false; - enum_value->resolve_status = RESOLVE_DONE; - decl_poison(enum_value); - // Reset! - value = (Int128) { 0, 0 }; - continue; - } - - assert(type_is_integer(expr->type->canonical)); - - // Here we might have a non-constant value, - if (expr->expr_kind != EXPR_CONST) - { - SEMA_ERROR(expr, "Expected a constant expression for enum."); - decl_poison(enum_value); - success = false; - // Skip one value. - continue; + SEMA_ERROR(enum_value, + "The enum value would implicitly be %s which does not fit in %s.", + i128_to_string(value, 10, type_is_signed(canonical)), + type_quoted_error_string(type)); + return false; } + enum_value->enum_constant.ordinal = value.low; // Update the value - value = i128_add64(expr->const_expr.ixx.i, 1); - DEBUG_LOG("* Value: %s", expr_const_to_error_string(&expr->const_expr)); + value.low++; enum_value->resolve_status = RESOLVE_DONE; } return success; diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 2c91fff3e..5c011a73d 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -622,7 +622,8 @@ static inline bool sema_cast_ident_rvalue(SemaContext *context, Expr *expr) SEMA_ERROR(expr, "Did you forget a '!' after '%s'?", decl->name); return expr_poison(expr); case DECL_ENUM_CONSTANT: - expr_replace(expr, decl->enum_constant.expr); + TODO + //expr_replace(expr, decl->enum_constant.expr); return true; case DECL_VAR: break; @@ -2946,28 +2947,6 @@ static void add_members_to_context(SemaContext *context, Decl *decl) } } -static Expr *enum_minmax_value(Decl *decl, BinaryOp comparison) -{ - assert(decl->decl_kind == DECL_ENUM); - bool is_signed = type_is_signed(decl->enums.type_info->type->canonical); - Expr *expr = NULL; - VECEACH(decl->enums.values, i) - { - Decl *enum_constant = decl->enums.values[i]; - Expr *candidate = enum_constant->enum_constant.expr; - assert(candidate->expr_kind == EXPR_CONST); - if (!expr) - { - expr = candidate; - continue; - } - if (expr_const_compare(&candidate->const_expr, &expr->const_expr, comparison)) - { - expr = candidate; - } - } - return expr; -} /** * 1. .A -> It is an enum constant. @@ -3127,34 +3106,12 @@ static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *exp expr_rewrite_to_int_const(expr, type_isize, vec_size(decl->enums.values), true); return true; } - if (name == kw_max) - { - Expr *max = enum_minmax_value(decl, BINARYOP_GT); - if (!max) - { - expr_rewrite_to_int_const(expr, decl->enums.type_info->type->canonical, 0, false); - return true; - } - expr_replace(expr, max); - return true; - } if (name == kw_values) { expr_replace_with_enum_array(expr, decl); return sema_analyse_expr(context, expr); return true; } - if (name == kw_min) - { - Expr *min = enum_minmax_value(decl, BINARYOP_LT); - if (!min) - { - expr_rewrite_to_int_const(expr, decl->enums.type_info->type->canonical, 0, false); - return true; - } - expr_replace(expr, min); - return true; - } break; case DECL_FAULT: unit_register_external_symbol(context->compilation_unit, decl); @@ -3173,28 +3130,6 @@ static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *exp expr_rewrite_to_int_const(expr, type_isize, vec_size(decl->enums.values), true); return true; } - if (name == kw_max) - { - Expr *max = enum_minmax_value(decl, BINARYOP_GT); - if (!max) - { - expr_rewrite_to_int_const(expr, decl->enums.type_info->type->canonical, 0, false); - return true; - } - expr_replace(expr, max); - return true; - } - if (name == kw_min) - { - Expr *min = enum_minmax_value(decl, BINARYOP_LT); - if (!min) - { - expr_rewrite_to_int_const(expr, decl->enums.type_info->type->canonical, 0, false); - return true; - } - expr_replace(expr, min); - return true; - } break; case DECL_UNION: case DECL_STRUCT: @@ -3377,6 +3312,16 @@ CHECK_DEEPER: } } + if (!is_macro && kw == kw_ordinal) + { + if (type->type_kind == TYPE_ENUM) + { + if (!cast(parent, type->decl->enums.type_info->type)) return false; + expr_replace(expr, parent); + return true; + } + } + // 9. At this point we may only have distinct, struct, union, error, enum if (!type_may_have_sub_elements(type)) { @@ -4353,7 +4298,10 @@ static inline bool sema_expr_analyse_cast(SemaContext *context, Expr *expr) { return sema_failed_cast(expr, type_no_fail(inner->type), target_type); } - cast(inner, target_type); + if (!cast(inner, target_type)) + { + return expr_poison(expr); + } expr_replace(expr, inner); return true; } diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index c9db83bef..f1a1de2f3 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -1683,12 +1683,15 @@ static inline ExprConst *flatten_enum_const(Expr *expr) if (const_expr->const_kind == CONST_ENUM) { const_expr->const_kind = CONST_INTEGER; + Decl *enum_val = const_expr->enum_val; - Expr *enum_expr = enum_val->enum_constant.expr; + TODO + /* + Expr *enum_expr = exprptr(enum_val->enum_constant.ordinal2); assert(enum_expr->expr_kind == EXPR_CONST); ExprConst *enum_const = &enum_expr->const_expr; assert(enum_const->const_kind == CONST_INTEGER); - *const_expr = *enum_const; + *const_expr = *enum_const;*/ } return const_expr; } @@ -1707,25 +1710,39 @@ static inline bool sema_check_value_case(SemaContext *context, Type *switch_type *if_chained = true; return true; } - ExprConst *const_expr = flatten_enum_const(expr); - ExprConst *to_const_expr = to_expr ? flatten_enum_const(to_expr) : const_expr; + ExprConst *const_expr = &expr->const_expr; + ExprConst *to_const_expr = to_expr ? &to_expr->const_expr : const_expr; - if (!*max_ranged && type_is_integer(expr->type) && to_const_expr != const_expr) + if (!*max_ranged && to_const_expr != const_expr) { - if (int_comp(const_expr->ixx, to_const_expr->ixx, BINARYOP_GT)) + if (const_expr->const_kind == CONST_ENUM) { - sema_error_at(extend_span_with_token(expr->span, to_expr->span), - "The range is not valid because the first value (%s) is greater than the second (%s). " - "It would work if you swapped their order.", - int_to_str(const_expr->ixx, 10), - int_to_str(to_const_expr->ixx, 10)); - return false; + assert(to_const_expr->const_kind == CONST_ENUM); + if (to_const_expr->enum_val->enum_constant.ordinal < const_expr->enum_val->enum_constant.ordinal) + { + sema_error_at(extend_span_with_token(expr->span, to_expr->span), + "A enum range must be have the enum with a lower ordinal followed by the one with a higher ordinal. " + "It would work if you swapped their order."); + return false; + } } - Int128 range = int_sub(to_const_expr->ixx, const_expr->ixx).i; - Int128 max_range = { .low = active_target.switchrange_max_size }; - if (i128_comp(range, max_range, type_i128) == CMP_GT) + else if (type_is_integer(expr->type)) { - *max_ranged = true; + if (int_comp(const_expr->ixx, to_const_expr->ixx, BINARYOP_GT)) + { + sema_error_at(extend_span_with_token(expr->span, to_expr->span), + "The range is not valid because the first value (%s) is greater than the second (%s). " + "It would work if you swapped their order.", + int_to_str(const_expr->ixx, 10), + int_to_str(to_const_expr->ixx, 10)); + return false; + } + Int128 range = int_sub(to_const_expr->ixx, const_expr->ixx).i; + Int128 max_range = { .low = active_target.switchrange_max_size }; + if (i128_comp(range, max_range, type_i128) == CMP_GT) + { + *max_ranged = true; + } } } for (unsigned i = 0; i < index; i++) @@ -1765,6 +1782,7 @@ static bool sema_analyse_switch_body(SemaContext *context, Ast *statement, Sourc bool type_switch = switch_type == type_typeid; for (unsigned i = 0; i < case_count; i++) { + if (!success) break; Ast *stmt = cases[i]; Ast *next = (i < case_count - 1) ? cases[i + 1] : NULL; PUSH_NEXT(next, statement); diff --git a/test/test_suite/enumerations/compile_time.c3t b/test/test_suite/enumerations/compile_time.c3t index bc26ed669..e014657f8 100644 --- a/test/test_suite/enumerations/compile_time.c3t +++ b/test/test_suite/enumerations/compile_time.c3t @@ -1,20 +1,16 @@ enum MyEnum : short { - HELO = 12, - WORLD = 14, - BYE = -5 + HELO, + WORLD, + BYE } -int myenum_max = MyEnum.max; -int myenum_min = MyEnum.min; int myenum_elements = MyEnum.elements; int myenum_alignof = $alignof(MyEnum); int myenum_sizeof = MyEnum.sizeof; // #expect: compile_time.ll -@compile_time.myenum_max = local_unnamed_addr global i32 14, align 4 -@compile_time.myenum_min = local_unnamed_addr global i32 -5, align 4 @compile_time.myenum_elements = local_unnamed_addr global i32 3, align 4 @compile_time.myenum_alignof = local_unnamed_addr global i32 2, align 4 @compile_time.myenum_sizeof = local_unnamed_addr global i32 2, align 4 \ No newline at end of file diff --git a/test/test_suite/enumerations/enum_cast.c3t b/test/test_suite/enumerations/enum_cast.c3t index d4daae2ca..7a6b98b46 100644 --- a/test/test_suite/enumerations/enum_cast.c3t +++ b/test/test_suite/enumerations/enum_cast.c3t @@ -3,9 +3,17 @@ module test; enum MyEnum : char { - FOO = 3, - BAR = 100 + FOO, + BAR } + +fn void test2() +{ + char ww = MyEnum.FOO.ordinal; + MyEnum x = MyEnum.BAR; + char zz = x.ordinal; +} + fn void test() { char b = MyEnum.FOO; @@ -22,10 +30,23 @@ fn void test() MyEnum! xf = MyEnum.BAR; float! e = (float)(x); e = (float)(xf); + } /* #expect: test.ll +define void @test.test2() #0 { +entry: + %ww = alloca i8, align 1 + %x = alloca i8, align 1 + %zz = alloca i8, align 1 + store i8 0, i8* %ww, align 1 + store i8 1, i8* %x, align 1 + %0 = load i8, i8* %x, align 1 + store i8 %0, i8* %zz, align 1 + ret void +} + define void @test.test() #0 { entry: %b = alloca i8, align 1 @@ -39,17 +60,17 @@ entry: %xf.f = alloca i64, align 8 %e = alloca float, align 4 %e.f = alloca i64, align 8 - store i8 3, i8* %b, align 1 - store i32 100, i32* %z, align 4 - store i8 100, i8* %x, align 1 + store i8 0, i8* %b, align 1 + store i32 1, i32* %z, align 4 + store i8 1, i8* %x, align 1 %0 = load i8, i8* %x, align 1 store i8 %0, i8* %b2, align 1 %1 = load i8, i8* %x, align 1 %uisiext = zext i8 %1 to i32 store i32 %uisiext, i32* %z2, align 4 - store float 3.000000e+00, float* %d, align 4 - store i8 1, i8* %hello, align 1 - store i8 100, i8* %xf, align 1 + store float 0.000000e+00, float* %d, align 4 + store i8 0, i8* %hello, align 1 + store i8 1, i8* %xf, align 1 store i64 0, i64* %xf.f, align 8 %2 = load i8, i8* %x, align 1 %uifp = uitofp i8 %2 to float @@ -75,4 +96,6 @@ after_assign: ; preds = %after_check, %error voiderr: ; preds = %after_assign ret void -} \ No newline at end of file +} + +attributes #0 = { nounwind } \ No newline at end of file diff --git a/test/test_suite/enumerations/enum_values.c3t b/test/test_suite/enumerations/enum_values.c3t index 26e18c0e2..74b2f190f 100644 --- a/test/test_suite/enumerations/enum_values.c3t +++ b/test/test_suite/enumerations/enum_values.c3t @@ -4,12 +4,10 @@ module test; enum Foo { - ABC = 3, - BCD = 123 + ABC, + BCD } -int z = Foo.min; -int w = Foo.max; Foo zfok = Foo.values[0]; Foo[] zw = &&Foo.values; @@ -22,10 +20,8 @@ fn void test(int x) %"Foo[]" = type { i32*, i64 } -@test.z = local_unnamed_addr global i32 3, align 4 -@test.w = local_unnamed_addr global i32 123, align 4 -@test.zfok = local_unnamed_addr global i32 3, align 4 -@.taddr = private global [2 x i32] [i32 3, i32 123], align 4 +@test.zfok = local_unnamed_addr global i32 0, align 4 +@.taddr = private global [2 x i32] [i32 0, i32 1], align 4 @test.zw = local_unnamed_addr global %"Foo[]" { i32* getelementptr inbounds ([2 x i32], [2 x i32]* @.taddr, i32 0, i32 0), i64 2 }, align 8 define void @test.test(i32 %0) #0 { @@ -33,9 +29,9 @@ entry: %zonk = alloca i32, align 4 %literal = alloca [2 x i32], align 4 %1 = getelementptr inbounds [2 x i32], [2 x i32]* %literal, i64 0, i64 0 - store i32 3, i32* %1, align 4 + store i32 0, i32* %1, align 4 %2 = getelementptr inbounds [2 x i32], [2 x i32]* %literal, i64 0, i64 1 - store i32 123, i32* %2, align 4 + store i32 1, i32* %2, align 4 %sisiext = sext i32 %0 to i64 %3 = getelementptr inbounds [2 x i32], [2 x i32]* %literal, i64 0, i64 %sisiext %4 = load i32, i32* %3, align 4 diff --git a/test/test_suite/expressions/casts/cast_enum_to_various.c3 b/test/test_suite/expressions/casts/cast_enum_to_various.c3 index e943e167c..2da5c9758 100644 --- a/test/test_suite/expressions/casts/cast_enum_to_various.c3 +++ b/test/test_suite/expressions/casts/cast_enum_to_various.c3 @@ -34,6 +34,6 @@ fn void test2(Enum e) fn void test3(Enum e) { - EnumB h = (EnumB)(e); + EnumB h = (EnumB)(e); // #error: 'Enum' to 'EnumB' is not allowed Func i = (Func)(e); // #error: cast 'Enum' to 'Func' } diff --git a/test/test_suite/from_docs/examples_forswitch.c3t b/test/test_suite/from_docs/examples_forswitch.c3t index d31d6a605..7f8a441b0 100644 --- a/test/test_suite/from_docs/examples_forswitch.c3t +++ b/test/test_suite/from_docs/examples_forswitch.c3t @@ -20,7 +20,7 @@ fn void example_for() enum Height : uint { - LOW = 0, + LOW, MEDIUM, HIGH, } diff --git a/test/test_suite/functions/test_regression.c3t b/test/test_suite/functions/test_regression.c3t index 255803b94..83e9eb69e 100644 --- a/test/test_suite/functions/test_regression.c3t +++ b/test/test_suite/functions/test_regression.c3t @@ -107,9 +107,9 @@ define IntList = LinkedList; enum MyEnum : int { - HELO = 12, - WORLD = 14, - BYE = -5 + HELO, + WORLD, + BYE } @@ -129,10 +129,8 @@ fn void main() } list.free(); - printf("Min %d Max %d Elements: %d\n", MyEnum.min, MyEnum.max, (int)(MyEnum.elements)); + printf("Elements: %d\n", (int)(MyEnum.elements)); - int maxv = MyEnum.max; - int minv = MyEnum.min; int elements = MyEnum.elements; printf("Hello\n"); IntArray array; @@ -211,8 +209,8 @@ fault MyErr enum Hello : int { - FOO = 3, - BAR = 4, + FOO, + BAR, } macro Hello wut() @@ -431,8 +429,6 @@ define void @test.main() #0 { entry: %list = alloca %LinkedList, align 8 %i = alloca i32, align 4 - %maxv = alloca i32, align 4 - %minv = alloca i32, align 4 %elements = alloca i32, align 4 %array = alloca %List, align 8 %i1 = alloca i32, align 4 @@ -486,9 +482,7 @@ loop.body: ; preds = %loop.cond loop.exit: ; preds = %loop.cond call void @"std::array::linkedlist.int.LinkedList__free"(%LinkedList* %list) - %11 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str.3, i32 0, i32 0), i32 -5, i32 14, i32 3) - store i32 14, i32* %maxv, align 4 - store i32 -5, i32* %minv, align 4 + %11 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.3, i32 0, i32 0), i32 3) store i32 3, i32* %elements, align 4 %12 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.4, i32 0, i32 0)) %13 = bitcast %List* %array to i8* diff --git a/test/test_suite/functions/test_regression_mingw.c3t b/test/test_suite/functions/test_regression_mingw.c3t index 62eb489c9..85cef878c 100644 --- a/test/test_suite/functions/test_regression_mingw.c3t +++ b/test/test_suite/functions/test_regression_mingw.c3t @@ -109,9 +109,9 @@ define IntList = LinkedList; enum MyEnum : int { - HELO = 12, - WORLD = 14, - BYE = -5 + HELO, + WORLD, + BYE } @@ -131,10 +131,8 @@ fn void main() } list.free(); - printf("Min %d Max %d Elements: %d\n", MyEnum.min, MyEnum.max, (int)(MyEnum.elements)); + printf("Elements: %d\n", (int)(MyEnum.elements)); - int maxv = MyEnum.max; - int minv = MyEnum.min; int elements = MyEnum.elements; printf("Hello\n"); IntArray array; @@ -213,8 +211,8 @@ fault MyErr enum Hello : int { - FOO = 3, - BAR = 4, + FOO, + BAR, } macro Hello wut() @@ -268,7 +266,7 @@ $introspect.Foo = comdat any @.str.1 = private unnamed_addr constant [16 x i8] c"Test static %d\0A\00", align 1 @.__const = private unnamed_addr constant [3 x i32] [i32 1, i32 2, i32 3], align 4 @.str.2 = private unnamed_addr constant [17 x i8] c"Element[%d]: %d\0A\00", align 1 -@.str.3 = private unnamed_addr constant [28 x i8] c"Min %d Max %d Elements: %d\0A\00", align 1 +@.str.3 = private unnamed_addr constant [14 x i8] c"Elements: %d\0A\00", align 1 @.str.4 = private unnamed_addr constant [7 x i8] c"Hello\0A\00", align 1 @.str.5 = private unnamed_addr constant [17 x i8] c"Element[%d]: %d\0A\00", align 1 @.__const.6 = private unnamed_addr constant %Blob.0 { i32 42 }, align 4 @@ -464,8 +462,6 @@ define void @test.main() #0 { entry: %list = alloca %LinkedList, align 8 %i = alloca i32, align 4 - %maxv = alloca i32, align 4 - %minv = alloca i32, align 4 %elements = alloca i32, align 4 %array = alloca %List, align 8 %i1 = alloca i32, align 4 @@ -525,9 +521,7 @@ loop.body: ; preds = %loop.cond loop.exit: ; preds = %loop.cond call void @"std::array::linkedlist.int.LinkedList__free"(%LinkedList* %list) - %11 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str.3, i32 0, i32 0), i32 -5, i32 14, i32 3) - store i32 14, i32* %maxv, align 4 - store i32 -5, i32* %minv, align 4 + %11 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.3, i32 0, i32 0), i32 3) store i32 3, i32* %elements, align 4 %12 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.4, i32 0, i32 0)) %13 = bitcast %List* %array to i8* diff --git a/test/test_suite/statements/switch_errors.c3 b/test/test_suite/statements/switch_errors.c3 index f3bfdbb33..995dcd023 100644 --- a/test/test_suite/statements/switch_errors.c3 +++ b/test/test_suite/statements/switch_errors.c3 @@ -18,7 +18,7 @@ fn void test_other_enum() break; case B: break; - case Bar.B: // #error: 'Bar' to 'Foo' + case Bar.B: // #error: 'Bar' into 'Foo' break; } } @@ -28,7 +28,7 @@ fn void test_check_nums() Foo f = A; switch (f) { - case (Foo)(2): + case (Foo)(1): break; case (Foo)(0): break; @@ -66,7 +66,7 @@ fn void test_duplicate_case2(Foo i) { case A: break; - case (Foo)(2): + case (Foo)(1): break; case A: // #error: same case value appears break; diff --git a/test/test_suite/symbols/various.c3 b/test/test_suite/symbols/various.c3 index f78a6ae5e..b6b381c6f 100644 --- a/test/test_suite/symbols/various.c3 +++ b/test/test_suite/symbols/various.c3 @@ -75,7 +75,7 @@ fn void test10() enum Enum : int { - A = 127, + A, B, } diff --git a/test/test_suite/types/enum_errors.c3 b/test/test_suite/types/enum_errors.c3 deleted file mode 100644 index 5c7b7bc5b..000000000 --- a/test/test_suite/types/enum_errors.c3 +++ /dev/null @@ -1,17 +0,0 @@ - -enum EnumTestErrorType3 : int -{ - A = FOO // #error: 'FOO' could not be found, did you spell it -} - -fn int foo() -{ - return 10; -} - -enum State -{ - A = foo(), // #error: Expected a constant expression for enum - B = "hello", // #error: 'char[5]*' into 'int' - C = true, // #error: 'bool' to 'int' -} diff --git a/test/test_suite/types/enum_implicit_overflow.c3 b/test/test_suite/types/enum_implicit_overflow.c3 index 318592e58..aa64a25ae 100644 --- a/test/test_suite/types/enum_implicit_overflow.c3 +++ b/test/test_suite/types/enum_implicit_overflow.c3 @@ -1,5 +1,136 @@ -enum Foo : char +enum Foo : ichar { - MY_VAL1 = 255, - MY_VAL2, // #error: The enum value would implicitly be 256 which does not fit in 'char' + MY_VAL0, + MY_VAL1, + MY_VAL2, + MY_VAL3, + MY_VAL4, + MY_VAL5, + MY_VAL6, + MY_VAL7, + MY_VAL8, + MY_VAL9, + MY_VAL10, + MY_VAL11, + MY_VAL12, + MY_VAL13, + MY_VAL14, + MY_VAL15, + MY_VAL16, + MY_VAL17, + MY_VAL18, + MY_VAL19, + MY_VAL20, + MY_VAL21, + MY_VAL22, + MY_VAL23, + MY_VAL24, + MY_VAL25, + MY_VAL26, + MY_VAL27, + MY_VAL28, + MY_VAL29, + MY_VAL30, + MY_VAL31, + MY_VAL32, + MY_VAL33, + MY_VAL34, + MY_VAL35, + MY_VAL36, + MY_VAL37, + MY_VAL38, + MY_VAL39, + MY_VAL40, + MY_VAL41, + MY_VAL42, + MY_VAL43, + MY_VAL44, + MY_VAL45, + MY_VAL46, + MY_VAL47, + MY_VAL48, + MY_VAL49, + MY_VAL50, + MY_VAL51, + MY_VAL52, + MY_VAL53, + MY_VAL54, + MY_VAL55, + MY_VAL56, + MY_VAL57, + MY_VAL58, + MY_VAL59, + MY_VAL60, + MY_VAL61, + MY_VAL62, + MY_VAL63, + MY_VAL64, + MY_VAL65, + MY_VAL66, + MY_VAL67, + MY_VAL68, + MY_VAL69, + MY_VAL70, + MY_VAL71, + MY_VAL72, + MY_VAL73, + MY_VAL74, + MY_VAL75, + MY_VAL76, + MY_VAL77, + MY_VAL78, + MY_VAL79, + MY_VAL80, + MY_VAL81, + MY_VAL82, + MY_VAL83, + MY_VAL84, + MY_VAL85, + MY_VAL86, + MY_VAL87, + MY_VAL88, + MY_VAL89, + MY_VAL90, + MY_VAL91, + MY_VAL92, + MY_VAL93, + MY_VAL94, + MY_VAL95, + MY_VAL96, + MY_VAL97, + MY_VAL98, + MY_VAL99, + MY_VAL100, + MY_VAL101, + MY_VAL102, + MY_VAL103, + MY_VAL104, + MY_VAL105, + MY_VAL106, + MY_VAL107, + MY_VAL108, + MY_VAL109, + MY_VAL110, + MY_VAL111, + MY_VAL112, + MY_VAL113, + MY_VAL114, + MY_VAL115, + MY_VAL116, + MY_VAL117, + MY_VAL118, + MY_VAL119, + MY_VAL120, + MY_VAL121, + MY_VAL122, + MY_VAL123, + MY_VAL124, + MY_VAL125, + MY_VAL126, + MY_VAL127, + MY_VAL128, // #error: The enum value would implicitly be 128 which does not fit in 'ichar' + MY_VAL129, + + + } \ No newline at end of file diff --git a/test/test_suite/types/enum_inference.c3 b/test/test_suite/types/enum_inference.c3 index 80b6e20ef..6899a879e 100644 --- a/test/test_suite/types/enum_inference.c3 +++ b/test/test_suite/types/enum_inference.c3 @@ -3,14 +3,14 @@ enum Inf { A, B, - C = 10000 + C } enum Inf2 : char { A, B, - C = 129, + C, } define BooInf = Inf; @@ -34,7 +34,7 @@ fn void enumInferenceTest() return; case B: return; - case (Inf2)(111): + case (Inf2)(2): x1 += 1; return; default: diff --git a/test/test_suite/types/enum_ok.c3 b/test/test_suite/types/enum_ok.c3 index 318822428..ed54853b2 100644 --- a/test/test_suite/types/enum_ok.c3 +++ b/test/test_suite/types/enum_ok.c3 @@ -1,6 +1,6 @@ enum EnumTest : long { - VALUE1 = 4, + VALUE1, VALUE2 } @@ -8,7 +8,7 @@ define Frob = long; enum EnumTestAlias : Frob { - VALUE1 = 4, + VALUE1, VALUE2 } @@ -18,17 +18,6 @@ enum EnumTestDefault VALUE2 } -enum EnumTestNoOverflowAfterLong : long -{ - VALUE = 0x7FFF_FFFF_FFFF_FFFE, - VALUE_NO_EXCEED -} - -enum EnumTestSmall : ushort -{ - VALUE = 0xFF, - VALUE2 = 0xFFFF -} enum EnumWithErrorData2 : int (int bar, ) { @@ -41,6 +30,6 @@ enum EnumTestErrorType4 enum EnumTest5 { - B = 0, + B, C, } \ No newline at end of file diff --git a/test/test_suite/types/enum_overflow.c3 b/test/test_suite/types/enum_overflow.c3 deleted file mode 100644 index ce13cbe10..000000000 --- a/test/test_suite/types/enum_overflow.c3 +++ /dev/null @@ -1,4 +0,0 @@ -enum EnumTestOverflow -{ - VALUE = 0x80000000i64, // #error: Cannot narrow 'long' to 'int' -} \ No newline at end of file