mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Prepare for struct refactoring.
This commit is contained in:
@@ -974,6 +974,46 @@ func void testMethodFunctions()
|
||||
printf("%d %d %d\n", x.x.x, x.x.y, x.x.z);
|
||||
}
|
||||
|
||||
enum TestEnumSize : ushort
|
||||
{
|
||||
BLURB
|
||||
}
|
||||
|
||||
enum TestEnumSizeDefault
|
||||
{
|
||||
BLURB
|
||||
}
|
||||
|
||||
struct TestStructSize
|
||||
{
|
||||
char x;
|
||||
long y;
|
||||
}
|
||||
|
||||
struct TestStructInt
|
||||
{
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
}
|
||||
|
||||
union TestUnionSize
|
||||
{
|
||||
short a;
|
||||
int b;
|
||||
char[5] c;
|
||||
}
|
||||
func void testTypeValues()
|
||||
{
|
||||
TestUnionSize.a.sizeof;
|
||||
printf("Enum size: %d = 2\n", TestEnumSize.sizeof);
|
||||
printf("Enum size: %d = 4\n", TestEnumSizeDefault.sizeof);
|
||||
printf("Struct size: %d = 12\n", TestStructInt.sizeof);
|
||||
printf("Struct size: %d = 16\n", TestStructSize.sizeof);
|
||||
printf("Union size: %d = 5\n", TestUnionSize.sizeof);
|
||||
printf("Error size: %d = 4\n", Err.sizeof);
|
||||
}
|
||||
|
||||
func int main(int x)
|
||||
{
|
||||
printf("Helo!\n");
|
||||
@@ -990,6 +1030,7 @@ func int main(int x)
|
||||
testExprBlock();
|
||||
testFuncPointer();
|
||||
testMethodFunctions();
|
||||
testTypeValues();
|
||||
int efd = 9;
|
||||
uint fefoek = 1;
|
||||
printf("Helo: %d\n", efd + cast(fefoek, int));
|
||||
|
||||
@@ -335,6 +335,10 @@ void fprint_type_recursive(FILE *file, Type *type, int indent)
|
||||
case TYPE_ERROR:
|
||||
DUMPF("(error %s)", type->name);
|
||||
return;
|
||||
case TYPE_MEMBER:
|
||||
DUMPF("(member %s", type->name);
|
||||
DUMPTYPE(type->decl->parent_struct->type);
|
||||
DUMPEND();
|
||||
case TYPE_TYPEDEF:
|
||||
DUMPF("(typedef %s", type->name);
|
||||
DUMPTYPE(type->canonical);
|
||||
|
||||
@@ -189,7 +189,7 @@ struct _Type
|
||||
void *backend_debug_type;
|
||||
union
|
||||
{
|
||||
// Error, Struct, Union, Typedef
|
||||
// Error, Struct, Union, Typedef, Member
|
||||
Decl *decl;
|
||||
// int, float, bool
|
||||
TypeBuiltin builtin;
|
||||
@@ -415,7 +415,7 @@ typedef struct _Decl
|
||||
union
|
||||
{
|
||||
Decl* parent_struct;
|
||||
Decl** method_functions;
|
||||
Decl** methods;
|
||||
};
|
||||
union
|
||||
{
|
||||
@@ -471,7 +471,7 @@ typedef struct
|
||||
union
|
||||
{
|
||||
Token name;
|
||||
Decl *method;
|
||||
Decl *decl;
|
||||
};
|
||||
} ExprTypeAccess;
|
||||
|
||||
@@ -949,7 +949,7 @@ typedef struct _Context
|
||||
Decl **error_types;
|
||||
Decl **types;
|
||||
Decl **functions;
|
||||
Decl **method_functions;
|
||||
Decl **methods;
|
||||
Decl **vars;
|
||||
Decl **ct_ifs;
|
||||
Ast **defers;
|
||||
@@ -1021,6 +1021,13 @@ typedef struct
|
||||
Type **type;
|
||||
} Compiler;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MODULE_SYMBOL_SEARCH_EXTERNAL,
|
||||
MODULE_SYMBOL_SEARCH_PARENT,
|
||||
MODULE_SYMBOL_SEARCH_THIS
|
||||
} ModuleSymbolSearch;
|
||||
|
||||
extern Compiler compiler;
|
||||
extern Ast *poisoned_ast;
|
||||
extern Decl *poisoned_decl;
|
||||
@@ -1041,7 +1048,8 @@ extern Type *type_typeid, *type_error_union, *type_error_base;
|
||||
|
||||
extern const char *attribute_list[NUMBER_OF_ATTRIBUTES];
|
||||
|
||||
extern const char *main_kw;
|
||||
extern const char *kw_main;
|
||||
extern const char *kw_sizeof;
|
||||
|
||||
#define AST_NEW_TOKEN(_kind, _token) new_ast(_kind, _token.span)
|
||||
#define AST_NEW(_kind, _loc) new_ast(_kind, _loc)
|
||||
@@ -1202,12 +1210,6 @@ void lexer_init_with_file(Lexer *lexer, File *file);
|
||||
File* lexer_current_file(Lexer *lexer);
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MODULE_SYMBOL_SEARCH_EXTERNAL,
|
||||
MODULE_SYMBOL_SEARCH_PARENT,
|
||||
MODULE_SYMBOL_SEARCH_THIS
|
||||
} ModuleSymbolSearch;
|
||||
|
||||
Decl *module_find_symbol(Module *module, const char *symbol, ModuleSymbolSearch search);
|
||||
|
||||
@@ -1306,7 +1308,7 @@ static inline bool type_is_signed(Type *type) { return type->type_kind >= TYPE_I
|
||||
static inline bool type_is_unsigned(Type *type) { return type->type_kind >= TYPE_U8 && type->type_kind <= TYPE_U64; }
|
||||
static inline bool type_ok(Type *type) { return !type || type->type_kind != TYPE_POISONED; }
|
||||
static inline bool type_info_ok(TypeInfo *type_info) { return !type_info || type_info->kind != TYPE_INFO_POISON; }
|
||||
bool type_may_have_method_functions(Type *type);
|
||||
bool type_may_have_method(Type *type);
|
||||
|
||||
static inline Type *type_reduced(Type *type)
|
||||
{
|
||||
|
||||
@@ -96,7 +96,7 @@ void context_register_global_decl(Context *context, Decl *decl)
|
||||
case DECL_FUNC:
|
||||
if (decl->func.type_parent)
|
||||
{
|
||||
vec_add(context->method_functions, decl);
|
||||
vec_add(context->methods, decl);
|
||||
// TODO set name
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -507,6 +507,7 @@ typedef enum
|
||||
TYPE_VARARRAY,
|
||||
TYPE_SUBARRAY,
|
||||
TYPE_TYPEID,
|
||||
TYPE_MEMBER,
|
||||
TYPE_LAST = TYPE_TYPEID
|
||||
} TypeKind;
|
||||
|
||||
|
||||
@@ -358,9 +358,9 @@ void llvm_codegen(Context *context)
|
||||
{
|
||||
gencontext_emit_extern_decl(&gen_context, context->external_symbol_list[i]);
|
||||
}
|
||||
VECEACH(context->method_functions, i)
|
||||
VECEACH(context->methods, i)
|
||||
{
|
||||
gencontext_emit_function_decl(&gen_context, context->method_functions[i]);
|
||||
gencontext_emit_function_decl(&gen_context, context->methods[i]);
|
||||
}
|
||||
VECEACH(context->functions, i)
|
||||
{
|
||||
@@ -383,9 +383,9 @@ void llvm_codegen(Context *context)
|
||||
Decl *decl = context->functions[i];
|
||||
if (decl->func.body) gencontext_emit_function_body(&gen_context, decl);
|
||||
}
|
||||
VECEACH(context->method_functions, i)
|
||||
VECEACH(context->methods, i)
|
||||
{
|
||||
Decl *decl = context->method_functions[i];
|
||||
Decl *decl = context->methods[i];
|
||||
if (decl->func.body) gencontext_emit_function_body(&gen_context, decl);
|
||||
}
|
||||
|
||||
|
||||
@@ -108,6 +108,7 @@ LLVMMetadataRef gencontext_get_debug_type(GenContext *context, Type *type)
|
||||
case TYPE_IXX:
|
||||
case TYPE_FXX:
|
||||
case TYPE_TYPEID:
|
||||
case TYPE_MEMBER:
|
||||
UNREACHABLE
|
||||
case TYPE_BOOL:
|
||||
return gencontext_simple_debug_type(context, type, DW_ATE_boolean);
|
||||
|
||||
@@ -165,7 +165,9 @@ LLVMTypeRef llvm_get_type(LLVMContextRef context, Type *type)
|
||||
DEBUG_LOG("Generating type %s", type->name);
|
||||
switch (type->type_kind)
|
||||
{
|
||||
case TYPE_MEMBER:
|
||||
case TYPE_POISONED:
|
||||
UNREACHABLE
|
||||
case TYPE_TYPEID:
|
||||
return type->backend_type = LLVMIntTypeInContext(context, type->builtin.bitsize);
|
||||
case TYPE_ERROR:
|
||||
|
||||
@@ -1528,7 +1528,7 @@ static inline Decl *parse_func_definition(Context *context, Visibility visibilit
|
||||
func->func.type_parent = type;
|
||||
advance_and_verify(context, TOKEN_TYPE_IDENT);
|
||||
|
||||
TRY_CONSUME_OR(TOKEN_DOT, "Expected '.' after the type in a method function.", poisoned_decl);
|
||||
TRY_CONSUME_OR(TOKEN_DOT, "Expected '.' after the type in a method declaration.", poisoned_decl);
|
||||
}
|
||||
|
||||
EXPECT_IDENT_FOR_OR("function name", poisoned_decl);
|
||||
|
||||
@@ -796,6 +796,7 @@ CastKind cast_to_bool_kind(Type *type)
|
||||
case TYPE_ERROR:
|
||||
case TYPE_ENUM:
|
||||
case TYPE_FUNC:
|
||||
case TYPE_MEMBER:
|
||||
case TYPE_ARRAY:
|
||||
case TYPE_VARARRAY:
|
||||
case TYPE_SUBARRAY:
|
||||
@@ -835,6 +836,7 @@ bool cast(Expr *expr, Type *to_type, CastType cast_type)
|
||||
case TYPE_POISONED:
|
||||
case TYPE_VOID:
|
||||
case TYPE_TYPEID:
|
||||
case TYPE_MEMBER:
|
||||
break;
|
||||
case TYPE_BOOL:
|
||||
// Bool may convert into integers and floats but only explicitly.
|
||||
|
||||
@@ -410,30 +410,30 @@ static inline bool sema_analyse_enum(Context *context, Decl *decl)
|
||||
|
||||
|
||||
|
||||
static inline bool sema_analyse_method_function(Context *context, Decl *decl)
|
||||
static inline bool sema_analyse_method(Context *context, Decl *decl)
|
||||
{
|
||||
TypeInfo *parent_type = decl->func.type_parent;
|
||||
if (!sema_resolve_type_info(context, parent_type)) return false;
|
||||
if (!type_may_have_method_functions(parent_type->type))
|
||||
if (!type_may_have_method(parent_type->type))
|
||||
{
|
||||
SEMA_ERROR(decl,
|
||||
"Method functions can not be associated with '%s'",
|
||||
"Methods can not be associated with '%s'",
|
||||
type_to_error_string(decl->func.type_parent->type));
|
||||
return false;
|
||||
}
|
||||
Decl *parent = parent_type->type->decl;
|
||||
VECEACH(parent->method_functions, i)
|
||||
VECEACH(parent->methods, i)
|
||||
{
|
||||
Decl *function = parent->method_functions[i];
|
||||
Decl *function = parent->methods[i];
|
||||
if (function->name == decl->name)
|
||||
{
|
||||
SEMA_ERROR(decl, "Duplicate name '%s' for method function.", function->name);
|
||||
SEMA_ERROR(decl, "Duplicate name '%s' for method.", function->name);
|
||||
SEMA_PREV(function, "Previous definition here.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
DEBUG_LOG("Method function '%s.%s' analysed.", parent->name, decl->name);
|
||||
vec_add(parent->method_functions, decl);
|
||||
DEBUG_LOG("Method '%s.%s' analysed.", parent->name, decl->name);
|
||||
vec_add(parent->methods, decl);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -563,7 +563,7 @@ static inline bool sema_analyse_func(Context *context, Decl *decl)
|
||||
if (!func_type) return decl_poison(decl);
|
||||
if (decl->func.type_parent)
|
||||
{
|
||||
if (!sema_analyse_method_function(context, decl)) return decl_poison(decl);
|
||||
if (!sema_analyse_method(context, decl)) return decl_poison(decl);
|
||||
}
|
||||
VECEACH(decl->attributes, i)
|
||||
{
|
||||
@@ -608,7 +608,7 @@ static inline bool sema_analyse_func(Context *context, Decl *decl)
|
||||
return decl_poison(decl);
|
||||
}
|
||||
}
|
||||
if (decl->name == main_kw)
|
||||
if (decl->name == kw_main)
|
||||
{
|
||||
if (decl->visibility == VISIBLE_LOCAL)
|
||||
{
|
||||
|
||||
@@ -480,7 +480,7 @@ static inline bool sema_expr_analyse_call(Context *context, Type *to, Expr *expr
|
||||
switch (func_expr->expr_kind)
|
||||
{
|
||||
case EXPR_TYPE_ACCESS:
|
||||
decl = func_expr->type_access.method;
|
||||
decl = func_expr->type_access.decl;
|
||||
break;
|
||||
case EXPR_IDENTIFIER:
|
||||
decl = func_expr->identifier_expr.decl;
|
||||
@@ -641,12 +641,12 @@ static inline bool sema_expr_analyse_subscript(Context *context, Type *to, Expr
|
||||
return sema_expr_analyse_subscript_after_parent_resolution(context, NULL, expr);
|
||||
}
|
||||
|
||||
static inline bool sema_expr_analyse_method_function(Context *context, Expr *expr, Decl *decl, bool is_pointer)
|
||||
static inline bool sema_expr_analyse_method(Context *context, Expr *expr, Decl *decl, bool is_pointer)
|
||||
{
|
||||
const char *name = expr->access_expr.sub_element.string;
|
||||
VECEACH(decl->method_functions, i)
|
||||
VECEACH(decl->methods, i)
|
||||
{
|
||||
Decl *function = decl->method_functions[i];
|
||||
Decl *function = decl->methods[i];
|
||||
if (function->name == name)
|
||||
{
|
||||
expr->access_expr.ref = function;
|
||||
@@ -657,11 +657,11 @@ static inline bool sema_expr_analyse_method_function(Context *context, Expr *exp
|
||||
|
||||
if (decl_is_struct_type(decl))
|
||||
{
|
||||
SEMA_ERROR(expr, "There is no element nor method function '%s.%s'.", decl->name, name);
|
||||
SEMA_ERROR(expr, "There is no element nor method '%s.%s'.", decl->name, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
SEMA_ERROR(expr, "Cannot find method function '%s.%s'", decl->name, name);
|
||||
SEMA_ERROR(expr, "Cannot find method '%s.%s'", decl->name, name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -706,7 +706,7 @@ static inline bool sema_expr_analyse_access(Context *context, Expr *expr)
|
||||
{
|
||||
type = type->pointer;
|
||||
}
|
||||
if (!type_may_have_method_functions(type))
|
||||
if (!type_may_have_method(type))
|
||||
{
|
||||
SEMA_ERROR(expr, "Cannot access '%s' on '%s'", expr->access_expr.sub_element.string, type_to_error_string(parent_type));
|
||||
return false;
|
||||
@@ -716,7 +716,7 @@ static inline bool sema_expr_analyse_access(Context *context, Expr *expr)
|
||||
{
|
||||
case DECL_ENUM:
|
||||
case DECL_ERROR:
|
||||
return sema_expr_analyse_method_function(context, expr, decl, is_pointer);
|
||||
return sema_expr_analyse_method(context, expr, decl, is_pointer);
|
||||
case DECL_STRUCT:
|
||||
case DECL_UNION:
|
||||
break;
|
||||
@@ -726,7 +726,7 @@ static inline bool sema_expr_analyse_access(Context *context, Expr *expr)
|
||||
Decl *member = strukt_recursive_search_member(decl, expr->access_expr.sub_element.string);
|
||||
if (!member)
|
||||
{
|
||||
return sema_expr_analyse_method_function(context, expr, decl, is_pointer);
|
||||
return sema_expr_analyse_method(context, expr, decl, is_pointer);
|
||||
return false;
|
||||
}
|
||||
if (is_pointer)
|
||||
@@ -743,6 +743,13 @@ static inline bool sema_expr_analyse_access(Context *context, Expr *expr)
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void expr_rewrite_to_int_const(Expr *expr_to_rewrite, Type *type, uint64_t value)
|
||||
{
|
||||
expr_to_rewrite->expr_kind = EXPR_CONST;
|
||||
expr_const_set_int(&expr_to_rewrite->const_expr, value, type->canonical->type_kind);
|
||||
expr_to_rewrite->type = type;
|
||||
expr_to_rewrite->resolve_status = true;
|
||||
}
|
||||
|
||||
static inline bool sema_expr_analyse_type_access(Context *context, Type *to, Expr *expr)
|
||||
{
|
||||
@@ -757,9 +764,9 @@ static inline bool sema_expr_analyse_type_access(Context *context, Type *to, Exp
|
||||
expr->resolve_status = RESOLVE_DONE;
|
||||
return true;
|
||||
}
|
||||
if (!type_may_have_method_functions(canonical))
|
||||
if (!type_may_have_method(canonical))
|
||||
{
|
||||
SEMA_ERROR(expr, "'%s' does not have method functions.", type_to_error_string(type_info->type));
|
||||
SEMA_ERROR(expr, "'%s' does not have methods.", type_to_error_string(type_info->type));
|
||||
return false;
|
||||
}
|
||||
Decl *decl = canonical->decl;
|
||||
@@ -777,6 +784,11 @@ static inline bool sema_expr_analyse_type_access(Context *context, Type *to, Exp
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (expr->type_access.name.start == kw_sizeof)
|
||||
{
|
||||
expr_rewrite_to_int_const(expr, type_usize, type_size(decl->enums.type_info->type));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case DECL_ERROR:
|
||||
if (expr->type_access.name.type == TOKEN_CONST_IDENT)
|
||||
@@ -788,24 +800,46 @@ static inline bool sema_expr_analyse_type_access(Context *context, Type *to, Exp
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (expr->type_access.name.start == kw_sizeof)
|
||||
{
|
||||
expr_rewrite_to_int_const(expr, type_usize, type_size(type_error_base->canonical));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case DECL_UNION:
|
||||
case DECL_STRUCT:
|
||||
if (expr->type_access.name.start == kw_sizeof)
|
||||
{
|
||||
expr_rewrite_to_int_const(expr, type_usize, type_size(decl->type));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE
|
||||
}
|
||||
VECEACH(type_info->type->decl->method_functions, i)
|
||||
|
||||
|
||||
VECEACH(decl->methods, i)
|
||||
{
|
||||
Decl *function = type_info->type->decl->method_functions[i];
|
||||
Decl *function = decl->methods[i];
|
||||
if (expr->type_access.name.string == function->name)
|
||||
{
|
||||
expr->type_access.method = function;
|
||||
expr->type = function->func.function_signature.rtype->type;
|
||||
expr->type_access.decl = function;
|
||||
expr->type = function->type;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
SEMA_ERROR(expr, "No function '%s.%s' found.", type_to_error_string(type_info->type), expr->type_access.name.string);
|
||||
VECEACH(decl->strukt.members, i)
|
||||
{
|
||||
Decl *member = decl->strukt.members[i];
|
||||
if (expr->type_access.name.string == member->name)
|
||||
{
|
||||
expr->type_access.decl = member;
|
||||
expr->type = member->type;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
SEMA_ERROR(expr, "No function or member '%s.%s' found.", type_to_error_string(type_info->type), expr->type_access.name.string);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2018,6 +2052,7 @@ static bool sema_expr_analyse_comp(Context *context, Expr *expr, Expr *left, Exp
|
||||
case TYPE_VARARRAY:
|
||||
case TYPE_SUBARRAY:
|
||||
case TYPE_TYPEID:
|
||||
case TYPE_MEMBER:
|
||||
// Only != and == allowed.
|
||||
goto ERR;
|
||||
case ALL_INTS:
|
||||
@@ -2259,6 +2294,7 @@ static bool sema_expr_analyse_not(Context *context, Type *to, Expr *expr, Expr *
|
||||
case TYPE_ENUM:
|
||||
case TYPE_ERROR:
|
||||
case TYPE_TYPEID:
|
||||
case TYPE_MEMBER:
|
||||
SEMA_ERROR(expr, "Cannot use 'not' on %s", type_to_error_string(inner->type));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -114,9 +114,9 @@ void sema_analysis_pass_decls(Context *context)
|
||||
{
|
||||
sema_analyse_decl(context, context->error_types[i]);
|
||||
}
|
||||
VECEACH(context->method_functions, i)
|
||||
VECEACH(context->methods, i)
|
||||
{
|
||||
sema_analyse_decl(context, context->method_functions[i]);
|
||||
sema_analyse_decl(context, context->methods[i]);
|
||||
}
|
||||
VECEACH(context->vars, i)
|
||||
{
|
||||
@@ -126,9 +126,9 @@ void sema_analysis_pass_decls(Context *context)
|
||||
{
|
||||
sema_analyse_decl(context, context->functions[i]);
|
||||
}
|
||||
VECEACH(context->method_functions, i)
|
||||
VECEACH(context->methods, i)
|
||||
{
|
||||
analyse_func_body(context, context->method_functions[i]);
|
||||
analyse_func_body(context, context->methods[i]);
|
||||
}
|
||||
VECEACH(context->functions, i)
|
||||
{
|
||||
|
||||
@@ -36,7 +36,8 @@ static SymTab symtab;
|
||||
|
||||
const char *attribute_list[NUMBER_OF_ATTRIBUTES];
|
||||
|
||||
const char *main_kw;
|
||||
const char *kw_main;
|
||||
const char *kw_sizeof;
|
||||
|
||||
void symtab_init(uint32_t capacity)
|
||||
{
|
||||
@@ -70,7 +71,8 @@ void symtab_init(uint32_t capacity)
|
||||
// Init some constant idents
|
||||
TokenType type = TOKEN_IDENT;
|
||||
#define KW_DEF(x) symtab_add(x, sizeof(x) - 1, fnv1a(x, sizeof(x) - 1), &type)
|
||||
main_kw = KW_DEF("main");
|
||||
kw_main = KW_DEF("main");
|
||||
kw_sizeof = KW_DEF("sizeof");
|
||||
attribute_list[ATTRIBUTE_INLINE] = KW_DEF("inline");
|
||||
attribute_list[ATTRIBUTE_NOINLINE] = KW_DEF("noinline");
|
||||
attribute_list[ATTRIBUTE_STDCALL] = KW_DEF("stdcall");
|
||||
|
||||
@@ -133,6 +133,8 @@ const char *type_to_error_string(Type *type)
|
||||
}
|
||||
asprintf(&buffer, "%s*", type_to_error_string(type->pointer));
|
||||
return buffer;
|
||||
case TYPE_MEMBER:
|
||||
return "member";
|
||||
case TYPE_STRING:
|
||||
return "string";
|
||||
case TYPE_ARRAY:
|
||||
@@ -236,6 +238,8 @@ size_t type_size(Type *canonical)
|
||||
case ALL_INTS:
|
||||
case ALL_FLOATS:
|
||||
return canonical->builtin.bytesize;
|
||||
case TYPE_MEMBER:
|
||||
return type_size(canonical->decl->var.type_info->type);
|
||||
case TYPE_FUNC:
|
||||
case TYPE_POINTER:
|
||||
case TYPE_VARARRAY:
|
||||
@@ -272,6 +276,8 @@ unsigned int type_abi_alignment(Type *canonical)
|
||||
case ALL_FLOATS:
|
||||
case TYPE_ERROR_UNION:
|
||||
return canonical->builtin.abi_alignment;
|
||||
case TYPE_MEMBER:
|
||||
return type_abi_alignment(canonical->decl->var.type_info->type);
|
||||
case TYPE_FUNC:
|
||||
case TYPE_POINTER:
|
||||
case TYPE_VARARRAY:
|
||||
@@ -552,7 +558,7 @@ bool type_is_subtype(Type *type, Type *possible_subtype)
|
||||
}
|
||||
|
||||
|
||||
bool type_may_have_method_functions(Type *type)
|
||||
bool type_may_have_method(Type *type)
|
||||
{
|
||||
// An alias is not ok.
|
||||
switch (type->type_kind)
|
||||
@@ -737,6 +743,7 @@ Type *type_find_max_type(Type *type, Type *other)
|
||||
case TYPE_ERROR:
|
||||
if (other->type_kind == TYPE_ERROR) return type_error_union;
|
||||
return NULL;
|
||||
case TYPE_MEMBER:
|
||||
case TYPE_FUNC:
|
||||
case TYPE_UNION:
|
||||
case TYPE_ERROR_UNION:
|
||||
|
||||
Reference in New Issue
Block a user