llvm::DIType ldc::DIBuilder::CreateCompositeType(Type *type) { Type* t = type->toBasetype(); assert((t->ty == Tstruct || t->ty == Tclass) && "Unsupported type for debug info in DIBuilder::CreateCompositeType"); AggregateDeclaration* sd; if (t->ty == Tstruct) { TypeStruct* ts = static_cast<TypeStruct*>(t); sd = ts->sym; } else { TypeClass* tc = static_cast<TypeClass*>(t); sd = tc->sym; } assert(sd); // Use the actual type associated with the declaration, ignoring any // const/… wrappers. LLType *T = DtoType(sd->type); IrTypeAggr *ir = sd->type->irtype->isAggr(); assert(ir); if (static_cast<llvm::MDNode *>(ir->diCompositeType) != 0) return ir->diCompositeType; // 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) #if LDC_LLVM_VER >= 304 return DBuilder.createUnspecifiedType(sd->toChars()); #else return llvm::DICompositeType(NULL); #endif // elements std::vector<llvm::Value *> elems; // defaults llvm::StringRef name = sd->toChars(); unsigned linnum = sd->loc.linnum; llvm::DICompileUnit CU(GetCU()); assert(CU && CU.Verify() && "Compilation unit missing or corrupted"); llvm::DIFile file = CreateFile(sd->loc); llvm::DIType derivedFrom; // set diCompositeType to handle recursive types properly unsigned tag = (t->ty == Tstruct) ? llvm::dwarf::DW_TAG_structure_type : llvm::dwarf::DW_TAG_class_type; ir->diCompositeType = DBuilder.createForwardDecl(tag, name, #if LDC_LLVM_VER >= 302 CU, #endif file, linnum); if (!sd->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 = CreateMemberType(vd->loc.linnum, vd->type, file, vd->toChars(), vd->offset); elems.push_back(dt); } } else { ClassDeclaration *classDecl = sd->isClassDeclaration(); AddBaseFields(classDecl, file, elems); if (classDecl->baseClass) derivedFrom = CreateCompositeType(classDecl->baseClass->getType()); } } llvm::DIArray elemsArray = DBuilder.getOrCreateArray(elems); llvm::DIType ret; if (t->ty == Tclass) { ret = DBuilder.createClassType( CU, // compile unit where defined name, // name file, // file 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 = DBuilder.createStructType( CU, // compile unit where defined name, // name file, // file where defined linnum, // line number where defined getTypeBitSize(T), // size in bits getABITypeAlign(T)*8, // alignment in bits llvm::DIType::FlagFwdDecl, // flags #if LDC_LLVM_VER >= 303 derivedFrom, // DerivedFrom #endif elemsArray ); } ir->diCompositeType.replaceAllUsesWith(ret); ir->diCompositeType = ret; return ret; }
ldc::DIType ldc::DIBuilder::CreateCompositeType(Type *type) { Type *t = type->toBasetype(); assert((t->ty == Tstruct || t->ty == Tclass) && "Unsupported type for debug info in DIBuilder::CreateCompositeType"); AggregateDeclaration *sd; if (t->ty == Tstruct) { TypeStruct *ts = static_cast<TypeStruct *>(t); sd = ts->sym; } else { TypeClass *tc = static_cast<TypeClass *>(t); sd = tc->sym; } assert(sd); // Use the actual type associated with the declaration, ignoring any // const/wrappers. LLType *T = DtoType(sd->type); IrTypeAggr *ir = sd->type->ctype->isAggr(); assert(ir); if (static_cast<llvm::MDNode *>(ir->diCompositeType) != nullptr) { return ir->diCompositeType; } // 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 == SIZEOKnone) { return DBuilder.createUnspecifiedType(sd->toChars()); } // elements llvm::SmallVector<LLMetadata *, 16> elems; // defaults llvm::StringRef name = sd->toChars(); unsigned linnum = sd->loc.linnum; ldc::DICompileUnit CU(GetCU()); assert(CU && "Compilation unit missing or corrupted"); ldc::DIFile file = CreateFile(sd); ldc::DIType derivedFrom = getNullDIType(); // set diCompositeType to handle recursive types properly unsigned tag = (t->ty == Tstruct) ? llvm::dwarf::DW_TAG_structure_type : llvm::dwarf::DW_TAG_class_type; #if LDC_LLVM_VER >= 307 ir->diCompositeType = DBuilder.createReplaceableCompositeType( #else ir->diCompositeType = DBuilder.createReplaceableForwardDecl( #endif tag, name, CU, file, linnum); if (!sd->isInterfaceDeclaration()) // plain interfaces don't have one { ClassDeclaration *classDecl = sd->isClassDeclaration(); if (classDecl && classDecl->baseClass) { derivedFrom = CreateCompositeType(classDecl->baseClass->getType()); // needs a forward declaration to add inheritence information to elems ldc::DIType fwd = DBuilder.createClassType(CU, // compile unit where defined name, // name file, // file where defined linnum, // line number where defined getTypeAllocSize(T) * 8, // size in bits getABITypeAlign(T) * 8, // alignment in bits 0, // offset in bits, DIFlags::FlagFwdDecl, // flags derivedFrom, // DerivedFrom getEmptyDINodeArray(), getNullDIType(), // VTableHolder nullptr, // TemplateParms uniqueIdent(t)); // UniqueIdentifier auto dt = DBuilder.createInheritance(fwd, derivedFrom, 0, #if LDC_LLVM_VER >= 306 DIFlags::FlagPublic #else 0 #endif ); elems.push_back(dt); } AddFields(sd, file, elems); } auto elemsArray = DBuilder.getOrCreateArray(elems); ldc::DIType ret; if (t->ty == Tclass) { ret = DBuilder.createClassType(CU, // compile unit where defined name, // name file, // file where defined linnum, // line number where defined getTypeAllocSize(T) * 8, // size in bits getABITypeAlign(T) * 8, // alignment in bits 0, // offset in bits, DIFlagZero, // flags derivedFrom, // DerivedFrom elemsArray, getNullDIType(), // VTableHolder nullptr, // TemplateParms uniqueIdent(t)); // UniqueIdentifier } else { ret = DBuilder.createStructType(CU, // compile unit where defined name, // name file, // file where defined linnum, // line number where defined getTypeAllocSize(T) * 8, // size in bits getABITypeAlign(T) * 8, // alignment in bits DIFlagZero, // flags derivedFrom, // DerivedFrom elemsArray, 0, // RunTimeLang getNullDIType(), // VTableHolder uniqueIdent(t)); // UniqueIdentifier } #if LDC_LLVM_VER >= 307 ir->diCompositeType = DBuilder.replaceTemporary( llvm::TempDINode(ir->diCompositeType), static_cast<llvm::DIType *>(ret)); #else ir->diCompositeType.replaceAllUsesWith(ret); #endif ir->diCompositeType = ret; return ret; }