LLVMValueRef gen_localdecl(compile_t* c, ast_t* ast) { ast_t* id = ast_child(ast); ast_t* type = ast_type(id); gentype_t g; if(!gentype(c, type, &g)) return NULL; // 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); const char* name = ast_name(id); LLVMValueRef l_value = LLVMBuildAlloca(c->builder, g.use_type, name); // Store the alloca to use when we reference this local. codegen_setlocal(c, name, l_value); // Emit debug info for local variable declaration. dwarf_local(&c->dwarf, ast, g.type_name, entry_block, inst, l_value); // Put the builder back where it was. LLVMPositionBuilderAtEnd(c->builder, this_block); return GEN_NOVALUE; }
static void name_param(compile_t* c, reachable_type_t* t, reachable_method_t* m, LLVMValueRef func, const char* name, unsigned index, size_t line, size_t pos) { LLVMValueRef value = LLVMGetParam(func, index); LLVMSetValueName(value, name); LLVMValueRef alloc = LLVMBuildAlloca(c->builder, t->use_type, name); LLVMBuildStore(c->builder, value, alloc); codegen_setlocal(c, name, alloc); LLVMMetadataRef info; if(index == 0) { info = LLVMDIBuilderCreateArtificialVariable(c->di, m->di_method, name, index + 1, m->di_file, (unsigned)ast_line(m->r_fun), t->di_type); } else { info = LLVMDIBuilderCreateParameterVariable(c->di, m->di_method, name, index + 1, m->di_file, (unsigned)ast_line(m->r_fun), t->di_type); } LLVMMetadataRef expr = LLVMDIBuilderCreateExpression(c->di, NULL, 0); LLVMDIBuilderInsertDeclare(c->di, alloc, info, expr, (unsigned)line, (unsigned)pos, m->di_method, LLVMGetInsertBlock(c->builder)); }
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; }
static void name_param(compile_t* c, LLVMValueRef func, const char* name, ast_t* type, int index) { gentype_t g; gentype(c, type, &g); LLVMValueRef param = LLVMGetParam(func, index); LLVMSetValueName(param, name); LLVMValueRef value = LLVMBuildAlloca(c->builder, g.use_type, name); LLVMBuildStore(c->builder, param, value); codegen_setlocal(c, name, value); }
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; }