| ... | @@ -2479,37 +2479,40 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa | ... | @@ -2479,37 +2479,40 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa |
| 2479 | value, variable->type, expr_type); | 2479 | value, variable->type, expr_type); |
| 2480 | } else { | 2480 | } else { |
| 2481 | bool ignore_uninit = false; | 2481 | bool ignore_uninit = false; |
| 2482 | TypeTableEntry *var_type = get_type_for_type_node(var_decl->type); | 2482 | // handle runtime stack allocation |
| 2483 | if (var_type->id == TypeTableEntryIdStruct && | 2483 | if (var_decl->type) { |
| 2484 | var_type->data.structure.is_unknown_size_array) | 2484 | TypeTableEntry *var_type = get_type_for_type_node(var_decl->type); |
| 2485 | { | 2485 | if (var_type->id == TypeTableEntryIdStruct && |
| 2486 | assert(var_decl->type->type == NodeTypeArrayType); | 2486 | var_type->data.structure.is_unknown_size_array) |
| 2487 | AstNode *size_node = var_decl->type->data.array_type.size; | 2487 | { |
| 2488 | if (size_node) { | 2488 | assert(var_decl->type->type == NodeTypeArrayType); |
| 2489 | ConstExprValue *const_val = &get_resolved_expr(size_node)->const_val; | 2489 | AstNode *size_node = var_decl->type->data.array_type.size; |
| 2490 | if (!const_val->ok) { | 2490 | if (size_node) { |
| 2491 | TypeTableEntry *ptr_type = var_type->data.structure.fields[0].type_entry; | 2491 | ConstExprValue *const_val = &get_resolved_expr(size_node)->const_val; |
| 2492 | assert(ptr_type->id == TypeTableEntryIdPointer); | 2492 | if (!const_val->ok) { |
| 2493 | TypeTableEntry *child_type = ptr_type->data.pointer.child_type; | 2493 | TypeTableEntry *ptr_type = var_type->data.structure.fields[0].type_entry; |
| 2494 | | 2494 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 2495 | LLVMValueRef size_val = gen_expr(g, size_node); | 2495 | TypeTableEntry *child_type = ptr_type->data.pointer.child_type; |
| 2496 | | 2496 | |
| 2497 | add_debug_source_node(g, source_node); | 2497 | LLVMValueRef size_val = gen_expr(g, size_node); |
| 2498 | LLVMValueRef ptr_val = LLVMBuildArrayAlloca(g->builder, child_type->type_ref, | 2498 | |
| 2499 | size_val, ""); | 2499 | add_debug_source_node(g, source_node); |
| 2500 | | 2500 | LLVMValueRef ptr_val = LLVMBuildArrayAlloca(g->builder, child_type->type_ref, |
| 2501 | // store the freshly allocated pointer in the unknown size array struct | 2501 | size_val, ""); |
| 2502 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, | 2502 | |
| 2503 | variable->value_ref, 0, ""); | 2503 | // store the freshly allocated pointer in the unknown size array struct |
| 2504 | LLVMBuildStore(g->builder, ptr_val, ptr_field_ptr); | 2504 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, |
| 2505 | | 2505 | variable->value_ref, 0, ""); |
| 2506 | // store the size in the len field | 2506 | LLVMBuildStore(g->builder, ptr_val, ptr_field_ptr); |
| 2507 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, | 2507 | |
| 2508 | variable->value_ref, 1, ""); | 2508 | // store the size in the len field |
| 2509 | LLVMBuildStore(g->builder, size_val, len_field_ptr); | 2509 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, |
| 2510 | | 2510 | variable->value_ref, 1, ""); |
| 2511 | // don't clobber what we just did with debug initialization | 2511 | LLVMBuildStore(g->builder, size_val, len_field_ptr); |
| 2512 | ignore_uninit = true; | 2512 | |
| | 2513 | // don't clobber what we just did with debug initialization |
| | 2514 | ignore_uninit = true; |
| | 2515 | } |
| 2513 | } | 2516 | } |
| 2514 | } | 2517 | } |
| 2515 | } | 2518 | } |