blob: cb80bd810e3baa0e0b994788e293d1ae37f1affb [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"
Devang Patel6f9d8ff2011-08-15 17:57:41 +000022#include "llvm/Target/Mangler.h"
Devang Patel161b2f42011-04-12 23:21:44 +000023#include "llvm/Target/TargetData.h"
24#include "llvm/Target/TargetFrameLowering.h"
25#include "llvm/Target/TargetMachine.h"
26#include "llvm/Target/TargetRegisterInfo.h"
27#include "llvm/ADT/APFloat.h"
28#include "llvm/Support/ErrorHandling.h"
29
30using namespace llvm;
31
32/// CompileUnit - Compile unit constructor.
33CompileUnit::CompileUnit(unsigned I, DIE *D, AsmPrinter *A, DwarfDebug *DW)
34 : ID(I), CUDie(D), Asm(A), DD(DW), IndexTyDie(0) {
35 DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1);
36}
37
38/// ~CompileUnit - Destructor for compile unit.
39CompileUnit::~CompileUnit() {
40 for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
41 DIEBlocks[j]->~DIEBlock();
42}
43
44/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug
45/// information entry.
46DIEEntry *CompileUnit::createDIEEntry(DIE *Entry) {
47 DIEEntry *Value = new (DIEValueAllocator) DIEEntry(Entry);
48 return Value;
49}
50
51/// addUInt - Add an unsigned integer attribute data and value.
52///
53void CompileUnit::addUInt(DIE *Die, unsigned Attribute,
54 unsigned Form, uint64_t Integer) {
55 if (!Form) Form = DIEInteger::BestForm(false, Integer);
56 DIEValue *Value = Integer == 1 ?
57 DIEIntegerOne : new (DIEValueAllocator) DIEInteger(Integer);
58 Die->addValue(Attribute, Form, Value);
59}
60
61/// addSInt - Add an signed integer attribute data and value.
62///
63void CompileUnit::addSInt(DIE *Die, unsigned Attribute,
64 unsigned Form, int64_t Integer) {
65 if (!Form) Form = DIEInteger::BestForm(true, Integer);
66 DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
67 Die->addValue(Attribute, Form, Value);
68}
69
Nick Lewycky6a7efcf2011-10-28 05:29:47 +000070/// addString - Add a string attribute data and value. We always emit a
71/// reference to the string pool instead of immediate strings so that DIEs have
72/// more predictable sizes.
Nick Lewycky390c40d2011-10-27 06:44:11 +000073void CompileUnit::addString(DIE *Die, unsigned Attribute, StringRef String) {
Nick Lewycky6a7efcf2011-10-28 05:29:47 +000074 MCSymbol *Symb = DD->getStringPoolEntry(String);
75 DIEValue *Value;
76 if (Asm->needsRelocationsForDwarfStringPool())
77 Value = new (DIEValueAllocator) DIELabel(Symb);
78 else {
79 MCSymbol *StringPool = DD->getStringPool();
80 Value = new (DIEValueAllocator) DIEDelta(Symb, StringPool);
Nick Lewycky390c40d2011-10-27 06:44:11 +000081 }
Nick Lewycky6a7efcf2011-10-28 05:29:47 +000082 Die->addValue(Attribute, dwarf::DW_FORM_strp, Value);
Devang Patel161b2f42011-04-12 23:21:44 +000083}
84
85/// addLabel - Add a Dwarf label attribute data and value.
86///
87void CompileUnit::addLabel(DIE *Die, unsigned Attribute, unsigned Form,
88 const MCSymbol *Label) {
89 DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
90 Die->addValue(Attribute, Form, Value);
91}
92
93/// addDelta - Add a label delta attribute data and value.
94///
95void CompileUnit::addDelta(DIE *Die, unsigned Attribute, unsigned Form,
96 const MCSymbol *Hi, const MCSymbol *Lo) {
97 DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo);
98 Die->addValue(Attribute, Form, Value);
99}
100
101/// addDIEEntry - Add a DIE attribute data and value.
102///
103void CompileUnit::addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form,
104 DIE *Entry) {
105 Die->addValue(Attribute, Form, createDIEEntry(Entry));
106}
107
Devang Patel161b2f42011-04-12 23:21:44 +0000108/// addBlock - Add block data.
109///
110void CompileUnit::addBlock(DIE *Die, unsigned Attribute, unsigned Form,
111 DIEBlock *Block) {
112 Block->ComputeSize(Asm);
113 DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.
114 Die->addValue(Attribute, Block->BestForm(), Block);
115}
116
117/// addSourceLine - Add location information to specified debug information
118/// entry.
119void CompileUnit::addSourceLine(DIE *Die, DIVariable V) {
120 // Verify variable.
121 if (!V.Verify())
122 return;
123
124 unsigned Line = V.getLineNumber();
125 if (Line == 0)
126 return;
127 unsigned FileID = DD->GetOrCreateSourceID(V.getContext().getFilename(),
128 V.getContext().getDirectory());
129 assert(FileID && "Invalid file id");
130 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
131 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
132}
133
134/// addSourceLine - Add location information to specified debug information
135/// entry.
136void CompileUnit::addSourceLine(DIE *Die, DIGlobalVariable G) {
137 // Verify global variable.
138 if (!G.Verify())
139 return;
140
141 unsigned Line = G.getLineNumber();
142 if (Line == 0)
143 return;
Nick Lewycky746cb672011-10-26 22:55:33 +0000144 unsigned FileID = DD->GetOrCreateSourceID(G.getFilename(), G.getDirectory());
Devang Patel161b2f42011-04-12 23:21:44 +0000145 assert(FileID && "Invalid file id");
146 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
147 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
148}
149
150/// addSourceLine - Add location information to specified debug information
151/// entry.
152void CompileUnit::addSourceLine(DIE *Die, DISubprogram SP) {
153 // Verify subprogram.
154 if (!SP.Verify())
155 return;
156 // If the line number is 0, don't add it.
157 if (SP.getLineNumber() == 0)
158 return;
159
160 unsigned Line = SP.getLineNumber();
161 if (!SP.getContext().Verify())
162 return;
Nick Lewycky746cb672011-10-26 22:55:33 +0000163 unsigned FileID = DD->GetOrCreateSourceID(SP.getFilename(),
164 SP.getDirectory());
Devang Patel161b2f42011-04-12 23:21:44 +0000165 assert(FileID && "Invalid file id");
166 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
167 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
168}
169
170/// addSourceLine - Add location information to specified debug information
171/// entry.
172void CompileUnit::addSourceLine(DIE *Die, DIType Ty) {
173 // Verify type.
174 if (!Ty.Verify())
175 return;
176
177 unsigned Line = Ty.getLineNumber();
178 if (Line == 0 || !Ty.getContext().Verify())
179 return;
Nick Lewycky746cb672011-10-26 22:55:33 +0000180 unsigned FileID = DD->GetOrCreateSourceID(Ty.getFilename(),
181 Ty.getDirectory());
Devang Patel161b2f42011-04-12 23:21:44 +0000182 assert(FileID && "Invalid file id");
183 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
184 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
185}
186
187/// addSourceLine - Add location information to specified debug information
188/// entry.
189void CompileUnit::addSourceLine(DIE *Die, DINameSpace NS) {
190 // Verify namespace.
191 if (!NS.Verify())
192 return;
193
194 unsigned Line = NS.getLineNumber();
195 if (Line == 0)
196 return;
197 StringRef FN = NS.getFilename();
198
199 unsigned FileID = DD->GetOrCreateSourceID(FN, NS.getDirectory());
200 assert(FileID && "Invalid file id");
201 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
202 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
203}
204
Devang Patele1cdf842011-04-27 22:45:24 +0000205/// addVariableAddress - Add DW_AT_location attribute for a
206/// DbgVariable based on provided MachineLocation.
207void CompileUnit::addVariableAddress(DbgVariable *&DV, DIE *Die,
208 MachineLocation Location) {
Devang Patel161b2f42011-04-12 23:21:44 +0000209 if (DV->variableHasComplexAddress())
210 addComplexAddress(DV, Die, dwarf::DW_AT_location, Location);
211 else if (DV->isBlockByrefVariable())
212 addBlockByrefAddress(DV, Die, dwarf::DW_AT_location, Location);
213 else
214 addAddress(Die, dwarf::DW_AT_location, Location);
215}
216
Devang Patel116da2f2011-04-26 19:06:18 +0000217/// addRegisterOp - Add register operand.
218void CompileUnit::addRegisterOp(DIE *TheDie, unsigned Reg) {
219 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
220 unsigned DWReg = RI->getDwarfRegNum(Reg, false);
221 if (DWReg < 32)
222 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + DWReg);
223 else {
224 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx);
225 addUInt(TheDie, 0, dwarf::DW_FORM_udata, DWReg);
226 }
227}
228
229/// addRegisterOffset - Add register offset.
230void CompileUnit::addRegisterOffset(DIE *TheDie, unsigned Reg,
231 int64_t Offset) {
232 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
233 unsigned DWReg = RI->getDwarfRegNum(Reg, false);
234 const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
235 if (Reg == TRI->getFrameRegister(*Asm->MF))
236 // If variable offset is based in frame register then use fbreg.
237 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_fbreg);
238 else if (DWReg < 32)
239 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + DWReg);
240 else {
241 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
242 addUInt(TheDie, 0, dwarf::DW_FORM_udata, DWReg);
243 }
244 addSInt(TheDie, 0, dwarf::DW_FORM_sdata, Offset);
245}
246
247/// addAddress - Add an address attribute to a die based on the location
248/// provided.
249void CompileUnit::addAddress(DIE *Die, unsigned Attribute,
250 const MachineLocation &Location) {
251 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
252
253 if (Location.isReg())
254 addRegisterOp(Block, Location.getReg());
255 else
256 addRegisterOffset(Block, Location.getReg(), Location.getOffset());
257
258 // Now attach the location information to the DIE.
259 addBlock(Die, Attribute, 0, Block);
260}
261
Devang Patel161b2f42011-04-12 23:21:44 +0000262/// addComplexAddress - Start with the address based on the location provided,
263/// and generate the DWARF information necessary to find the actual variable
264/// given the extra address information encoded in the DIVariable, starting from
265/// the starting location. Add the DWARF information to the die.
266///
267void CompileUnit::addComplexAddress(DbgVariable *&DV, DIE *Die,
268 unsigned Attribute,
269 const MachineLocation &Location) {
Devang Patel161b2f42011-04-12 23:21:44 +0000270 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patelc26f5442011-04-28 02:22:40 +0000271 unsigned N = DV->getNumAddrElements();
272 unsigned i = 0;
273 if (Location.isReg()) {
274 if (N >= 2 && DV->getAddrElement(0) == DIBuilder::OpPlus) {
275 // If first address element is OpPlus then emit
276 // DW_OP_breg + Offset instead of DW_OP_reg + Offset.
277 addRegisterOffset(Block, Location.getReg(), DV->getAddrElement(1));
278 i = 2;
279 } else
280 addRegisterOp(Block, Location.getReg());
281 }
Devang Patel116da2f2011-04-26 19:06:18 +0000282 else
283 addRegisterOffset(Block, Location.getReg(), Location.getOffset());
Devang Patel161b2f42011-04-12 23:21:44 +0000284
Devang Patelc26f5442011-04-28 02:22:40 +0000285 for (;i < N; ++i) {
Devang Patel161b2f42011-04-12 23:21:44 +0000286 uint64_t Element = DV->getAddrElement(i);
Devang Patel161b2f42011-04-12 23:21:44 +0000287 if (Element == DIBuilder::OpPlus) {
288 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
289 addUInt(Block, 0, dwarf::DW_FORM_udata, DV->getAddrElement(++i));
290 } else if (Element == DIBuilder::OpDeref) {
291 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
292 } else llvm_unreachable("unknown DIBuilder Opcode");
293 }
294
295 // Now attach the location information to the DIE.
296 addBlock(Die, Attribute, 0, Block);
297}
298
299/* Byref variables, in Blocks, are declared by the programmer as "SomeType
300 VarName;", but the compiler creates a __Block_byref_x_VarName struct, and
301 gives the variable VarName either the struct, or a pointer to the struct, as
302 its type. This is necessary for various behind-the-scenes things the
303 compiler needs to do with by-reference variables in Blocks.
304
305 However, as far as the original *programmer* is concerned, the variable
306 should still have type 'SomeType', as originally declared.
307
308 The function getBlockByrefType dives into the __Block_byref_x_VarName
309 struct to find the original type of the variable, which is then assigned to
310 the variable's Debug Information Entry as its real type. So far, so good.
311 However now the debugger will expect the variable VarName to have the type
312 SomeType. So we need the location attribute for the variable to be an
313 expression that explains to the debugger how to navigate through the
314 pointers and struct to find the actual variable of type SomeType.
315
316 The following function does just that. We start by getting
317 the "normal" location for the variable. This will be the location
318 of either the struct __Block_byref_x_VarName or the pointer to the
319 struct __Block_byref_x_VarName.
320
321 The struct will look something like:
322
323 struct __Block_byref_x_VarName {
324 ... <various fields>
325 struct __Block_byref_x_VarName *forwarding;
326 ... <various other fields>
327 SomeType VarName;
328 ... <maybe more fields>
329 };
330
331 If we are given the struct directly (as our starting point) we
332 need to tell the debugger to:
333
334 1). Add the offset of the forwarding field.
335
336 2). Follow that pointer to get the real __Block_byref_x_VarName
337 struct to use (the real one may have been copied onto the heap).
338
339 3). Add the offset for the field VarName, to find the actual variable.
340
341 If we started with a pointer to the struct, then we need to
342 dereference that pointer first, before the other steps.
343 Translating this into DWARF ops, we will need to append the following
344 to the current location description for the variable:
345
346 DW_OP_deref -- optional, if we start with a pointer
347 DW_OP_plus_uconst <forward_fld_offset>
348 DW_OP_deref
349 DW_OP_plus_uconst <varName_fld_offset>
350
351 That is what this function does. */
352
353/// addBlockByrefAddress - Start with the address based on the location
354/// provided, and generate the DWARF information necessary to find the
355/// actual Block variable (navigating the Block struct) based on the
356/// starting location. Add the DWARF information to the die. For
357/// more information, read large comment just above here.
358///
359void CompileUnit::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
360 unsigned Attribute,
361 const MachineLocation &Location) {
362 DIType Ty = DV->getType();
363 DIType TmpTy = Ty;
364 unsigned Tag = Ty.getTag();
365 bool isPointer = false;
366
367 StringRef varName = DV->getName();
368
369 if (Tag == dwarf::DW_TAG_pointer_type) {
370 DIDerivedType DTy = DIDerivedType(Ty);
371 TmpTy = DTy.getTypeDerivedFrom();
372 isPointer = true;
373 }
374
375 DICompositeType blockStruct = DICompositeType(TmpTy);
376
377 // Find the __forwarding field and the variable field in the __Block_byref
378 // struct.
379 DIArray Fields = blockStruct.getTypeArray();
380 DIDescriptor varField = DIDescriptor();
381 DIDescriptor forwardingField = DIDescriptor();
382
383 for (unsigned i = 0, N = Fields.getNumElements(); i < N; ++i) {
384 DIDescriptor Element = Fields.getElement(i);
385 DIDerivedType DT = DIDerivedType(Element);
386 StringRef fieldName = DT.getName();
387 if (fieldName == "__forwarding")
388 forwardingField = Element;
389 else if (fieldName == varName)
390 varField = Element;
391 }
392
393 // Get the offsets for the forwarding field and the variable field.
394 unsigned forwardingFieldOffset =
395 DIDerivedType(forwardingField).getOffsetInBits() >> 3;
396 unsigned varFieldOffset =
397 DIDerivedType(varField).getOffsetInBits() >> 3;
398
399 // Decode the original location, and use that as the start of the byref
400 // variable's location.
401 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
402 unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
403 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
404
405 if (Location.isReg()) {
406 if (Reg < 32)
407 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
408 else {
409 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx);
410 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
411 }
412 } else {
413 if (Reg < 32)
414 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
415 else {
416 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
417 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
418 }
419
420 addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
421 }
422
423 // If we started with a pointer to the __Block_byref... struct, then
424 // the first thing we need to do is dereference the pointer (DW_OP_deref).
425 if (isPointer)
426 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
427
428 // Next add the offset for the '__forwarding' field:
429 // DW_OP_plus_uconst ForwardingFieldOffset. Note there's no point in
430 // adding the offset if it's 0.
431 if (forwardingFieldOffset > 0) {
432 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
433 addUInt(Block, 0, dwarf::DW_FORM_udata, forwardingFieldOffset);
434 }
435
436 // Now dereference the __forwarding field to get to the real __Block_byref
437 // struct: DW_OP_deref.
438 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
439
440 // Now that we've got the real __Block_byref... struct, add the offset
441 // for the variable's field to get to the location of the actual variable:
442 // DW_OP_plus_uconst varFieldOffset. Again, don't add if it's 0.
443 if (varFieldOffset > 0) {
444 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
445 addUInt(Block, 0, dwarf::DW_FORM_udata, varFieldOffset);
446 }
447
448 // Now attach the location information to the DIE.
449 addBlock(Die, Attribute, 0, Block);
450}
451
Devang Patel4ec14b02011-07-20 21:57:04 +0000452/// isTypeSigned - Return true if the type is signed.
453static bool isTypeSigned(DIType Ty, int *SizeInBits) {
454 if (Ty.isDerivedType())
455 return isTypeSigned(DIDerivedType(Ty).getTypeDerivedFrom(), SizeInBits);
456 if (Ty.isBasicType())
457 if (DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed
458 || DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed_char) {
459 *SizeInBits = Ty.getSizeInBits();
460 return true;
461 }
462 return false;
463}
464
Devang Patel161b2f42011-04-12 23:21:44 +0000465/// addConstantValue - Add constant value entry in variable DIE.
Devang Patelb58128e2011-05-27 16:45:18 +0000466bool CompileUnit::addConstantValue(DIE *Die, const MachineOperand &MO,
467 DIType Ty) {
Nick Lewycky746cb672011-10-26 22:55:33 +0000468 assert(MO.isImm() && "Invalid machine operand!");
Devang Patel161b2f42011-04-12 23:21:44 +0000469 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel4ec14b02011-07-20 21:57:04 +0000470 int SizeInBits = -1;
471 bool SignedConstant = isTypeSigned(Ty, &SizeInBits);
472 unsigned Form = SignedConstant ? dwarf::DW_FORM_sdata : dwarf::DW_FORM_udata;
473 switch (SizeInBits) {
474 case 8: Form = dwarf::DW_FORM_data1; break;
475 case 16: Form = dwarf::DW_FORM_data2; break;
476 case 32: Form = dwarf::DW_FORM_data4; break;
477 case 64: Form = dwarf::DW_FORM_data8; break;
Devang Patel045c1d42011-05-27 19:13:26 +0000478 default: break;
479 }
Devang Patel4ec14b02011-07-20 21:57:04 +0000480 SignedConstant ? addSInt(Block, 0, Form, MO.getImm())
481 : addUInt(Block, 0, Form, MO.getImm());
Devang Patel72f0d9c2011-05-27 18:15:52 +0000482
Devang Patel161b2f42011-04-12 23:21:44 +0000483 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
484 return true;
485}
486
487/// addConstantFPValue - Add constant value entry in variable DIE.
488bool CompileUnit::addConstantFPValue(DIE *Die, const MachineOperand &MO) {
Nick Lewycky390c40d2011-10-27 06:44:11 +0000489 assert (MO.isFPImm() && "Invalid machine operand!");
Devang Patel161b2f42011-04-12 23:21:44 +0000490 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
491 APFloat FPImm = MO.getFPImm()->getValueAPF();
492
493 // Get the raw data form of the floating point.
494 const APInt FltVal = FPImm.bitcastToAPInt();
495 const char *FltPtr = (const char*)FltVal.getRawData();
496
497 int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte.
498 bool LittleEndian = Asm->getTargetData().isLittleEndian();
499 int Incr = (LittleEndian ? 1 : -1);
500 int Start = (LittleEndian ? 0 : NumBytes - 1);
501 int Stop = (LittleEndian ? NumBytes : -1);
502
503 // Output the constant to DWARF one byte at a time.
504 for (; Start != Stop; Start += Incr)
505 addUInt(Block, 0, dwarf::DW_FORM_data1,
506 (unsigned char)0xFF & FltPtr[Start]);
507
508 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
509 return true;
510}
511
512/// addConstantValue - Add constant value entry in variable DIE.
Devang Patel8594d422011-06-24 20:46:11 +0000513bool CompileUnit::addConstantValue(DIE *Die, const ConstantInt *CI,
Devang Patel161b2f42011-04-12 23:21:44 +0000514 bool Unsigned) {
Devang Pateld6a81362011-05-28 00:39:18 +0000515 unsigned CIBitWidth = CI->getBitWidth();
516 if (CIBitWidth <= 64) {
517 unsigned form = 0;
518 switch (CIBitWidth) {
519 case 8: form = dwarf::DW_FORM_data1; break;
520 case 16: form = dwarf::DW_FORM_data2; break;
521 case 32: form = dwarf::DW_FORM_data4; break;
522 case 64: form = dwarf::DW_FORM_data8; break;
523 default:
524 form = Unsigned ? dwarf::DW_FORM_udata : dwarf::DW_FORM_sdata;
525 }
Devang Patel161b2f42011-04-12 23:21:44 +0000526 if (Unsigned)
Devang Pateld6a81362011-05-28 00:39:18 +0000527 addUInt(Die, dwarf::DW_AT_const_value, form, CI->getZExtValue());
Devang Patel161b2f42011-04-12 23:21:44 +0000528 else
Devang Pateld6a81362011-05-28 00:39:18 +0000529 addSInt(Die, dwarf::DW_AT_const_value, form, CI->getSExtValue());
Devang Patel161b2f42011-04-12 23:21:44 +0000530 return true;
531 }
532
533 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
534
535 // Get the raw data form of the large APInt.
536 const APInt Val = CI->getValue();
NAKAMURA Takumic3e48c32011-10-28 14:12:22 +0000537 const uint64_t *Ptr64 = Val.getRawData();
Devang Patel161b2f42011-04-12 23:21:44 +0000538
539 int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte.
540 bool LittleEndian = Asm->getTargetData().isLittleEndian();
Devang Patel161b2f42011-04-12 23:21:44 +0000541
542 // Output the constant to DWARF one byte at a time.
NAKAMURA Takumic3e48c32011-10-28 14:12:22 +0000543 for (int i = 0; i < NumBytes; i++) {
544 uint8_t c;
545 if (LittleEndian)
546 c = Ptr64[i / 8] >> (8 * (i & 7));
547 else
548 c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7));
549 addUInt(Block, 0, dwarf::DW_FORM_data1, c);
550 }
Devang Patel161b2f42011-04-12 23:21:44 +0000551
552 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
553 return true;
554}
555
556/// addTemplateParams - Add template parameters in buffer.
557void CompileUnit::addTemplateParams(DIE &Buffer, DIArray TParams) {
558 // Add template parameters.
559 for (unsigned i = 0, e = TParams.getNumElements(); i != e; ++i) {
560 DIDescriptor Element = TParams.getElement(i);
561 if (Element.isTemplateTypeParameter())
562 Buffer.addChild(getOrCreateTemplateTypeParameterDIE(
563 DITemplateTypeParameter(Element)));
564 else if (Element.isTemplateValueParameter())
565 Buffer.addChild(getOrCreateTemplateValueParameterDIE(
566 DITemplateValueParameter(Element)));
567 }
Devang Patel161b2f42011-04-12 23:21:44 +0000568}
Nick Lewycky746cb672011-10-26 22:55:33 +0000569
Devang Patel161b2f42011-04-12 23:21:44 +0000570/// addToContextOwner - Add Die into the list of its context owner's children.
571void CompileUnit::addToContextOwner(DIE *Die, DIDescriptor Context) {
572 if (Context.isType()) {
573 DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context));
574 ContextDIE->addChild(Die);
575 } else if (Context.isNameSpace()) {
576 DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context));
577 ContextDIE->addChild(Die);
578 } else if (Context.isSubprogram()) {
Devang Pateldbc64af2011-08-15 17:24:54 +0000579 DIE *ContextDIE = getOrCreateSubprogramDIE(DISubprogram(Context));
Devang Patel161b2f42011-04-12 23:21:44 +0000580 ContextDIE->addChild(Die);
581 } else if (DIE *ContextDIE = getDIE(Context))
582 ContextDIE->addChild(Die);
583 else
584 addDie(Die);
585}
586
587/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
588/// given DIType.
Devang Patel94c7ddb2011-08-16 22:09:43 +0000589DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
590 DIType Ty(TyNode);
591 if (!Ty.Verify())
592 return NULL;
Devang Patel161b2f42011-04-12 23:21:44 +0000593 DIE *TyDIE = getDIE(Ty);
594 if (TyDIE)
595 return TyDIE;
596
597 // Create new type.
598 TyDIE = new DIE(dwarf::DW_TAG_base_type);
599 insertDIE(Ty, TyDIE);
600 if (Ty.isBasicType())
601 constructTypeDIE(*TyDIE, DIBasicType(Ty));
602 else if (Ty.isCompositeType())
603 constructTypeDIE(*TyDIE, DICompositeType(Ty));
604 else {
605 assert(Ty.isDerivedType() && "Unknown kind of DIType");
606 constructTypeDIE(*TyDIE, DIDerivedType(Ty));
607 }
608
609 addToContextOwner(TyDIE, Ty.getContext());
610 return TyDIE;
611}
612
613/// addType - Add a new type attribute to the specified entity.
614void CompileUnit::addType(DIE *Entity, DIType Ty) {
615 if (!Ty.Verify())
616 return;
617
618 // Check for pre-existence.
619 DIEEntry *Entry = getDIEEntry(Ty);
620 // If it exists then use the existing value.
621 if (Entry) {
622 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
623 return;
624 }
625
626 // Construct type.
627 DIE *Buffer = getOrCreateTypeDIE(Ty);
628
629 // Set up proxy.
630 Entry = createDIEEntry(Buffer);
631 insertDIEEntry(Ty, Entry);
Devang Patel161b2f42011-04-12 23:21:44 +0000632 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
Devang Patele9ae06c2011-05-31 22:56:51 +0000633
634 // If this is a complete composite type then include it in the
635 // list of global types.
Devang Patelc20bdf12011-06-01 00:23:24 +0000636 addGlobalType(Ty);
Devang Patel66658e42011-05-31 23:30:30 +0000637}
638
639/// addGlobalType - Add a new global type to the compile unit.
640///
Devang Patelc20bdf12011-06-01 00:23:24 +0000641void CompileUnit::addGlobalType(DIType Ty) {
Devang Patele9ae06c2011-05-31 22:56:51 +0000642 DIDescriptor Context = Ty.getContext();
643 if (Ty.isCompositeType() && !Ty.getName().empty() && !Ty.isForwardDecl()
Devang Patel94c7ddb2011-08-16 22:09:43 +0000644 && (!Context || Context.isCompileUnit() || Context.isFile()
645 || Context.isNameSpace()))
Devang Patelc20bdf12011-06-01 00:23:24 +0000646 if (DIEEntry *Entry = getDIEEntry(Ty))
647 GlobalTypes[Ty.getName()] = Entry->getEntry();
Devang Patel161b2f42011-04-12 23:21:44 +0000648}
649
Devang Patel31c5d052011-05-06 16:57:54 +0000650/// addPubTypes - Add type for pubtypes section.
651void CompileUnit::addPubTypes(DISubprogram SP) {
652 DICompositeType SPTy = SP.getType();
653 unsigned SPTag = SPTy.getTag();
654 if (SPTag != dwarf::DW_TAG_subroutine_type)
655 return;
656
657 DIArray Args = SPTy.getTypeArray();
658 for (unsigned i = 0, e = Args.getNumElements(); i != e; ++i) {
659 DIType ATy(Args.getElement(i));
660 if (!ATy.Verify())
661 continue;
Devang Patelc20bdf12011-06-01 00:23:24 +0000662 addGlobalType(ATy);
Devang Patel31c5d052011-05-06 16:57:54 +0000663 }
664}
665
Devang Patel161b2f42011-04-12 23:21:44 +0000666/// constructTypeDIE - Construct basic type die from DIBasicType.
667void CompileUnit::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
668 // Get core information.
669 StringRef Name = BTy.getName();
Devang Patel161b2f42011-04-12 23:21:44 +0000670 // Add name if not anonymous or intermediate type.
671 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000672 addString(&Buffer, dwarf::DW_AT_name, Name);
Devang Patel734a67c2011-09-14 23:13:28 +0000673
674 if (BTy.getTag() == dwarf::DW_TAG_unspecified_type) {
675 Buffer.setTag(dwarf::DW_TAG_unspecified_type);
676 // Unspecified types has only name, nothing else.
677 return;
678 }
679
680 Buffer.setTag(dwarf::DW_TAG_base_type);
Nick Lewycky746cb672011-10-26 22:55:33 +0000681 addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
Devang Patel734a67c2011-09-14 23:13:28 +0000682 BTy.getEncoding());
683
Devang Patel161b2f42011-04-12 23:21:44 +0000684 uint64_t Size = BTy.getSizeInBits() >> 3;
685 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
686}
687
688/// constructTypeDIE - Construct derived type die from DIDerivedType.
689void CompileUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
690 // Get core information.
691 StringRef Name = DTy.getName();
692 uint64_t Size = DTy.getSizeInBits() >> 3;
693 unsigned Tag = DTy.getTag();
694
695 // FIXME - Workaround for templates.
696 if (Tag == dwarf::DW_TAG_inheritance) Tag = dwarf::DW_TAG_reference_type;
697
698 Buffer.setTag(Tag);
699
700 // Map to main type, void will not have a type.
701 DIType FromTy = DTy.getTypeDerivedFrom();
702 addType(&Buffer, FromTy);
703
704 // Add name if not anonymous or intermediate type.
705 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000706 addString(&Buffer, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +0000707
708 // Add size if non-zero (derived types might be zero-sized.)
709 if (Size)
710 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
711
712 // Add source line info if available and TyDesc is not a forward declaration.
713 if (!DTy.isForwardDecl())
714 addSourceLine(&Buffer, DTy);
715}
716
717/// constructTypeDIE - Construct type DIE from DICompositeType.
718void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
719 // Get core information.
720 StringRef Name = CTy.getName();
721
722 uint64_t Size = CTy.getSizeInBits() >> 3;
723 unsigned Tag = CTy.getTag();
724 Buffer.setTag(Tag);
725
726 switch (Tag) {
727 case dwarf::DW_TAG_vector_type:
728 case dwarf::DW_TAG_array_type:
729 constructArrayTypeDIE(Buffer, &CTy);
730 break;
731 case dwarf::DW_TAG_enumeration_type: {
732 DIArray Elements = CTy.getTypeArray();
733
734 // Add enumerators to enumeration type.
735 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
736 DIE *ElemDie = NULL;
737 DIDescriptor Enum(Elements.getElement(i));
738 if (Enum.isEnumerator()) {
739 ElemDie = constructEnumTypeDIE(DIEnumerator(Enum));
740 Buffer.addChild(ElemDie);
741 }
742 }
743 }
744 break;
745 case dwarf::DW_TAG_subroutine_type: {
746 // Add return type.
747 DIArray Elements = CTy.getTypeArray();
748 DIDescriptor RTy = Elements.getElement(0);
749 addType(&Buffer, DIType(RTy));
750
751 bool isPrototyped = true;
752 // Add arguments.
753 for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
754 DIDescriptor Ty = Elements.getElement(i);
755 if (Ty.isUnspecifiedParameter()) {
756 DIE *Arg = new DIE(dwarf::DW_TAG_unspecified_parameters);
757 Buffer.addChild(Arg);
758 isPrototyped = false;
759 } else {
760 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
761 addType(Arg, DIType(Ty));
762 Buffer.addChild(Arg);
763 }
764 }
765 // Add prototype flag.
766 if (isPrototyped)
767 addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
768 }
769 break;
770 case dwarf::DW_TAG_structure_type:
771 case dwarf::DW_TAG_union_type:
772 case dwarf::DW_TAG_class_type: {
773 // Add elements to structure type.
774 DIArray Elements = CTy.getTypeArray();
775
776 // A forward struct declared type may not have elements available.
777 unsigned N = Elements.getNumElements();
778 if (N == 0)
779 break;
780
781 // Add elements to structure type.
782 for (unsigned i = 0; i < N; ++i) {
783 DIDescriptor Element = Elements.getElement(i);
784 DIE *ElemDie = NULL;
785 if (Element.isSubprogram()) {
786 DISubprogram SP(Element);
Devang Pateldbc64af2011-08-15 17:24:54 +0000787 ElemDie = getOrCreateSubprogramDIE(DISubprogram(Element));
Devang Patel161b2f42011-04-12 23:21:44 +0000788 if (SP.isProtected())
789 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
790 dwarf::DW_ACCESS_protected);
791 else if (SP.isPrivate())
792 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
793 dwarf::DW_ACCESS_private);
794 else
795 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
796 dwarf::DW_ACCESS_public);
797 if (SP.isExplicit())
798 addUInt(ElemDie, dwarf::DW_AT_explicit, dwarf::DW_FORM_flag, 1);
799 }
800 else if (Element.isVariable()) {
801 DIVariable DV(Element);
802 ElemDie = new DIE(dwarf::DW_TAG_variable);
Nick Lewycky390c40d2011-10-27 06:44:11 +0000803 addString(ElemDie, dwarf::DW_AT_name, DV.getName());
Devang Patel161b2f42011-04-12 23:21:44 +0000804 addType(ElemDie, DV.getType());
805 addUInt(ElemDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
806 addUInt(ElemDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
807 addSourceLine(ElemDie, DV);
808 } else if (Element.isDerivedType())
809 ElemDie = createMemberDIE(DIDerivedType(Element));
810 else
811 continue;
812 Buffer.addChild(ElemDie);
813 }
814
815 if (CTy.isAppleBlockExtension())
816 addUInt(&Buffer, dwarf::DW_AT_APPLE_block, dwarf::DW_FORM_flag, 1);
817
818 unsigned RLang = CTy.getRunTimeLang();
819 if (RLang)
820 addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class,
821 dwarf::DW_FORM_data1, RLang);
822
823 DICompositeType ContainingType = CTy.getContainingType();
824 if (DIDescriptor(ContainingType).isCompositeType())
825 addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
826 getOrCreateTypeDIE(DIType(ContainingType)));
827 else {
828 DIDescriptor Context = CTy.getContext();
829 addToContextOwner(&Buffer, Context);
830 }
831
Devang Patel201e6cd2011-05-12 21:29:42 +0000832 if (CTy.isObjcClassComplete())
833 addUInt(&Buffer, dwarf::DW_AT_APPLE_objc_complete_type,
Devang Patelb11f80e2011-05-12 19:06:16 +0000834 dwarf::DW_FORM_flag, 1);
835
Devang Patel161b2f42011-04-12 23:21:44 +0000836 if (Tag == dwarf::DW_TAG_class_type)
837 addTemplateParams(Buffer, CTy.getTemplateParams());
838
839 break;
840 }
841 default:
842 break;
843 }
844
845 // Add name if not anonymous or intermediate type.
846 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000847 addString(&Buffer, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +0000848
849 if (Tag == dwarf::DW_TAG_enumeration_type || Tag == dwarf::DW_TAG_class_type
850 || Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type)
Nick Lewycky746cb672011-10-26 22:55:33 +0000851 {
Devang Patel161b2f42011-04-12 23:21:44 +0000852 // Add size if non-zero (derived types might be zero-sized.)
853 if (Size)
854 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
855 else {
856 // Add zero size if it is not a forward declaration.
857 if (CTy.isForwardDecl())
858 addUInt(&Buffer, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
859 else
860 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, 0);
861 }
862
863 // Add source line info if available.
864 if (!CTy.isForwardDecl())
865 addSourceLine(&Buffer, CTy);
866 }
867}
868
869/// getOrCreateTemplateTypeParameterDIE - Find existing DIE or create new DIE
870/// for the given DITemplateTypeParameter.
871DIE *
872CompileUnit::getOrCreateTemplateTypeParameterDIE(DITemplateTypeParameter TP) {
873 DIE *ParamDIE = getDIE(TP);
874 if (ParamDIE)
875 return ParamDIE;
876
877 ParamDIE = new DIE(dwarf::DW_TAG_template_type_parameter);
878 addType(ParamDIE, TP.getType());
Nick Lewycky390c40d2011-10-27 06:44:11 +0000879 addString(ParamDIE, dwarf::DW_AT_name, TP.getName());
Devang Patel161b2f42011-04-12 23:21:44 +0000880 return ParamDIE;
881}
882
883/// getOrCreateTemplateValueParameterDIE - Find existing DIE or create new DIE
884/// for the given DITemplateValueParameter.
885DIE *
886CompileUnit::getOrCreateTemplateValueParameterDIE(DITemplateValueParameter TPV) {
887 DIE *ParamDIE = getDIE(TPV);
888 if (ParamDIE)
889 return ParamDIE;
890
891 ParamDIE = new DIE(dwarf::DW_TAG_template_value_parameter);
892 addType(ParamDIE, TPV.getType());
893 if (!TPV.getName().empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000894 addString(ParamDIE, dwarf::DW_AT_name, TPV.getName());
Devang Patel161b2f42011-04-12 23:21:44 +0000895 addUInt(ParamDIE, dwarf::DW_AT_const_value, dwarf::DW_FORM_udata,
896 TPV.getValue());
897 return ParamDIE;
898}
899
Devang Patel31c5d052011-05-06 16:57:54 +0000900/// getOrCreateNameSpace - Create a DIE for DINameSpace.
901DIE *CompileUnit::getOrCreateNameSpace(DINameSpace NS) {
902 DIE *NDie = getDIE(NS);
903 if (NDie)
904 return NDie;
905 NDie = new DIE(dwarf::DW_TAG_namespace);
906 insertDIE(NS, NDie);
Eric Christopher09ac3d82011-11-07 09:24:32 +0000907 if (!NS.getName().empty()) {
Nick Lewycky390c40d2011-10-27 06:44:11 +0000908 addString(NDie, dwarf::DW_AT_name, NS.getName());
Eric Christopher09ac3d82011-11-07 09:24:32 +0000909 addAccelNamespace(NS.getName(), NDie);
910 } else
911 addAccelNamespace("(anonymous namespace)", NDie);
Devang Patel31c5d052011-05-06 16:57:54 +0000912 addSourceLine(NDie, NS);
913 addToContextOwner(NDie, NS.getContext());
914 return NDie;
915}
916
Devang Pateldbc64af2011-08-15 17:24:54 +0000917/// getRealLinkageName - If special LLVM prefix that is used to inform the asm
918/// printer to not emit usual symbol prefix before the symbol name is used then
919/// return linkage name after skipping this special LLVM prefix.
920static StringRef getRealLinkageName(StringRef LinkageName) {
921 char One = '\1';
922 if (LinkageName.startswith(StringRef(&One, 1)))
923 return LinkageName.substr(1);
924 return LinkageName;
925}
926
927/// getOrCreateSubprogramDIE - Create new DIE using SP.
928DIE *CompileUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
929 DIE *SPDie = getDIE(SP);
930 if (SPDie)
931 return SPDie;
932
933 SPDie = new DIE(dwarf::DW_TAG_subprogram);
934
935 // DW_TAG_inlined_subroutine may refer to this DIE.
936 insertDIE(SP, SPDie);
937
938 // Add to context owner.
939 addToContextOwner(SPDie, SP.getContext());
940
941 // Add function template parameters.
942 addTemplateParams(*SPDie, SP.getTemplateParams());
943
944 StringRef LinkageName = SP.getLinkageName();
945 if (!LinkageName.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000946 addString(SPDie, dwarf::DW_AT_MIPS_linkage_name,
Nick Lewycky746cb672011-10-26 22:55:33 +0000947 getRealLinkageName(LinkageName));
Devang Pateldbc64af2011-08-15 17:24:54 +0000948
949 // If this DIE is going to refer declaration info using AT_specification
950 // then there is no need to add other attributes.
951 if (SP.getFunctionDeclaration().isSubprogram())
952 return SPDie;
953
954 // Constructors and operators for anonymous aggregates do not have names.
955 if (!SP.getName().empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000956 addString(SPDie, dwarf::DW_AT_name, SP.getName());
Devang Pateldbc64af2011-08-15 17:24:54 +0000957
958 addSourceLine(SPDie, SP);
959
960 if (SP.isPrototyped())
961 addUInt(SPDie, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
962
963 // Add Return Type.
964 DICompositeType SPTy = SP.getType();
965 DIArray Args = SPTy.getTypeArray();
966 unsigned SPTag = SPTy.getTag();
967
968 if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type)
969 addType(SPDie, SPTy);
970 else
971 addType(SPDie, DIType(Args.getElement(0)));
972
973 unsigned VK = SP.getVirtuality();
974 if (VK) {
975 addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK);
976 DIEBlock *Block = getDIEBlock();
977 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
978 addUInt(Block, 0, dwarf::DW_FORM_udata, SP.getVirtualIndex());
979 addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
980 ContainingTypeMap.insert(std::make_pair(SPDie,
981 SP.getContainingType()));
982 }
983
984 if (!SP.isDefinition()) {
985 addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
986
987 // Add arguments. Do not add arguments for subprogram definition. They will
988 // be handled while processing variables.
989 DICompositeType SPTy = SP.getType();
990 DIArray Args = SPTy.getTypeArray();
991 unsigned SPTag = SPTy.getTag();
992
993 if (SPTag == dwarf::DW_TAG_subroutine_type)
994 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
995 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
996 DIType ATy = DIType(DIType(Args.getElement(i)));
997 addType(Arg, ATy);
998 if (ATy.isArtificial())
999 addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
1000 SPDie->addChild(Arg);
1001 }
1002 }
1003
1004 if (SP.isArtificial())
1005 addUInt(SPDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
1006
1007 if (!SP.isLocalToUnit())
1008 addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
1009
1010 if (SP.isOptimized())
1011 addUInt(SPDie, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1);
1012
1013 if (unsigned isa = Asm->getISAEncoding()) {
1014 addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa);
1015 }
1016
1017 return SPDie;
1018}
1019
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001020// Return const expression if value is a GEP to access merged global
1021// constant. e.g.
1022// i8* getelementptr ({ i8, i8, i8, i8 }* @_MergedGlobals, i32 0, i32 0)
1023static const ConstantExpr *getMergedGlobalExpr(const Value *V) {
1024 const ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(V);
1025 if (!CE || CE->getNumOperands() != 3 ||
1026 CE->getOpcode() != Instruction::GetElementPtr)
1027 return NULL;
1028
1029 // First operand points to a global struct.
1030 Value *Ptr = CE->getOperand(0);
1031 if (!isa<GlobalValue>(Ptr) ||
1032 !isa<StructType>(cast<PointerType>(Ptr->getType())->getElementType()))
1033 return NULL;
1034
1035 // Second operand is zero.
1036 const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CE->getOperand(1));
1037 if (!CI || !CI->isZero())
1038 return NULL;
1039
1040 // Third operand is offset.
1041 if (!isa<ConstantInt>(CE->getOperand(2)))
1042 return NULL;
1043
1044 return CE;
1045}
1046
1047/// createGlobalVariableDIE - create global variable DIE.
1048void CompileUnit::createGlobalVariableDIE(const MDNode *N) {
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001049 // Check for pre-existence.
Devang Patel49e2f032011-08-18 22:21:50 +00001050 if (getDIE(N))
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001051 return;
1052
Devang Patel49e2f032011-08-18 22:21:50 +00001053 DIGlobalVariable GV(N);
Devang Patel28bea082011-08-18 23:17:55 +00001054 if (!GV.Verify())
1055 return;
1056
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001057 DIE *VariableDIE = new DIE(GV.getTag());
Devang Patel49e2f032011-08-18 22:21:50 +00001058 // Add to map.
1059 insertDIE(N, VariableDIE);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001060
1061 // Add name.
Nick Lewycky390c40d2011-10-27 06:44:11 +00001062 addString(VariableDIE, dwarf::DW_AT_name, GV.getDisplayName());
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001063 StringRef LinkageName = GV.getLinkageName();
Devang Patel49e2f032011-08-18 22:21:50 +00001064 bool isGlobalVariable = GV.getGlobal() != NULL;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001065 if (!LinkageName.empty() && isGlobalVariable)
Nick Lewycky746cb672011-10-26 22:55:33 +00001066 addString(VariableDIE, dwarf::DW_AT_MIPS_linkage_name,
Nick Lewycky390c40d2011-10-27 06:44:11 +00001067 getRealLinkageName(LinkageName));
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001068 // Add type.
Devang Patel49e2f032011-08-18 22:21:50 +00001069 DIType GTy = GV.getType();
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001070 addType(VariableDIE, GTy);
1071
1072 // Add scoping info.
1073 if (!GV.isLocalToUnit()) {
1074 addUInt(VariableDIE, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
1075 // Expose as global.
1076 addGlobal(GV.getName(), VariableDIE);
1077 }
1078 // Add line number info.
1079 addSourceLine(VariableDIE, GV);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001080 // Add to context owner.
1081 DIDescriptor GVContext = GV.getContext();
1082 addToContextOwner(VariableDIE, GVContext);
1083 // Add location.
Eric Christopher09ac3d82011-11-07 09:24:32 +00001084 bool addToAccelTable = false;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001085 if (isGlobalVariable) {
Eric Christopher09ac3d82011-11-07 09:24:32 +00001086 addToAccelTable = true;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001087 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
1088 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
1089 addLabel(Block, 0, dwarf::DW_FORM_udata,
1090 Asm->Mang->getSymbol(GV.getGlobal()));
1091 // Do not create specification DIE if context is either compile unit
1092 // or a subprogram.
Devang Patel1dd4e562011-09-21 23:41:11 +00001093 if (GVContext && GV.isDefinition() && !GVContext.isCompileUnit() &&
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001094 !GVContext.isFile() && !isSubprogramContext(GVContext)) {
1095 // Create specification DIE.
1096 DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
1097 addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
1098 dwarf::DW_FORM_ref4, VariableDIE);
1099 addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
1100 addUInt(VariableDIE, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag,
1101 1);
1102 addDie(VariableSpecDIE);
1103 } else {
1104 addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
Eric Christopher09ac3d82011-11-07 09:24:32 +00001105 }
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001106 } else if (const ConstantInt *CI =
1107 dyn_cast_or_null<ConstantInt>(GV.getConstant()))
1108 addConstantValue(VariableDIE, CI, GTy.isUnsignedDIType());
1109 else if (const ConstantExpr *CE = getMergedGlobalExpr(N->getOperand(11))) {
Eric Christopher09ac3d82011-11-07 09:24:32 +00001110 addToAccelTable = true;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001111 // GV is a merged global.
1112 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
1113 Value *Ptr = CE->getOperand(0);
1114 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
1115 addLabel(Block, 0, dwarf::DW_FORM_udata,
1116 Asm->Mang->getSymbol(cast<GlobalValue>(Ptr)));
1117 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1118 SmallVector<Value*, 3> Idx(CE->op_begin()+1, CE->op_end());
1119 addUInt(Block, 0, dwarf::DW_FORM_udata,
1120 Asm->getTargetData().getIndexedOffset(Ptr->getType(), Idx));
1121 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1122 addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
1123 }
1124
Eric Christopher09ac3d82011-11-07 09:24:32 +00001125 if (addToAccelTable)
1126 addAccelName(GV.getName(), VariableDIE);
1127
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001128 return;
1129}
1130
Devang Patel161b2f42011-04-12 23:21:44 +00001131/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
1132void CompileUnit::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){
1133 DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type);
1134 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IndexTy);
1135 int64_t L = SR.getLo();
1136 int64_t H = SR.getHi();
1137
1138 // The L value defines the lower bounds which is typically zero for C/C++. The
1139 // H value is the upper bounds. Values are 64 bit. H - L + 1 is the size
1140 // of the array. If L > H then do not emit DW_AT_lower_bound and
1141 // DW_AT_upper_bound attributes. If L is zero and H is also zero then the
1142 // array has one element and in such case do not emit lower bound.
1143
1144 if (L > H) {
1145 Buffer.addChild(DW_Subrange);
1146 return;
1147 }
1148 if (L)
1149 addSInt(DW_Subrange, dwarf::DW_AT_lower_bound, 0, L);
1150 addSInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, H);
1151 Buffer.addChild(DW_Subrange);
1152}
1153
1154/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
1155void CompileUnit::constructArrayTypeDIE(DIE &Buffer,
1156 DICompositeType *CTy) {
1157 Buffer.setTag(dwarf::DW_TAG_array_type);
1158 if (CTy->getTag() == dwarf::DW_TAG_vector_type)
1159 addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1);
1160
1161 // Emit derived type.
1162 addType(&Buffer, CTy->getTypeDerivedFrom());
1163 DIArray Elements = CTy->getTypeArray();
1164
1165 // Get an anonymous type for index type.
1166 DIE *IdxTy = getIndexTyDie();
1167 if (!IdxTy) {
1168 // Construct an anonymous type for index type.
1169 IdxTy = new DIE(dwarf::DW_TAG_base_type);
1170 addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t));
1171 addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
1172 dwarf::DW_ATE_signed);
1173 addDie(IdxTy);
1174 setIndexTyDie(IdxTy);
1175 }
1176
1177 // Add subranges to array type.
1178 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
1179 DIDescriptor Element = Elements.getElement(i);
1180 if (Element.getTag() == dwarf::DW_TAG_subrange_type)
1181 constructSubrangeDIE(Buffer, DISubrange(Element), IdxTy);
1182 }
1183}
1184
1185/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
1186DIE *CompileUnit::constructEnumTypeDIE(DIEnumerator ETy) {
1187 DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator);
1188 StringRef Name = ETy.getName();
Nick Lewycky390c40d2011-10-27 06:44:11 +00001189 addString(Enumerator, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +00001190 int64_t Value = ETy.getEnumValue();
1191 addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value);
1192 return Enumerator;
1193}
1194
Devang Pateldbc64af2011-08-15 17:24:54 +00001195/// constructContainingTypeDIEs - Construct DIEs for types that contain
1196/// vtables.
1197void CompileUnit::constructContainingTypeDIEs() {
1198 for (DenseMap<DIE *, const MDNode *>::iterator CI = ContainingTypeMap.begin(),
1199 CE = ContainingTypeMap.end(); CI != CE; ++CI) {
1200 DIE *SPDie = CI->first;
1201 const MDNode *N = CI->second;
1202 if (!N) continue;
1203 DIE *NDie = getDIE(N);
1204 if (!NDie) continue;
1205 addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
1206 }
1207}
1208
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001209/// constructVariableDIE - Construct a DIE for the given DbgVariable.
1210DIE *CompileUnit::constructVariableDIE(DbgVariable *DV, bool isScopeAbstract) {
1211 StringRef Name = DV->getName();
1212 if (Name.empty())
1213 return NULL;
1214
1215 // Translate tag to proper Dwarf tag.
1216 unsigned Tag = DV->getTag();
1217
1218 // Define variable debug information entry.
1219 DIE *VariableDie = new DIE(Tag);
1220 DbgVariable *AbsVar = DV->getAbstractVariable();
1221 DIE *AbsDIE = AbsVar ? AbsVar->getDIE() : NULL;
1222 if (AbsDIE)
1223 addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin,
1224 dwarf::DW_FORM_ref4, AbsDIE);
1225 else {
Nick Lewycky390c40d2011-10-27 06:44:11 +00001226 addString(VariableDie, dwarf::DW_AT_name, Name);
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001227 addSourceLine(VariableDie, DV->getVariable());
1228 addType(VariableDie, DV->getType());
1229 }
1230
1231 if (DV->isArtificial())
1232 addUInt(VariableDie, dwarf::DW_AT_artificial,
1233 dwarf::DW_FORM_flag, 1);
1234
1235 if (isScopeAbstract) {
1236 DV->setDIE(VariableDie);
1237 return VariableDie;
1238 }
1239
1240 // Add variable address.
1241
1242 unsigned Offset = DV->getDotDebugLocOffset();
1243 if (Offset != ~0U) {
1244 addLabel(VariableDie, dwarf::DW_AT_location,
1245 dwarf::DW_FORM_data4,
1246 Asm->GetTempSymbol("debug_loc", Offset));
1247 DV->setDIE(VariableDie);
1248 return VariableDie;
1249 }
1250
Eric Christopher8cf5e742011-10-03 15:49:20 +00001251 // Check if variable is described by a DBG_VALUE instruction.
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001252 if (const MachineInstr *DVInsn = DV->getMInsn()) {
1253 bool updated = false;
1254 if (DVInsn->getNumOperands() == 3) {
1255 if (DVInsn->getOperand(0).isReg()) {
1256 const MachineOperand RegOp = DVInsn->getOperand(0);
1257 const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
1258 if (DVInsn->getOperand(1).isImm() &&
1259 TRI->getFrameRegister(*Asm->MF) == RegOp.getReg()) {
1260 unsigned FrameReg = 0;
1261 const TargetFrameLowering *TFI = Asm->TM.getFrameLowering();
1262 int Offset =
1263 TFI->getFrameIndexReference(*Asm->MF,
1264 DVInsn->getOperand(1).getImm(),
1265 FrameReg);
1266 MachineLocation Location(FrameReg, Offset);
1267 addVariableAddress(DV, VariableDie, Location);
1268
1269 } else if (RegOp.getReg())
1270 addVariableAddress(DV, VariableDie,
1271 MachineLocation(RegOp.getReg()));
1272 updated = true;
1273 }
1274 else if (DVInsn->getOperand(0).isImm())
1275 updated =
1276 addConstantValue(VariableDie, DVInsn->getOperand(0),
1277 DV->getType());
1278 else if (DVInsn->getOperand(0).isFPImm())
1279 updated =
1280 addConstantFPValue(VariableDie, DVInsn->getOperand(0));
1281 else if (DVInsn->getOperand(0).isCImm())
1282 updated =
1283 addConstantValue(VariableDie,
1284 DVInsn->getOperand(0).getCImm(),
1285 DV->getType().isUnsignedDIType());
1286 } else {
1287 addVariableAddress(DV, VariableDie,
1288 Asm->getDebugValueLocation(DVInsn));
1289 updated = true;
1290 }
1291 if (!updated) {
1292 // If variableDie is not updated then DBG_VALUE instruction does not
1293 // have valid variable info.
1294 delete VariableDie;
1295 return NULL;
1296 }
1297 DV->setDIE(VariableDie);
1298 return VariableDie;
1299 } else {
1300 // .. else use frame index.
1301 int FI = DV->getFrameIndex();
1302 if (FI != ~0) {
1303 unsigned FrameReg = 0;
1304 const TargetFrameLowering *TFI = Asm->TM.getFrameLowering();
1305 int Offset =
1306 TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg);
1307 MachineLocation Location(FrameReg, Offset);
1308 addVariableAddress(DV, VariableDie, Location);
1309 }
1310 }
1311
1312 DV->setDIE(VariableDie);
1313 return VariableDie;
1314}
1315
Devang Patel161b2f42011-04-12 23:21:44 +00001316/// createMemberDIE - Create new member DIE.
1317DIE *CompileUnit::createMemberDIE(DIDerivedType DT) {
1318 DIE *MemberDie = new DIE(DT.getTag());
1319 StringRef Name = DT.getName();
1320 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001321 addString(MemberDie, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +00001322
1323 addType(MemberDie, DT.getTypeDerivedFrom());
1324
1325 addSourceLine(MemberDie, DT);
1326
1327 DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
1328 addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
1329
1330 uint64_t Size = DT.getSizeInBits();
1331 uint64_t FieldSize = DT.getOriginalTypeSize();
1332
1333 if (Size != FieldSize) {
1334 // Handle bitfield.
1335 addUInt(MemberDie, dwarf::DW_AT_byte_size, 0, DT.getOriginalTypeSize()>>3);
1336 addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits());
1337
1338 uint64_t Offset = DT.getOffsetInBits();
1339 uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
1340 uint64_t HiMark = (Offset + FieldSize) & AlignMask;
1341 uint64_t FieldOffset = (HiMark - FieldSize);
1342 Offset -= FieldOffset;
1343
1344 // Maybe we need to work from the other end.
1345 if (Asm->getTargetData().isLittleEndian())
1346 Offset = FieldSize - (Offset + Size);
1347 addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
1348
1349 // Here WD_AT_data_member_location points to the anonymous
1350 // field that includes this bit field.
1351 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, FieldOffset >> 3);
1352
1353 } else
1354 // This is not a bitfield.
1355 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);
1356
1357 if (DT.getTag() == dwarf::DW_TAG_inheritance
1358 && DT.isVirtual()) {
1359
1360 // For C++, virtual base classes are not at fixed offset. Use following
1361 // expression to extract appropriate offset from vtable.
1362 // BaseAddr = ObAddr + *((*ObAddr) - Offset)
1363
1364 DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock();
1365 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
1366 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1367 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1368 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits());
1369 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
1370 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1371 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1372
1373 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0,
1374 VBaseLocationDie);
1375 } else
1376 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
1377
1378 if (DT.isProtected())
1379 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1380 dwarf::DW_ACCESS_protected);
1381 else if (DT.isPrivate())
1382 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1383 dwarf::DW_ACCESS_private);
1384 // Otherwise C++ member and base classes are considered public.
Devang Patel94c7ddb2011-08-16 22:09:43 +00001385 else
Devang Patel161b2f42011-04-12 23:21:44 +00001386 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1387 dwarf::DW_ACCESS_public);
1388 if (DT.isVirtual())
1389 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag,
1390 dwarf::DW_VIRTUALITY_virtual);
Devang Patele9db5e22011-04-16 00:11:51 +00001391
1392 // Objective-C properties.
1393 StringRef PropertyName = DT.getObjCPropertyName();
1394 if (!PropertyName.empty()) {
Nick Lewycky390c40d2011-10-27 06:44:11 +00001395 addString(MemberDie, dwarf::DW_AT_APPLE_property_name, PropertyName);
Devang Patele9db5e22011-04-16 00:11:51 +00001396 StringRef GetterName = DT.getObjCPropertyGetterName();
1397 if (!GetterName.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001398 addString(MemberDie, dwarf::DW_AT_APPLE_property_getter, GetterName);
Devang Patele9db5e22011-04-16 00:11:51 +00001399 StringRef SetterName = DT.getObjCPropertySetterName();
1400 if (!SetterName.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001401 addString(MemberDie, dwarf::DW_AT_APPLE_property_setter, SetterName);
Devang Patele9db5e22011-04-16 00:11:51 +00001402 unsigned PropertyAttributes = 0;
1403 if (DT.isReadOnlyObjCProperty())
1404 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readonly;
1405 if (DT.isReadWriteObjCProperty())
1406 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readwrite;
1407 if (DT.isAssignObjCProperty())
1408 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_assign;
1409 if (DT.isRetainObjCProperty())
1410 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_retain;
1411 if (DT.isCopyObjCProperty())
1412 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_copy;
1413 if (DT.isNonAtomicObjCProperty())
1414 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_nonatomic;
1415 if (PropertyAttributes)
1416 addUInt(MemberDie, dwarf::DW_AT_APPLE_property_attribute, 0,
1417 PropertyAttributes);
1418 }
Devang Patel161b2f42011-04-12 23:21:44 +00001419 return MemberDie;
1420}