blob: f7462ef37a79f93757eb6fdc96e389ca2a514c2e [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"
19#include "llvm/Analysis/DIBuilder.h"
20#include "llvm/Target/TargetData.h"
21#include "llvm/Target/TargetFrameLowering.h"
22#include "llvm/Target/TargetMachine.h"
23#include "llvm/Target/TargetRegisterInfo.h"
24#include "llvm/ADT/APFloat.h"
25#include "llvm/Support/ErrorHandling.h"
26
27using namespace llvm;
28
29/// CompileUnit - Compile unit constructor.
30CompileUnit::CompileUnit(unsigned I, DIE *D, AsmPrinter *A, DwarfDebug *DW)
31 : ID(I), CUDie(D), Asm(A), DD(DW), IndexTyDie(0) {
32 DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1);
33}
34
35/// ~CompileUnit - Destructor for compile unit.
36CompileUnit::~CompileUnit() {
37 for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
38 DIEBlocks[j]->~DIEBlock();
39}
40
41/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug
42/// information entry.
43DIEEntry *CompileUnit::createDIEEntry(DIE *Entry) {
44 DIEEntry *Value = new (DIEValueAllocator) DIEEntry(Entry);
45 return Value;
46}
47
48/// addUInt - Add an unsigned integer attribute data and value.
49///
50void CompileUnit::addUInt(DIE *Die, unsigned Attribute,
51 unsigned Form, uint64_t Integer) {
52 if (!Form) Form = DIEInteger::BestForm(false, Integer);
53 DIEValue *Value = Integer == 1 ?
54 DIEIntegerOne : new (DIEValueAllocator) DIEInteger(Integer);
55 Die->addValue(Attribute, Form, Value);
56}
57
58/// addSInt - Add an signed integer attribute data and value.
59///
60void CompileUnit::addSInt(DIE *Die, unsigned Attribute,
61 unsigned Form, int64_t Integer) {
62 if (!Form) Form = DIEInteger::BestForm(true, Integer);
63 DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
64 Die->addValue(Attribute, Form, Value);
65}
66
67/// addString - Add a string attribute data and value. DIEString only
68/// keeps string reference.
69void CompileUnit::addString(DIE *Die, unsigned Attribute, unsigned Form,
70 StringRef String) {
71 DIEValue *Value = new (DIEValueAllocator) DIEString(String);
72 Die->addValue(Attribute, Form, Value);
73}
74
75/// addLabel - Add a Dwarf label attribute data and value.
76///
77void CompileUnit::addLabel(DIE *Die, unsigned Attribute, unsigned Form,
78 const MCSymbol *Label) {
79 DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
80 Die->addValue(Attribute, Form, Value);
81}
82
83/// addDelta - Add a label delta attribute data and value.
84///
85void CompileUnit::addDelta(DIE *Die, unsigned Attribute, unsigned Form,
86 const MCSymbol *Hi, const MCSymbol *Lo) {
87 DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo);
88 Die->addValue(Attribute, Form, Value);
89}
90
91/// addDIEEntry - Add a DIE attribute data and value.
92///
93void CompileUnit::addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form,
94 DIE *Entry) {
95 Die->addValue(Attribute, Form, createDIEEntry(Entry));
96}
97
98
99/// addBlock - Add block data.
100///
101void CompileUnit::addBlock(DIE *Die, unsigned Attribute, unsigned Form,
102 DIEBlock *Block) {
103 Block->ComputeSize(Asm);
104 DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.
105 Die->addValue(Attribute, Block->BestForm(), Block);
106}
107
108/// addSourceLine - Add location information to specified debug information
109/// entry.
110void CompileUnit::addSourceLine(DIE *Die, DIVariable V) {
111 // Verify variable.
112 if (!V.Verify())
113 return;
114
115 unsigned Line = V.getLineNumber();
116 if (Line == 0)
117 return;
118 unsigned FileID = DD->GetOrCreateSourceID(V.getContext().getFilename(),
119 V.getContext().getDirectory());
120 assert(FileID && "Invalid file id");
121 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
122 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
123}
124
125/// addSourceLine - Add location information to specified debug information
126/// entry.
127void CompileUnit::addSourceLine(DIE *Die, DIGlobalVariable G) {
128 // Verify global variable.
129 if (!G.Verify())
130 return;
131
132 unsigned Line = G.getLineNumber();
133 if (Line == 0)
134 return;
135 unsigned FileID = DD->GetOrCreateSourceID(G.getContext().getFilename(),
136 G.getContext().getDirectory());
137 assert(FileID && "Invalid file id");
138 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
139 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
140}
141
142/// addSourceLine - Add location information to specified debug information
143/// entry.
144void CompileUnit::addSourceLine(DIE *Die, DISubprogram SP) {
145 // Verify subprogram.
146 if (!SP.Verify())
147 return;
148 // If the line number is 0, don't add it.
149 if (SP.getLineNumber() == 0)
150 return;
151
152 unsigned Line = SP.getLineNumber();
153 if (!SP.getContext().Verify())
154 return;
155 unsigned FileID = DD->GetOrCreateSourceID(SP.getFilename(), SP.getDirectory());
156 assert(FileID && "Invalid file id");
157 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
158 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
159}
160
161/// addSourceLine - Add location information to specified debug information
162/// entry.
163void CompileUnit::addSourceLine(DIE *Die, DIType Ty) {
164 // Verify type.
165 if (!Ty.Verify())
166 return;
167
168 unsigned Line = Ty.getLineNumber();
169 if (Line == 0 || !Ty.getContext().Verify())
170 return;
171 unsigned FileID = DD->GetOrCreateSourceID(Ty.getFilename(), Ty.getDirectory());
172 assert(FileID && "Invalid file id");
173 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
174 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
175}
176
177/// addSourceLine - Add location information to specified debug information
178/// entry.
179void CompileUnit::addSourceLine(DIE *Die, DINameSpace NS) {
180 // Verify namespace.
181 if (!NS.Verify())
182 return;
183
184 unsigned Line = NS.getLineNumber();
185 if (Line == 0)
186 return;
187 StringRef FN = NS.getFilename();
188
189 unsigned FileID = DD->GetOrCreateSourceID(FN, NS.getDirectory());
190 assert(FileID && "Invalid file id");
191 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
192 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
193}
194
Devang Patele1cdf842011-04-27 22:45:24 +0000195/// addVariableAddress - Add DW_AT_location attribute for a
196/// DbgVariable based on provided MachineLocation.
197void CompileUnit::addVariableAddress(DbgVariable *&DV, DIE *Die,
198 MachineLocation Location) {
Devang Patel161b2f42011-04-12 23:21:44 +0000199 if (DV->variableHasComplexAddress())
200 addComplexAddress(DV, Die, dwarf::DW_AT_location, Location);
201 else if (DV->isBlockByrefVariable())
202 addBlockByrefAddress(DV, Die, dwarf::DW_AT_location, Location);
203 else
204 addAddress(Die, dwarf::DW_AT_location, Location);
205}
206
Devang Patel116da2f2011-04-26 19:06:18 +0000207/// addRegisterOp - Add register operand.
208void CompileUnit::addRegisterOp(DIE *TheDie, unsigned Reg) {
209 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
210 unsigned DWReg = RI->getDwarfRegNum(Reg, false);
211 if (DWReg < 32)
212 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + DWReg);
213 else {
214 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx);
215 addUInt(TheDie, 0, dwarf::DW_FORM_udata, DWReg);
216 }
217}
218
219/// addRegisterOffset - Add register offset.
220void CompileUnit::addRegisterOffset(DIE *TheDie, unsigned Reg,
221 int64_t Offset) {
222 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
223 unsigned DWReg = RI->getDwarfRegNum(Reg, false);
224 const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
225 if (Reg == TRI->getFrameRegister(*Asm->MF))
226 // If variable offset is based in frame register then use fbreg.
227 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_fbreg);
228 else if (DWReg < 32)
229 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + DWReg);
230 else {
231 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
232 addUInt(TheDie, 0, dwarf::DW_FORM_udata, DWReg);
233 }
234 addSInt(TheDie, 0, dwarf::DW_FORM_sdata, Offset);
235}
236
237/// addAddress - Add an address attribute to a die based on the location
238/// provided.
239void CompileUnit::addAddress(DIE *Die, unsigned Attribute,
240 const MachineLocation &Location) {
241 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
242
243 if (Location.isReg())
244 addRegisterOp(Block, Location.getReg());
245 else
246 addRegisterOffset(Block, Location.getReg(), Location.getOffset());
247
248 // Now attach the location information to the DIE.
249 addBlock(Die, Attribute, 0, Block);
250}
251
Devang Patel161b2f42011-04-12 23:21:44 +0000252/// addComplexAddress - Start with the address based on the location provided,
253/// and generate the DWARF information necessary to find the actual variable
254/// given the extra address information encoded in the DIVariable, starting from
255/// the starting location. Add the DWARF information to the die.
256///
257void CompileUnit::addComplexAddress(DbgVariable *&DV, DIE *Die,
258 unsigned Attribute,
259 const MachineLocation &Location) {
Devang Patel161b2f42011-04-12 23:21:44 +0000260 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patelc26f5442011-04-28 02:22:40 +0000261 unsigned N = DV->getNumAddrElements();
262 unsigned i = 0;
263 if (Location.isReg()) {
264 if (N >= 2 && DV->getAddrElement(0) == DIBuilder::OpPlus) {
265 // If first address element is OpPlus then emit
266 // DW_OP_breg + Offset instead of DW_OP_reg + Offset.
267 addRegisterOffset(Block, Location.getReg(), DV->getAddrElement(1));
268 i = 2;
269 } else
270 addRegisterOp(Block, Location.getReg());
271 }
Devang Patel116da2f2011-04-26 19:06:18 +0000272 else
273 addRegisterOffset(Block, Location.getReg(), Location.getOffset());
Devang Patel161b2f42011-04-12 23:21:44 +0000274
Devang Patelc26f5442011-04-28 02:22:40 +0000275 for (;i < N; ++i) {
Devang Patel161b2f42011-04-12 23:21:44 +0000276 uint64_t Element = DV->getAddrElement(i);
Devang Patel161b2f42011-04-12 23:21:44 +0000277 if (Element == DIBuilder::OpPlus) {
278 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
279 addUInt(Block, 0, dwarf::DW_FORM_udata, DV->getAddrElement(++i));
280 } else if (Element == DIBuilder::OpDeref) {
281 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
282 } else llvm_unreachable("unknown DIBuilder Opcode");
283 }
284
285 // Now attach the location information to the DIE.
286 addBlock(Die, Attribute, 0, Block);
287}
288
289/* Byref variables, in Blocks, are declared by the programmer as "SomeType
290 VarName;", but the compiler creates a __Block_byref_x_VarName struct, and
291 gives the variable VarName either the struct, or a pointer to the struct, as
292 its type. This is necessary for various behind-the-scenes things the
293 compiler needs to do with by-reference variables in Blocks.
294
295 However, as far as the original *programmer* is concerned, the variable
296 should still have type 'SomeType', as originally declared.
297
298 The function getBlockByrefType dives into the __Block_byref_x_VarName
299 struct to find the original type of the variable, which is then assigned to
300 the variable's Debug Information Entry as its real type. So far, so good.
301 However now the debugger will expect the variable VarName to have the type
302 SomeType. So we need the location attribute for the variable to be an
303 expression that explains to the debugger how to navigate through the
304 pointers and struct to find the actual variable of type SomeType.
305
306 The following function does just that. We start by getting
307 the "normal" location for the variable. This will be the location
308 of either the struct __Block_byref_x_VarName or the pointer to the
309 struct __Block_byref_x_VarName.
310
311 The struct will look something like:
312
313 struct __Block_byref_x_VarName {
314 ... <various fields>
315 struct __Block_byref_x_VarName *forwarding;
316 ... <various other fields>
317 SomeType VarName;
318 ... <maybe more fields>
319 };
320
321 If we are given the struct directly (as our starting point) we
322 need to tell the debugger to:
323
324 1). Add the offset of the forwarding field.
325
326 2). Follow that pointer to get the real __Block_byref_x_VarName
327 struct to use (the real one may have been copied onto the heap).
328
329 3). Add the offset for the field VarName, to find the actual variable.
330
331 If we started with a pointer to the struct, then we need to
332 dereference that pointer first, before the other steps.
333 Translating this into DWARF ops, we will need to append the following
334 to the current location description for the variable:
335
336 DW_OP_deref -- optional, if we start with a pointer
337 DW_OP_plus_uconst <forward_fld_offset>
338 DW_OP_deref
339 DW_OP_plus_uconst <varName_fld_offset>
340
341 That is what this function does. */
342
343/// addBlockByrefAddress - Start with the address based on the location
344/// provided, and generate the DWARF information necessary to find the
345/// actual Block variable (navigating the Block struct) based on the
346/// starting location. Add the DWARF information to the die. For
347/// more information, read large comment just above here.
348///
349void CompileUnit::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
350 unsigned Attribute,
351 const MachineLocation &Location) {
352 DIType Ty = DV->getType();
353 DIType TmpTy = Ty;
354 unsigned Tag = Ty.getTag();
355 bool isPointer = false;
356
357 StringRef varName = DV->getName();
358
359 if (Tag == dwarf::DW_TAG_pointer_type) {
360 DIDerivedType DTy = DIDerivedType(Ty);
361 TmpTy = DTy.getTypeDerivedFrom();
362 isPointer = true;
363 }
364
365 DICompositeType blockStruct = DICompositeType(TmpTy);
366
367 // Find the __forwarding field and the variable field in the __Block_byref
368 // struct.
369 DIArray Fields = blockStruct.getTypeArray();
370 DIDescriptor varField = DIDescriptor();
371 DIDescriptor forwardingField = DIDescriptor();
372
373 for (unsigned i = 0, N = Fields.getNumElements(); i < N; ++i) {
374 DIDescriptor Element = Fields.getElement(i);
375 DIDerivedType DT = DIDerivedType(Element);
376 StringRef fieldName = DT.getName();
377 if (fieldName == "__forwarding")
378 forwardingField = Element;
379 else if (fieldName == varName)
380 varField = Element;
381 }
382
383 // Get the offsets for the forwarding field and the variable field.
384 unsigned forwardingFieldOffset =
385 DIDerivedType(forwardingField).getOffsetInBits() >> 3;
386 unsigned varFieldOffset =
387 DIDerivedType(varField).getOffsetInBits() >> 3;
388
389 // Decode the original location, and use that as the start of the byref
390 // variable's location.
391 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
392 unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
393 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
394
395 if (Location.isReg()) {
396 if (Reg < 32)
397 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
398 else {
399 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx);
400 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
401 }
402 } else {
403 if (Reg < 32)
404 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
405 else {
406 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
407 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
408 }
409
410 addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
411 }
412
413 // If we started with a pointer to the __Block_byref... struct, then
414 // the first thing we need to do is dereference the pointer (DW_OP_deref).
415 if (isPointer)
416 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
417
418 // Next add the offset for the '__forwarding' field:
419 // DW_OP_plus_uconst ForwardingFieldOffset. Note there's no point in
420 // adding the offset if it's 0.
421 if (forwardingFieldOffset > 0) {
422 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
423 addUInt(Block, 0, dwarf::DW_FORM_udata, forwardingFieldOffset);
424 }
425
426 // Now dereference the __forwarding field to get to the real __Block_byref
427 // struct: DW_OP_deref.
428 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
429
430 // Now that we've got the real __Block_byref... struct, add the offset
431 // for the variable's field to get to the location of the actual variable:
432 // DW_OP_plus_uconst varFieldOffset. Again, don't add if it's 0.
433 if (varFieldOffset > 0) {
434 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
435 addUInt(Block, 0, dwarf::DW_FORM_udata, varFieldOffset);
436 }
437
438 // Now attach the location information to the DIE.
439 addBlock(Die, Attribute, 0, Block);
440}
441
Devang Patel4ec14b02011-07-20 21:57:04 +0000442/// isTypeSigned - Return true if the type is signed.
443static bool isTypeSigned(DIType Ty, int *SizeInBits) {
444 if (Ty.isDerivedType())
445 return isTypeSigned(DIDerivedType(Ty).getTypeDerivedFrom(), SizeInBits);
446 if (Ty.isBasicType())
447 if (DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed
448 || DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed_char) {
449 *SizeInBits = Ty.getSizeInBits();
450 return true;
451 }
452 return false;
453}
454
Devang Patel161b2f42011-04-12 23:21:44 +0000455/// addConstantValue - Add constant value entry in variable DIE.
Devang Patelb58128e2011-05-27 16:45:18 +0000456bool CompileUnit::addConstantValue(DIE *Die, const MachineOperand &MO,
457 DIType Ty) {
Devang Patel161b2f42011-04-12 23:21:44 +0000458 assert (MO.isImm() && "Invalid machine operand!");
459 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel4ec14b02011-07-20 21:57:04 +0000460 int SizeInBits = -1;
461 bool SignedConstant = isTypeSigned(Ty, &SizeInBits);
462 unsigned Form = SignedConstant ? dwarf::DW_FORM_sdata : dwarf::DW_FORM_udata;
463 switch (SizeInBits) {
464 case 8: Form = dwarf::DW_FORM_data1; break;
465 case 16: Form = dwarf::DW_FORM_data2; break;
466 case 32: Form = dwarf::DW_FORM_data4; break;
467 case 64: Form = dwarf::DW_FORM_data8; break;
Devang Patel045c1d42011-05-27 19:13:26 +0000468 default: break;
469 }
Devang Patel4ec14b02011-07-20 21:57:04 +0000470 SignedConstant ? addSInt(Block, 0, Form, MO.getImm())
471 : addUInt(Block, 0, Form, MO.getImm());
Devang Patel72f0d9c2011-05-27 18:15:52 +0000472
Devang Patel161b2f42011-04-12 23:21:44 +0000473 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
474 return true;
475}
476
477/// addConstantFPValue - Add constant value entry in variable DIE.
478bool CompileUnit::addConstantFPValue(DIE *Die, const MachineOperand &MO) {
479 assert (MO.isFPImm() && "Invalid machine operand!");
480 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
481 APFloat FPImm = MO.getFPImm()->getValueAPF();
482
483 // Get the raw data form of the floating point.
484 const APInt FltVal = FPImm.bitcastToAPInt();
485 const char *FltPtr = (const char*)FltVal.getRawData();
486
487 int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte.
488 bool LittleEndian = Asm->getTargetData().isLittleEndian();
489 int Incr = (LittleEndian ? 1 : -1);
490 int Start = (LittleEndian ? 0 : NumBytes - 1);
491 int Stop = (LittleEndian ? NumBytes : -1);
492
493 // Output the constant to DWARF one byte at a time.
494 for (; Start != Stop; Start += Incr)
495 addUInt(Block, 0, dwarf::DW_FORM_data1,
496 (unsigned char)0xFF & FltPtr[Start]);
497
498 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
499 return true;
500}
501
502/// addConstantValue - Add constant value entry in variable DIE.
Devang Patel8594d422011-06-24 20:46:11 +0000503bool CompileUnit::addConstantValue(DIE *Die, const ConstantInt *CI,
Devang Patel161b2f42011-04-12 23:21:44 +0000504 bool Unsigned) {
Devang Pateld6a81362011-05-28 00:39:18 +0000505 unsigned CIBitWidth = CI->getBitWidth();
506 if (CIBitWidth <= 64) {
507 unsigned form = 0;
508 switch (CIBitWidth) {
509 case 8: form = dwarf::DW_FORM_data1; break;
510 case 16: form = dwarf::DW_FORM_data2; break;
511 case 32: form = dwarf::DW_FORM_data4; break;
512 case 64: form = dwarf::DW_FORM_data8; break;
513 default:
514 form = Unsigned ? dwarf::DW_FORM_udata : dwarf::DW_FORM_sdata;
515 }
Devang Patel161b2f42011-04-12 23:21:44 +0000516 if (Unsigned)
Devang Pateld6a81362011-05-28 00:39:18 +0000517 addUInt(Die, dwarf::DW_AT_const_value, form, CI->getZExtValue());
Devang Patel161b2f42011-04-12 23:21:44 +0000518 else
Devang Pateld6a81362011-05-28 00:39:18 +0000519 addSInt(Die, dwarf::DW_AT_const_value, form, CI->getSExtValue());
Devang Patel161b2f42011-04-12 23:21:44 +0000520 return true;
521 }
522
523 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
524
525 // Get the raw data form of the large APInt.
526 const APInt Val = CI->getValue();
527 const char *Ptr = (const char*)Val.getRawData();
528
529 int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte.
530 bool LittleEndian = Asm->getTargetData().isLittleEndian();
531 int Incr = (LittleEndian ? 1 : -1);
532 int Start = (LittleEndian ? 0 : NumBytes - 1);
533 int Stop = (LittleEndian ? NumBytes : -1);
534
535 // Output the constant to DWARF one byte at a time.
536 for (; Start != Stop; Start += Incr)
537 addUInt(Block, 0, dwarf::DW_FORM_data1,
538 (unsigned char)0xFF & Ptr[Start]);
539
540 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
541 return true;
542}
543
544/// addTemplateParams - Add template parameters in buffer.
545void CompileUnit::addTemplateParams(DIE &Buffer, DIArray TParams) {
546 // Add template parameters.
547 for (unsigned i = 0, e = TParams.getNumElements(); i != e; ++i) {
548 DIDescriptor Element = TParams.getElement(i);
549 if (Element.isTemplateTypeParameter())
550 Buffer.addChild(getOrCreateTemplateTypeParameterDIE(
551 DITemplateTypeParameter(Element)));
552 else if (Element.isTemplateValueParameter())
553 Buffer.addChild(getOrCreateTemplateValueParameterDIE(
554 DITemplateValueParameter(Element)));
555 }
556
557}
558/// addToContextOwner - Add Die into the list of its context owner's children.
559void CompileUnit::addToContextOwner(DIE *Die, DIDescriptor Context) {
560 if (Context.isType()) {
561 DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context));
562 ContextDIE->addChild(Die);
563 } else if (Context.isNameSpace()) {
564 DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context));
565 ContextDIE->addChild(Die);
566 } else if (Context.isSubprogram()) {
567 DIE *ContextDIE = DD->createSubprogramDIE(DISubprogram(Context));
568 ContextDIE->addChild(Die);
569 } else if (DIE *ContextDIE = getDIE(Context))
570 ContextDIE->addChild(Die);
571 else
572 addDie(Die);
573}
574
575/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
576/// given DIType.
577DIE *CompileUnit::getOrCreateTypeDIE(DIType Ty) {
578 DIE *TyDIE = getDIE(Ty);
579 if (TyDIE)
580 return TyDIE;
581
582 // Create new type.
583 TyDIE = new DIE(dwarf::DW_TAG_base_type);
584 insertDIE(Ty, TyDIE);
585 if (Ty.isBasicType())
586 constructTypeDIE(*TyDIE, DIBasicType(Ty));
587 else if (Ty.isCompositeType())
588 constructTypeDIE(*TyDIE, DICompositeType(Ty));
589 else {
590 assert(Ty.isDerivedType() && "Unknown kind of DIType");
591 constructTypeDIE(*TyDIE, DIDerivedType(Ty));
592 }
593
594 addToContextOwner(TyDIE, Ty.getContext());
595 return TyDIE;
596}
597
598/// addType - Add a new type attribute to the specified entity.
599void CompileUnit::addType(DIE *Entity, DIType Ty) {
600 if (!Ty.Verify())
601 return;
602
603 // Check for pre-existence.
604 DIEEntry *Entry = getDIEEntry(Ty);
605 // If it exists then use the existing value.
606 if (Entry) {
607 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
608 return;
609 }
610
611 // Construct type.
612 DIE *Buffer = getOrCreateTypeDIE(Ty);
613
614 // Set up proxy.
615 Entry = createDIEEntry(Buffer);
616 insertDIEEntry(Ty, Entry);
Devang Patel161b2f42011-04-12 23:21:44 +0000617 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
Devang Patele9ae06c2011-05-31 22:56:51 +0000618
619 // If this is a complete composite type then include it in the
620 // list of global types.
Devang Patelc20bdf12011-06-01 00:23:24 +0000621 addGlobalType(Ty);
Devang Patel66658e42011-05-31 23:30:30 +0000622}
623
624/// addGlobalType - Add a new global type to the compile unit.
625///
Devang Patelc20bdf12011-06-01 00:23:24 +0000626void CompileUnit::addGlobalType(DIType Ty) {
Devang Patele9ae06c2011-05-31 22:56:51 +0000627 DIDescriptor Context = Ty.getContext();
628 if (Ty.isCompositeType() && !Ty.getName().empty() && !Ty.isForwardDecl()
629 && (Context.isCompileUnit() || Context.isFile() || Context.isNameSpace()))
Devang Patelc20bdf12011-06-01 00:23:24 +0000630 if (DIEEntry *Entry = getDIEEntry(Ty))
631 GlobalTypes[Ty.getName()] = Entry->getEntry();
Devang Patel161b2f42011-04-12 23:21:44 +0000632}
633
Devang Patel31c5d052011-05-06 16:57:54 +0000634/// addPubTypes - Add type for pubtypes section.
635void CompileUnit::addPubTypes(DISubprogram SP) {
636 DICompositeType SPTy = SP.getType();
637 unsigned SPTag = SPTy.getTag();
638 if (SPTag != dwarf::DW_TAG_subroutine_type)
639 return;
640
641 DIArray Args = SPTy.getTypeArray();
642 for (unsigned i = 0, e = Args.getNumElements(); i != e; ++i) {
643 DIType ATy(Args.getElement(i));
644 if (!ATy.Verify())
645 continue;
Devang Patelc20bdf12011-06-01 00:23:24 +0000646 addGlobalType(ATy);
Devang Patel31c5d052011-05-06 16:57:54 +0000647 }
648}
649
Devang Patel161b2f42011-04-12 23:21:44 +0000650/// constructTypeDIE - Construct basic type die from DIBasicType.
651void CompileUnit::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
652 // Get core information.
653 StringRef Name = BTy.getName();
654 Buffer.setTag(dwarf::DW_TAG_base_type);
655 addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
656 BTy.getEncoding());
657
658 // Add name if not anonymous or intermediate type.
659 if (!Name.empty())
660 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
661 uint64_t Size = BTy.getSizeInBits() >> 3;
662 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
663}
664
665/// constructTypeDIE - Construct derived type die from DIDerivedType.
666void CompileUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
667 // Get core information.
668 StringRef Name = DTy.getName();
669 uint64_t Size = DTy.getSizeInBits() >> 3;
670 unsigned Tag = DTy.getTag();
671
672 // FIXME - Workaround for templates.
673 if (Tag == dwarf::DW_TAG_inheritance) Tag = dwarf::DW_TAG_reference_type;
674
675 Buffer.setTag(Tag);
676
677 // Map to main type, void will not have a type.
678 DIType FromTy = DTy.getTypeDerivedFrom();
679 addType(&Buffer, FromTy);
680
681 // Add name if not anonymous or intermediate type.
682 if (!Name.empty())
683 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
684
685 // Add size if non-zero (derived types might be zero-sized.)
686 if (Size)
687 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
688
689 // Add source line info if available and TyDesc is not a forward declaration.
690 if (!DTy.isForwardDecl())
691 addSourceLine(&Buffer, DTy);
692}
693
694/// constructTypeDIE - Construct type DIE from DICompositeType.
695void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
696 // Get core information.
697 StringRef Name = CTy.getName();
698
699 uint64_t Size = CTy.getSizeInBits() >> 3;
700 unsigned Tag = CTy.getTag();
701 Buffer.setTag(Tag);
702
703 switch (Tag) {
704 case dwarf::DW_TAG_vector_type:
705 case dwarf::DW_TAG_array_type:
706 constructArrayTypeDIE(Buffer, &CTy);
707 break;
708 case dwarf::DW_TAG_enumeration_type: {
709 DIArray Elements = CTy.getTypeArray();
710
711 // Add enumerators to enumeration type.
712 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
713 DIE *ElemDie = NULL;
714 DIDescriptor Enum(Elements.getElement(i));
715 if (Enum.isEnumerator()) {
716 ElemDie = constructEnumTypeDIE(DIEnumerator(Enum));
717 Buffer.addChild(ElemDie);
718 }
719 }
720 }
721 break;
722 case dwarf::DW_TAG_subroutine_type: {
723 // Add return type.
724 DIArray Elements = CTy.getTypeArray();
725 DIDescriptor RTy = Elements.getElement(0);
726 addType(&Buffer, DIType(RTy));
727
728 bool isPrototyped = true;
729 // Add arguments.
730 for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
731 DIDescriptor Ty = Elements.getElement(i);
732 if (Ty.isUnspecifiedParameter()) {
733 DIE *Arg = new DIE(dwarf::DW_TAG_unspecified_parameters);
734 Buffer.addChild(Arg);
735 isPrototyped = false;
736 } else {
737 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
738 addType(Arg, DIType(Ty));
739 Buffer.addChild(Arg);
740 }
741 }
742 // Add prototype flag.
743 if (isPrototyped)
744 addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
745 }
746 break;
747 case dwarf::DW_TAG_structure_type:
748 case dwarf::DW_TAG_union_type:
749 case dwarf::DW_TAG_class_type: {
750 // Add elements to structure type.
751 DIArray Elements = CTy.getTypeArray();
752
753 // A forward struct declared type may not have elements available.
754 unsigned N = Elements.getNumElements();
755 if (N == 0)
756 break;
757
758 // Add elements to structure type.
759 for (unsigned i = 0; i < N; ++i) {
760 DIDescriptor Element = Elements.getElement(i);
761 DIE *ElemDie = NULL;
762 if (Element.isSubprogram()) {
763 DISubprogram SP(Element);
764 ElemDie = DD->createSubprogramDIE(DISubprogram(Element));
765 if (SP.isProtected())
766 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
767 dwarf::DW_ACCESS_protected);
768 else if (SP.isPrivate())
769 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
770 dwarf::DW_ACCESS_private);
771 else
772 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
773 dwarf::DW_ACCESS_public);
774 if (SP.isExplicit())
775 addUInt(ElemDie, dwarf::DW_AT_explicit, dwarf::DW_FORM_flag, 1);
776 }
777 else if (Element.isVariable()) {
778 DIVariable DV(Element);
779 ElemDie = new DIE(dwarf::DW_TAG_variable);
780 addString(ElemDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,
781 DV.getName());
782 addType(ElemDie, DV.getType());
783 addUInt(ElemDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
784 addUInt(ElemDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
785 addSourceLine(ElemDie, DV);
786 } else if (Element.isDerivedType())
787 ElemDie = createMemberDIE(DIDerivedType(Element));
788 else
789 continue;
790 Buffer.addChild(ElemDie);
791 }
792
793 if (CTy.isAppleBlockExtension())
794 addUInt(&Buffer, dwarf::DW_AT_APPLE_block, dwarf::DW_FORM_flag, 1);
795
796 unsigned RLang = CTy.getRunTimeLang();
797 if (RLang)
798 addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class,
799 dwarf::DW_FORM_data1, RLang);
800
801 DICompositeType ContainingType = CTy.getContainingType();
802 if (DIDescriptor(ContainingType).isCompositeType())
803 addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
804 getOrCreateTypeDIE(DIType(ContainingType)));
805 else {
806 DIDescriptor Context = CTy.getContext();
807 addToContextOwner(&Buffer, Context);
808 }
809
Devang Patel201e6cd2011-05-12 21:29:42 +0000810 if (CTy.isObjcClassComplete())
811 addUInt(&Buffer, dwarf::DW_AT_APPLE_objc_complete_type,
Devang Patelb11f80e2011-05-12 19:06:16 +0000812 dwarf::DW_FORM_flag, 1);
813
Devang Patel161b2f42011-04-12 23:21:44 +0000814 if (Tag == dwarf::DW_TAG_class_type)
815 addTemplateParams(Buffer, CTy.getTemplateParams());
816
817 break;
818 }
819 default:
820 break;
821 }
822
823 // Add name if not anonymous or intermediate type.
824 if (!Name.empty())
825 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
826
827 if (Tag == dwarf::DW_TAG_enumeration_type || Tag == dwarf::DW_TAG_class_type
828 || Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type)
829 {
830 // Add size if non-zero (derived types might be zero-sized.)
831 if (Size)
832 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
833 else {
834 // Add zero size if it is not a forward declaration.
835 if (CTy.isForwardDecl())
836 addUInt(&Buffer, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
837 else
838 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, 0);
839 }
840
841 // Add source line info if available.
842 if (!CTy.isForwardDecl())
843 addSourceLine(&Buffer, CTy);
844 }
845}
846
847/// getOrCreateTemplateTypeParameterDIE - Find existing DIE or create new DIE
848/// for the given DITemplateTypeParameter.
849DIE *
850CompileUnit::getOrCreateTemplateTypeParameterDIE(DITemplateTypeParameter TP) {
851 DIE *ParamDIE = getDIE(TP);
852 if (ParamDIE)
853 return ParamDIE;
854
855 ParamDIE = new DIE(dwarf::DW_TAG_template_type_parameter);
856 addType(ParamDIE, TP.getType());
857 addString(ParamDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string, TP.getName());
858 return ParamDIE;
859}
860
861/// getOrCreateTemplateValueParameterDIE - Find existing DIE or create new DIE
862/// for the given DITemplateValueParameter.
863DIE *
864CompileUnit::getOrCreateTemplateValueParameterDIE(DITemplateValueParameter TPV) {
865 DIE *ParamDIE = getDIE(TPV);
866 if (ParamDIE)
867 return ParamDIE;
868
869 ParamDIE = new DIE(dwarf::DW_TAG_template_value_parameter);
870 addType(ParamDIE, TPV.getType());
871 if (!TPV.getName().empty())
872 addString(ParamDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string, TPV.getName());
873 addUInt(ParamDIE, dwarf::DW_AT_const_value, dwarf::DW_FORM_udata,
874 TPV.getValue());
875 return ParamDIE;
876}
877
Devang Patel31c5d052011-05-06 16:57:54 +0000878/// getOrCreateNameSpace - Create a DIE for DINameSpace.
879DIE *CompileUnit::getOrCreateNameSpace(DINameSpace NS) {
880 DIE *NDie = getDIE(NS);
881 if (NDie)
882 return NDie;
883 NDie = new DIE(dwarf::DW_TAG_namespace);
884 insertDIE(NS, NDie);
885 if (!NS.getName().empty())
886 addString(NDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, NS.getName());
887 addSourceLine(NDie, NS);
888 addToContextOwner(NDie, NS.getContext());
889 return NDie;
890}
891
Devang Patel161b2f42011-04-12 23:21:44 +0000892/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
893void CompileUnit::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){
894 DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type);
895 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IndexTy);
896 int64_t L = SR.getLo();
897 int64_t H = SR.getHi();
898
899 // The L value defines the lower bounds which is typically zero for C/C++. The
900 // H value is the upper bounds. Values are 64 bit. H - L + 1 is the size
901 // of the array. If L > H then do not emit DW_AT_lower_bound and
902 // DW_AT_upper_bound attributes. If L is zero and H is also zero then the
903 // array has one element and in such case do not emit lower bound.
904
905 if (L > H) {
906 Buffer.addChild(DW_Subrange);
907 return;
908 }
909 if (L)
910 addSInt(DW_Subrange, dwarf::DW_AT_lower_bound, 0, L);
911 addSInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, H);
912 Buffer.addChild(DW_Subrange);
913}
914
915/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
916void CompileUnit::constructArrayTypeDIE(DIE &Buffer,
917 DICompositeType *CTy) {
918 Buffer.setTag(dwarf::DW_TAG_array_type);
919 if (CTy->getTag() == dwarf::DW_TAG_vector_type)
920 addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1);
921
922 // Emit derived type.
923 addType(&Buffer, CTy->getTypeDerivedFrom());
924 DIArray Elements = CTy->getTypeArray();
925
926 // Get an anonymous type for index type.
927 DIE *IdxTy = getIndexTyDie();
928 if (!IdxTy) {
929 // Construct an anonymous type for index type.
930 IdxTy = new DIE(dwarf::DW_TAG_base_type);
931 addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t));
932 addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
933 dwarf::DW_ATE_signed);
934 addDie(IdxTy);
935 setIndexTyDie(IdxTy);
936 }
937
938 // Add subranges to array type.
939 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
940 DIDescriptor Element = Elements.getElement(i);
941 if (Element.getTag() == dwarf::DW_TAG_subrange_type)
942 constructSubrangeDIE(Buffer, DISubrange(Element), IdxTy);
943 }
944}
945
946/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
947DIE *CompileUnit::constructEnumTypeDIE(DIEnumerator ETy) {
948 DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator);
949 StringRef Name = ETy.getName();
950 addString(Enumerator, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
951 int64_t Value = ETy.getEnumValue();
952 addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value);
953 return Enumerator;
954}
955
956/// createMemberDIE - Create new member DIE.
957DIE *CompileUnit::createMemberDIE(DIDerivedType DT) {
958 DIE *MemberDie = new DIE(DT.getTag());
959 StringRef Name = DT.getName();
960 if (!Name.empty())
961 addString(MemberDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
962
963 addType(MemberDie, DT.getTypeDerivedFrom());
964
965 addSourceLine(MemberDie, DT);
966
967 DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
968 addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
969
970 uint64_t Size = DT.getSizeInBits();
971 uint64_t FieldSize = DT.getOriginalTypeSize();
972
973 if (Size != FieldSize) {
974 // Handle bitfield.
975 addUInt(MemberDie, dwarf::DW_AT_byte_size, 0, DT.getOriginalTypeSize()>>3);
976 addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits());
977
978 uint64_t Offset = DT.getOffsetInBits();
979 uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
980 uint64_t HiMark = (Offset + FieldSize) & AlignMask;
981 uint64_t FieldOffset = (HiMark - FieldSize);
982 Offset -= FieldOffset;
983
984 // Maybe we need to work from the other end.
985 if (Asm->getTargetData().isLittleEndian())
986 Offset = FieldSize - (Offset + Size);
987 addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
988
989 // Here WD_AT_data_member_location points to the anonymous
990 // field that includes this bit field.
991 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, FieldOffset >> 3);
992
993 } else
994 // This is not a bitfield.
995 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);
996
997 if (DT.getTag() == dwarf::DW_TAG_inheritance
998 && DT.isVirtual()) {
999
1000 // For C++, virtual base classes are not at fixed offset. Use following
1001 // expression to extract appropriate offset from vtable.
1002 // BaseAddr = ObAddr + *((*ObAddr) - Offset)
1003
1004 DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock();
1005 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
1006 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1007 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1008 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits());
1009 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
1010 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1011 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1012
1013 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0,
1014 VBaseLocationDie);
1015 } else
1016 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
1017
1018 if (DT.isProtected())
1019 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1020 dwarf::DW_ACCESS_protected);
1021 else if (DT.isPrivate())
1022 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1023 dwarf::DW_ACCESS_private);
1024 // Otherwise C++ member and base classes are considered public.
1025 else if (DT.getCompileUnit().getLanguage() == dwarf::DW_LANG_C_plus_plus)
1026 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1027 dwarf::DW_ACCESS_public);
1028 if (DT.isVirtual())
1029 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag,
1030 dwarf::DW_VIRTUALITY_virtual);
Devang Patele9db5e22011-04-16 00:11:51 +00001031
1032 // Objective-C properties.
1033 StringRef PropertyName = DT.getObjCPropertyName();
1034 if (!PropertyName.empty()) {
1035 addString(MemberDie, dwarf::DW_AT_APPLE_property_name, dwarf::DW_FORM_string,
1036 PropertyName);
1037 StringRef GetterName = DT.getObjCPropertyGetterName();
1038 if (!GetterName.empty())
1039 addString(MemberDie, dwarf::DW_AT_APPLE_property_getter,
1040 dwarf::DW_FORM_string, GetterName);
1041 StringRef SetterName = DT.getObjCPropertySetterName();
1042 if (!SetterName.empty())
1043 addString(MemberDie, dwarf::DW_AT_APPLE_property_setter,
1044 dwarf::DW_FORM_string, SetterName);
1045 unsigned PropertyAttributes = 0;
1046 if (DT.isReadOnlyObjCProperty())
1047 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readonly;
1048 if (DT.isReadWriteObjCProperty())
1049 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readwrite;
1050 if (DT.isAssignObjCProperty())
1051 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_assign;
1052 if (DT.isRetainObjCProperty())
1053 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_retain;
1054 if (DT.isCopyObjCProperty())
1055 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_copy;
1056 if (DT.isNonAtomicObjCProperty())
1057 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_nonatomic;
1058 if (PropertyAttributes)
1059 addUInt(MemberDie, dwarf::DW_AT_APPLE_property_attribute, 0,
1060 PropertyAttributes);
1061 }
Devang Patel161b2f42011-04-12 23:21:44 +00001062 return MemberDie;
1063}