aboutsummaryrefslogtreecommitdiff
path: root/src/analyze.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-01-25 11:51:41 -0500
committerAndrew Kelley <superjoe30@gmail.com>2018-01-25 11:51:41 -0500
commit47be64af5add5c146541c16dbb043ddf97f97d34 (patch)
tree3fabcb50c94b254a71cdbf009f29ad1ece6b1f67 /src/analyze.cpp
parent4556f448060b19492d7b104ff01585241ba9c256 (diff)
parentf7670882aff5fb3a943057edd9da34d053b5fe59 (diff)
downloadzig-47be64af5add5c146541c16dbb043ddf97f97d34.tar.gz
zig-47be64af5add5c146541c16dbb043ddf97f97d34.zip
Merge remote-tracking branch 'origin/master' into llvm6
Diffstat (limited to 'src/analyze.cpp')
-rw-r--r--src/analyze.cpp176
1 files changed, 126 insertions, 50 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 9da8485014..49f8e093a0 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -609,7 +609,10 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t
buf_resize(&entry->name, 0);
buf_appendf(&entry->name, "[%" ZIG_PRI_u64 "]%s", array_size, buf_ptr(&child_type->name));
- if (!entry->zero_bits) {
+ if (entry->zero_bits) {
+ entry->di_type = ZigLLVMCreateDebugArrayType(g->dbuilder, 0,
+ 0, child_type->di_type, 0);
+ } else {
entry->type_ref = child_type->type_ref ? LLVMArrayType(child_type->type_ref,
(unsigned int)array_size) : nullptr;
@@ -915,9 +918,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
if (fn_type_id->alignment != 0) {
buf_appendf(&fn_type->name, " align(%" PRIu32 ")", fn_type_id->alignment);
}
- if (fn_type_id->return_type->id != TypeTableEntryIdVoid) {
- buf_appendf(&fn_type->name, " -> %s", buf_ptr(&fn_type_id->return_type->name));
- }
+ buf_appendf(&fn_type->name, " %s", buf_ptr(&fn_type_id->return_type->name));
skip_debug_info = skip_debug_info || !fn_type_id->return_type->di_type;
// next, loop over the parameters again and compute debug information
@@ -1079,7 +1080,7 @@ TypeTableEntry *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
const char *comma_str = (i == 0) ? "" : ",";
buf_appendf(&fn_type->name, "%svar", comma_str);
}
- buf_appendf(&fn_type->name, ")->var");
+ buf_appendf(&fn_type->name, ")var");
fn_type->data.fn.fn_type_id = *fn_type_id;
fn_type->data.fn.is_generic = true;
@@ -1155,6 +1156,104 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **
return true;
}
+static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
+ switch (type_entry->id) {
+ case TypeTableEntryIdInvalid:
+ case TypeTableEntryIdVar:
+ zig_unreachable();
+ case TypeTableEntryIdMetaType:
+ case TypeTableEntryIdUnreachable:
+ case TypeTableEntryIdNumLitFloat:
+ case TypeTableEntryIdNumLitInt:
+ case TypeTableEntryIdUndefLit:
+ case TypeTableEntryIdNullLit:
+ case TypeTableEntryIdErrorUnion:
+ case TypeTableEntryIdPureError:
+ case TypeTableEntryIdNamespace:
+ case TypeTableEntryIdBlock:
+ case TypeTableEntryIdBoundFn:
+ case TypeTableEntryIdArgTuple:
+ case TypeTableEntryIdOpaque:
+ return false;
+ case TypeTableEntryIdVoid:
+ case TypeTableEntryIdBool:
+ case TypeTableEntryIdInt:
+ case TypeTableEntryIdFloat:
+ case TypeTableEntryIdPointer:
+ case TypeTableEntryIdArray:
+ case TypeTableEntryIdFn:
+ return true;
+ case TypeTableEntryIdStruct:
+ return type_entry->data.structure.layout == ContainerLayoutPacked;
+ case TypeTableEntryIdUnion:
+ return type_entry->data.unionation.layout == ContainerLayoutPacked;
+ case TypeTableEntryIdMaybe:
+ {
+ TypeTableEntry *child_type = type_entry->data.maybe.child_type;
+ return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn;
+ }
+ case TypeTableEntryIdEnum:
+ return type_entry->data.enumeration.decl_node->data.container_decl.init_arg_expr != nullptr;
+ }
+ zig_unreachable();
+}
+
+static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {
+ switch (type_entry->id) {
+ case TypeTableEntryIdInvalid:
+ case TypeTableEntryIdVar:
+ zig_unreachable();
+ case TypeTableEntryIdMetaType:
+ case TypeTableEntryIdNumLitFloat:
+ case TypeTableEntryIdNumLitInt:
+ case TypeTableEntryIdUndefLit:
+ case TypeTableEntryIdNullLit:
+ case TypeTableEntryIdErrorUnion:
+ case TypeTableEntryIdPureError:
+ case TypeTableEntryIdNamespace:
+ case TypeTableEntryIdBlock:
+ case TypeTableEntryIdBoundFn:
+ case TypeTableEntryIdArgTuple:
+ return false;
+ case TypeTableEntryIdOpaque:
+ case TypeTableEntryIdUnreachable:
+ case TypeTableEntryIdVoid:
+ case TypeTableEntryIdBool:
+ return true;
+ case TypeTableEntryIdInt:
+ switch (type_entry->data.integral.bit_count) {
+ case 8:
+ case 16:
+ case 32:
+ case 64:
+ case 128:
+ return true;
+ default:
+ return false;
+ }
+ case TypeTableEntryIdFloat:
+ return true;
+ case TypeTableEntryIdArray:
+ return type_allowed_in_extern(g, type_entry->data.array.child_type);
+ case TypeTableEntryIdFn:
+ return type_entry->data.fn.fn_type_id.cc == CallingConventionC;
+ case TypeTableEntryIdPointer:
+ return type_allowed_in_extern(g, type_entry->data.pointer.child_type);
+ case TypeTableEntryIdStruct:
+ return type_entry->data.structure.layout == ContainerLayoutExtern;
+ case TypeTableEntryIdMaybe:
+ {
+ TypeTableEntry *child_type = type_entry->data.maybe.child_type;
+ return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn;
+ }
+ case TypeTableEntryIdEnum:
+ return type_entry->data.enumeration.layout == ContainerLayoutExtern;
+ case TypeTableEntryIdUnion:
+ return type_entry->data.unionation.layout == ContainerLayoutExtern;
+ }
+ zig_unreachable();
+}
+
static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope) {
assert(proto_node->type == NodeTypeFnProto);
AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
@@ -1205,6 +1304,14 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
}
}
+ if (fn_type_id.cc != CallingConventionUnspecified && !type_allowed_in_extern(g, type_entry)) {
+ add_node_error(g, param_node->data.param_decl.type,
+ buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'",
+ buf_ptr(&type_entry->name),
+ calling_convention_name(fn_type_id.cc)));
+ return g->builtin_types.entry_invalid;
+ }
+
switch (type_entry->id) {
case TypeTableEntryIdInvalid:
return g->builtin_types.entry_invalid;
@@ -1269,6 +1376,14 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
fn_type_id.return_type = (fn_proto->return_type == nullptr) ?
g->builtin_types.entry_void : analyze_type_expr(g, child_scope, fn_proto->return_type);
+ if (fn_type_id.cc != CallingConventionUnspecified && !type_allowed_in_extern(g, fn_type_id.return_type)) {
+ add_node_error(g, fn_proto->return_type,
+ buf_sprintf("return type '%s' not allowed in function with calling convention '%s'",
+ buf_ptr(&fn_type_id.return_type->name),
+ calling_convention_name(fn_type_id.cc)));
+ return g->builtin_types.entry_invalid;
+ }
+
switch (fn_type_id.return_type->id) {
case TypeTableEntryIdInvalid:
return g->builtin_types.entry_invalid;
@@ -1421,46 +1536,6 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
enum_type->di_type = tag_di_type;
}
-static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
- switch (type_entry->id) {
- case TypeTableEntryIdInvalid:
- case TypeTableEntryIdVar:
- zig_unreachable();
- case TypeTableEntryIdMetaType:
- case TypeTableEntryIdUnreachable:
- case TypeTableEntryIdNumLitFloat:
- case TypeTableEntryIdNumLitInt:
- case TypeTableEntryIdUndefLit:
- case TypeTableEntryIdNullLit:
- case TypeTableEntryIdErrorUnion:
- case TypeTableEntryIdPureError:
- case TypeTableEntryIdNamespace:
- case TypeTableEntryIdBlock:
- case TypeTableEntryIdBoundFn:
- case TypeTableEntryIdArgTuple:
- case TypeTableEntryIdOpaque:
- return false;
- case TypeTableEntryIdVoid:
- case TypeTableEntryIdBool:
- case TypeTableEntryIdInt:
- case TypeTableEntryIdFloat:
- case TypeTableEntryIdPointer:
- case TypeTableEntryIdArray:
- case TypeTableEntryIdUnion:
- case TypeTableEntryIdFn:
- return true;
- case TypeTableEntryIdStruct:
- return type_entry->data.structure.layout == ContainerLayoutPacked;
- case TypeTableEntryIdMaybe:
- {
- TypeTableEntry *child_type = type_entry->data.maybe.child_type;
- return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn;
- }
- case TypeTableEntryIdEnum:
- return type_entry->data.enumeration.decl_node->data.container_decl.init_arg_expr != nullptr;
- }
- zig_unreachable();
-}
TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
TypeTableEntry *field_types[], size_t field_count)
@@ -1864,7 +1939,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
uint64_t padding_in_bits = biggest_size_in_bits - size_of_most_aligned_member_in_bits;
TypeTableEntry *tag_type = union_type->data.unionation.tag_type;
- if (tag_type == nullptr) {
+ if (tag_type == nullptr || tag_type->zero_bits) {
assert(most_aligned_union_member != nullptr);
if (padding_in_bits > 0) {
@@ -2506,8 +2581,10 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
if (create_enum_type) {
ImportTableEntry *import = get_scope_import(scope);
- uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type->type_ref);
- uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type->type_ref);
+ uint64_t tag_debug_size_in_bits = tag_type->zero_bits ? 0 :
+ 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type->type_ref);
+ uint64_t tag_debug_align_in_bits = tag_type->zero_bits ? 0 :
+ 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type->type_ref);
// TODO get a more accurate debug scope
ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
ZigLLVMFileToScope(import->di_file), buf_ptr(&tag_type->name),
@@ -2586,7 +2663,7 @@ static bool scope_is_root_decls(Scope *scope) {
static void wrong_panic_prototype(CodeGen *g, AstNode *proto_node, TypeTableEntry *fn_type) {
add_node_error(g, proto_node,
- buf_sprintf("expected 'fn([]const u8, ?&builtin.StackTrace) -> unreachable', found '%s'",
+ buf_sprintf("expected 'fn([]const u8, ?&builtin.StackTrace) unreachable', found '%s'",
buf_ptr(&fn_type->name)));
}
@@ -3448,7 +3525,6 @@ TypeUnionField *find_union_type_field(TypeTableEntry *type_entry, Buf *name) {
TypeUnionField *find_union_field_by_tag(TypeTableEntry *type_entry, const BigInt *tag) {
assert(type_entry->id == TypeTableEntryIdUnion);
assert(type_entry->data.unionation.zero_bits_known);
- assert(type_entry->data.unionation.gen_tag_index != SIZE_MAX);
for (uint32_t i = 0; i < type_entry->data.unionation.src_field_count; i += 1) {
TypeUnionField *field = &type_entry->data.unionation.fields[i];
if (bigint_cmp(&field->enum_field->value, tag) == CmpEQ) {