/// addGlobalType - Add a new global type to the compile unit. /// void CompileUnit::addGlobalType(DIType Ty) { DIDescriptor Context = Ty.getContext(); if (Ty.isCompositeType() && !Ty.getName().empty() && !Ty.isForwardDecl() && (Context.isCompileUnit() || Context.isFile() || Context.isNameSpace())) if (DIEEntry *Entry = getDIEEntry(Ty)) GlobalTypes[Ty.getName()] = Entry->getEntry(); }
DICompositeType DIBuilder::createStructType(DIDescriptor Context, StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags, DIType DerivedFrom, DIArray Elements, unsigned RunTimeLang, DIType VTableHolder, StringRef UniqueIdentifier) { // TAG_structure_type is encoded in DICompositeType format. Value *Elts[] = { HeaderBuilder::get(dwarf::DW_TAG_structure_type) .concat(Name) .concat(LineNumber) .concat(SizeInBits) .concat(AlignInBits) .concat(0) .concat(Flags) .concat(RunTimeLang) .get(VMContext), File.getFileNode(), DIScope(getNonCompileUnitScope(Context)).getRef(), DerivedFrom.getRef(), Elements, VTableHolder.getRef(), nullptr, UniqueIdentifier.empty() ? nullptr : MDString::get(VMContext, UniqueIdentifier)}; DICompositeType R(MDNode::get(VMContext, Elts)); assert(R.isCompositeType() && "createStructType should return a DICompositeType"); if (!UniqueIdentifier.empty()) retainType(R); return R; }
/// EmitDeclare - Constructs the debug code for allocation of a new variable. /// region - "llvm.dbg.declare." void DebugInfo::EmitDeclare(tree decl, unsigned Tag, const char *Name, tree type, Value *AI, LLVMBuilder &Builder) { // Ignore compiler generated temporaries. if (DECL_IGNORED_P(decl)) return; assert(!RegionStack.empty() && "Region stack mismatch, stack empty!"); expanded_location Loc = GetNodeLocation(decl, false); // Construct variable. DIScope VarScope = DIScope(cast<MDNode>(RegionStack.back())); DIType Ty = getOrCreateType(type); if (DECL_ARTIFICIAL (decl)) Ty = DebugFactory.CreateArtificialType(Ty); // If type info is not available then do not emit debug info for this var. if (!Ty.getNode()) return; llvm::DIVariable D = DebugFactory.CreateVariable(Tag, VarScope, Name, getOrCreateFile(Loc.file), Loc.line, Ty, optimize); // Insert an llvm.dbg.declare into the current block. Instruction *Call = DebugFactory.InsertDeclare(AI, D, Builder.GetInsertBlock()); Call->setDebugLoc(DebugLoc::get(Loc.line, 0, VarScope.getNode())); }
void DebugInfoFinder::processType(DIType DT) { if (!addType(DT)) return; processScope(DT.getContext().resolve(TypeIdentifierMap)); if (DT.isCompositeType()) { DICompositeType DCT(DT); processType(DCT.getTypeDerivedFrom().resolve(TypeIdentifierMap)); if (DT.isSubroutineType()) { DITypeArray DTA = DISubroutineType(DT).getTypeArray(); for (unsigned i = 0, e = DTA.getNumElements(); i != e; ++i) processType(DTA.getElement(i).resolve(TypeIdentifierMap)); return; } DIArray DA = DCT.getElements(); for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) { DIDescriptor D = DA.getElement(i); if (D.isType()) processType(DIType(D)); else if (D.isSubprogram()) processSubprogram(DISubprogram(D)); } } else if (DT.isDerivedType()) { DIDerivedType DDT(DT); processType(DDT.getTypeDerivedFrom().resolve(TypeIdentifierMap)); } }
/// If this type is derived from a base type then return base type size. uint64_t DebugHandlerBase::getBaseTypeSize(const DITypeRef TyRef) { DIType *Ty = TyRef.resolve(); assert(Ty); DIDerivedType *DDTy = dyn_cast<DIDerivedType>(Ty); if (!DDTy) return Ty->getSizeInBits(); unsigned Tag = DDTy->getTag(); if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef && Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type && Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_atomic_type) return DDTy->getSizeInBits(); DIType *BaseType = DDTy->getBaseType().resolve(); assert(BaseType && "Unexpected invalid base type"); // If this is a derived type, go ahead and get the base type, unless it's a // reference then it's just the size of the field. Pointer types have no need // of this since they're a different type of qualification on the type. if (BaseType->getTag() == dwarf::DW_TAG_reference_type || BaseType->getTag() == dwarf::DW_TAG_rvalue_reference_type) return Ty->getSizeInBits(); return getBaseTypeSize(BaseType); }
DICompositeType DIBuilder::createClassType(DIDescriptor Context, StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, DIType DerivedFrom, DIArray Elements, DIType VTableHolder, MDNode *TemplateParams, StringRef UniqueIdentifier) { assert((!Context || Context.isScope() || Context.isType()) && "createClassType should be called with a valid Context"); // TAG_class_type is encoded in DICompositeType format. Value *Elts[] = { HeaderBuilder::get(dwarf::DW_TAG_class_type) .concat(Name) .concat(LineNumber) .concat(SizeInBits) .concat(AlignInBits) .concat(OffsetInBits) .concat(Flags) .concat(0) .get(VMContext), File.getFileNode(), DIScope(getNonCompileUnitScope(Context)).getRef(), DerivedFrom.getRef(), Elements, VTableHolder.getRef(), TemplateParams, UniqueIdentifier.empty() ? nullptr : MDString::get(VMContext, UniqueIdentifier)}; DICompositeType R(MDNode::get(VMContext, Elts)); assert(R.isCompositeType() && "createClassType should return a DICompositeType"); if (!UniqueIdentifier.empty()) retainType(R); return R; }
/// getOriginalTypeSize - If this type is derived from a base type then /// return base type size. uint64_t DIDerivedType::getOriginalTypeSize() const { unsigned Tag = getTag(); if (Tag == dwarf::DW_TAG_member || Tag == dwarf::DW_TAG_typedef || Tag == dwarf::DW_TAG_const_type || Tag == dwarf::DW_TAG_volatile_type || Tag == dwarf::DW_TAG_restrict_type) { DIType BaseType = getTypeDerivedFrom(); // If this type is not derived from any type then take conservative // approach. if (!BaseType.isValid()) return getSizeInBits(); // If this is a derived type, go ahead and get the base type, unless // it's a reference then it's just the size of the field. Pointer types // have no need of this since they're a different type of qualification // on the type. if (BaseType.getTag() == dwarf::DW_TAG_reference_type) return getSizeInBits(); else if (BaseType.isDerivedType()) return DIDerivedType(BaseType).getOriginalTypeSize(); else return BaseType.getSizeInBits(); } return getSizeInBits(); }
/// createVarinatType - Create variant type or return MainTy. DIType DebugInfo::createVariantType(tree type, DIType MainTy) { DIType Ty; if (tree TyDef = TYPE_NAME(type)) { std::map<tree_node *, WeakVH >::iterator I = TypeCache.find(TyDef); if (I != TypeCache.end()) if (Value *M = I->second) return DIType(cast<MDNode>(M)); if (TREE_CODE(TyDef) == TYPE_DECL && DECL_ORIGINAL_TYPE(TyDef)) { expanded_location TypeDefLoc = GetNodeLocation(TyDef); Ty = DebugFactory.CreateDerivedType(DW_TAG_typedef, findRegion(DECL_CONTEXT(TyDef)), GetNodeName(TyDef), getOrCreateFile(TypeDefLoc.file), TypeDefLoc.line, 0 /*size*/, 0 /*align*/, 0 /*offset */, 0 /*flags*/, MainTy); TypeCache[TyDef] = WeakVH(Ty.getNode()); return Ty; } } if (TYPE_VOLATILE(type)) { Ty = DebugFactory.CreateDerivedType(DW_TAG_volatile_type, findRegion(TYPE_CONTEXT(type)), StringRef(), getOrCreateFile(main_input_filename), 0 /*line no*/, NodeSizeInBits(type), NodeAlignInBits(type), 0 /*offset */, 0 /* flags */, MainTy); MainTy = Ty; } if (TYPE_READONLY(type)) Ty = DebugFactory.CreateDerivedType(DW_TAG_const_type, findRegion(TYPE_CONTEXT(type)), StringRef(), getOrCreateFile(main_input_filename), 0 /*line no*/, NodeSizeInBits(type), NodeAlignInBits(type), 0 /*offset */, 0 /* flags */, MainTy); if (TYPE_VOLATILE(type) || TYPE_READONLY(type)) { TypeCache[type] = WeakVH(Ty.getNode()); return Ty; } // If, for some reason, main type varaint type is seen then use it. return MainTy; }
/// getDICompositeType - Find underlying composite type. DICompositeType llvm::getDICompositeType(DIType T) { if (T.isCompositeType()) return DICompositeType(T); if (T.isDerivedType()) return getDICompositeType(DIDerivedType(T).getTypeDerivedFrom()); return DICompositeType(); }
void DIEItem::FormatDIType(wxTextOutputStream& out, DIType type) const { if (type.isCompositeType()) { DICompositeType diCompType(type); if (!type.getName().empty()) { out << toWxStr(type.getName()); } else { out << _("?Implement unnamed composite"); // TODO: Implement: // DW_TAG_array_type // DW_TAG_enumeration_type // DW_TAG_structure_type // DW_TAG_union_type // DW_TAG_vector_type // DW_TAG_subroutine_type // DW_TAG_inheritance } } else if (type.isDerivedType()) { DIDerivedType diDerivedType(type); DIType diBase = diDerivedType.getTypeDerivedFrom(); switch (diDerivedType.getTag()) { case dwarf::DW_TAG_inheritance: FormatDIType(out, diBase); break; case dwarf::DW_TAG_pointer_type: FormatDIType(out, diBase); out << _("*"); break; case dwarf::DW_TAG_array_type: FormatDIType(out, diBase); // TODO: Get the array size, use LLVM array notation. out << _("[]"); break; case dwarf::DW_TAG_member: out << toWxStr(diDerivedType.getName()); break; case dwarf::DW_TAG_reference_type: case dwarf::DW_TAG_const_type: case dwarf::DW_TAG_volatile_type: case dwarf::DW_TAG_restrict_type: case dwarf::DW_TAG_typedef: // TODO: Implement break; } } else if (type.isBasicType()) { DIBasicType diBasicType(type); const char * encodingName = dwarf::AttributeEncodingString(diBasicType.getEncoding()); if (encodingName != NULL) { out << toWxStr(encodingName); } } }
/// Verify - Verify that an ObjC property is well formed. bool DIObjCProperty::Verify() const { if (!isObjCProperty()) return false; DIType Ty = getType(); if (!Ty.Verify()) return false; // Don't worry about the rest of the strings for now. return DbgNode->getNumOperands() == 8; }
/// addType - Add type into Tys. bool DebugInfoFinder::addType(DIType DT) { if (DT.isNull()) return false; if (!NodesSeen.insert(DT.getNode())) return false; TYs.push_back(DT.getNode()); return true; }
/// Verify - Verify that an ObjC property is well formed. bool DIObjCProperty::Verify() const { if (!DbgNode) return false; unsigned Tag = getTag(); if (Tag != dwarf::DW_TAG_APPLE_property) return false; DIType Ty = getType(); if (!Ty.Verify()) return false; // Don't worry about the rest of the strings for now. return true; }
/// \brief Return the size reported by the variable's type. unsigned DIVariable::getSizeInBits(const DITypeIdentifierMap &Map) { DIType Ty = getType().resolve(Map); // Follow derived types until we reach a type that // reports back a size. while (Ty.isDerivedType() && !Ty.getSizeInBits()) { DIDerivedType DT(&*Ty); Ty = DT.getTypeDerivedFrom().resolve(Map); } assert(Ty.getSizeInBits() && "type with size 0"); return Ty.getSizeInBits(); }
static bool getLocationInfo(const Value *V, std::string &DisplayName, std::string &Type, unsigned &LineNo, std::string &File, std::string &Dir) { DICompileUnit Unit; DIType TypeD; if (GlobalVariable *GV = dyn_cast<GlobalVariable>(const_cast<Value*>(V))) { Value *DIGV = findDbgGlobalDeclare(GV); if (!DIGV) return false; DIGlobalVariable Var(cast<MDNode>(DIGV)); StringRef D = Var.getDisplayName(); if (!D.empty()) DisplayName = D; LineNo = Var.getLineNumber(); Unit = Var.getCompileUnit(); TypeD = Var.getType(); } else if (Function *F = dyn_cast<Function>(const_cast<Value*>(V))){ Value *DIF = findDbgSubprogramDeclare(F); if (!DIF) return false; DISubprogram Var(cast<MDNode>(DIF)); StringRef D = Var.getDisplayName(); if (!D.empty()) DisplayName = D; LineNo = Var.getLineNumber(); Unit = Var.getCompileUnit(); TypeD = Var.getType(); } else { const DbgDeclareInst *DDI = findDbgDeclare(V); if (!DDI) return false; DIVariable Var(cast<MDNode>(DDI->getVariable())); StringRef D = Var.getName(); if (!D.empty()) DisplayName = D; LineNo = Var.getLineNumber(); Unit = Var.getCompileUnit(); TypeD = Var.getType(); } StringRef T = TypeD.getName(); if (!T.empty()) Type = T; StringRef F = Unit.getFilename(); if (!F.empty()) File = F; StringRef D = Unit.getDirectory(); if (!D.empty()) Dir = D; return true; }
/// Verify - Verify that a variable descriptor is well formed. bool DIVariable::Verify() const { if (isNull()) return false; if (getContext().isNull()) return false; DIType Ty = getType(); if (!Ty.Verify()) return false; return true; }
/// Verify - Verify that a variable descriptor is well formed. bool DIVariable::Verify() const { if (!DbgNode) return false; if (getContext() && !getContext().Verify()) return false; DIType Ty = getType(); if (!Ty.Verify()) return false; return true; }
/// addSourceLine - Add location information to specified debug information /// entry. void CompileUnit::addSourceLine(DIE *Die, DIType Ty) { // Verify type. if (!Ty.Verify()) return; unsigned Line = Ty.getLineNumber(); if (Line == 0 || !Ty.getContext().Verify()) return; unsigned FileID = DD->GetOrCreateSourceID(Ty.getFilename(), Ty.getDirectory()); assert(FileID && "Invalid file id"); addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); }
/// Verify - Verify that a variable descriptor is well formed. bool DIVariable::Verify() const { if (!isVariable()) return false; if (getContext() && !getContext().Verify()) return false; DIType Ty = getType(); if (!Ty.Verify()) return false; return DbgNode->getNumOperands() >= 8; }
/// PopulateDebugInfo - Populate the TypeNo, Aux[] and TagName from Ty. /// void PIC16DbgInfo::PopulateDebugInfo (DIType Ty, unsigned short &TypeNo, bool &HasAux, int Aux[], std::string &TagName) { if (Ty.isBasicType()) PopulateBasicTypeInfo (Ty, TypeNo); else if (Ty.isCompositeType()) PopulateCompositeTypeInfo (Ty, TypeNo, HasAux, Aux, TagName); else if (Ty.isDerivedType()) PopulateDerivedTypeInfo (Ty, TypeNo, HasAux, Aux, TagName); else { TypeNo = PIC16Dbg::T_NULL; HasAux = false; } return; }
DICompositeType llvm::getDICompositeType(DIType T) { if (T.isCompositeType()) return DICompositeType(T); if (T.isDerivedType()) { // This function is currently used by dragonegg and dragonegg does // not generate identifier for types, so using an empty map to resolve // DerivedFrom should be fine. DITypeIdentifierMap EmptyMap; return getDICompositeType( DIDerivedType(T).getTypeDerivedFrom().resolve(EmptyMap)); } return DICompositeType(); }
DIDerivedType DIBuilder::createFriend(DIType Ty, DIType FriendTy) { // typedefs are encoded in DIDerivedType format. assert(Ty.isType() && "Invalid type!"); assert(FriendTy.isType() && "Invalid friend type!"); Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_friend) .concat(StringRef()) // Name .concat(0) // Line .concat(0) // Size .concat(0) // Align .concat(0) // Offset .concat(0) // Flags .get(VMContext), nullptr, Ty.getRef(), FriendTy.getRef()}; return DIDerivedType(MDNode::get(VMContext, Elts)); }
DIType DebugInfo::getDoubleTy() { if (DblTy.isValid()) return DblTy; DblTy = DBuilder->createBasicType("double", 64, 64, dwarf::DW_ATE_float); return DblTy; }
/// PopulateBasicTypeInfo- Populate TypeNo for basic type from Ty. /// void PIC16DbgInfo::PopulateBasicTypeInfo (DIType Ty, unsigned short &TypeNo) { std::string Name = ""; Ty.getName(Name); unsigned short BaseTy = GetTypeDebugNumber(Name); TypeNo = TypeNo << PIC16Dbg::S_BASIC; TypeNo = TypeNo | (0xffff & BaseTy); }
DIDerivedType DIBuilder::createMemberPointerType(DIType PointeeTy, DIType Base) { // Pointer types are encoded in DIDerivedType format. Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_ptr_to_member_type) .concat(StringRef()) .concat(0) // Line .concat(0) // Size .concat(0) // Align .concat(0) // Offset .concat(0) // Flags .get(VMContext), nullptr, // Filename nullptr, // Unused PointeeTy.getRef(), Base.getRef()}; return DIDerivedType(MDNode::get(VMContext, Elts)); }
/// CreateGlobalVariable - Create a new descriptor for the specified global. DIGlobalVariable DIFactory::CreateGlobalVariable(DIDescriptor Context, const char * Name, const char * DisplayName, const char * LinkageName, DICompileUnit CompileUnit, unsigned LineNo, DIType Type,bool isLocalToUnit, bool isDefinition, llvm::GlobalVariable *Val) { Value *Elts[] = { GetTagConstant(dwarf::DW_TAG_variable), llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), Context.getNode(), MDString::get(VMContext, Name), MDString::get(VMContext, DisplayName), MDString::get(VMContext, LinkageName), CompileUnit.getNode(), ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), Type.getNode(), ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit), ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition), Val }; Value *const *Vs = &Elts[0]; MDNode *Node = MDNode::get(VMContext,Vs, 12); // Create a named metadata so that we do not lose this mdnode. NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.gv"); NMD->addElement(Node); return DIGlobalVariable(Node); }
DICompositeType DIBuilder::createEnumerationType( DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, DIArray Elements, DIType UnderlyingType, StringRef UniqueIdentifier) { // TAG_enumeration_type is encoded in DICompositeType format. Value *Elts[] = { HeaderBuilder::get(dwarf::DW_TAG_enumeration_type) .concat(Name) .concat(LineNumber) .concat(SizeInBits) .concat(AlignInBits) .concat(0) // Offset .concat(0) // Flags .concat(0) .get(VMContext), File.getFileNode(), DIScope(getNonCompileUnitScope(Scope)).getRef(), UnderlyingType.getRef(), Elements, nullptr, nullptr, UniqueIdentifier.empty() ? nullptr : MDString::get(VMContext, UniqueIdentifier)}; DICompositeType CTy(MDNode::get(VMContext, Elts)); AllEnumTypes.push_back(CTy); if (!UniqueIdentifier.empty()) retainType(CTy); return CTy; }
DIDerivedType DIBuilder::createReferenceType(unsigned Tag, DIType RTy) { assert(RTy.isType() && "Unable to create reference type"); // References are encoded in DIDerivedType format. Value *Elts[] = {HeaderBuilder::get(Tag) .concat(StringRef()) // Name .concat(0) // Line .concat(0) // Size .concat(0) // Align .concat(0) // Offset .concat(0) // Flags .get(VMContext), nullptr, // Filename nullptr, // TheCU, RTy.getRef()}; return DIDerivedType(MDNode::get(VMContext, Elts)); }
/// CreateCompositeType - Create a composite type like array, struct, etc. DICompositeType DIFactory::CreateCompositeTypeEx(unsigned Tag, DIDescriptor Context, const char * Name, DICompileUnit CompileUnit, unsigned LineNumber, Constant *SizeInBits, Constant *AlignInBits, Constant *OffsetInBits, unsigned Flags, DIType DerivedFrom, DIArray Elements, unsigned RuntimeLang) { Value *Elts[] = { GetTagConstant(Tag), Context.getNode(), MDString::get(VMContext, Name), CompileUnit.getNode(), ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), SizeInBits, AlignInBits, OffsetInBits, ConstantInt::get(Type::getInt32Ty(VMContext), Flags), DerivedFrom.getNode(), Elements.getNode(), ConstantInt::get(Type::getInt32Ty(VMContext), RuntimeLang) }; return DICompositeType(MDNode::get(VMContext, &Elts[0], 12)); }
DIDerivedType DIBuilder::createInheritance(DIType Ty, DIType BaseTy, uint64_t BaseOffset, unsigned Flags) { assert(Ty.isType() && "Unable to create inheritance"); // TAG_inheritance is encoded in DIDerivedType format. Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_inheritance) .concat(StringRef()) // Name .concat(0) // Line .concat(0) // Size .concat(0) // Align .concat(BaseOffset) .concat(Flags) .get(VMContext), nullptr, Ty.getRef(), BaseTy.getRef()}; return DIDerivedType(MDNode::get(VMContext, Elts)); }