blob: 1e5170949e67415e026d3201b2060ff1d2dc22c3 [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 }
Eric Christopher1b3f9192011-11-10 19:52:58 +0000608 // If this is a named finished type then include it in the list of types
609 // for the accelerator tables.
610 if (!Ty.getName().empty() && !Ty.isForwardDecl())
611 addAccelType(Ty.getName(), TyDIE);
612
Devang Patel161b2f42011-04-12 23:21:44 +0000613 addToContextOwner(TyDIE, Ty.getContext());
614 return TyDIE;
615}
616
617/// addType - Add a new type attribute to the specified entity.
618void CompileUnit::addType(DIE *Entity, DIType Ty) {
619 if (!Ty.Verify())
620 return;
621
622 // Check for pre-existence.
623 DIEEntry *Entry = getDIEEntry(Ty);
624 // If it exists then use the existing value.
625 if (Entry) {
626 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
627 return;
628 }
629
630 // Construct type.
631 DIE *Buffer = getOrCreateTypeDIE(Ty);
632
633 // Set up proxy.
634 Entry = createDIEEntry(Buffer);
635 insertDIEEntry(Ty, Entry);
Devang Patel161b2f42011-04-12 23:21:44 +0000636 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
Devang Patele9ae06c2011-05-31 22:56:51 +0000637
638 // If this is a complete composite type then include it in the
639 // list of global types.
Devang Patelc20bdf12011-06-01 00:23:24 +0000640 addGlobalType(Ty);
Devang Patel66658e42011-05-31 23:30:30 +0000641}
642
643/// addGlobalType - Add a new global type to the compile unit.
644///
Devang Patelc20bdf12011-06-01 00:23:24 +0000645void CompileUnit::addGlobalType(DIType Ty) {
Devang Patele9ae06c2011-05-31 22:56:51 +0000646 DIDescriptor Context = Ty.getContext();
647 if (Ty.isCompositeType() && !Ty.getName().empty() && !Ty.isForwardDecl()
Devang Patel94c7ddb2011-08-16 22:09:43 +0000648 && (!Context || Context.isCompileUnit() || Context.isFile()
649 || Context.isNameSpace()))
Devang Patelc20bdf12011-06-01 00:23:24 +0000650 if (DIEEntry *Entry = getDIEEntry(Ty))
651 GlobalTypes[Ty.getName()] = Entry->getEntry();
Devang Patel161b2f42011-04-12 23:21:44 +0000652}
653
Devang Patel31c5d052011-05-06 16:57:54 +0000654/// addPubTypes - Add type for pubtypes section.
655void CompileUnit::addPubTypes(DISubprogram SP) {
656 DICompositeType SPTy = SP.getType();
657 unsigned SPTag = SPTy.getTag();
658 if (SPTag != dwarf::DW_TAG_subroutine_type)
659 return;
660
661 DIArray Args = SPTy.getTypeArray();
662 for (unsigned i = 0, e = Args.getNumElements(); i != e; ++i) {
663 DIType ATy(Args.getElement(i));
664 if (!ATy.Verify())
665 continue;
Devang Patelc20bdf12011-06-01 00:23:24 +0000666 addGlobalType(ATy);
Devang Patel31c5d052011-05-06 16:57:54 +0000667 }
668}
669
Devang Patel161b2f42011-04-12 23:21:44 +0000670/// constructTypeDIE - Construct basic type die from DIBasicType.
671void CompileUnit::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
672 // Get core information.
673 StringRef Name = BTy.getName();
Devang Patel161b2f42011-04-12 23:21:44 +0000674 // Add name if not anonymous or intermediate type.
675 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000676 addString(&Buffer, dwarf::DW_AT_name, Name);
Devang Patel734a67c2011-09-14 23:13:28 +0000677
678 if (BTy.getTag() == dwarf::DW_TAG_unspecified_type) {
679 Buffer.setTag(dwarf::DW_TAG_unspecified_type);
680 // Unspecified types has only name, nothing else.
681 return;
682 }
683
684 Buffer.setTag(dwarf::DW_TAG_base_type);
Nick Lewycky746cb672011-10-26 22:55:33 +0000685 addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
Devang Patel734a67c2011-09-14 23:13:28 +0000686 BTy.getEncoding());
687
Devang Patel161b2f42011-04-12 23:21:44 +0000688 uint64_t Size = BTy.getSizeInBits() >> 3;
689 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
690}
691
692/// constructTypeDIE - Construct derived type die from DIDerivedType.
693void CompileUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
694 // Get core information.
695 StringRef Name = DTy.getName();
696 uint64_t Size = DTy.getSizeInBits() >> 3;
697 unsigned Tag = DTy.getTag();
698
699 // FIXME - Workaround for templates.
700 if (Tag == dwarf::DW_TAG_inheritance) Tag = dwarf::DW_TAG_reference_type;
701
702 Buffer.setTag(Tag);
703
704 // Map to main type, void will not have a type.
705 DIType FromTy = DTy.getTypeDerivedFrom();
706 addType(&Buffer, FromTy);
707
708 // Add name if not anonymous or intermediate type.
709 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000710 addString(&Buffer, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +0000711
712 // Add size if non-zero (derived types might be zero-sized.)
713 if (Size)
714 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
715
716 // Add source line info if available and TyDesc is not a forward declaration.
717 if (!DTy.isForwardDecl())
718 addSourceLine(&Buffer, DTy);
719}
720
721/// constructTypeDIE - Construct type DIE from DICompositeType.
722void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
723 // Get core information.
724 StringRef Name = CTy.getName();
725
726 uint64_t Size = CTy.getSizeInBits() >> 3;
727 unsigned Tag = CTy.getTag();
728 Buffer.setTag(Tag);
729
730 switch (Tag) {
731 case dwarf::DW_TAG_vector_type:
732 case dwarf::DW_TAG_array_type:
733 constructArrayTypeDIE(Buffer, &CTy);
734 break;
735 case dwarf::DW_TAG_enumeration_type: {
736 DIArray Elements = CTy.getTypeArray();
737
738 // Add enumerators to enumeration type.
739 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
740 DIE *ElemDie = NULL;
741 DIDescriptor Enum(Elements.getElement(i));
742 if (Enum.isEnumerator()) {
743 ElemDie = constructEnumTypeDIE(DIEnumerator(Enum));
744 Buffer.addChild(ElemDie);
745 }
746 }
747 }
748 break;
749 case dwarf::DW_TAG_subroutine_type: {
750 // Add return type.
751 DIArray Elements = CTy.getTypeArray();
752 DIDescriptor RTy = Elements.getElement(0);
753 addType(&Buffer, DIType(RTy));
754
755 bool isPrototyped = true;
756 // Add arguments.
757 for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
758 DIDescriptor Ty = Elements.getElement(i);
759 if (Ty.isUnspecifiedParameter()) {
760 DIE *Arg = new DIE(dwarf::DW_TAG_unspecified_parameters);
761 Buffer.addChild(Arg);
762 isPrototyped = false;
763 } else {
764 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
765 addType(Arg, DIType(Ty));
766 Buffer.addChild(Arg);
767 }
768 }
769 // Add prototype flag.
770 if (isPrototyped)
771 addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
772 }
773 break;
774 case dwarf::DW_TAG_structure_type:
775 case dwarf::DW_TAG_union_type:
776 case dwarf::DW_TAG_class_type: {
777 // Add elements to structure type.
778 DIArray Elements = CTy.getTypeArray();
779
780 // A forward struct declared type may not have elements available.
781 unsigned N = Elements.getNumElements();
782 if (N == 0)
783 break;
784
785 // Add elements to structure type.
786 for (unsigned i = 0; i < N; ++i) {
787 DIDescriptor Element = Elements.getElement(i);
788 DIE *ElemDie = NULL;
789 if (Element.isSubprogram()) {
790 DISubprogram SP(Element);
Devang Pateldbc64af2011-08-15 17:24:54 +0000791 ElemDie = getOrCreateSubprogramDIE(DISubprogram(Element));
Devang Patel161b2f42011-04-12 23:21:44 +0000792 if (SP.isProtected())
793 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
794 dwarf::DW_ACCESS_protected);
795 else if (SP.isPrivate())
796 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
797 dwarf::DW_ACCESS_private);
798 else
799 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
800 dwarf::DW_ACCESS_public);
801 if (SP.isExplicit())
802 addUInt(ElemDie, dwarf::DW_AT_explicit, dwarf::DW_FORM_flag, 1);
803 }
804 else if (Element.isVariable()) {
805 DIVariable DV(Element);
806 ElemDie = new DIE(dwarf::DW_TAG_variable);
Nick Lewycky390c40d2011-10-27 06:44:11 +0000807 addString(ElemDie, dwarf::DW_AT_name, DV.getName());
Devang Patel161b2f42011-04-12 23:21:44 +0000808 addType(ElemDie, DV.getType());
809 addUInt(ElemDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
810 addUInt(ElemDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
811 addSourceLine(ElemDie, DV);
812 } else if (Element.isDerivedType())
813 ElemDie = createMemberDIE(DIDerivedType(Element));
814 else
815 continue;
816 Buffer.addChild(ElemDie);
817 }
818
819 if (CTy.isAppleBlockExtension())
820 addUInt(&Buffer, dwarf::DW_AT_APPLE_block, dwarf::DW_FORM_flag, 1);
821
822 unsigned RLang = CTy.getRunTimeLang();
823 if (RLang)
824 addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class,
825 dwarf::DW_FORM_data1, RLang);
826
827 DICompositeType ContainingType = CTy.getContainingType();
828 if (DIDescriptor(ContainingType).isCompositeType())
829 addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
830 getOrCreateTypeDIE(DIType(ContainingType)));
831 else {
832 DIDescriptor Context = CTy.getContext();
833 addToContextOwner(&Buffer, Context);
834 }
835
Devang Patel201e6cd2011-05-12 21:29:42 +0000836 if (CTy.isObjcClassComplete())
837 addUInt(&Buffer, dwarf::DW_AT_APPLE_objc_complete_type,
Devang Patelb11f80e2011-05-12 19:06:16 +0000838 dwarf::DW_FORM_flag, 1);
839
Devang Patel161b2f42011-04-12 23:21:44 +0000840 if (Tag == dwarf::DW_TAG_class_type)
841 addTemplateParams(Buffer, CTy.getTemplateParams());
842
843 break;
844 }
845 default:
846 break;
847 }
848
849 // Add name if not anonymous or intermediate type.
850 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000851 addString(&Buffer, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +0000852
853 if (Tag == dwarf::DW_TAG_enumeration_type || Tag == dwarf::DW_TAG_class_type
854 || Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type)
Nick Lewycky746cb672011-10-26 22:55:33 +0000855 {
Devang Patel161b2f42011-04-12 23:21:44 +0000856 // Add size if non-zero (derived types might be zero-sized.)
857 if (Size)
858 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
859 else {
860 // Add zero size if it is not a forward declaration.
861 if (CTy.isForwardDecl())
862 addUInt(&Buffer, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
863 else
864 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, 0);
865 }
866
867 // Add source line info if available.
868 if (!CTy.isForwardDecl())
869 addSourceLine(&Buffer, CTy);
870 }
871}
872
873/// getOrCreateTemplateTypeParameterDIE - Find existing DIE or create new DIE
874/// for the given DITemplateTypeParameter.
875DIE *
876CompileUnit::getOrCreateTemplateTypeParameterDIE(DITemplateTypeParameter TP) {
877 DIE *ParamDIE = getDIE(TP);
878 if (ParamDIE)
879 return ParamDIE;
880
881 ParamDIE = new DIE(dwarf::DW_TAG_template_type_parameter);
882 addType(ParamDIE, TP.getType());
Nick Lewycky390c40d2011-10-27 06:44:11 +0000883 addString(ParamDIE, dwarf::DW_AT_name, TP.getName());
Devang Patel161b2f42011-04-12 23:21:44 +0000884 return ParamDIE;
885}
886
887/// getOrCreateTemplateValueParameterDIE - Find existing DIE or create new DIE
888/// for the given DITemplateValueParameter.
889DIE *
890CompileUnit::getOrCreateTemplateValueParameterDIE(DITemplateValueParameter TPV) {
891 DIE *ParamDIE = getDIE(TPV);
892 if (ParamDIE)
893 return ParamDIE;
894
895 ParamDIE = new DIE(dwarf::DW_TAG_template_value_parameter);
896 addType(ParamDIE, TPV.getType());
897 if (!TPV.getName().empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000898 addString(ParamDIE, dwarf::DW_AT_name, TPV.getName());
Devang Patel161b2f42011-04-12 23:21:44 +0000899 addUInt(ParamDIE, dwarf::DW_AT_const_value, dwarf::DW_FORM_udata,
900 TPV.getValue());
901 return ParamDIE;
902}
903
Devang Patel31c5d052011-05-06 16:57:54 +0000904/// getOrCreateNameSpace - Create a DIE for DINameSpace.
905DIE *CompileUnit::getOrCreateNameSpace(DINameSpace NS) {
906 DIE *NDie = getDIE(NS);
907 if (NDie)
908 return NDie;
909 NDie = new DIE(dwarf::DW_TAG_namespace);
910 insertDIE(NS, NDie);
Eric Christopher09ac3d82011-11-07 09:24:32 +0000911 if (!NS.getName().empty()) {
Nick Lewycky390c40d2011-10-27 06:44:11 +0000912 addString(NDie, dwarf::DW_AT_name, NS.getName());
Eric Christopher09ac3d82011-11-07 09:24:32 +0000913 addAccelNamespace(NS.getName(), NDie);
914 } else
915 addAccelNamespace("(anonymous namespace)", NDie);
Devang Patel31c5d052011-05-06 16:57:54 +0000916 addSourceLine(NDie, NS);
917 addToContextOwner(NDie, NS.getContext());
918 return NDie;
919}
920
Devang Pateldbc64af2011-08-15 17:24:54 +0000921/// getRealLinkageName - If special LLVM prefix that is used to inform the asm
922/// printer to not emit usual symbol prefix before the symbol name is used then
923/// return linkage name after skipping this special LLVM prefix.
924static StringRef getRealLinkageName(StringRef LinkageName) {
925 char One = '\1';
926 if (LinkageName.startswith(StringRef(&One, 1)))
927 return LinkageName.substr(1);
928 return LinkageName;
929}
930
931/// getOrCreateSubprogramDIE - Create new DIE using SP.
932DIE *CompileUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
933 DIE *SPDie = getDIE(SP);
934 if (SPDie)
935 return SPDie;
936
Rafael Espindola01b55b42011-11-10 22:34:29 +0000937 DISubprogram SPDecl = SP.getFunctionDeclaration();
938 DIE *DeclDie = NULL;
939 if (SPDecl.isSubprogram()) {
940 DeclDie = getOrCreateSubprogramDIE(SPDecl);
941 }
942
Devang Pateldbc64af2011-08-15 17:24:54 +0000943 SPDie = new DIE(dwarf::DW_TAG_subprogram);
944
945 // DW_TAG_inlined_subroutine may refer to this DIE.
946 insertDIE(SP, SPDie);
947
948 // Add to context owner.
949 addToContextOwner(SPDie, SP.getContext());
950
951 // Add function template parameters.
952 addTemplateParams(*SPDie, SP.getTemplateParams());
953
954 StringRef LinkageName = SP.getLinkageName();
955 if (!LinkageName.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000956 addString(SPDie, dwarf::DW_AT_MIPS_linkage_name,
Nick Lewycky746cb672011-10-26 22:55:33 +0000957 getRealLinkageName(LinkageName));
Devang Pateldbc64af2011-08-15 17:24:54 +0000958
959 // If this DIE is going to refer declaration info using AT_specification
960 // then there is no need to add other attributes.
Rafael Espindola01b55b42011-11-10 22:34:29 +0000961 if (DeclDie) {
962 // Refer function declaration directly.
963 addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
964 DeclDie);
965
Devang Pateldbc64af2011-08-15 17:24:54 +0000966 return SPDie;
Rafael Espindola01b55b42011-11-10 22:34:29 +0000967 }
Devang Pateldbc64af2011-08-15 17:24:54 +0000968
969 // Constructors and operators for anonymous aggregates do not have names.
970 if (!SP.getName().empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000971 addString(SPDie, dwarf::DW_AT_name, SP.getName());
Devang Pateldbc64af2011-08-15 17:24:54 +0000972
973 addSourceLine(SPDie, SP);
974
975 if (SP.isPrototyped())
976 addUInt(SPDie, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
977
978 // Add Return Type.
979 DICompositeType SPTy = SP.getType();
980 DIArray Args = SPTy.getTypeArray();
981 unsigned SPTag = SPTy.getTag();
982
983 if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type)
984 addType(SPDie, SPTy);
985 else
986 addType(SPDie, DIType(Args.getElement(0)));
987
988 unsigned VK = SP.getVirtuality();
989 if (VK) {
990 addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK);
991 DIEBlock *Block = getDIEBlock();
992 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
993 addUInt(Block, 0, dwarf::DW_FORM_udata, SP.getVirtualIndex());
994 addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
995 ContainingTypeMap.insert(std::make_pair(SPDie,
996 SP.getContainingType()));
997 }
998
999 if (!SP.isDefinition()) {
1000 addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
1001
1002 // Add arguments. Do not add arguments for subprogram definition. They will
1003 // be handled while processing variables.
1004 DICompositeType SPTy = SP.getType();
1005 DIArray Args = SPTy.getTypeArray();
1006 unsigned SPTag = SPTy.getTag();
1007
1008 if (SPTag == dwarf::DW_TAG_subroutine_type)
1009 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
1010 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
1011 DIType ATy = DIType(DIType(Args.getElement(i)));
1012 addType(Arg, ATy);
1013 if (ATy.isArtificial())
1014 addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
1015 SPDie->addChild(Arg);
1016 }
1017 }
1018
1019 if (SP.isArtificial())
1020 addUInt(SPDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
1021
1022 if (!SP.isLocalToUnit())
1023 addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
1024
1025 if (SP.isOptimized())
1026 addUInt(SPDie, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1);
1027
1028 if (unsigned isa = Asm->getISAEncoding()) {
1029 addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa);
1030 }
1031
1032 return SPDie;
1033}
1034
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001035// Return const expression if value is a GEP to access merged global
1036// constant. e.g.
1037// i8* getelementptr ({ i8, i8, i8, i8 }* @_MergedGlobals, i32 0, i32 0)
1038static const ConstantExpr *getMergedGlobalExpr(const Value *V) {
1039 const ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(V);
1040 if (!CE || CE->getNumOperands() != 3 ||
1041 CE->getOpcode() != Instruction::GetElementPtr)
1042 return NULL;
1043
1044 // First operand points to a global struct.
1045 Value *Ptr = CE->getOperand(0);
1046 if (!isa<GlobalValue>(Ptr) ||
1047 !isa<StructType>(cast<PointerType>(Ptr->getType())->getElementType()))
1048 return NULL;
1049
1050 // Second operand is zero.
1051 const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CE->getOperand(1));
1052 if (!CI || !CI->isZero())
1053 return NULL;
1054
1055 // Third operand is offset.
1056 if (!isa<ConstantInt>(CE->getOperand(2)))
1057 return NULL;
1058
1059 return CE;
1060}
1061
1062/// createGlobalVariableDIE - create global variable DIE.
1063void CompileUnit::createGlobalVariableDIE(const MDNode *N) {
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001064 // Check for pre-existence.
Devang Patel49e2f032011-08-18 22:21:50 +00001065 if (getDIE(N))
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001066 return;
1067
Devang Patel49e2f032011-08-18 22:21:50 +00001068 DIGlobalVariable GV(N);
Devang Patel28bea082011-08-18 23:17:55 +00001069 if (!GV.Verify())
1070 return;
1071
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001072 DIE *VariableDIE = new DIE(GV.getTag());
Devang Patel49e2f032011-08-18 22:21:50 +00001073 // Add to map.
1074 insertDIE(N, VariableDIE);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001075
1076 // Add name.
Nick Lewycky390c40d2011-10-27 06:44:11 +00001077 addString(VariableDIE, dwarf::DW_AT_name, GV.getDisplayName());
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001078 StringRef LinkageName = GV.getLinkageName();
Devang Patel49e2f032011-08-18 22:21:50 +00001079 bool isGlobalVariable = GV.getGlobal() != NULL;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001080 if (!LinkageName.empty() && isGlobalVariable)
Nick Lewycky746cb672011-10-26 22:55:33 +00001081 addString(VariableDIE, dwarf::DW_AT_MIPS_linkage_name,
Nick Lewycky390c40d2011-10-27 06:44:11 +00001082 getRealLinkageName(LinkageName));
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001083 // Add type.
Devang Patel49e2f032011-08-18 22:21:50 +00001084 DIType GTy = GV.getType();
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001085 addType(VariableDIE, GTy);
1086
1087 // Add scoping info.
Eric Christopherdfa30e12011-11-09 05:24:07 +00001088 if (!GV.isLocalToUnit())
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001089 addUInt(VariableDIE, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
Eric Christopherdfa30e12011-11-09 05:24:07 +00001090
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001091 // Add line number info.
1092 addSourceLine(VariableDIE, GV);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001093 // Add to context owner.
1094 DIDescriptor GVContext = GV.getContext();
1095 addToContextOwner(VariableDIE, GVContext);
1096 // Add location.
Eric Christopher09ac3d82011-11-07 09:24:32 +00001097 bool addToAccelTable = false;
Eric Christopherd117fbb2011-11-11 01:55:22 +00001098 DIE *VariableSpecDIE;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001099 if (isGlobalVariable) {
Eric Christopher09ac3d82011-11-07 09:24:32 +00001100 addToAccelTable = true;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001101 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
1102 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
1103 addLabel(Block, 0, dwarf::DW_FORM_udata,
1104 Asm->Mang->getSymbol(GV.getGlobal()));
1105 // Do not create specification DIE if context is either compile unit
1106 // or a subprogram.
Devang Patel1dd4e562011-09-21 23:41:11 +00001107 if (GVContext && GV.isDefinition() && !GVContext.isCompileUnit() &&
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001108 !GVContext.isFile() && !isSubprogramContext(GVContext)) {
1109 // Create specification DIE.
Eric Christopherd117fbb2011-11-11 01:55:22 +00001110 VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001111 addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
1112 dwarf::DW_FORM_ref4, VariableDIE);
1113 addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
1114 addUInt(VariableDIE, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag,
1115 1);
1116 addDie(VariableSpecDIE);
1117 } else {
1118 addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
Eric Christopher09ac3d82011-11-07 09:24:32 +00001119 }
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001120 } else if (const ConstantInt *CI =
1121 dyn_cast_or_null<ConstantInt>(GV.getConstant()))
1122 addConstantValue(VariableDIE, CI, GTy.isUnsignedDIType());
1123 else if (const ConstantExpr *CE = getMergedGlobalExpr(N->getOperand(11))) {
Eric Christopher09ac3d82011-11-07 09:24:32 +00001124 addToAccelTable = true;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001125 // GV is a merged global.
1126 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
1127 Value *Ptr = CE->getOperand(0);
1128 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
1129 addLabel(Block, 0, dwarf::DW_FORM_udata,
1130 Asm->Mang->getSymbol(cast<GlobalValue>(Ptr)));
1131 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1132 SmallVector<Value*, 3> Idx(CE->op_begin()+1, CE->op_end());
1133 addUInt(Block, 0, dwarf::DW_FORM_udata,
1134 Asm->getTargetData().getIndexedOffset(Ptr->getType(), Idx));
1135 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1136 addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
1137 }
1138
Eric Christopherd117fbb2011-11-11 01:55:22 +00001139 if (addToAccelTable) {
1140 DIE *AddrDIE = VariableSpecDIE ? VariableSpecDIE : VariableDIE;
1141 addAccelName(GV.getName(), AddrDIE);
Eric Christopher09ac3d82011-11-07 09:24:32 +00001142
Eric Christopherd117fbb2011-11-11 01:55:22 +00001143 // If the linkage name is different than the name, go ahead and output
1144 // that as well into the name table.
1145 if (GV.getLinkageName() != "" && GV.getName() != GV.getLinkageName())
1146 addAccelName(GV.getLinkageName(), AddrDIE);
1147 }
Eric Christopher74d8a872011-11-08 21:56:23 +00001148
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001149 return;
1150}
1151
Devang Patel161b2f42011-04-12 23:21:44 +00001152/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
1153void CompileUnit::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){
1154 DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type);
1155 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IndexTy);
1156 int64_t L = SR.getLo();
1157 int64_t H = SR.getHi();
1158
1159 // The L value defines the lower bounds which is typically zero for C/C++. The
1160 // H value is the upper bounds. Values are 64 bit. H - L + 1 is the size
1161 // of the array. If L > H then do not emit DW_AT_lower_bound and
1162 // DW_AT_upper_bound attributes. If L is zero and H is also zero then the
1163 // array has one element and in such case do not emit lower bound.
1164
1165 if (L > H) {
1166 Buffer.addChild(DW_Subrange);
1167 return;
1168 }
1169 if (L)
1170 addSInt(DW_Subrange, dwarf::DW_AT_lower_bound, 0, L);
1171 addSInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, H);
1172 Buffer.addChild(DW_Subrange);
1173}
1174
1175/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
1176void CompileUnit::constructArrayTypeDIE(DIE &Buffer,
1177 DICompositeType *CTy) {
1178 Buffer.setTag(dwarf::DW_TAG_array_type);
1179 if (CTy->getTag() == dwarf::DW_TAG_vector_type)
1180 addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1);
1181
1182 // Emit derived type.
1183 addType(&Buffer, CTy->getTypeDerivedFrom());
1184 DIArray Elements = CTy->getTypeArray();
1185
1186 // Get an anonymous type for index type.
1187 DIE *IdxTy = getIndexTyDie();
1188 if (!IdxTy) {
1189 // Construct an anonymous type for index type.
1190 IdxTy = new DIE(dwarf::DW_TAG_base_type);
1191 addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t));
1192 addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
1193 dwarf::DW_ATE_signed);
1194 addDie(IdxTy);
1195 setIndexTyDie(IdxTy);
1196 }
1197
1198 // Add subranges to array type.
1199 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
1200 DIDescriptor Element = Elements.getElement(i);
1201 if (Element.getTag() == dwarf::DW_TAG_subrange_type)
1202 constructSubrangeDIE(Buffer, DISubrange(Element), IdxTy);
1203 }
1204}
1205
1206/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
1207DIE *CompileUnit::constructEnumTypeDIE(DIEnumerator ETy) {
1208 DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator);
1209 StringRef Name = ETy.getName();
Nick Lewycky390c40d2011-10-27 06:44:11 +00001210 addString(Enumerator, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +00001211 int64_t Value = ETy.getEnumValue();
1212 addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value);
1213 return Enumerator;
1214}
1215
Devang Pateldbc64af2011-08-15 17:24:54 +00001216/// constructContainingTypeDIEs - Construct DIEs for types that contain
1217/// vtables.
1218void CompileUnit::constructContainingTypeDIEs() {
1219 for (DenseMap<DIE *, const MDNode *>::iterator CI = ContainingTypeMap.begin(),
1220 CE = ContainingTypeMap.end(); CI != CE; ++CI) {
1221 DIE *SPDie = CI->first;
1222 const MDNode *N = CI->second;
1223 if (!N) continue;
1224 DIE *NDie = getDIE(N);
1225 if (!NDie) continue;
1226 addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
1227 }
1228}
1229
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001230/// constructVariableDIE - Construct a DIE for the given DbgVariable.
1231DIE *CompileUnit::constructVariableDIE(DbgVariable *DV, bool isScopeAbstract) {
1232 StringRef Name = DV->getName();
1233 if (Name.empty())
1234 return NULL;
1235
1236 // Translate tag to proper Dwarf tag.
1237 unsigned Tag = DV->getTag();
1238
1239 // Define variable debug information entry.
1240 DIE *VariableDie = new DIE(Tag);
1241 DbgVariable *AbsVar = DV->getAbstractVariable();
1242 DIE *AbsDIE = AbsVar ? AbsVar->getDIE() : NULL;
1243 if (AbsDIE)
1244 addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin,
1245 dwarf::DW_FORM_ref4, AbsDIE);
1246 else {
Nick Lewycky390c40d2011-10-27 06:44:11 +00001247 addString(VariableDie, dwarf::DW_AT_name, Name);
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001248 addSourceLine(VariableDie, DV->getVariable());
1249 addType(VariableDie, DV->getType());
1250 }
1251
1252 if (DV->isArtificial())
1253 addUInt(VariableDie, dwarf::DW_AT_artificial,
1254 dwarf::DW_FORM_flag, 1);
1255
1256 if (isScopeAbstract) {
1257 DV->setDIE(VariableDie);
1258 return VariableDie;
1259 }
1260
1261 // Add variable address.
1262
1263 unsigned Offset = DV->getDotDebugLocOffset();
1264 if (Offset != ~0U) {
1265 addLabel(VariableDie, dwarf::DW_AT_location,
1266 dwarf::DW_FORM_data4,
1267 Asm->GetTempSymbol("debug_loc", Offset));
1268 DV->setDIE(VariableDie);
1269 return VariableDie;
1270 }
1271
Eric Christopher8cf5e742011-10-03 15:49:20 +00001272 // Check if variable is described by a DBG_VALUE instruction.
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001273 if (const MachineInstr *DVInsn = DV->getMInsn()) {
1274 bool updated = false;
1275 if (DVInsn->getNumOperands() == 3) {
1276 if (DVInsn->getOperand(0).isReg()) {
1277 const MachineOperand RegOp = DVInsn->getOperand(0);
1278 const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
1279 if (DVInsn->getOperand(1).isImm() &&
1280 TRI->getFrameRegister(*Asm->MF) == RegOp.getReg()) {
1281 unsigned FrameReg = 0;
1282 const TargetFrameLowering *TFI = Asm->TM.getFrameLowering();
1283 int Offset =
1284 TFI->getFrameIndexReference(*Asm->MF,
1285 DVInsn->getOperand(1).getImm(),
1286 FrameReg);
1287 MachineLocation Location(FrameReg, Offset);
1288 addVariableAddress(DV, VariableDie, Location);
1289
1290 } else if (RegOp.getReg())
1291 addVariableAddress(DV, VariableDie,
1292 MachineLocation(RegOp.getReg()));
1293 updated = true;
1294 }
1295 else if (DVInsn->getOperand(0).isImm())
1296 updated =
1297 addConstantValue(VariableDie, DVInsn->getOperand(0),
1298 DV->getType());
1299 else if (DVInsn->getOperand(0).isFPImm())
1300 updated =
1301 addConstantFPValue(VariableDie, DVInsn->getOperand(0));
1302 else if (DVInsn->getOperand(0).isCImm())
1303 updated =
1304 addConstantValue(VariableDie,
1305 DVInsn->getOperand(0).getCImm(),
1306 DV->getType().isUnsignedDIType());
1307 } else {
1308 addVariableAddress(DV, VariableDie,
1309 Asm->getDebugValueLocation(DVInsn));
1310 updated = true;
1311 }
1312 if (!updated) {
1313 // If variableDie is not updated then DBG_VALUE instruction does not
1314 // have valid variable info.
1315 delete VariableDie;
1316 return NULL;
1317 }
1318 DV->setDIE(VariableDie);
1319 return VariableDie;
1320 } else {
1321 // .. else use frame index.
1322 int FI = DV->getFrameIndex();
1323 if (FI != ~0) {
1324 unsigned FrameReg = 0;
1325 const TargetFrameLowering *TFI = Asm->TM.getFrameLowering();
1326 int Offset =
1327 TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg);
1328 MachineLocation Location(FrameReg, Offset);
1329 addVariableAddress(DV, VariableDie, Location);
1330 }
1331 }
1332
1333 DV->setDIE(VariableDie);
1334 return VariableDie;
1335}
1336
Devang Patel161b2f42011-04-12 23:21:44 +00001337/// createMemberDIE - Create new member DIE.
1338DIE *CompileUnit::createMemberDIE(DIDerivedType DT) {
1339 DIE *MemberDie = new DIE(DT.getTag());
1340 StringRef Name = DT.getName();
1341 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001342 addString(MemberDie, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +00001343
1344 addType(MemberDie, DT.getTypeDerivedFrom());
1345
1346 addSourceLine(MemberDie, DT);
1347
1348 DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
1349 addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
1350
1351 uint64_t Size = DT.getSizeInBits();
1352 uint64_t FieldSize = DT.getOriginalTypeSize();
1353
1354 if (Size != FieldSize) {
1355 // Handle bitfield.
1356 addUInt(MemberDie, dwarf::DW_AT_byte_size, 0, DT.getOriginalTypeSize()>>3);
1357 addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits());
1358
1359 uint64_t Offset = DT.getOffsetInBits();
1360 uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
1361 uint64_t HiMark = (Offset + FieldSize) & AlignMask;
1362 uint64_t FieldOffset = (HiMark - FieldSize);
1363 Offset -= FieldOffset;
1364
1365 // Maybe we need to work from the other end.
1366 if (Asm->getTargetData().isLittleEndian())
1367 Offset = FieldSize - (Offset + Size);
1368 addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
1369
1370 // Here WD_AT_data_member_location points to the anonymous
1371 // field that includes this bit field.
1372 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, FieldOffset >> 3);
1373
1374 } else
1375 // This is not a bitfield.
1376 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);
1377
1378 if (DT.getTag() == dwarf::DW_TAG_inheritance
1379 && DT.isVirtual()) {
1380
1381 // For C++, virtual base classes are not at fixed offset. Use following
1382 // expression to extract appropriate offset from vtable.
1383 // BaseAddr = ObAddr + *((*ObAddr) - Offset)
1384
1385 DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock();
1386 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
1387 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1388 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1389 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits());
1390 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
1391 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1392 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1393
1394 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0,
1395 VBaseLocationDie);
1396 } else
1397 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
1398
1399 if (DT.isProtected())
1400 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1401 dwarf::DW_ACCESS_protected);
1402 else if (DT.isPrivate())
1403 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1404 dwarf::DW_ACCESS_private);
1405 // Otherwise C++ member and base classes are considered public.
Devang Patel94c7ddb2011-08-16 22:09:43 +00001406 else
Devang Patel161b2f42011-04-12 23:21:44 +00001407 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1408 dwarf::DW_ACCESS_public);
1409 if (DT.isVirtual())
1410 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag,
1411 dwarf::DW_VIRTUALITY_virtual);
Devang Patele9db5e22011-04-16 00:11:51 +00001412
1413 // Objective-C properties.
1414 StringRef PropertyName = DT.getObjCPropertyName();
1415 if (!PropertyName.empty()) {
Nick Lewycky390c40d2011-10-27 06:44:11 +00001416 addString(MemberDie, dwarf::DW_AT_APPLE_property_name, PropertyName);
Devang Patele9db5e22011-04-16 00:11:51 +00001417 StringRef GetterName = DT.getObjCPropertyGetterName();
1418 if (!GetterName.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001419 addString(MemberDie, dwarf::DW_AT_APPLE_property_getter, GetterName);
Devang Patele9db5e22011-04-16 00:11:51 +00001420 StringRef SetterName = DT.getObjCPropertySetterName();
1421 if (!SetterName.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001422 addString(MemberDie, dwarf::DW_AT_APPLE_property_setter, SetterName);
Devang Patele9db5e22011-04-16 00:11:51 +00001423 unsigned PropertyAttributes = 0;
1424 if (DT.isReadOnlyObjCProperty())
1425 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readonly;
1426 if (DT.isReadWriteObjCProperty())
1427 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readwrite;
1428 if (DT.isAssignObjCProperty())
1429 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_assign;
1430 if (DT.isRetainObjCProperty())
1431 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_retain;
1432 if (DT.isCopyObjCProperty())
1433 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_copy;
1434 if (DT.isNonAtomicObjCProperty())
1435 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_nonatomic;
1436 if (PropertyAttributes)
1437 addUInt(MemberDie, dwarf::DW_AT_APPLE_property_attribute, 0,
1438 PropertyAttributes);
1439 }
Devang Patel161b2f42011-04-12 23:21:44 +00001440 return MemberDie;
1441}