/// 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); }
/// constructTypeDIE - Construct derived type die from DIDerivedType. void CompileUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) { // Get core information. StringRef Name = DTy.getName(); uint64_t Size = DTy.getSizeInBits() >> 3; unsigned Tag = DTy.getTag(); // FIXME - Workaround for templates. if (Tag == dwarf::DW_TAG_inheritance) Tag = dwarf::DW_TAG_reference_type; Buffer.setTag(Tag); // Map to main type, void will not have a type. DIType FromTy = DTy.getTypeDerivedFrom(); addType(&Buffer, FromTy); // Add name if not anonymous or intermediate type. if (!Name.empty()) addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); // Add size if non-zero (derived types might be zero-sized.) if (Size) addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size); // Add source line info if available and TyDesc is not a forward declaration. if (!DTy.isForwardDecl()) addSourceLine(&Buffer, DTy); }
/// \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 (isa<MDDerivedType>(Ty) && !Ty.getSizeInBits()) { DIDerivedType DT = cast<MDDerivedType>(Ty); Ty = DT.getTypeDerivedFrom().resolve(Map); } assert(Ty.getSizeInBits() && "type with size 0"); return Ty.getSizeInBits(); }
/// print - Print type. void DIType::print(raw_ostream &OS) const { if (!DbgNode) return; StringRef Res = getName(); if (!Res.empty()) OS << " [" << Res << "] "; unsigned Tag = getTag(); OS << " [" << dwarf::TagString(Tag) << "] "; // TODO : Print context OS << " [" << "line " << getLineNumber() << ", " << getSizeInBits() << " bits, " << getAlignInBits() << " bit alignment, " << getOffsetInBits() << " bit offset" << "] "; if (isPrivate()) OS << " [private] "; else if (isProtected()) OS << " [protected] "; if (isForwardDecl()) OS << " [fwd] "; if (isBasicType()) DIBasicType(DbgNode).print(OS); else if (isDerivedType()) { DIDerivedType DTy = DIDerivedType(DbgNode); DTy.print(OS); DICompositeType CTy = getDICompositeType(DTy); if (CTy.Verify()) CTy.print(OS); } else if (isCompositeType()) DICompositeType(DbgNode).print(OS); else { OS << "Invalid DIType\n"; return; } OS << "\n"; }
BitFieldAggregation *BitFieldAggregation::getBitFieldAggregation(TYPECONST Type *type, const EDIType *aEDIType, bool returnOnError, unsigned typeIndex, unsigned EDITypeIndex, unsigned lastTypeIndex, unsigned lastEDITypeIndex, unsigned counter) { static BitFieldAggregation bfa; TYPECONST Type *containedType = type->getContainedType(typeIndex); unsigned typeBits = TypeUtil::typeToBits(containedType); assert(typeBits > 0); unsigned nextTypeBits = 0; if (typeIndex < lastTypeIndex) { nextTypeBits = TypeUtil::typeToBits(type->getContainedType(typeIndex+1)); } const int maxNumMembers = (lastEDITypeIndex - EDITypeIndex) - (lastTypeIndex - typeIndex) + 1; unsigned index = EDITypeIndex; std::vector<DIDerivedType> members; std::vector<EDIType> containedEDITypes; BitFieldAggregation_assert_or_return(returnOnError, NULL, type, aEDIType, maxNumMembers > 0); #if DEBUG_BFA BitFieldAggregationErr("getBitFieldAggregation(): typeIndex = " << typeIndex << ", EDITypeIndex = " << EDITypeIndex << ", maxNumMembers = " << maxNumMembers); BitFieldAggregationErr("getBitFieldAggregation(): lastTypeIndex = " << lastTypeIndex << ", lastEDITypeIndex = " << lastEDITypeIndex); BitFieldAggregationErr("getBitFieldAggregation(): " << TypeUtil::getDescription(type) << " VS " << TypeUtil::getDescription(aEDIType)); #endif while(index <= lastEDITypeIndex && members.size() < (unsigned)maxNumMembers) { const EDIType containedEDIType = aEDIType->getContainedType(index); #if DEBUG_BFA BitFieldAggregationErr("Examining type " << TypeUtil::getDescription(&containedEDIType)); #endif BitFieldAggregation_assert_or_return(returnOnError, NULL, type, aEDIType, containedEDIType.isIntegerTy()); DIDerivedType member = aEDIType->getMember(index); unsigned EDITypeBits = member.getSizeInBits(); #if DEBUG_BFA BitFieldAggregationErr("Type bits = " << typeBits << ", next type bits = " << nextTypeBits << ", index = " << index); BitFieldAggregationErr("This is member " << member.getName() << " with bits " << EDITypeBits); #endif if((index > EDITypeIndex && EDITypeBits == nextTypeBits) || EDITypeBits > typeBits) { break; } typeBits -= EDITypeBits; members.push_back(member); containedEDITypes.push_back(containedEDIType); index++; } bfa.init(containedType, containedEDITypes, typeIndex, EDITypeIndex, members, counter); return &bfa; }
/// addBlockByrefAddress - Start with the address based on the location /// provided, and generate the DWARF information necessary to find the /// actual Block variable (navigating the Block struct) based on the /// starting location. Add the DWARF information to the die. For /// more information, read large comment just above here. /// void CompileUnit::addBlockByrefAddress(DbgVariable *&DV, DIE *Die, unsigned Attribute, const MachineLocation &Location) { DIType Ty = DV->getType(); DIType TmpTy = Ty; unsigned Tag = Ty.getTag(); bool isPointer = false; StringRef varName = DV->getName(); if (Tag == dwarf::DW_TAG_pointer_type) { DIDerivedType DTy = DIDerivedType(Ty); TmpTy = DTy.getTypeDerivedFrom(); isPointer = true; } DICompositeType blockStruct = DICompositeType(TmpTy); // Find the __forwarding field and the variable field in the __Block_byref // struct. DIArray Fields = blockStruct.getTypeArray(); DIDescriptor varField = DIDescriptor(); DIDescriptor forwardingField = DIDescriptor(); for (unsigned i = 0, N = Fields.getNumElements(); i < N; ++i) { DIDescriptor Element = Fields.getElement(i); DIDerivedType DT = DIDerivedType(Element); StringRef fieldName = DT.getName(); if (fieldName == "__forwarding") forwardingField = Element; else if (fieldName == varName) varField = Element; } // Get the offsets for the forwarding field and the variable field. unsigned forwardingFieldOffset = DIDerivedType(forwardingField).getOffsetInBits() >> 3; unsigned varFieldOffset = DIDerivedType(varField).getOffsetInBits() >> 3; // Decode the original location, and use that as the start of the byref // variable's location. const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false); DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); if (Location.isReg()) { if (Reg < 32) addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg); else { addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx); addUInt(Block, 0, dwarf::DW_FORM_udata, Reg); } } else { if (Reg < 32) addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg); else { addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx); addUInt(Block, 0, dwarf::DW_FORM_udata, Reg); } addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset()); } // If we started with a pointer to the __Block_byref... struct, then // the first thing we need to do is dereference the pointer (DW_OP_deref). if (isPointer) addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); // Next add the offset for the '__forwarding' field: // DW_OP_plus_uconst ForwardingFieldOffset. Note there's no point in // adding the offset if it's 0. if (forwardingFieldOffset > 0) { addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); addUInt(Block, 0, dwarf::DW_FORM_udata, forwardingFieldOffset); } // Now dereference the __forwarding field to get to the real __Block_byref // struct: DW_OP_deref. addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); // Now that we've got the real __Block_byref... struct, add the offset // for the variable's field to get to the location of the actual variable: // DW_OP_plus_uconst varFieldOffset. Again, don't add if it's 0. if (varFieldOffset > 0) { addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); addUInt(Block, 0, dwarf::DW_FORM_udata, varFieldOffset); } // Now attach the location information to the DIE. addBlock(Die, Attribute, 0, Block); }