mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Updated membersof. "Type.kind" renamed "Type.kindof"
This commit is contained in:
committed by
Christoffer Lerno
parent
f010f6a926
commit
bb20a38cdb
@@ -103,7 +103,7 @@ macro bitcast(expr, $Type) @builtin
|
||||
}
|
||||
|
||||
/**
|
||||
* @require $Type.kind == TypeKind.ENUM `Only enums may be used`
|
||||
* @require $Type.kindof == TypeKind.ENUM `Only enums may be used`
|
||||
**/
|
||||
macro enum_by_name($Type, char[] enum_name) @builtin
|
||||
{
|
||||
|
||||
@@ -51,10 +51,10 @@ macro void clear(void* dst, usize len, usize $dst_align = 0, bool $is_volatile =
|
||||
}
|
||||
|
||||
/**
|
||||
* @require $typeof(a).kind == TypeKind.SUBARRAY || $typeof(a).kind == TypeKind.POINTER
|
||||
* @require $typeof(b).kind == TypeKind.SUBARRAY || $typeof(b).kind == TypeKind.POINTER
|
||||
* @require $typeof(a).kind != TypeKind.SUBARRAY || len == -1
|
||||
* @require $typeof(a).kind != TypeKind.POINTER || len > -1
|
||||
* @require $typeof(a).kindof == TypeKind.SUBARRAY || $typeof(a).kindof == TypeKind.POINTER
|
||||
* @require $typeof(b).kindof == TypeKind.SUBARRAY || $typeof(b).kindof == TypeKind.POINTER
|
||||
* @require $typeof(a).kindof != TypeKind.SUBARRAY || len == -1
|
||||
* @require $typeof(a).kindof != TypeKind.POINTER || len > -1
|
||||
* @checked (a = b), (b = a)
|
||||
**/
|
||||
macro bool equals(a, b, isize len = -1, usize $align = 0)
|
||||
@@ -64,7 +64,7 @@ macro bool equals(a, b, isize len = -1, usize $align = 0)
|
||||
$endif;
|
||||
void* x = void;
|
||||
void* y = void;
|
||||
$if ($typeof(a).kind == TypeKind.SUBARRAY):
|
||||
$if ($typeof(a).kindof == TypeKind.SUBARRAY):
|
||||
len = a.len;
|
||||
if (len != b.len) return false;
|
||||
x = a.ptr;
|
||||
|
||||
@@ -8,18 +8,18 @@ fault ConversionResult
|
||||
VALUE_OUT_OF_UNSIGNED_RANGE,
|
||||
}
|
||||
/**
|
||||
* @require $Type.kind.is_int() || $Type.kind == TypeKind.ENUM "Argument was not an integer"
|
||||
* @require $Type.kindof.is_int() || $Type.kindof == TypeKind.ENUM "Argument was not an integer"
|
||||
**/
|
||||
macro variant_to_int(variant v, $Type)
|
||||
{
|
||||
typeid variant_type = v.type;
|
||||
TypeKind kind = variant_type.kind;
|
||||
TypeKind kind = variant_type.kindof;
|
||||
if (kind == TypeKind.ENUM)
|
||||
{
|
||||
variant_type = variant_type.inner;
|
||||
kind = variant_type.kind;
|
||||
kind = variant_type.kindof;
|
||||
}
|
||||
bool is_mixed_signed = $Type.kind != variant_type.kind;
|
||||
bool is_mixed_signed = $Type.kindof != variant_type.kindof;
|
||||
$Type max = $Type.max;
|
||||
$Type min = $Type.min;
|
||||
switch (variant_type)
|
||||
@@ -83,7 +83,7 @@ macro variant_to_int(variant v, $Type)
|
||||
|
||||
macro bool is_numerical($Type)
|
||||
{
|
||||
var $kind = $Type.kind;
|
||||
var $kind = $Type.kindof;
|
||||
$if ($kind == TypeKind.DISTINCT):
|
||||
return is_numerical($Type.inner);
|
||||
$else:
|
||||
@@ -104,7 +104,7 @@ macro bool is_indexable($Type)
|
||||
|
||||
macro bool is_comparable($Type)
|
||||
{
|
||||
var $kind = $Type.kind;
|
||||
var $kind = $Type.kindof;
|
||||
$if ($kind == TypeKind.DISTINCT):
|
||||
return is_comparable($Type.inner);
|
||||
$else:
|
||||
@@ -121,11 +121,11 @@ macro bool is_equatable($Type)
|
||||
|
||||
macro bool is_subarray_convertable($Type)
|
||||
{
|
||||
$switch ($Type.kind):
|
||||
$switch ($Type.kindof):
|
||||
$case SUBARRAY:
|
||||
return true;
|
||||
$case POINTER:
|
||||
return $Type.inner.kind == TypeKind.ARRAY;
|
||||
return $Type.inner.kindof == TypeKind.ARRAY;
|
||||
$default:
|
||||
return false;
|
||||
$endswitch;
|
||||
@@ -133,12 +133,12 @@ macro bool is_subarray_convertable($Type)
|
||||
|
||||
macro bool is_intlike($Type)
|
||||
{
|
||||
$switch ($Type.kind):
|
||||
$switch ($Type.kindof):
|
||||
$case SIGNED_INT:
|
||||
$case UNSIGNED_INT:
|
||||
return true;
|
||||
$case VECTOR:
|
||||
return $Type.inner.kind == TypeKind.SIGNED_INT || $Type.inner.kind == TypeKind.UNSIGNED_INT;
|
||||
return $Type.inner.kindof == TypeKind.SIGNED_INT || $Type.inner.kindof == TypeKind.UNSIGNED_INT;
|
||||
$default:
|
||||
return false;
|
||||
$endswitch;
|
||||
@@ -146,11 +146,11 @@ macro bool is_intlike($Type)
|
||||
|
||||
macro bool is_floatlike($Type)
|
||||
{
|
||||
$switch ($Type.kind):
|
||||
$switch ($Type.kindof):
|
||||
$case FLOAT:
|
||||
return true;
|
||||
$case VECTOR:
|
||||
return $Type.inner.kind == TypeKind.FLOAT;
|
||||
return $Type.inner.kindof == TypeKind.FLOAT;
|
||||
$default:
|
||||
return false;
|
||||
$endswitch;
|
||||
@@ -158,7 +158,7 @@ macro bool is_floatlike($Type)
|
||||
|
||||
macro bool is_vector($Type)
|
||||
{
|
||||
return $Type.kind == TypeKind.VECTOR;
|
||||
return $Type.kindof == TypeKind.VECTOR;
|
||||
}
|
||||
|
||||
macro bool is_same($TypeA, $TypeB)
|
||||
|
||||
@@ -27,7 +27,7 @@ private fn NtoaType int_from_variant(variant arg, bool *is_neg)
|
||||
}
|
||||
$endif;
|
||||
|
||||
if (arg.type.kind == TypeKind.POINTER)
|
||||
if (arg.type.kindof == TypeKind.POINTER)
|
||||
{
|
||||
return (NtoaType)(uptr)*(void**)arg.ptr;
|
||||
}
|
||||
@@ -84,7 +84,7 @@ private fn FloatType float_from_variant(variant arg)
|
||||
if (arg.type == float16.typeid) return *((float16*)arg.ptr);
|
||||
$endif;
|
||||
|
||||
if (arg.type.kind == TypeKind.POINTER)
|
||||
if (arg.type.kindof == TypeKind.POINTER)
|
||||
{
|
||||
return (FloatType)(uptr)(void*)arg.ptr;
|
||||
}
|
||||
@@ -565,7 +565,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 (!val.type.kind.is_int()) return FormattingFault.INVALID_WIDTH_ARG!;
|
||||
if (!val.type.kindof.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;
|
||||
|
||||
@@ -133,7 +133,7 @@ macro bool! Formatter.print_with_function(Formatter* this, variant arg)
|
||||
}
|
||||
private fn void! Formatter.out_str(Formatter* this, variant arg)
|
||||
{
|
||||
switch (arg.type.kind)
|
||||
switch (arg.type.kindof)
|
||||
{
|
||||
case TYPEID:
|
||||
return this.out_substr("<typeid>");
|
||||
@@ -171,7 +171,7 @@ private fn void! Formatter.out_str(Formatter* this, variant arg)
|
||||
case POINTER:
|
||||
if (this.print_with_function(arg)?) return;
|
||||
typeid inner = arg.type.inner;
|
||||
if (inner.kind == TypeKind.ARRAY && inner.inner == char.typeid)
|
||||
if (inner.kindof == TypeKind.ARRAY && inner.inner == char.typeid)
|
||||
{
|
||||
char *ptr = *(char**)arg.ptr;
|
||||
return this.out_substr(ptr[:inner.len]);
|
||||
|
||||
@@ -435,6 +435,41 @@ Decl *decl_find_enum_constant(Decl *decl, const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AlignSize decl_find_member_offset(Decl *decl, Decl *member)
|
||||
{
|
||||
static const AlignSize NO_MATCH = ~(AlignSize)0;
|
||||
while (decl->decl_kind == DECL_DISTINCT) decl = decl->distinct_decl.base_type->decl;
|
||||
Decl **members = NULL;
|
||||
switch (decl->decl_kind)
|
||||
{
|
||||
case DECL_BITSTRUCT:
|
||||
members = decl->bitstruct.members;
|
||||
break;
|
||||
case DECL_STRUCT:
|
||||
case DECL_UNION:
|
||||
members = decl->strukt.members;
|
||||
break;
|
||||
default:
|
||||
return NO_MATCH;
|
||||
}
|
||||
assert(members);
|
||||
unsigned list = vec_size(members);
|
||||
for (unsigned i = 0; i < list; i++)
|
||||
{
|
||||
Decl *m = members[i];
|
||||
if (m == member)
|
||||
{
|
||||
return member->offset;
|
||||
}
|
||||
if (m->decl_kind != DECL_VAR)
|
||||
{
|
||||
AlignSize possible_offset = decl_find_member_offset(m, member);
|
||||
if (possible_offset != NO_MATCH) return possible_offset + m->offset;
|
||||
}
|
||||
}
|
||||
return NO_MATCH;
|
||||
}
|
||||
|
||||
bool ast_supports_continue(Ast *stmt)
|
||||
{
|
||||
if (stmt->ast_kind != AST_FOR_STMT) return false;
|
||||
|
||||
@@ -204,6 +204,12 @@ typedef struct
|
||||
Type *typeid;
|
||||
ConstInitializer *initializer;
|
||||
Expr **untyped_list;
|
||||
struct
|
||||
{
|
||||
AlignSize offset;
|
||||
AlignSize align;
|
||||
Decl *decl;
|
||||
} member;
|
||||
};
|
||||
} ExprConst;
|
||||
|
||||
@@ -1795,7 +1801,7 @@ extern Type *type_ichar, *type_short, *type_int, *type_long, *type_isize;
|
||||
extern Type *type_char, *type_ushort, *type_uint, *type_ulong, *type_usize;
|
||||
extern Type *type_iptr, *type_uptr, *type_iptrdiff, *type_uptrdiff;
|
||||
extern Type *type_u128, *type_i128;
|
||||
extern Type *type_typeid, *type_anyerr, *type_typeinfo;
|
||||
extern Type *type_typeid, *type_anyerr, *type_typeinfo, *type_member;
|
||||
extern Type *type_any;
|
||||
extern Type *type_untypedlist;
|
||||
extern Type *type_anyfail;
|
||||
@@ -1812,38 +1818,39 @@ extern const char *kw_std__core;
|
||||
extern const char *kw_std__core__types;
|
||||
extern const char *kw_typekind;
|
||||
|
||||
extern const char *kw_std;
|
||||
extern const char *kw_finalize;
|
||||
extern const char *kw_align;
|
||||
extern const char *kw_nameof;
|
||||
extern const char *kw_in;
|
||||
extern const char *kw_initialize;
|
||||
extern const char *kw_out;
|
||||
extern const char *kw_inout;
|
||||
extern const char *kw_deprecated;
|
||||
extern const char *kw_distinct;
|
||||
extern const char *kw_inline;
|
||||
extern const char *kw_kind;
|
||||
extern const char *kw_len;
|
||||
extern const char *kw_noinline;
|
||||
extern const char *kw_main;
|
||||
extern const char *kw_ordinal;
|
||||
extern const char *kw_pure;
|
||||
extern const char *kw_ptr;
|
||||
extern const char *kw_return;
|
||||
extern const char *kw_type;
|
||||
extern const char *kw_incr;
|
||||
extern const char *kw_check_assign;
|
||||
extern const char *kw_argc;
|
||||
extern const char *kw_argv;
|
||||
extern const char *kw_mainstub;
|
||||
extern const char *kw_at_checked;
|
||||
extern const char *kw_at_ensure;
|
||||
extern const char *kw_at_require;
|
||||
extern const char *kw_at_pure;
|
||||
extern const char *kw_at_optreturn;
|
||||
extern const char *kw_at_param;
|
||||
extern const char *kw_at_pure;
|
||||
extern const char *kw_at_require;
|
||||
extern const char *kw_at_return;
|
||||
extern const char *kw_at_checked;
|
||||
extern const char *kw_check_assign;
|
||||
extern const char *kw_deprecated;
|
||||
extern const char *kw_distinct;
|
||||
extern const char *kw_finalize;
|
||||
extern const char *kw_in;
|
||||
extern const char *kw_incr;
|
||||
extern const char *kw_initialize;
|
||||
extern const char *kw_inline;
|
||||
extern const char *kw_inout;
|
||||
extern const char *kw_kind;
|
||||
extern const char *kw_len;
|
||||
extern const char *kw_main;
|
||||
extern const char *kw_mainstub;
|
||||
extern const char *kw_nameof;
|
||||
extern const char *kw_noinline;
|
||||
extern const char *kw_offsetof;
|
||||
extern const char *kw_ordinal;
|
||||
extern const char *kw_out;
|
||||
extern const char *kw_ptr;
|
||||
extern const char *kw_pure;
|
||||
extern const char *kw_return;
|
||||
extern const char *kw_std;
|
||||
extern const char *kw_type;
|
||||
extern ArchOsTarget default_target;
|
||||
|
||||
ARENA_DEF(chars, char)
|
||||
@@ -2065,6 +2072,7 @@ static inline Decl *decl_raw(Decl *decl);
|
||||
static inline DeclKind decl_from_token(TokenType type);
|
||||
static inline bool decl_is_local(Decl *decl);
|
||||
Decl *decl_find_enum_constant(Decl *decl, const char *name);
|
||||
AlignSize decl_find_member_offset(Decl *decl, Decl *member);
|
||||
|
||||
// --- Expression functions
|
||||
|
||||
@@ -2098,9 +2106,11 @@ INLINE bool exprid_is_constant_eval(ExprId expr, ConstantEvalKind eval_kind);
|
||||
INLINE bool expr_is_init_list(Expr *expr);
|
||||
INLINE bool expr_is_deref(Expr *expr);
|
||||
INLINE bool expr_is_const(Expr *expr);
|
||||
INLINE bool expr_is_const_int(Expr *expr);
|
||||
INLINE bool expr_is_const_string(Expr *expr);
|
||||
INLINE bool expr_is_const_initializer(Expr *expr);
|
||||
INLINE bool expr_is_const_untyped_list(Expr *expr);
|
||||
INLINE bool expr_is_const_member(Expr *expr);
|
||||
|
||||
INLINE void expr_rewrite_const_null(Expr *expr, Type *type);
|
||||
INLINE void expr_rewrite_const_bool(Expr *expr, Type *type, bool b);
|
||||
@@ -3017,10 +3027,6 @@ static inline Clobbers clobbers_make(unsigned index, ...)
|
||||
return clobbers;
|
||||
}
|
||||
|
||||
static inline bool expr_is_const_int(Expr *expr)
|
||||
{
|
||||
return expr->expr_kind == EXPR_CONST && expr->const_expr.const_kind == CONST_INTEGER;
|
||||
}
|
||||
|
||||
INLINE unsigned arg_bits_max(AsmArgBits bits, unsigned limit)
|
||||
{
|
||||
@@ -3069,3 +3075,13 @@ INLINE bool expr_is_const_untyped_list(Expr *expr)
|
||||
{
|
||||
return expr->expr_kind == EXPR_CONST && expr->const_expr.const_kind == CONST_UNTYPED_LIST;
|
||||
}
|
||||
|
||||
INLINE bool expr_is_const_int(Expr *expr)
|
||||
{
|
||||
return expr->expr_kind == EXPR_CONST && expr->const_expr.const_kind == CONST_INTEGER;
|
||||
}
|
||||
|
||||
INLINE bool expr_is_const_member(Expr *expr)
|
||||
{
|
||||
return expr->expr_kind == EXPR_CONST && expr->const_expr.const_kind == CONST_MEMBER;
|
||||
}
|
||||
|
||||
@@ -275,6 +275,9 @@ INLINE Expr *copy_const_expr(CopyStruct *c, Expr *expr)
|
||||
case CONST_UNTYPED_LIST:
|
||||
expr->const_expr.untyped_list = copy_expr_list(c, expr->const_expr.untyped_list);
|
||||
break;
|
||||
case CONST_MEMBER:
|
||||
fixup_decl(c, &expr->const_expr.member.decl);
|
||||
break;
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
@@ -201,64 +201,64 @@ typedef enum
|
||||
{
|
||||
EXPR_POISONED,
|
||||
EXPR_ACCESS,
|
||||
EXPR_ARGV_TO_SUBARRAY,
|
||||
EXPR_ASM,
|
||||
EXPR_BINARY,
|
||||
EXPR_BITACCESS,
|
||||
EXPR_BITASSIGN,
|
||||
EXPR_BINARY,
|
||||
EXPR_BUILTIN,
|
||||
EXPR_COMPILER_CONST,
|
||||
EXPR_MACRO_BODY_EXPANSION,
|
||||
EXPR_BUILTIN_ACCESS,
|
||||
EXPR_CALL,
|
||||
EXPR_CAST,
|
||||
EXPR_CATCH,
|
||||
EXPR_CATCH_UNWRAP,
|
||||
EXPR_COMPILER_CONST,
|
||||
EXPR_COMPOUND_LITERAL,
|
||||
EXPR_CONST,
|
||||
EXPR_CT_CHECKS,
|
||||
EXPR_CT_CALL,
|
||||
EXPR_CT_IDENT,
|
||||
EXPR_CT_EVAL,
|
||||
EXPR_CT_ARG,
|
||||
EXPR_COND,
|
||||
EXPR_CONST,
|
||||
EXPR_CT_ARG,
|
||||
EXPR_CT_CALL,
|
||||
EXPR_CT_CHECKS,
|
||||
EXPR_CT_EVAL,
|
||||
EXPR_CT_IDENT,
|
||||
EXPR_DECL,
|
||||
EXPR_DESIGNATOR,
|
||||
EXPR_EXPR_BLOCK,
|
||||
EXPR_EXPRESSION_LIST,
|
||||
EXPR_FAILABLE,
|
||||
EXPR_GROUP,
|
||||
EXPR_RETHROW,
|
||||
EXPR_FORCE_UNWRAP,
|
||||
EXPR_HASH_IDENT,
|
||||
EXPR_MACRO_BLOCK,
|
||||
EXPR_IDENTIFIER,
|
||||
EXPR_RETVAL,
|
||||
EXPR_FLATPATH,
|
||||
EXPR_INITIALIZER_LIST,
|
||||
EXPR_DESIGNATED_INITIALIZER_LIST,
|
||||
EXPR_DESIGNATOR,
|
||||
EXPR_EXPRESSION_LIST,
|
||||
EXPR_EXPR_BLOCK,
|
||||
EXPR_FAILABLE,
|
||||
EXPR_FLATPATH,
|
||||
EXPR_FORCE_UNWRAP,
|
||||
EXPR_GROUP,
|
||||
EXPR_HASH_IDENT,
|
||||
EXPR_IDENTIFIER,
|
||||
EXPR_INITIALIZER_LIST,
|
||||
EXPR_MACRO_BLOCK,
|
||||
EXPR_MACRO_BODY_EXPANSION,
|
||||
EXPR_NOP,
|
||||
EXPR_OPERATOR_CHARS,
|
||||
EXPR_POINTER_OFFSET,
|
||||
EXPR_POST_UNARY,
|
||||
EXPR_RETHROW,
|
||||
EXPR_RETVAL,
|
||||
EXPR_SLICE,
|
||||
EXPR_SLICE_ASSIGN,
|
||||
EXPR_SLICE_COPY,
|
||||
EXPR_STRINGIFY,
|
||||
EXPR_SUBSCRIPT,
|
||||
EXPR_SUBSCRIPT_ADDR,
|
||||
EXPR_SUBSCRIPT_ASSIGN,
|
||||
EXPR_POINTER_OFFSET,
|
||||
EXPR_STRINGIFY,
|
||||
EXPR_ARGV_TO_SUBARRAY,
|
||||
EXPR_TERNARY,
|
||||
EXPR_TRY,
|
||||
EXPR_TRY_UNWRAP,
|
||||
EXPR_TRY_UNWRAP_CHAIN,
|
||||
EXPR_TYPEID,
|
||||
EXPR_TYPEID_INFO,
|
||||
EXPR_TYPEINFO,
|
||||
EXPR_UNARY,
|
||||
EXPR_VARIANT,
|
||||
EXPR_VARIANTSWITCH,
|
||||
EXPR_VASPLAT,
|
||||
EXPR_NOP,
|
||||
EXPR_TYPEID_INFO,
|
||||
EXPR_VARIANT,
|
||||
EXPR_BUILTIN_ACCESS,
|
||||
EXPR_ASM,
|
||||
EXPR_OPERATOR_CHARS,
|
||||
} ExprKind;
|
||||
|
||||
typedef enum
|
||||
@@ -316,6 +316,7 @@ typedef enum
|
||||
CONST_TYPEID,
|
||||
CONST_INITIALIZER,
|
||||
CONST_UNTYPED_LIST,
|
||||
CONST_MEMBER,
|
||||
} ConstKind;
|
||||
|
||||
typedef enum
|
||||
@@ -654,13 +655,15 @@ typedef enum
|
||||
TYPE_OPTIONAL,
|
||||
TYPE_FAILABLE_ANY,
|
||||
TYPE_TYPEINFO,
|
||||
TYPE_MEMBER,
|
||||
TYPE_INFERRED_VECTOR,
|
||||
TYPE_SCALED_VECTOR,
|
||||
TYPE_VECTOR,
|
||||
TYPE_LAST = TYPE_ANY
|
||||
} TypeKind;
|
||||
|
||||
#define CT_TYPES TYPE_TYPEINFO: case TYPE_INFERRED_ARRAY: case TYPE_INFERRED_VECTOR: case TYPE_UNTYPED_LIST: case TYPE_POISONED
|
||||
#define CT_TYPES TYPE_TYPEINFO: case TYPE_INFERRED_ARRAY: case TYPE_INFERRED_VECTOR: case TYPE_UNTYPED_LIST: \
|
||||
case TYPE_POISONED: case TYPE_MEMBER
|
||||
#define ALL_INTS TYPE_I8: case TYPE_I16: case TYPE_I32: case TYPE_I64: case TYPE_I128: \
|
||||
case TYPE_U8: case TYPE_U16: case TYPE_U32: case TYPE_U64: case TYPE_U128
|
||||
#define ALL_SIGNED_INTS TYPE_I8: case TYPE_I16: case TYPE_I32: case TYPE_I64: case TYPE_I128
|
||||
@@ -880,6 +883,7 @@ typedef enum
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TYPE_PROPERTY_ALIGNOF,
|
||||
TYPE_PROPERTY_ELEMENTS,
|
||||
TYPE_PROPERTY_EXTNAMEOF,
|
||||
TYPE_PROPERTY_INF,
|
||||
@@ -889,7 +893,7 @@ typedef enum
|
||||
TYPE_PROPERTY_MIN,
|
||||
TYPE_PROPERTY_NAN,
|
||||
TYPE_PROPERTY_INNER,
|
||||
TYPE_PROPERTY_KIND,
|
||||
TYPE_PROPERTY_KINDOF,
|
||||
TYPE_PROPERTY_NAMES,
|
||||
TYPE_PROPERTY_NAMEOF,
|
||||
TYPE_PROPERTY_PARAMS,
|
||||
|
||||
@@ -80,59 +80,59 @@ bool expr_may_addr(Expr *expr)
|
||||
case EXPR_SUBSCRIPT:
|
||||
case EXPR_SLICE:
|
||||
return true;
|
||||
case EXPR_SUBSCRIPT_ADDR:
|
||||
case EXPR_POISONED:
|
||||
case EXPR_BITASSIGN:
|
||||
case EXPR_ARGV_TO_SUBARRAY:
|
||||
case EXPR_ASM:
|
||||
case EXPR_BINARY:
|
||||
case EXPR_BITASSIGN:
|
||||
case EXPR_BUILTIN:
|
||||
case EXPR_COMPILER_CONST:
|
||||
case EXPR_MACRO_BODY_EXPANSION:
|
||||
case EXPR_BUILTIN_ACCESS:
|
||||
case EXPR_CALL:
|
||||
case EXPR_CAST:
|
||||
case EXPR_CATCH:
|
||||
case EXPR_CATCH_UNWRAP:
|
||||
case EXPR_COMPILER_CONST:
|
||||
case EXPR_COMPOUND_LITERAL:
|
||||
case EXPR_CONST:
|
||||
case EXPR_CT_CALL:
|
||||
case EXPR_CT_IDENT:
|
||||
case EXPR_CT_EVAL:
|
||||
case EXPR_COND:
|
||||
case EXPR_CONST:
|
||||
case EXPR_CT_ARG:
|
||||
case EXPR_CT_CALL:
|
||||
case EXPR_CT_CHECKS:
|
||||
case EXPR_CT_EVAL:
|
||||
case EXPR_CT_IDENT:
|
||||
case EXPR_DECL:
|
||||
case EXPR_DESIGNATED_INITIALIZER_LIST:
|
||||
case EXPR_DESIGNATOR:
|
||||
case EXPR_EXPR_BLOCK:
|
||||
case EXPR_EXPRESSION_LIST:
|
||||
case EXPR_EXPR_BLOCK:
|
||||
case EXPR_FAILABLE:
|
||||
case EXPR_RETHROW:
|
||||
case EXPR_FLATPATH:
|
||||
case EXPR_FORCE_UNWRAP:
|
||||
case EXPR_HASH_IDENT:
|
||||
case EXPR_MACRO_BLOCK:
|
||||
case EXPR_RETVAL:
|
||||
case EXPR_FLATPATH:
|
||||
case EXPR_INITIALIZER_LIST:
|
||||
case EXPR_DESIGNATED_INITIALIZER_LIST:
|
||||
case EXPR_MACRO_BLOCK:
|
||||
case EXPR_MACRO_BODY_EXPANSION:
|
||||
case EXPR_NOP:
|
||||
case EXPR_OPERATOR_CHARS:
|
||||
case EXPR_POINTER_OFFSET:
|
||||
case EXPR_POISONED:
|
||||
case EXPR_POST_UNARY:
|
||||
case EXPR_RETHROW:
|
||||
case EXPR_RETVAL:
|
||||
case EXPR_SLICE_ASSIGN:
|
||||
case EXPR_SLICE_COPY:
|
||||
case EXPR_STRINGIFY:
|
||||
case EXPR_ARGV_TO_SUBARRAY:
|
||||
case EXPR_SUBSCRIPT_ADDR:
|
||||
case EXPR_SUBSCRIPT_ASSIGN:
|
||||
case EXPR_TERNARY:
|
||||
case EXPR_TRY:
|
||||
case EXPR_TRY_UNWRAP:
|
||||
case EXPR_TRY_UNWRAP_CHAIN:
|
||||
case EXPR_TYPEID:
|
||||
case EXPR_TYPEINFO:
|
||||
case EXPR_VARIANTSWITCH:
|
||||
case EXPR_NOP:
|
||||
case EXPR_TYPEID_INFO:
|
||||
case EXPR_TYPEINFO:
|
||||
case EXPR_VARIANT:
|
||||
case EXPR_BUILTIN_ACCESS:
|
||||
case EXPR_POINTER_OFFSET:
|
||||
case EXPR_CT_ARG:
|
||||
case EXPR_ASM:
|
||||
case EXPR_VARIANTSWITCH:
|
||||
case EXPR_VASPLAT:
|
||||
case EXPR_OPERATOR_CHARS:
|
||||
case EXPR_CT_CHECKS:
|
||||
case EXPR_SUBSCRIPT_ASSIGN:
|
||||
return false;
|
||||
}
|
||||
UNREACHABLE
|
||||
@@ -573,6 +573,7 @@ void expr_rewrite_to_const_zero(Expr *expr, Type *type)
|
||||
case TYPE_FAILABLE_ANY:
|
||||
case TYPE_OPTIONAL:
|
||||
case TYPE_TYPEINFO:
|
||||
case TYPE_MEMBER:
|
||||
UNREACHABLE
|
||||
case TYPE_STRUCT:
|
||||
case TYPE_UNION:
|
||||
|
||||
@@ -3977,6 +3977,7 @@ static void llvm_emit_const_expr(GenContext *c, BEValue *be_value, Expr *expr)
|
||||
case CONST_ENUM:
|
||||
llvm_value_set(be_value, llvm_const_int(c, type, expr->const_expr.enum_val->enum_constant.ordinal), type);
|
||||
return;
|
||||
case CONST_MEMBER:
|
||||
case CONST_UNTYPED_LIST:
|
||||
UNREACHABLE
|
||||
}
|
||||
|
||||
@@ -716,6 +716,7 @@ LLVMValueRef llvm_get_typeid(GenContext *c, Type *type)
|
||||
case TYPE_UNTYPED_LIST:
|
||||
case TYPE_FAILABLE_ANY:
|
||||
case TYPE_TYPEINFO:
|
||||
case TYPE_MEMBER:
|
||||
UNREACHABLE
|
||||
case TYPE_VOID:
|
||||
return llvm_get_introspection_for_builtin_type(c, type, INTROSPECT_TYPE_VOID, 0);
|
||||
|
||||
@@ -210,6 +210,8 @@ const char *expr_const_to_error_string(const ExprConst *expr)
|
||||
return expr->err_val->name;
|
||||
case CONST_TYPEID:
|
||||
return type_to_error_string(expr->typeid);
|
||||
case CONST_MEMBER:
|
||||
return "member";
|
||||
case CONST_INITIALIZER:
|
||||
return "constant list";
|
||||
case CONST_UNTYPED_LIST:
|
||||
|
||||
@@ -400,6 +400,7 @@ CastKind cast_to_bool_kind(Type *type)
|
||||
case TYPE_FLEXIBLE_ARRAY:
|
||||
case TYPE_SCALED_VECTOR:
|
||||
case TYPE_INFERRED_VECTOR:
|
||||
case TYPE_MEMBER:
|
||||
return CAST_ERROR;
|
||||
}
|
||||
UNREACHABLE
|
||||
@@ -458,6 +459,7 @@ bool cast_may_explicit(Type *from_type, Type *to_type, bool ignore_failability,
|
||||
case TYPE_FLEXIBLE_ARRAY:
|
||||
case TYPE_INFERRED_VECTOR:
|
||||
case TYPE_SCALED_VECTOR:
|
||||
case TYPE_MEMBER:
|
||||
return false;
|
||||
case TYPE_TYPEID:
|
||||
// May convert to anything pointer sized or larger, no enums
|
||||
@@ -852,7 +854,6 @@ Expr *recursive_may_narrow_float(Expr *expr, Type *type)
|
||||
case EXPR_SUBSCRIPT_ASSIGN:
|
||||
UNREACHABLE
|
||||
case EXPR_BUILTIN_ACCESS:
|
||||
|
||||
return false;
|
||||
case EXPR_POST_UNARY:
|
||||
return recursive_may_narrow_float(expr->unary_expr.expr, type);
|
||||
|
||||
@@ -2234,12 +2234,20 @@ static bool sema_analyse_attributes_for_var(SemaContext *context, Decl *decl)
|
||||
|
||||
bool sema_analyse_decl_type(SemaContext *context, Type *type, SourceSpan span)
|
||||
{
|
||||
if (type == type_void)
|
||||
switch (type->type_kind)
|
||||
{
|
||||
sema_error_at(span, "The use of 'void' as a variable type is not permitted.");
|
||||
return false;
|
||||
case TYPE_VOID:
|
||||
sema_error_at(span, "The use of 'void' as a variable type is not permitted.");
|
||||
return false;
|
||||
case TYPE_UNTYPED_LIST:
|
||||
case TYPE_MEMBER:
|
||||
case TYPE_TYPEINFO:
|
||||
sema_error_at(span, "The variable cannot have an compile time %s type.",
|
||||
type_quoted_error_string(type));
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!type_is_optional(type)) return true;
|
||||
if (type_is_optional_any(type) || type_flatten_distinct(type->failable) == type_void)
|
||||
{
|
||||
|
||||
@@ -160,7 +160,8 @@ static Type *sema_expr_check_type_exists(SemaContext *context, TypeInfo *type_in
|
||||
static inline Expr *sema_ct_checks_exprlist_compiles(SemaContext *context, Expr *exprlist);
|
||||
static inline bool sema_cast_ct_ident_rvalue(SemaContext *context, Expr *expr);
|
||||
static bool sema_expr_rewrite_to_typeid_property(SemaContext *context, Expr *expr, Expr *typeid, const char *kw);
|
||||
static bool sema_expr_rewrite_to_type_property(SemaContext *context, Expr *expr, Type *type, TypeProperty property);
|
||||
static bool sema_expr_rewrite_to_type_property(SemaContext *context, Expr *expr, Type *type, TypeProperty property,
|
||||
AlignSize alignment, AlignSize offset);
|
||||
static bool sema_expr_rewrite_typeid_call(Expr *expr, Expr *typeid, TypeIdInfoKind kind, Type *result_type);
|
||||
static inline void sema_expr_rewrite_typeid_kind(Expr *expr, Expr *parent);
|
||||
static inline void sema_expr_replace_with_enum_array(Expr *enum_array_expr, Decl *enum_decl);
|
||||
@@ -173,7 +174,8 @@ static inline bool sema_create_const_inner(SemaContext *context, Expr *expr, Typ
|
||||
static inline bool sema_create_const_min(SemaContext *context, Expr *expr, Type *type, Type *flat);
|
||||
static inline bool sema_create_const_max(SemaContext *context, Expr *expr, Type *type, Type *flat);
|
||||
static inline bool sema_create_const_params(SemaContext *context, Expr *expr, Type *type);
|
||||
static inline bool sema_create_const_membersof(SemaContext *context, Expr *expr, Type *type);
|
||||
static inline void sema_create_const_membersof(SemaContext *context, Expr *expr, Type *type, AlignSize alignment,
|
||||
AlignSize offset);
|
||||
|
||||
void expr_insert_widening_type(Expr *expr, Type *infer_type);
|
||||
static Expr *expr_access_inline_member(Expr *parent, Decl *parent_decl);
|
||||
@@ -186,6 +188,7 @@ static inline bool sema_cast_ident_rvalue(SemaContext *context, Expr *expr);
|
||||
static inline bool sema_cast_rvalue(SemaContext *context, Expr *expr);
|
||||
|
||||
static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *expr, TypeInfo *parent, bool was_group, Expr *identifier);
|
||||
static inline bool sema_expr_analyse_member_access(SemaContext *context, Expr *expr, Expr *parent, bool was_group, Expr *identifier);
|
||||
static inline bool sema_expr_fold_to_member(Expr *expr, Expr *parent, Decl *member);
|
||||
|
||||
// -- implementations
|
||||
@@ -425,54 +428,54 @@ static bool sema_binary_is_expr_lvalue(Expr *top_expr, Expr *expr)
|
||||
SEMA_ERROR(top_expr, "You cannot assign to an unevaluated expression.");
|
||||
return false;
|
||||
case EXPR_POISONED:
|
||||
case EXPR_BITASSIGN:
|
||||
case EXPR_ARGV_TO_SUBARRAY:
|
||||
case EXPR_ASM:
|
||||
case EXPR_BINARY:
|
||||
case EXPR_BITASSIGN:
|
||||
case EXPR_BUILTIN:
|
||||
case EXPR_COMPILER_CONST:
|
||||
case EXPR_MACRO_BODY_EXPANSION:
|
||||
case EXPR_BUILTIN_ACCESS:
|
||||
case EXPR_CALL:
|
||||
case EXPR_CAST:
|
||||
case EXPR_CATCH:
|
||||
case EXPR_CATCH_UNWRAP:
|
||||
case EXPR_COMPILER_CONST:
|
||||
case EXPR_COMPOUND_LITERAL:
|
||||
case EXPR_CONST:
|
||||
case EXPR_CT_CALL:
|
||||
case EXPR_CT_EVAL:
|
||||
case EXPR_COND:
|
||||
case EXPR_CONST:
|
||||
case EXPR_CT_ARG:
|
||||
case EXPR_CT_CALL:
|
||||
case EXPR_CT_CHECKS:
|
||||
case EXPR_CT_EVAL:
|
||||
case EXPR_DECL:
|
||||
case EXPR_DESIGNATOR:
|
||||
case EXPR_EXPR_BLOCK:
|
||||
case EXPR_EXPRESSION_LIST:
|
||||
case EXPR_FAILABLE:
|
||||
case EXPR_RETHROW:
|
||||
case EXPR_FORCE_UNWRAP:
|
||||
case EXPR_MACRO_BLOCK:
|
||||
case EXPR_RETVAL:
|
||||
case EXPR_FLATPATH:
|
||||
case EXPR_INITIALIZER_LIST:
|
||||
case EXPR_DESIGNATED_INITIALIZER_LIST:
|
||||
case EXPR_DESIGNATOR:
|
||||
case EXPR_EXPRESSION_LIST:
|
||||
case EXPR_EXPR_BLOCK:
|
||||
case EXPR_FAILABLE:
|
||||
case EXPR_FLATPATH:
|
||||
case EXPR_FORCE_UNWRAP:
|
||||
case EXPR_INITIALIZER_LIST:
|
||||
case EXPR_MACRO_BLOCK:
|
||||
case EXPR_MACRO_BODY_EXPANSION:
|
||||
case EXPR_NOP:
|
||||
case EXPR_OPERATOR_CHARS:
|
||||
case EXPR_POINTER_OFFSET:
|
||||
case EXPR_POST_UNARY:
|
||||
case EXPR_RETHROW:
|
||||
case EXPR_RETVAL:
|
||||
case EXPR_SLICE_ASSIGN:
|
||||
case EXPR_SLICE_COPY:
|
||||
case EXPR_STRINGIFY:
|
||||
case EXPR_ARGV_TO_SUBARRAY:
|
||||
case EXPR_TERNARY:
|
||||
case EXPR_TRY:
|
||||
case EXPR_TRY_UNWRAP:
|
||||
case EXPR_TRY_UNWRAP_CHAIN:
|
||||
case EXPR_TYPEID:
|
||||
case EXPR_TYPEINFO:
|
||||
case EXPR_VARIANTSWITCH:
|
||||
case EXPR_NOP:
|
||||
case EXPR_TYPEID_INFO:
|
||||
case EXPR_TYPEINFO:
|
||||
case EXPR_VARIANT:
|
||||
case EXPR_BUILTIN_ACCESS:
|
||||
case EXPR_POINTER_OFFSET:
|
||||
case EXPR_CT_ARG:
|
||||
case EXPR_ASM:
|
||||
case EXPR_VARIANTSWITCH:
|
||||
case EXPR_VASPLAT:
|
||||
case EXPR_OPERATOR_CHARS:
|
||||
case EXPR_CT_CHECKS:
|
||||
goto ERR;
|
||||
}
|
||||
UNREACHABLE
|
||||
@@ -2698,7 +2701,8 @@ static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *exp
|
||||
|
||||
if (!is_const)
|
||||
{
|
||||
if (sema_expr_rewrite_to_type_property(context, expr, canonical, type_property_by_name(name))) return true;
|
||||
if (sema_expr_rewrite_to_type_property(context, expr, canonical, type_property_by_name(name),
|
||||
type_abi_alignment(parent->type), 0)) return true;
|
||||
}
|
||||
|
||||
if (!type_may_have_sub_elements(canonical))
|
||||
@@ -2750,25 +2754,19 @@ static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *exp
|
||||
return false;
|
||||
}
|
||||
|
||||
if (member->decl_kind == DECL_VAR)
|
||||
if (member->decl_kind == DECL_VAR || member->decl_kind == DECL_UNION || member->decl_kind == DECL_STRUCT || member->decl_kind == DECL_BITSTRUCT)
|
||||
{
|
||||
expr->expr_kind = EXPR_TYPEINFO;
|
||||
expr->type_expr->type = member->type;
|
||||
expr->type_expr->resolve_status = RESOLVE_DONE;
|
||||
expr->type = type_typeinfo;
|
||||
expr->expr_kind = EXPR_CONST;
|
||||
expr->const_expr = (ExprConst) {
|
||||
.member.decl = member,
|
||||
.member.align = type_abi_alignment(decl->type),
|
||||
.member.offset = decl_find_member_offset(decl, member),
|
||||
.const_kind = CONST_MEMBER
|
||||
};
|
||||
expr->type = type_member;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (member->decl_kind == DECL_UNION || member->decl_kind == DECL_STRUCT || member->decl_kind == DECL_BITSTRUCT)
|
||||
{
|
||||
expr->expr_kind = EXPR_TYPEINFO;
|
||||
expr->type_expr->type = member->type;
|
||||
expr->type_expr->resolve_status = RESOLVE_DONE;
|
||||
expr->type = type_typeinfo;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
expr->identifier_expr.ident = name;
|
||||
expr->expr_kind = EXPR_IDENTIFIER;
|
||||
expr->identifier_expr.decl = member;
|
||||
@@ -2776,6 +2774,91 @@ static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *exp
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool sema_expr_analyse_member_access(SemaContext *context, Expr *expr, Expr *parent, bool was_group, Expr *identifier)
|
||||
{
|
||||
assert(identifier->expr_kind == EXPR_IDENTIFIER);
|
||||
|
||||
Decl *decl = parent->const_expr.member.decl;
|
||||
const char *name = identifier->identifier_expr.ident;
|
||||
bool is_const = identifier->identifier_expr.is_const;
|
||||
|
||||
if (is_const)
|
||||
{
|
||||
SEMA_ERROR(expr, "There is no member '%s' for %s.", name, type_to_error_string(decl->type));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (name == kw_offsetof)
|
||||
{
|
||||
expr_rewrite_const_int(expr, type_usize, parent->const_expr.member.offset, true);
|
||||
return true;
|
||||
}
|
||||
TypeProperty type_property = type_property_by_name(name);
|
||||
switch (type_property)
|
||||
{
|
||||
case TYPE_PROPERTY_NONE:
|
||||
break;
|
||||
case TYPE_PROPERTY_QNAMEOF:
|
||||
break;
|
||||
case TYPE_PROPERTY_NAMEOF:
|
||||
expr_rewrite_to_string(expr, decl->name ? decl->name : "");
|
||||
return true;
|
||||
case TYPE_PROPERTY_ALIGNOF:
|
||||
expr_rewrite_const_int(expr, type_usize,
|
||||
type_min_alignment(parent->const_expr.member.offset, parent->const_expr.member.align),
|
||||
true);
|
||||
return true;
|
||||
case TYPE_PROPERTY_MEMBERSOF:
|
||||
sema_create_const_membersof(context, expr, decl->type->canonical, parent->const_expr.member.align, parent->const_expr.member.offset);
|
||||
return true;
|
||||
case TYPE_PROPERTY_KINDOF:
|
||||
case TYPE_PROPERTY_SIZEOF:
|
||||
if (sema_expr_rewrite_to_type_property(context, expr, decl->type, type_property,
|
||||
parent->const_expr.member.align,
|
||||
parent->const_expr.member.offset)) return true;
|
||||
return true;
|
||||
case TYPE_PROPERTY_ELEMENTS:
|
||||
case TYPE_PROPERTY_EXTNAMEOF:
|
||||
case TYPE_PROPERTY_PARAMS:
|
||||
case TYPE_PROPERTY_RETURNS:
|
||||
case TYPE_PROPERTY_INF:
|
||||
case TYPE_PROPERTY_LEN:
|
||||
case TYPE_PROPERTY_MAX:
|
||||
case TYPE_PROPERTY_MIN:
|
||||
case TYPE_PROPERTY_NAN:
|
||||
case TYPE_PROPERTY_INNER:
|
||||
case TYPE_PROPERTY_NAMES:
|
||||
case TYPE_PROPERTY_VALUES:
|
||||
break;
|
||||
}
|
||||
|
||||
Type *underlying_type = type_flatten_distinct(decl->type);
|
||||
|
||||
if (!type_is_union_or_strukt(underlying_type) && underlying_type->type_kind != TYPE_BITSTRUCT)
|
||||
{
|
||||
SEMA_ERROR(parent, "No member or property '%s' was found.", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
Decl *underlying_type_decl = underlying_type->decl;
|
||||
Decl *member = sema_decl_stack_find_decl_member(underlying_type_decl, name);
|
||||
if (!member || !(decl_is_struct_type(member) || member->decl_kind == DECL_VAR || member->decl_kind == DECL_BITSTRUCT))
|
||||
{
|
||||
SEMA_ERROR(expr, "No member '%s' found.", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
expr->expr_kind = EXPR_CONST;
|
||||
expr->const_expr = (ExprConst) {
|
||||
.member.decl = member,
|
||||
.member.align = parent->const_expr.member.align,
|
||||
.member.offset = parent->const_expr.member.offset + decl_find_member_offset(decl, member),
|
||||
.const_kind = CONST_MEMBER
|
||||
};
|
||||
expr->type = type_member;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void sema_expr_rewrite_typeid_kind(Expr *expr, Expr *parent)
|
||||
{
|
||||
Module *module = global_context_find_module(kw_std__core__types);
|
||||
@@ -2939,7 +3022,8 @@ static inline bool sema_create_const_params(SemaContext *context, Expr *expr, Ty
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool sema_create_const_membersof(SemaContext *context, Expr *expr, Type *type)
|
||||
static inline void sema_create_const_membersof(SemaContext *context, Expr *expr, Type *type, AlignSize alignment,
|
||||
AlignSize offset)
|
||||
{
|
||||
Decl **members = NULL;
|
||||
if (type_is_union_or_strukt(type))
|
||||
@@ -2952,18 +3036,25 @@ static inline bool sema_create_const_membersof(SemaContext *context, Expr *expr,
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
expr_rewrite_const_untyped_list(expr, NULL);
|
||||
return;
|
||||
}
|
||||
unsigned count = vec_size(members);
|
||||
Expr **member_exprs = count ? VECNEW(Expr*, count) : NULL;
|
||||
for (unsigned i = 0; i < count; i++)
|
||||
{
|
||||
Decl *decl = members[i];
|
||||
Expr *expr_element = expr_new_const_typeid(expr->span, decl->type->canonical);
|
||||
Expr *expr_element = expr_new(EXPR_CONST, expr->span);
|
||||
expr_element->type = type_member;
|
||||
expr_element->const_expr = (ExprConst) {
|
||||
.const_kind = CONST_MEMBER,
|
||||
.member.decl = decl,
|
||||
.member.offset = offset + decl->offset,
|
||||
.member.align = alignment
|
||||
};
|
||||
vec_add(member_exprs, expr_element);
|
||||
}
|
||||
expr_rewrite_const_untyped_list(expr, member_exprs);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool sema_create_const_max(SemaContext *context, Expr *expr, Type *type, Type *flat)
|
||||
@@ -3055,7 +3146,8 @@ static bool sema_expr_rewrite_to_typeid_property(SemaContext *context, Expr *exp
|
||||
TypeProperty property = type_property_by_name(kw);
|
||||
if (typeid->expr_kind == EXPR_CONST)
|
||||
{
|
||||
return sema_expr_rewrite_to_type_property(context, expr, typeid->const_expr.typeid, property);
|
||||
Type *type = typeid->const_expr.typeid;
|
||||
return sema_expr_rewrite_to_type_property(context, expr, type, property, type_abi_alignment(type), 0);
|
||||
}
|
||||
switch (property)
|
||||
{
|
||||
@@ -3065,11 +3157,12 @@ static bool sema_expr_rewrite_to_typeid_property(SemaContext *context, Expr *exp
|
||||
return sema_expr_rewrite_typeid_call(expr, typeid, TYPEID_INFO_LEN, type_usize);
|
||||
case TYPE_PROPERTY_INNER:
|
||||
return sema_expr_rewrite_typeid_call(expr, typeid, TYPEID_INFO_INNER, type_typeid);
|
||||
case TYPE_PROPERTY_KIND:
|
||||
case TYPE_PROPERTY_KINDOF:
|
||||
sema_expr_rewrite_typeid_kind(expr, typeid);
|
||||
return true;
|
||||
case TYPE_PROPERTY_NAMES:
|
||||
return sema_expr_rewrite_typeid_call(expr, typeid, TYPEID_INFO_NAMES, type_get_subarray(type_chars));
|
||||
case TYPE_PROPERTY_ALIGNOF:
|
||||
case TYPE_PROPERTY_INF:
|
||||
case TYPE_PROPERTY_MIN:
|
||||
case TYPE_PROPERTY_MAX:
|
||||
@@ -3146,7 +3239,8 @@ EVAL:
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool sema_expr_rewrite_to_type_property(SemaContext *context, Expr *expr, Type *type, TypeProperty property)
|
||||
static bool sema_expr_rewrite_to_type_property(SemaContext *context, Expr *expr, Type *type, TypeProperty property,
|
||||
AlignSize alignment, AlignSize offset)
|
||||
{
|
||||
assert(type == type->canonical);
|
||||
if (property == TYPE_PROPERTY_NONE) return false;
|
||||
@@ -3164,7 +3258,7 @@ static bool sema_expr_rewrite_to_type_property(SemaContext *context, Expr *expr,
|
||||
return true;
|
||||
case TYPE_PROPERTY_INNER:
|
||||
return sema_create_const_inner(context, expr, type);
|
||||
case TYPE_PROPERTY_KIND:
|
||||
case TYPE_PROPERTY_KINDOF:
|
||||
return sema_create_const_kind(expr, type);
|
||||
case TYPE_PROPERTY_LEN:
|
||||
return sema_create_const_len(context, expr, flat);
|
||||
@@ -3193,7 +3287,8 @@ static bool sema_expr_rewrite_to_type_property(SemaContext *context, Expr *expr,
|
||||
expr->resolve_status = RESOLVE_DONE;
|
||||
return true;
|
||||
case TYPE_PROPERTY_MEMBERSOF:
|
||||
return sema_create_const_membersof(context, expr, flat);
|
||||
sema_create_const_membersof(context, expr, flat, alignment, offset);
|
||||
return true;
|
||||
case TYPE_PROPERTY_PARAMS:
|
||||
return sema_create_const_params(context, expr, flat);
|
||||
case TYPE_PROPERTY_RETURNS:
|
||||
@@ -3210,6 +3305,9 @@ static bool sema_expr_rewrite_to_type_property(SemaContext *context, Expr *expr,
|
||||
case TYPE_PROPERTY_QNAMEOF:
|
||||
sema_expr_rewrite_to_type_nameof(expr, type, TOKEN_CT_QNAMEOF);
|
||||
return true;
|
||||
case TYPE_PROPERTY_ALIGNOF:
|
||||
expr_rewrite_const_int(expr, type_usize, type_abi_alignment(type), true);
|
||||
return true;
|
||||
case TYPE_PROPERTY_EXTNAMEOF:
|
||||
if (type_is_builtin(type->type_kind))
|
||||
{
|
||||
@@ -3247,19 +3345,26 @@ static inline bool sema_expr_analyse_access(SemaContext *context, Expr *expr)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parent->expr_kind != EXPR_TYPEINFO)
|
||||
if (parent->expr_kind == EXPR_TYPEINFO)
|
||||
{
|
||||
SEMA_ERROR(expr, "'typeid' can only be used with types, not values");
|
||||
return false;
|
||||
expr->type = type_typeid;
|
||||
expr->expr_kind = EXPR_CONST;
|
||||
expr->const_expr.const_kind = CONST_TYPEID;
|
||||
expr->const_expr.typeid = parent->type_expr->type->canonical;
|
||||
expr->resolve_status = RESOLVE_DONE;
|
||||
return true;
|
||||
}
|
||||
|
||||
expr->type = type_typeid;
|
||||
expr->expr_kind = EXPR_CONST;
|
||||
expr->const_expr.const_kind = CONST_TYPEID;
|
||||
expr->const_expr.typeid = parent->type_expr->type->canonical;
|
||||
expr->resolve_status = RESOLVE_DONE;
|
||||
return true;
|
||||
|
||||
if (expr_is_const_member(parent))
|
||||
{
|
||||
expr->type = type_typeid;
|
||||
expr->expr_kind = EXPR_CONST;
|
||||
expr->const_expr.const_kind = CONST_TYPEID;
|
||||
expr->const_expr.typeid = parent->const_expr.member.decl->type->canonical;
|
||||
expr->resolve_status = RESOLVE_DONE;
|
||||
return true;
|
||||
}
|
||||
SEMA_ERROR(expr, "'typeid' can only be used with types, not values");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 3. Find the actual token.
|
||||
@@ -3272,6 +3377,10 @@ static inline bool sema_expr_analyse_access(SemaContext *context, Expr *expr)
|
||||
{
|
||||
return sema_expr_analyse_type_access(context, expr, parent->type_expr, was_group, identifier);
|
||||
}
|
||||
if (expr_is_const_member(parent))
|
||||
{
|
||||
return sema_expr_analyse_member_access(context, expr, parent, was_group, identifier);
|
||||
}
|
||||
|
||||
// 6. Copy failability
|
||||
bool failable = IS_OPTIONAL(parent);
|
||||
@@ -3316,6 +3425,11 @@ CHECK_DEEPER:
|
||||
expr_rewrite_const_int(expr, type_isize, flat_type->array.len, true);
|
||||
return true;
|
||||
}
|
||||
if (flat_type->type_kind == TYPE_UNTYPED_LIST)
|
||||
{
|
||||
expr_rewrite_const_int(expr, type_isize, vec_size(current_parent->const_expr.untyped_list), true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (flat_type->type_kind == TYPE_TYPEID)
|
||||
{
|
||||
|
||||
@@ -227,6 +227,7 @@ bool sema_resolve_type(SemaContext *context, Type *type)
|
||||
case TYPE_ANYERR:
|
||||
case TYPE_VECTOR:
|
||||
case TYPE_TYPEINFO:
|
||||
case TYPE_MEMBER:
|
||||
case TYPE_UNTYPED_LIST:
|
||||
case TYPE_FAILABLE_ANY:
|
||||
return true;
|
||||
|
||||
@@ -70,6 +70,7 @@ const char *kw_main;
|
||||
const char *kw_mainstub;
|
||||
const char *kw_nameof;
|
||||
const char *kw_noinline;
|
||||
const char *kw_offsetof;
|
||||
const char *kw_ordinal;
|
||||
const char *kw_out;
|
||||
const char *kw_ptr;
|
||||
@@ -148,6 +149,7 @@ void symtab_init(uint32_t capacity)
|
||||
kw_main = KW_DEF("main");
|
||||
kw_nameof = KW_DEF("nameof");
|
||||
kw_noinline = KW_DEF("noinline");
|
||||
kw_offsetof = KW_DEF("offsetof");
|
||||
kw_ordinal = KW_DEF("ordinal");
|
||||
kw_out = KW_DEF("out");
|
||||
kw_ptr = KW_DEF("ptr");
|
||||
@@ -162,11 +164,12 @@ void symtab_init(uint32_t capacity)
|
||||
|
||||
type_property_list[TYPE_PROPERTY_LEN] = kw_len = KW_DEF("len");
|
||||
|
||||
type_property_list[TYPE_PROPERTY_ALIGNOF] = KW_DEF("alignof");
|
||||
type_property_list[TYPE_PROPERTY_ELEMENTS] = KW_DEF("elements");
|
||||
type_property_list[TYPE_PROPERTY_EXTNAMEOF] = KW_DEF("extnameof");
|
||||
type_property_list[TYPE_PROPERTY_INF] = KW_DEF("inf");
|
||||
type_property_list[TYPE_PROPERTY_INNER] = KW_DEF("inner");
|
||||
type_property_list[TYPE_PROPERTY_KIND] = KW_DEF("kind");
|
||||
type_property_list[TYPE_PROPERTY_KINDOF] = KW_DEF("kindof");
|
||||
type_property_list[TYPE_PROPERTY_MEMBERSOF] = KW_DEF("membersof");
|
||||
type_property_list[TYPE_PROPERTY_NAMEOF] = KW_DEF("nameof");
|
||||
type_property_list[TYPE_PROPERTY_NAMES] = KW_DEF("names");
|
||||
|
||||
@@ -12,7 +12,7 @@ static struct
|
||||
Type u8, u16, u32, u64, u128;
|
||||
Type f16, f32, f64, f128, fxx;
|
||||
Type usz, isz, uptr, iptr, uptrdiff, iptrdiff;
|
||||
Type voidstar, typeid, anyerr, typeinfo, untyped_list;
|
||||
Type voidstar, typeid, anyerr, member, typeinfo, untyped_list;
|
||||
Type any, anyfail;
|
||||
} t;
|
||||
|
||||
@@ -45,6 +45,7 @@ Type *type_usize = &t.usz;
|
||||
Type *type_anyerr = &t.anyerr;
|
||||
Type *type_untypedlist = &t.untyped_list;
|
||||
Type *type_anyfail = &t.anyfail;
|
||||
Type *type_member = &t.member;
|
||||
Type *type_chars = NULL;
|
||||
|
||||
static unsigned size_subarray;
|
||||
@@ -165,6 +166,7 @@ static void type_append_name_to_scratch(Type *type)
|
||||
case TYPE_INFERRED_ARRAY:
|
||||
case TYPE_INFERRED_VECTOR:
|
||||
case TYPE_TYPEINFO:
|
||||
case TYPE_MEMBER:
|
||||
UNREACHABLE
|
||||
break;
|
||||
case TYPE_FUNC:
|
||||
@@ -223,6 +225,7 @@ const char *type_to_error_string(Type *type)
|
||||
case TYPE_ANYERR:
|
||||
case TYPE_UNTYPED_LIST:
|
||||
case TYPE_ANY:
|
||||
case TYPE_MEMBER:
|
||||
return type->name;
|
||||
case TYPE_FUNC:
|
||||
scratch_buffer_clear();
|
||||
@@ -400,6 +403,7 @@ bool type_is_abi_aggregate(Type *type)
|
||||
case TYPE_UNTYPED_LIST:
|
||||
case TYPE_FLEXIBLE_ARRAY:
|
||||
case TYPE_SCALED_VECTOR:
|
||||
case TYPE_MEMBER:
|
||||
UNREACHABLE
|
||||
}
|
||||
UNREACHABLE
|
||||
@@ -487,6 +491,7 @@ void type_mangle_introspect_name_to_buffer(Type *type)
|
||||
case TYPE_INFERRED_VECTOR:
|
||||
case TYPE_UNTYPED_LIST:
|
||||
case TYPE_FAILABLE_ANY:
|
||||
case TYPE_MEMBER:
|
||||
UNREACHABLE
|
||||
case TYPE_VOID:
|
||||
case TYPE_BOOL:
|
||||
@@ -583,6 +588,7 @@ AlignSize type_abi_alignment(Type *type)
|
||||
case TYPE_POISONED:
|
||||
case TYPE_TYPEINFO:
|
||||
case TYPE_UNTYPED_LIST:
|
||||
case TYPE_MEMBER:
|
||||
UNREACHABLE;
|
||||
case TYPE_BITSTRUCT:
|
||||
type = type->decl->bitstruct.base_type->type;
|
||||
@@ -1420,6 +1426,7 @@ void type_setup(PlatformTarget *target)
|
||||
type_init_int("void", &t.u0, TYPE_VOID, BITS8);
|
||||
|
||||
type_create("typeinfo", &t.typeinfo, TYPE_TYPEINFO, 1, 1, 1);
|
||||
type_create("member_ref", &t.member, TYPE_MEMBER, 1, 1, 1);
|
||||
type_create("untyped_list", &t.untyped_list, TYPE_UNTYPED_LIST, 1, 1, 1);
|
||||
type_create("void!", &t.anyfail, TYPE_FAILABLE_ANY, 1, 1, 1);
|
||||
type_init("typeid", &t.typeid, TYPE_TYPEID, target->width_pointer, target->align_pointer);
|
||||
@@ -1636,6 +1643,7 @@ bool type_may_have_method(Type *type)
|
||||
case TYPE_OPTIONAL:
|
||||
case TYPE_FAILABLE_ANY:
|
||||
case TYPE_TYPEINFO:
|
||||
case TYPE_MEMBER:
|
||||
return false;
|
||||
}
|
||||
UNREACHABLE
|
||||
@@ -1857,10 +1865,12 @@ Type *type_find_max_type(Type *type, Type *other)
|
||||
type = other->function.prototype->raw_type;
|
||||
return other == type ? type : NULL;
|
||||
case TYPE_UNION:
|
||||
case TYPE_TYPEID:
|
||||
case TYPE_STRUCT:
|
||||
case TYPE_UNTYPED_LIST:
|
||||
TODO
|
||||
case TYPE_TYPEID:
|
||||
case TYPE_MEMBER:
|
||||
return NULL;
|
||||
case TYPE_TYPEDEF:
|
||||
UNREACHABLE
|
||||
case TYPE_DISTINCT:
|
||||
@@ -1985,6 +1995,7 @@ unsigned type_get_introspection_kind(TypeKind kind)
|
||||
case TYPE_FAILABLE_ANY:
|
||||
case TYPE_TYPEINFO:
|
||||
case TYPE_OPTIONAL:
|
||||
case TYPE_MEMBER:
|
||||
UNREACHABLE
|
||||
return 0;
|
||||
}
|
||||
@@ -2035,6 +2046,7 @@ Module *type_base_module(Type *type)
|
||||
case TYPE_UNTYPED_LIST:
|
||||
case TYPE_FAILABLE_ANY:
|
||||
case TYPE_TYPEINFO:
|
||||
case TYPE_MEMBER:
|
||||
UNREACHABLE
|
||||
}
|
||||
UNREACHABLE
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.3.73"
|
||||
#define COMPILER_VERSION "0.3.74"
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user