aboutsummaryrefslogtreecommitdiff
path: root/src/analyze.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-12-18 00:09:43 -0500
committerAndrew Kelley <superjoe30@gmail.com>2016-12-18 00:09:43 -0500
commit85b6d1463792a321832ff79b81d5ba51c324d7fa (patch)
tree1a9d6779ce2bcda6d18c4f724b19dbcddc502ff9 /src/analyze.cpp
parente73faf9a9efad4c3a8deb1ae8a21302f4366c0ac (diff)
downloadzig-85b6d1463792a321832ff79b81d5ba51c324d7fa.tar.gz
zig-85b6d1463792a321832ff79b81d5ba51c324d7fa.zip
IR: support var type args and fix phi peer type resolution
Diffstat (limited to 'src/analyze.cpp')
-rw-r--r--src/analyze.cpp141
1 files changed, 91 insertions, 50 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 8bc861c879..6c4d05be17 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -723,6 +723,8 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
fn_type->data.fn.calling_convention = LLVMFastCallConv;
}
+ bool skip_debug_info = false;
+
// populate the name of the type
buf_resize(&fn_type->name, 0);
const char *extern_str = fn_type_id->is_extern ? "extern " : "";
@@ -736,6 +738,8 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
const char *comma = (i == 0) ? "" : ", ";
const char *noalias_str = param_info->is_noalias ? "noalias " : "";
buf_appendf(&fn_type->name, "%s%s%s", comma, noalias_str, buf_ptr(&param_type->name));
+
+ skip_debug_info = skip_debug_info || !param_type->di_type;
}
if (fn_type_id->is_var_args) {
@@ -746,66 +750,69 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
if (fn_type_id->return_type->id != TypeTableEntryIdVoid) {
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
// and codegen information
- bool first_arg_return = !fn_type_id->is_extern && handle_is_ptr(fn_type_id->return_type);
- // +1 for maybe making the first argument the return value
- LLVMTypeRef *gen_param_types = allocate<LLVMTypeRef>(1 + fn_type_id->param_count);
- // +1 because 0 is the return type and +1 for maybe making first arg ret val
- ZigLLVMDIType **param_di_types = allocate<ZigLLVMDIType*>(2 + fn_type_id->param_count);
- param_di_types[0] = fn_type_id->return_type->di_type;
- size_t gen_param_index = 0;
- TypeTableEntry *gen_return_type;
- if (!type_has_bits(fn_type_id->return_type)) {
- gen_return_type = g->builtin_types.entry_void;
- } else if (first_arg_return) {
- TypeTableEntry *gen_type = get_pointer_to_type(g, fn_type_id->return_type, false);
- gen_param_types[gen_param_index] = gen_type->type_ref;
- gen_param_index += 1;
- // after the gen_param_index += 1 because 0 is the return type
- param_di_types[gen_param_index] = gen_type->di_type;
- gen_return_type = g->builtin_types.entry_void;
- } else {
- gen_return_type = fn_type_id->return_type;
- }
- fn_type->data.fn.gen_return_type = gen_return_type;
-
- fn_type->data.fn.gen_param_info = allocate<FnGenParamInfo>(fn_type_id->param_count);
- for (size_t i = 0; i < fn_type_id->param_count; i += 1) {
- FnTypeParamInfo *src_param_info = &fn_type->data.fn.fn_type_id.param_info[i];
- TypeTableEntry *type_entry = src_param_info->type;
- FnGenParamInfo *gen_param_info = &fn_type->data.fn.gen_param_info[i];
-
- gen_param_info->src_index = i;
- gen_param_info->gen_index = SIZE_MAX;
-
- assert(type_is_complete(type_entry));
- if (type_has_bits(type_entry)) {
- TypeTableEntry *gen_type;
- if (handle_is_ptr(type_entry)) {
- gen_type = get_pointer_to_type(g, type_entry, true);
- gen_param_info->is_byval = true;
- } else {
- gen_type = type_entry;
- }
+ if (!skip_debug_info) {
+ bool first_arg_return = !fn_type_id->is_extern && handle_is_ptr(fn_type_id->return_type);
+ // +1 for maybe making the first argument the return value
+ LLVMTypeRef *gen_param_types = allocate<LLVMTypeRef>(1 + fn_type_id->param_count);
+ // +1 because 0 is the return type and +1 for maybe making first arg ret val
+ ZigLLVMDIType **param_di_types = allocate<ZigLLVMDIType*>(2 + fn_type_id->param_count);
+ param_di_types[0] = fn_type_id->return_type->di_type;
+ size_t gen_param_index = 0;
+ TypeTableEntry *gen_return_type;
+ if (!type_has_bits(fn_type_id->return_type)) {
+ gen_return_type = g->builtin_types.entry_void;
+ } else if (first_arg_return) {
+ TypeTableEntry *gen_type = get_pointer_to_type(g, fn_type_id->return_type, false);
gen_param_types[gen_param_index] = gen_type->type_ref;
- gen_param_info->gen_index = gen_param_index;
- gen_param_info->type = gen_type;
-
gen_param_index += 1;
-
// after the gen_param_index += 1 because 0 is the return type
param_di_types[gen_param_index] = gen_type->di_type;
+ gen_return_type = g->builtin_types.entry_void;
+ } else {
+ gen_return_type = fn_type_id->return_type;
}
- }
+ fn_type->data.fn.gen_return_type = gen_return_type;
+
+ fn_type->data.fn.gen_param_info = allocate<FnGenParamInfo>(fn_type_id->param_count);
+ for (size_t i = 0; i < fn_type_id->param_count; i += 1) {
+ FnTypeParamInfo *src_param_info = &fn_type->data.fn.fn_type_id.param_info[i];
+ TypeTableEntry *type_entry = src_param_info->type;
+ FnGenParamInfo *gen_param_info = &fn_type->data.fn.gen_param_info[i];
+
+ gen_param_info->src_index = i;
+ gen_param_info->gen_index = SIZE_MAX;
+
+ assert(type_is_complete(type_entry));
+ if (type_has_bits(type_entry)) {
+ TypeTableEntry *gen_type;
+ if (handle_is_ptr(type_entry)) {
+ gen_type = get_pointer_to_type(g, type_entry, true);
+ gen_param_info->is_byval = true;
+ } else {
+ gen_type = type_entry;
+ }
+ gen_param_types[gen_param_index] = gen_type->type_ref;
+ gen_param_info->gen_index = gen_param_index;
+ gen_param_info->type = gen_type;
+
+ gen_param_index += 1;
- fn_type->data.fn.gen_param_count = gen_param_index;
+ // after the gen_param_index += 1 because 0 is the return type
+ param_di_types[gen_param_index] = gen_type->di_type;
+ }
+ }
- fn_type->data.fn.raw_type_ref = LLVMFunctionType(gen_return_type->type_ref,
- gen_param_types, gen_param_index, fn_type_id->is_var_args);
- fn_type->type_ref = LLVMPointerType(fn_type->data.fn.raw_type_ref, 0);
- fn_type->di_type = ZigLLVMCreateSubroutineType(g->dbuilder, param_di_types, gen_param_index + 1, 0);
+ fn_type->data.fn.gen_param_count = gen_param_index;
+
+ fn_type->data.fn.raw_type_ref = LLVMFunctionType(gen_return_type->type_ref,
+ gen_param_types, gen_param_index, fn_type_id->is_var_args);
+ fn_type->type_ref = LLVMPointerType(fn_type->data.fn.raw_type_ref, 0);
+ fn_type->di_type = ZigLLVMCreateSubroutineType(g->dbuilder, param_di_types, gen_param_index + 1, 0);
+ }
g->fn_type_table.put(&fn_type->data.fn.fn_type_id, fn_type);
@@ -2765,6 +2772,40 @@ static TypeTableEntry *type_of_first_thing_in_memory(TypeTableEntry *type_entry)
zig_unreachable();
}
+bool type_requires_comptime(TypeTableEntry *type_entry) {
+ switch (type_entry->id) {
+ case TypeTableEntryIdInvalid:
+ case TypeTableEntryIdUnreachable:
+ case TypeTableEntryIdVar:
+ zig_unreachable();
+ case TypeTableEntryIdNumLitFloat:
+ case TypeTableEntryIdNumLitInt:
+ case TypeTableEntryIdUndefLit:
+ case TypeTableEntryIdNullLit:
+ case TypeTableEntryIdMetaType:
+ case TypeTableEntryIdVoid:
+ case TypeTableEntryIdNamespace:
+ case TypeTableEntryIdBlock:
+ case TypeTableEntryIdBoundFn:
+ return true;
+ case TypeTableEntryIdArray:
+ case TypeTableEntryIdStruct:
+ case TypeTableEntryIdUnion:
+ case TypeTableEntryIdMaybe:
+ case TypeTableEntryIdErrorUnion:
+ case TypeTableEntryIdTypeDecl:
+ case TypeTableEntryIdEnum:
+ case TypeTableEntryIdPureError:
+ case TypeTableEntryIdFn:
+ case TypeTableEntryIdBool:
+ case TypeTableEntryIdInt:
+ case TypeTableEntryIdFloat:
+ case TypeTableEntryIdPointer:
+ return false;
+ }
+ zig_unreachable();
+}
+
uint64_t get_memcpy_align(CodeGen *g, TypeTableEntry *type_entry) {
TypeTableEntry *first_type_in_mem = type_of_first_thing_in_memory(type_entry);
return LLVMABISizeOfType(g->target_data_ref, first_type_in_mem->type_ref);