authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-26 10:03:30-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-26 10:03:30-04:00
logede0c22a6796600cfc4555e9ac2f0481c41c290a
tree6d565af62f39457688c3fa059e7a67d6b73c6cac
parentb13af0750fbe8b38a95b05ec78c8364281fcf477
signaturelock-open Commit is signed but in an unrecognized format.

make `@alignOf` lazily evaluate the target type

this case works now: ```zig const Foo = struct { field: Bar(@alignOf(*Foo)), }; fn Bar(comptime alignment: u29) type { return struct { field: *align(alignment) Foo, }; } ```

4 files changed, 60 insertions(+), 56 deletions(-)

src/all_types.hpp+3-1
...@@ -314,7 +314,9 @@ struct LazyValue {...@@ -314,7 +314,9 @@ struct LazyValue {
314314
315struct LazyValueAlignOf {315struct LazyValueAlignOf {
316 LazyValue base;316 LazyValue base;
317 ZigType *target_type;317
318 ConstExprValue *target_type_val;
319 AstNode *target_type_src_node;
318};320};
319321
320struct LazyValueSliceType {322struct LazyValueSliceType {
src/analyze.cpp+4-3
...@@ -1100,13 +1100,14 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue...@@ -1100,13 +1100,14 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue
1100 zig_unreachable();1100 zig_unreachable();
1101}1101}
11021102
1103static Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t *abi_align) {1103Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t *abi_align) {
1104 Error err;1104 Error err;
1105 if (type_val->special != ConstValSpecialLazy) {1105 if (type_val->special != ConstValSpecialLazy) {
1106 assert(type_val->special == ConstValSpecialStatic);1106 assert(type_val->special == ConstValSpecialStatic);
1107 if ((err = type_resolve(g, type_val->data.x_type, ResolveStatusAlignmentKnown)))1107 ZigType *ty = type_val->data.x_type;
1108 if ((err = type_resolve(g, ty, ResolveStatusAlignmentKnown)))
1108 return err;1109 return err;
1109 *abi_align = type_val->data.x_type->abi_align;1110 *abi_align = ty->abi_align;
1110 return ErrorNone;1111 return ErrorNone;
1111 }1112 }
1112 switch (type_val->data.x_lazy->id) {1113 switch (type_val->data.x_lazy->id) {
src/analyze.hpp+1-1
...@@ -247,6 +247,6 @@ ConstExprValue *analyze_const_value_allow_lazy(CodeGen *g, Scope *scope, AstNode...@@ -247,6 +247,6 @@ ConstExprValue *analyze_const_value_allow_lazy(CodeGen *g, Scope *scope, AstNode
247void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);247void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);
248bool fn_is_async(ZigFn *fn);248bool fn_is_async(ZigFn *fn);
249249
250Error type_val_resolve_is_opaque_type(CodeGen *g, ConstExprValue *type_val, bool *is_opaque_type);250Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, uint32_t *abi_align);
251251
252#endif252#endif
src/ir.cpp+52-51
...@@ -22325,63 +22325,24 @@ static IrInstruction *ir_analyze_instruction_frame_size(IrAnalyze *ira, IrInstru...@@ -22325,63 +22325,24 @@ static IrInstruction *ir_analyze_instruction_frame_size(IrAnalyze *ira, IrInstru
22325}22325}
2232622326
22327static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) {22327static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) {
22328 IrInstruction *type_value = instruction->type_value->child;
22329 if (type_is_invalid(type_value->value.type))
22330 return ira->codegen->invalid_instruction;
22331 ZigType *type_entry = ir_resolve_type(ira, type_value);
22332
22333 switch (type_entry->id) {
22334 case ZigTypeIdInvalid:
22335 zig_unreachable();
22336 case ZigTypeIdMetaType:
22337 case ZigTypeIdUnreachable:
22338 case ZigTypeIdComptimeFloat:
22339 case ZigTypeIdComptimeInt:
22340 case ZigTypeIdEnumLiteral:
22341 case ZigTypeIdUndefined:
22342 case ZigTypeIdNull:
22343 case ZigTypeIdBoundFn:
22344 case ZigTypeIdArgTuple:
22345 case ZigTypeIdVoid:
22346 case ZigTypeIdOpaque:
22347 ir_add_error(ira, instruction->type_value,
22348 buf_sprintf("no align available for type '%s'", buf_ptr(&type_entry->name)));
22349 return ira->codegen->invalid_instruction;
22350 case ZigTypeIdBool:
22351 case ZigTypeIdInt:
22352 case ZigTypeIdFloat:
22353 case ZigTypeIdPointer:
22354 case ZigTypeIdArray:
22355 case ZigTypeIdStruct:
22356 case ZigTypeIdOptional:
22357 case ZigTypeIdErrorUnion:
22358 case ZigTypeIdErrorSet:
22359 case ZigTypeIdEnum:
22360 case ZigTypeIdUnion:
22361 case ZigTypeIdFn:
22362 case ZigTypeIdVector:
22363 case ZigTypeIdFnFrame:
22364 case ZigTypeIdAnyFrame:
22365 break;
22366 }
22367
22368 if (type_is_resolved(type_entry, ResolveStatusAlignmentKnown)) {
22369 uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry);
22370 return ir_const_unsigned(ira, &instruction->base, align_in_bytes);
22371 }
22372
22373 // Here we create a lazy value in order to avoid resolving the alignment of the type22328 // Here we create a lazy value in order to avoid resolving the alignment of the type
22374 // immediately. This avoids false positive dependency loops such as:22329 // immediately. This avoids false positive dependency loops such as:
22375 // const Node = struct {22330 // const Node = struct {
22376 // field: []align(@alignOf(Node)) Node,22331 // field: []align(@alignOf(Node)) Node,
22377 // };22332 // };
22378 LazyValueAlignOf *lazy_align_of = allocate<LazyValueAlignOf>(1);
22379 lazy_align_of->base.id = LazyValueIdAlignOf;
22380 lazy_align_of->base.exec = ira->new_irb.exec;
22381 lazy_align_of->target_type = type_entry;
22382 IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int);22333 IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int);
22383 result->value.special = ConstValSpecialLazy;22334 result->value.special = ConstValSpecialLazy;
22335
22336 LazyValueAlignOf *lazy_align_of = allocate<LazyValueAlignOf>(1);
22384 result->value.data.x_lazy = &lazy_align_of->base;22337 result->value.data.x_lazy = &lazy_align_of->base;
22338 lazy_align_of->base.id = LazyValueIdAlignOf;
22339 lazy_align_of->base.exec = ira->new_irb.exec;
22340
22341 lazy_align_of->target_type_val = ir_resolve_type_lazy(ira, instruction->type_value->child);
22342 if (lazy_align_of->target_type_val == nullptr)
22343 return ira->codegen->invalid_instruction;
22344 lazy_align_of->target_type_src_node = instruction->type_value->source_node;
22345
22385 return result;22346 return result;
22386}22347}
2238722348
...@@ -25530,9 +25491,49 @@ static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstEx...@@ -25530,9 +25491,49 @@ static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstEx
25530 zig_unreachable();25491 zig_unreachable();
25531 case LazyValueIdAlignOf: {25492 case LazyValueIdAlignOf: {
25532 LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy);25493 LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy);
25533 if ((err = type_resolve(codegen, lazy_align_of->target_type, ResolveStatusAlignmentKnown)))25494
25495 if (lazy_align_of->target_type_val->special == ConstValSpecialStatic) {
25496 switch (lazy_align_of->target_type_val->data.x_type->id) {
25497 case ZigTypeIdInvalid:
25498 zig_unreachable();
25499 case ZigTypeIdMetaType:
25500 case ZigTypeIdUnreachable:
25501 case ZigTypeIdComptimeFloat:
25502 case ZigTypeIdComptimeInt:
25503 case ZigTypeIdEnumLiteral:
25504 case ZigTypeIdUndefined:
25505 case ZigTypeIdNull:
25506 case ZigTypeIdBoundFn:
25507 case ZigTypeIdArgTuple:
25508 case ZigTypeIdVoid:
25509 case ZigTypeIdOpaque:
25510 exec_add_error_node(codegen, exec, lazy_align_of->target_type_src_node,
25511 buf_sprintf("no align available for type '%s'",
25512 buf_ptr(&lazy_align_of->target_type_val->data.x_type->name)));
25513 return ErrorSemanticAnalyzeFail;
25514 case ZigTypeIdBool:
25515 case ZigTypeIdInt:
25516 case ZigTypeIdFloat:
25517 case ZigTypeIdPointer:
25518 case ZigTypeIdArray:
25519 case ZigTypeIdStruct:
25520 case ZigTypeIdOptional:
25521 case ZigTypeIdErrorUnion:
25522 case ZigTypeIdErrorSet:
25523 case ZigTypeIdEnum:
25524 case ZigTypeIdUnion:
25525 case ZigTypeIdFn:
25526 case ZigTypeIdVector:
25527 case ZigTypeIdFnFrame:
25528 case ZigTypeIdAnyFrame:
25529 break;
25530 }
25531 }
25532
25533 uint32_t align_in_bytes;
25534 if ((err = type_val_resolve_abi_align(codegen, lazy_align_of->target_type_val, &align_in_bytes)))
25534 return err;25535 return err;
25535 uint64_t align_in_bytes = get_abi_alignment(codegen, lazy_align_of->target_type);25536
25536 val->special = ConstValSpecialStatic;25537 val->special = ConstValSpecialStatic;
25537 assert(val->type->id == ZigTypeIdComptimeInt);25538 assert(val->type->id == ZigTypeIdComptimeInt);
25538 bigint_init_unsigned(&val->data.x_bigint, align_in_bytes);25539 bigint_init_unsigned(&val->data.x_bigint, align_in_bytes);