blob: f128308fb6df8c645390de546c7d46bf8cf0d696 [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 Patel161b2f42011-04-12 23:21:44 +0000442/// addConstantValue - Add constant value entry in variable DIE.
Devang Patelb58128e2011-05-27 16:45:18 +0000443bool CompileUnit::addConstantValue(DIE *Die, const MachineOperand &MO,
444 DIType Ty) {
Devang Patel161b2f42011-04-12 23:21:44 +0000445 assert (MO.isImm() && "Invalid machine operand!");
446 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patelb58128e2011-05-27 16:45:18 +0000447 unsigned form = dwarf::DW_FORM_udata;
Devang Patel045c1d42011-05-27 19:13:26 +0000448 switch (Ty.getSizeInBits()) {
449 case 8: form = dwarf::DW_FORM_data1; break;
450 case 16: form = dwarf::DW_FORM_data2; break;
451 case 32: form = dwarf::DW_FORM_data4; break;
452 case 64: form = dwarf::DW_FORM_data8; break;
453 default: break;
454 }
455
Devang Patel72f0d9c2011-05-27 18:15:52 +0000456 DIBasicType BTy(Ty);
Devang Patel045c1d42011-05-27 19:13:26 +0000457 if (BTy.Verify() &&
458 (BTy.getEncoding() == dwarf::DW_ATE_signed
459 || BTy.getEncoding() == dwarf::DW_ATE_signed_char))
460 addSInt(Block, 0, form, MO.getImm());
461 else
Devang Patel72f0d9c2011-05-27 18:15:52 +0000462 addUInt(Block, 0, form, MO.getImm());
463
Devang Patel161b2f42011-04-12 23:21:44 +0000464 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
465 return true;
466}
467
468/// addConstantFPValue - Add constant value entry in variable DIE.
469bool CompileUnit::addConstantFPValue(DIE *Die, const MachineOperand &MO) {
470 assert (MO.isFPImm() && "Invalid machine operand!");
471 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
472 APFloat FPImm = MO.getFPImm()->getValueAPF();
473
474 // Get the raw data form of the floating point.
475 const APInt FltVal = FPImm.bitcastToAPInt();
476 const char *FltPtr = (const char*)FltVal.getRawData();
477
478 int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte.
479 bool LittleEndian = Asm->getTargetData().isLittleEndian();
480 int Incr = (LittleEndian ? 1 : -1);
481 int Start = (LittleEndian ? 0 : NumBytes - 1);
482 int Stop = (LittleEndian ? NumBytes : -1);
483
484 // Output the constant to DWARF one byte at a time.
485 for (; Start != Stop; Start += Incr)
486 addUInt(Block, 0, dwarf::DW_FORM_data1,
487 (unsigned char)0xFF & FltPtr[Start]);
488
489 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
490 return true;
491}
492
493/// addConstantValue - Add constant value entry in variable DIE.
494bool CompileUnit::addConstantValue(DIE *Die, ConstantInt *CI,
495 bool Unsigned) {
Devang Pateld6a81362011-05-28 00:39:18 +0000496 unsigned CIBitWidth = CI->getBitWidth();
497 if (CIBitWidth <= 64) {
498 unsigned form = 0;
499 switch (CIBitWidth) {
500 case 8: form = dwarf::DW_FORM_data1; break;
501 case 16: form = dwarf::DW_FORM_data2; break;
502 case 32: form = dwarf::DW_FORM_data4; break;
503 case 64: form = dwarf::DW_FORM_data8; break;
504 default:
505 form = Unsigned ? dwarf::DW_FORM_udata : dwarf::DW_FORM_sdata;
506 }
Devang Patel161b2f42011-04-12 23:21:44 +0000507 if (Unsigned)
Devang Pateld6a81362011-05-28 00:39:18 +0000508 addUInt(Die, dwarf::DW_AT_const_value, form, CI->getZExtValue());
Devang Patel161b2f42011-04-12 23:21:44 +0000509 else
Devang Pateld6a81362011-05-28 00:39:18 +0000510 addSInt(Die, dwarf::DW_AT_const_value, form, CI->getSExtValue());
Devang Patel161b2f42011-04-12 23:21:44 +0000511 return true;
512 }
513
514 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
515
516 // Get the raw data form of the large APInt.
517 const APInt Val = CI->getValue();
518 const char *Ptr = (const char*)Val.getRawData();
519
520 int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte.
521 bool LittleEndian = Asm->getTargetData().isLittleEndian();
522 int Incr = (LittleEndian ? 1 : -1);
523 int Start = (LittleEndian ? 0 : NumBytes - 1);
524 int Stop = (LittleEndian ? NumBytes : -1);
525
526 // Output the constant to DWARF one byte at a time.
527 for (; Start != Stop; Start += Incr)
528 addUInt(Block, 0, dwarf::DW_FORM_data1,
529 (unsigned char)0xFF & Ptr[Start]);
530
531 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
532 return true;
533}
534
535/// addTemplateParams - Add template parameters in buffer.
536void CompileUnit::addTemplateParams(DIE &Buffer, DIArray TParams) {
537 // Add template parameters.
538 for (unsigned i = 0, e = TParams.getNumElements(); i != e; ++i) {
539 DIDescriptor Element = TParams.getElement(i);
540 if (Element.isTemplateTypeParameter())
541 Buffer.addChild(getOrCreateTemplateTypeParameterDIE(
542 DITemplateTypeParameter(Element)));
543 else if (Element.isTemplateValueParameter())
544 Buffer.addChild(getOrCreateTemplateValueParameterDIE(
545 DITemplateValueParameter(Element)));
546 }
547
548}
549/// addToContextOwner - Add Die into the list of its context owner's children.
550void CompileUnit::addToContextOwner(DIE *Die, DIDescriptor Context) {
551 if (Context.isType()) {
552 DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context));
553 ContextDIE->addChild(Die);
554 } else if (Context.isNameSpace()) {
555 DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context));
556 ContextDIE->addChild(Die);
557 } else if (Context.isSubprogram()) {
558 DIE *ContextDIE = DD->createSubprogramDIE(DISubprogram(Context));
559 ContextDIE->addChild(Die);
560 } else if (DIE *ContextDIE = getDIE(Context))
561 ContextDIE->addChild(Die);
562 else
563 addDie(Die);
564}
565
566/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
567/// given DIType.
568DIE *CompileUnit::getOrCreateTypeDIE(DIType Ty) {
569 DIE *TyDIE = getDIE(Ty);
570 if (TyDIE)
571 return TyDIE;
572
573 // Create new type.
574 TyDIE = new DIE(dwarf::DW_TAG_base_type);
575 insertDIE(Ty, TyDIE);
576 if (Ty.isBasicType())
577 constructTypeDIE(*TyDIE, DIBasicType(Ty));
578 else if (Ty.isCompositeType())
579 constructTypeDIE(*TyDIE, DICompositeType(Ty));
580 else {
581 assert(Ty.isDerivedType() && "Unknown kind of DIType");
582 constructTypeDIE(*TyDIE, DIDerivedType(Ty));
583 }
584
585 addToContextOwner(TyDIE, Ty.getContext());
586 return TyDIE;
587}
588
589/// addType - Add a new type attribute to the specified entity.
590void CompileUnit::addType(DIE *Entity, DIType Ty) {
591 if (!Ty.Verify())
592 return;
593
594 // Check for pre-existence.
595 DIEEntry *Entry = getDIEEntry(Ty);
596 // If it exists then use the existing value.
597 if (Entry) {
598 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
599 return;
600 }
601
602 // Construct type.
603 DIE *Buffer = getOrCreateTypeDIE(Ty);
604
605 // Set up proxy.
606 Entry = createDIEEntry(Buffer);
607 insertDIEEntry(Ty, Entry);
Devang Patel161b2f42011-04-12 23:21:44 +0000608 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
Devang Patele9ae06c2011-05-31 22:56:51 +0000609
610 // If this is a complete composite type then include it in the
611 // list of global types.
Devang Patel66658e42011-05-31 23:30:30 +0000612 addGlobalType(Ty, Entry->getEntry());
613}
614
615/// addGlobalType - Add a new global type to the compile unit.
616///
617void CompileUnit::addGlobalType(DIType Ty, DIE *Die) {
Devang Patele9ae06c2011-05-31 22:56:51 +0000618 DIDescriptor Context = Ty.getContext();
619 if (Ty.isCompositeType() && !Ty.getName().empty() && !Ty.isForwardDecl()
620 && (Context.isCompileUnit() || Context.isFile() || Context.isNameSpace()))
Devang Patel66658e42011-05-31 23:30:30 +0000621 GlobalTypes[Ty.getName()] = Die;
Devang Patel161b2f42011-04-12 23:21:44 +0000622}
623
Devang Patel31c5d052011-05-06 16:57:54 +0000624/// addPubTypes - Add type for pubtypes section.
625void CompileUnit::addPubTypes(DISubprogram SP) {
626 DICompositeType SPTy = SP.getType();
627 unsigned SPTag = SPTy.getTag();
628 if (SPTag != dwarf::DW_TAG_subroutine_type)
629 return;
630
631 DIArray Args = SPTy.getTypeArray();
632 for (unsigned i = 0, e = Args.getNumElements(); i != e; ++i) {
633 DIType ATy(Args.getElement(i));
634 if (!ATy.Verify())
635 continue;
Devang Patel66658e42011-05-31 23:30:30 +0000636 addGlobalType(ATy, getDIEEntry(ATy)->getEntry());
Devang Patel31c5d052011-05-06 16:57:54 +0000637 }
638}
639
Devang Patel161b2f42011-04-12 23:21:44 +0000640/// constructTypeDIE - Construct basic type die from DIBasicType.
641void CompileUnit::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
642 // Get core information.
643 StringRef Name = BTy.getName();
644 Buffer.setTag(dwarf::DW_TAG_base_type);
645 addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
646 BTy.getEncoding());
647
648 // Add name if not anonymous or intermediate type.
649 if (!Name.empty())
650 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
651 uint64_t Size = BTy.getSizeInBits() >> 3;
652 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
653}
654
655/// constructTypeDIE - Construct derived type die from DIDerivedType.
656void CompileUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
657 // Get core information.
658 StringRef Name = DTy.getName();
659 uint64_t Size = DTy.getSizeInBits() >> 3;
660 unsigned Tag = DTy.getTag();
661
662 // FIXME - Workaround for templates.
663 if (Tag == dwarf::DW_TAG_inheritance) Tag = dwarf::DW_TAG_reference_type;
664
665 Buffer.setTag(Tag);
666
667 // Map to main type, void will not have a type.
668 DIType FromTy = DTy.getTypeDerivedFrom();
669 addType(&Buffer, FromTy);
670
671 // Add name if not anonymous or intermediate type.
672 if (!Name.empty())
673 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
674
675 // Add size if non-zero (derived types might be zero-sized.)
676 if (Size)
677 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
678
679 // Add source line info if available and TyDesc is not a forward declaration.
680 if (!DTy.isForwardDecl())
681 addSourceLine(&Buffer, DTy);
682}
683
684/// constructTypeDIE - Construct type DIE from DICompositeType.
685void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
686 // Get core information.
687 StringRef Name = CTy.getName();
688
689 uint64_t Size = CTy.getSizeInBits() >> 3;
690 unsigned Tag = CTy.getTag();
691 Buffer.setTag(Tag);
692
693 switch (Tag) {
694 case dwarf::DW_TAG_vector_type:
695 case dwarf::DW_TAG_array_type:
696 constructArrayTypeDIE(Buffer, &CTy);
697 break;
698 case dwarf::DW_TAG_enumeration_type: {
699 DIArray Elements = CTy.getTypeArray();
700
701 // Add enumerators to enumeration type.
702 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
703 DIE *ElemDie = NULL;
704 DIDescriptor Enum(Elements.getElement(i));
705 if (Enum.isEnumerator()) {
706 ElemDie = constructEnumTypeDIE(DIEnumerator(Enum));
707 Buffer.addChild(ElemDie);
708 }
709 }
710 }
711 break;
712 case dwarf::DW_TAG_subroutine_type: {
713 // Add return type.
714 DIArray Elements = CTy.getTypeArray();
715 DIDescriptor RTy = Elements.getElement(0);
716 addType(&Buffer, DIType(RTy));
717
718 bool isPrototyped = true;
719 // Add arguments.
720 for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
721 DIDescriptor Ty = Elements.getElement(i);
722 if (Ty.isUnspecifiedParameter()) {
723 DIE *Arg = new DIE(dwarf::DW_TAG_unspecified_parameters);
724 Buffer.addChild(Arg);
725 isPrototyped = false;
726 } else {
727 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
728 addType(Arg, DIType(Ty));
729 Buffer.addChild(Arg);
730 }
731 }
732 // Add prototype flag.
733 if (isPrototyped)
734 addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
735 }
736 break;
737 case dwarf::DW_TAG_structure_type:
738 case dwarf::DW_TAG_union_type:
739 case dwarf::DW_TAG_class_type: {
740 // Add elements to structure type.
741 DIArray Elements = CTy.getTypeArray();
742
743 // A forward struct declared type may not have elements available.
744 unsigned N = Elements.getNumElements();
745 if (N == 0)
746 break;
747
748 // Add elements to structure type.
749 for (unsigned i = 0; i < N; ++i) {
750 DIDescriptor Element = Elements.getElement(i);
751 DIE *ElemDie = NULL;
752 if (Element.isSubprogram()) {
753 DISubprogram SP(Element);
754 ElemDie = DD->createSubprogramDIE(DISubprogram(Element));
755 if (SP.isProtected())
756 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
757 dwarf::DW_ACCESS_protected);
758 else if (SP.isPrivate())
759 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
760 dwarf::DW_ACCESS_private);
761 else
762 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
763 dwarf::DW_ACCESS_public);
764 if (SP.isExplicit())
765 addUInt(ElemDie, dwarf::DW_AT_explicit, dwarf::DW_FORM_flag, 1);
766 }
767 else if (Element.isVariable()) {
768 DIVariable DV(Element);
769 ElemDie = new DIE(dwarf::DW_TAG_variable);
770 addString(ElemDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,
771 DV.getName());
772 addType(ElemDie, DV.getType());
773 addUInt(ElemDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
774 addUInt(ElemDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
775 addSourceLine(ElemDie, DV);
776 } else if (Element.isDerivedType())
777 ElemDie = createMemberDIE(DIDerivedType(Element));
778 else
779 continue;
780 Buffer.addChild(ElemDie);
781 }
782
783 if (CTy.isAppleBlockExtension())
784 addUInt(&Buffer, dwarf::DW_AT_APPLE_block, dwarf::DW_FORM_flag, 1);
785
786 unsigned RLang = CTy.getRunTimeLang();
787 if (RLang)
788 addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class,
789 dwarf::DW_FORM_data1, RLang);
790
791 DICompositeType ContainingType = CTy.getContainingType();
792 if (DIDescriptor(ContainingType).isCompositeType())
793 addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
794 getOrCreateTypeDIE(DIType(ContainingType)));
795 else {
796 DIDescriptor Context = CTy.getContext();
797 addToContextOwner(&Buffer, Context);
798 }
799
Devang Patel201e6cd2011-05-12 21:29:42 +0000800 if (CTy.isObjcClassComplete())
801 addUInt(&Buffer, dwarf::DW_AT_APPLE_objc_complete_type,
Devang Patelb11f80e2011-05-12 19:06:16 +0000802 dwarf::DW_FORM_flag, 1);
803
Devang Patel161b2f42011-04-12 23:21:44 +0000804 if (Tag == dwarf::DW_TAG_class_type)
805 addTemplateParams(Buffer, CTy.getTemplateParams());
806
807 break;
808 }
809 default:
810 break;
811 }
812
813 // Add name if not anonymous or intermediate type.
814 if (!Name.empty())
815 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
816
817 if (Tag == dwarf::DW_TAG_enumeration_type || Tag == dwarf::DW_TAG_class_type
818 || Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type)
819 {
820 // Add size if non-zero (derived types might be zero-sized.)
821 if (Size)
822 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
823 else {
824 // Add zero size if it is not a forward declaration.
825 if (CTy.isForwardDecl())
826 addUInt(&Buffer, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
827 else
828 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, 0);
829 }
830
831 // Add source line info if available.
832 if (!CTy.isForwardDecl())
833 addSourceLine(&Buffer, CTy);
834 }
835}
836
837/// getOrCreateTemplateTypeParameterDIE - Find existing DIE or create new DIE
838/// for the given DITemplateTypeParameter.
839DIE *
840CompileUnit::getOrCreateTemplateTypeParameterDIE(DITemplateTypeParameter TP) {
841 DIE *ParamDIE = getDIE(TP);
842 if (ParamDIE)
843 return ParamDIE;
844
845 ParamDIE = new DIE(dwarf::DW_TAG_template_type_parameter);
846 addType(ParamDIE, TP.getType());
847 addString(ParamDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string, TP.getName());
848 return ParamDIE;
849}
850
851/// getOrCreateTemplateValueParameterDIE - Find existing DIE or create new DIE
852/// for the given DITemplateValueParameter.
853DIE *
854CompileUnit::getOrCreateTemplateValueParameterDIE(DITemplateValueParameter TPV) {
855 DIE *ParamDIE = getDIE(TPV);
856 if (ParamDIE)
857 return ParamDIE;
858
859 ParamDIE = new DIE(dwarf::DW_TAG_template_value_parameter);
860 addType(ParamDIE, TPV.getType());
861 if (!TPV.getName().empty())
862 addString(ParamDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string, TPV.getName());
863 addUInt(ParamDIE, dwarf::DW_AT_const_value, dwarf::DW_FORM_udata,
864 TPV.getValue());
865 return ParamDIE;
866}
867
Devang Patel31c5d052011-05-06 16:57:54 +0000868/// getOrCreateNameSpace - Create a DIE for DINameSpace.
869DIE *CompileUnit::getOrCreateNameSpace(DINameSpace NS) {
870 DIE *NDie = getDIE(NS);
871 if (NDie)
872 return NDie;
873 NDie = new DIE(dwarf::DW_TAG_namespace);
874 insertDIE(NS, NDie);
875 if (!NS.getName().empty())
876 addString(NDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, NS.getName());
877 addSourceLine(NDie, NS);
878 addToContextOwner(NDie, NS.getContext());
879 return NDie;
880}
881
Devang Patel161b2f42011-04-12 23:21:44 +0000882/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
883void CompileUnit::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){
884 DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type);
885 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IndexTy);
886 int64_t L = SR.getLo();
887 int64_t H = SR.getHi();
888
889 // The L value defines the lower bounds which is typically zero for C/C++. The
890 // H value is the upper bounds. Values are 64 bit. H - L + 1 is the size
891 // of the array. If L > H then do not emit DW_AT_lower_bound and
892 // DW_AT_upper_bound attributes. If L is zero and H is also zero then the
893 // array has one element and in such case do not emit lower bound.
894
895 if (L > H) {
896 Buffer.addChild(DW_Subrange);
897 return;
898 }
899 if (L)
900 addSInt(DW_Subrange, dwarf::DW_AT_lower_bound, 0, L);
901 addSInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, H);
902 Buffer.addChild(DW_Subrange);
903}
904
905/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
906void CompileUnit::constructArrayTypeDIE(DIE &Buffer,
907 DICompositeType *CTy) {
908 Buffer.setTag(dwarf::DW_TAG_array_type);
909 if (CTy->getTag() == dwarf::DW_TAG_vector_type)
910 addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1);
911
912 // Emit derived type.
913 addType(&Buffer, CTy->getTypeDerivedFrom());
914 DIArray Elements = CTy->getTypeArray();
915
916 // Get an anonymous type for index type.
917 DIE *IdxTy = getIndexTyDie();
918 if (!IdxTy) {
919 // Construct an anonymous type for index type.
920 IdxTy = new DIE(dwarf::DW_TAG_base_type);
921 addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t));
922 addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
923 dwarf::DW_ATE_signed);
924 addDie(IdxTy);
925 setIndexTyDie(IdxTy);
926 }
927
928 // Add subranges to array type.
929 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
930 DIDescriptor Element = Elements.getElement(i);
931 if (Element.getTag() == dwarf::DW_TAG_subrange_type)
932 constructSubrangeDIE(Buffer, DISubrange(Element), IdxTy);
933 }
934}
935
936/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
937DIE *CompileUnit::constructEnumTypeDIE(DIEnumerator ETy) {
938 DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator);
939 StringRef Name = ETy.getName();
940 addString(Enumerator, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
941 int64_t Value = ETy.getEnumValue();
942 addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value);
943 return Enumerator;
944}
945
946/// createMemberDIE - Create new member DIE.
947DIE *CompileUnit::createMemberDIE(DIDerivedType DT) {
948 DIE *MemberDie = new DIE(DT.getTag());
949 StringRef Name = DT.getName();
950 if (!Name.empty())
951 addString(MemberDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
952
953 addType(MemberDie, DT.getTypeDerivedFrom());
954
955 addSourceLine(MemberDie, DT);
956
957 DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
958 addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
959
960 uint64_t Size = DT.getSizeInBits();
961 uint64_t FieldSize = DT.getOriginalTypeSize();
962
963 if (Size != FieldSize) {
964 // Handle bitfield.
965 addUInt(MemberDie, dwarf::DW_AT_byte_size, 0, DT.getOriginalTypeSize()>>3);
966 addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits());
967
968 uint64_t Offset = DT.getOffsetInBits();
969 uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
970 uint64_t HiMark = (Offset + FieldSize) & AlignMask;
971 uint64_t FieldOffset = (HiMark - FieldSize);
972 Offset -= FieldOffset;
973
974 // Maybe we need to work from the other end.
975 if (Asm->getTargetData().isLittleEndian())
976 Offset = FieldSize - (Offset + Size);
977 addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
978
979 // Here WD_AT_data_member_location points to the anonymous
980 // field that includes this bit field.
981 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, FieldOffset >> 3);
982
983 } else
984 // This is not a bitfield.
985 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);
986
987 if (DT.getTag() == dwarf::DW_TAG_inheritance
988 && DT.isVirtual()) {
989
990 // For C++, virtual base classes are not at fixed offset. Use following
991 // expression to extract appropriate offset from vtable.
992 // BaseAddr = ObAddr + *((*ObAddr) - Offset)
993
994 DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock();
995 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
996 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
997 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
998 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits());
999 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
1000 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1001 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1002
1003 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0,
1004 VBaseLocationDie);
1005 } else
1006 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
1007
1008 if (DT.isProtected())
1009 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1010 dwarf::DW_ACCESS_protected);
1011 else if (DT.isPrivate())
1012 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1013 dwarf::DW_ACCESS_private);
1014 // Otherwise C++ member and base classes are considered public.
1015 else if (DT.getCompileUnit().getLanguage() == dwarf::DW_LANG_C_plus_plus)
1016 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1017 dwarf::DW_ACCESS_public);
1018 if (DT.isVirtual())
1019 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag,
1020 dwarf::DW_VIRTUALITY_virtual);
Devang Patele9db5e22011-04-16 00:11:51 +00001021
1022 // Objective-C properties.
1023 StringRef PropertyName = DT.getObjCPropertyName();
1024 if (!PropertyName.empty()) {
1025 addString(MemberDie, dwarf::DW_AT_APPLE_property_name, dwarf::DW_FORM_string,
1026 PropertyName);
1027 StringRef GetterName = DT.getObjCPropertyGetterName();
1028 if (!GetterName.empty())
1029 addString(MemberDie, dwarf::DW_AT_APPLE_property_getter,
1030 dwarf::DW_FORM_string, GetterName);
1031 StringRef SetterName = DT.getObjCPropertySetterName();
1032 if (!SetterName.empty())
1033 addString(MemberDie, dwarf::DW_AT_APPLE_property_setter,
1034 dwarf::DW_FORM_string, SetterName);
1035 unsigned PropertyAttributes = 0;
1036 if (DT.isReadOnlyObjCProperty())
1037 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readonly;
1038 if (DT.isReadWriteObjCProperty())
1039 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readwrite;
1040 if (DT.isAssignObjCProperty())
1041 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_assign;
1042 if (DT.isRetainObjCProperty())
1043 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_retain;
1044 if (DT.isCopyObjCProperty())
1045 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_copy;
1046 if (DT.isNonAtomicObjCProperty())
1047 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_nonatomic;
1048 if (PropertyAttributes)
1049 addUInt(MemberDie, dwarf::DW_AT_APPLE_property_attribute, 0,
1050 PropertyAttributes);
1051 }
Devang Patel161b2f42011-04-12 23:21:44 +00001052 return MemberDie;
1053}