mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
structs have debug information
This commit is contained in:
parent
4d45d14b55
commit
e4cb28dbf2
5 changed files with 142 additions and 33 deletions
102
src/analyze.cpp
102
src/analyze.cpp
|
|
@ -114,6 +114,7 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool
|
|||
buf_appendf(&entry->name, "&%s%s", is_const ? "const " : "", buf_ptr(&child_type->name));
|
||||
entry->size_in_bits = g->pointer_size_bytes * 8;
|
||||
entry->align_in_bits = g->pointer_size_bytes * 8;
|
||||
assert(child_type->di_type);
|
||||
entry->di_type = LLVMZigCreateDebugPointerType(g->dbuilder, child_type->di_type,
|
||||
entry->size_in_bits, entry->align_in_bits, buf_ptr(&entry->name));
|
||||
entry->data.pointer.child_type = child_type;
|
||||
|
|
@ -269,6 +270,70 @@ static void preview_function_labels(CodeGen *g, AstNode *node, FnTableEntry *fn_
|
|||
}
|
||||
}
|
||||
|
||||
static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type) {
|
||||
assert(struct_type->id == TypeTableEntryIdStruct);
|
||||
|
||||
AstNode *decl_node = struct_type->data.structure.decl_node;
|
||||
|
||||
assert(struct_type->di_type);
|
||||
assert(!struct_type->data.structure.fields);
|
||||
|
||||
int field_count = decl_node->data.struct_decl.fields.length;
|
||||
struct_type->data.structure.field_count = field_count;
|
||||
struct_type->data.structure.fields = allocate<TypeStructField>(field_count);
|
||||
|
||||
LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);
|
||||
LLVMZigDIType **di_element_types = allocate<LLVMZigDIType*>(field_count);
|
||||
|
||||
uint64_t total_size_in_bits = 0;
|
||||
uint64_t first_field_align_in_bits = 0;
|
||||
uint64_t offset_in_bits = 0;
|
||||
|
||||
for (int i = 0; i < field_count; i += 1) {
|
||||
AstNode *field_node = decl_node->data.struct_decl.fields.at(i);
|
||||
TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
|
||||
type_struct_field->name = &field_node->data.struct_field.name;
|
||||
type_struct_field->type_entry = resolve_type(g, field_node->data.struct_field.type);
|
||||
|
||||
if (type_struct_field->type_entry->id == TypeTableEntryIdStruct) {
|
||||
resolve_struct_type(g, import, type_struct_field->type_entry);
|
||||
}
|
||||
|
||||
di_element_types[i] = LLVMZigCreateDebugMemberType(g->dbuilder,
|
||||
LLVMZigTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name),
|
||||
import->di_file, field_node->line + 1,
|
||||
type_struct_field->type_entry->size_in_bits,
|
||||
type_struct_field->type_entry->align_in_bits,
|
||||
offset_in_bits, 0, type_struct_field->type_entry->di_type);
|
||||
|
||||
element_types[i] = type_struct_field->type_entry->type_ref;
|
||||
assert(di_element_types[i]);
|
||||
assert(element_types[i]);
|
||||
|
||||
total_size_in_bits += type_struct_field->type_entry->size_in_bits;
|
||||
if (first_field_align_in_bits == 0) {
|
||||
first_field_align_in_bits = type_struct_field->type_entry->align_in_bits;
|
||||
}
|
||||
offset_in_bits += type_struct_field->type_entry->size_in_bits;
|
||||
|
||||
}
|
||||
|
||||
LLVMStructSetBody(struct_type->type_ref, element_types, field_count, false);
|
||||
|
||||
struct_type->align_in_bits = first_field_align_in_bits;
|
||||
struct_type->size_in_bits = total_size_in_bits;
|
||||
|
||||
LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder,
|
||||
LLVMZigFileToScope(import->di_file),
|
||||
buf_ptr(&decl_node->data.struct_decl.name),
|
||||
import->di_file, decl_node->line + 1, struct_type->size_in_bits, struct_type->align_in_bits, 0,
|
||||
nullptr, di_element_types, field_count, 0, nullptr, "");
|
||||
|
||||
LLVMZigReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type);
|
||||
struct_type->di_type = replacement_di_type;
|
||||
}
|
||||
|
||||
|
||||
static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, AstNode *node) {
|
||||
switch (node->type) {
|
||||
case NodeTypeExternBlock:
|
||||
|
|
@ -414,37 +479,7 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import,
|
|||
StructDeclNode *struct_codegen = &node->codegen_node->data.struct_decl_node;
|
||||
TypeTableEntry *type_entry = struct_codegen->type_entry;
|
||||
|
||||
int field_count = node->data.struct_decl.fields.length;;
|
||||
type_entry->data.structure.field_count = field_count;
|
||||
type_entry->data.structure.fields = allocate<TypeStructField>(field_count);
|
||||
|
||||
LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);
|
||||
LLVMZigDIType **di_element_types = allocate<LLVMZigDIType*>(field_count);
|
||||
|
||||
uint64_t total_size_in_bits = 0;
|
||||
|
||||
for (int i = 0; i < field_count; i += 1) {
|
||||
AstNode *field_node = node->data.struct_decl.fields.at(i);
|
||||
TypeStructField *type_struct_field = &type_entry->data.structure.fields[i];
|
||||
type_struct_field->name = &field_node->data.struct_field.name;
|
||||
type_struct_field->type_entry = resolve_type(g, field_node->data.struct_field.type);
|
||||
|
||||
total_size_in_bits = type_struct_field->type_entry->size_in_bits;
|
||||
di_element_types[i] = type_struct_field->type_entry->di_type;
|
||||
|
||||
element_types[i] = type_struct_field->type_entry->type_ref;
|
||||
}
|
||||
LLVMStructSetBody(type_entry->type_ref, element_types, field_count, false);
|
||||
|
||||
// TODO re-evaluate this align in bits and size in bits
|
||||
type_entry->align_in_bits = 0;
|
||||
type_entry->size_in_bits = total_size_in_bits;
|
||||
type_entry->di_type = LLVMZigCreateDebugStructType(g->dbuilder,
|
||||
LLVMZigFileToScope(import->di_file),
|
||||
buf_ptr(&node->data.struct_decl.name),
|
||||
import->di_file, node->line + 1, type_entry->size_in_bits, type_entry->align_in_bits, 0,
|
||||
nullptr, di_element_types, field_count, 0, nullptr, "");
|
||||
|
||||
resolve_struct_type(g, import, type_entry);
|
||||
break;
|
||||
}
|
||||
case NodeTypeUse:
|
||||
|
|
@ -496,6 +531,11 @@ static void preview_types(CodeGen *g, ImportTableEntry *import, AstNode *node) {
|
|||
} else {
|
||||
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct);
|
||||
entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(name));
|
||||
entry->data.structure.decl_node = node;
|
||||
entry->di_type = LLVMZigCreateReplaceableCompositeType(g->dbuilder,
|
||||
LLVMZigTag_DW_structure_type(), buf_ptr(&node->data.struct_decl.name),
|
||||
LLVMZigFileToScope(import->di_file), import->di_file, node->line + 1);
|
||||
|
||||
buf_init_from_buf(&entry->name, name);
|
||||
// put off adding the debug type until we do the full struct body
|
||||
// this type is incomplete until we do another pass
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ struct TypeStructField {
|
|||
};
|
||||
|
||||
struct TypeTableEntryStruct {
|
||||
AstNode *decl_node;
|
||||
bool is_packed;
|
||||
int field_count;
|
||||
TypeStructField *fields;
|
||||
|
|
|
|||
|
|
@ -215,8 +215,7 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou
|
|||
|
||||
/*
|
||||
if (struct_type->id == TypeTableEntryIdPointer) {
|
||||
add_debug_source_node(g, node);
|
||||
struct_ptr = LLVMBuildLoad(g->builder, struct_ptr, "");
|
||||
zig_panic("TODO pointer field struct access");
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -161,6 +161,18 @@ LLVMZigDIType *LLVMZigCreateDebugArrayType(LLVMZigDIBuilder *dibuilder, uint64_t
|
|||
return reinterpret_cast<LLVMZigDIType*>(di_type);
|
||||
}
|
||||
|
||||
LLVMZigDIType *LLVMZigCreateDebugMemberType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,
|
||||
const char *name, LLVMZigDIFile *file, unsigned line, uint64_t size_in_bits,
|
||||
uint64_t align_in_bits, uint64_t offset_in_bits, unsigned flags, LLVMZigDIType *type)
|
||||
{
|
||||
DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createMemberType(
|
||||
reinterpret_cast<DIScope*>(scope),
|
||||
name,
|
||||
reinterpret_cast<DIFile*>(file),
|
||||
line, size_in_bits, align_in_bits, offset_in_bits, flags,
|
||||
reinterpret_cast<DIType*>(type));
|
||||
return reinterpret_cast<LLVMZigDIType*>(di_type);
|
||||
}
|
||||
|
||||
LLVMZigDIType *LLVMZigCreateDebugStructType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,
|
||||
const char *name, LLVMZigDIFile *file, unsigned line_number, uint64_t size_in_bits,
|
||||
|
|
@ -186,6 +198,39 @@ LLVMZigDIType *LLVMZigCreateDebugStructType(LLVMZigDIBuilder *dibuilder, LLVMZig
|
|||
return reinterpret_cast<LLVMZigDIType*>(di_type);
|
||||
}
|
||||
|
||||
LLVMZigDIType *LLVMZigCreateReplaceableCompositeType(LLVMZigDIBuilder *dibuilder, unsigned tag,
|
||||
const char *name, LLVMZigDIScope *scope, LLVMZigDIFile *file, unsigned line)
|
||||
{
|
||||
DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createReplaceableCompositeType(
|
||||
tag, name,
|
||||
reinterpret_cast<DIScope*>(scope),
|
||||
reinterpret_cast<DIFile*>(file),
|
||||
line);
|
||||
return reinterpret_cast<LLVMZigDIType*>(di_type);
|
||||
}
|
||||
|
||||
void LLVMZigReplaceTemporary(LLVMZigDIBuilder *dibuilder, LLVMZigDIType *type,
|
||||
LLVMZigDIType *replacement)
|
||||
{
|
||||
reinterpret_cast<DIBuilder*>(dibuilder)->replaceTemporary(
|
||||
TempDIType(reinterpret_cast<DIType*>(type)),
|
||||
reinterpret_cast<DIType*>(replacement));
|
||||
}
|
||||
|
||||
void LLVMZigReplaceDebugArrays(LLVMZigDIBuilder *dibuilder, LLVMZigDIType *type,
|
||||
LLVMZigDIType **types_array, int types_array_len)
|
||||
{
|
||||
SmallVector<Metadata *, 8> fields;
|
||||
for (int i = 0; i < types_array_len; i += 1) {
|
||||
DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
|
||||
fields.push_back(ditype);
|
||||
}
|
||||
DICompositeType *composite_type = (DICompositeType*)reinterpret_cast<DIType*>(type);
|
||||
reinterpret_cast<DIBuilder*>(dibuilder)->replaceArrays(
|
||||
composite_type,
|
||||
reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields));
|
||||
}
|
||||
|
||||
LLVMZigDISubroutineType *LLVMZigCreateSubroutineType(LLVMZigDIBuilder *dibuilder_wrapped,
|
||||
LLVMZigDIFile *file, LLVMZigDIType **types_array, int types_array_len, unsigned flags)
|
||||
{
|
||||
|
|
@ -226,6 +271,10 @@ unsigned LLVMZigTag_DW_arg_variable(void) {
|
|||
return dwarf::DW_TAG_arg_variable;
|
||||
}
|
||||
|
||||
unsigned LLVMZigTag_DW_structure_type(void) {
|
||||
return dwarf::DW_TAG_structure_type;
|
||||
}
|
||||
|
||||
LLVMZigDIBuilder *LLVMZigCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved) {
|
||||
DIBuilder *di_builder = new DIBuilder(*unwrap(module), allow_unresolved);
|
||||
return reinterpret_cast<LLVMZigDIBuilder *>(di_builder);
|
||||
|
|
@ -286,6 +335,11 @@ LLVMZigDIScope *LLVMZigSubprogramToScope(LLVMZigDISubprogram *subprogram) {
|
|||
return reinterpret_cast<LLVMZigDIScope*>(scope);
|
||||
}
|
||||
|
||||
LLVMZigDIScope *LLVMZigTypeToScope(LLVMZigDIType *type) {
|
||||
DIScope *scope = reinterpret_cast<DIType*>(type);
|
||||
return reinterpret_cast<LLVMZigDIScope*>(scope);
|
||||
}
|
||||
|
||||
LLVMZigDICompileUnit *LLVMZigCreateCompileUnit(LLVMZigDIBuilder *dibuilder,
|
||||
unsigned lang, const char *file, const char *dir, const char *producer,
|
||||
bool is_optimized, const char *flags, unsigned runtime_version, const char *split_name,
|
||||
|
|
|
|||
|
|
@ -55,6 +55,19 @@ LLVMZigDIType *LLVMZigCreateDebugStructType(LLVMZigDIBuilder *dibuilder, LLVMZig
|
|||
LLVMZigDIType **types_array, int types_array_len, unsigned run_time_lang, LLVMZigDIType *vtable_holder,
|
||||
const char *unique_id);
|
||||
|
||||
LLVMZigDIType *LLVMZigCreateDebugMemberType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,
|
||||
const char *name, LLVMZigDIFile *file, unsigned line, uint64_t size_in_bits,
|
||||
uint64_t align_in_bits, uint64_t offset_in_bits, unsigned flags, LLVMZigDIType *type);
|
||||
|
||||
LLVMZigDIType *LLVMZigCreateReplaceableCompositeType(LLVMZigDIBuilder *dibuilder, unsigned tag,
|
||||
const char *name, LLVMZigDIScope *scope, LLVMZigDIFile *file, unsigned line);
|
||||
|
||||
void LLVMZigReplaceTemporary(LLVMZigDIBuilder *dibuilder, LLVMZigDIType *type,
|
||||
LLVMZigDIType *replacement);
|
||||
|
||||
void LLVMZigReplaceDebugArrays(LLVMZigDIBuilder *dibuilder, LLVMZigDIType *type,
|
||||
LLVMZigDIType **types_array, int types_array_len);
|
||||
|
||||
LLVMZigDISubroutineType *LLVMZigCreateSubroutineType(LLVMZigDIBuilder *dibuilder_wrapped,
|
||||
LLVMZigDIFile *file, LLVMZigDIType **types_array, int types_array_len, unsigned flags);
|
||||
|
||||
|
|
@ -64,6 +77,7 @@ unsigned LLVMZigEncoding_DW_ATE_float(void);
|
|||
unsigned LLVMZigLang_DW_LANG_C99(void);
|
||||
unsigned LLVMZigTag_DW_auto_variable(void);
|
||||
unsigned LLVMZigTag_DW_arg_variable(void);
|
||||
unsigned LLVMZigTag_DW_structure_type(void);
|
||||
|
||||
LLVMZigDIBuilder *LLVMZigCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved);
|
||||
|
||||
|
|
@ -73,6 +87,7 @@ LLVMZigDIScope *LLVMZigLexicalBlockToScope(LLVMZigDILexicalBlock *lexical_block)
|
|||
LLVMZigDIScope *LLVMZigCompileUnitToScope(LLVMZigDICompileUnit *compile_unit);
|
||||
LLVMZigDIScope *LLVMZigFileToScope(LLVMZigDIFile *difile);
|
||||
LLVMZigDIScope *LLVMZigSubprogramToScope(LLVMZigDISubprogram *subprogram);
|
||||
LLVMZigDIScope *LLVMZigTypeToScope(LLVMZigDIType *type);
|
||||
|
||||
LLVMZigDILocalVariable *LLVMZigCreateLocalVariable(LLVMZigDIBuilder *dbuilder, unsigned tag,
|
||||
LLVMZigDIScope *scope, const char *name, LLVMZigDIFile *file, unsigned line_no,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue