Commit c7591736b4

Andrew Kelley <superjoe30@gmail.com>
2017-01-16 07:44:47
fix array of enums. also render debug info for const vars
1 parent 3752e0c
Changed files (3)
src/analyze.cpp
@@ -1336,7 +1336,6 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {
 
     Scope *scope = &struct_type->data.structure.decls_scope->base;
 
-    //if (buf_eql_str(&struct_type->name, "Particle")) { BREAKPOINT; }
     for (size_t i = 0; i < field_count; i += 1) {
         TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
         TypeTableEntry *field_type = type_struct_field->type_entry;
src/codegen.cpp
@@ -1238,7 +1238,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
     if (!type_has_bits(var->value.type))
         return nullptr;
 
-    if (var->ref_count == 0)
+    if (var->ref_count == 0 && g->is_release_build)
         return nullptr;
 
     IrInstruction *init_value = decl_var_instruction->init_value;
@@ -2501,14 +2501,13 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
             }
         case TypeTableEntryIdArray:
             {
-                TypeTableEntry *child_type = canon_type->data.array.child_type;
                 uint64_t len = canon_type->data.array.len;
                 LLVMValueRef *values = allocate<LLVMValueRef>(len);
                 for (uint64_t i = 0; i < len; i += 1) {
                     ConstExprValue *elem_value = &const_val->data.x_array.elements[i];
                     values[i] = gen_const_val(g, elem_value);
                 }
-                return LLVMConstArray(child_type->type_ref, values, len);
+                return LLVMConstArray(LLVMTypeOf(values[0]), values, len);
             }
         case TypeTableEntryIdEnum:
             {
@@ -2554,35 +2553,43 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
             {
                 render_const_val_global(g, const_val);
                 size_t index = const_val->data.x_ptr.index;
-                if (index == SIZE_MAX) {
-                    render_const_val(g, const_val->data.x_ptr.base_ptr);
-                    render_const_val_global(g, const_val->data.x_ptr.base_ptr);
-                    ConstExprValue *other_val = const_val->data.x_ptr.base_ptr;
-                    const_val->llvm_value = LLVMConstBitCast(other_val->llvm_global, const_val->type->type_ref);
-                    render_const_val_global(g, const_val);
-                    return const_val->llvm_value;
-                } else {
-                    ConstExprValue *array_const_val = const_val->data.x_ptr.base_ptr;
-                    assert(array_const_val->type->id == TypeTableEntryIdArray);
-                    if (array_const_val->type->zero_bits) {
-                        // make this a null pointer
-                        TypeTableEntry *usize_type = g->builtin_types.entry_usize;
-                        const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize_type->type_ref),
-                                const_val->type->type_ref);
+                ConstExprValue *base_ptr = const_val->data.x_ptr.base_ptr;
+                TypeTableEntry *usize = g->builtin_types.entry_usize;
+                if (base_ptr) {
+                    if (index == SIZE_MAX) {
+                        render_const_val(g, base_ptr);
+                        render_const_val_global(g, base_ptr);
+                        ConstExprValue *other_val = base_ptr;
+                        const_val->llvm_value = LLVMConstBitCast(other_val->llvm_global, const_val->type->type_ref);
                         render_const_val_global(g, const_val);
                         return const_val->llvm_value;
+                    } else {
+                        ConstExprValue *array_const_val = base_ptr;
+                        assert(array_const_val->type->id == TypeTableEntryIdArray);
+                        if (array_const_val->type->zero_bits) {
+                            // make this a null pointer
+                            TypeTableEntry *usize_type = g->builtin_types.entry_usize;
+                            const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize_type->type_ref),
+                                    const_val->type->type_ref);
+                            render_const_val_global(g, const_val);
+                            return const_val->llvm_value;
+                        }
+                        render_const_val(g, array_const_val);
+                        render_const_val_global(g, array_const_val);
+                        LLVMValueRef indices[] = {
+                            LLVMConstNull(usize->type_ref),
+                            LLVMConstInt(usize->type_ref, index, false),
+                        };
+                        LLVMValueRef uncasted_ptr_val = LLVMConstInBoundsGEP(array_const_val->llvm_global, indices, 2);
+                        LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref);
+                        const_val->llvm_value = ptr_val;
+                        render_const_val_global(g, const_val);
+                        return ptr_val;
                     }
-                    render_const_val(g, array_const_val);
-                    render_const_val_global(g, array_const_val);
-                    TypeTableEntry *usize = g->builtin_types.entry_usize;
-                    LLVMValueRef indices[] = {
-                        LLVMConstNull(usize->type_ref),
-                        LLVMConstInt(usize->type_ref, index, false),
-                    };
-                    LLVMValueRef ptr_val = LLVMConstInBoundsGEP(array_const_val->llvm_global, indices, 2);
-                    const_val->llvm_value = ptr_val;
+                } else {
+                    const_val->llvm_value = LLVMConstIntToPtr(LLVMConstInt(usize->type_ref, index, false), const_val->type->type_ref);
                     render_const_val_global(g, const_val);
-                    return ptr_val;
+                    return const_val->llvm_value;
                 }
             }
         case TypeTableEntryIdErrorUnion:
src/ir.cpp
@@ -3465,7 +3465,7 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld
         {
             TldVar *tld_var = (TldVar *)tld;
             VariableTableEntry *var = tld_var->var;
-            IrInstruction *var_ptr = ir_build_var_ptr(irb, scope, source_node, var, false);
+            IrInstruction *var_ptr = ir_build_var_ptr(irb, scope, source_node, var, lval == LValPurposeAddressOfConst);
             if (lval != LValPurposeNone)
                 return var_ptr;
             else
@@ -7655,9 +7655,9 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
         buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name);
         impl_fn->fndef_scope = create_fndef_scope(impl_fn->fn_def_node, parent_scope, impl_fn);
         impl_fn->child_scope = &impl_fn->fndef_scope->base;
-        FnTypeId fn_type_id = {0};
-        init_fn_type_id(&fn_type_id, fn_proto_node);
-        fn_type_id.param_count = 0;
+        FnTypeId inst_fn_type_id = {0};
+        init_fn_type_id(&inst_fn_type_id, fn_proto_node);
+        inst_fn_type_id.param_count = 0;
 
         // TODO maybe GenericFnTypeId can be replaced with using the child_scope directly
         // as the key in generic_table
@@ -7679,7 +7679,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
             }
 
             if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, first_arg, &impl_fn->child_scope,
-                &next_proto_i, generic_id, &fn_type_id, casted_args, impl_fn))
+                &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn))
             {
                 return ira->codegen->builtin_types.entry_invalid;
             }
@@ -7690,7 +7690,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
                 return ira->codegen->builtin_types.entry_invalid;
 
             if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg, &impl_fn->child_scope,
-                &next_proto_i, generic_id, &fn_type_id, casted_args, impl_fn))
+                &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn))
             {
                 return ira->codegen->builtin_types.entry_invalid;
             }
@@ -7701,7 +7701,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
             TypeTableEntry *return_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, return_type_node);
             if (return_type->id == TypeTableEntryIdInvalid)
                 return ira->codegen->builtin_types.entry_invalid;
-            fn_type_id.return_type = return_type;
+            inst_fn_type_id.return_type = return_type;
 
             if (type_requires_comptime(return_type)) {
                 // Throw out our work and call the function as if it were inline.
@@ -7715,7 +7715,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
             impl_fn = existing_entry->value;
         } else {
             // finish instantiating the function
-            impl_fn->type_entry = get_fn_type(ira->codegen, &fn_type_id);
+            impl_fn->type_entry = get_fn_type(ira->codegen, &inst_fn_type_id);
             if (impl_fn->type_entry->id == TypeTableEntryIdInvalid)
                 return ira->codegen->builtin_types.entry_invalid;
 
@@ -7802,7 +7802,7 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction
 
     bool is_inline = call_instruction->is_comptime || ir_should_inline(&ira->new_irb);
 
-    if (is_inline || fn_ref->value.special != ConstValSpecialRuntime) {
+    if (is_inline || instr_is_comptime(fn_ref)) {
         if (fn_ref->value.type->id == TypeTableEntryIdMetaType) {
             TypeTableEntry *dest_type = ir_resolve_type(ira, fn_ref);
             if (dest_type->id == TypeTableEntryIdInvalid)