mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-27 16:01:47 -07:00
Merge branch 'master' into freestanding_amd64
This commit is contained in:
+2
-2
@@ -473,11 +473,11 @@ void print_bug_report_help() {
|
||||
|
||||
#elif defined(GB_SYSTEM_LINUX)
|
||||
/*
|
||||
Try to parse `/usr/lib/os-release` for `PRETTY_NAME="Ubuntu 20.04.3 LTS`
|
||||
Try to parse `/etc/os-release` for `PRETTY_NAME="Ubuntu 20.04.3 LTS`
|
||||
*/
|
||||
gbAllocator a = heap_allocator();
|
||||
|
||||
gbFileContents release = gb_file_read_contents(a, 1, "/usr/lib/os-release");
|
||||
gbFileContents release = gb_file_read_contents(a, 1, "/etc/os-release");
|
||||
defer (gb_file_free_contents(&release));
|
||||
|
||||
b32 found = 0;
|
||||
|
||||
+63
-1
@@ -132,6 +132,62 @@ void check_did_you_mean_print(DidYouMeanAnswers *d, char const *prefix = "") {
|
||||
}
|
||||
}
|
||||
|
||||
void populate_check_did_you_mean_objc_entity(StringSet *set, Entity *e, bool is_type) {
|
||||
if (e->kind != Entity_TypeName) {
|
||||
return;
|
||||
}
|
||||
if (e->TypeName.objc_metadata == nullptr) {
|
||||
return;
|
||||
}
|
||||
TypeNameObjCMetadata *objc_metadata = e->TypeName.objc_metadata;
|
||||
Type *t = base_type(e->type);
|
||||
GB_ASSERT(t->kind == Type_Struct);
|
||||
|
||||
if (is_type) {
|
||||
for_array(i, objc_metadata->type_entries) {
|
||||
String name = objc_metadata->type_entries[i].name;
|
||||
string_set_add(set, name);
|
||||
}
|
||||
} else {
|
||||
for_array(i, objc_metadata->value_entries) {
|
||||
String name = objc_metadata->value_entries[i].name;
|
||||
string_set_add(set, name);
|
||||
}
|
||||
}
|
||||
|
||||
for_array(i, t->Struct.fields) {
|
||||
Entity *f = t->Struct.fields[i];
|
||||
if (f->flags & EntityFlag_Using && f->type != nullptr) {
|
||||
if (f->type->kind == Type_Named && f->type->Named.type_name) {
|
||||
populate_check_did_you_mean_objc_entity(set, f->type->Named.type_name, is_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void check_did_you_mean_objc_entity(String const &name, Entity *e, bool is_type, char const *prefix = "") {
|
||||
ERROR_BLOCK();
|
||||
GB_ASSERT(e->kind == Entity_TypeName);
|
||||
GB_ASSERT(e->TypeName.objc_metadata != nullptr);
|
||||
auto *objc_metadata = e->TypeName.objc_metadata;
|
||||
mutex_lock(objc_metadata->mutex);
|
||||
defer (mutex_unlock(objc_metadata->mutex));
|
||||
|
||||
StringSet set = {};
|
||||
string_set_init(&set, heap_allocator());
|
||||
defer (string_set_destroy(&set));
|
||||
populate_check_did_you_mean_objc_entity(&set, e, is_type);
|
||||
|
||||
|
||||
DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), set.entries.count, name);
|
||||
defer (did_you_mean_destroy(&d));
|
||||
for_array(i, set.entries) {
|
||||
did_you_mean_append(&d, set.entries[i].value);
|
||||
}
|
||||
check_did_you_mean_print(&d, prefix);
|
||||
}
|
||||
|
||||
void check_did_you_mean_type(String const &name, Array<Entity *> const &fields, char const *prefix = "") {
|
||||
ERROR_BLOCK();
|
||||
|
||||
@@ -144,6 +200,7 @@ void check_did_you_mean_type(String const &name, Array<Entity *> const &fields,
|
||||
check_did_you_mean_print(&d, prefix);
|
||||
}
|
||||
|
||||
|
||||
void check_did_you_mean_type(String const &name, Slice<Entity *> const &fields, char const *prefix = "") {
|
||||
ERROR_BLOCK();
|
||||
|
||||
@@ -4420,7 +4477,12 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ
|
||||
if (operand->type != nullptr && selector->kind == Ast_Ident) {
|
||||
String const &name = selector->Ident.token.string;
|
||||
Type *bt = base_type(operand->type);
|
||||
if (bt->kind == Type_Struct) {
|
||||
if (operand->type->kind == Type_Named &&
|
||||
operand->type->Named.type_name &&
|
||||
operand->type->Named.type_name->kind == Entity_TypeName &&
|
||||
operand->type->Named.type_name->TypeName.objc_metadata) {
|
||||
check_did_you_mean_objc_entity(name, operand->type->Named.type_name, operand->mode == Addressing_Type);
|
||||
} else if (bt->kind == Type_Struct) {
|
||||
check_did_you_mean_type(name, bt->Struct.fields);
|
||||
} else if (bt->kind == Type_Enum) {
|
||||
check_did_you_mean_type(name, bt->Enum.fields);
|
||||
|
||||
+16
-5
@@ -50,9 +50,9 @@ struct ExactValue {
|
||||
union {
|
||||
bool value_bool;
|
||||
String value_string;
|
||||
BigInt value_integer; // NOTE(bill): This must be an integer and not a pointer
|
||||
BigInt value_integer;
|
||||
f64 value_float;
|
||||
i64 value_pointer;
|
||||
i64 value_pointer; // NOTE(bill): This must be an integer and not a pointer
|
||||
Complex128 *value_complex;
|
||||
Quaternion256 *value_quaternion;
|
||||
Ast * value_compound;
|
||||
@@ -630,6 +630,9 @@ void match_exact_values(ExactValue *x, ExactValue *y) {
|
||||
case ExactValue_Bool:
|
||||
case ExactValue_String:
|
||||
case ExactValue_Quaternion:
|
||||
case ExactValue_Pointer:
|
||||
case ExactValue_Procedure:
|
||||
case ExactValue_Typeid:
|
||||
return;
|
||||
|
||||
case ExactValue_Integer:
|
||||
@@ -671,9 +674,6 @@ void match_exact_values(ExactValue *x, ExactValue *y) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case ExactValue_Procedure:
|
||||
return;
|
||||
}
|
||||
|
||||
compiler_error("match_exact_values: How'd you get here? Invalid ExactValueKind %d", x->kind);
|
||||
@@ -932,6 +932,17 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
|
||||
break;
|
||||
}
|
||||
|
||||
case ExactValue_Pointer: {
|
||||
switch (op) {
|
||||
case Token_CmpEq: return x.value_pointer == y.value_pointer;
|
||||
case Token_NotEq: return x.value_pointer != y.value_pointer;
|
||||
case Token_Lt: return x.value_pointer < y.value_pointer;
|
||||
case Token_LtEq: return x.value_pointer <= y.value_pointer;
|
||||
case Token_Gt: return x.value_pointer > y.value_pointer;
|
||||
case Token_GtEq: return x.value_pointer >= y.value_pointer;
|
||||
}
|
||||
}
|
||||
|
||||
case ExactValue_Typeid:
|
||||
switch (op) {
|
||||
case Token_CmpEq: return are_types_identical(x.value_typeid, y.value_typeid);
|
||||
|
||||
@@ -6093,6 +6093,7 @@ gbFileContents gb_file_read_contents(gbAllocator a, b32 zero_terminate, char con
|
||||
}
|
||||
|
||||
void gb_file_free_contents(gbFileContents *fc) {
|
||||
if (fc == NULL || fc->size == 0) return;
|
||||
GB_ASSERT_NOT_NULL(fc->data);
|
||||
gb_free(fc->allocator, fc->data);
|
||||
fc->data = NULL;
|
||||
|
||||
+47
-49
@@ -3015,64 +3015,62 @@ i32 token_precedence(AstFile *f, TokenKind t) {
|
||||
|
||||
Ast *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) {
|
||||
Ast *expr = parse_unary_expr(f, lhs);
|
||||
for (i32 prec = token_precedence(f, f->curr_token.kind); prec >= prec_in; prec--) {
|
||||
for (;;) {
|
||||
Token op = f->curr_token;
|
||||
i32 op_prec = token_precedence(f, op.kind);
|
||||
if (op_prec != prec) {
|
||||
// NOTE(bill): This will also catch operators that are not valid "binary" operators
|
||||
break;
|
||||
for (;;) {
|
||||
Token op = f->curr_token;
|
||||
i32 op_prec = token_precedence(f, op.kind);
|
||||
if (op_prec < prec_in) {
|
||||
// NOTE(bill): This will also catch operators that are not valid "binary" operators
|
||||
break;
|
||||
}
|
||||
Token prev = f->prev_token;
|
||||
switch (op.kind) {
|
||||
case Token_if:
|
||||
case Token_when:
|
||||
if (prev.pos.line < op.pos.line) {
|
||||
// NOTE(bill): Check to see if the `if` or `when` is on the same line of the `lhs` condition
|
||||
goto loop_end;
|
||||
}
|
||||
Token prev = f->prev_token;
|
||||
break;
|
||||
}
|
||||
expect_operator(f); // NOTE(bill): error checks too
|
||||
|
||||
if (op.kind == Token_Question) {
|
||||
Ast *cond = expr;
|
||||
// Token_Question
|
||||
Ast *x = parse_expr(f, lhs);
|
||||
Token token_c = expect_token(f, Token_Colon);
|
||||
Ast *y = parse_expr(f, lhs);
|
||||
expr = ast_ternary_if_expr(f, x, cond, y);
|
||||
} else if (op.kind == Token_if || op.kind == Token_when) {
|
||||
Ast *x = expr;
|
||||
Ast *cond = parse_expr(f, lhs);
|
||||
Token tok_else = expect_token(f, Token_else);
|
||||
Ast *y = parse_expr(f, lhs);
|
||||
|
||||
switch (op.kind) {
|
||||
case Token_if:
|
||||
expr = ast_ternary_if_expr(f, x, cond, y);
|
||||
break;
|
||||
case Token_when:
|
||||
if (prev.pos.line < op.pos.line) {
|
||||
// NOTE(bill): Check to see if the `if` or `when` is on the same line of the `lhs` condition
|
||||
goto loop_end;
|
||||
}
|
||||
expr = ast_ternary_when_expr(f, x, cond, y);
|
||||
break;
|
||||
}
|
||||
expect_operator(f); // NOTE(bill): error checks too
|
||||
|
||||
if (op.kind == Token_Question) {
|
||||
Ast *cond = expr;
|
||||
// Token_Question
|
||||
Ast *x = parse_expr(f, lhs);
|
||||
Token token_c = expect_token(f, Token_Colon);
|
||||
Ast *y = parse_expr(f, lhs);
|
||||
expr = ast_ternary_if_expr(f, x, cond, y);
|
||||
} else if (op.kind == Token_if || op.kind == Token_when) {
|
||||
Ast *x = expr;
|
||||
Ast *cond = parse_expr(f, lhs);
|
||||
Token tok_else = expect_token(f, Token_else);
|
||||
Ast *y = parse_expr(f, lhs);
|
||||
|
||||
switch (op.kind) {
|
||||
case Token_if:
|
||||
expr = ast_ternary_if_expr(f, x, cond, y);
|
||||
break;
|
||||
case Token_when:
|
||||
expr = ast_ternary_when_expr(f, x, cond, y);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
Ast *right = parse_binary_expr(f, false, prec+1);
|
||||
if (right == nullptr) {
|
||||
syntax_error(op, "Expected expression on the right-hand side of the binary operator '%.*s'", LIT(op.string));
|
||||
}
|
||||
if (op.kind == Token_or_else) {
|
||||
// NOTE(bill): easier to handle its logic different with its own AST kind
|
||||
expr = ast_or_else_expr(f, expr, op, right);
|
||||
} else {
|
||||
expr = ast_binary_expr(f, op, expr, right);
|
||||
}
|
||||
} else {
|
||||
Ast *right = parse_binary_expr(f, false, op_prec+1);
|
||||
if (right == nullptr) {
|
||||
syntax_error(op, "Expected expression on the right-hand side of the binary operator '%.*s'", LIT(op.string));
|
||||
}
|
||||
if (op.kind == Token_or_else) {
|
||||
// NOTE(bill): easier to handle its logic different with its own AST kind
|
||||
expr = ast_or_else_expr(f, expr, op, right);
|
||||
} else {
|
||||
expr = ast_binary_expr(f, op, expr, right);
|
||||
}
|
||||
|
||||
lhs = false;
|
||||
}
|
||||
loop_end:;
|
||||
|
||||
lhs = false;
|
||||
}
|
||||
loop_end:;
|
||||
return expr;
|
||||
}
|
||||
|
||||
|
||||
@@ -2623,6 +2623,17 @@ i64 union_tag_size(Type *u) {
|
||||
|
||||
// TODO(bill): Is this an okay approach?
|
||||
i64 max_align = 1;
|
||||
|
||||
if (u->Union.variants.count < 1ull<<8) {
|
||||
max_align = 1;
|
||||
} else if (u->Union.variants.count < 1ull<<16) {
|
||||
max_align = 2;
|
||||
} else if (u->Union.variants.count < 1ull<<32) {
|
||||
max_align = 4;
|
||||
} else {
|
||||
GB_PANIC("how many variants do you have?!");
|
||||
}
|
||||
|
||||
for_array(i, u->Union.variants) {
|
||||
Type *variant_type = u->Union.variants[i];
|
||||
i64 align = type_align_of(variant_type);
|
||||
|
||||
Reference in New Issue
Block a user