Commit 94bbb46ca6

Andrew Kelley <andrew@ziglang.org>
2019-08-29 16:24:24
fix not fully resolving debug info for structs causing llvm error
1 parent 834a789
src/all_types.hpp
@@ -1214,6 +1214,7 @@ struct ZigTypeStruct {
     HashMap<Buf *, TypeStructField *, buf_hash, buf_eql_buf> fields_by_name;
     RootStruct *root_struct;
     uint32_t *host_int_bytes; // available for packed structs, indexed by gen_index
+    size_t llvm_full_type_queue_index;
 
     uint32_t src_field_count;
     uint32_t gen_field_count;
@@ -1861,6 +1862,7 @@ struct CodeGen {
     ZigList<ErrorTableEntry *> errors_by_index;
     ZigList<CacheHash *> caches_to_release;
     size_t largest_err_name_len;
+    ZigList<ZigType *> type_resolve_stack;
 
     ZigPackage *std_package;
     ZigPackage *panic_package;
src/analyze.cpp
@@ -7271,7 +7271,13 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
             di_scope, di_file, line);
 
         struct_type->data.structure.resolve_status = ResolveStatusLLVMFwdDecl;
-        if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return;
+        if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) {
+            struct_type->data.structure.llvm_full_type_queue_index = g->type_resolve_stack.length;
+            g->type_resolve_stack.append(struct_type);
+            return;
+        } else {
+            struct_type->data.structure.llvm_full_type_queue_index = SIZE_MAX;
+        }
     }
 
     size_t field_count = struct_type->data.structure.src_field_count;
@@ -7475,6 +7481,13 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
     ZigLLVMReplaceTemporary(g->dbuilder, struct_type->llvm_di_type, replacement_di_type);
     struct_type->llvm_di_type = replacement_di_type;
     struct_type->data.structure.resolve_status = ResolveStatusLLVMFull;
+    if (struct_type->data.structure.llvm_full_type_queue_index != SIZE_MAX) {
+        ZigType *last = g->type_resolve_stack.last();
+        assert(last->id == ZigTypeIdStruct);
+        last->data.structure.llvm_full_type_queue_index = struct_type->data.structure.llvm_full_type_queue_index;
+        g->type_resolve_stack.swap_remove(struct_type->data.structure.llvm_full_type_queue_index);
+        struct_type->data.structure.llvm_full_type_queue_index = SIZE_MAX;
+    }
 }
 
 static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatus wanted_resolve_status) {
src/codegen.cpp
@@ -7208,6 +7208,12 @@ static void do_code_gen(CodeGen *g) {
         LLVMSetModuleInlineAsm(g->module, buf_ptr(&g->global_asm));
     }
 
+    while (g->type_resolve_stack.length != 0) {
+        ZigType *ty = g->type_resolve_stack.last();
+        if (type_resolve(g, ty, ResolveStatusLLVMFull))
+            zig_unreachable();
+    }
+
     ZigLLVMDIBuilderFinalize(g->dbuilder);
 
     if (g->verbose_llvm_ir) {
src/list.hpp
@@ -74,6 +74,17 @@ struct ZigList {
         capacity = better_capacity;
     }
 
+    T swap_remove(size_t index) {
+        if (length - 1 == index) return pop();
+
+        assert(index != SIZE_MAX);
+        assert(index < length);
+
+        T old_item = items[index];
+        items[index] = pop();
+        return old_item;
+    }
+
     T *items;
     size_t length;
     size_t capacity;