DwarfCompileUnit.cpp revision 229042
1221337Sdim//===-- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Unit ------------===// 2221337Sdim// 3221337Sdim// The LLVM Compiler Infrastructure 4221337Sdim// 5221337Sdim// This file is distributed under the University of Illinois Open Source 6221337Sdim// License. See LICENSE.TXT for details. 7221337Sdim// 8221337Sdim//===----------------------------------------------------------------------===// 9221337Sdim// 10221337Sdim// This file contains support for writing dwarf compile unit. 11221337Sdim// 12221337Sdim//===----------------------------------------------------------------------===// 13221337Sdim 14221337Sdim#define DEBUG_TYPE "dwarfdebug" 15221337Sdim 16221337Sdim#include "DwarfCompileUnit.h" 17221337Sdim#include "DwarfDebug.h" 18221337Sdim#include "llvm/Constants.h" 19226890Sdim#include "llvm/GlobalVariable.h" 20226890Sdim#include "llvm/Instructions.h" 21221337Sdim#include "llvm/Analysis/DIBuilder.h" 22226890Sdim#include "llvm/Target/Mangler.h" 23221337Sdim#include "llvm/Target/TargetData.h" 24221337Sdim#include "llvm/Target/TargetFrameLowering.h" 25221337Sdim#include "llvm/Target/TargetMachine.h" 26221337Sdim#include "llvm/Target/TargetRegisterInfo.h" 27221337Sdim#include "llvm/ADT/APFloat.h" 28221337Sdim#include "llvm/Support/ErrorHandling.h" 29221337Sdim 30221337Sdimusing namespace llvm; 31221337Sdim 32221337Sdim/// CompileUnit - Compile unit constructor. 33221337SdimCompileUnit::CompileUnit(unsigned I, DIE *D, AsmPrinter *A, DwarfDebug *DW) 34221337Sdim : ID(I), CUDie(D), Asm(A), DD(DW), IndexTyDie(0) { 35221337Sdim DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1); 36221337Sdim} 37221337Sdim 38221337Sdim/// ~CompileUnit - Destructor for compile unit. 39221337SdimCompileUnit::~CompileUnit() { 40221337Sdim for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j) 41221337Sdim DIEBlocks[j]->~DIEBlock(); 42221337Sdim} 43221337Sdim 44221337Sdim/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug 45221337Sdim/// information entry. 46221337SdimDIEEntry *CompileUnit::createDIEEntry(DIE *Entry) { 47221337Sdim DIEEntry *Value = new (DIEValueAllocator) DIEEntry(Entry); 48221337Sdim return Value; 49221337Sdim} 50221337Sdim 51221337Sdim/// addUInt - Add an unsigned integer attribute data and value. 52221337Sdim/// 53221337Sdimvoid CompileUnit::addUInt(DIE *Die, unsigned Attribute, 54221337Sdim unsigned Form, uint64_t Integer) { 55221337Sdim if (!Form) Form = DIEInteger::BestForm(false, Integer); 56221337Sdim DIEValue *Value = Integer == 1 ? 57221337Sdim DIEIntegerOne : new (DIEValueAllocator) DIEInteger(Integer); 58221337Sdim Die->addValue(Attribute, Form, Value); 59221337Sdim} 60221337Sdim 61221337Sdim/// addSInt - Add an signed integer attribute data and value. 62221337Sdim/// 63221337Sdimvoid CompileUnit::addSInt(DIE *Die, unsigned Attribute, 64221337Sdim unsigned Form, int64_t Integer) { 65221337Sdim if (!Form) Form = DIEInteger::BestForm(true, Integer); 66221337Sdim DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer); 67221337Sdim Die->addValue(Attribute, Form, Value); 68221337Sdim} 69221337Sdim 70221337Sdim/// addString - Add a string attribute data and value. DIEString only 71221337Sdim/// keeps string reference. 72221337Sdimvoid CompileUnit::addString(DIE *Die, unsigned Attribute, unsigned Form, 73221337Sdim StringRef String) { 74221337Sdim DIEValue *Value = new (DIEValueAllocator) DIEString(String); 75221337Sdim Die->addValue(Attribute, Form, Value); 76221337Sdim} 77221337Sdim 78221337Sdim/// addLabel - Add a Dwarf label attribute data and value. 79221337Sdim/// 80221337Sdimvoid CompileUnit::addLabel(DIE *Die, unsigned Attribute, unsigned Form, 81221337Sdim const MCSymbol *Label) { 82221337Sdim DIEValue *Value = new (DIEValueAllocator) DIELabel(Label); 83221337Sdim Die->addValue(Attribute, Form, Value); 84221337Sdim} 85221337Sdim 86221337Sdim/// addDelta - Add a label delta attribute data and value. 87221337Sdim/// 88221337Sdimvoid CompileUnit::addDelta(DIE *Die, unsigned Attribute, unsigned Form, 89221337Sdim const MCSymbol *Hi, const MCSymbol *Lo) { 90221337Sdim DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo); 91221337Sdim Die->addValue(Attribute, Form, Value); 92221337Sdim} 93221337Sdim 94221337Sdim/// addDIEEntry - Add a DIE attribute data and value. 95221337Sdim/// 96221337Sdimvoid CompileUnit::addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form, 97221337Sdim DIE *Entry) { 98221337Sdim Die->addValue(Attribute, Form, createDIEEntry(Entry)); 99221337Sdim} 100221337Sdim 101221337Sdim 102221337Sdim/// addBlock - Add block data. 103221337Sdim/// 104221337Sdimvoid CompileUnit::addBlock(DIE *Die, unsigned Attribute, unsigned Form, 105221337Sdim DIEBlock *Block) { 106221337Sdim Block->ComputeSize(Asm); 107221337Sdim DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on. 108221337Sdim Die->addValue(Attribute, Block->BestForm(), Block); 109221337Sdim} 110221337Sdim 111221337Sdim/// addSourceLine - Add location information to specified debug information 112221337Sdim/// entry. 113221337Sdimvoid CompileUnit::addSourceLine(DIE *Die, DIVariable V) { 114221337Sdim // Verify variable. 115221337Sdim if (!V.Verify()) 116221337Sdim return; 117221337Sdim 118221337Sdim unsigned Line = V.getLineNumber(); 119221337Sdim if (Line == 0) 120221337Sdim return; 121221337Sdim unsigned FileID = DD->GetOrCreateSourceID(V.getContext().getFilename(), 122221337Sdim V.getContext().getDirectory()); 123221337Sdim assert(FileID && "Invalid file id"); 124221337Sdim addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); 125221337Sdim addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); 126221337Sdim} 127221337Sdim 128221337Sdim/// addSourceLine - Add location information to specified debug information 129221337Sdim/// entry. 130221337Sdimvoid CompileUnit::addSourceLine(DIE *Die, DIGlobalVariable G) { 131221337Sdim // Verify global variable. 132221337Sdim if (!G.Verify()) 133221337Sdim return; 134221337Sdim 135221337Sdim unsigned Line = G.getLineNumber(); 136221337Sdim if (Line == 0) 137221337Sdim return; 138226890Sdim unsigned FileID = DD->GetOrCreateSourceID(G.getFilename(), 139226890Sdim G.getDirectory()); 140221337Sdim assert(FileID && "Invalid file id"); 141221337Sdim addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); 142221337Sdim addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); 143221337Sdim} 144221337Sdim 145221337Sdim/// addSourceLine - Add location information to specified debug information 146221337Sdim/// entry. 147221337Sdimvoid CompileUnit::addSourceLine(DIE *Die, DISubprogram SP) { 148221337Sdim // Verify subprogram. 149221337Sdim if (!SP.Verify()) 150221337Sdim return; 151221337Sdim // If the line number is 0, don't add it. 152221337Sdim if (SP.getLineNumber() == 0) 153221337Sdim return; 154221337Sdim 155221337Sdim unsigned Line = SP.getLineNumber(); 156221337Sdim if (!SP.getContext().Verify()) 157221337Sdim return; 158221337Sdim unsigned FileID = DD->GetOrCreateSourceID(SP.getFilename(), SP.getDirectory()); 159221337Sdim assert(FileID && "Invalid file id"); 160221337Sdim addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); 161221337Sdim addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); 162221337Sdim} 163221337Sdim 164221337Sdim/// addSourceLine - Add location information to specified debug information 165221337Sdim/// entry. 166221337Sdimvoid CompileUnit::addSourceLine(DIE *Die, DIType Ty) { 167221337Sdim // Verify type. 168221337Sdim if (!Ty.Verify()) 169221337Sdim return; 170221337Sdim 171221337Sdim unsigned Line = Ty.getLineNumber(); 172221337Sdim if (Line == 0 || !Ty.getContext().Verify()) 173221337Sdim return; 174221337Sdim unsigned FileID = DD->GetOrCreateSourceID(Ty.getFilename(), Ty.getDirectory()); 175221337Sdim assert(FileID && "Invalid file id"); 176221337Sdim addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); 177221337Sdim addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); 178221337Sdim} 179221337Sdim 180221337Sdim/// addSourceLine - Add location information to specified debug information 181221337Sdim/// entry. 182221337Sdimvoid CompileUnit::addSourceLine(DIE *Die, DINameSpace NS) { 183221337Sdim // Verify namespace. 184221337Sdim if (!NS.Verify()) 185221337Sdim return; 186221337Sdim 187221337Sdim unsigned Line = NS.getLineNumber(); 188221337Sdim if (Line == 0) 189221337Sdim return; 190221337Sdim StringRef FN = NS.getFilename(); 191221337Sdim 192221337Sdim unsigned FileID = DD->GetOrCreateSourceID(FN, NS.getDirectory()); 193221337Sdim assert(FileID && "Invalid file id"); 194221337Sdim addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); 195221337Sdim addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); 196221337Sdim} 197221337Sdim 198221337Sdim/// addVariableAddress - Add DW_AT_location attribute for a 199221337Sdim/// DbgVariable based on provided MachineLocation. 200221337Sdimvoid CompileUnit::addVariableAddress(DbgVariable *&DV, DIE *Die, 201221337Sdim MachineLocation Location) { 202221337Sdim if (DV->variableHasComplexAddress()) 203221337Sdim addComplexAddress(DV, Die, dwarf::DW_AT_location, Location); 204221337Sdim else if (DV->isBlockByrefVariable()) 205221337Sdim addBlockByrefAddress(DV, Die, dwarf::DW_AT_location, Location); 206221337Sdim else 207221337Sdim addAddress(Die, dwarf::DW_AT_location, Location); 208221337Sdim} 209221337Sdim 210221337Sdim/// addRegisterOp - Add register operand. 211221337Sdimvoid CompileUnit::addRegisterOp(DIE *TheDie, unsigned Reg) { 212221337Sdim const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); 213221337Sdim unsigned DWReg = RI->getDwarfRegNum(Reg, false); 214221337Sdim if (DWReg < 32) 215221337Sdim addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + DWReg); 216221337Sdim else { 217221337Sdim addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx); 218221337Sdim addUInt(TheDie, 0, dwarf::DW_FORM_udata, DWReg); 219221337Sdim } 220221337Sdim} 221221337Sdim 222221337Sdim/// addRegisterOffset - Add register offset. 223221337Sdimvoid CompileUnit::addRegisterOffset(DIE *TheDie, unsigned Reg, 224221337Sdim int64_t Offset) { 225221337Sdim const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); 226221337Sdim unsigned DWReg = RI->getDwarfRegNum(Reg, false); 227221337Sdim const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo(); 228221337Sdim if (Reg == TRI->getFrameRegister(*Asm->MF)) 229221337Sdim // If variable offset is based in frame register then use fbreg. 230221337Sdim addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_fbreg); 231221337Sdim else if (DWReg < 32) 232221337Sdim addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + DWReg); 233221337Sdim else { 234221337Sdim addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx); 235221337Sdim addUInt(TheDie, 0, dwarf::DW_FORM_udata, DWReg); 236221337Sdim } 237221337Sdim addSInt(TheDie, 0, dwarf::DW_FORM_sdata, Offset); 238221337Sdim} 239221337Sdim 240221337Sdim/// addAddress - Add an address attribute to a die based on the location 241221337Sdim/// provided. 242221337Sdimvoid CompileUnit::addAddress(DIE *Die, unsigned Attribute, 243221337Sdim const MachineLocation &Location) { 244221337Sdim DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); 245221337Sdim 246221337Sdim if (Location.isReg()) 247221337Sdim addRegisterOp(Block, Location.getReg()); 248221337Sdim else 249221337Sdim addRegisterOffset(Block, Location.getReg(), Location.getOffset()); 250221337Sdim 251221337Sdim // Now attach the location information to the DIE. 252221337Sdim addBlock(Die, Attribute, 0, Block); 253221337Sdim} 254221337Sdim 255221337Sdim/// addComplexAddress - Start with the address based on the location provided, 256221337Sdim/// and generate the DWARF information necessary to find the actual variable 257221337Sdim/// given the extra address information encoded in the DIVariable, starting from 258221337Sdim/// the starting location. Add the DWARF information to the die. 259221337Sdim/// 260221337Sdimvoid CompileUnit::addComplexAddress(DbgVariable *&DV, DIE *Die, 261221337Sdim unsigned Attribute, 262221337Sdim const MachineLocation &Location) { 263221337Sdim DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); 264221337Sdim unsigned N = DV->getNumAddrElements(); 265221337Sdim unsigned i = 0; 266221337Sdim if (Location.isReg()) { 267221337Sdim if (N >= 2 && DV->getAddrElement(0) == DIBuilder::OpPlus) { 268221337Sdim // If first address element is OpPlus then emit 269221337Sdim // DW_OP_breg + Offset instead of DW_OP_reg + Offset. 270221337Sdim addRegisterOffset(Block, Location.getReg(), DV->getAddrElement(1)); 271221337Sdim i = 2; 272221337Sdim } else 273221337Sdim addRegisterOp(Block, Location.getReg()); 274221337Sdim } 275221337Sdim else 276221337Sdim addRegisterOffset(Block, Location.getReg(), Location.getOffset()); 277221337Sdim 278221337Sdim for (;i < N; ++i) { 279221337Sdim uint64_t Element = DV->getAddrElement(i); 280221337Sdim if (Element == DIBuilder::OpPlus) { 281221337Sdim addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); 282221337Sdim addUInt(Block, 0, dwarf::DW_FORM_udata, DV->getAddrElement(++i)); 283221337Sdim } else if (Element == DIBuilder::OpDeref) { 284221337Sdim addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); 285221337Sdim } else llvm_unreachable("unknown DIBuilder Opcode"); 286221337Sdim } 287221337Sdim 288221337Sdim // Now attach the location information to the DIE. 289221337Sdim addBlock(Die, Attribute, 0, Block); 290221337Sdim} 291221337Sdim 292221337Sdim/* Byref variables, in Blocks, are declared by the programmer as "SomeType 293221337Sdim VarName;", but the compiler creates a __Block_byref_x_VarName struct, and 294221337Sdim gives the variable VarName either the struct, or a pointer to the struct, as 295221337Sdim its type. This is necessary for various behind-the-scenes things the 296221337Sdim compiler needs to do with by-reference variables in Blocks. 297221337Sdim 298221337Sdim However, as far as the original *programmer* is concerned, the variable 299221337Sdim should still have type 'SomeType', as originally declared. 300221337Sdim 301221337Sdim The function getBlockByrefType dives into the __Block_byref_x_VarName 302221337Sdim struct to find the original type of the variable, which is then assigned to 303221337Sdim the variable's Debug Information Entry as its real type. So far, so good. 304221337Sdim However now the debugger will expect the variable VarName to have the type 305221337Sdim SomeType. So we need the location attribute for the variable to be an 306221337Sdim expression that explains to the debugger how to navigate through the 307221337Sdim pointers and struct to find the actual variable of type SomeType. 308221337Sdim 309221337Sdim The following function does just that. We start by getting 310221337Sdim the "normal" location for the variable. This will be the location 311221337Sdim of either the struct __Block_byref_x_VarName or the pointer to the 312221337Sdim struct __Block_byref_x_VarName. 313221337Sdim 314221337Sdim The struct will look something like: 315221337Sdim 316221337Sdim struct __Block_byref_x_VarName { 317221337Sdim ... <various fields> 318221337Sdim struct __Block_byref_x_VarName *forwarding; 319221337Sdim ... <various other fields> 320221337Sdim SomeType VarName; 321221337Sdim ... <maybe more fields> 322221337Sdim }; 323221337Sdim 324221337Sdim If we are given the struct directly (as our starting point) we 325221337Sdim need to tell the debugger to: 326221337Sdim 327221337Sdim 1). Add the offset of the forwarding field. 328221337Sdim 329221337Sdim 2). Follow that pointer to get the real __Block_byref_x_VarName 330221337Sdim struct to use (the real one may have been copied onto the heap). 331221337Sdim 332221337Sdim 3). Add the offset for the field VarName, to find the actual variable. 333221337Sdim 334221337Sdim If we started with a pointer to the struct, then we need to 335221337Sdim dereference that pointer first, before the other steps. 336221337Sdim Translating this into DWARF ops, we will need to append the following 337221337Sdim to the current location description for the variable: 338221337Sdim 339221337Sdim DW_OP_deref -- optional, if we start with a pointer 340221337Sdim DW_OP_plus_uconst <forward_fld_offset> 341221337Sdim DW_OP_deref 342221337Sdim DW_OP_plus_uconst <varName_fld_offset> 343221337Sdim 344221337Sdim That is what this function does. */ 345221337Sdim 346221337Sdim/// addBlockByrefAddress - Start with the address based on the location 347221337Sdim/// provided, and generate the DWARF information necessary to find the 348221337Sdim/// actual Block variable (navigating the Block struct) based on the 349221337Sdim/// starting location. Add the DWARF information to the die. For 350221337Sdim/// more information, read large comment just above here. 351221337Sdim/// 352221337Sdimvoid CompileUnit::addBlockByrefAddress(DbgVariable *&DV, DIE *Die, 353221337Sdim unsigned Attribute, 354221337Sdim const MachineLocation &Location) { 355221337Sdim DIType Ty = DV->getType(); 356221337Sdim DIType TmpTy = Ty; 357221337Sdim unsigned Tag = Ty.getTag(); 358221337Sdim bool isPointer = false; 359221337Sdim 360221337Sdim StringRef varName = DV->getName(); 361221337Sdim 362221337Sdim if (Tag == dwarf::DW_TAG_pointer_type) { 363221337Sdim DIDerivedType DTy = DIDerivedType(Ty); 364221337Sdim TmpTy = DTy.getTypeDerivedFrom(); 365221337Sdim isPointer = true; 366221337Sdim } 367221337Sdim 368221337Sdim DICompositeType blockStruct = DICompositeType(TmpTy); 369221337Sdim 370221337Sdim // Find the __forwarding field and the variable field in the __Block_byref 371221337Sdim // struct. 372221337Sdim DIArray Fields = blockStruct.getTypeArray(); 373221337Sdim DIDescriptor varField = DIDescriptor(); 374221337Sdim DIDescriptor forwardingField = DIDescriptor(); 375221337Sdim 376221337Sdim for (unsigned i = 0, N = Fields.getNumElements(); i < N; ++i) { 377221337Sdim DIDescriptor Element = Fields.getElement(i); 378221337Sdim DIDerivedType DT = DIDerivedType(Element); 379221337Sdim StringRef fieldName = DT.getName(); 380221337Sdim if (fieldName == "__forwarding") 381221337Sdim forwardingField = Element; 382221337Sdim else if (fieldName == varName) 383221337Sdim varField = Element; 384221337Sdim } 385221337Sdim 386221337Sdim // Get the offsets for the forwarding field and the variable field. 387221337Sdim unsigned forwardingFieldOffset = 388221337Sdim DIDerivedType(forwardingField).getOffsetInBits() >> 3; 389221337Sdim unsigned varFieldOffset = 390221337Sdim DIDerivedType(varField).getOffsetInBits() >> 3; 391221337Sdim 392221337Sdim // Decode the original location, and use that as the start of the byref 393221337Sdim // variable's location. 394221337Sdim const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo(); 395221337Sdim unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false); 396221337Sdim DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); 397221337Sdim 398221337Sdim if (Location.isReg()) { 399221337Sdim if (Reg < 32) 400221337Sdim addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg); 401221337Sdim else { 402221337Sdim addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx); 403221337Sdim addUInt(Block, 0, dwarf::DW_FORM_udata, Reg); 404221337Sdim } 405221337Sdim } else { 406221337Sdim if (Reg < 32) 407221337Sdim addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg); 408221337Sdim else { 409221337Sdim addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx); 410221337Sdim addUInt(Block, 0, dwarf::DW_FORM_udata, Reg); 411221337Sdim } 412221337Sdim 413221337Sdim addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset()); 414221337Sdim } 415221337Sdim 416221337Sdim // If we started with a pointer to the __Block_byref... struct, then 417221337Sdim // the first thing we need to do is dereference the pointer (DW_OP_deref). 418221337Sdim if (isPointer) 419221337Sdim addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); 420221337Sdim 421221337Sdim // Next add the offset for the '__forwarding' field: 422221337Sdim // DW_OP_plus_uconst ForwardingFieldOffset. Note there's no point in 423221337Sdim // adding the offset if it's 0. 424221337Sdim if (forwardingFieldOffset > 0) { 425221337Sdim addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); 426221337Sdim addUInt(Block, 0, dwarf::DW_FORM_udata, forwardingFieldOffset); 427221337Sdim } 428221337Sdim 429221337Sdim // Now dereference the __forwarding field to get to the real __Block_byref 430221337Sdim // struct: DW_OP_deref. 431221337Sdim addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); 432221337Sdim 433221337Sdim // Now that we've got the real __Block_byref... struct, add the offset 434221337Sdim // for the variable's field to get to the location of the actual variable: 435221337Sdim // DW_OP_plus_uconst varFieldOffset. Again, don't add if it's 0. 436221337Sdim if (varFieldOffset > 0) { 437221337Sdim addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); 438221337Sdim addUInt(Block, 0, dwarf::DW_FORM_udata, varFieldOffset); 439221337Sdim } 440221337Sdim 441221337Sdim // Now attach the location information to the DIE. 442221337Sdim addBlock(Die, Attribute, 0, Block); 443221337Sdim} 444221337Sdim 445226890Sdim/// isTypeSigned - Return true if the type is signed. 446226890Sdimstatic bool isTypeSigned(DIType Ty, int *SizeInBits) { 447226890Sdim if (Ty.isDerivedType()) 448226890Sdim return isTypeSigned(DIDerivedType(Ty).getTypeDerivedFrom(), SizeInBits); 449226890Sdim if (Ty.isBasicType()) 450226890Sdim if (DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed 451226890Sdim || DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed_char) { 452226890Sdim *SizeInBits = Ty.getSizeInBits(); 453226890Sdim return true; 454226890Sdim } 455226890Sdim return false; 456226890Sdim} 457226890Sdim 458221337Sdim/// addConstantValue - Add constant value entry in variable DIE. 459223017Sdimbool CompileUnit::addConstantValue(DIE *Die, const MachineOperand &MO, 460223017Sdim DIType Ty) { 461221337Sdim assert (MO.isImm() && "Invalid machine operand!"); 462221337Sdim DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); 463226890Sdim int SizeInBits = -1; 464226890Sdim bool SignedConstant = isTypeSigned(Ty, &SizeInBits); 465226890Sdim unsigned Form = SignedConstant ? dwarf::DW_FORM_sdata : dwarf::DW_FORM_udata; 466226890Sdim switch (SizeInBits) { 467226890Sdim case 8: Form = dwarf::DW_FORM_data1; break; 468226890Sdim case 16: Form = dwarf::DW_FORM_data2; break; 469226890Sdim case 32: Form = dwarf::DW_FORM_data4; break; 470226890Sdim case 64: Form = dwarf::DW_FORM_data8; break; 471223017Sdim default: break; 472223017Sdim } 473226890Sdim SignedConstant ? addSInt(Block, 0, Form, MO.getImm()) 474226890Sdim : addUInt(Block, 0, Form, MO.getImm()); 475223017Sdim 476221337Sdim addBlock(Die, dwarf::DW_AT_const_value, 0, Block); 477221337Sdim return true; 478221337Sdim} 479221337Sdim 480221337Sdim/// addConstantFPValue - Add constant value entry in variable DIE. 481221337Sdimbool CompileUnit::addConstantFPValue(DIE *Die, const MachineOperand &MO) { 482221337Sdim assert (MO.isFPImm() && "Invalid machine operand!"); 483221337Sdim DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); 484221337Sdim APFloat FPImm = MO.getFPImm()->getValueAPF(); 485221337Sdim 486221337Sdim // Get the raw data form of the floating point. 487221337Sdim const APInt FltVal = FPImm.bitcastToAPInt(); 488221337Sdim const char *FltPtr = (const char*)FltVal.getRawData(); 489221337Sdim 490221337Sdim int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte. 491221337Sdim bool LittleEndian = Asm->getTargetData().isLittleEndian(); 492221337Sdim int Incr = (LittleEndian ? 1 : -1); 493221337Sdim int Start = (LittleEndian ? 0 : NumBytes - 1); 494221337Sdim int Stop = (LittleEndian ? NumBytes : -1); 495221337Sdim 496221337Sdim // Output the constant to DWARF one byte at a time. 497221337Sdim for (; Start != Stop; Start += Incr) 498221337Sdim addUInt(Block, 0, dwarf::DW_FORM_data1, 499221337Sdim (unsigned char)0xFF & FltPtr[Start]); 500221337Sdim 501221337Sdim addBlock(Die, dwarf::DW_AT_const_value, 0, Block); 502221337Sdim return true; 503221337Sdim} 504221337Sdim 505221337Sdim/// addConstantValue - Add constant value entry in variable DIE. 506224145Sdimbool CompileUnit::addConstantValue(DIE *Die, const ConstantInt *CI, 507221337Sdim bool Unsigned) { 508223017Sdim unsigned CIBitWidth = CI->getBitWidth(); 509223017Sdim if (CIBitWidth <= 64) { 510223017Sdim unsigned form = 0; 511223017Sdim switch (CIBitWidth) { 512223017Sdim case 8: form = dwarf::DW_FORM_data1; break; 513223017Sdim case 16: form = dwarf::DW_FORM_data2; break; 514223017Sdim case 32: form = dwarf::DW_FORM_data4; break; 515223017Sdim case 64: form = dwarf::DW_FORM_data8; break; 516223017Sdim default: 517223017Sdim form = Unsigned ? dwarf::DW_FORM_udata : dwarf::DW_FORM_sdata; 518223017Sdim } 519221337Sdim if (Unsigned) 520223017Sdim addUInt(Die, dwarf::DW_AT_const_value, form, CI->getZExtValue()); 521221337Sdim else 522223017Sdim addSInt(Die, dwarf::DW_AT_const_value, form, CI->getSExtValue()); 523221337Sdim return true; 524221337Sdim } 525221337Sdim 526221337Sdim DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); 527221337Sdim 528221337Sdim // Get the raw data form of the large APInt. 529221337Sdim const APInt Val = CI->getValue(); 530229042Sdim const uint64_t *Ptr64 = Val.getRawData(); 531221337Sdim 532221337Sdim int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte. 533221337Sdim bool LittleEndian = Asm->getTargetData().isLittleEndian(); 534221337Sdim 535221337Sdim // Output the constant to DWARF one byte at a time. 536229042Sdim for (int i = 0; i < NumBytes; i++) { 537229042Sdim uint8_t c; 538229042Sdim if (LittleEndian) 539229042Sdim c = Ptr64[i / 8] >> (8 * (i & 7)); 540229042Sdim else 541229042Sdim c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7)); 542229042Sdim addUInt(Block, 0, dwarf::DW_FORM_data1, c); 543229042Sdim } 544221337Sdim 545221337Sdim addBlock(Die, dwarf::DW_AT_const_value, 0, Block); 546221337Sdim return true; 547221337Sdim} 548221337Sdim 549221337Sdim/// addTemplateParams - Add template parameters in buffer. 550221337Sdimvoid CompileUnit::addTemplateParams(DIE &Buffer, DIArray TParams) { 551221337Sdim // Add template parameters. 552221337Sdim for (unsigned i = 0, e = TParams.getNumElements(); i != e; ++i) { 553221337Sdim DIDescriptor Element = TParams.getElement(i); 554221337Sdim if (Element.isTemplateTypeParameter()) 555221337Sdim Buffer.addChild(getOrCreateTemplateTypeParameterDIE( 556221337Sdim DITemplateTypeParameter(Element))); 557221337Sdim else if (Element.isTemplateValueParameter()) 558221337Sdim Buffer.addChild(getOrCreateTemplateValueParameterDIE( 559221337Sdim DITemplateValueParameter(Element))); 560221337Sdim } 561221337Sdim 562221337Sdim} 563221337Sdim/// addToContextOwner - Add Die into the list of its context owner's children. 564221337Sdimvoid CompileUnit::addToContextOwner(DIE *Die, DIDescriptor Context) { 565221337Sdim if (Context.isType()) { 566221337Sdim DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context)); 567221337Sdim ContextDIE->addChild(Die); 568221337Sdim } else if (Context.isNameSpace()) { 569221337Sdim DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context)); 570221337Sdim ContextDIE->addChild(Die); 571221337Sdim } else if (Context.isSubprogram()) { 572226890Sdim DIE *ContextDIE = getOrCreateSubprogramDIE(DISubprogram(Context)); 573221337Sdim ContextDIE->addChild(Die); 574221337Sdim } else if (DIE *ContextDIE = getDIE(Context)) 575221337Sdim ContextDIE->addChild(Die); 576221337Sdim else 577221337Sdim addDie(Die); 578221337Sdim} 579221337Sdim 580221337Sdim/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the 581221337Sdim/// given DIType. 582226890SdimDIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) { 583226890Sdim DIType Ty(TyNode); 584226890Sdim if (!Ty.Verify()) 585226890Sdim return NULL; 586221337Sdim DIE *TyDIE = getDIE(Ty); 587221337Sdim if (TyDIE) 588221337Sdim return TyDIE; 589221337Sdim 590221337Sdim // Create new type. 591221337Sdim TyDIE = new DIE(dwarf::DW_TAG_base_type); 592221337Sdim insertDIE(Ty, TyDIE); 593221337Sdim if (Ty.isBasicType()) 594221337Sdim constructTypeDIE(*TyDIE, DIBasicType(Ty)); 595221337Sdim else if (Ty.isCompositeType()) 596221337Sdim constructTypeDIE(*TyDIE, DICompositeType(Ty)); 597221337Sdim else { 598221337Sdim assert(Ty.isDerivedType() && "Unknown kind of DIType"); 599221337Sdim constructTypeDIE(*TyDIE, DIDerivedType(Ty)); 600221337Sdim } 601221337Sdim 602221337Sdim addToContextOwner(TyDIE, Ty.getContext()); 603221337Sdim return TyDIE; 604221337Sdim} 605221337Sdim 606221337Sdim/// addType - Add a new type attribute to the specified entity. 607221337Sdimvoid CompileUnit::addType(DIE *Entity, DIType Ty) { 608221337Sdim if (!Ty.Verify()) 609221337Sdim return; 610221337Sdim 611221337Sdim // Check for pre-existence. 612221337Sdim DIEEntry *Entry = getDIEEntry(Ty); 613221337Sdim // If it exists then use the existing value. 614221337Sdim if (Entry) { 615221337Sdim Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry); 616221337Sdim return; 617221337Sdim } 618221337Sdim 619221337Sdim // Construct type. 620221337Sdim DIE *Buffer = getOrCreateTypeDIE(Ty); 621221337Sdim 622221337Sdim // Set up proxy. 623221337Sdim Entry = createDIEEntry(Buffer); 624221337Sdim insertDIEEntry(Ty, Entry); 625223017Sdim Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry); 626221337Sdim 627223017Sdim // If this is a complete composite type then include it in the 628223017Sdim // list of global types. 629223017Sdim addGlobalType(Ty); 630221337Sdim} 631221337Sdim 632223017Sdim/// addGlobalType - Add a new global type to the compile unit. 633223017Sdim/// 634223017Sdimvoid CompileUnit::addGlobalType(DIType Ty) { 635223017Sdim DIDescriptor Context = Ty.getContext(); 636223017Sdim if (Ty.isCompositeType() && !Ty.getName().empty() && !Ty.isForwardDecl() 637226890Sdim && (!Context || Context.isCompileUnit() || Context.isFile() 638226890Sdim || Context.isNameSpace())) 639223017Sdim if (DIEEntry *Entry = getDIEEntry(Ty)) 640223017Sdim GlobalTypes[Ty.getName()] = Entry->getEntry(); 641223017Sdim} 642223017Sdim 643223017Sdim/// addPubTypes - Add type for pubtypes section. 644223017Sdimvoid CompileUnit::addPubTypes(DISubprogram SP) { 645223017Sdim DICompositeType SPTy = SP.getType(); 646223017Sdim unsigned SPTag = SPTy.getTag(); 647223017Sdim if (SPTag != dwarf::DW_TAG_subroutine_type) 648223017Sdim return; 649223017Sdim 650223017Sdim DIArray Args = SPTy.getTypeArray(); 651223017Sdim for (unsigned i = 0, e = Args.getNumElements(); i != e; ++i) { 652223017Sdim DIType ATy(Args.getElement(i)); 653223017Sdim if (!ATy.Verify()) 654223017Sdim continue; 655223017Sdim addGlobalType(ATy); 656223017Sdim } 657223017Sdim} 658223017Sdim 659221337Sdim/// constructTypeDIE - Construct basic type die from DIBasicType. 660221337Sdimvoid CompileUnit::constructTypeDIE(DIE &Buffer, DIBasicType BTy) { 661221337Sdim // Get core information. 662221337Sdim StringRef Name = BTy.getName(); 663226890Sdim // Add name if not anonymous or intermediate type. 664226890Sdim if (!Name.empty()) 665226890Sdim addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); 666226890Sdim 667226890Sdim if (BTy.getTag() == dwarf::DW_TAG_unspecified_type) { 668226890Sdim Buffer.setTag(dwarf::DW_TAG_unspecified_type); 669226890Sdim // Unspecified types has only name, nothing else. 670226890Sdim return; 671226890Sdim } 672226890Sdim 673221337Sdim Buffer.setTag(dwarf::DW_TAG_base_type); 674221337Sdim addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, 675226890Sdim BTy.getEncoding()); 676221337Sdim 677221337Sdim uint64_t Size = BTy.getSizeInBits() >> 3; 678221337Sdim addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size); 679221337Sdim} 680221337Sdim 681221337Sdim/// constructTypeDIE - Construct derived type die from DIDerivedType. 682221337Sdimvoid CompileUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) { 683221337Sdim // Get core information. 684221337Sdim StringRef Name = DTy.getName(); 685221337Sdim uint64_t Size = DTy.getSizeInBits() >> 3; 686221337Sdim unsigned Tag = DTy.getTag(); 687221337Sdim 688221337Sdim // FIXME - Workaround for templates. 689221337Sdim if (Tag == dwarf::DW_TAG_inheritance) Tag = dwarf::DW_TAG_reference_type; 690221337Sdim 691221337Sdim Buffer.setTag(Tag); 692221337Sdim 693221337Sdim // Map to main type, void will not have a type. 694221337Sdim DIType FromTy = DTy.getTypeDerivedFrom(); 695221337Sdim addType(&Buffer, FromTy); 696221337Sdim 697221337Sdim // Add name if not anonymous or intermediate type. 698221337Sdim if (!Name.empty()) 699221337Sdim addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); 700221337Sdim 701221337Sdim // Add size if non-zero (derived types might be zero-sized.) 702221337Sdim if (Size) 703221337Sdim addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size); 704221337Sdim 705221337Sdim // Add source line info if available and TyDesc is not a forward declaration. 706221337Sdim if (!DTy.isForwardDecl()) 707221337Sdim addSourceLine(&Buffer, DTy); 708221337Sdim} 709221337Sdim 710221337Sdim/// constructTypeDIE - Construct type DIE from DICompositeType. 711221337Sdimvoid CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { 712221337Sdim // Get core information. 713221337Sdim StringRef Name = CTy.getName(); 714221337Sdim 715221337Sdim uint64_t Size = CTy.getSizeInBits() >> 3; 716221337Sdim unsigned Tag = CTy.getTag(); 717221337Sdim Buffer.setTag(Tag); 718221337Sdim 719221337Sdim switch (Tag) { 720221337Sdim case dwarf::DW_TAG_vector_type: 721221337Sdim case dwarf::DW_TAG_array_type: 722221337Sdim constructArrayTypeDIE(Buffer, &CTy); 723221337Sdim break; 724221337Sdim case dwarf::DW_TAG_enumeration_type: { 725221337Sdim DIArray Elements = CTy.getTypeArray(); 726221337Sdim 727221337Sdim // Add enumerators to enumeration type. 728221337Sdim for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) { 729221337Sdim DIE *ElemDie = NULL; 730221337Sdim DIDescriptor Enum(Elements.getElement(i)); 731221337Sdim if (Enum.isEnumerator()) { 732221337Sdim ElemDie = constructEnumTypeDIE(DIEnumerator(Enum)); 733221337Sdim Buffer.addChild(ElemDie); 734221337Sdim } 735221337Sdim } 736221337Sdim } 737221337Sdim break; 738221337Sdim case dwarf::DW_TAG_subroutine_type: { 739221337Sdim // Add return type. 740221337Sdim DIArray Elements = CTy.getTypeArray(); 741221337Sdim DIDescriptor RTy = Elements.getElement(0); 742221337Sdim addType(&Buffer, DIType(RTy)); 743221337Sdim 744221337Sdim bool isPrototyped = true; 745221337Sdim // Add arguments. 746221337Sdim for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) { 747221337Sdim DIDescriptor Ty = Elements.getElement(i); 748221337Sdim if (Ty.isUnspecifiedParameter()) { 749221337Sdim DIE *Arg = new DIE(dwarf::DW_TAG_unspecified_parameters); 750221337Sdim Buffer.addChild(Arg); 751221337Sdim isPrototyped = false; 752221337Sdim } else { 753221337Sdim DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter); 754221337Sdim addType(Arg, DIType(Ty)); 755221337Sdim Buffer.addChild(Arg); 756221337Sdim } 757221337Sdim } 758221337Sdim // Add prototype flag. 759221337Sdim if (isPrototyped) 760221337Sdim addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1); 761221337Sdim } 762221337Sdim break; 763221337Sdim case dwarf::DW_TAG_structure_type: 764221337Sdim case dwarf::DW_TAG_union_type: 765221337Sdim case dwarf::DW_TAG_class_type: { 766221337Sdim // Add elements to structure type. 767221337Sdim DIArray Elements = CTy.getTypeArray(); 768221337Sdim 769221337Sdim // A forward struct declared type may not have elements available. 770221337Sdim unsigned N = Elements.getNumElements(); 771221337Sdim if (N == 0) 772221337Sdim break; 773221337Sdim 774221337Sdim // Add elements to structure type. 775221337Sdim for (unsigned i = 0; i < N; ++i) { 776221337Sdim DIDescriptor Element = Elements.getElement(i); 777221337Sdim DIE *ElemDie = NULL; 778221337Sdim if (Element.isSubprogram()) { 779221337Sdim DISubprogram SP(Element); 780226890Sdim ElemDie = getOrCreateSubprogramDIE(DISubprogram(Element)); 781221337Sdim if (SP.isProtected()) 782221337Sdim addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, 783221337Sdim dwarf::DW_ACCESS_protected); 784221337Sdim else if (SP.isPrivate()) 785221337Sdim addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, 786221337Sdim dwarf::DW_ACCESS_private); 787221337Sdim else 788221337Sdim addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, 789221337Sdim dwarf::DW_ACCESS_public); 790221337Sdim if (SP.isExplicit()) 791221337Sdim addUInt(ElemDie, dwarf::DW_AT_explicit, dwarf::DW_FORM_flag, 1); 792221337Sdim } 793221337Sdim else if (Element.isVariable()) { 794221337Sdim DIVariable DV(Element); 795221337Sdim ElemDie = new DIE(dwarf::DW_TAG_variable); 796221337Sdim addString(ElemDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, 797221337Sdim DV.getName()); 798221337Sdim addType(ElemDie, DV.getType()); 799221337Sdim addUInt(ElemDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); 800221337Sdim addUInt(ElemDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); 801221337Sdim addSourceLine(ElemDie, DV); 802221337Sdim } else if (Element.isDerivedType()) 803221337Sdim ElemDie = createMemberDIE(DIDerivedType(Element)); 804221337Sdim else 805221337Sdim continue; 806221337Sdim Buffer.addChild(ElemDie); 807221337Sdim } 808221337Sdim 809221337Sdim if (CTy.isAppleBlockExtension()) 810221337Sdim addUInt(&Buffer, dwarf::DW_AT_APPLE_block, dwarf::DW_FORM_flag, 1); 811221337Sdim 812221337Sdim unsigned RLang = CTy.getRunTimeLang(); 813221337Sdim if (RLang) 814221337Sdim addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class, 815221337Sdim dwarf::DW_FORM_data1, RLang); 816221337Sdim 817221337Sdim DICompositeType ContainingType = CTy.getContainingType(); 818221337Sdim if (DIDescriptor(ContainingType).isCompositeType()) 819221337Sdim addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, 820221337Sdim getOrCreateTypeDIE(DIType(ContainingType))); 821221337Sdim else { 822221337Sdim DIDescriptor Context = CTy.getContext(); 823221337Sdim addToContextOwner(&Buffer, Context); 824221337Sdim } 825221337Sdim 826223017Sdim if (CTy.isObjcClassComplete()) 827223017Sdim addUInt(&Buffer, dwarf::DW_AT_APPLE_objc_complete_type, 828223017Sdim dwarf::DW_FORM_flag, 1); 829223017Sdim 830221337Sdim if (Tag == dwarf::DW_TAG_class_type) 831221337Sdim addTemplateParams(Buffer, CTy.getTemplateParams()); 832221337Sdim 833221337Sdim break; 834221337Sdim } 835221337Sdim default: 836221337Sdim break; 837221337Sdim } 838221337Sdim 839221337Sdim // Add name if not anonymous or intermediate type. 840221337Sdim if (!Name.empty()) 841221337Sdim addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); 842221337Sdim 843221337Sdim if (Tag == dwarf::DW_TAG_enumeration_type || Tag == dwarf::DW_TAG_class_type 844221337Sdim || Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) 845221337Sdim { 846221337Sdim // Add size if non-zero (derived types might be zero-sized.) 847221337Sdim if (Size) 848221337Sdim addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size); 849221337Sdim else { 850221337Sdim // Add zero size if it is not a forward declaration. 851221337Sdim if (CTy.isForwardDecl()) 852221337Sdim addUInt(&Buffer, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); 853221337Sdim else 854221337Sdim addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, 0); 855221337Sdim } 856221337Sdim 857221337Sdim // Add source line info if available. 858221337Sdim if (!CTy.isForwardDecl()) 859221337Sdim addSourceLine(&Buffer, CTy); 860221337Sdim } 861221337Sdim} 862221337Sdim 863221337Sdim/// getOrCreateTemplateTypeParameterDIE - Find existing DIE or create new DIE 864221337Sdim/// for the given DITemplateTypeParameter. 865221337SdimDIE * 866221337SdimCompileUnit::getOrCreateTemplateTypeParameterDIE(DITemplateTypeParameter TP) { 867221337Sdim DIE *ParamDIE = getDIE(TP); 868221337Sdim if (ParamDIE) 869221337Sdim return ParamDIE; 870221337Sdim 871221337Sdim ParamDIE = new DIE(dwarf::DW_TAG_template_type_parameter); 872221337Sdim addType(ParamDIE, TP.getType()); 873221337Sdim addString(ParamDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string, TP.getName()); 874221337Sdim return ParamDIE; 875221337Sdim} 876221337Sdim 877221337Sdim/// getOrCreateTemplateValueParameterDIE - Find existing DIE or create new DIE 878221337Sdim/// for the given DITemplateValueParameter. 879221337SdimDIE * 880221337SdimCompileUnit::getOrCreateTemplateValueParameterDIE(DITemplateValueParameter TPV) { 881221337Sdim DIE *ParamDIE = getDIE(TPV); 882221337Sdim if (ParamDIE) 883221337Sdim return ParamDIE; 884221337Sdim 885221337Sdim ParamDIE = new DIE(dwarf::DW_TAG_template_value_parameter); 886221337Sdim addType(ParamDIE, TPV.getType()); 887221337Sdim if (!TPV.getName().empty()) 888221337Sdim addString(ParamDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string, TPV.getName()); 889221337Sdim addUInt(ParamDIE, dwarf::DW_AT_const_value, dwarf::DW_FORM_udata, 890221337Sdim TPV.getValue()); 891221337Sdim return ParamDIE; 892221337Sdim} 893221337Sdim 894223017Sdim/// getOrCreateNameSpace - Create a DIE for DINameSpace. 895223017SdimDIE *CompileUnit::getOrCreateNameSpace(DINameSpace NS) { 896223017Sdim DIE *NDie = getDIE(NS); 897223017Sdim if (NDie) 898223017Sdim return NDie; 899223017Sdim NDie = new DIE(dwarf::DW_TAG_namespace); 900223017Sdim insertDIE(NS, NDie); 901223017Sdim if (!NS.getName().empty()) 902223017Sdim addString(NDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, NS.getName()); 903223017Sdim addSourceLine(NDie, NS); 904223017Sdim addToContextOwner(NDie, NS.getContext()); 905223017Sdim return NDie; 906223017Sdim} 907223017Sdim 908226890Sdim/// getRealLinkageName - If special LLVM prefix that is used to inform the asm 909226890Sdim/// printer to not emit usual symbol prefix before the symbol name is used then 910226890Sdim/// return linkage name after skipping this special LLVM prefix. 911226890Sdimstatic StringRef getRealLinkageName(StringRef LinkageName) { 912226890Sdim char One = '\1'; 913226890Sdim if (LinkageName.startswith(StringRef(&One, 1))) 914226890Sdim return LinkageName.substr(1); 915226890Sdim return LinkageName; 916226890Sdim} 917226890Sdim 918226890Sdim/// getOrCreateSubprogramDIE - Create new DIE using SP. 919226890SdimDIE *CompileUnit::getOrCreateSubprogramDIE(DISubprogram SP) { 920226890Sdim DIE *SPDie = getDIE(SP); 921226890Sdim if (SPDie) 922226890Sdim return SPDie; 923226890Sdim 924226890Sdim SPDie = new DIE(dwarf::DW_TAG_subprogram); 925226890Sdim 926226890Sdim // DW_TAG_inlined_subroutine may refer to this DIE. 927226890Sdim insertDIE(SP, SPDie); 928226890Sdim 929226890Sdim // Add to context owner. 930226890Sdim addToContextOwner(SPDie, SP.getContext()); 931226890Sdim 932226890Sdim // Add function template parameters. 933226890Sdim addTemplateParams(*SPDie, SP.getTemplateParams()); 934226890Sdim 935226890Sdim StringRef LinkageName = SP.getLinkageName(); 936226890Sdim if (!LinkageName.empty()) 937226890Sdim addString(SPDie, dwarf::DW_AT_MIPS_linkage_name, 938226890Sdim dwarf::DW_FORM_string, 939226890Sdim getRealLinkageName(LinkageName)); 940226890Sdim 941226890Sdim // If this DIE is going to refer declaration info using AT_specification 942226890Sdim // then there is no need to add other attributes. 943226890Sdim if (SP.getFunctionDeclaration().isSubprogram()) 944226890Sdim return SPDie; 945226890Sdim 946226890Sdim // Constructors and operators for anonymous aggregates do not have names. 947226890Sdim if (!SP.getName().empty()) 948226890Sdim addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, 949226890Sdim SP.getName()); 950226890Sdim 951226890Sdim addSourceLine(SPDie, SP); 952226890Sdim 953226890Sdim if (SP.isPrototyped()) 954226890Sdim addUInt(SPDie, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1); 955226890Sdim 956226890Sdim // Add Return Type. 957226890Sdim DICompositeType SPTy = SP.getType(); 958226890Sdim DIArray Args = SPTy.getTypeArray(); 959226890Sdim unsigned SPTag = SPTy.getTag(); 960226890Sdim 961226890Sdim if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type) 962226890Sdim addType(SPDie, SPTy); 963226890Sdim else 964226890Sdim addType(SPDie, DIType(Args.getElement(0))); 965226890Sdim 966226890Sdim unsigned VK = SP.getVirtuality(); 967226890Sdim if (VK) { 968226890Sdim addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK); 969226890Sdim DIEBlock *Block = getDIEBlock(); 970226890Sdim addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); 971226890Sdim addUInt(Block, 0, dwarf::DW_FORM_udata, SP.getVirtualIndex()); 972226890Sdim addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block); 973226890Sdim ContainingTypeMap.insert(std::make_pair(SPDie, 974226890Sdim SP.getContainingType())); 975226890Sdim } 976226890Sdim 977226890Sdim if (!SP.isDefinition()) { 978226890Sdim addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); 979226890Sdim 980226890Sdim // Add arguments. Do not add arguments for subprogram definition. They will 981226890Sdim // be handled while processing variables. 982226890Sdim DICompositeType SPTy = SP.getType(); 983226890Sdim DIArray Args = SPTy.getTypeArray(); 984226890Sdim unsigned SPTag = SPTy.getTag(); 985226890Sdim 986226890Sdim if (SPTag == dwarf::DW_TAG_subroutine_type) 987226890Sdim for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) { 988226890Sdim DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter); 989226890Sdim DIType ATy = DIType(DIType(Args.getElement(i))); 990226890Sdim addType(Arg, ATy); 991226890Sdim if (ATy.isArtificial()) 992226890Sdim addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); 993226890Sdim SPDie->addChild(Arg); 994226890Sdim } 995226890Sdim } 996226890Sdim 997226890Sdim if (SP.isArtificial()) 998226890Sdim addUInt(SPDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); 999226890Sdim 1000226890Sdim if (!SP.isLocalToUnit()) 1001226890Sdim addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); 1002226890Sdim 1003226890Sdim if (SP.isOptimized()) 1004226890Sdim addUInt(SPDie, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1); 1005226890Sdim 1006226890Sdim if (unsigned isa = Asm->getISAEncoding()) { 1007226890Sdim addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa); 1008226890Sdim } 1009226890Sdim 1010226890Sdim return SPDie; 1011226890Sdim} 1012226890Sdim 1013226890Sdim// Return const expression if value is a GEP to access merged global 1014226890Sdim// constant. e.g. 1015226890Sdim// i8* getelementptr ({ i8, i8, i8, i8 }* @_MergedGlobals, i32 0, i32 0) 1016226890Sdimstatic const ConstantExpr *getMergedGlobalExpr(const Value *V) { 1017226890Sdim const ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(V); 1018226890Sdim if (!CE || CE->getNumOperands() != 3 || 1019226890Sdim CE->getOpcode() != Instruction::GetElementPtr) 1020226890Sdim return NULL; 1021226890Sdim 1022226890Sdim // First operand points to a global struct. 1023226890Sdim Value *Ptr = CE->getOperand(0); 1024226890Sdim if (!isa<GlobalValue>(Ptr) || 1025226890Sdim !isa<StructType>(cast<PointerType>(Ptr->getType())->getElementType())) 1026226890Sdim return NULL; 1027226890Sdim 1028226890Sdim // Second operand is zero. 1029226890Sdim const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CE->getOperand(1)); 1030226890Sdim if (!CI || !CI->isZero()) 1031226890Sdim return NULL; 1032226890Sdim 1033226890Sdim // Third operand is offset. 1034226890Sdim if (!isa<ConstantInt>(CE->getOperand(2))) 1035226890Sdim return NULL; 1036226890Sdim 1037226890Sdim return CE; 1038226890Sdim} 1039226890Sdim 1040226890Sdim/// createGlobalVariableDIE - create global variable DIE. 1041226890Sdimvoid CompileUnit::createGlobalVariableDIE(const MDNode *N) { 1042226890Sdim // Check for pre-existence. 1043226890Sdim if (getDIE(N)) 1044226890Sdim return; 1045226890Sdim 1046226890Sdim DIGlobalVariable GV(N); 1047226890Sdim if (!GV.Verify()) 1048226890Sdim return; 1049226890Sdim 1050226890Sdim DIE *VariableDIE = new DIE(GV.getTag()); 1051226890Sdim // Add to map. 1052226890Sdim insertDIE(N, VariableDIE); 1053226890Sdim 1054226890Sdim // Add name. 1055226890Sdim addString(VariableDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string, 1056226890Sdim GV.getDisplayName()); 1057226890Sdim StringRef LinkageName = GV.getLinkageName(); 1058226890Sdim bool isGlobalVariable = GV.getGlobal() != NULL; 1059226890Sdim if (!LinkageName.empty() && isGlobalVariable) 1060226890Sdim addString(VariableDIE, dwarf::DW_AT_MIPS_linkage_name, 1061226890Sdim dwarf::DW_FORM_string, 1062226890Sdim getRealLinkageName(LinkageName)); 1063226890Sdim // Add type. 1064226890Sdim DIType GTy = GV.getType(); 1065226890Sdim addType(VariableDIE, GTy); 1066226890Sdim 1067226890Sdim // Add scoping info. 1068226890Sdim if (!GV.isLocalToUnit()) { 1069226890Sdim addUInt(VariableDIE, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); 1070226890Sdim // Expose as global. 1071226890Sdim addGlobal(GV.getName(), VariableDIE); 1072226890Sdim } 1073226890Sdim // Add line number info. 1074226890Sdim addSourceLine(VariableDIE, GV); 1075226890Sdim // Add to context owner. 1076226890Sdim DIDescriptor GVContext = GV.getContext(); 1077226890Sdim addToContextOwner(VariableDIE, GVContext); 1078226890Sdim // Add location. 1079226890Sdim if (isGlobalVariable) { 1080226890Sdim DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); 1081226890Sdim addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); 1082226890Sdim addLabel(Block, 0, dwarf::DW_FORM_udata, 1083226890Sdim Asm->Mang->getSymbol(GV.getGlobal())); 1084226890Sdim // Do not create specification DIE if context is either compile unit 1085226890Sdim // or a subprogram. 1086226890Sdim if (GVContext && GV.isDefinition() && !GVContext.isCompileUnit() && 1087226890Sdim !GVContext.isFile() && !isSubprogramContext(GVContext)) { 1088226890Sdim // Create specification DIE. 1089226890Sdim DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable); 1090226890Sdim addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification, 1091226890Sdim dwarf::DW_FORM_ref4, VariableDIE); 1092226890Sdim addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block); 1093226890Sdim addUInt(VariableDIE, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1094226890Sdim 1); 1095226890Sdim addDie(VariableSpecDIE); 1096226890Sdim } else { 1097226890Sdim addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block); 1098226890Sdim } 1099226890Sdim } else if (const ConstantInt *CI = 1100226890Sdim dyn_cast_or_null<ConstantInt>(GV.getConstant())) 1101226890Sdim addConstantValue(VariableDIE, CI, GTy.isUnsignedDIType()); 1102226890Sdim else if (const ConstantExpr *CE = getMergedGlobalExpr(N->getOperand(11))) { 1103226890Sdim // GV is a merged global. 1104226890Sdim DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); 1105226890Sdim Value *Ptr = CE->getOperand(0); 1106226890Sdim addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); 1107226890Sdim addLabel(Block, 0, dwarf::DW_FORM_udata, 1108226890Sdim Asm->Mang->getSymbol(cast<GlobalValue>(Ptr))); 1109226890Sdim addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); 1110226890Sdim SmallVector<Value*, 3> Idx(CE->op_begin()+1, CE->op_end()); 1111226890Sdim addUInt(Block, 0, dwarf::DW_FORM_udata, 1112226890Sdim Asm->getTargetData().getIndexedOffset(Ptr->getType(), Idx)); 1113226890Sdim addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); 1114226890Sdim addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block); 1115226890Sdim } 1116226890Sdim 1117226890Sdim return; 1118226890Sdim} 1119226890Sdim 1120221337Sdim/// constructSubrangeDIE - Construct subrange DIE from DISubrange. 1121221337Sdimvoid CompileUnit::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){ 1122221337Sdim DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type); 1123221337Sdim addDIEEntry(DW_Subrange, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IndexTy); 1124221337Sdim int64_t L = SR.getLo(); 1125221337Sdim int64_t H = SR.getHi(); 1126221337Sdim 1127221337Sdim // The L value defines the lower bounds which is typically zero for C/C++. The 1128221337Sdim // H value is the upper bounds. Values are 64 bit. H - L + 1 is the size 1129221337Sdim // of the array. If L > H then do not emit DW_AT_lower_bound and 1130221337Sdim // DW_AT_upper_bound attributes. If L is zero and H is also zero then the 1131221337Sdim // array has one element and in such case do not emit lower bound. 1132221337Sdim 1133221337Sdim if (L > H) { 1134221337Sdim Buffer.addChild(DW_Subrange); 1135221337Sdim return; 1136221337Sdim } 1137221337Sdim if (L) 1138221337Sdim addSInt(DW_Subrange, dwarf::DW_AT_lower_bound, 0, L); 1139221337Sdim addSInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, H); 1140221337Sdim Buffer.addChild(DW_Subrange); 1141221337Sdim} 1142221337Sdim 1143221337Sdim/// constructArrayTypeDIE - Construct array type DIE from DICompositeType. 1144221337Sdimvoid CompileUnit::constructArrayTypeDIE(DIE &Buffer, 1145221337Sdim DICompositeType *CTy) { 1146221337Sdim Buffer.setTag(dwarf::DW_TAG_array_type); 1147221337Sdim if (CTy->getTag() == dwarf::DW_TAG_vector_type) 1148221337Sdim addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1); 1149221337Sdim 1150221337Sdim // Emit derived type. 1151221337Sdim addType(&Buffer, CTy->getTypeDerivedFrom()); 1152221337Sdim DIArray Elements = CTy->getTypeArray(); 1153221337Sdim 1154221337Sdim // Get an anonymous type for index type. 1155221337Sdim DIE *IdxTy = getIndexTyDie(); 1156221337Sdim if (!IdxTy) { 1157221337Sdim // Construct an anonymous type for index type. 1158221337Sdim IdxTy = new DIE(dwarf::DW_TAG_base_type); 1159221337Sdim addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t)); 1160221337Sdim addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, 1161221337Sdim dwarf::DW_ATE_signed); 1162221337Sdim addDie(IdxTy); 1163221337Sdim setIndexTyDie(IdxTy); 1164221337Sdim } 1165221337Sdim 1166221337Sdim // Add subranges to array type. 1167221337Sdim for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) { 1168221337Sdim DIDescriptor Element = Elements.getElement(i); 1169221337Sdim if (Element.getTag() == dwarf::DW_TAG_subrange_type) 1170221337Sdim constructSubrangeDIE(Buffer, DISubrange(Element), IdxTy); 1171221337Sdim } 1172221337Sdim} 1173221337Sdim 1174221337Sdim/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator. 1175221337SdimDIE *CompileUnit::constructEnumTypeDIE(DIEnumerator ETy) { 1176221337Sdim DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator); 1177221337Sdim StringRef Name = ETy.getName(); 1178221337Sdim addString(Enumerator, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); 1179221337Sdim int64_t Value = ETy.getEnumValue(); 1180221337Sdim addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value); 1181221337Sdim return Enumerator; 1182221337Sdim} 1183221337Sdim 1184226890Sdim/// constructContainingTypeDIEs - Construct DIEs for types that contain 1185226890Sdim/// vtables. 1186226890Sdimvoid CompileUnit::constructContainingTypeDIEs() { 1187226890Sdim for (DenseMap<DIE *, const MDNode *>::iterator CI = ContainingTypeMap.begin(), 1188226890Sdim CE = ContainingTypeMap.end(); CI != CE; ++CI) { 1189226890Sdim DIE *SPDie = CI->first; 1190226890Sdim const MDNode *N = CI->second; 1191226890Sdim if (!N) continue; 1192226890Sdim DIE *NDie = getDIE(N); 1193226890Sdim if (!NDie) continue; 1194226890Sdim addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie); 1195226890Sdim } 1196226890Sdim} 1197226890Sdim 1198226890Sdim/// constructVariableDIE - Construct a DIE for the given DbgVariable. 1199226890SdimDIE *CompileUnit::constructVariableDIE(DbgVariable *DV, bool isScopeAbstract) { 1200226890Sdim StringRef Name = DV->getName(); 1201226890Sdim if (Name.empty()) 1202226890Sdim return NULL; 1203226890Sdim 1204226890Sdim // Translate tag to proper Dwarf tag. 1205226890Sdim unsigned Tag = DV->getTag(); 1206226890Sdim 1207226890Sdim // Define variable debug information entry. 1208226890Sdim DIE *VariableDie = new DIE(Tag); 1209226890Sdim DbgVariable *AbsVar = DV->getAbstractVariable(); 1210226890Sdim DIE *AbsDIE = AbsVar ? AbsVar->getDIE() : NULL; 1211226890Sdim if (AbsDIE) 1212226890Sdim addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin, 1213226890Sdim dwarf::DW_FORM_ref4, AbsDIE); 1214226890Sdim else { 1215226890Sdim addString(VariableDie, dwarf::DW_AT_name, 1216226890Sdim dwarf::DW_FORM_string, Name); 1217226890Sdim addSourceLine(VariableDie, DV->getVariable()); 1218226890Sdim addType(VariableDie, DV->getType()); 1219226890Sdim } 1220226890Sdim 1221226890Sdim if (DV->isArtificial()) 1222226890Sdim addUInt(VariableDie, dwarf::DW_AT_artificial, 1223226890Sdim dwarf::DW_FORM_flag, 1); 1224226890Sdim 1225226890Sdim if (isScopeAbstract) { 1226226890Sdim DV->setDIE(VariableDie); 1227226890Sdim return VariableDie; 1228226890Sdim } 1229226890Sdim 1230226890Sdim // Add variable address. 1231226890Sdim 1232226890Sdim unsigned Offset = DV->getDotDebugLocOffset(); 1233226890Sdim if (Offset != ~0U) { 1234226890Sdim addLabel(VariableDie, dwarf::DW_AT_location, 1235226890Sdim dwarf::DW_FORM_data4, 1236226890Sdim Asm->GetTempSymbol("debug_loc", Offset)); 1237226890Sdim DV->setDIE(VariableDie); 1238226890Sdim return VariableDie; 1239226890Sdim } 1240226890Sdim 1241226890Sdim // Check if variable is described by a DBG_VALUE instruction. 1242226890Sdim if (const MachineInstr *DVInsn = DV->getMInsn()) { 1243226890Sdim bool updated = false; 1244226890Sdim if (DVInsn->getNumOperands() == 3) { 1245226890Sdim if (DVInsn->getOperand(0).isReg()) { 1246226890Sdim const MachineOperand RegOp = DVInsn->getOperand(0); 1247226890Sdim const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo(); 1248226890Sdim if (DVInsn->getOperand(1).isImm() && 1249226890Sdim TRI->getFrameRegister(*Asm->MF) == RegOp.getReg()) { 1250226890Sdim unsigned FrameReg = 0; 1251226890Sdim const TargetFrameLowering *TFI = Asm->TM.getFrameLowering(); 1252226890Sdim int Offset = 1253226890Sdim TFI->getFrameIndexReference(*Asm->MF, 1254226890Sdim DVInsn->getOperand(1).getImm(), 1255226890Sdim FrameReg); 1256226890Sdim MachineLocation Location(FrameReg, Offset); 1257226890Sdim addVariableAddress(DV, VariableDie, Location); 1258226890Sdim 1259226890Sdim } else if (RegOp.getReg()) 1260226890Sdim addVariableAddress(DV, VariableDie, 1261226890Sdim MachineLocation(RegOp.getReg())); 1262226890Sdim updated = true; 1263226890Sdim } 1264226890Sdim else if (DVInsn->getOperand(0).isImm()) 1265226890Sdim updated = 1266226890Sdim addConstantValue(VariableDie, DVInsn->getOperand(0), 1267226890Sdim DV->getType()); 1268226890Sdim else if (DVInsn->getOperand(0).isFPImm()) 1269226890Sdim updated = 1270226890Sdim addConstantFPValue(VariableDie, DVInsn->getOperand(0)); 1271226890Sdim else if (DVInsn->getOperand(0).isCImm()) 1272226890Sdim updated = 1273226890Sdim addConstantValue(VariableDie, 1274226890Sdim DVInsn->getOperand(0).getCImm(), 1275226890Sdim DV->getType().isUnsignedDIType()); 1276226890Sdim } else { 1277226890Sdim addVariableAddress(DV, VariableDie, 1278226890Sdim Asm->getDebugValueLocation(DVInsn)); 1279226890Sdim updated = true; 1280226890Sdim } 1281226890Sdim if (!updated) { 1282226890Sdim // If variableDie is not updated then DBG_VALUE instruction does not 1283226890Sdim // have valid variable info. 1284226890Sdim delete VariableDie; 1285226890Sdim return NULL; 1286226890Sdim } 1287226890Sdim DV->setDIE(VariableDie); 1288226890Sdim return VariableDie; 1289226890Sdim } else { 1290226890Sdim // .. else use frame index. 1291226890Sdim int FI = DV->getFrameIndex(); 1292226890Sdim if (FI != ~0) { 1293226890Sdim unsigned FrameReg = 0; 1294226890Sdim const TargetFrameLowering *TFI = Asm->TM.getFrameLowering(); 1295226890Sdim int Offset = 1296226890Sdim TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg); 1297226890Sdim MachineLocation Location(FrameReg, Offset); 1298226890Sdim addVariableAddress(DV, VariableDie, Location); 1299226890Sdim } 1300226890Sdim } 1301226890Sdim 1302226890Sdim DV->setDIE(VariableDie); 1303226890Sdim return VariableDie; 1304226890Sdim} 1305226890Sdim 1306221337Sdim/// createMemberDIE - Create new member DIE. 1307221337SdimDIE *CompileUnit::createMemberDIE(DIDerivedType DT) { 1308221337Sdim DIE *MemberDie = new DIE(DT.getTag()); 1309221337Sdim StringRef Name = DT.getName(); 1310221337Sdim if (!Name.empty()) 1311221337Sdim addString(MemberDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); 1312221337Sdim 1313221337Sdim addType(MemberDie, DT.getTypeDerivedFrom()); 1314221337Sdim 1315221337Sdim addSourceLine(MemberDie, DT); 1316221337Sdim 1317221337Sdim DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock(); 1318221337Sdim addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst); 1319221337Sdim 1320221337Sdim uint64_t Size = DT.getSizeInBits(); 1321221337Sdim uint64_t FieldSize = DT.getOriginalTypeSize(); 1322221337Sdim 1323221337Sdim if (Size != FieldSize) { 1324221337Sdim // Handle bitfield. 1325221337Sdim addUInt(MemberDie, dwarf::DW_AT_byte_size, 0, DT.getOriginalTypeSize()>>3); 1326221337Sdim addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits()); 1327221337Sdim 1328221337Sdim uint64_t Offset = DT.getOffsetInBits(); 1329221337Sdim uint64_t AlignMask = ~(DT.getAlignInBits() - 1); 1330221337Sdim uint64_t HiMark = (Offset + FieldSize) & AlignMask; 1331221337Sdim uint64_t FieldOffset = (HiMark - FieldSize); 1332221337Sdim Offset -= FieldOffset; 1333221337Sdim 1334221337Sdim // Maybe we need to work from the other end. 1335221337Sdim if (Asm->getTargetData().isLittleEndian()) 1336221337Sdim Offset = FieldSize - (Offset + Size); 1337221337Sdim addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset); 1338221337Sdim 1339221337Sdim // Here WD_AT_data_member_location points to the anonymous 1340221337Sdim // field that includes this bit field. 1341221337Sdim addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, FieldOffset >> 3); 1342221337Sdim 1343221337Sdim } else 1344221337Sdim // This is not a bitfield. 1345221337Sdim addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3); 1346221337Sdim 1347221337Sdim if (DT.getTag() == dwarf::DW_TAG_inheritance 1348221337Sdim && DT.isVirtual()) { 1349221337Sdim 1350221337Sdim // For C++, virtual base classes are not at fixed offset. Use following 1351221337Sdim // expression to extract appropriate offset from vtable. 1352221337Sdim // BaseAddr = ObAddr + *((*ObAddr) - Offset) 1353221337Sdim 1354221337Sdim DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock(); 1355221337Sdim addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup); 1356221337Sdim addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); 1357221337Sdim addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); 1358221337Sdim addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits()); 1359221337Sdim addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_minus); 1360221337Sdim addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); 1361221337Sdim addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); 1362221337Sdim 1363221337Sdim addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, 1364221337Sdim VBaseLocationDie); 1365221337Sdim } else 1366221337Sdim addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie); 1367221337Sdim 1368221337Sdim if (DT.isProtected()) 1369221337Sdim addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, 1370221337Sdim dwarf::DW_ACCESS_protected); 1371221337Sdim else if (DT.isPrivate()) 1372221337Sdim addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, 1373221337Sdim dwarf::DW_ACCESS_private); 1374221337Sdim // Otherwise C++ member and base classes are considered public. 1375226890Sdim else 1376221337Sdim addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, 1377221337Sdim dwarf::DW_ACCESS_public); 1378221337Sdim if (DT.isVirtual()) 1379221337Sdim addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, 1380221337Sdim dwarf::DW_VIRTUALITY_virtual); 1381221337Sdim 1382221337Sdim // Objective-C properties. 1383221337Sdim StringRef PropertyName = DT.getObjCPropertyName(); 1384221337Sdim if (!PropertyName.empty()) { 1385221337Sdim addString(MemberDie, dwarf::DW_AT_APPLE_property_name, dwarf::DW_FORM_string, 1386221337Sdim PropertyName); 1387221337Sdim StringRef GetterName = DT.getObjCPropertyGetterName(); 1388221337Sdim if (!GetterName.empty()) 1389221337Sdim addString(MemberDie, dwarf::DW_AT_APPLE_property_getter, 1390221337Sdim dwarf::DW_FORM_string, GetterName); 1391221337Sdim StringRef SetterName = DT.getObjCPropertySetterName(); 1392221337Sdim if (!SetterName.empty()) 1393221337Sdim addString(MemberDie, dwarf::DW_AT_APPLE_property_setter, 1394221337Sdim dwarf::DW_FORM_string, SetterName); 1395221337Sdim unsigned PropertyAttributes = 0; 1396221337Sdim if (DT.isReadOnlyObjCProperty()) 1397221337Sdim PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readonly; 1398221337Sdim if (DT.isReadWriteObjCProperty()) 1399221337Sdim PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readwrite; 1400221337Sdim if (DT.isAssignObjCProperty()) 1401221337Sdim PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_assign; 1402221337Sdim if (DT.isRetainObjCProperty()) 1403221337Sdim PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_retain; 1404221337Sdim if (DT.isCopyObjCProperty()) 1405221337Sdim PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_copy; 1406221337Sdim if (DT.isNonAtomicObjCProperty()) 1407221337Sdim PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_nonatomic; 1408221337Sdim if (PropertyAttributes) 1409221337Sdim addUInt(MemberDie, dwarf::DW_AT_APPLE_property_attribute, 0, 1410221337Sdim PropertyAttributes); 1411221337Sdim } 1412221337Sdim return MemberDie; 1413221337Sdim} 1414