LLVMValueRef gen_localdecl(compile_t* c, ast_t* ast) { ast_t* id = ast_child(ast); const char* name = ast_name(id); // If this local has already been generated, don't create another copy. This // can happen when the same ast node is generated more than once, such as // the condition block of a while expression. LLVMValueRef value = codegen_getlocal(c, name); if(value != NULL) return GEN_NOVALUE; ast_t* type = deferred_reify(c->frame->reify, ast_type(id), c->opt); reach_type_t* t = reach_type(c->reach, type); ast_free_unattached(type); compile_type_t* c_t = (compile_type_t*)t->c_type; // All alloca should happen in the entry block of a function. LLVMBasicBlockRef this_block = LLVMGetInsertBlock(c->builder); LLVMBasicBlockRef entry_block = LLVMGetEntryBasicBlock(codegen_fun(c)); LLVMValueRef inst = LLVMGetFirstInstruction(entry_block); if(inst != NULL) LLVMPositionBuilderBefore(c->builder, inst); else LLVMPositionBuilderAtEnd(c->builder, entry_block); LLVMValueRef alloc = LLVMBuildAlloca(c->builder, c_t->mem_type, name); // Store the alloca to use when we reference this local. codegen_setlocal(c, name, alloc); LLVMMetadataRef file = codegen_difile(c); LLVMMetadataRef scope = codegen_discope(c); #if PONY_LLVM >= 700 uint32_t align_bytes = LLVMABIAlignmentOfType(c->target_data, c_t->mem_type); LLVMMetadataRef info = LLVMDIBuilderCreateAutoVariable(c->di, scope, name, strlen(name), file, (unsigned)ast_line(ast), c_t->di_type, true, LLVMDIFlagZero, align_bytes * 8); #else LLVMMetadataRef info = LLVMDIBuilderCreateAutoVariable(c->di, scope, name, file, (unsigned)ast_line(ast), c_t->di_type); #endif LLVMMetadataRef expr = LLVMDIBuilderCreateExpression(c->di, NULL, 0); LLVMDIBuilderInsertDeclare(c->di, alloc, info, expr, (unsigned)ast_line(ast), (unsigned)ast_pos(ast), scope, LLVMGetInsertBlock(c->builder)); // Put the builder back where it was. LLVMPositionBuilderAtEnd(c->builder, this_block); return GEN_NOTNEEDED; }
LLVMValueRef gen_localdecl(compile_t* c, ast_t* ast) { ast_t* id = ast_child(ast); ast_t* type = ast_type(id); const char* name = ast_name(id); // If this local has already been generated, don't create another copy. This // can happen when the same ast node is generated more than once, such as // the condition block of a while expression. LLVMValueRef value = codegen_getlocal(c, name); if(value != NULL) return GEN_NOVALUE; reach_type_t* t = reach_type(c->reach, type); // All alloca should happen in the entry block of a function. LLVMBasicBlockRef this_block = LLVMGetInsertBlock(c->builder); LLVMBasicBlockRef entry_block = LLVMGetEntryBasicBlock(codegen_fun(c)); LLVMValueRef inst = LLVMGetFirstInstruction(entry_block); if(inst != NULL) LLVMPositionBuilderBefore(c->builder, inst); else LLVMPositionBuilderAtEnd(c->builder, entry_block); LLVMValueRef alloc = LLVMBuildAlloca(c->builder, t->use_type, name); // Store the alloca to use when we reference this local. codegen_setlocal(c, name, alloc); LLVMMetadataRef file = codegen_difile(c); LLVMMetadataRef scope = codegen_discope(c); LLVMMetadataRef info = LLVMDIBuilderCreateAutoVariable(c->di, scope, name, file, (unsigned)ast_line(ast), t->di_type); LLVMMetadataRef expr = LLVMDIBuilderCreateExpression(c->di, NULL, 0); LLVMDIBuilderInsertDeclare(c->di, alloc, info, expr, (unsigned)ast_line(ast), (unsigned)ast_pos(ast), scope, LLVMGetInsertBlock(c->builder)); // Put the builder back where it was. LLVMPositionBuilderAtEnd(c->builder, this_block); return GEN_NOVALUE; }