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