static llvm::DIType dwarfCompositeType(Type* type) { LLType* T = DtoType(type); Type* t = type->toBasetype(); // defaults llvm::StringRef name; unsigned linnum = 0; llvm::DIFile file; // elements std::vector<llvm::Value*> elems; llvm::DIType derivedFrom; assert((t->ty == Tstruct || t->ty == Tclass) && "unsupported type for dwarfCompositeType"); AggregateDeclaration* sd; if (t->ty == Tstruct) { 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; name = sd->toChars(); linnum = sd->loc.linnum; file = DtoDwarfFile(sd->loc); // set diCompositeType to handle recursive types properly if (!ir->diCompositeType) ir->diCompositeType = gIR->dibuilder.createTemporaryType(); if (!ir->aggrdecl->isInterfaceDeclaration()) // plain interfaces don't have one { if (t->ty == Tstruct) { ArrayIter<VarDeclaration> 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); } } else { ClassDeclaration *classDecl = ir->aggrdecl->isClassDeclaration(); add_base_fields(classDecl, file, elems); if (classDecl->baseClass) derivedFrom = dwarfCompositeType(classDecl->baseClass->getType()); } } llvm::DIArray elemsArray = gIR->dibuilder.getOrCreateArray(elems); 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 ); } ir->diCompositeType.replaceAllUsesWith(ret); ir->diCompositeType = ret; return ret; }