Mercurial > projects > ldc
view gen/todebug.cpp @ 945:03d7c4aac654
SWITCHED TO LLVM 2.5 !
Applied patch from ticket #129 to compile against latest LLVM. Thanks Frits van Bommel.
Fixed implicit return by asm block at the end of a function on x86-32. Other architectures will produce an error at the moment. Adding support for new targets is fairly simple.
Fixed return calling convention for complex numbers, ST and ST(1) were switched around.
Added some testcases.
I've run a dstress test and there are no regressions. However, the runtime does not seem to compile with symbolic debug information. -O3 -release -inline works well and is what I used for the dstress run. Tango does not compile, a small workaround is needed in tango.io.digest.Digest.Digest.hexDigest. See ticket #206 .
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Sun, 08 Feb 2009 05:26:54 +0100 |
parents | 01d9ece9982a |
children | 1714836f2c0b |
line wrap: on
line source
#include "gen/llvm.h" #include "llvm/Support/Dwarf.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/System/Path.h" #include "declaration.h" #include "module.h" #include "mars.h" #include "gen/todebug.h" #include "gen/irstate.h" #include "gen/tollvm.h" #include "gen/logger.h" #include "ir/irmodule.h" using namespace llvm::dwarf; #define DBG_NULL ( LLConstant::getNullValue(DBG_TYPE) ) #define DBG_TYPE ( getPtrToType(llvm::StructType::get(NULL,NULL)) ) #define DBG_CAST(X) ( llvm::ConstantExpr::getBitCast(X, DBG_TYPE) ) #define DBG_TAG(X) ( llvm::ConstantExpr::getAdd( DtoConstUint( X ), DtoConstUint( llvm::LLVMDebugVersion ) ) ) ////////////////////////////////////////////////////////////////////////////////////////////////// /** * Emits a global variable, LLVM Dwarf style. * @param type Type of variable. * @param values Initializers. * @param name Name. * @return The global variable. */ static LLGlobalVariable* emitDwarfGlobal(const LLStructType* type, const std::vector<LLConstant*> values, const char* name, bool linkonce=false) { LLConstant* c = llvm::ConstantStruct::get(type, values); LLGlobalValue::LinkageTypes linkage = linkonce ? LLGlobalValue::LinkOnceLinkage : LLGlobalValue::InternalLinkage; LLGlobalVariable* gv = new LLGlobalVariable(type, true, linkage, c, name, gIR->module); gv->setSection("llvm.metadata"); return gv; } /** * Emits a global variable, LLVM Dwarf style, only declares. * @param type Type of variable. * @param name Name. * @return The global variable. */ static LLGlobalVariable* emitDwarfGlobalDecl(const LLStructType* type, const char* name, bool linkonce=false) { LLGlobalValue::LinkageTypes linkage = linkonce ? LLGlobalValue::LinkOnceLinkage : LLGlobalValue::InternalLinkage; LLGlobalVariable* gv = new LLGlobalVariable(type, true, linkage, NULL, name, gIR->module); gv->setSection("llvm.metadata"); return gv; } ////////////////////////////////////////////////////////////////////////////////////////////////// /** * Emits the Dwarf anchors that are used repeatedly by LLVM debug info. */ static void emitDwarfAnchors() { const llvm::StructType* anchorTy = isaStruct(gIR->module->getTypeByName("llvm.dbg.anchor.type")); std::vector<LLConstant*> vals(2); vals[0] = DtoConstUint(llvm::LLVMDebugVersion); vals[1] = DtoConstUint(DW_TAG_compile_unit); gIR->dwarfCUs = emitDwarfGlobal(anchorTy, vals, "llvm.dbg.compile_units", true); vals[0] = DtoConstUint(llvm::LLVMDebugVersion); vals[1] = DtoConstUint(DW_TAG_variable); gIR->dwarfGVs = emitDwarfGlobal(anchorTy, vals, "llvm.dbg.global_variables", true); vals[0] = DtoConstUint(llvm::LLVMDebugVersion); vals[1] = DtoConstUint(DW_TAG_subprogram); gIR->dwarfSPs = emitDwarfGlobal(anchorTy, vals, "llvm.dbg.subprograms", true); } ////////////////////////////////////////////////////////////////////////////////////////////////// static LLConstant* getDwarfAnchor(dwarf_constants c) { if (!gIR->dwarfCUs) emitDwarfAnchors(); switch (c) { case DW_TAG_compile_unit: return gIR->dwarfCUs; case DW_TAG_variable: return gIR->dwarfGVs; case DW_TAG_subprogram: return gIR->dwarfSPs; default: assert(0); } } ////////////////////////////////////////////////////////////////////////////////////////////////// static const llvm::StructType* getDwarfCompileUnitType() { return isaStruct(gIR->module->getTypeByName("llvm.dbg.compile_unit.type")); } static const llvm::StructType* getDwarfSubProgramType() { return isaStruct(gIR->module->getTypeByName("llvm.dbg.subprogram.type")); } static const llvm::StructType* getDwarfVariableType() { return isaStruct(gIR->module->getTypeByName("llvm.dbg.variable.type")); } static const llvm::StructType* getDwarfDerivedTypeType() { return isaStruct(gIR->module->getTypeByName("llvm.dbg.derivedtype.type")); } static const llvm::StructType* getDwarfBasicTypeType() { return isaStruct(gIR->module->getTypeByName("llvm.dbg.basictype.type")); } static const llvm::StructType* getDwarfCompositeTypeType() { return isaStruct(gIR->module->getTypeByName("llvm.dbg.compositetype.type")); } static const llvm::StructType* getDwarfGlobalVariableType() { return isaStruct(gIR->module->getTypeByName("llvm.dbg.global_variable.type")); } ////////////////////////////////////////////////////////////////////////////////////////////////// static LLGlobalVariable* dwarfCompileUnit(Module* m) { std::vector<LLConstant*> vals(6); vals[0] = DBG_TAG(DW_TAG_compile_unit); vals[1] = DBG_CAST(getDwarfAnchor(DW_TAG_compile_unit)); if (global.params.symdebug == 2) vals[2] = DtoConstUint(DW_LANG_C); else vals[2] = DtoConstUint(DW_LANG_D); vals[3] = DtoConstStringPtr(FileName::name(m->srcfile->name->toChars()), "llvm.metadata"); std::string srcpath(FileName::path(m->srcfile->name->toChars())); if (!FileName::absolute(srcpath.c_str())) { llvm::sys::Path tmp = llvm::sys::Path::GetCurrentDirectory(); tmp.appendComponent(srcpath); srcpath = tmp.toString(); if (!srcpath.empty() && *srcpath.rbegin() != '/' && *srcpath.rbegin() != '\\') srcpath = srcpath + '/'; } vals[4] = DtoConstStringPtr(srcpath.c_str(), "llvm.metadata"); vals[5] = DtoConstStringPtr("LDC (http://www.dsource.org/projects/ldc)", "llvm.metadata"); LLGlobalVariable* gv = emitDwarfGlobal(getDwarfCompileUnitType(), vals, "llvm.dbg.compile_unit"); m->ir.irModule->dwarfCompileUnit = gv; return gv; } ////////////////////////////////////////////////////////////////////////////////////////////////// static LLGlobalVariable* dwarfSubProgram(llvm::GlobalVariable* emitUnit, llvm::GlobalVariable* defineUnit, const char* prettyname, const char* mangledname, unsigned int linenum, bool isprivate) { std::vector<LLConstant*> vals(11); vals[0] = DBG_TAG(DW_TAG_subprogram); vals[1] = DBG_CAST(getDwarfAnchor(DW_TAG_subprogram)); vals[2] = DBG_CAST(emitUnit); vals[3] = DtoConstStringPtr(prettyname, "llvm.metadata"); vals[4] = vals[3]; vals[5] = DtoConstStringPtr(mangledname, "llvm.metadata"); vals[6] = DBG_CAST(defineUnit); vals[7] = DtoConstUint(linenum); vals[8] = DBG_NULL; vals[9] = DtoConstBool(isprivate); vals[10] = DtoConstBool(emitUnit == defineUnit); Logger::println("emitting subprogram global"); return emitDwarfGlobal(getDwarfSubProgramType(), vals, "llvm.dbg.subprogram"); } /* static LLGlobalVariable* dwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariable* compileUnit) { std::vector<LLConstant*> vals(11); vals[0] = DBG_TAG(DW_TAG_subprogram); vals[1] = DBG_CAST(getDwarfAnchor(DW_TAG_subprogram)); vals[2] = DBG_CAST(compileUnit); vals[3] = DtoConstStringPtr(fd->toPrettyChars(), "llvm.metadata"); vals[4] = vals[3]; vals[5] = DtoConstStringPtr(fd->mangle(), "llvm.metadata"); vals[6] = DBG_CAST( DtoDwarfCompileUnit(fd->getModule()) ); vals[7] = DtoConstUint(fd->loc.linnum); vals[8] = DBG_NULL; vals[9] = DtoConstBool(fd->protection == PROTprivate); vals[10] = DtoConstBool(fd->getModule() == gIR->dmodule); Logger::println("emitting subprogram global"); return emitDwarfGlobal(getDwarfSubProgramType(), vals, "llvm.dbg.subprogram"); }*/ ////////////////////////////////////////////////////////////////////////////////////////////////// static LLGlobalVariable* dwarfTypeDescription_impl(Type* type, LLGlobalVariable* cu, const char* c_name); static LLGlobalVariable* dwarfTypeDescription(Type* type, LLGlobalVariable* cu, const char* c_name); ////////////////////////////////////////////////////////////////////////////////////////////////// static LLGlobalVariable* dwarfBasicType(Type* type, llvm::GlobalVariable* compileUnit) { Type* t = type->toBasetype(); const LLType* T = DtoType(type); std::vector<LLConstant*> vals(10); // tag vals[0] = DBG_TAG(DW_TAG_base_type); // context vals[1] = DBG_CAST(compileUnit); // name vals[2] = DtoConstStringPtr(type->toChars(), "llvm.metadata"); // compile unit where defined vals[3] = DBG_NULL; // line number where defined vals[4] = DtoConstInt(0); // size in bits vals[5] = LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false); // alignment in bits vals[6] = LLConstantInt::get(LLType::Int64Ty, getABITypeAlign(T)*8, false); // offset in bits vals[7] = LLConstantInt::get(LLType::Int64Ty, 0, false); // FIXME: dont know what this is vals[8] = DtoConstUint(0); // dwarf type unsigned id; if (t->isintegral()) { if (type->isunsigned()) id = DW_ATE_unsigned; else id = DW_ATE_signed; } else if (t->isfloating()) { id = DW_ATE_float; } else { assert(0 && "unsupported basictype for debug info"); } vals[9] = DtoConstUint(id); return emitDwarfGlobal(getDwarfBasicTypeType(), vals, "llvm.dbg.basictype"); } ////////////////////////////////////////////////////////////////////////////////////////////////// static LLGlobalVariable* dwarfDerivedType(Type* type, llvm::GlobalVariable* compileUnit) { const LLType* T = DtoType(type); Type* t = type->toBasetype(); // defaults LLConstant* name = getNullPtr(getVoidPtrType()); // find tag unsigned tag; if (t->ty == Tpointer) { tag = DW_TAG_pointer_type; } else { assert(0 && "unsupported derivedtype for debug info"); } std::vector<LLConstant*> vals(10); // tag vals[0] = DBG_TAG(tag); // context vals[1] = DBG_CAST(compileUnit); // name vals[2] = name; // compile unit where defined vals[3] = DBG_NULL; // line number where defined vals[4] = DtoConstInt(0); // size in bits vals[5] = LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false); // alignment in bits vals[6] = LLConstantInt::get(LLType::Int64Ty, getABITypeAlign(T)*8, false); // offset in bits vals[7] = LLConstantInt::get(LLType::Int64Ty, 0, false); // FIXME: dont know what this is vals[8] = DtoConstUint(0); // base type Type* nt = t->nextOf(); LLGlobalVariable* nTD = dwarfTypeDescription_impl(nt, compileUnit, NULL); if (nt->ty == Tvoid || !nTD) vals[9] = DBG_NULL; else vals[9] = DBG_CAST(nTD); return emitDwarfGlobal(getDwarfDerivedTypeType(), vals, "llvm.dbg.derivedtype"); } ////////////////////////////////////////////////////////////////////////////////////////////////// static LLGlobalVariable* dwarfMemberType(unsigned linnum, Type* type, LLGlobalVariable* compileUnit, LLGlobalVariable* definedCU, const char* c_name, unsigned offset) { const LLType* T = DtoType(type); Type* t = type->toBasetype(); // defaults LLConstant* name; if (c_name) name = DtoConstStringPtr(c_name, "llvm.metadata"); else name = getNullPtr(getVoidPtrType()); std::vector<LLConstant*> vals(10); // tag vals[0] = DBG_TAG(DW_TAG_member); // context vals[1] = DBG_CAST(compileUnit); // name vals[2] = name; // compile unit where defined if (definedCU) vals[3] = DBG_CAST(definedCU); else vals[3] = DBG_NULL; // line number where defined vals[4] = DtoConstInt(linnum); // size in bits vals[5] = LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false); // alignment in bits vals[6] = LLConstantInt::get(LLType::Int64Ty, getABITypeAlign(T)*8, false); // offset in bits vals[7] = LLConstantInt::get(LLType::Int64Ty, offset*8, false); // FIXME: dont know what this is vals[8] = DtoConstUint(0); // base type LLGlobalVariable* nTD = dwarfTypeDescription(t, compileUnit, NULL); if (t->ty == Tvoid || !nTD) vals[9] = DBG_NULL; else vals[9] = DBG_CAST(nTD); return emitDwarfGlobal(getDwarfDerivedTypeType(), vals, "llvm.dbg.derivedtype"); } ////////////////////////////////////////////////////////////////////////////////////////////////// static LLGlobalVariable* dwarfCompositeType(Type* type, llvm::GlobalVariable* compileUnit) { const LLType* T = DtoType(type); Type* t = type->toBasetype(); // defaults LLConstant* name = getNullPtr(getVoidPtrType()); LLGlobalVariable* members = NULL; unsigned linnum = 0; LLGlobalVariable* definedCU = NULL; // prepare tag and members unsigned tag; // declare final global variable LLGlobalVariable* gv = NULL; // dynamic array if (t->ty == Tarray) { tag = DW_TAG_structure_type; LLGlobalVariable* len = dwarfMemberType(0, Type::tsize_t, compileUnit, NULL, "length", 0); assert(len); LLGlobalVariable* ptr = dwarfMemberType(0, t->nextOf()->pointerTo(), compileUnit, NULL, "ptr", global.params.is64bit?8:4); assert(ptr); const LLArrayType* at = LLArrayType::get(DBG_TYPE, 2); std::vector<LLConstant*> elems(2); elems[0] = DBG_CAST(len); elems[1] = DBG_CAST(ptr); LLConstant* ca = LLConstantArray::get(at, elems); members = new LLGlobalVariable(ca->getType(), true, LLGlobalValue::InternalLinkage, ca, ".array", gIR->module); members->setSection("llvm.metadata"); name = DtoConstStringPtr(t->toChars(), "llvm.metadata"); } // struct/class else if (t->ty == Tstruct || t->ty == Tclass) { AggregateDeclaration* sd; if (t->ty == Tstruct) { TypeStruct* ts = (TypeStruct*)t; sd = ts->sym; } else { TypeClass* tc = (TypeClass*)t; sd = tc->sym; } assert(sd); // if we don't know the aggregate's size, we don't know enough about it // to provide debug info. probably a forward-declared struct? if (sd->sizeok == 0) return NULL; IrStruct* ir = sd->ir.irStruct; assert(ir); if (ir->dwarfComposite) return ir->dwarfComposite; // set to handle recursive types properly gv = emitDwarfGlobalDecl(getDwarfCompositeTypeType(), "llvm.dbg.compositetype"); ir->dwarfComposite = gv; tag = DW_TAG_structure_type; name = DtoConstStringPtr(sd->toChars(), "llvm.metadata"); linnum = sd->loc.linnum; definedCU = DtoDwarfCompileUnit(sd->getModule()); std::vector<LLConstant*> elems; if (!ir->aggrdecl->isInterfaceDeclaration()) // plain interfaces don't have one { std::vector<VarDeclaration*>& arr = ir->varDecls; size_t narr = arr.size(); elems.reserve(narr); for (int k=0; k<narr; k++) { VarDeclaration* vd = arr[k]; assert(vd); LLGlobalVariable* ptr = dwarfMemberType(vd->loc.linnum, vd->type, compileUnit, definedCU, vd->toChars(), vd->offset); elems.push_back(DBG_CAST(ptr)); } } const LLArrayType* at = LLArrayType::get(DBG_TYPE, elems.size()); LLConstant* ca = LLConstantArray::get(at, elems); members = new LLGlobalVariable(ca->getType(), true, LLGlobalValue::InternalLinkage, ca, ".array", gIR->module); members->setSection("llvm.metadata"); } // unsupported composite type else { assert(0 && "unsupported compositetype for debug info"); } std::vector<LLConstant*> vals(11); // tag vals[0] = DBG_TAG(tag); // context vals[1] = DBG_CAST(compileUnit); // name vals[2] = name; // compile unit where defined if (definedCU) vals[3] = DBG_CAST(definedCU); else vals[3] = DBG_NULL; // line number where defined vals[4] = DtoConstInt(linnum); // size in bits vals[5] = LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false); // alignment in bits vals[6] = LLConstantInt::get(LLType::Int64Ty, getABITypeAlign(T)*8, false); // offset in bits vals[7] = LLConstantInt::get(LLType::Int64Ty, 0, false); // FIXME: dont know what this is vals[8] = DtoConstUint(0); // FIXME: ditto vals[9] = DBG_NULL; // members array if (members) vals[10] = DBG_CAST(members); else vals[10] = DBG_NULL; // set initializer if (!gv) gv = emitDwarfGlobalDecl(getDwarfCompositeTypeType(), "llvm.dbg.compositetype"); LLConstant* initia = LLConstantStruct::get(getDwarfCompositeTypeType(), vals); gv->setInitializer(initia); return gv; } ////////////////////////////////////////////////////////////////////////////////////////////////// static LLGlobalVariable* dwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd) { assert(vd->isDataseg()); LLGlobalVariable* compileUnit = DtoDwarfCompileUnit(gIR->dmodule); std::vector<LLConstant*> vals(12); vals[0] = DBG_TAG(DW_TAG_variable); vals[1] = DBG_CAST(getDwarfAnchor(DW_TAG_variable)); vals[2] = DBG_CAST(compileUnit); vals[3] = DtoConstStringPtr(vd->mangle(), "llvm.metadata"); vals[4] = DtoConstStringPtr(vd->toPrettyChars(), "llvm.metadata"); vals[5] = DtoConstStringPtr(vd->toChars(), "llvm.metadata"); vals[6] = DBG_CAST(DtoDwarfCompileUnit(vd->getModule())); vals[7] = DtoConstUint(vd->loc.linnum); LLGlobalVariable* TY = dwarfTypeDescription_impl(vd->type, compileUnit, NULL); vals[8] = TY ? DBG_CAST(TY) : DBG_NULL; vals[9] = DtoConstBool(vd->protection == PROTprivate); vals[10] = DtoConstBool(vd->getModule() == gIR->dmodule); vals[11] = DBG_CAST(ll); return emitDwarfGlobal(getDwarfGlobalVariableType(), vals, "llvm.dbg.global_variable"); } ////////////////////////////////////////////////////////////////////////////////////////////////// static LLGlobalVariable* dwarfVariable(VarDeclaration* vd, LLGlobalVariable* typeDescr) { assert(!vd->isDataseg() && "static variable"); unsigned tag; if (vd->isParameter()) tag = DW_TAG_arg_variable; else tag = DW_TAG_auto_variable; std::vector<LLConstant*> vals(6); // tag vals[0] = DBG_TAG(tag); // context vals[1] = DBG_CAST(gIR->func()->dwarfSubProg); // name vals[2] = DtoConstStringPtr(vd->toChars(), "llvm.metadata"); // compile unit where defined vals[3] = DBG_CAST(DtoDwarfCompileUnit(vd->getModule())); // line number where defined vals[4] = DtoConstUint(vd->loc.linnum); // type descriptor vals[5] = DBG_CAST(typeDescr); return emitDwarfGlobal(getDwarfVariableType(), vals, "llvm.dbg.variable"); } ////////////////////////////////////////////////////////////////////////////////////////////////// static void dwarfDeclare(LLValue* var, LLGlobalVariable* varDescr) { LLSmallVector<LLValue*,2> args(2); args[0] = DtoBitCast(var, DBG_TYPE); args[1] = DBG_CAST(varDescr); gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.declare"), args.begin(), args.end()); } ////////////////////////////////////////////////////////////////////////////////////////////////// static LLGlobalVariable* dwarfTypeDescription_impl(Type* type, LLGlobalVariable* cu, const char* c_name) { Type* t = type->toBasetype(); if (t->ty == Tvoid) return NULL; else if (t->isintegral() || t->isfloating()) return dwarfBasicType(type, cu); else if (t->ty == Tpointer) return dwarfDerivedType(type, cu); else if (t->ty == Tarray || t->ty == Tstruct || t->ty == Tclass) return dwarfCompositeType(type, cu); return NULL; } static LLGlobalVariable* dwarfTypeDescription(Type* type, LLGlobalVariable* cu, const char* c_name) { Type* t = type->toBasetype(); if (t->ty == Tclass) return dwarfTypeDescription_impl(type->pointerTo(), cu, c_name); else return dwarfTypeDescription_impl(type, cu, c_name); } ////////////////////////////////////////////////////////////////////////////////////////////////// void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd) { Logger::println("D to dwarf local variable"); LOG_SCOPE; // get compile units LLGlobalVariable* thisCU = DtoDwarfCompileUnit(gIR->dmodule); LLGlobalVariable* varCU = thisCU; if (vd->getModule() != gIR->dmodule) varCU = DtoDwarfCompileUnit(vd->getModule()); // get type description Type* t = vd->type->toBasetype(); LLGlobalVariable* TD = dwarfTypeDescription(vd->type, thisCU, NULL); if (TD == NULL) return; // unsupported // get variable description LLGlobalVariable* VD; VD = dwarfVariable(vd, TD); // declare dwarfDeclare(ll, VD); } ////////////////////////////////////////////////////////////////////////////////////////////////// LLGlobalVariable* DtoDwarfCompileUnit(Module* m) { Logger::println("D to dwarf compile_unit"); LOG_SCOPE; // we might be generating for an import if (!m->ir.irModule) m->ir.irModule = new IrModule(m, m->srcfile->toChars()); else if (m->ir.irModule->dwarfCompileUnit) { if (m->ir.irModule->dwarfCompileUnit->getParent() == gIR->module) return m->ir.irModule->dwarfCompileUnit; } LLGlobalVariable* gv = dwarfCompileUnit(m); m->ir.irModule->dwarfCompileUnit = gv; return gv; } ////////////////////////////////////////////////////////////////////////////////////////////////// LLGlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd) { Logger::println("D to dwarf subprogram"); LOG_SCOPE; // FIXME: duplicates ? return dwarfSubProgram( DtoDwarfCompileUnit(gIR->dmodule), DtoDwarfCompileUnit(fd->getModule()), fd->toPrettyChars(), fd->mangle(), fd->loc.linnum, fd->protection == PROTprivate); } ////////////////////////////////////////////////////////////////////////////////////////////////// LLGlobalVariable* DtoDwarfSubProgramInternal(const char* prettyname, const char* mangledname) { Logger::println("D to dwarf subprogram"); LOG_SCOPE; // FIXME: duplicates ? return dwarfSubProgram( DtoDwarfCompileUnit(gIR->dmodule), DtoDwarfCompileUnit(gIR->dmodule), prettyname, mangledname, 0, true); } ////////////////////////////////////////////////////////////////////////////////////////////////// LLGlobalVariable* DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd) { Logger::println("D to dwarf global_variable"); LOG_SCOPE; // FIXME: duplicates ? return dwarfGlobalVariable(ll, vd); } ////////////////////////////////////////////////////////////////////////////////////////////////// void DtoDwarfFuncStart(FuncDeclaration* fd) { Logger::println("D to dwarf funcstart"); LOG_SCOPE; assert(fd->ir.irFunc->dwarfSubProg); gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(fd->ir.irFunc->dwarfSubProg)); } ////////////////////////////////////////////////////////////////////////////////////////////////// void DtoDwarfFuncEnd(FuncDeclaration* fd) { Logger::println("D to dwarf funcend"); LOG_SCOPE; assert(fd->ir.irFunc->dwarfSubProg); gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(fd->ir.irFunc->dwarfSubProg)); } ////////////////////////////////////////////////////////////////////////////////////////////////// void DtoDwarfStopPoint(unsigned ln) { Logger::println("D to dwarf stoppoint at line %u", ln); LOG_SCOPE; LLSmallVector<LLValue*,3> args(3); args[0] = DtoConstUint(ln); args[1] = DtoConstUint(0); FuncDeclaration* fd = gIR->func()->decl; args[2] = DBG_CAST(DtoDwarfCompileUnit(fd->getModule())); gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.stoppoint"), args.begin(), args.end()); }