blob: 18a965364ca3fb7eb9edd7fba5776188baf8a902 [file] [log] [blame]
Devang Patel161b2f42011-04-12 23:21:44 +00001//===-- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Unit ------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains support for writing dwarf compile unit.
11//
12//===----------------------------------------------------------------------===//
13
14#define DEBUG_TYPE "dwarfdebug"
15
16#include "DwarfCompileUnit.h"
17#include "DwarfDebug.h"
18#include "llvm/Constants.h"
Devang Patel6f9d8ff2011-08-15 17:57:41 +000019#include "llvm/GlobalVariable.h"
20#include "llvm/Instructions.h"
Devang Patel161b2f42011-04-12 23:21:44 +000021#include "llvm/Analysis/DIBuilder.h"
Eric Christopherd61c34b2011-11-11 03:16:32 +000022#include "llvm/Support/Debug.h"
Devang Patel6f9d8ff2011-08-15 17:57:41 +000023#include "llvm/Target/Mangler.h"
Devang Patel161b2f42011-04-12 23:21:44 +000024#include "llvm/Target/TargetData.h"
25#include "llvm/Target/TargetFrameLowering.h"
26#include "llvm/Target/TargetMachine.h"
27#include "llvm/Target/TargetRegisterInfo.h"
28#include "llvm/ADT/APFloat.h"
29#include "llvm/Support/ErrorHandling.h"
30
31using namespace llvm;
32
33/// CompileUnit - Compile unit constructor.
34CompileUnit::CompileUnit(unsigned I, DIE *D, AsmPrinter *A, DwarfDebug *DW)
35 : ID(I), CUDie(D), Asm(A), DD(DW), IndexTyDie(0) {
36 DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1);
37}
38
39/// ~CompileUnit - Destructor for compile unit.
40CompileUnit::~CompileUnit() {
41 for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
42 DIEBlocks[j]->~DIEBlock();
43}
44
45/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug
46/// information entry.
47DIEEntry *CompileUnit::createDIEEntry(DIE *Entry) {
48 DIEEntry *Value = new (DIEValueAllocator) DIEEntry(Entry);
49 return Value;
50}
51
52/// addUInt - Add an unsigned integer attribute data and value.
53///
54void CompileUnit::addUInt(DIE *Die, unsigned Attribute,
55 unsigned Form, uint64_t Integer) {
56 if (!Form) Form = DIEInteger::BestForm(false, Integer);
57 DIEValue *Value = Integer == 1 ?
58 DIEIntegerOne : new (DIEValueAllocator) DIEInteger(Integer);
59 Die->addValue(Attribute, Form, Value);
60}
61
62/// addSInt - Add an signed integer attribute data and value.
63///
64void CompileUnit::addSInt(DIE *Die, unsigned Attribute,
65 unsigned Form, int64_t Integer) {
66 if (!Form) Form = DIEInteger::BestForm(true, Integer);
67 DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
68 Die->addValue(Attribute, Form, Value);
69}
70
Nick Lewycky6a7efcf2011-10-28 05:29:47 +000071/// addString - Add a string attribute data and value. We always emit a
72/// reference to the string pool instead of immediate strings so that DIEs have
73/// more predictable sizes.
Nick Lewycky390c40d2011-10-27 06:44:11 +000074void CompileUnit::addString(DIE *Die, unsigned Attribute, StringRef String) {
Nick Lewycky6a7efcf2011-10-28 05:29:47 +000075 MCSymbol *Symb = DD->getStringPoolEntry(String);
76 DIEValue *Value;
77 if (Asm->needsRelocationsForDwarfStringPool())
78 Value = new (DIEValueAllocator) DIELabel(Symb);
79 else {
80 MCSymbol *StringPool = DD->getStringPool();
81 Value = new (DIEValueAllocator) DIEDelta(Symb, StringPool);
Nick Lewycky390c40d2011-10-27 06:44:11 +000082 }
Nick Lewycky6a7efcf2011-10-28 05:29:47 +000083 Die->addValue(Attribute, dwarf::DW_FORM_strp, Value);
Devang Patel161b2f42011-04-12 23:21:44 +000084}
85
86/// addLabel - Add a Dwarf label attribute data and value.
87///
88void CompileUnit::addLabel(DIE *Die, unsigned Attribute, unsigned Form,
89 const MCSymbol *Label) {
90 DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
91 Die->addValue(Attribute, Form, Value);
92}
93
94/// addDelta - Add a label delta attribute data and value.
95///
96void CompileUnit::addDelta(DIE *Die, unsigned Attribute, unsigned Form,
97 const MCSymbol *Hi, const MCSymbol *Lo) {
98 DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo);
99 Die->addValue(Attribute, Form, Value);
100}
101
102/// addDIEEntry - Add a DIE attribute data and value.
103///
104void CompileUnit::addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form,
105 DIE *Entry) {
106 Die->addValue(Attribute, Form, createDIEEntry(Entry));
107}
108
Devang Patel161b2f42011-04-12 23:21:44 +0000109/// addBlock - Add block data.
110///
111void CompileUnit::addBlock(DIE *Die, unsigned Attribute, unsigned Form,
112 DIEBlock *Block) {
113 Block->ComputeSize(Asm);
114 DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.
115 Die->addValue(Attribute, Block->BestForm(), Block);
116}
117
118/// addSourceLine - Add location information to specified debug information
119/// entry.
120void CompileUnit::addSourceLine(DIE *Die, DIVariable V) {
121 // Verify variable.
122 if (!V.Verify())
123 return;
124
125 unsigned Line = V.getLineNumber();
126 if (Line == 0)
127 return;
128 unsigned FileID = DD->GetOrCreateSourceID(V.getContext().getFilename(),
129 V.getContext().getDirectory());
130 assert(FileID && "Invalid file id");
131 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
132 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
133}
134
135/// addSourceLine - Add location information to specified debug information
136/// entry.
137void CompileUnit::addSourceLine(DIE *Die, DIGlobalVariable G) {
138 // Verify global variable.
139 if (!G.Verify())
140 return;
141
142 unsigned Line = G.getLineNumber();
143 if (Line == 0)
144 return;
Nick Lewycky746cb672011-10-26 22:55:33 +0000145 unsigned FileID = DD->GetOrCreateSourceID(G.getFilename(), G.getDirectory());
Devang Patel161b2f42011-04-12 23:21:44 +0000146 assert(FileID && "Invalid file id");
147 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
148 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
149}
150
151/// addSourceLine - Add location information to specified debug information
152/// entry.
153void CompileUnit::addSourceLine(DIE *Die, DISubprogram SP) {
154 // Verify subprogram.
155 if (!SP.Verify())
156 return;
157 // If the line number is 0, don't add it.
158 if (SP.getLineNumber() == 0)
159 return;
160
161 unsigned Line = SP.getLineNumber();
162 if (!SP.getContext().Verify())
163 return;
Nick Lewycky746cb672011-10-26 22:55:33 +0000164 unsigned FileID = DD->GetOrCreateSourceID(SP.getFilename(),
165 SP.getDirectory());
Devang Patel161b2f42011-04-12 23:21:44 +0000166 assert(FileID && "Invalid file id");
167 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
168 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
169}
170
171/// addSourceLine - Add location information to specified debug information
172/// entry.
173void CompileUnit::addSourceLine(DIE *Die, DIType Ty) {
174 // Verify type.
175 if (!Ty.Verify())
176 return;
177
178 unsigned Line = Ty.getLineNumber();
179 if (Line == 0 || !Ty.getContext().Verify())
180 return;
Nick Lewycky746cb672011-10-26 22:55:33 +0000181 unsigned FileID = DD->GetOrCreateSourceID(Ty.getFilename(),
182 Ty.getDirectory());
Devang Patel161b2f42011-04-12 23:21:44 +0000183 assert(FileID && "Invalid file id");
184 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
185 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
186}
187
188/// addSourceLine - Add location information to specified debug information
189/// entry.
190void CompileUnit::addSourceLine(DIE *Die, DINameSpace NS) {
191 // Verify namespace.
192 if (!NS.Verify())
193 return;
194
195 unsigned Line = NS.getLineNumber();
196 if (Line == 0)
197 return;
198 StringRef FN = NS.getFilename();
199
200 unsigned FileID = DD->GetOrCreateSourceID(FN, NS.getDirectory());
201 assert(FileID && "Invalid file id");
202 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
203 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
204}
205
Devang Patele1cdf842011-04-27 22:45:24 +0000206/// addVariableAddress - Add DW_AT_location attribute for a
207/// DbgVariable based on provided MachineLocation.
208void CompileUnit::addVariableAddress(DbgVariable *&DV, DIE *Die,
209 MachineLocation Location) {
Devang Patel161b2f42011-04-12 23:21:44 +0000210 if (DV->variableHasComplexAddress())
211 addComplexAddress(DV, Die, dwarf::DW_AT_location, Location);
212 else if (DV->isBlockByrefVariable())
213 addBlockByrefAddress(DV, Die, dwarf::DW_AT_location, Location);
214 else
215 addAddress(Die, dwarf::DW_AT_location, Location);
216}
217
Devang Patel116da2f2011-04-26 19:06:18 +0000218/// addRegisterOp - Add register operand.
219void CompileUnit::addRegisterOp(DIE *TheDie, unsigned Reg) {
220 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
221 unsigned DWReg = RI->getDwarfRegNum(Reg, false);
222 if (DWReg < 32)
223 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + DWReg);
224 else {
225 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx);
226 addUInt(TheDie, 0, dwarf::DW_FORM_udata, DWReg);
227 }
228}
229
230/// addRegisterOffset - Add register offset.
231void CompileUnit::addRegisterOffset(DIE *TheDie, unsigned Reg,
232 int64_t Offset) {
233 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
234 unsigned DWReg = RI->getDwarfRegNum(Reg, false);
235 const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
236 if (Reg == TRI->getFrameRegister(*Asm->MF))
237 // If variable offset is based in frame register then use fbreg.
238 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_fbreg);
239 else if (DWReg < 32)
240 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + DWReg);
241 else {
242 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
243 addUInt(TheDie, 0, dwarf::DW_FORM_udata, DWReg);
244 }
245 addSInt(TheDie, 0, dwarf::DW_FORM_sdata, Offset);
246}
247
248/// addAddress - Add an address attribute to a die based on the location
249/// provided.
250void CompileUnit::addAddress(DIE *Die, unsigned Attribute,
251 const MachineLocation &Location) {
252 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
253
254 if (Location.isReg())
255 addRegisterOp(Block, Location.getReg());
256 else
257 addRegisterOffset(Block, Location.getReg(), Location.getOffset());
258
259 // Now attach the location information to the DIE.
260 addBlock(Die, Attribute, 0, Block);
261}
262
Devang Patel161b2f42011-04-12 23:21:44 +0000263/// addComplexAddress - Start with the address based on the location provided,
264/// and generate the DWARF information necessary to find the actual variable
265/// given the extra address information encoded in the DIVariable, starting from
266/// the starting location. Add the DWARF information to the die.
267///
268void CompileUnit::addComplexAddress(DbgVariable *&DV, DIE *Die,
269 unsigned Attribute,
270 const MachineLocation &Location) {
Devang Patel161b2f42011-04-12 23:21:44 +0000271 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patelc26f5442011-04-28 02:22:40 +0000272 unsigned N = DV->getNumAddrElements();
273 unsigned i = 0;
274 if (Location.isReg()) {
275 if (N >= 2 && DV->getAddrElement(0) == DIBuilder::OpPlus) {
276 // If first address element is OpPlus then emit
277 // DW_OP_breg + Offset instead of DW_OP_reg + Offset.
278 addRegisterOffset(Block, Location.getReg(), DV->getAddrElement(1));
279 i = 2;
280 } else
281 addRegisterOp(Block, Location.getReg());
282 }
Devang Patel116da2f2011-04-26 19:06:18 +0000283 else
284 addRegisterOffset(Block, Location.getReg(), Location.getOffset());
Devang Patel161b2f42011-04-12 23:21:44 +0000285
Devang Patelc26f5442011-04-28 02:22:40 +0000286 for (;i < N; ++i) {
Devang Patel161b2f42011-04-12 23:21:44 +0000287 uint64_t Element = DV->getAddrElement(i);
Devang Patel161b2f42011-04-12 23:21:44 +0000288 if (Element == DIBuilder::OpPlus) {
289 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
290 addUInt(Block, 0, dwarf::DW_FORM_udata, DV->getAddrElement(++i));
291 } else if (Element == DIBuilder::OpDeref) {
292 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
293 } else llvm_unreachable("unknown DIBuilder Opcode");
294 }
295
296 // Now attach the location information to the DIE.
297 addBlock(Die, Attribute, 0, Block);
298}
299
300/* Byref variables, in Blocks, are declared by the programmer as "SomeType
301 VarName;", but the compiler creates a __Block_byref_x_VarName struct, and
302 gives the variable VarName either the struct, or a pointer to the struct, as
303 its type. This is necessary for various behind-the-scenes things the
304 compiler needs to do with by-reference variables in Blocks.
305
306 However, as far as the original *programmer* is concerned, the variable
307 should still have type 'SomeType', as originally declared.
308
309 The function getBlockByrefType dives into the __Block_byref_x_VarName
310 struct to find the original type of the variable, which is then assigned to
311 the variable's Debug Information Entry as its real type. So far, so good.
312 However now the debugger will expect the variable VarName to have the type
313 SomeType. So we need the location attribute for the variable to be an
314 expression that explains to the debugger how to navigate through the
315 pointers and struct to find the actual variable of type SomeType.
316
317 The following function does just that. We start by getting
318 the "normal" location for the variable. This will be the location
319 of either the struct __Block_byref_x_VarName or the pointer to the
320 struct __Block_byref_x_VarName.
321
322 The struct will look something like:
323
324 struct __Block_byref_x_VarName {
325 ... <various fields>
326 struct __Block_byref_x_VarName *forwarding;
327 ... <various other fields>
328 SomeType VarName;
329 ... <maybe more fields>
330 };
331
332 If we are given the struct directly (as our starting point) we
333 need to tell the debugger to:
334
335 1). Add the offset of the forwarding field.
336
337 2). Follow that pointer to get the real __Block_byref_x_VarName
338 struct to use (the real one may have been copied onto the heap).
339
340 3). Add the offset for the field VarName, to find the actual variable.
341
342 If we started with a pointer to the struct, then we need to
343 dereference that pointer first, before the other steps.
344 Translating this into DWARF ops, we will need to append the following
345 to the current location description for the variable:
346
347 DW_OP_deref -- optional, if we start with a pointer
348 DW_OP_plus_uconst <forward_fld_offset>
349 DW_OP_deref
350 DW_OP_plus_uconst <varName_fld_offset>
351
352 That is what this function does. */
353
354/// addBlockByrefAddress - Start with the address based on the location
355/// provided, and generate the DWARF information necessary to find the
356/// actual Block variable (navigating the Block struct) based on the
357/// starting location. Add the DWARF information to the die. For
358/// more information, read large comment just above here.
359///
360void CompileUnit::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
361 unsigned Attribute,
362 const MachineLocation &Location) {
363 DIType Ty = DV->getType();
364 DIType TmpTy = Ty;
365 unsigned Tag = Ty.getTag();
366 bool isPointer = false;
367
368 StringRef varName = DV->getName();
369
370 if (Tag == dwarf::DW_TAG_pointer_type) {
371 DIDerivedType DTy = DIDerivedType(Ty);
372 TmpTy = DTy.getTypeDerivedFrom();
373 isPointer = true;
374 }
375
376 DICompositeType blockStruct = DICompositeType(TmpTy);
377
378 // Find the __forwarding field and the variable field in the __Block_byref
379 // struct.
380 DIArray Fields = blockStruct.getTypeArray();
381 DIDescriptor varField = DIDescriptor();
382 DIDescriptor forwardingField = DIDescriptor();
383
384 for (unsigned i = 0, N = Fields.getNumElements(); i < N; ++i) {
385 DIDescriptor Element = Fields.getElement(i);
386 DIDerivedType DT = DIDerivedType(Element);
387 StringRef fieldName = DT.getName();
388 if (fieldName == "__forwarding")
389 forwardingField = Element;
390 else if (fieldName == varName)
391 varField = Element;
392 }
393
394 // Get the offsets for the forwarding field and the variable field.
395 unsigned forwardingFieldOffset =
396 DIDerivedType(forwardingField).getOffsetInBits() >> 3;
397 unsigned varFieldOffset =
398 DIDerivedType(varField).getOffsetInBits() >> 3;
399
400 // Decode the original location, and use that as the start of the byref
401 // variable's location.
402 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
403 unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
404 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
405
406 if (Location.isReg()) {
407 if (Reg < 32)
408 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
409 else {
410 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx);
411 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
412 }
413 } else {
414 if (Reg < 32)
415 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
416 else {
417 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
418 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
419 }
420
421 addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
422 }
423
424 // If we started with a pointer to the __Block_byref... struct, then
425 // the first thing we need to do is dereference the pointer (DW_OP_deref).
426 if (isPointer)
427 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
428
429 // Next add the offset for the '__forwarding' field:
430 // DW_OP_plus_uconst ForwardingFieldOffset. Note there's no point in
431 // adding the offset if it's 0.
432 if (forwardingFieldOffset > 0) {
433 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
434 addUInt(Block, 0, dwarf::DW_FORM_udata, forwardingFieldOffset);
435 }
436
437 // Now dereference the __forwarding field to get to the real __Block_byref
438 // struct: DW_OP_deref.
439 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
440
441 // Now that we've got the real __Block_byref... struct, add the offset
442 // for the variable's field to get to the location of the actual variable:
443 // DW_OP_plus_uconst varFieldOffset. Again, don't add if it's 0.
444 if (varFieldOffset > 0) {
445 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
446 addUInt(Block, 0, dwarf::DW_FORM_udata, varFieldOffset);
447 }
448
449 // Now attach the location information to the DIE.
450 addBlock(Die, Attribute, 0, Block);
451}
452
Devang Patel4ec14b02011-07-20 21:57:04 +0000453/// isTypeSigned - Return true if the type is signed.
454static bool isTypeSigned(DIType Ty, int *SizeInBits) {
455 if (Ty.isDerivedType())
456 return isTypeSigned(DIDerivedType(Ty).getTypeDerivedFrom(), SizeInBits);
457 if (Ty.isBasicType())
458 if (DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed
459 || DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed_char) {
460 *SizeInBits = Ty.getSizeInBits();
461 return true;
462 }
463 return false;
464}
465
Devang Patel161b2f42011-04-12 23:21:44 +0000466/// addConstantValue - Add constant value entry in variable DIE.
Devang Patelb58128e2011-05-27 16:45:18 +0000467bool CompileUnit::addConstantValue(DIE *Die, const MachineOperand &MO,
468 DIType Ty) {
Nick Lewycky746cb672011-10-26 22:55:33 +0000469 assert(MO.isImm() && "Invalid machine operand!");
Devang Patel161b2f42011-04-12 23:21:44 +0000470 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel4ec14b02011-07-20 21:57:04 +0000471 int SizeInBits = -1;
472 bool SignedConstant = isTypeSigned(Ty, &SizeInBits);
473 unsigned Form = SignedConstant ? dwarf::DW_FORM_sdata : dwarf::DW_FORM_udata;
474 switch (SizeInBits) {
475 case 8: Form = dwarf::DW_FORM_data1; break;
476 case 16: Form = dwarf::DW_FORM_data2; break;
477 case 32: Form = dwarf::DW_FORM_data4; break;
478 case 64: Form = dwarf::DW_FORM_data8; break;
Devang Patel045c1d42011-05-27 19:13:26 +0000479 default: break;
480 }
Devang Patel4ec14b02011-07-20 21:57:04 +0000481 SignedConstant ? addSInt(Block, 0, Form, MO.getImm())
482 : addUInt(Block, 0, Form, MO.getImm());
Devang Patel72f0d9c2011-05-27 18:15:52 +0000483
Devang Patel161b2f42011-04-12 23:21:44 +0000484 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
485 return true;
486}
487
488/// addConstantFPValue - Add constant value entry in variable DIE.
489bool CompileUnit::addConstantFPValue(DIE *Die, const MachineOperand &MO) {
Nick Lewycky390c40d2011-10-27 06:44:11 +0000490 assert (MO.isFPImm() && "Invalid machine operand!");
Devang Patel161b2f42011-04-12 23:21:44 +0000491 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
492 APFloat FPImm = MO.getFPImm()->getValueAPF();
493
494 // Get the raw data form of the floating point.
495 const APInt FltVal = FPImm.bitcastToAPInt();
496 const char *FltPtr = (const char*)FltVal.getRawData();
497
498 int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte.
499 bool LittleEndian = Asm->getTargetData().isLittleEndian();
500 int Incr = (LittleEndian ? 1 : -1);
501 int Start = (LittleEndian ? 0 : NumBytes - 1);
502 int Stop = (LittleEndian ? NumBytes : -1);
503
504 // Output the constant to DWARF one byte at a time.
505 for (; Start != Stop; Start += Incr)
506 addUInt(Block, 0, dwarf::DW_FORM_data1,
507 (unsigned char)0xFF & FltPtr[Start]);
508
509 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
510 return true;
511}
512
513/// addConstantValue - Add constant value entry in variable DIE.
Devang Patel8594d422011-06-24 20:46:11 +0000514bool CompileUnit::addConstantValue(DIE *Die, const ConstantInt *CI,
Devang Patel161b2f42011-04-12 23:21:44 +0000515 bool Unsigned) {
Devang Pateld6a81362011-05-28 00:39:18 +0000516 unsigned CIBitWidth = CI->getBitWidth();
517 if (CIBitWidth <= 64) {
518 unsigned form = 0;
519 switch (CIBitWidth) {
520 case 8: form = dwarf::DW_FORM_data1; break;
521 case 16: form = dwarf::DW_FORM_data2; break;
522 case 32: form = dwarf::DW_FORM_data4; break;
523 case 64: form = dwarf::DW_FORM_data8; break;
524 default:
525 form = Unsigned ? dwarf::DW_FORM_udata : dwarf::DW_FORM_sdata;
526 }
Devang Patel161b2f42011-04-12 23:21:44 +0000527 if (Unsigned)
Devang Pateld6a81362011-05-28 00:39:18 +0000528 addUInt(Die, dwarf::DW_AT_const_value, form, CI->getZExtValue());
Devang Patel161b2f42011-04-12 23:21:44 +0000529 else
Devang Pateld6a81362011-05-28 00:39:18 +0000530 addSInt(Die, dwarf::DW_AT_const_value, form, CI->getSExtValue());
Devang Patel161b2f42011-04-12 23:21:44 +0000531 return true;
532 }
533
534 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
535
536 // Get the raw data form of the large APInt.
537 const APInt Val = CI->getValue();
NAKAMURA Takumic3e48c32011-10-28 14:12:22 +0000538 const uint64_t *Ptr64 = Val.getRawData();
Devang Patel161b2f42011-04-12 23:21:44 +0000539
540 int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte.
541 bool LittleEndian = Asm->getTargetData().isLittleEndian();
Devang Patel161b2f42011-04-12 23:21:44 +0000542
543 // Output the constant to DWARF one byte at a time.
NAKAMURA Takumic3e48c32011-10-28 14:12:22 +0000544 for (int i = 0; i < NumBytes; i++) {
545 uint8_t c;
546 if (LittleEndian)
547 c = Ptr64[i / 8] >> (8 * (i & 7));
548 else
549 c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7));
550 addUInt(Block, 0, dwarf::DW_FORM_data1, c);
551 }
Devang Patel161b2f42011-04-12 23:21:44 +0000552
553 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
554 return true;
555}
556
557/// addTemplateParams - Add template parameters in buffer.
558void CompileUnit::addTemplateParams(DIE &Buffer, DIArray TParams) {
559 // Add template parameters.
560 for (unsigned i = 0, e = TParams.getNumElements(); i != e; ++i) {
561 DIDescriptor Element = TParams.getElement(i);
562 if (Element.isTemplateTypeParameter())
563 Buffer.addChild(getOrCreateTemplateTypeParameterDIE(
564 DITemplateTypeParameter(Element)));
565 else if (Element.isTemplateValueParameter())
566 Buffer.addChild(getOrCreateTemplateValueParameterDIE(
567 DITemplateValueParameter(Element)));
568 }
Devang Patel161b2f42011-04-12 23:21:44 +0000569}
Nick Lewycky746cb672011-10-26 22:55:33 +0000570
Devang Patel161b2f42011-04-12 23:21:44 +0000571/// addToContextOwner - Add Die into the list of its context owner's children.
572void CompileUnit::addToContextOwner(DIE *Die, DIDescriptor Context) {
573 if (Context.isType()) {
574 DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context));
575 ContextDIE->addChild(Die);
576 } else if (Context.isNameSpace()) {
577 DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context));
578 ContextDIE->addChild(Die);
579 } else if (Context.isSubprogram()) {
Devang Pateldbc64af2011-08-15 17:24:54 +0000580 DIE *ContextDIE = getOrCreateSubprogramDIE(DISubprogram(Context));
Devang Patel161b2f42011-04-12 23:21:44 +0000581 ContextDIE->addChild(Die);
582 } else if (DIE *ContextDIE = getDIE(Context))
583 ContextDIE->addChild(Die);
584 else
585 addDie(Die);
586}
587
588/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
589/// given DIType.
Devang Patel94c7ddb2011-08-16 22:09:43 +0000590DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
591 DIType Ty(TyNode);
592 if (!Ty.Verify())
593 return NULL;
Devang Patel161b2f42011-04-12 23:21:44 +0000594 DIE *TyDIE = getDIE(Ty);
595 if (TyDIE)
596 return TyDIE;
597
598 // Create new type.
599 TyDIE = new DIE(dwarf::DW_TAG_base_type);
600 insertDIE(Ty, TyDIE);
601 if (Ty.isBasicType())
602 constructTypeDIE(*TyDIE, DIBasicType(Ty));
603 else if (Ty.isCompositeType())
604 constructTypeDIE(*TyDIE, DICompositeType(Ty));
605 else {
606 assert(Ty.isDerivedType() && "Unknown kind of DIType");
607 constructTypeDIE(*TyDIE, DIDerivedType(Ty));
608 }
Eric Christopher1b3f9192011-11-10 19:52:58 +0000609 // If this is a named finished type then include it in the list of types
610 // for the accelerator tables.
611 if (!Ty.getName().empty() && !Ty.isForwardDecl())
612 addAccelType(Ty.getName(), TyDIE);
613
Devang Patel161b2f42011-04-12 23:21:44 +0000614 addToContextOwner(TyDIE, Ty.getContext());
615 return TyDIE;
616}
617
618/// addType - Add a new type attribute to the specified entity.
619void CompileUnit::addType(DIE *Entity, DIType Ty) {
620 if (!Ty.Verify())
621 return;
622
623 // Check for pre-existence.
624 DIEEntry *Entry = getDIEEntry(Ty);
625 // If it exists then use the existing value.
626 if (Entry) {
627 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
628 return;
629 }
630
631 // Construct type.
632 DIE *Buffer = getOrCreateTypeDIE(Ty);
633
634 // Set up proxy.
635 Entry = createDIEEntry(Buffer);
636 insertDIEEntry(Ty, Entry);
Devang Patel161b2f42011-04-12 23:21:44 +0000637 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
Devang Patele9ae06c2011-05-31 22:56:51 +0000638
639 // If this is a complete composite type then include it in the
640 // list of global types.
Devang Patelc20bdf12011-06-01 00:23:24 +0000641 addGlobalType(Ty);
Devang Patel66658e42011-05-31 23:30:30 +0000642}
643
644/// addGlobalType - Add a new global type to the compile unit.
645///
Devang Patelc20bdf12011-06-01 00:23:24 +0000646void CompileUnit::addGlobalType(DIType Ty) {
Devang Patele9ae06c2011-05-31 22:56:51 +0000647 DIDescriptor Context = Ty.getContext();
648 if (Ty.isCompositeType() && !Ty.getName().empty() && !Ty.isForwardDecl()
Devang Patel94c7ddb2011-08-16 22:09:43 +0000649 && (!Context || Context.isCompileUnit() || Context.isFile()
650 || Context.isNameSpace()))
Devang Patelc20bdf12011-06-01 00:23:24 +0000651 if (DIEEntry *Entry = getDIEEntry(Ty))
652 GlobalTypes[Ty.getName()] = Entry->getEntry();
Devang Patel161b2f42011-04-12 23:21:44 +0000653}
654
Devang Patel31c5d052011-05-06 16:57:54 +0000655/// addPubTypes - Add type for pubtypes section.
656void CompileUnit::addPubTypes(DISubprogram SP) {
657 DICompositeType SPTy = SP.getType();
658 unsigned SPTag = SPTy.getTag();
659 if (SPTag != dwarf::DW_TAG_subroutine_type)
660 return;
661
662 DIArray Args = SPTy.getTypeArray();
663 for (unsigned i = 0, e = Args.getNumElements(); i != e; ++i) {
664 DIType ATy(Args.getElement(i));
665 if (!ATy.Verify())
666 continue;
Devang Patelc20bdf12011-06-01 00:23:24 +0000667 addGlobalType(ATy);
Devang Patel31c5d052011-05-06 16:57:54 +0000668 }
669}
670
Devang Patel161b2f42011-04-12 23:21:44 +0000671/// constructTypeDIE - Construct basic type die from DIBasicType.
672void CompileUnit::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
673 // Get core information.
674 StringRef Name = BTy.getName();
Devang Patel161b2f42011-04-12 23:21:44 +0000675 // Add name if not anonymous or intermediate type.
676 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000677 addString(&Buffer, dwarf::DW_AT_name, Name);
Devang Patel734a67c2011-09-14 23:13:28 +0000678
679 if (BTy.getTag() == dwarf::DW_TAG_unspecified_type) {
680 Buffer.setTag(dwarf::DW_TAG_unspecified_type);
681 // Unspecified types has only name, nothing else.
682 return;
683 }
684
685 Buffer.setTag(dwarf::DW_TAG_base_type);
Nick Lewycky746cb672011-10-26 22:55:33 +0000686 addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
Devang Patel734a67c2011-09-14 23:13:28 +0000687 BTy.getEncoding());
688
Devang Patel161b2f42011-04-12 23:21:44 +0000689 uint64_t Size = BTy.getSizeInBits() >> 3;
690 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
691}
692
693/// constructTypeDIE - Construct derived type die from DIDerivedType.
694void CompileUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
695 // Get core information.
696 StringRef Name = DTy.getName();
697 uint64_t Size = DTy.getSizeInBits() >> 3;
698 unsigned Tag = DTy.getTag();
699
700 // FIXME - Workaround for templates.
701 if (Tag == dwarf::DW_TAG_inheritance) Tag = dwarf::DW_TAG_reference_type;
702
703 Buffer.setTag(Tag);
704
705 // Map to main type, void will not have a type.
706 DIType FromTy = DTy.getTypeDerivedFrom();
707 addType(&Buffer, FromTy);
708
709 // Add name if not anonymous or intermediate type.
710 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000711 addString(&Buffer, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +0000712
713 // Add size if non-zero (derived types might be zero-sized.)
714 if (Size)
715 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
716
717 // Add source line info if available and TyDesc is not a forward declaration.
718 if (!DTy.isForwardDecl())
719 addSourceLine(&Buffer, DTy);
720}
721
722/// constructTypeDIE - Construct type DIE from DICompositeType.
723void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
724 // Get core information.
725 StringRef Name = CTy.getName();
726
727 uint64_t Size = CTy.getSizeInBits() >> 3;
728 unsigned Tag = CTy.getTag();
729 Buffer.setTag(Tag);
730
731 switch (Tag) {
732 case dwarf::DW_TAG_vector_type:
733 case dwarf::DW_TAG_array_type:
734 constructArrayTypeDIE(Buffer, &CTy);
735 break;
736 case dwarf::DW_TAG_enumeration_type: {
737 DIArray Elements = CTy.getTypeArray();
738
739 // Add enumerators to enumeration type.
740 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
741 DIE *ElemDie = NULL;
742 DIDescriptor Enum(Elements.getElement(i));
743 if (Enum.isEnumerator()) {
744 ElemDie = constructEnumTypeDIE(DIEnumerator(Enum));
745 Buffer.addChild(ElemDie);
746 }
747 }
748 }
749 break;
750 case dwarf::DW_TAG_subroutine_type: {
751 // Add return type.
752 DIArray Elements = CTy.getTypeArray();
753 DIDescriptor RTy = Elements.getElement(0);
754 addType(&Buffer, DIType(RTy));
755
756 bool isPrototyped = true;
757 // Add arguments.
758 for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
759 DIDescriptor Ty = Elements.getElement(i);
760 if (Ty.isUnspecifiedParameter()) {
761 DIE *Arg = new DIE(dwarf::DW_TAG_unspecified_parameters);
762 Buffer.addChild(Arg);
763 isPrototyped = false;
764 } else {
765 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
766 addType(Arg, DIType(Ty));
767 Buffer.addChild(Arg);
768 }
769 }
770 // Add prototype flag.
771 if (isPrototyped)
772 addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
773 }
774 break;
775 case dwarf::DW_TAG_structure_type:
776 case dwarf::DW_TAG_union_type:
777 case dwarf::DW_TAG_class_type: {
778 // Add elements to structure type.
779 DIArray Elements = CTy.getTypeArray();
780
781 // A forward struct declared type may not have elements available.
782 unsigned N = Elements.getNumElements();
783 if (N == 0)
784 break;
785
786 // Add elements to structure type.
787 for (unsigned i = 0; i < N; ++i) {
788 DIDescriptor Element = Elements.getElement(i);
789 DIE *ElemDie = NULL;
790 if (Element.isSubprogram()) {
791 DISubprogram SP(Element);
Devang Pateldbc64af2011-08-15 17:24:54 +0000792 ElemDie = getOrCreateSubprogramDIE(DISubprogram(Element));
Devang Patel161b2f42011-04-12 23:21:44 +0000793 if (SP.isProtected())
Nick Lewycky13aaca52011-12-13 05:09:11 +0000794 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +0000795 dwarf::DW_ACCESS_protected);
796 else if (SP.isPrivate())
Nick Lewycky13aaca52011-12-13 05:09:11 +0000797 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +0000798 dwarf::DW_ACCESS_private);
799 else
Nick Lewycky13aaca52011-12-13 05:09:11 +0000800 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +0000801 dwarf::DW_ACCESS_public);
802 if (SP.isExplicit())
803 addUInt(ElemDie, dwarf::DW_AT_explicit, dwarf::DW_FORM_flag, 1);
804 }
805 else if (Element.isVariable()) {
806 DIVariable DV(Element);
807 ElemDie = new DIE(dwarf::DW_TAG_variable);
Nick Lewycky390c40d2011-10-27 06:44:11 +0000808 addString(ElemDie, dwarf::DW_AT_name, DV.getName());
Devang Patel161b2f42011-04-12 23:21:44 +0000809 addType(ElemDie, DV.getType());
810 addUInt(ElemDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
811 addUInt(ElemDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
812 addSourceLine(ElemDie, DV);
813 } else if (Element.isDerivedType())
814 ElemDie = createMemberDIE(DIDerivedType(Element));
815 else
816 continue;
817 Buffer.addChild(ElemDie);
818 }
819
820 if (CTy.isAppleBlockExtension())
821 addUInt(&Buffer, dwarf::DW_AT_APPLE_block, dwarf::DW_FORM_flag, 1);
822
823 unsigned RLang = CTy.getRunTimeLang();
824 if (RLang)
825 addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class,
826 dwarf::DW_FORM_data1, RLang);
827
828 DICompositeType ContainingType = CTy.getContainingType();
829 if (DIDescriptor(ContainingType).isCompositeType())
830 addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
831 getOrCreateTypeDIE(DIType(ContainingType)));
832 else {
833 DIDescriptor Context = CTy.getContext();
834 addToContextOwner(&Buffer, Context);
835 }
836
Devang Patel201e6cd2011-05-12 21:29:42 +0000837 if (CTy.isObjcClassComplete())
838 addUInt(&Buffer, dwarf::DW_AT_APPLE_objc_complete_type,
Devang Patelb11f80e2011-05-12 19:06:16 +0000839 dwarf::DW_FORM_flag, 1);
840
Eric Christopher44625f92011-12-16 23:42:38 +0000841 // FIXME: a structure type can have template params too.
Devang Patel161b2f42011-04-12 23:21:44 +0000842 if (Tag == dwarf::DW_TAG_class_type)
843 addTemplateParams(Buffer, CTy.getTemplateParams());
844
845 break;
846 }
847 default:
848 break;
849 }
850
851 // Add name if not anonymous or intermediate type.
852 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000853 addString(&Buffer, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +0000854
855 if (Tag == dwarf::DW_TAG_enumeration_type || Tag == dwarf::DW_TAG_class_type
856 || Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type)
Nick Lewycky746cb672011-10-26 22:55:33 +0000857 {
Devang Patel161b2f42011-04-12 23:21:44 +0000858 // Add size if non-zero (derived types might be zero-sized.)
859 if (Size)
860 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
861 else {
862 // Add zero size if it is not a forward declaration.
863 if (CTy.isForwardDecl())
864 addUInt(&Buffer, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
865 else
866 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, 0);
867 }
868
869 // Add source line info if available.
870 if (!CTy.isForwardDecl())
871 addSourceLine(&Buffer, CTy);
872 }
873}
874
875/// getOrCreateTemplateTypeParameterDIE - Find existing DIE or create new DIE
876/// for the given DITemplateTypeParameter.
877DIE *
878CompileUnit::getOrCreateTemplateTypeParameterDIE(DITemplateTypeParameter TP) {
879 DIE *ParamDIE = getDIE(TP);
880 if (ParamDIE)
881 return ParamDIE;
882
883 ParamDIE = new DIE(dwarf::DW_TAG_template_type_parameter);
884 addType(ParamDIE, TP.getType());
Nick Lewycky390c40d2011-10-27 06:44:11 +0000885 addString(ParamDIE, dwarf::DW_AT_name, TP.getName());
Devang Patel161b2f42011-04-12 23:21:44 +0000886 return ParamDIE;
887}
888
889/// getOrCreateTemplateValueParameterDIE - Find existing DIE or create new DIE
890/// for the given DITemplateValueParameter.
891DIE *
892CompileUnit::getOrCreateTemplateValueParameterDIE(DITemplateValueParameter TPV) {
893 DIE *ParamDIE = getDIE(TPV);
894 if (ParamDIE)
895 return ParamDIE;
896
897 ParamDIE = new DIE(dwarf::DW_TAG_template_value_parameter);
898 addType(ParamDIE, TPV.getType());
899 if (!TPV.getName().empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000900 addString(ParamDIE, dwarf::DW_AT_name, TPV.getName());
Devang Patel161b2f42011-04-12 23:21:44 +0000901 addUInt(ParamDIE, dwarf::DW_AT_const_value, dwarf::DW_FORM_udata,
902 TPV.getValue());
903 return ParamDIE;
904}
905
Devang Patel31c5d052011-05-06 16:57:54 +0000906/// getOrCreateNameSpace - Create a DIE for DINameSpace.
907DIE *CompileUnit::getOrCreateNameSpace(DINameSpace NS) {
908 DIE *NDie = getDIE(NS);
909 if (NDie)
910 return NDie;
911 NDie = new DIE(dwarf::DW_TAG_namespace);
912 insertDIE(NS, NDie);
Eric Christopher09ac3d82011-11-07 09:24:32 +0000913 if (!NS.getName().empty()) {
Nick Lewycky390c40d2011-10-27 06:44:11 +0000914 addString(NDie, dwarf::DW_AT_name, NS.getName());
Eric Christopher09ac3d82011-11-07 09:24:32 +0000915 addAccelNamespace(NS.getName(), NDie);
916 } else
917 addAccelNamespace("(anonymous namespace)", NDie);
Devang Patel31c5d052011-05-06 16:57:54 +0000918 addSourceLine(NDie, NS);
919 addToContextOwner(NDie, NS.getContext());
920 return NDie;
921}
922
Devang Pateldbc64af2011-08-15 17:24:54 +0000923/// getRealLinkageName - If special LLVM prefix that is used to inform the asm
924/// printer to not emit usual symbol prefix before the symbol name is used then
925/// return linkage name after skipping this special LLVM prefix.
926static StringRef getRealLinkageName(StringRef LinkageName) {
927 char One = '\1';
928 if (LinkageName.startswith(StringRef(&One, 1)))
929 return LinkageName.substr(1);
930 return LinkageName;
931}
932
933/// getOrCreateSubprogramDIE - Create new DIE using SP.
934DIE *CompileUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
935 DIE *SPDie = getDIE(SP);
936 if (SPDie)
937 return SPDie;
938
Rafael Espindola01b55b42011-11-10 22:34:29 +0000939 DISubprogram SPDecl = SP.getFunctionDeclaration();
940 DIE *DeclDie = NULL;
941 if (SPDecl.isSubprogram()) {
942 DeclDie = getOrCreateSubprogramDIE(SPDecl);
943 }
944
Devang Pateldbc64af2011-08-15 17:24:54 +0000945 SPDie = new DIE(dwarf::DW_TAG_subprogram);
946
947 // DW_TAG_inlined_subroutine may refer to this DIE.
948 insertDIE(SP, SPDie);
949
950 // Add to context owner.
951 addToContextOwner(SPDie, SP.getContext());
952
953 // Add function template parameters.
954 addTemplateParams(*SPDie, SP.getTemplateParams());
955
956 StringRef LinkageName = SP.getLinkageName();
957 if (!LinkageName.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000958 addString(SPDie, dwarf::DW_AT_MIPS_linkage_name,
Nick Lewycky746cb672011-10-26 22:55:33 +0000959 getRealLinkageName(LinkageName));
Devang Pateldbc64af2011-08-15 17:24:54 +0000960
961 // If this DIE is going to refer declaration info using AT_specification
962 // then there is no need to add other attributes.
Rafael Espindola01b55b42011-11-10 22:34:29 +0000963 if (DeclDie) {
964 // Refer function declaration directly.
965 addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
966 DeclDie);
967
Devang Pateldbc64af2011-08-15 17:24:54 +0000968 return SPDie;
Rafael Espindola01b55b42011-11-10 22:34:29 +0000969 }
Devang Pateldbc64af2011-08-15 17:24:54 +0000970
971 // Constructors and operators for anonymous aggregates do not have names.
972 if (!SP.getName().empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000973 addString(SPDie, dwarf::DW_AT_name, SP.getName());
Devang Pateldbc64af2011-08-15 17:24:54 +0000974
975 addSourceLine(SPDie, SP);
976
977 if (SP.isPrototyped())
978 addUInt(SPDie, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
979
980 // Add Return Type.
981 DICompositeType SPTy = SP.getType();
982 DIArray Args = SPTy.getTypeArray();
983 unsigned SPTag = SPTy.getTag();
984
985 if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type)
986 addType(SPDie, SPTy);
987 else
988 addType(SPDie, DIType(Args.getElement(0)));
989
990 unsigned VK = SP.getVirtuality();
991 if (VK) {
Nick Lewycky798313d2011-12-14 00:56:07 +0000992 addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, VK);
Devang Pateldbc64af2011-08-15 17:24:54 +0000993 DIEBlock *Block = getDIEBlock();
994 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
995 addUInt(Block, 0, dwarf::DW_FORM_udata, SP.getVirtualIndex());
996 addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
997 ContainingTypeMap.insert(std::make_pair(SPDie,
998 SP.getContainingType()));
999 }
1000
1001 if (!SP.isDefinition()) {
1002 addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
1003
1004 // Add arguments. Do not add arguments for subprogram definition. They will
1005 // be handled while processing variables.
1006 DICompositeType SPTy = SP.getType();
1007 DIArray Args = SPTy.getTypeArray();
1008 unsigned SPTag = SPTy.getTag();
1009
1010 if (SPTag == dwarf::DW_TAG_subroutine_type)
1011 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
1012 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
1013 DIType ATy = DIType(DIType(Args.getElement(i)));
1014 addType(Arg, ATy);
1015 if (ATy.isArtificial())
1016 addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
1017 SPDie->addChild(Arg);
1018 }
1019 }
1020
1021 if (SP.isArtificial())
1022 addUInt(SPDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
1023
1024 if (!SP.isLocalToUnit())
1025 addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
1026
1027 if (SP.isOptimized())
1028 addUInt(SPDie, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1);
1029
1030 if (unsigned isa = Asm->getISAEncoding()) {
1031 addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa);
1032 }
1033
1034 return SPDie;
1035}
1036
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001037// Return const expression if value is a GEP to access merged global
1038// constant. e.g.
1039// i8* getelementptr ({ i8, i8, i8, i8 }* @_MergedGlobals, i32 0, i32 0)
1040static const ConstantExpr *getMergedGlobalExpr(const Value *V) {
1041 const ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(V);
1042 if (!CE || CE->getNumOperands() != 3 ||
1043 CE->getOpcode() != Instruction::GetElementPtr)
1044 return NULL;
1045
1046 // First operand points to a global struct.
1047 Value *Ptr = CE->getOperand(0);
1048 if (!isa<GlobalValue>(Ptr) ||
1049 !isa<StructType>(cast<PointerType>(Ptr->getType())->getElementType()))
1050 return NULL;
1051
1052 // Second operand is zero.
1053 const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CE->getOperand(1));
1054 if (!CI || !CI->isZero())
1055 return NULL;
1056
1057 // Third operand is offset.
1058 if (!isa<ConstantInt>(CE->getOperand(2)))
1059 return NULL;
1060
1061 return CE;
1062}
1063
1064/// createGlobalVariableDIE - create global variable DIE.
1065void CompileUnit::createGlobalVariableDIE(const MDNode *N) {
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001066 // Check for pre-existence.
Devang Patel49e2f032011-08-18 22:21:50 +00001067 if (getDIE(N))
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001068 return;
1069
Devang Patel49e2f032011-08-18 22:21:50 +00001070 DIGlobalVariable GV(N);
Devang Patel28bea082011-08-18 23:17:55 +00001071 if (!GV.Verify())
1072 return;
1073
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001074 DIE *VariableDIE = new DIE(GV.getTag());
Devang Patel49e2f032011-08-18 22:21:50 +00001075 // Add to map.
1076 insertDIE(N, VariableDIE);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001077
1078 // Add name.
Nick Lewycky390c40d2011-10-27 06:44:11 +00001079 addString(VariableDIE, dwarf::DW_AT_name, GV.getDisplayName());
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001080 StringRef LinkageName = GV.getLinkageName();
Devang Patel49e2f032011-08-18 22:21:50 +00001081 bool isGlobalVariable = GV.getGlobal() != NULL;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001082 if (!LinkageName.empty() && isGlobalVariable)
Nick Lewycky746cb672011-10-26 22:55:33 +00001083 addString(VariableDIE, dwarf::DW_AT_MIPS_linkage_name,
Nick Lewycky390c40d2011-10-27 06:44:11 +00001084 getRealLinkageName(LinkageName));
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001085 // Add type.
Devang Patel49e2f032011-08-18 22:21:50 +00001086 DIType GTy = GV.getType();
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001087 addType(VariableDIE, GTy);
1088
1089 // Add scoping info.
Eric Christopherdfa30e12011-11-09 05:24:07 +00001090 if (!GV.isLocalToUnit())
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001091 addUInt(VariableDIE, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
Eric Christopherdfa30e12011-11-09 05:24:07 +00001092
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001093 // Add line number info.
1094 addSourceLine(VariableDIE, GV);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001095 // Add to context owner.
1096 DIDescriptor GVContext = GV.getContext();
1097 addToContextOwner(VariableDIE, GVContext);
1098 // Add location.
Eric Christopher09ac3d82011-11-07 09:24:32 +00001099 bool addToAccelTable = false;
Eric Christopherd61c34b2011-11-11 03:16:32 +00001100 DIE *VariableSpecDIE = NULL;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001101 if (isGlobalVariable) {
Eric Christopher09ac3d82011-11-07 09:24:32 +00001102 addToAccelTable = true;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001103 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
1104 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
1105 addLabel(Block, 0, dwarf::DW_FORM_udata,
1106 Asm->Mang->getSymbol(GV.getGlobal()));
1107 // Do not create specification DIE if context is either compile unit
1108 // or a subprogram.
Devang Patel1dd4e562011-09-21 23:41:11 +00001109 if (GVContext && GV.isDefinition() && !GVContext.isCompileUnit() &&
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001110 !GVContext.isFile() && !isSubprogramContext(GVContext)) {
1111 // Create specification DIE.
Eric Christopherd117fbb2011-11-11 01:55:22 +00001112 VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001113 addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
1114 dwarf::DW_FORM_ref4, VariableDIE);
1115 addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
1116 addUInt(VariableDIE, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag,
1117 1);
1118 addDie(VariableSpecDIE);
1119 } else {
1120 addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
Eric Christopher09ac3d82011-11-07 09:24:32 +00001121 }
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001122 } else if (const ConstantInt *CI =
1123 dyn_cast_or_null<ConstantInt>(GV.getConstant()))
1124 addConstantValue(VariableDIE, CI, GTy.isUnsignedDIType());
1125 else if (const ConstantExpr *CE = getMergedGlobalExpr(N->getOperand(11))) {
Eric Christopher09ac3d82011-11-07 09:24:32 +00001126 addToAccelTable = true;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001127 // GV is a merged global.
1128 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
1129 Value *Ptr = CE->getOperand(0);
1130 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
1131 addLabel(Block, 0, dwarf::DW_FORM_udata,
1132 Asm->Mang->getSymbol(cast<GlobalValue>(Ptr)));
1133 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1134 SmallVector<Value*, 3> Idx(CE->op_begin()+1, CE->op_end());
1135 addUInt(Block, 0, dwarf::DW_FORM_udata,
1136 Asm->getTargetData().getIndexedOffset(Ptr->getType(), Idx));
1137 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1138 addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
1139 }
1140
Eric Christopherd117fbb2011-11-11 01:55:22 +00001141 if (addToAccelTable) {
1142 DIE *AddrDIE = VariableSpecDIE ? VariableSpecDIE : VariableDIE;
1143 addAccelName(GV.getName(), AddrDIE);
Eric Christopher09ac3d82011-11-07 09:24:32 +00001144
Eric Christopherd117fbb2011-11-11 01:55:22 +00001145 // If the linkage name is different than the name, go ahead and output
1146 // that as well into the name table.
1147 if (GV.getLinkageName() != "" && GV.getName() != GV.getLinkageName())
1148 addAccelName(GV.getLinkageName(), AddrDIE);
1149 }
Eric Christopher74d8a872011-11-08 21:56:23 +00001150
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001151 return;
1152}
1153
Devang Patel161b2f42011-04-12 23:21:44 +00001154/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
1155void CompileUnit::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){
1156 DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type);
1157 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IndexTy);
Devang Patelce35d8b2011-11-17 23:43:15 +00001158 uint64_t L = SR.getLo();
1159 uint64_t H = SR.getHi();
Devang Patel161b2f42011-04-12 23:21:44 +00001160
1161 // The L value defines the lower bounds which is typically zero for C/C++. The
1162 // H value is the upper bounds. Values are 64 bit. H - L + 1 is the size
1163 // of the array. If L > H then do not emit DW_AT_lower_bound and
1164 // DW_AT_upper_bound attributes. If L is zero and H is also zero then the
1165 // array has one element and in such case do not emit lower bound.
1166
1167 if (L > H) {
1168 Buffer.addChild(DW_Subrange);
1169 return;
1170 }
1171 if (L)
Devang Patelce35d8b2011-11-17 23:43:15 +00001172 addUInt(DW_Subrange, dwarf::DW_AT_lower_bound, 0, L);
1173 addUInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, H);
Devang Patel161b2f42011-04-12 23:21:44 +00001174 Buffer.addChild(DW_Subrange);
1175}
1176
1177/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
1178void CompileUnit::constructArrayTypeDIE(DIE &Buffer,
1179 DICompositeType *CTy) {
1180 Buffer.setTag(dwarf::DW_TAG_array_type);
1181 if (CTy->getTag() == dwarf::DW_TAG_vector_type)
1182 addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1);
1183
1184 // Emit derived type.
1185 addType(&Buffer, CTy->getTypeDerivedFrom());
1186 DIArray Elements = CTy->getTypeArray();
1187
1188 // Get an anonymous type for index type.
1189 DIE *IdxTy = getIndexTyDie();
1190 if (!IdxTy) {
1191 // Construct an anonymous type for index type.
1192 IdxTy = new DIE(dwarf::DW_TAG_base_type);
1193 addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t));
1194 addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
1195 dwarf::DW_ATE_signed);
1196 addDie(IdxTy);
1197 setIndexTyDie(IdxTy);
1198 }
1199
1200 // Add subranges to array type.
1201 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
1202 DIDescriptor Element = Elements.getElement(i);
1203 if (Element.getTag() == dwarf::DW_TAG_subrange_type)
1204 constructSubrangeDIE(Buffer, DISubrange(Element), IdxTy);
1205 }
1206}
1207
1208/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
1209DIE *CompileUnit::constructEnumTypeDIE(DIEnumerator ETy) {
1210 DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator);
1211 StringRef Name = ETy.getName();
Nick Lewycky390c40d2011-10-27 06:44:11 +00001212 addString(Enumerator, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +00001213 int64_t Value = ETy.getEnumValue();
1214 addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value);
1215 return Enumerator;
1216}
1217
Devang Pateldbc64af2011-08-15 17:24:54 +00001218/// constructContainingTypeDIEs - Construct DIEs for types that contain
1219/// vtables.
1220void CompileUnit::constructContainingTypeDIEs() {
1221 for (DenseMap<DIE *, const MDNode *>::iterator CI = ContainingTypeMap.begin(),
1222 CE = ContainingTypeMap.end(); CI != CE; ++CI) {
1223 DIE *SPDie = CI->first;
1224 const MDNode *N = CI->second;
1225 if (!N) continue;
1226 DIE *NDie = getDIE(N);
1227 if (!NDie) continue;
1228 addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
1229 }
1230}
1231
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001232/// constructVariableDIE - Construct a DIE for the given DbgVariable.
1233DIE *CompileUnit::constructVariableDIE(DbgVariable *DV, bool isScopeAbstract) {
1234 StringRef Name = DV->getName();
1235 if (Name.empty())
1236 return NULL;
1237
1238 // Translate tag to proper Dwarf tag.
1239 unsigned Tag = DV->getTag();
1240
1241 // Define variable debug information entry.
1242 DIE *VariableDie = new DIE(Tag);
1243 DbgVariable *AbsVar = DV->getAbstractVariable();
1244 DIE *AbsDIE = AbsVar ? AbsVar->getDIE() : NULL;
1245 if (AbsDIE)
1246 addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin,
1247 dwarf::DW_FORM_ref4, AbsDIE);
1248 else {
Nick Lewycky390c40d2011-10-27 06:44:11 +00001249 addString(VariableDie, dwarf::DW_AT_name, Name);
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001250 addSourceLine(VariableDie, DV->getVariable());
1251 addType(VariableDie, DV->getType());
1252 }
1253
1254 if (DV->isArtificial())
1255 addUInt(VariableDie, dwarf::DW_AT_artificial,
1256 dwarf::DW_FORM_flag, 1);
1257
1258 if (isScopeAbstract) {
1259 DV->setDIE(VariableDie);
1260 return VariableDie;
1261 }
1262
1263 // Add variable address.
1264
1265 unsigned Offset = DV->getDotDebugLocOffset();
1266 if (Offset != ~0U) {
1267 addLabel(VariableDie, dwarf::DW_AT_location,
1268 dwarf::DW_FORM_data4,
1269 Asm->GetTempSymbol("debug_loc", Offset));
1270 DV->setDIE(VariableDie);
1271 return VariableDie;
1272 }
1273
Eric Christopher8cf5e742011-10-03 15:49:20 +00001274 // Check if variable is described by a DBG_VALUE instruction.
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001275 if (const MachineInstr *DVInsn = DV->getMInsn()) {
1276 bool updated = false;
1277 if (DVInsn->getNumOperands() == 3) {
1278 if (DVInsn->getOperand(0).isReg()) {
1279 const MachineOperand RegOp = DVInsn->getOperand(0);
1280 const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
1281 if (DVInsn->getOperand(1).isImm() &&
1282 TRI->getFrameRegister(*Asm->MF) == RegOp.getReg()) {
1283 unsigned FrameReg = 0;
1284 const TargetFrameLowering *TFI = Asm->TM.getFrameLowering();
1285 int Offset =
1286 TFI->getFrameIndexReference(*Asm->MF,
1287 DVInsn->getOperand(1).getImm(),
1288 FrameReg);
1289 MachineLocation Location(FrameReg, Offset);
1290 addVariableAddress(DV, VariableDie, Location);
1291
1292 } else if (RegOp.getReg())
1293 addVariableAddress(DV, VariableDie,
1294 MachineLocation(RegOp.getReg()));
1295 updated = true;
1296 }
1297 else if (DVInsn->getOperand(0).isImm())
1298 updated =
1299 addConstantValue(VariableDie, DVInsn->getOperand(0),
1300 DV->getType());
1301 else if (DVInsn->getOperand(0).isFPImm())
1302 updated =
1303 addConstantFPValue(VariableDie, DVInsn->getOperand(0));
1304 else if (DVInsn->getOperand(0).isCImm())
1305 updated =
1306 addConstantValue(VariableDie,
1307 DVInsn->getOperand(0).getCImm(),
1308 DV->getType().isUnsignedDIType());
1309 } else {
1310 addVariableAddress(DV, VariableDie,
1311 Asm->getDebugValueLocation(DVInsn));
1312 updated = true;
1313 }
1314 if (!updated) {
1315 // If variableDie is not updated then DBG_VALUE instruction does not
1316 // have valid variable info.
1317 delete VariableDie;
1318 return NULL;
1319 }
1320 DV->setDIE(VariableDie);
1321 return VariableDie;
1322 } else {
1323 // .. else use frame index.
1324 int FI = DV->getFrameIndex();
1325 if (FI != ~0) {
1326 unsigned FrameReg = 0;
1327 const TargetFrameLowering *TFI = Asm->TM.getFrameLowering();
1328 int Offset =
1329 TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg);
1330 MachineLocation Location(FrameReg, Offset);
1331 addVariableAddress(DV, VariableDie, Location);
1332 }
1333 }
1334
1335 DV->setDIE(VariableDie);
1336 return VariableDie;
1337}
1338
Devang Patel161b2f42011-04-12 23:21:44 +00001339/// createMemberDIE - Create new member DIE.
1340DIE *CompileUnit::createMemberDIE(DIDerivedType DT) {
1341 DIE *MemberDie = new DIE(DT.getTag());
1342 StringRef Name = DT.getName();
1343 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001344 addString(MemberDie, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +00001345
1346 addType(MemberDie, DT.getTypeDerivedFrom());
1347
1348 addSourceLine(MemberDie, DT);
1349
1350 DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
1351 addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
1352
1353 uint64_t Size = DT.getSizeInBits();
1354 uint64_t FieldSize = DT.getOriginalTypeSize();
1355
1356 if (Size != FieldSize) {
1357 // Handle bitfield.
1358 addUInt(MemberDie, dwarf::DW_AT_byte_size, 0, DT.getOriginalTypeSize()>>3);
1359 addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits());
1360
1361 uint64_t Offset = DT.getOffsetInBits();
1362 uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
1363 uint64_t HiMark = (Offset + FieldSize) & AlignMask;
1364 uint64_t FieldOffset = (HiMark - FieldSize);
1365 Offset -= FieldOffset;
1366
1367 // Maybe we need to work from the other end.
1368 if (Asm->getTargetData().isLittleEndian())
1369 Offset = FieldSize - (Offset + Size);
1370 addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
1371
1372 // Here WD_AT_data_member_location points to the anonymous
1373 // field that includes this bit field.
1374 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, FieldOffset >> 3);
1375
1376 } else
1377 // This is not a bitfield.
1378 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);
1379
1380 if (DT.getTag() == dwarf::DW_TAG_inheritance
1381 && DT.isVirtual()) {
1382
1383 // For C++, virtual base classes are not at fixed offset. Use following
1384 // expression to extract appropriate offset from vtable.
1385 // BaseAddr = ObAddr + *((*ObAddr) - Offset)
1386
1387 DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock();
1388 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
1389 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1390 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1391 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits());
1392 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
1393 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1394 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1395
1396 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0,
1397 VBaseLocationDie);
1398 } else
1399 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
1400
1401 if (DT.isProtected())
Nick Lewycky13aaca52011-12-13 05:09:11 +00001402 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +00001403 dwarf::DW_ACCESS_protected);
1404 else if (DT.isPrivate())
Nick Lewycky13aaca52011-12-13 05:09:11 +00001405 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +00001406 dwarf::DW_ACCESS_private);
1407 // Otherwise C++ member and base classes are considered public.
Devang Patel94c7ddb2011-08-16 22:09:43 +00001408 else
Nick Lewycky13aaca52011-12-13 05:09:11 +00001409 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +00001410 dwarf::DW_ACCESS_public);
1411 if (DT.isVirtual())
Nick Lewycky798313d2011-12-14 00:56:07 +00001412 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +00001413 dwarf::DW_VIRTUALITY_virtual);
Devang Patele9db5e22011-04-16 00:11:51 +00001414
1415 // Objective-C properties.
1416 StringRef PropertyName = DT.getObjCPropertyName();
1417 if (!PropertyName.empty()) {
Nick Lewycky390c40d2011-10-27 06:44:11 +00001418 addString(MemberDie, dwarf::DW_AT_APPLE_property_name, PropertyName);
Devang Patele9db5e22011-04-16 00:11:51 +00001419 StringRef GetterName = DT.getObjCPropertyGetterName();
1420 if (!GetterName.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001421 addString(MemberDie, dwarf::DW_AT_APPLE_property_getter, GetterName);
Devang Patele9db5e22011-04-16 00:11:51 +00001422 StringRef SetterName = DT.getObjCPropertySetterName();
1423 if (!SetterName.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001424 addString(MemberDie, dwarf::DW_AT_APPLE_property_setter, SetterName);
Devang Patele9db5e22011-04-16 00:11:51 +00001425 unsigned PropertyAttributes = 0;
1426 if (DT.isReadOnlyObjCProperty())
1427 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readonly;
1428 if (DT.isReadWriteObjCProperty())
1429 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readwrite;
1430 if (DT.isAssignObjCProperty())
1431 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_assign;
1432 if (DT.isRetainObjCProperty())
1433 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_retain;
1434 if (DT.isCopyObjCProperty())
1435 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_copy;
1436 if (DT.isNonAtomicObjCProperty())
1437 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_nonatomic;
1438 if (PropertyAttributes)
1439 addUInt(MemberDie, dwarf::DW_AT_APPLE_property_attribute, 0,
1440 PropertyAttributes);
1441 }
Devang Patel161b2f42011-04-12 23:21:44 +00001442 return MemberDie;
1443}