Merge branch 'master' into freestanding_amd64

This commit is contained in:
gingerBill
2022-02-23 11:03:48 +00:00
29 changed files with 1073 additions and 319 deletions
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+1
View File
@@ -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
View File
@@ -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;
}
+11
View File
@@ -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);