Implicit Context and #thread_local

This commit is contained in:
gingerBill
2016-08-19 23:35:09 +01:00
parent 745237459a
commit 680274b6f1
16 changed files with 1161 additions and 618 deletions
+2 -1
View File
@@ -38,9 +38,9 @@ struct DeclInfo {
AstNode *type_expr;
AstNode *init_expr;
AstNode *proc_decl; // AstNode_ProcDecl
u32 var_decl_tags;
Map<b32> deps; // Key: Entity *
i32 mark;
};
@@ -605,6 +605,7 @@ void check_parsed_files(Checker *c) {
d = make_declaration_info(gb_heap_allocator(), c->global_scope);
d->type_expr = vd->type;
d->init_expr = init_expr;
d->var_decl_tags = vd->tags;
}
add_file_entity(c, name, e, d);
+25 -2
View File
@@ -874,6 +874,12 @@ b32 check_castable_to(Checker *c, Operand *operand, Type *y) {
return true;
}
// proc -> rawptr
if (is_type_proc(xb), is_type_rawptr(yb)) {
return true;
}
return false;
}
@@ -912,7 +918,7 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
gbString type_str = type_to_string(type);
defer (gb_string_free(expr_str));
defer (gb_string_free(type_str));
error(&c->error_collector, ast_node_token(x->expr), "Cannot cast `%s` to `%s`", expr_str, type_str);
error(&c->error_collector, ast_node_token(x->expr), "Cannot cast `%s` as `%s`", expr_str, type_str);
x->mode = Addressing_Invalid;
return;
@@ -1199,8 +1205,18 @@ void convert_to_typed(Checker *c, Operand *operand, Type *target_type) {
convert_untyped_error(c, operand, target_type);
return;
}
break;
case Type_Proc:
switch (operand->type->basic.kind) {
case Basic_UntypedPointer:
break;
default:
convert_untyped_error(c, operand, target_type);
return;
}
break;
default:
convert_untyped_error(c, operand, target_type);
return;
@@ -1992,6 +2008,13 @@ ExpressionKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *typ
i64 max = 0;
for (AstNode *elem = cl->elem_list; elem != NULL; elem = elem->next, index++) {
AstNode *e = elem;
if (e->kind == AstNode_FieldValue) {
error(&c->error_collector, ast_node_token(e),
"`field = value` is only allowed in structure literals");
continue;
}
if (t->kind == Type_Array &&
t->array.count >= 0 &&
index >= t->array.count) {
+2 -2
View File
@@ -119,7 +119,9 @@ b32 check_is_assignable_to(Checker *c, Operand *operand, Type *type) {
}
}
return false;
}
@@ -742,8 +744,6 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
}
case_end;
// Declarations
case_ast_node(vd, VarDecl, node);
isize entity_count = vd->name_count;
isize entity_index = 0;
+39 -28
View File
@@ -80,7 +80,13 @@ String const type_strings[] = {
#undef TYPE_KIND
};
enum TypeFlag {
TypeFlag_thread_local = GB_BIT(0),
TypeFlag_volatile = GB_BIT(1),
};
struct Type {
u32 flags;
TypeKind kind;
union {
BasicType basic;
@@ -206,43 +212,46 @@ Type *make_type_proc(gbAllocator a, Scope *scope, Type *params, isize param_coun
Type *type_deref(Type *t) {
if (t != NULL && t->kind == Type_Pointer)
return t->pointer.elem;
if (t != NULL) {
Type *bt = get_base_type(t);
if (bt != NULL && bt->kind == Type_Pointer)
return bt->pointer.elem;
}
return t;
}
#define STR_LIT(x) {cast(u8 *)(x), gb_size_of(x)-1}
gb_global Type basic_types[] = {
{Type_Basic, {Basic_Invalid, 0, STR_LIT("invalid type")}},
{Type_Basic, {Basic_bool, BasicFlag_Boolean, STR_LIT("bool")}},
{Type_Basic, {Basic_i8, BasicFlag_Integer, STR_LIT("i8")}},
{Type_Basic, {Basic_i16, BasicFlag_Integer, STR_LIT("i16")}},
{Type_Basic, {Basic_i32, BasicFlag_Integer, STR_LIT("i32")}},
{Type_Basic, {Basic_i64, BasicFlag_Integer, STR_LIT("i64")}},
{Type_Basic, {Basic_i128, BasicFlag_Integer, STR_LIT("i128")}},
{Type_Basic, {Basic_u8, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u8")}},
{Type_Basic, {Basic_u16, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u16")}},
{Type_Basic, {Basic_u32, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u32")}},
{Type_Basic, {Basic_u64, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u64")}},
{Type_Basic, {Basic_u128, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u128")}},
{Type_Basic, {Basic_f32, BasicFlag_Float, STR_LIT("f32")}},
{Type_Basic, {Basic_f64, BasicFlag_Float, STR_LIT("f64")}},
{Type_Basic, {Basic_int, BasicFlag_Integer, STR_LIT("int")}},
{Type_Basic, {Basic_uint, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("uint")}},
{Type_Basic, {Basic_rawptr, BasicFlag_Pointer, STR_LIT("rawptr")}},
{Type_Basic, {Basic_string, BasicFlag_String, STR_LIT("string")}},
{Type_Basic, {Basic_UntypedBool, BasicFlag_Boolean | BasicFlag_Untyped, STR_LIT("untyped bool")}},
{Type_Basic, {Basic_UntypedInteger, BasicFlag_Integer | BasicFlag_Untyped, STR_LIT("untyped integer")}},
{Type_Basic, {Basic_UntypedFloat, BasicFlag_Float | BasicFlag_Untyped, STR_LIT("untyped float")}},
{Type_Basic, {Basic_UntypedPointer, BasicFlag_Pointer | BasicFlag_Untyped, STR_LIT("untyped pointer")}},
{Type_Basic, {Basic_UntypedString, BasicFlag_String | BasicFlag_Untyped, STR_LIT("untyped string")}},
{Type_Basic, {Basic_UntypedRune, BasicFlag_Integer | BasicFlag_Untyped, STR_LIT("untyped rune")}},
{0, Type_Basic, {Basic_Invalid, 0, STR_LIT("invalid type")}},
{0, Type_Basic, {Basic_bool, BasicFlag_Boolean, STR_LIT("bool")}},
{0, Type_Basic, {Basic_i8, BasicFlag_Integer, STR_LIT("i8")}},
{0, Type_Basic, {Basic_i16, BasicFlag_Integer, STR_LIT("i16")}},
{0, Type_Basic, {Basic_i32, BasicFlag_Integer, STR_LIT("i32")}},
{0, Type_Basic, {Basic_i64, BasicFlag_Integer, STR_LIT("i64")}},
{0, Type_Basic, {Basic_i128, BasicFlag_Integer, STR_LIT("i128")}},
{0, Type_Basic, {Basic_u8, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u8")}},
{0, Type_Basic, {Basic_u16, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u16")}},
{0, Type_Basic, {Basic_u32, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u32")}},
{0, Type_Basic, {Basic_u64, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u64")}},
{0, Type_Basic, {Basic_u128, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u128")}},
{0, Type_Basic, {Basic_f32, BasicFlag_Float, STR_LIT("f32")}},
{0, Type_Basic, {Basic_f64, BasicFlag_Float, STR_LIT("f64")}},
{0, Type_Basic, {Basic_int, BasicFlag_Integer, STR_LIT("int")}},
{0, Type_Basic, {Basic_uint, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("uint")}},
{0, Type_Basic, {Basic_rawptr, BasicFlag_Pointer, STR_LIT("rawptr")}},
{0, Type_Basic, {Basic_string, BasicFlag_String, STR_LIT("string")}},
{0, Type_Basic, {Basic_UntypedBool, BasicFlag_Boolean | BasicFlag_Untyped, STR_LIT("untyped bool")}},
{0, Type_Basic, {Basic_UntypedInteger, BasicFlag_Integer | BasicFlag_Untyped, STR_LIT("untyped integer")}},
{0, Type_Basic, {Basic_UntypedFloat, BasicFlag_Float | BasicFlag_Untyped, STR_LIT("untyped float")}},
{0, Type_Basic, {Basic_UntypedPointer, BasicFlag_Pointer | BasicFlag_Untyped, STR_LIT("untyped pointer")}},
{0, Type_Basic, {Basic_UntypedString, BasicFlag_String | BasicFlag_Untyped, STR_LIT("untyped string")}},
{0, Type_Basic, {Basic_UntypedRune, BasicFlag_Integer | BasicFlag_Untyped, STR_LIT("untyped rune")}},
};
gb_global Type basic_type_aliases[] = {
{Type_Basic, {Basic_byte, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("byte")}},
{Type_Basic, {Basic_rune, BasicFlag_Integer, STR_LIT("rune")}},
{0, Type_Basic, {Basic_byte, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("byte")}},
{0, Type_Basic, {Basic_rune, BasicFlag_Integer, STR_LIT("rune")}},
};
gb_global Type *t_invalid = &basic_types[Basic_Invalid];
@@ -392,6 +401,8 @@ b32 is_type_comparable(Type *t) {
return is_type_comparable(t->array.elem);
case Type_Vector:
return is_type_comparable(t->vector.elem);
case Type_Proc:
return true;
}
return false;
}
+5 -3
View File
@@ -77,8 +77,10 @@ void ssa_gen_code(ssaGen *s) {
} break;
case Entity_Variable: {
// TODO(bill): global runtime initialization
ssaValue *g = ssa_make_value_global(a, e, NULL);
if (decl->var_decl_tags & VarDeclTag_thread_local) {
g->Global.is_thread_local = true;
}
ssaGlobalVariable var = {};
var.var = g;
var.decl = decl;
@@ -95,7 +97,7 @@ void ssa_gen_code(ssaGen *s) {
name = pd->foreign_name;
}
ssaValue *p = ssa_make_value_procedure(a, m, e->type, decl->type_expr, body, name);
p->proc.tags = pd->tags;
p->Proc.tags = pd->tags;
map_set(&m->values, hash_pointer(e), p);
map_set(&m->members, hash_string(name), p);
@@ -127,7 +129,7 @@ void ssa_gen_code(ssaGen *s) {
map_set(&m->values, hash_pointer(e), p);
map_set(&m->members, hash_string(name), p);
ssaProcedure *proc = &p->proc;
ssaProcedure *proc = &p->Proc;
proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
ssa_begin_procedure_body(proc);
+72 -68
View File
@@ -230,10 +230,10 @@ void ssa_print_exact_value(gbFile *f, ssaModule *m, ExactValue value, Type *type
if (is_type_float(type) && type->basic.kind == Basic_f32) {
// IMPORTANT NOTE(bill): LLVM requires all floating point constants to be
// a 64 bit number if bits_of(float type) <= 64.
// For some bizarre reason, you need to clear the bottom 28 bits
// For some bizarre reason, you need to clear the bottom 29 bits
// https://groups.google.com/forum/#!topic/llvm-dev/IlqV3TbSk6M
u >>= 28;
u <<= 28;
u >>= 29;
u <<= 29;
}
ssa_fprintf(f, "0x%016llx", u);
} break;
@@ -262,19 +262,19 @@ void ssa_print_value(gbFile *f, ssaModule *m, ssaValue *value, Type *type_hint)
}
switch (value->kind) {
case ssaValue_Constant:
ssa_print_exact_value(f, m, value->constant.value, type_hint);
ssa_print_exact_value(f, m, value->Constant.value, type_hint);
break;
case ssaValue_TypeName:
ssa_print_encoded_local(f, value->type_name.name);
ssa_print_encoded_local(f, value->TypeName.name);
break;
case ssaValue_Global:
ssa_print_encoded_global(f, value->global.entity->token.string);
ssa_print_encoded_global(f, value->Global.entity->token.string);
break;
case ssaValue_Param:
ssa_print_encoded_local(f, value->param.entity->token.string);
ssa_print_encoded_local(f, value->Param.entity->token.string);
break;
case ssaValue_Proc:
ssa_print_encoded_global(f, value->proc.name);
ssa_print_encoded_global(f, value->Proc.name);
break;
case ssaValue_Instr:
ssa_fprintf(f, "%%%d", value->id);
@@ -284,7 +284,7 @@ void ssa_print_value(gbFile *f, ssaModule *m, ssaValue *value, Type *type_hint)
void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
GB_ASSERT(value->kind == ssaValue_Instr);
ssaInstr *instr = &value->instr;
ssaInstr *instr = &value->Instr;
ssa_fprintf(f, "\t");
@@ -294,14 +294,14 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
} break;
case ssaInstr_Local: {
Type *type = instr->local.entity->type;
Type *type = instr->Local.entity->type;
ssa_fprintf(f, "%%%d = alloca ", value->id);
ssa_print_type(f, m->sizes, type);
ssa_fprintf(f, ", align %lld ", type_align_of(m->sizes, m->allocator, type));
{
String str = instr->local.entity->token.string;
String str = instr->Local.entity->token.string;
if (str.len > 0)
ssa_fprintf(f, "; %.*s", LIT(instr->local.entity->token.string));
ssa_fprintf(f, "; %.*s", LIT(instr->Local.entity->token.string));
}
ssa_fprintf(f, "\n");
ssa_fprintf(f, "\tstore ");
@@ -312,33 +312,33 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
} break;
case ssaInstr_Store: {
Type *type = ssa_value_type(instr->store.address);
Type *type = ssa_type(instr->Store.address);
ssa_fprintf(f, "store ");
ssa_print_type(f, m->sizes, type);
ssa_fprintf(f, " ");
ssa_print_value(f, m, instr->store.value, type);
ssa_print_value(f, m, instr->Store.value, type);
ssa_fprintf(f, ", ");
ssa_print_type(f, m->sizes, type);
ssa_fprintf(f, "* ");
ssa_print_value(f, m, instr->store.address, type);
ssa_print_value(f, m, instr->Store.address, type);
ssa_fprintf(f, "\n");
} break;
case ssaInstr_Load: {
Type *type = instr->load.type;
Type *type = instr->Load.type;
ssa_fprintf(f, "%%%d = load ", value->id);
ssa_print_type(f, m->sizes, type);
ssa_fprintf(f, ", ");
ssa_print_type(f, m->sizes, type);
ssa_fprintf(f, "* ");
ssa_print_value(f, m, instr->load.address, type);
ssa_print_value(f, m, instr->Load.address, type);
ssa_fprintf(f, ", align %lld\n", type_align_of(m->sizes, m->allocator, type));
} break;
case ssaInstr_GetElementPtr: {
Type *et = instr->get_element_ptr.elem_type;
Type *et = instr->GetElementPtr.elem_type;
ssa_fprintf(f, "%%%d = getelementptr ", value->id);
if (instr->get_element_ptr.inbounds) {
if (instr->GetElementPtr.inbounds) {
ssa_fprintf(f, "inbounds ");
}
@@ -346,10 +346,10 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
ssa_fprintf(f, ", ");
ssa_print_type(f, m->sizes, et);
ssa_fprintf(f, "* ");
ssa_print_value(f, m, instr->get_element_ptr.address, et);
for (isize i = 0; i < instr->get_element_ptr.index_count; i++) {
ssaValue *index = instr->get_element_ptr.indices[i];
Type *t = ssa_value_type(index);
ssa_print_value(f, m, instr->GetElementPtr.address, et);
for (isize i = 0; i < instr->GetElementPtr.index_count; i++) {
ssaValue *index = instr->GetElementPtr.indices[i];
Type *t = ssa_type(index);
ssa_fprintf(f, ", ");
ssa_print_type(f, m->sizes, t);
ssa_fprintf(f, " ");
@@ -359,13 +359,13 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
} break;
case ssaInstr_ExtractValue: {
Type *et = instr->extract_value.elem_type;
Type *et = instr->ExtractValue.elem_type;
ssa_fprintf(f, "%%%d = extractvalue ", value->id);
ssa_print_type(f, m->sizes, et);
ssa_fprintf(f, " ");
ssa_print_value(f, m, instr->extract_value.address, et);
ssa_fprintf(f, ", %d\n", instr->extract_value.index);
ssa_print_value(f, m, instr->ExtractValue.address, et);
ssa_fprintf(f, ", %d\n", instr->ExtractValue.index);
} break;
case ssaInstr_NoOp: {;
@@ -374,28 +374,28 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
case ssaInstr_Br: {;
ssa_fprintf(f, "br ");
if (instr->br.cond != NULL) {
if (instr->Br.cond != NULL) {
ssa_print_type(f, m->sizes, t_bool);
ssa_fprintf(f, " ");
ssa_print_value(f, m, instr->br.cond, t_bool);
ssa_fprintf(f, ", ", instr->br.cond->id);
ssa_print_value(f, m, instr->Br.cond, t_bool);
ssa_fprintf(f, ", ", instr->Br.cond->id);
}
ssa_fprintf(f, "label ");
ssa_fprintf(f, "%%"); ssa_print_block_name(f, instr->br.true_block);
if (instr->br.false_block != NULL) {
ssa_fprintf(f, "%%"); ssa_print_block_name(f, instr->Br.true_block);
if (instr->Br.false_block != NULL) {
ssa_fprintf(f, ", label ");
ssa_fprintf(f, "%%"); ssa_print_block_name(f, instr->br.false_block);
ssa_fprintf(f, "%%"); ssa_print_block_name(f, instr->Br.false_block);
}
ssa_fprintf(f, "\n");
} break;
case ssaInstr_Ret: {
auto *ret = &instr->ret;
auto *ret = &instr->Ret;
ssa_fprintf(f, "ret ");
if (ret->value == NULL) {
ssa_fprintf(f, "void");
} else {
Type *t = ssa_value_type(ret->value);
Type *t = ssa_type(ret->value);
ssa_print_type(f, m->sizes, t);
ssa_fprintf(f, " ");
ssa_print_value(f, m, ret->value, t);
@@ -406,7 +406,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
} break;
case ssaInstr_Conv: {
auto *c = &instr->conv;
auto *c = &instr->Conv;
ssa_fprintf(f, "%%%d = %.*s ", value->id, LIT(ssa_conv_strings[c->kind]));
ssa_print_type(f, m->sizes, c->from);
ssa_fprintf(f, " ");
@@ -422,8 +422,8 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
} break;
case ssaInstr_BinaryOp: {
auto *bo = &value->instr.binary_op;
Type *type = get_base_type(ssa_value_type(bo->left));
auto *bo = &value->Instr.BinaryOp;
Type *type = get_base_type(ssa_type(bo->left));
Type *elem_type = type;
while (elem_type->kind == Type_Vector) {
elem_type = get_base_type(elem_type->vector.elem);
@@ -528,7 +528,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
} break;
case ssaInstr_Call: {
auto *call = &instr->call;
auto *call = &instr->Call;
Type *result_type = call->type;
if (result_type) {
ssa_fprintf(f, "%%%d = ", value->id);
@@ -545,7 +545,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
ssa_fprintf(f, "(");
if (call->arg_count > 0) {
Type *proc_type = get_base_type(ssa_value_type(call->value));
Type *proc_type = get_base_type(ssa_type(call->value));
GB_ASSERT(proc_type->kind == Type_Proc);
auto *params = &proc_type->proc.params->tuple;
for (isize i = 0; i < call->arg_count; i++) {
@@ -567,15 +567,15 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
case ssaInstr_Select: {
ssa_fprintf(f, "%%%d = select i1 ", value->id);
ssa_print_value(f, m, instr->select.cond, t_bool);
ssa_print_value(f, m, instr->Select.cond, t_bool);
ssa_fprintf(f, ", ");
ssa_print_type(f, m->sizes, ssa_value_type(instr->select.true_value));
ssa_print_type(f, m->sizes, ssa_type(instr->Select.true_value));
ssa_fprintf(f, " ");
ssa_print_value(f, m, instr->select.true_value, ssa_value_type(instr->select.true_value));
ssa_print_value(f, m, instr->Select.true_value, ssa_type(instr->Select.true_value));
ssa_fprintf(f, ", ");
ssa_print_type(f, m->sizes, ssa_value_type(instr->select.false_value));
ssa_print_type(f, m->sizes, ssa_type(instr->Select.false_value));
ssa_fprintf(f, " ");
ssa_print_value(f, m, instr->select.false_value, ssa_value_type(instr->select.false_value));
ssa_print_value(f, m, instr->Select.false_value, ssa_type(instr->Select.false_value));
ssa_fprintf(f, "\n");
} break;
@@ -583,39 +583,39 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
ssa_fprintf(f, "call void @llvm.memmove.p0i8.p0i8.");
ssa_print_type(f, m->sizes, t_int);
ssa_fprintf(f, "(i8* ");
ssa_print_value(f, m, instr->copy_memory.dst, t_rawptr);
ssa_print_value(f, m, instr->CopyMemory.dst, t_rawptr);
ssa_fprintf(f, ", i8* ");
ssa_print_value(f, m, instr->copy_memory.src, t_rawptr);
ssa_print_value(f, m, instr->CopyMemory.src, t_rawptr);
ssa_fprintf(f, ", ");
ssa_print_type(f, m->sizes, t_int);
ssa_fprintf(f, " ");
ssa_print_value(f, m, instr->copy_memory.len, t_int);
ssa_print_value(f, m, instr->CopyMemory.len, t_int);
char *vol_str = "false";
if (instr->copy_memory.is_volatile) {
if (instr->CopyMemory.is_volatile) {
vol_str = "true";
}
ssa_fprintf(f, ", i32 %d, i1 %s)\n", instr->copy_memory.align, vol_str);
ssa_fprintf(f, ", i32 %d, i1 %s)\n", instr->CopyMemory.align, vol_str);
} break;
case ssaInstr_ExtractElement: {
Type *vt = ssa_value_type(instr->extract_element.vector);
Type *vt = ssa_type(instr->ExtractElement.vector);
ssa_fprintf(f, "%%%d = extractelement ", value->id);
ssa_print_type(f, m->sizes, vt);
ssa_fprintf(f, " ");
ssa_print_value(f, m, instr->extract_element.vector, vt);
ssa_print_value(f, m, instr->ExtractElement.vector, vt);
ssa_fprintf(f, ", ");
Type *it = ssa_value_type(instr->extract_element.index);
Type *it = ssa_type(instr->ExtractElement.index);
ssa_print_type(f, m->sizes, it);
ssa_fprintf(f, " ");
ssa_print_value(f, m, instr->extract_element.index, it);
ssa_print_value(f, m, instr->ExtractElement.index, it);
ssa_fprintf(f, "\n");
} break;
case ssaInstr_InsertElement: {
auto *ie = &instr->insert_element;
Type *vt = ssa_value_type(ie->vector);
auto *ie = &instr->InsertElement;
Type *vt = ssa_type(ie->vector);
ssa_fprintf(f, "%%%d = insertelement ", value->id);
ssa_print_type(f, m->sizes, vt);
@@ -623,21 +623,21 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) {
ssa_print_value(f, m, ie->vector, vt);
ssa_fprintf(f, ", ");
ssa_print_type(f, m->sizes, ssa_value_type(ie->elem));
ssa_print_type(f, m->sizes, ssa_type(ie->elem));
ssa_fprintf(f, " ");
ssa_print_value(f, m, ie->elem, ssa_value_type(ie->elem));
ssa_print_value(f, m, ie->elem, ssa_type(ie->elem));
ssa_fprintf(f, ", ");
ssa_print_type(f, m->sizes, ssa_value_type(ie->index));
ssa_print_type(f, m->sizes, ssa_type(ie->index));
ssa_fprintf(f, " ");
ssa_print_value(f, m, ie->index, ssa_value_type(ie->index));
ssa_print_value(f, m, ie->index, ssa_type(ie->index));
ssa_fprintf(f, "\n");
} break;
case ssaInstr_ShuffleVector: {
auto *sv = &instr->shuffle_vector;
Type *vt = ssa_value_type(sv->vector);
auto *sv = &instr->ShuffleVector;
Type *vt = ssa_type(sv->vector);
ssa_fprintf(f, "%%%d = shufflevector ", value->id);
ssa_print_type(f, m->sizes, vt);
@@ -738,9 +738,9 @@ void ssa_print_proc(gbFile *f, ssaModule *m, ssaProcedure *proc) {
void ssa_print_type_name(gbFile *f, ssaModule *m, ssaValue *v) {
GB_ASSERT(v->kind == ssaValue_TypeName);
ssa_print_encoded_local(f, v->type_name.name);
ssa_print_encoded_local(f, v->TypeName.name);
ssa_fprintf(f, " = type ");
ssa_print_type(f, m->sizes, get_base_type(v->type_name.type));
ssa_print_type(f, m->sizes, get_base_type(v->TypeName.type));
ssa_fprintf(f, "\n");
}
@@ -763,9 +763,9 @@ void ssa_print_llvm_ir(gbFile *f, ssaModule *m) {
ssaValue *v = entry->value;
switch (v->kind) {
case ssaValue_TypeName: {
ssa_print_encoded_local(f, v->type_name.name);
ssa_print_encoded_local(f, v->TypeName.name);
ssa_fprintf(f, " = type ");
ssa_print_type(f, m->sizes, get_base_type(v->type_name.type));
ssa_print_type(f, m->sizes, get_base_type(v->TypeName.type));
ssa_fprintf(f, "\n");
} break;
}
@@ -790,16 +790,20 @@ void ssa_print_llvm_ir(gbFile *f, ssaModule *m) {
ssaValue *v = entry->value;
switch (v->kind) {
case ssaValue_Global: {
auto *g = &v->global;
auto *g = &v->Global;
ssa_print_encoded_global(f, g->entity->token.string);
ssa_fprintf(f, " = ");
if (g->is_thread_local) {
ssa_fprintf(f, "thread_local ");
}
if (g->is_constant) {
ssa_fprintf(f, "private constant ");
} else {
ssa_fprintf(f, "global ");
}
ssa_print_type(f, m->sizes, get_base_type(g->entity->type));
ssa_print_type(f, m->sizes, g->entity->type);
ssa_fprintf(f, " ");
if (g->value != NULL) {
ssa_print_value(f, m, g->value, g->entity->type);
@@ -810,7 +814,7 @@ void ssa_print_llvm_ir(gbFile *f, ssaModule *m) {
} break;
case ssaValue_Proc: {
ssa_print_proc(f, m, &v->proc);
ssa_print_proc(f, m, &v->Proc);
} break;
}
}
+334 -378
View File
File diff suppressed because it is too large Load Diff
+21 -1
View File
@@ -77,6 +77,10 @@ enum ProcTag {
ProcTag_no_inline = GB_BIT(2),
};
enum VarDeclTag {
VarDeclTag_thread_local = GB_BIT(0),
};
#define AST_NODE_KINDS \
AST_NODE_KIND(Invalid, struct{}) \
AST_NODE_KIND(BasicLit, Token) \
@@ -165,6 +169,7 @@ AST_NODE_KIND(_DeclBegin, struct{}) \
AST_NODE_KIND(BadDecl, struct { Token begin, end; }) \
AST_NODE_KIND(VarDecl, struct { \
DeclKind kind; \
u32 tags; \
AstNode *name_list; \
AstNode *type; \
AstNode *value_list; \
@@ -177,7 +182,7 @@ AST_NODE_KIND(_DeclBegin, struct{}) \
u64 tags; \
String foreign_name; \
}) \
AST_NODE_KIND(TypeDecl, struct { Token token; AstNode *name, *type; }) \
AST_NODE_KIND(TypeDecl, struct { Token token; AstNode *name, *type; }) \
AST_NODE_KIND(LoadDecl, struct { Token token, filepath; }) \
AST_NODE_KIND(_DeclEnd, struct{}) \
AST_NODE_KIND(_TypeBegin, struct{}) \
@@ -1994,7 +1999,22 @@ AstNode *parse_stmt(AstFile *f) {
}
ast_file_err(f, token, "You cannot `load` within a procedure. This must be done at the file scope.");
return make_bad_decl(f, token, file_path);
} else if (are_strings_equal(s->TagStmt.name.string, make_string("thread_local"))) {
AstNode *var_decl = parse_simple_stmt(f);
if (var_decl->kind != AstNode_VarDecl ||
var_decl->VarDecl.kind != Declaration_Mutable) {
ast_file_err(f, token, "#thread_local may only be applied to variable declarations");
return make_bad_decl(f, token, ast_node_token(var_decl));
}
if (f->curr_scope != f->file_scope) {
ast_file_err(f, token, "#thread_local is only allowed at the file scope.");
return make_bad_decl(f, token, ast_node_token(var_decl));
}
var_decl->VarDecl.tags |= VarDeclTag_thread_local;
return var_decl;
}
s->TagStmt.stmt = parse_stmt(f); // TODO(bill): Find out why this doesn't work as an argument
return s;
} break;
+4 -4
View File
@@ -371,25 +371,25 @@ void tokenizer_skip_whitespace(Tokenizer *t) {
if (t->read_curr[0] == '/') { // Line comment //
while (t->curr_rune != '\n')
advance_to_next_rune(t);
} else if (t->read_curr[0] == '{') { // (Nested) Block comment /{}/
} else if (t->read_curr[0] == '*') { // (Nested) Block comment /**/
isize comment_scope = 1;
for (;;) {
advance_to_next_rune(t);
if (t->curr_rune == '/') {
advance_to_next_rune(t);
if (t->curr_rune == '{') {
if (t->curr_rune == '*') {
advance_to_next_rune(t);
comment_scope++;
}
}
if (t->curr_rune == '}') {
if (t->curr_rune == '*') {
advance_to_next_rune(t);
if (t->curr_rune == '/') {
advance_to_next_rune(t);
comment_scope--;
}
}
if (comment_scope == 0)
if (comment_scope <= 0)
break;
}
} else {