Pass 'field_parent_pointer'
This commit is contained in:
parent
0e1d279623
commit
b5c5f9682f
131
src/compiler.bbb
131
src/compiler.bbb
@ -1838,6 +1838,7 @@ ValueId = enum
|
|||||||
select,
|
select,
|
||||||
string_to_enum,
|
string_to_enum,
|
||||||
macro_instantiation,
|
macro_instantiation,
|
||||||
|
field_parent_pointer,
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueConstantInteger = struct
|
ValueConstantInteger = struct
|
||||||
@ -2099,6 +2100,12 @@ MacroInstantiation = struct
|
|||||||
return_block: &LLVMBasicBlock,
|
return_block: &LLVMBasicBlock,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ValueFieldParentPointer = struct
|
||||||
|
{
|
||||||
|
pointer: &Value,
|
||||||
|
name: []u8,
|
||||||
|
}
|
||||||
|
|
||||||
ValueContent = union
|
ValueContent = union
|
||||||
{
|
{
|
||||||
constant_integer: ValueConstantInteger,
|
constant_integer: ValueConstantInteger,
|
||||||
@ -2120,6 +2127,7 @@ ValueContent = union
|
|||||||
string_to_enum: ValueStringToEnum,
|
string_to_enum: ValueStringToEnum,
|
||||||
macro: &MacroDeclaration,
|
macro: &MacroDeclaration,
|
||||||
macro_instantiation: MacroInstantiation,
|
macro_instantiation: MacroInstantiation,
|
||||||
|
field_parent_pointer: ValueFieldParentPointer,
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueKind = enum
|
ValueKind = enum
|
||||||
@ -5643,7 +5651,30 @@ parse_left = fn (module: &Module, scope: &Scope, builder: ValueBuilder) &Value
|
|||||||
},
|
},
|
||||||
.field_parent_pointer =>
|
.field_parent_pointer =>
|
||||||
{
|
{
|
||||||
#trap();
|
skip_space(module);
|
||||||
|
expect_character(module, left_parenthesis);
|
||||||
|
|
||||||
|
>field_pointer = parse_value(module, scope, zero);
|
||||||
|
|
||||||
|
skip_space(module);
|
||||||
|
expect_character(module, ',');
|
||||||
|
skip_space(module);
|
||||||
|
|
||||||
|
>field_name = parse_string_literal(module);
|
||||||
|
|
||||||
|
skip_space(module);
|
||||||
|
expect_character(module, right_parenthesis);
|
||||||
|
|
||||||
|
result.& = {
|
||||||
|
.content = {
|
||||||
|
.field_parent_pointer = {
|
||||||
|
.pointer = field_pointer,
|
||||||
|
.name = field_name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.id = .field_parent_pointer,
|
||||||
|
zero,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -11829,6 +11860,53 @@ analyze_type = fn (module: &Module, value: &Value, expected_type: &Type, analysi
|
|||||||
module.current_macro_instantiation = current_macro_instantiation;
|
module.current_macro_instantiation = current_macro_instantiation;
|
||||||
module.current_function = current_function;
|
module.current_function = current_function;
|
||||||
},
|
},
|
||||||
|
.field_parent_pointer =>
|
||||||
|
{
|
||||||
|
>field_pointer = value.content.field_parent_pointer.pointer;
|
||||||
|
>field_name = value.content.field_parent_pointer.name;
|
||||||
|
|
||||||
|
if (!expected_type)
|
||||||
|
{
|
||||||
|
report_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
value_type = expected_type;
|
||||||
|
|
||||||
|
if (value_type.id != .pointer)
|
||||||
|
{
|
||||||
|
report_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
>aggregate_type = value_type.content.pointer.element_type;
|
||||||
|
|
||||||
|
>field_type: &Type = zero;
|
||||||
|
|
||||||
|
switch (aggregate_type.id)
|
||||||
|
{
|
||||||
|
.struct =>
|
||||||
|
{
|
||||||
|
>fields = aggregate_type.content.struct.fields;
|
||||||
|
|
||||||
|
for (&field: fields)
|
||||||
|
{
|
||||||
|
if (string_equal(field_name, field.name))
|
||||||
|
{
|
||||||
|
field_type = field.type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => { #trap(); },
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!field_type)
|
||||||
|
{
|
||||||
|
report_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
>pointer_to_field = get_pointer_type(module, field_type);
|
||||||
|
analyze_type(module, field_pointer, pointer_to_field, zero);
|
||||||
|
},
|
||||||
else =>
|
else =>
|
||||||
{
|
{
|
||||||
#trap();
|
#trap();
|
||||||
@ -14817,6 +14895,56 @@ emit_value = fn (module: &Module, value: &Value, type_kind: TypeKind, expect_con
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
.field_parent_pointer =>
|
||||||
|
{
|
||||||
|
>field_pointer = value.content.field_parent_pointer.pointer;
|
||||||
|
>field_name = value.content.field_parent_pointer.name;
|
||||||
|
|
||||||
|
emit_value(module, field_pointer, .memory, 0);
|
||||||
|
|
||||||
|
>llvm_field_pointer = field_pointer.llvm;
|
||||||
|
assert(llvm_field_pointer != zero);
|
||||||
|
|
||||||
|
assert(resolved_value_type.id == .pointer);
|
||||||
|
>aggregate_type = resolved_value_type.content.pointer.element_type;
|
||||||
|
|
||||||
|
switch (aggregate_type.id)
|
||||||
|
{
|
||||||
|
.struct =>
|
||||||
|
{
|
||||||
|
>fields = aggregate_type.content.struct.fields;
|
||||||
|
|
||||||
|
>result_field: &Field = zero;
|
||||||
|
|
||||||
|
for (&field: fields)
|
||||||
|
{
|
||||||
|
if (string_equal(field_name, field.name))
|
||||||
|
{
|
||||||
|
result_field = field;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(result_field != zero);
|
||||||
|
>offset = result_field.offset;
|
||||||
|
|
||||||
|
>u64_type = uint64(module);
|
||||||
|
resolve_type_in_place(module, u64_type);
|
||||||
|
|
||||||
|
>llvm_u64 = u64_type.llvm.abi;
|
||||||
|
|
||||||
|
>address_int = LLVMBuildPtrToInt(module.llvm.builder, llvm_field_pointer, llvm_u64, "");
|
||||||
|
address_int = LLVMBuildSub(module.llvm.builder, address_int, LLVMConstInt(llvm_u64, offset, 0), "");
|
||||||
|
|
||||||
|
>address_pointer = LLVMBuildIntToPtr(module.llvm.builder, address_int, resolved_value_type.llvm.abi, "");
|
||||||
|
llvm_value = address_pointer;
|
||||||
|
},
|
||||||
|
else =>
|
||||||
|
{
|
||||||
|
report_error();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
else =>
|
else =>
|
||||||
{
|
{
|
||||||
#trap();
|
#trap();
|
||||||
@ -17634,6 +17762,7 @@ names: [_][]u8 =
|
|||||||
"return_array",
|
"return_array",
|
||||||
"bool_pair",
|
"bool_pair",
|
||||||
"min_max",
|
"min_max",
|
||||||
|
"field_parent_pointer",
|
||||||
];
|
];
|
||||||
|
|
||||||
[export] main = fn [cc(c)] (argument_count: u32, argv: &&u8, envp: &&u8) s32
|
[export] main = fn [cc(c)] (argument_count: u32, argv: &&u8, envp: &&u8) s32
|
||||||
|
Loading…
x
Reference in New Issue
Block a user