authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-16 17:11:35-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-16 17:11:35-07:00
loge4cb28dbf2d0bc70581502d751ba9e4f7a46ed93
tree632db4aa17921b6fbb256b2c5d9bf0c5735a02c5
parent4d45d14b557365bfb5b9059347ec144784d481b7

structs have debug information


5 files changed, 142 insertions(+), 33 deletions(-)

src/analyze.cpp+71-31
...@@ -114,6 +114,7 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool...@@ -114,6 +114,7 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool
114 buf_appendf(&entry->name, "&%s%s", is_const ? "const " : "", buf_ptr(&child_type->name));114 buf_appendf(&entry->name, "&%s%s", is_const ? "const " : "", buf_ptr(&child_type->name));
115 entry->size_in_bits = g->pointer_size_bytes * 8;115 entry->size_in_bits = g->pointer_size_bytes * 8;
116 entry->align_in_bits = g->pointer_size_bytes * 8;116 entry->align_in_bits = g->pointer_size_bytes * 8;
117 assert(child_type->di_type);
117 entry->di_type = LLVMZigCreateDebugPointerType(g->dbuilder, child_type->di_type,118 entry->di_type = LLVMZigCreateDebugPointerType(g->dbuilder, child_type->di_type,
118 entry->size_in_bits, entry->align_in_bits, buf_ptr(&entry->name));119 entry->size_in_bits, entry->align_in_bits, buf_ptr(&entry->name));
119 entry->data.pointer.child_type = child_type;120 entry->data.pointer.child_type = child_type;
...@@ -269,6 +270,70 @@ static void preview_function_labels(CodeGen *g, AstNode *node, FnTableEntry *fn_...@@ -269,6 +270,70 @@ static void preview_function_labels(CodeGen *g, AstNode *node, FnTableEntry *fn_
269 }270 }
270}271}
271272
273static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type) {
274 assert(struct_type->id == TypeTableEntryIdStruct);
275
276 AstNode *decl_node = struct_type->data.structure.decl_node;
277
278 assert(struct_type->di_type);
279 assert(!struct_type->data.structure.fields);
280
281 int field_count = decl_node->data.struct_decl.fields.length;
282 struct_type->data.structure.field_count = field_count;
283 struct_type->data.structure.fields = allocate<TypeStructField>(field_count);
284
285 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);
286 LLVMZigDIType **di_element_types = allocate<LLVMZigDIType*>(field_count);
287
288 uint64_t total_size_in_bits = 0;
289 uint64_t first_field_align_in_bits = 0;
290 uint64_t offset_in_bits = 0;
291
292 for (int i = 0; i < field_count; i += 1) {
293 AstNode *field_node = decl_node->data.struct_decl.fields.at(i);
294 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
295 type_struct_field->name = &field_node->data.struct_field.name;
296 type_struct_field->type_entry = resolve_type(g, field_node->data.struct_field.type);
297
298 if (type_struct_field->type_entry->id == TypeTableEntryIdStruct) {
299 resolve_struct_type(g, import, type_struct_field->type_entry);
300 }
301
302 di_element_types[i] = LLVMZigCreateDebugMemberType(g->dbuilder,
303 LLVMZigTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name),
304 import->di_file, field_node->line + 1,
305 type_struct_field->type_entry->size_in_bits,
306 type_struct_field->type_entry->align_in_bits,
307 offset_in_bits, 0, type_struct_field->type_entry->di_type);
308
309 element_types[i] = type_struct_field->type_entry->type_ref;
310 assert(di_element_types[i]);
311 assert(element_types[i]);
312
313 total_size_in_bits += type_struct_field->type_entry->size_in_bits;
314 if (first_field_align_in_bits == 0) {
315 first_field_align_in_bits = type_struct_field->type_entry->align_in_bits;
316 }
317 offset_in_bits += type_struct_field->type_entry->size_in_bits;
318
319 }
320
321 LLVMStructSetBody(struct_type->type_ref, element_types, field_count, false);
322
323 struct_type->align_in_bits = first_field_align_in_bits;
324 struct_type->size_in_bits = total_size_in_bits;
325
326 LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder,
327 LLVMZigFileToScope(import->di_file),
328 buf_ptr(&decl_node->data.struct_decl.name),
329 import->di_file, decl_node->line + 1, struct_type->size_in_bits, struct_type->align_in_bits, 0,
330 nullptr, di_element_types, field_count, 0, nullptr, "");
331
332 LLVMZigReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type);
333 struct_type->di_type = replacement_di_type;
334}
335
336
272static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, AstNode *node) {337static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, AstNode *node) {
273 switch (node->type) {338 switch (node->type) {
274 case NodeTypeExternBlock:339 case NodeTypeExternBlock:
...@@ -414,37 +479,7 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import,...@@ -414,37 +479,7 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import,
414 StructDeclNode *struct_codegen = &node->codegen_node->data.struct_decl_node;479 StructDeclNode *struct_codegen = &node->codegen_node->data.struct_decl_node;
415 TypeTableEntry *type_entry = struct_codegen->type_entry;480 TypeTableEntry *type_entry = struct_codegen->type_entry;
416481
417 int field_count = node->data.struct_decl.fields.length;;482 resolve_struct_type(g, import, type_entry);
418 type_entry->data.structure.field_count = field_count;
419 type_entry->data.structure.fields = allocate<TypeStructField>(field_count);
420
421 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);
422 LLVMZigDIType **di_element_types = allocate<LLVMZigDIType*>(field_count);
423
424 uint64_t total_size_in_bits = 0;
425
426 for (int i = 0; i < field_count; i += 1) {
427 AstNode *field_node = node->data.struct_decl.fields.at(i);
428 TypeStructField *type_struct_field = &type_entry->data.structure.fields[i];
429 type_struct_field->name = &field_node->data.struct_field.name;
430 type_struct_field->type_entry = resolve_type(g, field_node->data.struct_field.type);
431
432 total_size_in_bits = type_struct_field->type_entry->size_in_bits;
433 di_element_types[i] = type_struct_field->type_entry->di_type;
434
435 element_types[i] = type_struct_field->type_entry->type_ref;
436 }
437 LLVMStructSetBody(type_entry->type_ref, element_types, field_count, false);
438
439 // TODO re-evaluate this align in bits and size in bits
440 type_entry->align_in_bits = 0;
441 type_entry->size_in_bits = total_size_in_bits;
442 type_entry->di_type = LLVMZigCreateDebugStructType(g->dbuilder,
443 LLVMZigFileToScope(import->di_file),
444 buf_ptr(&node->data.struct_decl.name),
445 import->di_file, node->line + 1, type_entry->size_in_bits, type_entry->align_in_bits, 0,
446 nullptr, di_element_types, field_count, 0, nullptr, "");
447
448 break;483 break;
449 }484 }
450 case NodeTypeUse:485 case NodeTypeUse:
...@@ -496,6 +531,11 @@ static void preview_types(CodeGen *g, ImportTableEntry *import, AstNode *node) {...@@ -496,6 +531,11 @@ static void preview_types(CodeGen *g, ImportTableEntry *import, AstNode *node) {
496 } else {531 } else {
497 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct);532 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct);
498 entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(name));533 entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(name));
534 entry->data.structure.decl_node = node;
535 entry->di_type = LLVMZigCreateReplaceableCompositeType(g->dbuilder,
536 LLVMZigTag_DW_structure_type(), buf_ptr(&node->data.struct_decl.name),
537 LLVMZigFileToScope(import->di_file), import->di_file, node->line + 1);
538
499 buf_init_from_buf(&entry->name, name);539 buf_init_from_buf(&entry->name, name);
500 // put off adding the debug type until we do the full struct body540 // put off adding the debug type until we do the full struct body
501 // this type is incomplete until we do another pass541 // this type is incomplete until we do another pass
src/analyze.hpp+1
...@@ -39,6 +39,7 @@ struct TypeStructField {...@@ -39,6 +39,7 @@ struct TypeStructField {
39};39};
4040
41struct TypeTableEntryStruct {41struct TypeTableEntryStruct {
42 AstNode *decl_node;
42 bool is_packed;43 bool is_packed;
43 int field_count;44 int field_count;
44 TypeStructField *fields;45 TypeStructField *fields;
src/codegen.cpp+1-2
...@@ -215,8 +215,7 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou...@@ -215,8 +215,7 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou
215215
216 /*216 /*
217 if (struct_type->id == TypeTableEntryIdPointer) {217 if (struct_type->id == TypeTableEntryIdPointer) {
218 add_debug_source_node(g, node);218 zig_panic("TODO pointer field struct access");
219 struct_ptr = LLVMBuildLoad(g->builder, struct_ptr, "");
220 }219 }
221 */220 */
222221
src/zig_llvm.cpp+54
...@@ -161,6 +161,18 @@ LLVMZigDIType *LLVMZigCreateDebugArrayType(LLVMZigDIBuilder *dibuilder, uint64_t...@@ -161,6 +161,18 @@ LLVMZigDIType *LLVMZigCreateDebugArrayType(LLVMZigDIBuilder *dibuilder, uint64_t
161 return reinterpret_cast<LLVMZigDIType*>(di_type);161 return reinterpret_cast<LLVMZigDIType*>(di_type);
162}162}
163163
164LLVMZigDIType *LLVMZigCreateDebugMemberType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,
165 const char *name, LLVMZigDIFile *file, unsigned line, uint64_t size_in_bits,
166 uint64_t align_in_bits, uint64_t offset_in_bits, unsigned flags, LLVMZigDIType *type)
167{
168 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createMemberType(
169 reinterpret_cast<DIScope*>(scope),
170 name,
171 reinterpret_cast<DIFile*>(file),
172 line, size_in_bits, align_in_bits, offset_in_bits, flags,
173 reinterpret_cast<DIType*>(type));
174 return reinterpret_cast<LLVMZigDIType*>(di_type);
175}
164176
165LLVMZigDIType *LLVMZigCreateDebugStructType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,177LLVMZigDIType *LLVMZigCreateDebugStructType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,
166 const char *name, LLVMZigDIFile *file, unsigned line_number, uint64_t size_in_bits,178 const char *name, LLVMZigDIFile *file, unsigned line_number, uint64_t size_in_bits,
...@@ -186,6 +198,39 @@ LLVMZigDIType *LLVMZigCreateDebugStructType(LLVMZigDIBuilder *dibuilder, LLVMZig...@@ -186,6 +198,39 @@ LLVMZigDIType *LLVMZigCreateDebugStructType(LLVMZigDIBuilder *dibuilder, LLVMZig
186 return reinterpret_cast<LLVMZigDIType*>(di_type);198 return reinterpret_cast<LLVMZigDIType*>(di_type);
187}199}
188200
201LLVMZigDIType *LLVMZigCreateReplaceableCompositeType(LLVMZigDIBuilder *dibuilder, unsigned tag,
202 const char *name, LLVMZigDIScope *scope, LLVMZigDIFile *file, unsigned line)
203{
204 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createReplaceableCompositeType(
205 tag, name,
206 reinterpret_cast<DIScope*>(scope),
207 reinterpret_cast<DIFile*>(file),
208 line);
209 return reinterpret_cast<LLVMZigDIType*>(di_type);
210}
211
212void LLVMZigReplaceTemporary(LLVMZigDIBuilder *dibuilder, LLVMZigDIType *type,
213 LLVMZigDIType *replacement)
214{
215 reinterpret_cast<DIBuilder*>(dibuilder)->replaceTemporary(
216 TempDIType(reinterpret_cast<DIType*>(type)),
217 reinterpret_cast<DIType*>(replacement));
218}
219
220void LLVMZigReplaceDebugArrays(LLVMZigDIBuilder *dibuilder, LLVMZigDIType *type,
221 LLVMZigDIType **types_array, int types_array_len)
222{
223 SmallVector<Metadata *, 8> fields;
224 for (int i = 0; i < types_array_len; i += 1) {
225 DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
226 fields.push_back(ditype);
227 }
228 DICompositeType *composite_type = (DICompositeType*)reinterpret_cast<DIType*>(type);
229 reinterpret_cast<DIBuilder*>(dibuilder)->replaceArrays(
230 composite_type,
231 reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields));
232}
233
189LLVMZigDISubroutineType *LLVMZigCreateSubroutineType(LLVMZigDIBuilder *dibuilder_wrapped,234LLVMZigDISubroutineType *LLVMZigCreateSubroutineType(LLVMZigDIBuilder *dibuilder_wrapped,
190 LLVMZigDIFile *file, LLVMZigDIType **types_array, int types_array_len, unsigned flags)235 LLVMZigDIFile *file, LLVMZigDIType **types_array, int types_array_len, unsigned flags)
191{236{
...@@ -226,6 +271,10 @@ unsigned LLVMZigTag_DW_arg_variable(void) {...@@ -226,6 +271,10 @@ unsigned LLVMZigTag_DW_arg_variable(void) {
226 return dwarf::DW_TAG_arg_variable;271 return dwarf::DW_TAG_arg_variable;
227}272}
228273
274unsigned LLVMZigTag_DW_structure_type(void) {
275 return dwarf::DW_TAG_structure_type;
276}
277
229LLVMZigDIBuilder *LLVMZigCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved) {278LLVMZigDIBuilder *LLVMZigCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved) {
230 DIBuilder *di_builder = new DIBuilder(*unwrap(module), allow_unresolved);279 DIBuilder *di_builder = new DIBuilder(*unwrap(module), allow_unresolved);
231 return reinterpret_cast<LLVMZigDIBuilder *>(di_builder);280 return reinterpret_cast<LLVMZigDIBuilder *>(di_builder);
...@@ -286,6 +335,11 @@ LLVMZigDIScope *LLVMZigSubprogramToScope(LLVMZigDISubprogram *subprogram) {...@@ -286,6 +335,11 @@ LLVMZigDIScope *LLVMZigSubprogramToScope(LLVMZigDISubprogram *subprogram) {
286 return reinterpret_cast<LLVMZigDIScope*>(scope);335 return reinterpret_cast<LLVMZigDIScope*>(scope);
287}336}
288337
338LLVMZigDIScope *LLVMZigTypeToScope(LLVMZigDIType *type) {
339 DIScope *scope = reinterpret_cast<DIType*>(type);
340 return reinterpret_cast<LLVMZigDIScope*>(scope);
341}
342
289LLVMZigDICompileUnit *LLVMZigCreateCompileUnit(LLVMZigDIBuilder *dibuilder,343LLVMZigDICompileUnit *LLVMZigCreateCompileUnit(LLVMZigDIBuilder *dibuilder,
290 unsigned lang, const char *file, const char *dir, const char *producer,344 unsigned lang, const char *file, const char *dir, const char *producer,
291 bool is_optimized, const char *flags, unsigned runtime_version, const char *split_name,345 bool is_optimized, const char *flags, unsigned runtime_version, const char *split_name,
src/zig_llvm.hpp+15
...@@ -55,6 +55,19 @@ LLVMZigDIType *LLVMZigCreateDebugStructType(LLVMZigDIBuilder *dibuilder, LLVMZig...@@ -55,6 +55,19 @@ LLVMZigDIType *LLVMZigCreateDebugStructType(LLVMZigDIBuilder *dibuilder, LLVMZig
55 LLVMZigDIType **types_array, int types_array_len, unsigned run_time_lang, LLVMZigDIType *vtable_holder,55 LLVMZigDIType **types_array, int types_array_len, unsigned run_time_lang, LLVMZigDIType *vtable_holder,
56 const char *unique_id);56 const char *unique_id);
5757
58LLVMZigDIType *LLVMZigCreateDebugMemberType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,
59 const char *name, LLVMZigDIFile *file, unsigned line, uint64_t size_in_bits,
60 uint64_t align_in_bits, uint64_t offset_in_bits, unsigned flags, LLVMZigDIType *type);
61
62LLVMZigDIType *LLVMZigCreateReplaceableCompositeType(LLVMZigDIBuilder *dibuilder, unsigned tag,
63 const char *name, LLVMZigDIScope *scope, LLVMZigDIFile *file, unsigned line);
64
65void LLVMZigReplaceTemporary(LLVMZigDIBuilder *dibuilder, LLVMZigDIType *type,
66 LLVMZigDIType *replacement);
67
68void LLVMZigReplaceDebugArrays(LLVMZigDIBuilder *dibuilder, LLVMZigDIType *type,
69 LLVMZigDIType **types_array, int types_array_len);
70
58LLVMZigDISubroutineType *LLVMZigCreateSubroutineType(LLVMZigDIBuilder *dibuilder_wrapped,71LLVMZigDISubroutineType *LLVMZigCreateSubroutineType(LLVMZigDIBuilder *dibuilder_wrapped,
59 LLVMZigDIFile *file, LLVMZigDIType **types_array, int types_array_len, unsigned flags);72 LLVMZigDIFile *file, LLVMZigDIType **types_array, int types_array_len, unsigned flags);
6073
...@@ -64,6 +77,7 @@ unsigned LLVMZigEncoding_DW_ATE_float(void);...@@ -64,6 +77,7 @@ unsigned LLVMZigEncoding_DW_ATE_float(void);
64unsigned LLVMZigLang_DW_LANG_C99(void);77unsigned LLVMZigLang_DW_LANG_C99(void);
65unsigned LLVMZigTag_DW_auto_variable(void);78unsigned LLVMZigTag_DW_auto_variable(void);
66unsigned LLVMZigTag_DW_arg_variable(void);79unsigned LLVMZigTag_DW_arg_variable(void);
80unsigned LLVMZigTag_DW_structure_type(void);
6781
68LLVMZigDIBuilder *LLVMZigCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved);82LLVMZigDIBuilder *LLVMZigCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved);
6983
...@@ -73,6 +87,7 @@ LLVMZigDIScope *LLVMZigLexicalBlockToScope(LLVMZigDILexicalBlock *lexical_block)...@@ -73,6 +87,7 @@ LLVMZigDIScope *LLVMZigLexicalBlockToScope(LLVMZigDILexicalBlock *lexical_block)
73LLVMZigDIScope *LLVMZigCompileUnitToScope(LLVMZigDICompileUnit *compile_unit);87LLVMZigDIScope *LLVMZigCompileUnitToScope(LLVMZigDICompileUnit *compile_unit);
74LLVMZigDIScope *LLVMZigFileToScope(LLVMZigDIFile *difile);88LLVMZigDIScope *LLVMZigFileToScope(LLVMZigDIFile *difile);
75LLVMZigDIScope *LLVMZigSubprogramToScope(LLVMZigDISubprogram *subprogram);89LLVMZigDIScope *LLVMZigSubprogramToScope(LLVMZigDISubprogram *subprogram);
90LLVMZigDIScope *LLVMZigTypeToScope(LLVMZigDIType *type);
7691
77LLVMZigDILocalVariable *LLVMZigCreateLocalVariable(LLVMZigDIBuilder *dbuilder, unsigned tag,92LLVMZigDILocalVariable *LLVMZigCreateLocalVariable(LLVMZigDIBuilder *dbuilder, unsigned tag,
78 LLVMZigDIScope *scope, const char *name, LLVMZigDIFile *file, unsigned line_no,93 LLVMZigDIScope *scope, const char *name, LLVMZigDIFile *file, unsigned line_no,