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