mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-29 19:00:06 +00:00
fmt.String_Buffer, Fix issue #44, Tweak overloading rules
This commit is contained in:
+43
-32
@@ -413,7 +413,7 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count
|
||||
}
|
||||
|
||||
|
||||
void check_alias_decl(Checker *c, Entity *e, AstNode *expr) {
|
||||
void check_alias_decl(Checker *c, Entity *e, AstNode *expr, Type *named_type) {
|
||||
GB_ASSERT(e->type == NULL);
|
||||
GB_ASSERT(e->kind == Entity_Alias);
|
||||
|
||||
@@ -431,36 +431,47 @@ void check_alias_decl(Checker *c, Entity *e, AstNode *expr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (expr->kind == AstNode_Ident) {
|
||||
Operand o = {0};
|
||||
Entity *f = check_ident(c, &o, expr, NULL, NULL, true);
|
||||
if (f != NULL) {
|
||||
e->Alias.original = f;
|
||||
e->type = f->type;
|
||||
}
|
||||
return;
|
||||
} else if (expr->kind == AstNode_SelectorExpr) {
|
||||
Operand o = {0};
|
||||
Entity *f = check_selector(c, &o, expr, NULL);
|
||||
if (f != NULL) {
|
||||
e->Alias.original = f;
|
||||
e->type = f->type;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Operand o = {0};
|
||||
check_expr_or_type(c, &o, expr);
|
||||
if (o.mode == Addressing_Invalid) {
|
||||
return;
|
||||
}
|
||||
switch (o.mode) {
|
||||
case Addressing_Type:
|
||||
e->type = o.type;
|
||||
break;
|
||||
default:
|
||||
Operand operand = {0};
|
||||
check_expr_or_type(c, &operand, expr);
|
||||
if (operand.mode != Addressing_Type) {
|
||||
error_node(expr, "#alias declarations only allow types");
|
||||
return;
|
||||
}
|
||||
e->kind = Entity_TypeName;
|
||||
e->TypeName.is_type_alias = true;
|
||||
e->type = NULL;
|
||||
|
||||
DeclInfo *d = c->context.decl;
|
||||
d->type_expr = expr;
|
||||
check_type_decl(c, e, d->type_expr, named_type);
|
||||
|
||||
|
||||
// Operand o = {0};
|
||||
// Entity *f = NULL;
|
||||
// if (expr->kind == AstNode_Ident) {
|
||||
// f = check_ident(c, &o, expr, NULL, NULL, true);
|
||||
// } else if (expr->kind == AstNode_SelectorExpr) {
|
||||
// f = check_selector(c, &o, expr, NULL);
|
||||
// } else {
|
||||
// check_expr_or_type(c, &o, expr);
|
||||
// }
|
||||
// if (o.mode == Addressing_Invalid) {
|
||||
// return;
|
||||
// }
|
||||
// switch (o.mode) {
|
||||
// case Addressing_Type:
|
||||
// e->type = o.type;
|
||||
// // e->kind = Entity_TypeName;
|
||||
// // e->TypeName.is_type_alias = true;
|
||||
// e->Alias.kind = EntityAlias_Type;
|
||||
// e->Alias.original = f;
|
||||
// break;
|
||||
// default:
|
||||
// error_node(expr, "#alias declarations only allow types");
|
||||
// e->kind = Entity_Invalid;
|
||||
// e->type = t_invalid;
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
|
||||
void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
|
||||
@@ -495,12 +506,12 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
|
||||
case Entity_TypeName:
|
||||
check_type_decl(c, e, d->type_expr, named_type);
|
||||
break;
|
||||
case Entity_Alias:
|
||||
check_alias_decl(c, e, d->init_expr, named_type);
|
||||
break;
|
||||
case Entity_Procedure:
|
||||
check_proc_lit(c, e, d);
|
||||
break;
|
||||
case Entity_Alias:
|
||||
check_alias_decl(c, e, d->init_expr);
|
||||
break;
|
||||
}
|
||||
|
||||
c->context = prev;
|
||||
|
||||
+45
-20
@@ -147,7 +147,31 @@ i64 check_distance_between_types(Checker *c, Operand *operand, Type *type) {
|
||||
if (dst->kind == Type_Basic) {
|
||||
if (operand->mode == Addressing_Constant) {
|
||||
if (check_representable_as_constant(c, operand->value, dst, NULL)) {
|
||||
return 1;
|
||||
if (is_type_typed(dst) && src->kind == Type_Basic) {
|
||||
switch (src->Basic.kind) {
|
||||
case Basic_UntypedInteger:
|
||||
if (is_type_integer(dst)) {
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case Basic_UntypedFloat:
|
||||
if (is_type_float(dst)) {
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case Basic_UntypedComplex:
|
||||
if (is_type_complex(dst)) {
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case Basic_UntypedQuaternion:
|
||||
if (is_type_quaternion(dst)) {
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -1058,12 +1082,7 @@ Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) {
|
||||
case 32: new_type = t_u32; break;
|
||||
case 64: new_type = t_u64; break;
|
||||
default:
|
||||
// NOTE(bill): It could be an empty struct that is passed
|
||||
// and if that is the case, no need to pass by pointer
|
||||
// (I think..)
|
||||
if (size > 0) {
|
||||
new_type = make_type_pointer(a, original_type);
|
||||
}
|
||||
new_type = make_type_pointer(a, original_type);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
@@ -1196,11 +1215,6 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
|
||||
|
||||
e->flags |= EntityFlag_Used;
|
||||
|
||||
Entity *original_e = e;
|
||||
while (e != NULL && e->kind == Entity_Alias && e->Alias.original != NULL) {
|
||||
e = e->Alias.original;
|
||||
}
|
||||
|
||||
Type *type = e->type;
|
||||
switch (e->kind) {
|
||||
case Entity_Constant:
|
||||
@@ -1261,6 +1275,17 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
|
||||
o->mode = Addressing_Value;
|
||||
break;
|
||||
|
||||
case Entity_Alias: {
|
||||
// error_node(n, "#alias entities are not yet supported");
|
||||
// TODO(bill): Fix Entity_Alias rules
|
||||
if (e->Alias.kind == EntityAlias_Type) {
|
||||
o->mode = Addressing_Type;
|
||||
} else {
|
||||
o->mode = Addressing_Invalid;
|
||||
return e;
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
compiler_error("Unknown EntityKind");
|
||||
break;
|
||||
@@ -3136,6 +3161,11 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
|
||||
operand->builtin_id = entity->Builtin.id;
|
||||
break;
|
||||
|
||||
case Entity_Alias: {
|
||||
error_node(selector, "#alias entities are not yet supported");
|
||||
return NULL;
|
||||
} break;
|
||||
|
||||
// NOTE(bill): These cases should never be hit but are here for sanity reasons
|
||||
case Entity_Nil:
|
||||
operand->mode = Addressing_Value;
|
||||
@@ -3899,8 +3929,6 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
Operand z = {0};
|
||||
Operand w = {0};
|
||||
|
||||
GB_PANIC("BuiltinProc_quaternion");
|
||||
|
||||
// NOTE(bill): Invalid will be the default till fixed
|
||||
operand->type = t_invalid;
|
||||
operand->mode = Addressing_Invalid;
|
||||
@@ -3990,12 +4018,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
|
||||
BasicKind kind = core_type(x.type)->Basic.kind;
|
||||
switch (kind) {
|
||||
case Basic_complex64: x.type = t_f32; break;
|
||||
case Basic_complex128: x.type = t_f64; break;
|
||||
case Basic_UntypedComplex: x.type = t_untyped_float; break;
|
||||
case Basic_quaternion128: x.type = t_f32; break;
|
||||
case Basic_quaternion256: x.type = t_f64; break;
|
||||
case Basic_UntypedQuaternion: x.type = t_untyped_float; break;
|
||||
case Basic_f32: operand->type = t_quaternion128; break;
|
||||
case Basic_f64: operand->type = t_quaternion256; break;
|
||||
case Basic_UntypedFloat: operand->type = t_untyped_quaternion; break;
|
||||
default: GB_PANIC("Invalid type"); break;
|
||||
}
|
||||
} break;
|
||||
|
||||
+130
-112
@@ -432,6 +432,134 @@ void check_label(Checker *c, AstNode *label) {
|
||||
}
|
||||
}
|
||||
|
||||
// Returns `true` for `continue`, `false` for `return`
|
||||
bool check_using_stmt_entity(Checker *c, AstNodeUsingStmt *us, AstNode *expr, bool is_selector, Entity *e) {
|
||||
if (e == NULL) {
|
||||
error(us->token, "`using` applied to an unknown entity");
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (e->kind) {
|
||||
case Entity_Alias: {
|
||||
if (e->Alias.original != NULL) {
|
||||
check_using_stmt_entity(c, us, expr, is_selector, e->Alias.original);
|
||||
} else {
|
||||
error(us->token, "`using` cannot be applied to the alias `%.*s`", LIT(e->token.string));
|
||||
return false;
|
||||
}
|
||||
} break;
|
||||
|
||||
case Entity_TypeName: {
|
||||
Type *t = base_type(e->type);
|
||||
if (is_type_union(t)) {
|
||||
TokenPos pos = ast_node_token(expr).pos;
|
||||
for (isize i = 1; i < t->Record.variant_count; i++) {
|
||||
Entity *f = t->Record.variants[i];
|
||||
// gb_printf_err("%s\n", type_to_string(f->type));
|
||||
Entity *found = scope_insert_entity(c->context.scope, f);
|
||||
if (found != NULL) {
|
||||
gbString expr_str = expr_to_string(expr);
|
||||
error(us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string));
|
||||
gb_string_free(expr_str);
|
||||
return false;
|
||||
}
|
||||
f->using_parent = e;
|
||||
}
|
||||
} else if (is_type_enum(t)) {
|
||||
for (isize i = 0; i < t->Record.field_count; i++) {
|
||||
Entity *f = t->Record.fields[i];
|
||||
Entity *found = scope_insert_entity(c->context.scope, f);
|
||||
if (found != NULL) {
|
||||
gbString expr_str = expr_to_string(expr);
|
||||
error(us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string));
|
||||
gb_string_free(expr_str);
|
||||
return false;
|
||||
}
|
||||
f->using_parent = e;
|
||||
}
|
||||
|
||||
} else {
|
||||
error(us->token, "`using` can be only applied to `union` or `enum` type entities");
|
||||
}
|
||||
} break;
|
||||
|
||||
case Entity_ImportName: {
|
||||
Scope *scope = e->ImportName.scope;
|
||||
for_array(i, scope->elements.entries) {
|
||||
Entity *decl = scope->elements.entries.e[i].value;
|
||||
Entity *found = scope_insert_entity(c->context.scope, decl);
|
||||
if (found != NULL) {
|
||||
gbString expr_str = expr_to_string(expr);
|
||||
error(us->token,
|
||||
"Namespace collision while `using` `%s` of: %.*s\n"
|
||||
"\tat %.*s(%td:%td)\n"
|
||||
"\tat %.*s(%td:%td)",
|
||||
expr_str, LIT(found->token.string),
|
||||
LIT(found->token.pos.file), found->token.pos.line, found->token.pos.column,
|
||||
LIT(decl->token.pos.file), decl->token.pos.line, decl->token.pos.column
|
||||
);
|
||||
gb_string_free(expr_str);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case Entity_Variable: {
|
||||
Type *t = base_type(type_deref(e->type));
|
||||
if (is_type_struct(t) || is_type_raw_union(t)) {
|
||||
// TODO(bill): Make it work for unions too
|
||||
Scope **found = map_scope_get(&c->info.scopes, hash_pointer(t->Record.node));
|
||||
GB_ASSERT(found != NULL);
|
||||
for_array(i, (*found)->elements.entries) {
|
||||
Entity *f = (*found)->elements.entries.e[i].value;
|
||||
if (f->kind == Entity_Variable) {
|
||||
Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type);
|
||||
if (is_selector) {
|
||||
uvar->using_expr = expr;
|
||||
}
|
||||
Entity *prev = scope_insert_entity(c->context.scope, uvar);
|
||||
if (prev != NULL) {
|
||||
gbString expr_str = expr_to_string(expr);
|
||||
error(us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(prev->token.string));
|
||||
gb_string_free(expr_str);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error(us->token, "`using` can only be applied to variables of type struct or raw_union");
|
||||
return false;
|
||||
}
|
||||
} break;
|
||||
|
||||
case Entity_Constant:
|
||||
error(us->token, "`using` cannot be applied to a constant");
|
||||
break;
|
||||
|
||||
case Entity_Procedure:
|
||||
case Entity_Builtin:
|
||||
error(us->token, "`using` cannot be applied to a procedure");
|
||||
break;
|
||||
|
||||
case Entity_Nil:
|
||||
error(us->token, "`using` cannot be applied to `nil`");
|
||||
break;
|
||||
|
||||
case Entity_Label:
|
||||
error(us->token, "`using` cannot be applied to a label");
|
||||
break;
|
||||
|
||||
case Entity_Invalid:
|
||||
error(us->token, "`using` cannot be applied to an invalid entity");
|
||||
break;
|
||||
|
||||
default:
|
||||
GB_PANIC("TODO(bill): `using` other expressions?");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
u32 mod_flags = flags & (~Stmt_FallthroughAllowed);
|
||||
switch (node->kind) {
|
||||
@@ -1341,118 +1469,8 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (e == NULL) {
|
||||
error(us->token, "`using` applied to an unknown entity");
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (e->kind) {
|
||||
case Entity_TypeName: {
|
||||
Type *t = base_type(e->type);
|
||||
if (is_type_union(t)) {
|
||||
TokenPos pos = ast_node_token(expr).pos;
|
||||
for (isize i = 1; i < t->Record.variant_count; i++) {
|
||||
Entity *f = t->Record.variants[i];
|
||||
// gb_printf_err("%s\n", type_to_string(f->type));
|
||||
Entity *found = scope_insert_entity(c->context.scope, f);
|
||||
if (found != NULL) {
|
||||
gbString expr_str = expr_to_string(expr);
|
||||
error(us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string));
|
||||
gb_string_free(expr_str);
|
||||
return;
|
||||
}
|
||||
f->using_parent = e;
|
||||
}
|
||||
} else if (is_type_enum(t)) {
|
||||
for (isize i = 0; i < t->Record.field_count; i++) {
|
||||
Entity *f = t->Record.fields[i];
|
||||
Entity *found = scope_insert_entity(c->context.scope, f);
|
||||
if (found != NULL) {
|
||||
gbString expr_str = expr_to_string(expr);
|
||||
error(us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string));
|
||||
gb_string_free(expr_str);
|
||||
return;
|
||||
}
|
||||
f->using_parent = e;
|
||||
}
|
||||
|
||||
} else {
|
||||
error(us->token, "`using` can be only applied to `union` or `enum` type entities");
|
||||
}
|
||||
} break;
|
||||
|
||||
case Entity_ImportName: {
|
||||
Scope *scope = e->ImportName.scope;
|
||||
for_array(i, scope->elements.entries) {
|
||||
Entity *decl = scope->elements.entries.e[i].value;
|
||||
Entity *found = scope_insert_entity(c->context.scope, decl);
|
||||
if (found != NULL) {
|
||||
gbString expr_str = expr_to_string(expr);
|
||||
error(us->token,
|
||||
"Namespace collision while `using` `%s` of: %.*s\n"
|
||||
"\tat %.*s(%td:%td)\n"
|
||||
"\tat %.*s(%td:%td)",
|
||||
expr_str, LIT(found->token.string),
|
||||
LIT(found->token.pos.file), found->token.pos.line, found->token.pos.column,
|
||||
LIT(decl->token.pos.file), decl->token.pos.line, decl->token.pos.column
|
||||
);
|
||||
gb_string_free(expr_str);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case Entity_Variable: {
|
||||
Type *t = base_type(type_deref(e->type));
|
||||
if (is_type_struct(t) || is_type_raw_union(t)) {
|
||||
// TODO(bill): Make it work for unions too
|
||||
Scope **found = map_scope_get(&c->info.scopes, hash_pointer(t->Record.node));
|
||||
GB_ASSERT(found != NULL);
|
||||
for_array(i, (*found)->elements.entries) {
|
||||
Entity *f = (*found)->elements.entries.e[i].value;
|
||||
if (f->kind == Entity_Variable) {
|
||||
Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type);
|
||||
if (is_selector) {
|
||||
uvar->using_expr = expr;
|
||||
}
|
||||
Entity *prev = scope_insert_entity(c->context.scope, uvar);
|
||||
if (prev != NULL) {
|
||||
gbString expr_str = expr_to_string(expr);
|
||||
error(us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(prev->token.string));
|
||||
gb_string_free(expr_str);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error(us->token, "`using` can only be applied to variables of type struct or raw_union");
|
||||
return;
|
||||
}
|
||||
} break;
|
||||
|
||||
case Entity_Constant:
|
||||
error(us->token, "`using` cannot be applied to a constant");
|
||||
break;
|
||||
|
||||
case Entity_Procedure:
|
||||
case Entity_Builtin:
|
||||
error(us->token, "`using` cannot be applied to a procedure");
|
||||
break;
|
||||
|
||||
case Entity_Nil:
|
||||
error(us->token, "`using` cannot be applied to `nil`");
|
||||
break;
|
||||
|
||||
case Entity_Label:
|
||||
error(us->token, "`using` cannot be applied to a label");
|
||||
break;
|
||||
|
||||
case Entity_Invalid:
|
||||
error(us->token, "`using` cannot be applied to an invalid entity");
|
||||
break;
|
||||
|
||||
default:
|
||||
GB_PANIC("TODO(bill): `using` other expressions?");
|
||||
if (!check_using_stmt_entity(c, us, expr, is_selector, e)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
case_end;
|
||||
|
||||
+9
-4
@@ -1531,11 +1531,15 @@ void check_collect_entities(Checker *c, AstNodeArray nodes, bool is_file_scope)
|
||||
d->type_expr = type;
|
||||
d->init_expr = type;
|
||||
} else if (up_init != NULL && up_init->kind == AstNode_Alias) {
|
||||
#if 1
|
||||
error_node(up_init, "#alias declarations are not yet supported");
|
||||
continue;
|
||||
// e = make_entity_alias(c->allocator, d->scope, name->Ident, NULL, NULL);
|
||||
// d->init_expr = init->Alias.expr;
|
||||
}else if (init != NULL && up_init->kind == AstNode_ProcLit) {
|
||||
#else
|
||||
e = make_entity_alias(c->allocator, d->scope, name->Ident, NULL, EntityAlias_Invalid, NULL);
|
||||
d->type_expr = vd->type;
|
||||
d->init_expr = up_init->Alias.expr;
|
||||
#endif
|
||||
} else if (init != NULL && up_init->kind == AstNode_ProcLit) {
|
||||
e = make_entity_procedure(c->allocator, d->scope, name->Ident, NULL, up_init->ProcLit.tags);
|
||||
d->proc_lit = up_init;
|
||||
d->type_expr = vd->type;
|
||||
@@ -1989,7 +1993,8 @@ void check_parsed_files(Checker *c) {
|
||||
// NOTE(bill): Check for illegal cyclic type declarations
|
||||
for_array(i, c->info.definitions.entries) {
|
||||
Entity *e = c->info.definitions.entries.e[i].value;
|
||||
if (e->kind == Entity_TypeName) {
|
||||
if (e->kind == Entity_TypeName ||
|
||||
(e->kind == Entity_Alias && e->Alias.kind == EntityAlias_Type)) {
|
||||
if (e->type != NULL) {
|
||||
// i64 size = type_size_of(c->sizes, c->allocator, e->type);
|
||||
i64 align = type_align_of(c->allocator, e->type);
|
||||
|
||||
+13
-2
@@ -50,11 +50,18 @@ typedef enum OverloadKind {
|
||||
Overload_Yes,
|
||||
} OverloadKind;
|
||||
|
||||
typedef enum EntityAliasKind {
|
||||
EntityAlias_Invalid,
|
||||
EntityAlias_Type,
|
||||
EntityAlias_Entity,
|
||||
} EntityAliasKind;
|
||||
|
||||
|
||||
// An Entity is a named "thing" in the language
|
||||
typedef struct Entity Entity;
|
||||
struct Entity {
|
||||
EntityKind kind;
|
||||
u64 id;
|
||||
u32 flags;
|
||||
Token token;
|
||||
Scope * scope;
|
||||
@@ -101,7 +108,8 @@ struct Entity {
|
||||
bool used;
|
||||
} LibraryName;
|
||||
struct {
|
||||
Entity *original;
|
||||
EntityAliasKind kind;
|
||||
Entity * original;
|
||||
} Alias;
|
||||
i32 Nil;
|
||||
struct {
|
||||
@@ -138,6 +146,7 @@ bool is_entity_exported(Entity *e) {
|
||||
return name.text[0] != '_';
|
||||
}
|
||||
|
||||
gb_global u64 global_entity_id = 0;
|
||||
|
||||
Entity *alloc_entity(gbAllocator a, EntityKind kind, Scope *scope, Token token, Type *type) {
|
||||
Entity *entity = gb_alloc_item(a, Entity);
|
||||
@@ -145,6 +154,7 @@ Entity *alloc_entity(gbAllocator a, EntityKind kind, Scope *scope, Token token,
|
||||
entity->scope = scope;
|
||||
entity->token = token;
|
||||
entity->type = type;
|
||||
entity->id = ++global_entity_id;
|
||||
return entity;
|
||||
}
|
||||
|
||||
@@ -231,8 +241,9 @@ Entity *make_entity_library_name(gbAllocator a, Scope *scope, Token token, Type
|
||||
}
|
||||
|
||||
Entity *make_entity_alias(gbAllocator a, Scope *scope, Token token, Type *type,
|
||||
Entity *original) {
|
||||
EntityAliasKind kind, Entity *original) {
|
||||
Entity *entity = alloc_entity(a, Entity_Alias, scope, token, type);
|
||||
entity->Alias.kind = kind;
|
||||
entity->Alias.original = original;
|
||||
return entity;
|
||||
}
|
||||
|
||||
@@ -3284,23 +3284,34 @@ String ir_mangle_name(irGen *s, String path, Entity *e) {
|
||||
char const *ext = gb_path_extension(base);
|
||||
isize base_len = ext-1-base;
|
||||
|
||||
isize max_len = base_len + 1 + 10 + 1 + name.len;
|
||||
isize max_len = base_len + 1 + 1 + 10 + 1 + name.len;
|
||||
bool is_overloaded = check_is_entity_overloaded(e);
|
||||
if (is_overloaded) {
|
||||
max_len += 21;
|
||||
}
|
||||
|
||||
u8 *new_name = gb_alloc_array(a, u8, max_len);
|
||||
isize new_name_len = gb_snprintf(
|
||||
cast(char *)new_name, max_len,
|
||||
"%.*s-%u.%.*s",
|
||||
cast(int)base_len, base,
|
||||
file->id,
|
||||
LIT(name));
|
||||
isize new_name_len = 0;
|
||||
if ((base_len > 0 && gb_char_is_digit(base[0])) ||
|
||||
base_len == 0) {
|
||||
new_name_len = gb_snprintf(
|
||||
cast(char *)new_name, max_len,
|
||||
"_%.*s-%u.%.*s",
|
||||
cast(int)base_len, base,
|
||||
file->id,
|
||||
LIT(name));
|
||||
} else {
|
||||
new_name_len = gb_snprintf(
|
||||
cast(char *)new_name, max_len,
|
||||
"%.*s-%u.%.*s",
|
||||
cast(int)base_len, base,
|
||||
file->id,
|
||||
LIT(name));
|
||||
}
|
||||
if (is_overloaded) {
|
||||
char *str = cast(char *)new_name + new_name_len-1;
|
||||
isize len = max_len-new_name_len;
|
||||
isize extra = gb_snprintf(str, len, "-%tu", cast(usize)cast(uintptr)e);
|
||||
isize extra = gb_snprintf(str, len, "-%llu", cast(unsigned long long)e->id);
|
||||
new_name_len += extra-1;
|
||||
}
|
||||
|
||||
@@ -4311,7 +4322,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||
irValue *kmag = ir_build_expr(proc, ce->args.e[3]);
|
||||
irValue *dst = ir_add_local_generated(proc, tv->type);
|
||||
|
||||
Type *ft = base_complex_elem_type(tv->type);
|
||||
Type *ft = base_quaternion_elem_type(tv->type);
|
||||
real = ir_emit_conv(proc, real, ft);
|
||||
imag = ir_emit_conv(proc, imag, ft);
|
||||
jmag = ir_emit_conv(proc, jmag, ft);
|
||||
@@ -7217,6 +7228,7 @@ void ir_gen_tree(irGen *s) {
|
||||
if (var->init != NULL && var->init->kind == irValue_Constant) {
|
||||
Type *t = type_deref(ir_type(var->var));
|
||||
if (is_type_any(t)) {
|
||||
// NOTE(bill): Edge case for `any` type
|
||||
Type *var_type = default_type(ir_type(var->init));
|
||||
irValue *g = ir_add_global_generated(proc->module, var_type, var->init);
|
||||
irValue *data = ir_emit_struct_ep(proc, var->var, 0);
|
||||
@@ -7233,7 +7245,8 @@ void ir_gen_tree(irGen *s) {
|
||||
irGlobalVariable *var = &global_variables.e[i];
|
||||
if (var->init != NULL && var->init->kind != irValue_Constant) {
|
||||
Type *t = type_deref(ir_type(var->var));
|
||||
if (is_type_any(t)) {
|
||||
if (is_type_any(t)) {
|
||||
// NOTE(bill): Edge case for `any` type
|
||||
Type *var_type = default_type(ir_type(var->init));
|
||||
irValue *g = ir_add_global_generated(proc->module, var_type, var->init);
|
||||
ir_emit_store(proc, g, var->init);
|
||||
|
||||
+1
-1
@@ -430,7 +430,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
exit_code = system_exec_command_line_app("ld-link", true,
|
||||
"%s \"%.*s\".o -o \"%.*s%s\" %s "
|
||||
"-lc "
|
||||
"-lc -lm "
|
||||
" %.*s "
|
||||
" %s "
|
||||
#if defined(GB_SYSTEM_OSX)
|
||||
|
||||
+8
-4
@@ -33,6 +33,7 @@ typedef struct AstFile {
|
||||
// NOTE(bill): Used to prevent type literals in control clauses
|
||||
isize expr_level;
|
||||
bool allow_range;
|
||||
bool ignore_operand;
|
||||
|
||||
AstNodeArray decls;
|
||||
bool is_global_scope;
|
||||
@@ -1849,10 +1850,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
|
||||
}
|
||||
}
|
||||
|
||||
Token begin = f->curr_token;
|
||||
syntax_error(begin, "Expected an operand");
|
||||
fix_advance_to_next_stmt(f);
|
||||
return ast_bad_expr(f, begin, f->curr_token);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool is_literal_type(AstNode *node) {
|
||||
@@ -1937,6 +1935,12 @@ AstNode *parse_macro_call_expr(AstFile *f, AstNode *operand) {
|
||||
|
||||
AstNode *parse_atom_expr(AstFile *f, bool lhs) {
|
||||
AstNode *operand = parse_operand(f, lhs);
|
||||
if (operand == NULL) {
|
||||
Token begin = f->curr_token;
|
||||
syntax_error(begin, "Expected an operand");
|
||||
fix_advance_to_next_stmt(f);
|
||||
operand = ast_bad_expr(f, begin, f->curr_token);
|
||||
}
|
||||
|
||||
bool loop = true;
|
||||
while (loop) {
|
||||
|
||||
+14
@@ -551,6 +551,20 @@ bool is_type_named(Type *t) {
|
||||
}
|
||||
return t->kind == Type_Named;
|
||||
}
|
||||
bool is_type_named_alias(Type *t) {
|
||||
if (!is_type_named(t)) {
|
||||
return false;
|
||||
}
|
||||
Entity *e = t->Named.type_name;
|
||||
if (e == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (e->kind != Entity_TypeName) {
|
||||
return false;
|
||||
}
|
||||
return e->TypeName.is_type_alias;
|
||||
}
|
||||
|
||||
bool is_type_boolean(Type *t) {
|
||||
t = core_type(t);
|
||||
if (t->kind == Type_Basic) {
|
||||
|
||||
Reference in New Issue
Block a user