mirror of
https://github.com/ziglang/zig.git
synced 2026-01-21 06:45:24 +00:00
resolve enum types and emit debug info
This commit is contained in:
parent
b147ff5b60
commit
2061cd50c0
@ -705,8 +705,32 @@ struct TypeTableEntryMaybe {
|
||||
TypeTableEntry *child_type;
|
||||
};
|
||||
|
||||
struct TypeTableEntryMetaType {
|
||||
TypeTableEntry *child_type;
|
||||
};
|
||||
|
||||
struct TypeEnumField {
|
||||
Buf *name;
|
||||
TypeTableEntry *type_entry;
|
||||
};
|
||||
|
||||
struct TypeTableEntryEnum {
|
||||
AstNode *decl_node;
|
||||
int field_count;
|
||||
TypeEnumField *fields;
|
||||
bool is_invalid; // true if any fields are invalid
|
||||
|
||||
// reminder: hash tables must be initialized before use
|
||||
HashMap<Buf *, FnTableEntry *, buf_hash, buf_eql_buf> fn_table;
|
||||
|
||||
// set this flag temporarily to detect infinite loops
|
||||
bool embedded_in_current;
|
||||
bool reported_infinite_err;
|
||||
};
|
||||
|
||||
enum TypeTableEntryId {
|
||||
TypeTableEntryIdInvalid,
|
||||
TypeTableEntryIdMetaType,
|
||||
TypeTableEntryIdVoid,
|
||||
TypeTableEntryIdBool,
|
||||
TypeTableEntryIdUnreachable,
|
||||
@ -717,6 +741,7 @@ enum TypeTableEntryId {
|
||||
TypeTableEntryIdStruct,
|
||||
TypeTableEntryIdNumberLiteral,
|
||||
TypeTableEntryIdMaybe,
|
||||
TypeTableEntryIdEnum,
|
||||
};
|
||||
|
||||
struct TypeTableEntry {
|
||||
@ -736,6 +761,8 @@ struct TypeTableEntry {
|
||||
TypeTableEntryStruct structure;
|
||||
TypeTableEntryNumLit num_lit;
|
||||
TypeTableEntryMaybe maybe;
|
||||
TypeTableEntryEnum enumeration;
|
||||
TypeTableEntryMetaType meta_type;
|
||||
} data;
|
||||
|
||||
// use these fields to make sure we don't duplicate type table entries for the same type
|
||||
@ -743,7 +770,7 @@ struct TypeTableEntry {
|
||||
TypeTableEntry *unknown_size_array_parent[2][2]; // 0 - const. 1 - noalias
|
||||
HashMap<uint64_t, TypeTableEntry *, uint64_hash, uint64_eq> arrays_by_size;
|
||||
TypeTableEntry *maybe_parent;
|
||||
|
||||
TypeTableEntry *meta_parent;
|
||||
};
|
||||
|
||||
struct ImporterInfo {
|
||||
|
||||
280
src/analyze.cpp
280
src/analyze.cpp
@ -18,6 +18,7 @@ static TypeTableEntry *eval_const_expr(CodeGen *g, BlockContext *context,
|
||||
static void collect_type_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *type_node, TopLevelDecl *decl_node);
|
||||
static VariableTableEntry *analyze_variable_declaration(CodeGen *g, ImportTableEntry *import,
|
||||
BlockContext *context, TypeTableEntry *expected_type, AstNode *node);
|
||||
static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type);
|
||||
|
||||
static AstNode *first_executing_node(AstNode *node) {
|
||||
switch (node->type) {
|
||||
@ -116,8 +117,27 @@ TypeTableEntry *new_type_table_entry(TypeTableEntryId id) {
|
||||
entry->arrays_by_size.init(2);
|
||||
entry->id = id;
|
||||
|
||||
if (id == TypeTableEntryIdStruct) {
|
||||
entry->data.structure.fn_table.init(8);
|
||||
switch (id) {
|
||||
case TypeTableEntryIdInvalid:
|
||||
case TypeTableEntryIdMetaType:
|
||||
case TypeTableEntryIdVoid:
|
||||
case TypeTableEntryIdBool:
|
||||
case TypeTableEntryIdUnreachable:
|
||||
case TypeTableEntryIdInt:
|
||||
case TypeTableEntryIdFloat:
|
||||
case TypeTableEntryIdPointer:
|
||||
case TypeTableEntryIdArray:
|
||||
case TypeTableEntryIdNumberLiteral:
|
||||
case TypeTableEntryIdMaybe:
|
||||
// nothing to init
|
||||
break;
|
||||
case TypeTableEntryIdStruct:
|
||||
entry->data.structure.fn_table.init(8);
|
||||
break;
|
||||
case TypeTableEntryIdEnum:
|
||||
entry->data.enumeration.fn_table.init(8);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return entry;
|
||||
@ -139,6 +159,35 @@ static TypeTableEntry *get_number_literal_type_unsigned(CodeGen *g, uint64_t x)
|
||||
return g->num_lit_types[get_number_literal_kind_unsigned(x)];
|
||||
}
|
||||
|
||||
static TypeTableEntry *get_int_type_unsigned(CodeGen *g, uint64_t x) {
|
||||
switch (get_number_literal_kind_unsigned(x)) {
|
||||
case NumLitU8:
|
||||
return g->builtin_types.entry_u8;
|
||||
case NumLitU16:
|
||||
return g->builtin_types.entry_u16;
|
||||
case NumLitU32:
|
||||
return g->builtin_types.entry_u32;
|
||||
case NumLitU64:
|
||||
return g->builtin_types.entry_u64;
|
||||
default:
|
||||
zig_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
static TypeTableEntry *get_meta_type(CodeGen *g, TypeTableEntry *child_type) {
|
||||
if (child_type->meta_parent) {
|
||||
return child_type->maybe_parent;
|
||||
} else {
|
||||
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMetaType);
|
||||
buf_resize(&entry->name, 0);
|
||||
buf_appendf(&entry->name, "(%s declaration)", buf_ptr(&child_type->name));
|
||||
|
||||
entry->data.meta_type.child_type = child_type;
|
||||
child_type->meta_parent = entry;
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const, bool is_noalias) {
|
||||
TypeTableEntry **parent_pointer = &child_type->pointer_parent[(is_const ? 1 : 0)][(is_noalias ? 1 : 0)];
|
||||
if (*parent_pointer) {
|
||||
@ -146,8 +195,12 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool
|
||||
} else {
|
||||
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPointer);
|
||||
entry->type_ref = LLVMPointerType(child_type->type_ref, 0);
|
||||
|
||||
const char *const_str = is_const ? "const " : "";
|
||||
const char *noalias_str = is_noalias ? "noalias " : "";
|
||||
buf_resize(&entry->name, 0);
|
||||
buf_appendf(&entry->name, "&%s%s", is_const ? "const " : "", buf_ptr(&child_type->name));
|
||||
buf_appendf(&entry->name, "&%s%s%s", const_str, noalias_str, 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);
|
||||
@ -165,7 +218,6 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool
|
||||
static TypeTableEntry *get_maybe_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *child_type) {
|
||||
if (child_type->maybe_parent) {
|
||||
TypeTableEntry *entry = child_type->maybe_parent;
|
||||
import->block_context->type_table.put(&entry->name, entry);
|
||||
return entry;
|
||||
} else {
|
||||
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMaybe);
|
||||
@ -209,7 +261,6 @@ static TypeTableEntry *get_maybe_type(CodeGen *g, ImportTableEntry *import, Type
|
||||
|
||||
entry->data.maybe.child_type = child_type;
|
||||
|
||||
import->block_context->type_table.put(&entry->name, entry);
|
||||
child_type->maybe_parent = entry;
|
||||
return entry;
|
||||
}
|
||||
@ -221,7 +272,6 @@ static TypeTableEntry *get_array_type(CodeGen *g, ImportTableEntry *import,
|
||||
auto existing_entry = child_type->arrays_by_size.maybe_get(array_size);
|
||||
if (existing_entry) {
|
||||
TypeTableEntry *entry = existing_entry->value;
|
||||
import->block_context->type_table.put(&entry->name, entry);
|
||||
return entry;
|
||||
} else {
|
||||
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray);
|
||||
@ -237,7 +287,6 @@ static TypeTableEntry *get_array_type(CodeGen *g, ImportTableEntry *import,
|
||||
entry->data.array.child_type = child_type;
|
||||
entry->data.array.len = array_size;
|
||||
|
||||
import->block_context->type_table.put(&entry->name, entry);
|
||||
child_type->arrays_by_size.put(array_size, entry);
|
||||
return entry;
|
||||
}
|
||||
@ -636,7 +685,165 @@ static void preview_function_labels(CodeGen *g, AstNode *node, FnTableEntry *fn_
|
||||
}
|
||||
}
|
||||
|
||||
static void resolve_container_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type) {
|
||||
static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *enum_type) {
|
||||
assert(enum_type->id == TypeTableEntryIdEnum);
|
||||
|
||||
AstNode *decl_node = enum_type->data.enumeration.decl_node;
|
||||
|
||||
if (enum_type->data.enumeration.embedded_in_current) {
|
||||
if (!enum_type->data.enumeration.reported_infinite_err) {
|
||||
enum_type->data.enumeration.reported_infinite_err = true;
|
||||
add_node_error(g, decl_node, buf_sprintf("enum has infinite size"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (enum_type->data.enumeration.fields) {
|
||||
// we already resolved this type. skip
|
||||
return;
|
||||
}
|
||||
|
||||
assert(enum_type->di_type);
|
||||
|
||||
int field_count = decl_node->data.struct_decl.fields.length;
|
||||
|
||||
enum_type->data.enumeration.field_count = field_count;
|
||||
enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count);
|
||||
LLVMZigDIEnumerator **di_enumerators = allocate<LLVMZigDIEnumerator*>(field_count);
|
||||
|
||||
// we possibly allocate too much here since gen_field_count can be lower than field_count.
|
||||
// the only problem is potential wasted space though.
|
||||
LLVMZigDIType **union_inner_di_types = allocate<LLVMZigDIType*>(field_count);
|
||||
|
||||
TypeTableEntry *biggest_union_member = nullptr;
|
||||
uint64_t biggest_align_in_bits = 0;
|
||||
uint64_t biggest_union_member_size_in_bits = 0;
|
||||
|
||||
// set temporary flag
|
||||
enum_type->data.enumeration.embedded_in_current = true;
|
||||
|
||||
int gen_field_index = 0;
|
||||
for (int i = 0; i < field_count; i += 1) {
|
||||
AstNode *field_node = decl_node->data.struct_decl.fields.at(i);
|
||||
TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i];
|
||||
type_enum_field->name = &field_node->data.struct_field.name;
|
||||
type_enum_field->type_entry = resolve_type(g, field_node->data.struct_field.type,
|
||||
import, import->block_context, false);
|
||||
|
||||
di_enumerators[i] = LLVMZigCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i);
|
||||
|
||||
if (type_enum_field->type_entry->id == TypeTableEntryIdStruct) {
|
||||
resolve_struct_type(g, import, type_enum_field->type_entry);
|
||||
} else if (type_enum_field->type_entry->id == TypeTableEntryIdEnum) {
|
||||
resolve_enum_type(g, import, type_enum_field->type_entry);
|
||||
} else if (type_enum_field->type_entry->id == TypeTableEntryIdInvalid) {
|
||||
enum_type->data.enumeration.is_invalid = true;
|
||||
continue;
|
||||
} else if (type_enum_field->type_entry->id == TypeTableEntryIdVoid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
union_inner_di_types[gen_field_index] = LLVMZigCreateDebugMemberType(g->dbuilder,
|
||||
LLVMZigTypeToScope(enum_type->di_type), buf_ptr(type_enum_field->name),
|
||||
import->di_file, field_node->line + 1,
|
||||
type_enum_field->type_entry->size_in_bits,
|
||||
type_enum_field->type_entry->align_in_bits,
|
||||
0, 0, type_enum_field->type_entry->di_type);
|
||||
|
||||
biggest_align_in_bits = max(biggest_align_in_bits, type_enum_field->type_entry->align_in_bits);
|
||||
|
||||
if (!biggest_union_member ||
|
||||
type_enum_field->type_entry->size_in_bits > biggest_union_member->size_in_bits)
|
||||
{
|
||||
biggest_union_member = type_enum_field->type_entry;
|
||||
biggest_union_member_size_in_bits = biggest_union_member->size_in_bits;
|
||||
}
|
||||
|
||||
gen_field_index += 1;
|
||||
}
|
||||
|
||||
// unset temporary flag
|
||||
enum_type->data.enumeration.embedded_in_current = false;
|
||||
|
||||
if (!enum_type->data.enumeration.is_invalid) {
|
||||
uint64_t tag_size_in_bits = get_number_literal_type_unsigned(g, field_count)->size_in_bits;
|
||||
enum_type->align_in_bits = tag_size_in_bits;
|
||||
enum_type->size_in_bits = tag_size_in_bits + biggest_union_member_size_in_bits;
|
||||
TypeTableEntry *tag_type_entry = get_int_type_unsigned(g, field_count);
|
||||
|
||||
if (biggest_union_member) {
|
||||
// create llvm type for union
|
||||
LLVMTypeRef union_element_type = biggest_union_member->type_ref;
|
||||
LLVMTypeRef union_type_ref = LLVMStructType(&union_element_type, 1, false);
|
||||
|
||||
// create llvm type for root struct
|
||||
LLVMTypeRef root_struct_element_types[] = {
|
||||
tag_type_entry->type_ref,
|
||||
union_type_ref,
|
||||
};
|
||||
LLVMStructSetBody(enum_type->type_ref, root_struct_element_types, 2, false);
|
||||
|
||||
// create debug type for tag
|
||||
LLVMZigDIType *tag_di_type = LLVMZigCreateDebugEnumerationType(g->dbuilder,
|
||||
LLVMZigTypeToScope(enum_type->di_type), "AnonEnum", import->di_file, decl_node->line + 1,
|
||||
tag_type_entry->size_in_bits, tag_type_entry->align_in_bits, di_enumerators, field_count,
|
||||
tag_type_entry->di_type, "");
|
||||
|
||||
// create debug type for union
|
||||
LLVMZigDIType *union_di_type = LLVMZigCreateDebugUnionType(g->dbuilder,
|
||||
LLVMZigTypeToScope(enum_type->di_type), "AnonUnion", import->di_file, decl_node->line + 1,
|
||||
biggest_union_member->size_in_bits, biggest_align_in_bits, 0, union_inner_di_types,
|
||||
gen_field_index, 0, "");
|
||||
|
||||
// create debug types for members of root struct
|
||||
LLVMZigDIType *tag_member_di_type = LLVMZigCreateDebugMemberType(g->dbuilder,
|
||||
LLVMZigTypeToScope(enum_type->di_type), "tag_field",
|
||||
import->di_file, decl_node->line + 1,
|
||||
tag_type_entry->size_in_bits,
|
||||
tag_type_entry->align_in_bits,
|
||||
0, 0, tag_di_type);
|
||||
LLVMZigDIType *union_member_di_type = LLVMZigCreateDebugMemberType(g->dbuilder,
|
||||
LLVMZigTypeToScope(enum_type->di_type), "union_field",
|
||||
import->di_file, decl_node->line + 1,
|
||||
biggest_union_member->size_in_bits,
|
||||
biggest_align_in_bits,
|
||||
tag_type_entry->size_in_bits, 0, union_di_type);
|
||||
|
||||
// create debug type for root struct
|
||||
LLVMZigDIType *di_root_members[] = {
|
||||
tag_member_di_type,
|
||||
union_member_di_type,
|
||||
};
|
||||
|
||||
|
||||
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, enum_type->size_in_bits, enum_type->align_in_bits, 0,
|
||||
nullptr, di_root_members, 2, 0, nullptr, "");
|
||||
|
||||
LLVMZigReplaceTemporary(g->dbuilder, enum_type->di_type, replacement_di_type);
|
||||
enum_type->di_type = replacement_di_type;
|
||||
} else {
|
||||
// create llvm type for root struct
|
||||
enum_type->type_ref = tag_type_entry->type_ref;
|
||||
|
||||
// create debug type for tag
|
||||
LLVMZigDIType *tag_di_type = LLVMZigCreateDebugEnumerationType(g->dbuilder,
|
||||
LLVMZigFileToScope(import->di_file), buf_ptr(&decl_node->data.struct_decl.name),
|
||||
import->di_file, decl_node->line + 1,
|
||||
tag_type_entry->size_in_bits, tag_type_entry->align_in_bits, di_enumerators, field_count,
|
||||
tag_type_entry->di_type, "");
|
||||
|
||||
LLVMZigReplaceTemporary(g->dbuilder, enum_type->di_type, tag_di_type);
|
||||
enum_type->di_type = tag_di_type;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@ -672,7 +879,7 @@ static void resolve_container_type(CodeGen *g, ImportTableEntry *import, TypeTab
|
||||
uint64_t first_field_align_in_bits = 0;
|
||||
uint64_t offset_in_bits = 0;
|
||||
|
||||
// this field should be set to true only during the recursive calls to resolve_container_type
|
||||
// this field should be set to true only during the recursive calls to resolve_struct_type
|
||||
struct_type->data.structure.embedded_in_current = true;
|
||||
|
||||
int gen_field_index = 0;
|
||||
@ -686,7 +893,9 @@ static void resolve_container_type(CodeGen *g, ImportTableEntry *import, TypeTab
|
||||
type_struct_field->gen_index = -1;
|
||||
|
||||
if (type_struct_field->type_entry->id == TypeTableEntryIdStruct) {
|
||||
resolve_container_type(g, import, type_struct_field->type_entry);
|
||||
resolve_struct_type(g, import, type_struct_field->type_entry);
|
||||
} else if (type_struct_field->type_entry->id == TypeTableEntryIdEnum) {
|
||||
resolve_enum_type(g, import, type_struct_field->type_entry);
|
||||
} else if (type_struct_field->type_entry->id == TypeTableEntryIdInvalid) {
|
||||
struct_type->data.structure.is_invalid = true;
|
||||
continue;
|
||||
@ -903,9 +1112,17 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
|
||||
{
|
||||
TypeTableEntry *type_entry = node->data.struct_decl.type_entry;
|
||||
|
||||
resolve_container_type(g, import, type_entry);
|
||||
// struct/enum member fns will get resolved independently
|
||||
|
||||
switch (node->data.struct_decl.kind) {
|
||||
case ContainerKindStruct:
|
||||
resolve_struct_type(g, import, type_entry);
|
||||
break;
|
||||
case ContainerKindEnum:
|
||||
resolve_enum_type(g, import, type_entry);
|
||||
break;
|
||||
}
|
||||
|
||||
// struct member fns will get resolved independently
|
||||
break;
|
||||
}
|
||||
case NodeTypeVariableDeclaration:
|
||||
@ -986,6 +1203,8 @@ static bool num_lit_fits_in_other_type(CodeGen *g, TypeTableEntry *literal_type,
|
||||
case TypeTableEntryIdPointer:
|
||||
case TypeTableEntryIdArray:
|
||||
case TypeTableEntryIdStruct:
|
||||
case TypeTableEntryIdEnum:
|
||||
case TypeTableEntryIdMetaType:
|
||||
return false;
|
||||
case TypeTableEntryIdInt:
|
||||
if (is_num_lit_unsigned(num_lit)) {
|
||||
@ -1326,6 +1545,12 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
|
||||
buf_ptr(&struct_type->name)));
|
||||
return_type = g->builtin_types.entry_invalid;
|
||||
}
|
||||
} else if (struct_type->id == TypeTableEntryIdMetaType &&
|
||||
struct_type->data.meta_type.child_type->id == TypeTableEntryIdEnum)
|
||||
{
|
||||
//TypeTableEntry *enum_type = struct_type->data.meta_type.child_type;
|
||||
|
||||
zig_panic("TODO enum field access");
|
||||
} else {
|
||||
if (struct_type->id != TypeTableEntryIdInvalid) {
|
||||
add_node_error(g, node,
|
||||
@ -1421,7 +1646,7 @@ static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import,
|
||||
} else {
|
||||
TypeTableEntry *container_type = find_container(context, variable_name);
|
||||
if (container_type) {
|
||||
return container_type;
|
||||
return get_meta_type(g, container_type);
|
||||
} else {
|
||||
add_node_error(g, node,
|
||||
buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));
|
||||
@ -2179,6 +2404,10 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import
|
||||
fn_table = &struct_type->data.pointer.child_type->data.structure.fn_table;
|
||||
} else if (struct_type->id == TypeTableEntryIdInvalid) {
|
||||
return struct_type;
|
||||
} else if (struct_type->id == TypeTableEntryIdMetaType &&
|
||||
struct_type->data.meta_type.child_type->id == TypeTableEntryIdEnum)
|
||||
{
|
||||
zig_panic("TODO enum initialization");
|
||||
} else {
|
||||
add_node_error(g, fn_ref_expr->data.field_access_expr.struct_expr,
|
||||
buf_sprintf("member reference base type not struct or enum"));
|
||||
@ -2846,6 +3075,16 @@ static void collect_type_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode
|
||||
}
|
||||
}
|
||||
|
||||
static TypeTableEntryId container_to_type(ContainerKind kind) {
|
||||
switch (kind) {
|
||||
case ContainerKindStruct:
|
||||
return TypeTableEntryIdStruct;
|
||||
case ContainerKindEnum:
|
||||
return TypeTableEntryIdEnum;
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *node) {
|
||||
switch (node->type) {
|
||||
case NodeTypeStructDecl:
|
||||
@ -2860,11 +3099,20 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
|
||||
add_node_error(g, node,
|
||||
buf_sprintf("redefinition of '%s'", buf_ptr(name)));
|
||||
} else {
|
||||
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct);
|
||||
TypeTableEntryId type_id = container_to_type(node->data.struct_decl.kind);
|
||||
TypeTableEntry *entry = new_type_table_entry(type_id);
|
||||
switch (node->data.struct_decl.kind) {
|
||||
case ContainerKindStruct:
|
||||
entry->data.structure.decl_node = node;
|
||||
break;
|
||||
case ContainerKindEnum:
|
||||
entry->data.enumeration.decl_node = node;
|
||||
break;
|
||||
}
|
||||
|
||||
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),
|
||||
LLVMZigTag_DW_structure_type(), buf_ptr(name),
|
||||
LLVMZigFileToScope(import->di_file), import->di_file, node->line + 1);
|
||||
|
||||
buf_init_from_buf(&entry->name, name);
|
||||
|
||||
@ -161,6 +161,32 @@ LLVMZigDIType *LLVMZigCreateDebugArrayType(LLVMZigDIBuilder *dibuilder, uint64_t
|
||||
return reinterpret_cast<LLVMZigDIType*>(di_type);
|
||||
}
|
||||
|
||||
LLVMZigDIEnumerator *LLVMZigCreateDebugEnumerator(LLVMZigDIBuilder *dibuilder, const char *name, int64_t val) {
|
||||
DIEnumerator *di_enumerator = reinterpret_cast<DIBuilder*>(dibuilder)->createEnumerator(name, val);
|
||||
return reinterpret_cast<LLVMZigDIEnumerator*>(di_enumerator);
|
||||
}
|
||||
|
||||
LLVMZigDIType *LLVMZigCreateDebugEnumerationType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,
|
||||
const char *name, LLVMZigDIFile *file, unsigned line_number, uint64_t size_in_bits,
|
||||
uint64_t align_in_bits, LLVMZigDIEnumerator **enumerator_array, int enumerator_array_len,
|
||||
LLVMZigDIType *underlying_type, const char *unique_id)
|
||||
{
|
||||
SmallVector<Metadata *, 8> fields;
|
||||
for (int i = 0; i < enumerator_array_len; i += 1) {
|
||||
DIEnumerator *dienumerator = reinterpret_cast<DIEnumerator*>(enumerator_array[i]);
|
||||
fields.push_back(dienumerator);
|
||||
}
|
||||
DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createEnumerationType(
|
||||
reinterpret_cast<DIScope*>(scope),
|
||||
name,
|
||||
reinterpret_cast<DIFile*>(file),
|
||||
line_number, size_in_bits, align_in_bits,
|
||||
reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields),
|
||||
reinterpret_cast<DIType*>(underlying_type),
|
||||
unique_id);
|
||||
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)
|
||||
@ -174,6 +200,26 @@ LLVMZigDIType *LLVMZigCreateDebugMemberType(LLVMZigDIBuilder *dibuilder, LLVMZig
|
||||
return reinterpret_cast<LLVMZigDIType*>(di_type);
|
||||
}
|
||||
|
||||
LLVMZigDIType *LLVMZigCreateDebugUnionType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,
|
||||
const char *name, LLVMZigDIFile *file, unsigned line_number, uint64_t size_in_bits,
|
||||
uint64_t align_in_bits, unsigned flags, LLVMZigDIType **types_array, int types_array_len,
|
||||
unsigned run_time_lang, const char *unique_id)
|
||||
{
|
||||
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);
|
||||
}
|
||||
DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createUnionType(
|
||||
reinterpret_cast<DIScope*>(scope),
|
||||
name,
|
||||
reinterpret_cast<DIFile*>(file),
|
||||
line_number, size_in_bits, align_in_bits, flags,
|
||||
reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields),
|
||||
run_time_lang, unique_id);
|
||||
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,
|
||||
uint64_t align_in_bits, unsigned flags, LLVMZigDIType *derived_from,
|
||||
|
||||
@ -24,6 +24,7 @@ struct LLVMZigDISubprogram;
|
||||
struct LLVMZigDISubroutineType;
|
||||
struct LLVMZigDILocalVariable;
|
||||
struct LLVMZigDILocation;
|
||||
struct LLVMZigDIEnumerator;
|
||||
struct LLVMZigInsertionPoint;
|
||||
|
||||
void LLVMZigInitializeLoopStrengthReducePass(LLVMPassRegistryRef R);
|
||||
@ -49,12 +50,24 @@ LLVMZigDIType *LLVMZigCreateDebugArrayType(LLVMZigDIBuilder *dibuilder,
|
||||
uint64_t size_in_bits, uint64_t align_in_bits, LLVMZigDIType *elem_type,
|
||||
int elem_count);
|
||||
|
||||
LLVMZigDIEnumerator *LLVMZigCreateDebugEnumerator(LLVMZigDIBuilder *dibuilder, const char *name, int64_t val);
|
||||
|
||||
LLVMZigDIType *LLVMZigCreateDebugEnumerationType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,
|
||||
const char *name, LLVMZigDIFile *file, unsigned line_number, uint64_t size_in_bits,
|
||||
uint64_t align_in_bits, LLVMZigDIEnumerator **enumerator_array, int enumerator_array_len,
|
||||
LLVMZigDIType *underlying_type, const char *unique_id);
|
||||
|
||||
LLVMZigDIType *LLVMZigCreateDebugStructType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,
|
||||
const char *name, LLVMZigDIFile *file, unsigned line_number, uint64_t size_in_bits,
|
||||
uint64_t align_in_bits, unsigned flags, LLVMZigDIType *derived_from,
|
||||
LLVMZigDIType **types_array, int types_array_len, unsigned run_time_lang, LLVMZigDIType *vtable_holder,
|
||||
const char *unique_id);
|
||||
|
||||
LLVMZigDIType *LLVMZigCreateDebugUnionType(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope,
|
||||
const char *name, LLVMZigDIFile *file, unsigned line_number, uint64_t size_in_bits,
|
||||
uint64_t align_in_bits, unsigned flags, LLVMZigDIType **types_array, int types_array_len,
|
||||
unsigned run_time_lang, 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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user