blob: a68da04907c11465c7e213744af95ec5af575564 [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);
Eric Christopher56c2b102011-11-07 22:11:16 +0000637
638 // If this is a named finished type then include it in the list of types
639 // for the accelerator tables.
640 if (!Ty.getName().empty() && !Ty.isForwardDecl())
641 if (DIEEntry *Entry = getDIEEntry(Ty))
642 AccelTypes[Ty.getName()] = Entry->getEntry();
Devang Patel66658e42011-05-31 23:30:30 +0000643}
644
645/// addGlobalType - Add a new global type to the compile unit.
646///
Devang Patelc20bdf12011-06-01 00:23:24 +0000647void CompileUnit::addGlobalType(DIType Ty) {
Devang Patele9ae06c2011-05-31 22:56:51 +0000648 DIDescriptor Context = Ty.getContext();
649 if (Ty.isCompositeType() && !Ty.getName().empty() && !Ty.isForwardDecl()
Devang Patel94c7ddb2011-08-16 22:09:43 +0000650 && (!Context || Context.isCompileUnit() || Context.isFile()
651 || Context.isNameSpace()))
Devang Patelc20bdf12011-06-01 00:23:24 +0000652 if (DIEEntry *Entry = getDIEEntry(Ty))
653 GlobalTypes[Ty.getName()] = Entry->getEntry();
Devang Patel161b2f42011-04-12 23:21:44 +0000654}
655
Devang Patel31c5d052011-05-06 16:57:54 +0000656/// addPubTypes - Add type for pubtypes section.
657void CompileUnit::addPubTypes(DISubprogram SP) {
658 DICompositeType SPTy = SP.getType();
659 unsigned SPTag = SPTy.getTag();
660 if (SPTag != dwarf::DW_TAG_subroutine_type)
661 return;
662
663 DIArray Args = SPTy.getTypeArray();
664 for (unsigned i = 0, e = Args.getNumElements(); i != e; ++i) {
665 DIType ATy(Args.getElement(i));
666 if (!ATy.Verify())
667 continue;
Devang Patelc20bdf12011-06-01 00:23:24 +0000668 addGlobalType(ATy);
Devang Patel31c5d052011-05-06 16:57:54 +0000669 }
670}
671
Devang Patel161b2f42011-04-12 23:21:44 +0000672/// constructTypeDIE - Construct basic type die from DIBasicType.
673void CompileUnit::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
674 // Get core information.
675 StringRef Name = BTy.getName();
Devang Patel161b2f42011-04-12 23:21:44 +0000676 // Add name if not anonymous or intermediate type.
677 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000678 addString(&Buffer, dwarf::DW_AT_name, Name);
Devang Patel734a67c2011-09-14 23:13:28 +0000679
680 if (BTy.getTag() == dwarf::DW_TAG_unspecified_type) {
681 Buffer.setTag(dwarf::DW_TAG_unspecified_type);
682 // Unspecified types has only name, nothing else.
683 return;
684 }
685
686 Buffer.setTag(dwarf::DW_TAG_base_type);
Nick Lewycky746cb672011-10-26 22:55:33 +0000687 addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
Devang Patel734a67c2011-09-14 23:13:28 +0000688 BTy.getEncoding());
689
Devang Patel161b2f42011-04-12 23:21:44 +0000690 uint64_t Size = BTy.getSizeInBits() >> 3;
691 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
692}
693
694/// constructTypeDIE - Construct derived type die from DIDerivedType.
695void CompileUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
696 // Get core information.
697 StringRef Name = DTy.getName();
698 uint64_t Size = DTy.getSizeInBits() >> 3;
699 unsigned Tag = DTy.getTag();
700
701 // FIXME - Workaround for templates.
702 if (Tag == dwarf::DW_TAG_inheritance) Tag = dwarf::DW_TAG_reference_type;
703
704 Buffer.setTag(Tag);
705
706 // Map to main type, void will not have a type.
707 DIType FromTy = DTy.getTypeDerivedFrom();
708 addType(&Buffer, FromTy);
709
710 // Add name if not anonymous or intermediate type.
711 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000712 addString(&Buffer, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +0000713
714 // Add size if non-zero (derived types might be zero-sized.)
715 if (Size)
716 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
717
718 // Add source line info if available and TyDesc is not a forward declaration.
719 if (!DTy.isForwardDecl())
720 addSourceLine(&Buffer, DTy);
721}
722
723/// constructTypeDIE - Construct type DIE from DICompositeType.
724void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
725 // Get core information.
726 StringRef Name = CTy.getName();
727
728 uint64_t Size = CTy.getSizeInBits() >> 3;
729 unsigned Tag = CTy.getTag();
730 Buffer.setTag(Tag);
731
732 switch (Tag) {
733 case dwarf::DW_TAG_vector_type:
734 case dwarf::DW_TAG_array_type:
735 constructArrayTypeDIE(Buffer, &CTy);
736 break;
737 case dwarf::DW_TAG_enumeration_type: {
738 DIArray Elements = CTy.getTypeArray();
739
740 // Add enumerators to enumeration type.
741 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
742 DIE *ElemDie = NULL;
743 DIDescriptor Enum(Elements.getElement(i));
744 if (Enum.isEnumerator()) {
745 ElemDie = constructEnumTypeDIE(DIEnumerator(Enum));
746 Buffer.addChild(ElemDie);
747 }
748 }
749 }
750 break;
751 case dwarf::DW_TAG_subroutine_type: {
752 // Add return type.
753 DIArray Elements = CTy.getTypeArray();
754 DIDescriptor RTy = Elements.getElement(0);
755 addType(&Buffer, DIType(RTy));
756
757 bool isPrototyped = true;
758 // Add arguments.
759 for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
760 DIDescriptor Ty = Elements.getElement(i);
761 if (Ty.isUnspecifiedParameter()) {
762 DIE *Arg = new DIE(dwarf::DW_TAG_unspecified_parameters);
763 Buffer.addChild(Arg);
764 isPrototyped = false;
765 } else {
766 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
767 addType(Arg, DIType(Ty));
768 Buffer.addChild(Arg);
769 }
770 }
771 // Add prototype flag.
772 if (isPrototyped)
773 addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
774 }
775 break;
776 case dwarf::DW_TAG_structure_type:
777 case dwarf::DW_TAG_union_type:
778 case dwarf::DW_TAG_class_type: {
779 // Add elements to structure type.
780 DIArray Elements = CTy.getTypeArray();
781
782 // A forward struct declared type may not have elements available.
783 unsigned N = Elements.getNumElements();
784 if (N == 0)
785 break;
786
787 // Add elements to structure type.
788 for (unsigned i = 0; i < N; ++i) {
789 DIDescriptor Element = Elements.getElement(i);
790 DIE *ElemDie = NULL;
791 if (Element.isSubprogram()) {
792 DISubprogram SP(Element);
Devang Pateldbc64af2011-08-15 17:24:54 +0000793 ElemDie = getOrCreateSubprogramDIE(DISubprogram(Element));
Devang Patel161b2f42011-04-12 23:21:44 +0000794 if (SP.isProtected())
795 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
796 dwarf::DW_ACCESS_protected);
797 else if (SP.isPrivate())
798 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
799 dwarf::DW_ACCESS_private);
800 else
801 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
802 dwarf::DW_ACCESS_public);
803 if (SP.isExplicit())
804 addUInt(ElemDie, dwarf::DW_AT_explicit, dwarf::DW_FORM_flag, 1);
805 }
806 else if (Element.isVariable()) {
807 DIVariable DV(Element);
808 ElemDie = new DIE(dwarf::DW_TAG_variable);
Nick Lewycky390c40d2011-10-27 06:44:11 +0000809 addString(ElemDie, dwarf::DW_AT_name, DV.getName());
Devang Patel161b2f42011-04-12 23:21:44 +0000810 addType(ElemDie, DV.getType());
811 addUInt(ElemDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
812 addUInt(ElemDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
813 addSourceLine(ElemDie, DV);
814 } else if (Element.isDerivedType())
815 ElemDie = createMemberDIE(DIDerivedType(Element));
816 else
817 continue;
818 Buffer.addChild(ElemDie);
819 }
820
821 if (CTy.isAppleBlockExtension())
822 addUInt(&Buffer, dwarf::DW_AT_APPLE_block, dwarf::DW_FORM_flag, 1);
823
824 unsigned RLang = CTy.getRunTimeLang();
825 if (RLang)
826 addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class,
827 dwarf::DW_FORM_data1, RLang);
828
829 DICompositeType ContainingType = CTy.getContainingType();
830 if (DIDescriptor(ContainingType).isCompositeType())
831 addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
832 getOrCreateTypeDIE(DIType(ContainingType)));
833 else {
834 DIDescriptor Context = CTy.getContext();
835 addToContextOwner(&Buffer, Context);
836 }
837
Devang Patel201e6cd2011-05-12 21:29:42 +0000838 if (CTy.isObjcClassComplete())
839 addUInt(&Buffer, dwarf::DW_AT_APPLE_objc_complete_type,
Devang Patelb11f80e2011-05-12 19:06:16 +0000840 dwarf::DW_FORM_flag, 1);
841
Devang Patel161b2f42011-04-12 23:21:44 +0000842 if (Tag == dwarf::DW_TAG_class_type)
843 addTemplateParams(Buffer, CTy.getTemplateParams());
844
845 break;
846 }
847 default:
848 break;
849 }
850
851 // Add name if not anonymous or intermediate type.
852 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000853 addString(&Buffer, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +0000854
855 if (Tag == dwarf::DW_TAG_enumeration_type || Tag == dwarf::DW_TAG_class_type
856 || Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type)
Nick Lewycky746cb672011-10-26 22:55:33 +0000857 {
Devang Patel161b2f42011-04-12 23:21:44 +0000858 // Add size if non-zero (derived types might be zero-sized.)
859 if (Size)
860 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
861 else {
862 // Add zero size if it is not a forward declaration.
863 if (CTy.isForwardDecl())
864 addUInt(&Buffer, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
865 else
866 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, 0);
867 }
868
869 // Add source line info if available.
870 if (!CTy.isForwardDecl())
871 addSourceLine(&Buffer, CTy);
872 }
873}
874
875/// getOrCreateTemplateTypeParameterDIE - Find existing DIE or create new DIE
876/// for the given DITemplateTypeParameter.
877DIE *
878CompileUnit::getOrCreateTemplateTypeParameterDIE(DITemplateTypeParameter TP) {
879 DIE *ParamDIE = getDIE(TP);
880 if (ParamDIE)
881 return ParamDIE;
882
883 ParamDIE = new DIE(dwarf::DW_TAG_template_type_parameter);
884 addType(ParamDIE, TP.getType());
Nick Lewycky390c40d2011-10-27 06:44:11 +0000885 addString(ParamDIE, dwarf::DW_AT_name, TP.getName());
Devang Patel161b2f42011-04-12 23:21:44 +0000886 return ParamDIE;
887}
888
889/// getOrCreateTemplateValueParameterDIE - Find existing DIE or create new DIE
890/// for the given DITemplateValueParameter.
891DIE *
892CompileUnit::getOrCreateTemplateValueParameterDIE(DITemplateValueParameter TPV) {
893 DIE *ParamDIE = getDIE(TPV);
894 if (ParamDIE)
895 return ParamDIE;
896
897 ParamDIE = new DIE(dwarf::DW_TAG_template_value_parameter);
898 addType(ParamDIE, TPV.getType());
899 if (!TPV.getName().empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000900 addString(ParamDIE, dwarf::DW_AT_name, TPV.getName());
Devang Patel161b2f42011-04-12 23:21:44 +0000901 addUInt(ParamDIE, dwarf::DW_AT_const_value, dwarf::DW_FORM_udata,
902 TPV.getValue());
903 return ParamDIE;
904}
905
Devang Patel31c5d052011-05-06 16:57:54 +0000906/// getOrCreateNameSpace - Create a DIE for DINameSpace.
907DIE *CompileUnit::getOrCreateNameSpace(DINameSpace NS) {
908 DIE *NDie = getDIE(NS);
909 if (NDie)
910 return NDie;
911 NDie = new DIE(dwarf::DW_TAG_namespace);
912 insertDIE(NS, NDie);
Eric Christopher09ac3d82011-11-07 09:24:32 +0000913 if (!NS.getName().empty()) {
Nick Lewycky390c40d2011-10-27 06:44:11 +0000914 addString(NDie, dwarf::DW_AT_name, NS.getName());
Eric Christopher09ac3d82011-11-07 09:24:32 +0000915 addAccelNamespace(NS.getName(), NDie);
916 } else
917 addAccelNamespace("(anonymous namespace)", NDie);
Devang Patel31c5d052011-05-06 16:57:54 +0000918 addSourceLine(NDie, NS);
919 addToContextOwner(NDie, NS.getContext());
920 return NDie;
921}
922
Devang Pateldbc64af2011-08-15 17:24:54 +0000923/// getRealLinkageName - If special LLVM prefix that is used to inform the asm
924/// printer to not emit usual symbol prefix before the symbol name is used then
925/// return linkage name after skipping this special LLVM prefix.
926static StringRef getRealLinkageName(StringRef LinkageName) {
927 char One = '\1';
928 if (LinkageName.startswith(StringRef(&One, 1)))
929 return LinkageName.substr(1);
930 return LinkageName;
931}
932
933/// getOrCreateSubprogramDIE - Create new DIE using SP.
934DIE *CompileUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
935 DIE *SPDie = getDIE(SP);
936 if (SPDie)
937 return SPDie;
938
939 SPDie = new DIE(dwarf::DW_TAG_subprogram);
940
941 // DW_TAG_inlined_subroutine may refer to this DIE.
942 insertDIE(SP, SPDie);
943
944 // Add to context owner.
945 addToContextOwner(SPDie, SP.getContext());
946
947 // Add function template parameters.
948 addTemplateParams(*SPDie, SP.getTemplateParams());
949
950 StringRef LinkageName = SP.getLinkageName();
951 if (!LinkageName.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000952 addString(SPDie, dwarf::DW_AT_MIPS_linkage_name,
Nick Lewycky746cb672011-10-26 22:55:33 +0000953 getRealLinkageName(LinkageName));
Devang Pateldbc64af2011-08-15 17:24:54 +0000954
955 // If this DIE is going to refer declaration info using AT_specification
956 // then there is no need to add other attributes.
957 if (SP.getFunctionDeclaration().isSubprogram())
958 return SPDie;
959
960 // Constructors and operators for anonymous aggregates do not have names.
961 if (!SP.getName().empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000962 addString(SPDie, dwarf::DW_AT_name, SP.getName());
Devang Pateldbc64af2011-08-15 17:24:54 +0000963
964 addSourceLine(SPDie, SP);
965
966 if (SP.isPrototyped())
967 addUInt(SPDie, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
968
969 // Add Return Type.
970 DICompositeType SPTy = SP.getType();
971 DIArray Args = SPTy.getTypeArray();
972 unsigned SPTag = SPTy.getTag();
973
974 if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type)
975 addType(SPDie, SPTy);
976 else
977 addType(SPDie, DIType(Args.getElement(0)));
978
979 unsigned VK = SP.getVirtuality();
980 if (VK) {
981 addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK);
982 DIEBlock *Block = getDIEBlock();
983 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
984 addUInt(Block, 0, dwarf::DW_FORM_udata, SP.getVirtualIndex());
985 addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
986 ContainingTypeMap.insert(std::make_pair(SPDie,
987 SP.getContainingType()));
988 }
989
990 if (!SP.isDefinition()) {
991 addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
992
993 // Add arguments. Do not add arguments for subprogram definition. They will
994 // be handled while processing variables.
995 DICompositeType SPTy = SP.getType();
996 DIArray Args = SPTy.getTypeArray();
997 unsigned SPTag = SPTy.getTag();
998
999 if (SPTag == dwarf::DW_TAG_subroutine_type)
1000 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
1001 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
1002 DIType ATy = DIType(DIType(Args.getElement(i)));
1003 addType(Arg, ATy);
1004 if (ATy.isArtificial())
1005 addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
1006 SPDie->addChild(Arg);
1007 }
1008 }
1009
1010 if (SP.isArtificial())
1011 addUInt(SPDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
1012
1013 if (!SP.isLocalToUnit())
1014 addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
1015
1016 if (SP.isOptimized())
1017 addUInt(SPDie, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1);
1018
1019 if (unsigned isa = Asm->getISAEncoding()) {
1020 addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa);
1021 }
1022
1023 return SPDie;
1024}
1025
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001026// Return const expression if value is a GEP to access merged global
1027// constant. e.g.
1028// i8* getelementptr ({ i8, i8, i8, i8 }* @_MergedGlobals, i32 0, i32 0)
1029static const ConstantExpr *getMergedGlobalExpr(const Value *V) {
1030 const ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(V);
1031 if (!CE || CE->getNumOperands() != 3 ||
1032 CE->getOpcode() != Instruction::GetElementPtr)
1033 return NULL;
1034
1035 // First operand points to a global struct.
1036 Value *Ptr = CE->getOperand(0);
1037 if (!isa<GlobalValue>(Ptr) ||
1038 !isa<StructType>(cast<PointerType>(Ptr->getType())->getElementType()))
1039 return NULL;
1040
1041 // Second operand is zero.
1042 const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CE->getOperand(1));
1043 if (!CI || !CI->isZero())
1044 return NULL;
1045
1046 // Third operand is offset.
1047 if (!isa<ConstantInt>(CE->getOperand(2)))
1048 return NULL;
1049
1050 return CE;
1051}
1052
1053/// createGlobalVariableDIE - create global variable DIE.
1054void CompileUnit::createGlobalVariableDIE(const MDNode *N) {
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001055 // Check for pre-existence.
Devang Patel49e2f032011-08-18 22:21:50 +00001056 if (getDIE(N))
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001057 return;
1058
Devang Patel49e2f032011-08-18 22:21:50 +00001059 DIGlobalVariable GV(N);
Devang Patel28bea082011-08-18 23:17:55 +00001060 if (!GV.Verify())
1061 return;
1062
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001063 DIE *VariableDIE = new DIE(GV.getTag());
Devang Patel49e2f032011-08-18 22:21:50 +00001064 // Add to map.
1065 insertDIE(N, VariableDIE);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001066
1067 // Add name.
Nick Lewycky390c40d2011-10-27 06:44:11 +00001068 addString(VariableDIE, dwarf::DW_AT_name, GV.getDisplayName());
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001069 StringRef LinkageName = GV.getLinkageName();
Devang Patel49e2f032011-08-18 22:21:50 +00001070 bool isGlobalVariable = GV.getGlobal() != NULL;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001071 if (!LinkageName.empty() && isGlobalVariable)
Nick Lewycky746cb672011-10-26 22:55:33 +00001072 addString(VariableDIE, dwarf::DW_AT_MIPS_linkage_name,
Nick Lewycky390c40d2011-10-27 06:44:11 +00001073 getRealLinkageName(LinkageName));
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001074 // Add type.
Devang Patel49e2f032011-08-18 22:21:50 +00001075 DIType GTy = GV.getType();
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001076 addType(VariableDIE, GTy);
1077
1078 // Add scoping info.
Eric Christopherdfa30e12011-11-09 05:24:07 +00001079 if (!GV.isLocalToUnit())
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001080 addUInt(VariableDIE, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
Eric Christopherdfa30e12011-11-09 05:24:07 +00001081
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001082 // Add line number info.
1083 addSourceLine(VariableDIE, GV);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001084 // Add to context owner.
1085 DIDescriptor GVContext = GV.getContext();
1086 addToContextOwner(VariableDIE, GVContext);
1087 // Add location.
Eric Christopher09ac3d82011-11-07 09:24:32 +00001088 bool addToAccelTable = false;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001089 if (isGlobalVariable) {
Eric Christopher09ac3d82011-11-07 09:24:32 +00001090 addToAccelTable = true;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001091 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
1092 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
1093 addLabel(Block, 0, dwarf::DW_FORM_udata,
1094 Asm->Mang->getSymbol(GV.getGlobal()));
1095 // Do not create specification DIE if context is either compile unit
1096 // or a subprogram.
Devang Patel1dd4e562011-09-21 23:41:11 +00001097 if (GVContext && GV.isDefinition() && !GVContext.isCompileUnit() &&
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001098 !GVContext.isFile() && !isSubprogramContext(GVContext)) {
1099 // Create specification DIE.
1100 DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
1101 addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
1102 dwarf::DW_FORM_ref4, VariableDIE);
1103 addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
1104 addUInt(VariableDIE, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag,
1105 1);
1106 addDie(VariableSpecDIE);
1107 } else {
1108 addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
Eric Christopher09ac3d82011-11-07 09:24:32 +00001109 }
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001110 } else if (const ConstantInt *CI =
1111 dyn_cast_or_null<ConstantInt>(GV.getConstant()))
1112 addConstantValue(VariableDIE, CI, GTy.isUnsignedDIType());
1113 else if (const ConstantExpr *CE = getMergedGlobalExpr(N->getOperand(11))) {
Eric Christopher09ac3d82011-11-07 09:24:32 +00001114 addToAccelTable = true;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001115 // GV is a merged global.
1116 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
1117 Value *Ptr = CE->getOperand(0);
1118 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
1119 addLabel(Block, 0, dwarf::DW_FORM_udata,
1120 Asm->Mang->getSymbol(cast<GlobalValue>(Ptr)));
1121 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1122 SmallVector<Value*, 3> Idx(CE->op_begin()+1, CE->op_end());
1123 addUInt(Block, 0, dwarf::DW_FORM_udata,
1124 Asm->getTargetData().getIndexedOffset(Ptr->getType(), Idx));
1125 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1126 addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
1127 }
1128
Eric Christopher09ac3d82011-11-07 09:24:32 +00001129 if (addToAccelTable)
1130 addAccelName(GV.getName(), VariableDIE);
1131
Eric Christopher74d8a872011-11-08 21:56:23 +00001132 // If the linkage name is different than the name, go ahead and output
1133 // that as well into the name table.
1134 if (GV.getLinkageName() != "" && GV.getName() != GV.getLinkageName())
1135 addAccelName(GV.getLinkageName(), VariableDIE);
1136
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001137 return;
1138}
1139
Devang Patel161b2f42011-04-12 23:21:44 +00001140/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
1141void CompileUnit::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){
1142 DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type);
1143 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IndexTy);
1144 int64_t L = SR.getLo();
1145 int64_t H = SR.getHi();
1146
1147 // The L value defines the lower bounds which is typically zero for C/C++. The
1148 // H value is the upper bounds. Values are 64 bit. H - L + 1 is the size
1149 // of the array. If L > H then do not emit DW_AT_lower_bound and
1150 // DW_AT_upper_bound attributes. If L is zero and H is also zero then the
1151 // array has one element and in such case do not emit lower bound.
1152
1153 if (L > H) {
1154 Buffer.addChild(DW_Subrange);
1155 return;
1156 }
1157 if (L)
1158 addSInt(DW_Subrange, dwarf::DW_AT_lower_bound, 0, L);
1159 addSInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, H);
1160 Buffer.addChild(DW_Subrange);
1161}
1162
1163/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
1164void CompileUnit::constructArrayTypeDIE(DIE &Buffer,
1165 DICompositeType *CTy) {
1166 Buffer.setTag(dwarf::DW_TAG_array_type);
1167 if (CTy->getTag() == dwarf::DW_TAG_vector_type)
1168 addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1);
1169
1170 // Emit derived type.
1171 addType(&Buffer, CTy->getTypeDerivedFrom());
1172 DIArray Elements = CTy->getTypeArray();
1173
1174 // Get an anonymous type for index type.
1175 DIE *IdxTy = getIndexTyDie();
1176 if (!IdxTy) {
1177 // Construct an anonymous type for index type.
1178 IdxTy = new DIE(dwarf::DW_TAG_base_type);
1179 addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t));
1180 addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
1181 dwarf::DW_ATE_signed);
1182 addDie(IdxTy);
1183 setIndexTyDie(IdxTy);
1184 }
1185
1186 // Add subranges to array type.
1187 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
1188 DIDescriptor Element = Elements.getElement(i);
1189 if (Element.getTag() == dwarf::DW_TAG_subrange_type)
1190 constructSubrangeDIE(Buffer, DISubrange(Element), IdxTy);
1191 }
1192}
1193
1194/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
1195DIE *CompileUnit::constructEnumTypeDIE(DIEnumerator ETy) {
1196 DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator);
1197 StringRef Name = ETy.getName();
Nick Lewycky390c40d2011-10-27 06:44:11 +00001198 addString(Enumerator, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +00001199 int64_t Value = ETy.getEnumValue();
1200 addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value);
1201 return Enumerator;
1202}
1203
Devang Pateldbc64af2011-08-15 17:24:54 +00001204/// constructContainingTypeDIEs - Construct DIEs for types that contain
1205/// vtables.
1206void CompileUnit::constructContainingTypeDIEs() {
1207 for (DenseMap<DIE *, const MDNode *>::iterator CI = ContainingTypeMap.begin(),
1208 CE = ContainingTypeMap.end(); CI != CE; ++CI) {
1209 DIE *SPDie = CI->first;
1210 const MDNode *N = CI->second;
1211 if (!N) continue;
1212 DIE *NDie = getDIE(N);
1213 if (!NDie) continue;
1214 addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
1215 }
1216}
1217
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001218/// constructVariableDIE - Construct a DIE for the given DbgVariable.
1219DIE *CompileUnit::constructVariableDIE(DbgVariable *DV, bool isScopeAbstract) {
1220 StringRef Name = DV->getName();
1221 if (Name.empty())
1222 return NULL;
1223
1224 // Translate tag to proper Dwarf tag.
1225 unsigned Tag = DV->getTag();
1226
1227 // Define variable debug information entry.
1228 DIE *VariableDie = new DIE(Tag);
1229 DbgVariable *AbsVar = DV->getAbstractVariable();
1230 DIE *AbsDIE = AbsVar ? AbsVar->getDIE() : NULL;
1231 if (AbsDIE)
1232 addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin,
1233 dwarf::DW_FORM_ref4, AbsDIE);
1234 else {
Nick Lewycky390c40d2011-10-27 06:44:11 +00001235 addString(VariableDie, dwarf::DW_AT_name, Name);
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001236 addSourceLine(VariableDie, DV->getVariable());
1237 addType(VariableDie, DV->getType());
1238 }
1239
1240 if (DV->isArtificial())
1241 addUInt(VariableDie, dwarf::DW_AT_artificial,
1242 dwarf::DW_FORM_flag, 1);
1243
1244 if (isScopeAbstract) {
1245 DV->setDIE(VariableDie);
1246 return VariableDie;
1247 }
1248
1249 // Add variable address.
1250
1251 unsigned Offset = DV->getDotDebugLocOffset();
1252 if (Offset != ~0U) {
1253 addLabel(VariableDie, dwarf::DW_AT_location,
1254 dwarf::DW_FORM_data4,
1255 Asm->GetTempSymbol("debug_loc", Offset));
1256 DV->setDIE(VariableDie);
1257 return VariableDie;
1258 }
1259
Eric Christopher8cf5e742011-10-03 15:49:20 +00001260 // Check if variable is described by a DBG_VALUE instruction.
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001261 if (const MachineInstr *DVInsn = DV->getMInsn()) {
1262 bool updated = false;
1263 if (DVInsn->getNumOperands() == 3) {
1264 if (DVInsn->getOperand(0).isReg()) {
1265 const MachineOperand RegOp = DVInsn->getOperand(0);
1266 const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
1267 if (DVInsn->getOperand(1).isImm() &&
1268 TRI->getFrameRegister(*Asm->MF) == RegOp.getReg()) {
1269 unsigned FrameReg = 0;
1270 const TargetFrameLowering *TFI = Asm->TM.getFrameLowering();
1271 int Offset =
1272 TFI->getFrameIndexReference(*Asm->MF,
1273 DVInsn->getOperand(1).getImm(),
1274 FrameReg);
1275 MachineLocation Location(FrameReg, Offset);
1276 addVariableAddress(DV, VariableDie, Location);
1277
1278 } else if (RegOp.getReg())
1279 addVariableAddress(DV, VariableDie,
1280 MachineLocation(RegOp.getReg()));
1281 updated = true;
1282 }
1283 else if (DVInsn->getOperand(0).isImm())
1284 updated =
1285 addConstantValue(VariableDie, DVInsn->getOperand(0),
1286 DV->getType());
1287 else if (DVInsn->getOperand(0).isFPImm())
1288 updated =
1289 addConstantFPValue(VariableDie, DVInsn->getOperand(0));
1290 else if (DVInsn->getOperand(0).isCImm())
1291 updated =
1292 addConstantValue(VariableDie,
1293 DVInsn->getOperand(0).getCImm(),
1294 DV->getType().isUnsignedDIType());
1295 } else {
1296 addVariableAddress(DV, VariableDie,
1297 Asm->getDebugValueLocation(DVInsn));
1298 updated = true;
1299 }
1300 if (!updated) {
1301 // If variableDie is not updated then DBG_VALUE instruction does not
1302 // have valid variable info.
1303 delete VariableDie;
1304 return NULL;
1305 }
1306 DV->setDIE(VariableDie);
1307 return VariableDie;
1308 } else {
1309 // .. else use frame index.
1310 int FI = DV->getFrameIndex();
1311 if (FI != ~0) {
1312 unsigned FrameReg = 0;
1313 const TargetFrameLowering *TFI = Asm->TM.getFrameLowering();
1314 int Offset =
1315 TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg);
1316 MachineLocation Location(FrameReg, Offset);
1317 addVariableAddress(DV, VariableDie, Location);
1318 }
1319 }
1320
1321 DV->setDIE(VariableDie);
1322 return VariableDie;
1323}
1324
Devang Patel161b2f42011-04-12 23:21:44 +00001325/// createMemberDIE - Create new member DIE.
1326DIE *CompileUnit::createMemberDIE(DIDerivedType DT) {
1327 DIE *MemberDie = new DIE(DT.getTag());
1328 StringRef Name = DT.getName();
1329 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001330 addString(MemberDie, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +00001331
1332 addType(MemberDie, DT.getTypeDerivedFrom());
1333
1334 addSourceLine(MemberDie, DT);
1335
1336 DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
1337 addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
1338
1339 uint64_t Size = DT.getSizeInBits();
1340 uint64_t FieldSize = DT.getOriginalTypeSize();
1341
1342 if (Size != FieldSize) {
1343 // Handle bitfield.
1344 addUInt(MemberDie, dwarf::DW_AT_byte_size, 0, DT.getOriginalTypeSize()>>3);
1345 addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits());
1346
1347 uint64_t Offset = DT.getOffsetInBits();
1348 uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
1349 uint64_t HiMark = (Offset + FieldSize) & AlignMask;
1350 uint64_t FieldOffset = (HiMark - FieldSize);
1351 Offset -= FieldOffset;
1352
1353 // Maybe we need to work from the other end.
1354 if (Asm->getTargetData().isLittleEndian())
1355 Offset = FieldSize - (Offset + Size);
1356 addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
1357
1358 // Here WD_AT_data_member_location points to the anonymous
1359 // field that includes this bit field.
1360 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, FieldOffset >> 3);
1361
1362 } else
1363 // This is not a bitfield.
1364 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);
1365
1366 if (DT.getTag() == dwarf::DW_TAG_inheritance
1367 && DT.isVirtual()) {
1368
1369 // For C++, virtual base classes are not at fixed offset. Use following
1370 // expression to extract appropriate offset from vtable.
1371 // BaseAddr = ObAddr + *((*ObAddr) - Offset)
1372
1373 DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock();
1374 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
1375 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1376 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1377 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits());
1378 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
1379 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1380 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1381
1382 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0,
1383 VBaseLocationDie);
1384 } else
1385 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
1386
1387 if (DT.isProtected())
1388 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1389 dwarf::DW_ACCESS_protected);
1390 else if (DT.isPrivate())
1391 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1392 dwarf::DW_ACCESS_private);
1393 // Otherwise C++ member and base classes are considered public.
Devang Patel94c7ddb2011-08-16 22:09:43 +00001394 else
Devang Patel161b2f42011-04-12 23:21:44 +00001395 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1396 dwarf::DW_ACCESS_public);
1397 if (DT.isVirtual())
1398 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag,
1399 dwarf::DW_VIRTUALITY_virtual);
Devang Patele9db5e22011-04-16 00:11:51 +00001400
1401 // Objective-C properties.
1402 StringRef PropertyName = DT.getObjCPropertyName();
1403 if (!PropertyName.empty()) {
Nick Lewycky390c40d2011-10-27 06:44:11 +00001404 addString(MemberDie, dwarf::DW_AT_APPLE_property_name, PropertyName);
Devang Patele9db5e22011-04-16 00:11:51 +00001405 StringRef GetterName = DT.getObjCPropertyGetterName();
1406 if (!GetterName.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001407 addString(MemberDie, dwarf::DW_AT_APPLE_property_getter, GetterName);
Devang Patele9db5e22011-04-16 00:11:51 +00001408 StringRef SetterName = DT.getObjCPropertySetterName();
1409 if (!SetterName.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001410 addString(MemberDie, dwarf::DW_AT_APPLE_property_setter, SetterName);
Devang Patele9db5e22011-04-16 00:11:51 +00001411 unsigned PropertyAttributes = 0;
1412 if (DT.isReadOnlyObjCProperty())
1413 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readonly;
1414 if (DT.isReadWriteObjCProperty())
1415 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readwrite;
1416 if (DT.isAssignObjCProperty())
1417 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_assign;
1418 if (DT.isRetainObjCProperty())
1419 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_retain;
1420 if (DT.isCopyObjCProperty())
1421 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_copy;
1422 if (DT.isNonAtomicObjCProperty())
1423 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_nonatomic;
1424 if (PropertyAttributes)
1425 addUInt(MemberDie, dwarf::DW_AT_APPLE_property_attribute, 0,
1426 PropertyAttributes);
1427 }
Devang Patel161b2f42011-04-12 23:21:44 +00001428 return MemberDie;
1429}