diff --git a/gen/configfile.cpp b/gen/configfile.cpp index 1f5a8cd0..b9221ab1 100644 --- a/gen/configfile.cpp +++ b/gen/configfile.cpp @@ -3,7 +3,7 @@ #include #include -#include "llvm/Support/Path.h" +#include "llvm/System/Path.h" #include "libconfig.h++" diff --git a/gen/irstate.cpp b/gen/irstate.cpp index 6cf3b1d9..6c43fb79 100644 --- a/gen/irstate.cpp +++ b/gen/irstate.cpp @@ -57,7 +57,7 @@ IRTargetScope::IRTargetScope(Statement* s, EnclosingHandler* enclosinghandler, l ////////////////////////////////////////////////////////////////////////////////////////// IRState::IRState(llvm::Module* m) - : module(m), dibuilder(*m) + : module(m), difactory(*m) { interfaceInfoType = NULL; mutexType = NULL; diff --git a/gen/irstate.h b/gen/irstate.h index fb1460af..4323a3d8 100644 --- a/gen/irstate.h +++ b/gen/irstate.h @@ -13,7 +13,6 @@ #include "ir/irstruct.h" #include "ir/irvar.h" -#include "llvm/Analysis/DIBuilder.h" #include "llvm/Support/CallSite.h" namespace llvm { @@ -158,7 +157,7 @@ struct IRState IRBuilderHelper ir; // debug info helper - llvm::DIBuilder dibuilder; + llvm::DIFactory difactory; // static ctors/dtors/unittests typedef std::list FuncDeclList; diff --git a/gen/linker.cpp b/gen/linker.cpp index d2173c1f..343f73bd 100644 --- a/gen/linker.cpp +++ b/gen/linker.cpp @@ -1,7 +1,7 @@ #include "gen/linker.h" #include "gen/llvm.h" #include "llvm/Linker.h" -#include "llvm/Support/Program.h" +#include "llvm/System/Program.h" #if _WIN32 #include "llvm/Support/SystemUtils.h" #endif diff --git a/gen/main.cpp b/gen/main.cpp index 38699d8c..b96233e5 100644 --- a/gen/main.cpp +++ b/gen/main.cpp @@ -7,6 +7,7 @@ #include "llvm/LinkAllVMCore.h" #include "llvm/Linker.h" #include "llvm/LLVMContext.h" +#include "llvm/System/Signals.h" #include "llvm/Target/SubtargetFeature.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" @@ -159,6 +160,15 @@ int main(int argc, char** argv) VersionCondition::addPredefinedGlobalIdent("D_Version2"); #endif + // merge DFLAGS environment variable into argc/argv + getenv_setargv("DFLAGS", &argc, &argv); +#if 0 + for (int i = 0; i < argc; i++) + { + printf("argv[%d] = '%s'\n", i, argv[i]); + } +#endif + // build complete fixed up list of command line arguments std::vector final_args; final_args.reserve(argc); diff --git a/gen/nested.cpp b/gen/nested.cpp index 035606f1..6c832872 100644 --- a/gen/nested.cpp +++ b/gen/nested.cpp @@ -7,7 +7,6 @@ #include "gen/tollvm.h" #include "gen/functions.h" -#include "llvm/Analysis/ValueTracking.h" #include "llvm/Support/CommandLine.h" namespace cl = llvm::cl; @@ -438,7 +437,7 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) { assert(vd->ir.irLocal->value); LLValue* value = vd->ir.irLocal->value; const LLType* type = value->getType(); - if (llvm::isa(llvm::GetUnderlyingObject(value))) + if (llvm::isa(value->getUnderlyingObject())) // This will be copied to the nesting frame. type = type->getContainedType(0); types.push_back(type); @@ -632,7 +631,7 @@ void DtoCreateNestedContext(FuncDeclaration* fd) { Logger::println("nested param: %s", vd->toChars()); LOG_SCOPE LLValue* value = vd->ir.irLocal->value; - if (llvm::isa(llvm::GetUnderlyingObject(value))) { + if (llvm::isa(value->getUnderlyingObject())) { Logger::println("Copying to nested frame"); // The parameter value is an alloca'd stack slot. // Copy to the nesting frame and leave the alloca for diff --git a/gen/optimizer.cpp b/gen/optimizer.cpp index 280b9541..c58a8cf3 100644 --- a/gen/optimizer.cpp +++ b/gen/optimizer.cpp @@ -183,6 +183,7 @@ static void addPassesForOptLevel(PassManager& pm) { addPass(pm, createLoopRotatePass()); addPass(pm, createLICMPass()); addPass(pm, createLoopUnswitchPass()); + addPass(pm, createLoopIndexSplitPass()); addPass(pm, createInstructionCombiningPass()); addPass(pm, createIndVarSimplifyPass()); addPass(pm, createLoopDeletionPass()); diff --git a/gen/programs.cpp b/gen/programs.cpp index 00134314..605504b7 100644 --- a/gen/programs.cpp +++ b/gen/programs.cpp @@ -1,7 +1,7 @@ #include "gen/programs.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/Program.h" +#include "llvm/System/Program.h" #include "root.h" // error(char*) #include "mars.h" // fatal() diff --git a/gen/programs.h b/gen/programs.h index 38f3135b..27a00fc7 100644 --- a/gen/programs.h +++ b/gen/programs.h @@ -1,7 +1,7 @@ #ifndef LDC_GEN_PROGRAMS_H #define LDC_GEN_PROGRAMS_H -#include "llvm/Support/Path.h" +#include "llvm/System/Path.h" llvm::sys::Path getGcc(); diff --git a/gen/todebug.cpp b/gen/todebug.cpp index c6e4a3fb..d290a70f 100644 --- a/gen/todebug.cpp +++ b/gen/todebug.cpp @@ -1,8 +1,7 @@ #include "gen/llvm.h" -#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/Support/Dwarf.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/PathV2.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/System/Path.h" #include "declaration.h" #include "module.h" @@ -44,25 +43,22 @@ static Module* getDefinedModule(Dsymbol* s) ////////////////////////////////////////////////////////////////////////////////////////////////// -static llvm::DIType dwarfTypeDescription_impl(Type* type, const char* c_name); -static llvm::DIType dwarfTypeDescription(Type* type, const char* c_name); +static llvm::DIType dwarfTypeDescription_impl(Type* type, llvm::DICompileUnit cu, const char* c_name); +static llvm::DIType dwarfTypeDescription(Type* type, llvm::DICompileUnit cu, const char* c_name); ////////////////////////////////////////////////////////////////////////////////////////////////// -llvm::DIFile DtoDwarfFile(Loc loc) +llvm::DIFile DtoDwarfFile(Loc loc, llvm::DICompileUnit compileUnit) { - llvm::SmallString<128> path(loc.filename); - llvm::sys::fs::make_absolute(path); - - return gIR->dibuilder.createFile( - llvm::sys::path::filename(path), - llvm::sys::path::parent_path(path) - ); + typedef llvm::sys::Path LLPath; + LLPath path = loc.filename ? LLPath(loc.filename) : LLPath(); + path.makeAbsolute(); + return gIR->difactory.CreateFile(path.getLast(), path.getDirname(), compileUnit); } ////////////////////////////////////////////////////////////////////////////////////////////////// -static llvm::DIType dwarfBasicType(Type* type) +static llvm::DIBasicType dwarfBasicType(Type* type, llvm::DICompileUnit compileUnit) { Type* t = type->toBasetype(); const LLType* T = DtoType(type); @@ -85,52 +81,67 @@ static llvm::DIType dwarfBasicType(Type* type) assert(0 && "unsupported basictype for debug info"); } - return gIR->dibuilder.createBasicType( + return gIR->difactory.CreateBasicType( + compileUnit, // context type->toChars(), // name + DtoDwarfFile(Loc(gIR->dmodule, 0), DtoDwarfCompileUnit(gIR->dmodule)), // file + 0, // line number getTypeBitSize(T), // size (bits) getABITypeAlign(T)*8, // align (bits) - id + 0, // offset (bits) +//FIXME: need flags? + 0, // flags + id // encoding ); } ////////////////////////////////////////////////////////////////////////////////////////////////// -static llvm::DIType dwarfPointerType(Type* type) +static llvm::DIDerivedType dwarfDerivedType(Type* type, llvm::DICompileUnit compileUnit) { const LLType* T = DtoType(type); Type* t = type->toBasetype(); - assert(t->ty == Tpointer && "only pointers allowed for debug info in dwarfPointerType"); + assert(t->ty == Tpointer && "unsupported derivedtype for debug info, only pointers allowed"); // find base type llvm::DIType basetype; Type* nt = t->nextOf(); - basetype = dwarfTypeDescription_impl(nt, NULL); + basetype = dwarfTypeDescription_impl(nt, compileUnit, NULL); if (nt->ty == Tvoid) basetype = llvm::DIType(NULL); - return gIR->dibuilder.createPointerType( - basetype, + return gIR->difactory.CreateDerivedType( + DW_TAG_pointer_type, // tag + compileUnit, // context + type->toChars(), // name + DtoDwarfFile(Loc(gIR->dmodule, 0), DtoDwarfCompileUnit(gIR->dmodule)), // file + 0, // line number getTypeBitSize(T), // size (bits) getABITypeAlign(T)*8, // align (bits) - type->toChars() // name + 0, // offset (bits) +//FIXME: need flags? + 0, // flags + basetype // derived from ); } ////////////////////////////////////////////////////////////////////////////////////////////////// -static llvm::DIType dwarfMemberType(unsigned linnum, Type* type, llvm::DIFile file, const char* c_name, unsigned offset) +static llvm::DIDerivedType dwarfMemberType(unsigned linnum, Type* type, llvm::DICompileUnit compileUnit, llvm::DIFile file, const char* c_name, unsigned offset) { const LLType* T = DtoType(type); Type* t = type->toBasetype(); // find base type llvm::DIType basetype; - basetype = dwarfTypeDescription(t, NULL); + basetype = dwarfTypeDescription(t, compileUnit, NULL); if (t->ty == Tvoid) basetype = llvm::DIType(NULL); - return gIR->dibuilder.createMemberType( + return gIR->difactory.CreateDerivedType( + DW_TAG_member, // tag + compileUnit, // context c_name, // name file, // file linnum, // line number @@ -147,12 +158,13 @@ static llvm::DIType dwarfMemberType(unsigned linnum, Type* type, llvm::DIFile fi static void add_base_fields( ClassDeclaration* sd, + llvm::DICompileUnit compileUnit, llvm::DIFile file, - std::vector& elems) + std::vector& elems) { if (sd->baseClass) { - add_base_fields(sd->baseClass, file, elems); + add_base_fields(sd->baseClass, compileUnit, file, elems); } ArrayIter it(sd->fields); @@ -161,12 +173,15 @@ static void add_base_fields( for (; !it.done(); it.next()) { VarDeclaration* vd = it.get(); - elems.push_back(dwarfMemberType(vd->loc.linnum, vd->type, file, vd->toChars(), vd->offset)); + elems.push_back(dwarfMemberType(vd->loc.linnum, vd->type, compileUnit, file, vd->toChars(), vd->offset)); } } -static llvm::DIType dwarfCompositeType(Type* type) + +//FIXME: This does not use llvm's DIFactory as it can't +// handle recursive types properly. +static llvm::DICompositeType dwarfCompositeType(Type* type, llvm::DICompileUnit compileUnit) { const LLType* T = DtoType(type); Type* t = type->toBasetype(); @@ -176,126 +191,121 @@ static llvm::DIType dwarfCompositeType(Type* type) unsigned linnum = 0; llvm::DIFile file; + // prepare tag and members + unsigned tag; + // elements - std::vector elems; + std::vector elems; // pointer to ir->diCompositeType - llvm::DIType *diCompositeType = 0; + llvm::DICompositeType *diCompositeType = 0; - llvm::DIType derivedFrom; + llvm::DICompositeType derivedFrom; - assert((t->ty == Tstruct || t->ty == Tclass) && - "unsupported type for dwarfCompositeType"); - AggregateDeclaration* sd; - if (t->ty == Tstruct) + // dynamic array + if (t->ty == Tarray) { - TypeStruct* ts = (TypeStruct*)t; - sd = ts->sym; - } - else - { - TypeClass* tc = (TypeClass*)t; - sd = tc->sym; - } - assert(sd); - - // make sure it's resolved - sd->codegen(Type::sir); - - // 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 llvm::DICompositeType(NULL); - - IrStruct* ir = sd->ir.irStruct; - assert(ir); - if ((llvm::MDNode*)ir->diCompositeType != 0) - return ir->diCompositeType; - - diCompositeType = &ir->diCompositeType; - name = sd->toChars(); - linnum = sd->loc.linnum; - file = DtoDwarfFile(sd->loc); - // set diCompositeType to handle recursive types properly - if (t->ty == Tclass) { - ir->diCompositeType = gIR->dibuilder.createClassType( - llvm::DIDescriptor(file), - name, // name - file, // compile unit where defined - linnum, // line number where defined - getTypeBitSize(T), // size in bits - getABITypeAlign(T)*8, // alignment in bits - 0, // offset in bits, - llvm::DIType::FlagFwdDecl, // flags - derivedFrom, // DerivedFrom - llvm::DIArray(0) - ); - } else { - ir->diCompositeType = gIR->dibuilder.createStructType( - llvm::DIDescriptor(file), - name, // name - file, // compile unit where defined - linnum, // line number where defined - getTypeBitSize(T), // size in bits - getABITypeAlign(T)*8, // alignment in bits - llvm::DIType::FlagFwdDecl, // flags - llvm::DIArray(0) - ); + file = DtoDwarfFile(Loc(gIR->dmodule, 0), DtoDwarfCompileUnit(gIR->dmodule)); + tag = DW_TAG_structure_type; + elems.push_back(dwarfMemberType(0, Type::tsize_t, compileUnit, file, "length", 0)); + elems.push_back(dwarfMemberType(0, t->nextOf()->pointerTo(), compileUnit, file, "ptr", global.params.is64bit?8:4)); } - if (!ir->aggrdecl->isInterfaceDeclaration()) // plain interfaces don't have one + // struct/class + else if (t->ty == Tstruct || t->ty == Tclass) { + AggregateDeclaration* sd; if (t->ty == Tstruct) { - ArrayIter it(sd->fields); - size_t narr = sd->fields.dim; - elems.reserve(narr); - for (; !it.done(); it.next()) - { - VarDeclaration* vd = it.get(); - llvm::DIType dt = dwarfMemberType(vd->loc.linnum, vd->type, file, vd->toChars(), vd->offset); - elems.push_back(dt); - } + TypeStruct* ts = (TypeStruct*)t; + sd = ts->sym; + tag = DW_TAG_structure_type; } else { - ClassDeclaration *classDecl = ir->aggrdecl->isClassDeclaration(); - add_base_fields(classDecl, file, elems); - if (classDecl->baseClass) - derivedFrom = dwarfCompositeType(classDecl->baseClass->getType()); + TypeClass* tc = (TypeClass*)t; + sd = tc->sym; + tag = DW_TAG_class_type; + } + assert(sd); + + // make sure it's resolved + sd->codegen(Type::sir); + + // 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 llvm::DICompositeType(NULL); + + IrStruct* ir = sd->ir.irStruct; + assert(ir); + if ((llvm::MDNode*)ir->diCompositeType != 0) + return ir->diCompositeType; + + diCompositeType = &ir->diCompositeType; + name = sd->toChars(); + linnum = sd->loc.linnum; + file = DtoDwarfFile(sd->loc, DtoDwarfCompileUnit(getDefinedModule(sd))); + // set diCompositeType to handle recursive types properly + ir->diCompositeType = gIR->difactory.CreateCompositeTypeEx( + tag, // tag + compileUnit, // context + name, // name + file, // compile unit where defined + linnum, // line number where defined + LLConstantInt::get(LLType::getInt64Ty(gIR->context()), getTypeBitSize(T), false), // size in bits + LLConstantInt::get(LLType::getInt64Ty(gIR->context()), getABITypeAlign(T)*8, false), // alignment in bits + LLConstantInt::get(LLType::getInt64Ty(gIR->context()), 0, false), // offset in bits, + llvm::DIType::FlagFwdDecl, // flags + derivedFrom, // DerivedFrom + llvm::DIArray(0) + ); + + if (!ir->aggrdecl->isInterfaceDeclaration()) // plain interfaces don't have one + { + if (t->ty == Tstruct) + { + ArrayIter it(sd->fields); + size_t narr = sd->fields.dim; + elems.reserve(narr); + for (; !it.done(); it.next()) + { + VarDeclaration* vd = it.get(); + llvm::DIDerivedType dt = dwarfMemberType(vd->loc.linnum, vd->type, compileUnit, file, vd->toChars(), vd->offset); + elems.push_back(dt); + } + } + else + { + ClassDeclaration *classDecl = ir->aggrdecl->isClassDeclaration(); + add_base_fields(classDecl, compileUnit, file, elems); + if (classDecl->baseClass) + derivedFrom = dwarfCompositeType(classDecl->baseClass->getType(), compileUnit); + } } } - llvm::DIArray elemsArray = - gIR->dibuilder.getOrCreateArray(elems.data(), elems.size()); - - llvm::DIType ret; - if (t->ty == Tclass) { - ret = gIR->dibuilder.createClassType( - llvm::DIDescriptor(file), - name, // name - file, // compile unit where defined - linnum, // line number where defined - getTypeBitSize(T), // size in bits - getABITypeAlign(T)*8, // alignment in bits - 0, // offset in bits, - llvm::DIType::FlagFwdDecl, // flags - derivedFrom, // DerivedFrom - elemsArray - ); - } else { - ret = gIR->dibuilder.createStructType( - llvm::DIDescriptor(file), - name, // name - file, // compile unit where defined - linnum, // line number where defined - getTypeBitSize(T), // size in bits - getABITypeAlign(T)*8, // alignment in bits - llvm::DIType::FlagFwdDecl, // flags - elemsArray - ); + // unsupported composite type + else + { + assert(0 && "unsupported compositetype for debug info"); } + llvm::DIArray elemsArray = + gIR->difactory.GetOrCreateArray(elems.data(), elems.size()); + + llvm::DICompositeType ret = gIR->difactory.CreateCompositeTypeEx( + tag, // tag + compileUnit, // context + name, // name + file, // compile unit where defined + linnum, // line number where defined + LLConstantInt::get(LLType::getInt64Ty(gIR->context()), getTypeBitSize(T), false), // size in bits + LLConstantInt::get(LLType::getInt64Ty(gIR->context()), getABITypeAlign(T)*8, false), // alignment in bits + LLConstantInt::get(LLType::getInt64Ty(gIR->context()), 0, false), // offset in bits, + llvm::DIType::FlagFwdDecl, // flags + derivedFrom, // DerivedFrom + elemsArray); if (diCompositeType) *diCompositeType = ret; return ret; @@ -310,79 +320,77 @@ static llvm::DIGlobalVariable dwarfGlobalVariable(LLGlobalVariable* ll, VarDecla #else assert(vd->isDataseg()); #endif + llvm::DICompileUnit compileUnit = DtoDwarfCompileUnit(gIR->dmodule); - return gIR->dibuilder.createGlobalVariable( - vd->toChars(), // name TODO: mangle() or toPrettyChars() instead? - DtoDwarfFile(vd->loc), // file + return gIR->difactory.CreateGlobalVariable( + compileUnit, // context + vd->mangle(), // name + vd->toPrettyChars(), // displayname + vd->toChars(), // linkage name + DtoDwarfFile(vd->loc, DtoDwarfCompileUnit(getDefinedModule(vd))), // file vd->loc.linnum, // line num - dwarfTypeDescription_impl(vd->type, NULL), // type + dwarfTypeDescription_impl(vd->type, compileUnit, NULL), // type vd->protection == PROTprivate, // is local to unit + true, // is definition ll // value ); } +////////////////////////////////////////////////////////////////////////////////////////////////// + +static llvm::DIVariable dwarfVariable(VarDeclaration* vd, llvm::DIType type) +{ + assert(!vd->isDataseg() && "static variable"); + + unsigned tag; + if (vd->isParameter()) + tag = DW_TAG_arg_variable; + else + tag = DW_TAG_auto_variable; + + return gIR->difactory.CreateVariable( + tag, // tag + gIR->func()->diSubprogram, // context + vd->toChars(), // name + DtoDwarfFile(vd->loc, DtoDwarfCompileUnit(getDefinedModule(vd))), // file + vd->loc.linnum, // line num + type, // type + true // preserve + ); +} ////////////////////////////////////////////////////////////////////////////////////////////////// static void dwarfDeclare(LLValue* var, llvm::DIVariable divar) { - llvm::Instruction *instr = gIR->dibuilder.insertDeclare(var, divar, gIR->scopebb()); + llvm::Instruction *instr = gIR->difactory.InsertDeclare(var, divar, gIR->scopebb()); instr->setDebugLoc(gIR->ir->getCurrentDebugLocation()); } ////////////////////////////////////////////////////////////////////////////////////////////////// - -llvm::DIType dwarfArrayType(Type* type) { - const LLType* T = DtoType(type); - Type* t = type->toBasetype(); - - llvm::DIFile file = DtoDwarfFile(Loc(gIR->dmodule, 0)); - - std::vector elems; - elems.push_back(dwarfMemberType(0, Type::tsize_t, file, "length", 0)); - elems.push_back(dwarfMemberType(0, t->nextOf()->pointerTo(), file, "ptr", global.params.is64bit?8:4)); - - return gIR->dibuilder.createStructType - ( - llvm::DIDescriptor(file), - llvm::StringRef(), // Name TODO: Really no name for arrays? - file, // File - 0, // LineNo - getTypeBitSize(T), // size in bits - getABITypeAlign(T)*8, // alignment in bits - 0, // What here? - gIR->dibuilder.getOrCreateArray(elems.data(), elems.size()) - ); - -} - -////////////////////////////////////////////////////////////////////////////////////////////////// - -static llvm::DIType dwarfTypeDescription_impl(Type* type, const char* c_name) +static llvm::DIType dwarfTypeDescription_impl(Type* type, llvm::DICompileUnit cu, const char* c_name) { Type* t = type->toBasetype(); if (t->ty == Tvoid) return llvm::DIType(NULL); else if (t->isintegral() || t->isfloating()) - return dwarfBasicType(type); + return dwarfBasicType(type, cu); else if (t->ty == Tpointer) - return dwarfPointerType(type); - else if (t->ty == Tarray) - return dwarfArrayType(type); - else if (t->ty == Tstruct || t->ty == Tclass) - return dwarfCompositeType(type); + return dwarfDerivedType(type, cu); + else if (t->ty == Tarray || t->ty == Tstruct || t->ty == Tclass) + return dwarfCompositeType(type, cu); return llvm::DIType(NULL); } -static llvm::DIType dwarfTypeDescription(Type* type, const char* c_name) +static llvm::DIType dwarfTypeDescription(Type* type, llvm::DICompileUnit cu, const char* c_name) { Type* t = type->toBasetype(); if (t->ty == Tclass) - return dwarfTypeDescription_impl(type->pointerTo(), c_name); + return dwarfTypeDescription_impl(type->pointerTo(), cu, c_name); else - return dwarfTypeDescription_impl(type, c_name); + return dwarfTypeDescription_impl(type, cu, c_name); } ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -392,29 +400,17 @@ void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd) Logger::println("D to dwarf local variable"); LOG_SCOPE; + // get compile units + llvm::DICompileUnit thisCU = DtoDwarfCompileUnit(gIR->dmodule); + llvm::DICompileUnit varCU = DtoDwarfCompileUnit(getDefinedModule(vd)); + // get type description - llvm::DIType TD = dwarfTypeDescription(vd->type, NULL); + llvm::DIType TD = dwarfTypeDescription(vd->type, thisCU, NULL); if ((llvm::MDNode*)TD == 0) return; // unsupported // get variable description - assert(!vd->isDataseg() && "static variable"); - - unsigned tag; - if (vd->isParameter()) - tag = DW_TAG_arg_variable; - else - tag = DW_TAG_auto_variable; - - vd->debugVariable = gIR->dibuilder.createLocalVariable( - tag, // tag - gIR->func()->diSubprogram, // context - vd->toChars(), // name - DtoDwarfFile(vd->loc), // file - vd->loc.linnum, // line num - TD, // type - true // preserve - ); + vd->debugVariable = dwarfVariable(vd, TD); // declare dwarfDeclare(ll, vd->debugVariable); @@ -422,11 +418,23 @@ void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd) ////////////////////////////////////////////////////////////////////////////////////////////////// -void DtoDwarfCompileUnit(Module* m) +llvm::DICompileUnit DtoDwarfCompileUnit(Module* m) { Logger::println("D to dwarf compile_unit"); LOG_SCOPE; + static bool mainUnitCreated = false; + + // we might be generating for an import + IrModule* irmod = getIrModule(m); + + if ((llvm::MDNode*)irmod->diCompileUnit != 0) + { + //assert (irmod->diCompileUnit.getGV()->getParent() == gIR->module + // && "debug info compile unit belongs to incorrect llvm module!"); + return irmod->diCompileUnit; + } + // prepare srcpath std::string srcpath(FileName::path(m->srcfile->name->toChars())); if (!FileName::absolute(srcpath.c_str())) { @@ -437,15 +445,20 @@ void DtoDwarfCompileUnit(Module* m) srcpath = srcpath + '/'; } - gIR->dibuilder.createCompileUnit( + bool isMain = !mainUnitCreated && gIR->dmodule == m; + // make compile unit + irmod->diCompileUnit = gIR->difactory.CreateCompileUnit( global.params.symdebug == 2 ? DW_LANG_C : DW_LANG_D, m->srcfile->name->toChars(), srcpath, "LDC (http://www.dsource.org/projects/ldc)", - false, // isOptimized TODO - llvm::StringRef(), // Flags TODO - 1 // Runtime Version TODO + isMain, // isMain, + false // isOptimized ); + if (isMain) + mainUnitCreated = true; + + return irmod->diCompileUnit; } ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -455,20 +468,24 @@ llvm::DISubprogram DtoDwarfSubProgram(FuncDeclaration* fd) Logger::println("D to dwarf subprogram"); LOG_SCOPE; - llvm::DIFile file = DtoDwarfFile(fd->loc); + llvm::DICompileUnit context = DtoDwarfCompileUnit(gIR->dmodule); + llvm::DIFile file = DtoDwarfFile(fd->loc, DtoDwarfCompileUnit(getDefinedModule(fd))); Type *retType = ((TypeFunction*)fd->type)->next; // FIXME: duplicates ? - return gIR->dibuilder.createFunction( - llvm::DICompileUnit(file), // context + return gIR->difactory.CreateSubprogram( + context, // context fd->toPrettyChars(), // name + fd->toPrettyChars(), // display name fd->mangle(), // linkage name file, // file fd->loc.linnum, // line no - dwarfTypeDescription(retType, NULL), // type + dwarfTypeDescription(retType, context, NULL), // type fd->protection == PROTprivate, // is local to unit gIR->dmodule == getDefinedModule(fd), // isdefinition - 0, // Flags + 0, 0, // VK, Index + llvm::DIType(), + false, // isArtificial false, // isOptimized fd->ir.irFunc->func ); @@ -481,14 +498,15 @@ llvm::DISubprogram DtoDwarfSubProgramInternal(const char* prettyname, const char Logger::println("D to dwarf subprogram"); LOG_SCOPE; - llvm::DIFile file(DtoDwarfFile(Loc(gIR->dmodule, 0))); + llvm::DICompileUnit context = DtoDwarfCompileUnit(gIR->dmodule); // FIXME: duplicates ? - return gIR->dibuilder.createFunction( - llvm::DIDescriptor(file), // context + return gIR->difactory.CreateSubprogram( + context, // context prettyname, // name + prettyname, // display name mangledname, // linkage name - file, // file + DtoDwarfFile(Loc(gIR->dmodule, 0), context), // compile unit 0, // line no llvm::DIType(NULL), // return type. TODO: fill it up true, // is local to unit @@ -550,7 +568,7 @@ void DtoDwarfValue(LLValue* var, VarDeclaration* vd) if (llvm::isa(vd->ir.irLocal->value) == 0) return; - llvm::Instruction *instr = gIR->dibuilder.insertDbgValueIntrinsic(vd->ir.irLocal->value, 0, vd->debugVariable, gIR->scopebb()); + llvm::Instruction *instr = gIR->difactory.InsertDbgValueIntrinsic(vd->ir.irLocal->value, 0, vd->debugVariable, gIR->scopebb()); instr->setDebugLoc(gIR->ir->getCurrentDebugLocation()); } diff --git a/gen/todebug.h b/gen/todebug.h index c78b666a..5a4fa757 100644 --- a/gen/todebug.h +++ b/gen/todebug.h @@ -8,8 +8,9 @@ void RegisterDwarfSymbols(llvm::Module* mod); /** * Emit the Dwarf compile_unit global for a Module m. * @param m + * @return the Dwarf compile_unit. */ -void DtoDwarfCompileUnit(Module* m); +llvm::DICompileUnit DtoDwarfCompileUnit(Module* m); /** * Emit the Dwarf subprogram global for a function declaration fd. diff --git a/gen/toobj.cpp b/gen/toobj.cpp index 4d3517bd..f1cbfb31 100644 --- a/gen/toobj.cpp +++ b/gen/toobj.cpp @@ -16,7 +16,7 @@ #include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/LinkAllPasses.h" -#include "llvm/Support/Program.h" +#include "llvm/System/Program.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FormattedStream.h" @@ -200,7 +200,7 @@ void writeModule(llvm::Module* m, std::string filename) LOG_SCOPE; if (llvm::verifyModule(*m,llvm::ReturnStatusAction,&verifyErr)) { - error("%s", verifyErr.c_str()); + //error("%s", verifyErr.c_str()); fatal(); } else { diff --git a/gen/utils.h b/gen/utils.h index b4a3b4b5..04323ac7 100644 --- a/gen/utils.h +++ b/gen/utils.h @@ -19,14 +19,14 @@ struct ArrayIter ArrayIter& operator=(const Array& arr) { - array = const_cast(&arr); + array = &arr; index = 0; return *this; } ArrayIter& operator=(const Array* arr) { assert(arr && "null array"); - array = const_cast(arr); + array = arr; index = 0; return *this; } diff --git a/ir/irmodule.h b/ir/irmodule.h index af12d904..3073e2c9 100644 --- a/ir/irmodule.h +++ b/ir/irmodule.h @@ -13,6 +13,7 @@ struct IrModule : IrBase Module* M; LLGlobalVariable* fileName; + llvm::DICompileUnit diCompileUnit; }; #endif diff --git a/ir/irstruct.h b/ir/irstruct.h index 1fbe9cd0..8454df58 100644 --- a/ir/irstruct.h +++ b/ir/irstruct.h @@ -32,7 +32,7 @@ struct IrStruct : IrBase bool packed; /// Composite type debug description. - llvm::DIType diCompositeType; + llvm::DICompositeType diCompositeType; //////////////////////////////////////////////////////////////////////////