blob: 21cceaf7c3ca165e30807879a51bace4bb1a86bb [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//
Eric Christopher443c9ed2012-08-14 05:13:29 +000010// This file contains support for constructing a dwarf compile unit.
Devang Patel161b2f42011-04-12 23:21:44 +000011//
12//===----------------------------------------------------------------------===//
13
14#define DEBUG_TYPE "dwarfdebug"
15
16#include "DwarfCompileUnit.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000017#include "DwarfAccelTable.h"
Devang Patel161b2f42011-04-12 23:21:44 +000018#include "DwarfDebug.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000019#include "llvm/ADT/APFloat.h"
Bill Wendling16eeb6f2012-06-29 08:32:07 +000020#include "llvm/DIBuilder.h"
Chandler Carruth0b8c9a82013-01-02 11:36:10 +000021#include "llvm/IR/Constants.h"
22#include "llvm/IR/DataLayout.h"
23#include "llvm/IR/GlobalVariable.h"
24#include "llvm/IR/Instructions.h"
Eric Christopherd61c34b2011-11-11 03:16:32 +000025#include "llvm/Support/Debug.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000026#include "llvm/Support/ErrorHandling.h"
Devang Patel6f9d8ff2011-08-15 17:57:41 +000027#include "llvm/Target/Mangler.h"
Devang Patel161b2f42011-04-12 23:21:44 +000028#include "llvm/Target/TargetFrameLowering.h"
29#include "llvm/Target/TargetMachine.h"
30#include "llvm/Target/TargetRegisterInfo.h"
Devang Patel161b2f42011-04-12 23:21:44 +000031
32using namespace llvm;
33
34/// CompileUnit - Compile unit constructor.
Eli Benderskyd4a05e02012-12-03 18:45:45 +000035CompileUnit::CompileUnit(unsigned UID, unsigned L, DIE *D, AsmPrinter *A,
Eric Christopher2e5d8702012-12-20 21:58:36 +000036 DwarfDebug *DW, DwarfUnits *DWU)
37 : UniqueID(UID), Language(L), CUDie(D), Asm(A), DD(DW), DU(DWU),
38 IndexTyDie(0) {
Devang Patel161b2f42011-04-12 23:21:44 +000039 DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1);
40}
41
42/// ~CompileUnit - Destructor for compile unit.
43CompileUnit::~CompileUnit() {
44 for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
45 DIEBlocks[j]->~DIEBlock();
46}
47
48/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug
49/// information entry.
50DIEEntry *CompileUnit::createDIEEntry(DIE *Entry) {
51 DIEEntry *Value = new (DIEValueAllocator) DIEEntry(Entry);
52 return Value;
53}
54
Bill Wendling6afe4782012-12-06 07:55:19 +000055/// getDefaultLowerBound - Return the default lower bound for an array. If the
Bill Wendling222c2fd2012-12-06 07:38:10 +000056/// DWARF version doesn't handle the language, return -1.
Bill Wendling6afe4782012-12-06 07:55:19 +000057int64_t CompileUnit::getDefaultLowerBound() const {
Bill Wendling222c2fd2012-12-06 07:38:10 +000058 switch (Language) {
59 default:
60 break;
61
62 case dwarf::DW_LANG_C89:
63 case dwarf::DW_LANG_C99:
64 case dwarf::DW_LANG_C:
65 case dwarf::DW_LANG_C_plus_plus:
66 case dwarf::DW_LANG_ObjC:
67 case dwarf::DW_LANG_ObjC_plus_plus:
68 return 0;
69
70 case dwarf::DW_LANG_Fortran77:
71 case dwarf::DW_LANG_Fortran90:
72 case dwarf::DW_LANG_Fortran95:
73 return 1;
74
75 // The languages below have valid values only if the DWARF version >= 4.
76 case dwarf::DW_LANG_Java:
77 case dwarf::DW_LANG_Python:
78 case dwarf::DW_LANG_UPC:
79 case dwarf::DW_LANG_D:
80 if (dwarf::DWARF_VERSION >= 4)
81 return 0;
82 break;
83
84 case dwarf::DW_LANG_Ada83:
85 case dwarf::DW_LANG_Ada95:
86 case dwarf::DW_LANG_Cobol74:
87 case dwarf::DW_LANG_Cobol85:
88 case dwarf::DW_LANG_Modula2:
89 case dwarf::DW_LANG_Pascal83:
90 case dwarf::DW_LANG_PLI:
91 if (dwarf::DWARF_VERSION >= 4)
92 return 1;
93 break;
94 }
95
96 return -1;
97}
98
Eric Christopher873cf0a2012-08-24 01:14:27 +000099/// addFlag - Add a flag that is true.
100void CompileUnit::addFlag(DIE *Die, unsigned Attribute) {
101 if (!DD->useDarwinGDBCompat())
102 Die->addValue(Attribute, dwarf::DW_FORM_flag_present,
103 DIEIntegerOne);
104 else
105 addUInt(Die, Attribute, dwarf::DW_FORM_flag, 1);
106}
107
Devang Patel161b2f42011-04-12 23:21:44 +0000108/// addUInt - Add an unsigned integer attribute data and value.
109///
110void CompileUnit::addUInt(DIE *Die, unsigned Attribute,
111 unsigned Form, uint64_t Integer) {
112 if (!Form) Form = DIEInteger::BestForm(false, Integer);
113 DIEValue *Value = Integer == 1 ?
114 DIEIntegerOne : new (DIEValueAllocator) DIEInteger(Integer);
115 Die->addValue(Attribute, Form, Value);
116}
117
118/// addSInt - Add an signed integer attribute data and value.
119///
120void CompileUnit::addSInt(DIE *Die, unsigned Attribute,
121 unsigned Form, int64_t Integer) {
122 if (!Form) Form = DIEInteger::BestForm(true, Integer);
123 DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
124 Die->addValue(Attribute, Form, Value);
125}
126
Nick Lewycky6a7efcf2011-10-28 05:29:47 +0000127/// addString - Add a string attribute data and value. We always emit a
128/// reference to the string pool instead of immediate strings so that DIEs have
Eric Christopher3cc42202013-01-07 19:32:45 +0000129/// more predictable sizes. In the case of split dwarf we emit an index
130/// into another table which gets us the static offset into the string
131/// table.
Nick Lewycky390c40d2011-10-27 06:44:11 +0000132void CompileUnit::addString(DIE *Die, unsigned Attribute, StringRef String) {
Eric Christopherdd8e9f32013-01-07 19:32:41 +0000133 if (!DD->useSplitDwarf()) {
134 MCSymbol *Symb = DU->getStringPoolEntry(String);
135 DIEValue *Value;
136 if (Asm->needsRelocationsForDwarfStringPool())
137 Value = new (DIEValueAllocator) DIELabel(Symb);
138 else {
139 MCSymbol *StringPool = DU->getStringPoolSym();
140 Value = new (DIEValueAllocator) DIEDelta(Symb, StringPool);
141 }
142 Die->addValue(Attribute, dwarf::DW_FORM_strp, Value);
143 } else {
144 unsigned idx = DU->getStringPoolIndex(String);
145 DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx);
146 Die->addValue(Attribute, dwarf::DW_FORM_GNU_str_index, Value);
147 }
148}
149
150/// addLocalString - Add a string attribute data and value. This is guaranteed
151/// to be in the local string pool instead of indirected.
152void CompileUnit::addLocalString(DIE *Die, unsigned Attribute,
153 StringRef String) {
Eric Christopher2e5d8702012-12-20 21:58:36 +0000154 MCSymbol *Symb = DU->getStringPoolEntry(String);
Nick Lewycky6a7efcf2011-10-28 05:29:47 +0000155 DIEValue *Value;
156 if (Asm->needsRelocationsForDwarfStringPool())
157 Value = new (DIEValueAllocator) DIELabel(Symb);
158 else {
Eric Christopher2e5d8702012-12-20 21:58:36 +0000159 MCSymbol *StringPool = DU->getStringPoolSym();
Nick Lewycky6a7efcf2011-10-28 05:29:47 +0000160 Value = new (DIEValueAllocator) DIEDelta(Symb, StringPool);
Nick Lewycky390c40d2011-10-27 06:44:11 +0000161 }
Nick Lewycky6a7efcf2011-10-28 05:29:47 +0000162 Die->addValue(Attribute, dwarf::DW_FORM_strp, Value);
Devang Patel161b2f42011-04-12 23:21:44 +0000163}
164
165/// addLabel - Add a Dwarf label attribute data and value.
166///
167void CompileUnit::addLabel(DIE *Die, unsigned Attribute, unsigned Form,
168 const MCSymbol *Label) {
169 DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
170 Die->addValue(Attribute, Form, Value);
171}
172
173/// addDelta - Add a label delta attribute data and value.
174///
175void CompileUnit::addDelta(DIE *Die, unsigned Attribute, unsigned Form,
176 const MCSymbol *Hi, const MCSymbol *Lo) {
177 DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo);
178 Die->addValue(Attribute, Form, Value);
179}
180
181/// addDIEEntry - Add a DIE attribute data and value.
182///
183void CompileUnit::addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form,
184 DIE *Entry) {
185 Die->addValue(Attribute, Form, createDIEEntry(Entry));
186}
187
Devang Patel161b2f42011-04-12 23:21:44 +0000188/// addBlock - Add block data.
189///
190void CompileUnit::addBlock(DIE *Die, unsigned Attribute, unsigned Form,
191 DIEBlock *Block) {
192 Block->ComputeSize(Asm);
193 DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.
194 Die->addValue(Attribute, Block->BestForm(), Block);
195}
196
197/// addSourceLine - Add location information to specified debug information
198/// entry.
199void CompileUnit::addSourceLine(DIE *Die, DIVariable V) {
200 // Verify variable.
201 if (!V.Verify())
202 return;
Eric Christopher8b4310b2012-11-21 00:34:38 +0000203
Devang Patel161b2f42011-04-12 23:21:44 +0000204 unsigned Line = V.getLineNumber();
205 if (Line == 0)
206 return;
Eric Christopher7ee5f5d2012-11-21 00:34:35 +0000207 unsigned FileID = DD->getOrCreateSourceID(V.getContext().getFilename(),
Devang Patel161b2f42011-04-12 23:21:44 +0000208 V.getContext().getDirectory());
209 assert(FileID && "Invalid file id");
210 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
211 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
212}
213
214/// addSourceLine - Add location information to specified debug information
215/// entry.
216void CompileUnit::addSourceLine(DIE *Die, DIGlobalVariable G) {
217 // Verify global variable.
218 if (!G.Verify())
219 return;
220
221 unsigned Line = G.getLineNumber();
222 if (Line == 0)
223 return;
Eric Christopher7ee5f5d2012-11-21 00:34:35 +0000224 unsigned FileID = DD->getOrCreateSourceID(G.getFilename(), G.getDirectory());
Devang Patel161b2f42011-04-12 23:21:44 +0000225 assert(FileID && "Invalid file id");
226 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
227 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
228}
229
230/// addSourceLine - Add location information to specified debug information
231/// entry.
232void CompileUnit::addSourceLine(DIE *Die, DISubprogram SP) {
233 // Verify subprogram.
234 if (!SP.Verify())
235 return;
Eric Christopher2125d5a2012-03-15 23:55:40 +0000236
Devang Patel161b2f42011-04-12 23:21:44 +0000237 // If the line number is 0, don't add it.
Eric Christopher2125d5a2012-03-15 23:55:40 +0000238 unsigned Line = SP.getLineNumber();
239 if (Line == 0)
Devang Patel161b2f42011-04-12 23:21:44 +0000240 return;
241
Eric Christopher7ee5f5d2012-11-21 00:34:35 +0000242 unsigned FileID = DD->getOrCreateSourceID(SP.getFilename(),
Nick Lewycky746cb672011-10-26 22:55:33 +0000243 SP.getDirectory());
Devang Patel161b2f42011-04-12 23:21:44 +0000244 assert(FileID && "Invalid file id");
245 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
246 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
247}
248
249/// addSourceLine - Add location information to specified debug information
250/// entry.
251void CompileUnit::addSourceLine(DIE *Die, DIType Ty) {
252 // Verify type.
253 if (!Ty.Verify())
254 return;
255
256 unsigned Line = Ty.getLineNumber();
Eric Christopher2125d5a2012-03-15 23:55:40 +0000257 if (Line == 0)
Devang Patel161b2f42011-04-12 23:21:44 +0000258 return;
Eric Christopher7ee5f5d2012-11-21 00:34:35 +0000259 unsigned FileID = DD->getOrCreateSourceID(Ty.getFilename(),
Nick Lewycky746cb672011-10-26 22:55:33 +0000260 Ty.getDirectory());
Devang Patel161b2f42011-04-12 23:21:44 +0000261 assert(FileID && "Invalid file id");
262 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
263 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
264}
265
266/// addSourceLine - Add location information to specified debug information
267/// entry.
Eric Christopherb8ca9882012-03-29 08:42:56 +0000268void CompileUnit::addSourceLine(DIE *Die, DIObjCProperty Ty) {
269 // Verify type.
270 if (!Ty.Verify())
271 return;
272
273 unsigned Line = Ty.getLineNumber();
274 if (Line == 0)
275 return;
276 DIFile File = Ty.getFile();
Eric Christopher7ee5f5d2012-11-21 00:34:35 +0000277 unsigned FileID = DD->getOrCreateSourceID(File.getFilename(),
Eric Christopher4d069bf2012-05-22 18:45:24 +0000278 File.getDirectory());
Eric Christopherb8ca9882012-03-29 08:42:56 +0000279 assert(FileID && "Invalid file id");
280 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
281 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
282}
283
284/// addSourceLine - Add location information to specified debug information
285/// entry.
Devang Patel161b2f42011-04-12 23:21:44 +0000286void CompileUnit::addSourceLine(DIE *Die, DINameSpace NS) {
287 // Verify namespace.
288 if (!NS.Verify())
289 return;
290
291 unsigned Line = NS.getLineNumber();
292 if (Line == 0)
293 return;
294 StringRef FN = NS.getFilename();
295
Eric Christopher7ee5f5d2012-11-21 00:34:35 +0000296 unsigned FileID = DD->getOrCreateSourceID(FN, NS.getDirectory());
Devang Patel161b2f42011-04-12 23:21:44 +0000297 assert(FileID && "Invalid file id");
298 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
299 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
300}
301
Eric Christopher8b4310b2012-11-21 00:34:38 +0000302/// addVariableAddress - Add DW_AT_location attribute for a
Devang Patele1cdf842011-04-27 22:45:24 +0000303/// DbgVariable based on provided MachineLocation.
Eric Christopher8b4310b2012-11-21 00:34:38 +0000304void CompileUnit::addVariableAddress(DbgVariable *&DV, DIE *Die,
Devang Patele1cdf842011-04-27 22:45:24 +0000305 MachineLocation Location) {
Devang Patel161b2f42011-04-12 23:21:44 +0000306 if (DV->variableHasComplexAddress())
307 addComplexAddress(DV, Die, dwarf::DW_AT_location, Location);
308 else if (DV->isBlockByrefVariable())
309 addBlockByrefAddress(DV, Die, dwarf::DW_AT_location, Location);
310 else
311 addAddress(Die, dwarf::DW_AT_location, Location);
312}
313
Devang Patel116da2f2011-04-26 19:06:18 +0000314/// addRegisterOp - Add register operand.
315void CompileUnit::addRegisterOp(DIE *TheDie, unsigned Reg) {
316 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
317 unsigned DWReg = RI->getDwarfRegNum(Reg, false);
318 if (DWReg < 32)
319 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + DWReg);
320 else {
321 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx);
322 addUInt(TheDie, 0, dwarf::DW_FORM_udata, DWReg);
323 }
324}
325
326/// addRegisterOffset - Add register offset.
327void CompileUnit::addRegisterOffset(DIE *TheDie, unsigned Reg,
328 int64_t Offset) {
329 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
330 unsigned DWReg = RI->getDwarfRegNum(Reg, false);
331 const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
332 if (Reg == TRI->getFrameRegister(*Asm->MF))
333 // If variable offset is based in frame register then use fbreg.
334 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_fbreg);
335 else if (DWReg < 32)
336 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + DWReg);
337 else {
338 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
339 addUInt(TheDie, 0, dwarf::DW_FORM_udata, DWReg);
340 }
341 addSInt(TheDie, 0, dwarf::DW_FORM_sdata, Offset);
342}
343
344/// addAddress - Add an address attribute to a die based on the location
345/// provided.
346void CompileUnit::addAddress(DIE *Die, unsigned Attribute,
347 const MachineLocation &Location) {
348 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
349
350 if (Location.isReg())
351 addRegisterOp(Block, Location.getReg());
352 else
353 addRegisterOffset(Block, Location.getReg(), Location.getOffset());
354
355 // Now attach the location information to the DIE.
356 addBlock(Die, Attribute, 0, Block);
357}
358
Devang Patel161b2f42011-04-12 23:21:44 +0000359/// addComplexAddress - Start with the address based on the location provided,
360/// and generate the DWARF information necessary to find the actual variable
361/// given the extra address information encoded in the DIVariable, starting from
362/// the starting location. Add the DWARF information to the die.
363///
364void CompileUnit::addComplexAddress(DbgVariable *&DV, DIE *Die,
365 unsigned Attribute,
366 const MachineLocation &Location) {
Devang Patel161b2f42011-04-12 23:21:44 +0000367 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patelc26f5442011-04-28 02:22:40 +0000368 unsigned N = DV->getNumAddrElements();
369 unsigned i = 0;
370 if (Location.isReg()) {
371 if (N >= 2 && DV->getAddrElement(0) == DIBuilder::OpPlus) {
372 // If first address element is OpPlus then emit
373 // DW_OP_breg + Offset instead of DW_OP_reg + Offset.
374 addRegisterOffset(Block, Location.getReg(), DV->getAddrElement(1));
375 i = 2;
376 } else
377 addRegisterOp(Block, Location.getReg());
378 }
Devang Patel116da2f2011-04-26 19:06:18 +0000379 else
380 addRegisterOffset(Block, Location.getReg(), Location.getOffset());
Devang Patel161b2f42011-04-12 23:21:44 +0000381
Devang Patelc26f5442011-04-28 02:22:40 +0000382 for (;i < N; ++i) {
Devang Patel161b2f42011-04-12 23:21:44 +0000383 uint64_t Element = DV->getAddrElement(i);
Devang Patel161b2f42011-04-12 23:21:44 +0000384 if (Element == DIBuilder::OpPlus) {
385 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
386 addUInt(Block, 0, dwarf::DW_FORM_udata, DV->getAddrElement(++i));
387 } else if (Element == DIBuilder::OpDeref) {
Eric Christopher50120762012-05-08 18:56:00 +0000388 if (!Location.isReg())
389 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
Devang Patel161b2f42011-04-12 23:21:44 +0000390 } else llvm_unreachable("unknown DIBuilder Opcode");
391 }
392
393 // Now attach the location information to the DIE.
394 addBlock(Die, Attribute, 0, Block);
395}
396
397/* Byref variables, in Blocks, are declared by the programmer as "SomeType
398 VarName;", but the compiler creates a __Block_byref_x_VarName struct, and
399 gives the variable VarName either the struct, or a pointer to the struct, as
400 its type. This is necessary for various behind-the-scenes things the
401 compiler needs to do with by-reference variables in Blocks.
402
403 However, as far as the original *programmer* is concerned, the variable
404 should still have type 'SomeType', as originally declared.
405
406 The function getBlockByrefType dives into the __Block_byref_x_VarName
407 struct to find the original type of the variable, which is then assigned to
408 the variable's Debug Information Entry as its real type. So far, so good.
409 However now the debugger will expect the variable VarName to have the type
410 SomeType. So we need the location attribute for the variable to be an
411 expression that explains to the debugger how to navigate through the
412 pointers and struct to find the actual variable of type SomeType.
413
414 The following function does just that. We start by getting
415 the "normal" location for the variable. This will be the location
416 of either the struct __Block_byref_x_VarName or the pointer to the
417 struct __Block_byref_x_VarName.
418
419 The struct will look something like:
420
421 struct __Block_byref_x_VarName {
422 ... <various fields>
423 struct __Block_byref_x_VarName *forwarding;
424 ... <various other fields>
425 SomeType VarName;
426 ... <maybe more fields>
427 };
428
429 If we are given the struct directly (as our starting point) we
430 need to tell the debugger to:
431
432 1). Add the offset of the forwarding field.
433
434 2). Follow that pointer to get the real __Block_byref_x_VarName
435 struct to use (the real one may have been copied onto the heap).
436
437 3). Add the offset for the field VarName, to find the actual variable.
438
439 If we started with a pointer to the struct, then we need to
440 dereference that pointer first, before the other steps.
441 Translating this into DWARF ops, we will need to append the following
442 to the current location description for the variable:
443
444 DW_OP_deref -- optional, if we start with a pointer
445 DW_OP_plus_uconst <forward_fld_offset>
446 DW_OP_deref
447 DW_OP_plus_uconst <varName_fld_offset>
448
449 That is what this function does. */
450
451/// addBlockByrefAddress - Start with the address based on the location
452/// provided, and generate the DWARF information necessary to find the
453/// actual Block variable (navigating the Block struct) based on the
454/// starting location. Add the DWARF information to the die. For
455/// more information, read large comment just above here.
456///
457void CompileUnit::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
458 unsigned Attribute,
459 const MachineLocation &Location) {
460 DIType Ty = DV->getType();
461 DIType TmpTy = Ty;
462 unsigned Tag = Ty.getTag();
463 bool isPointer = false;
464
465 StringRef varName = DV->getName();
466
467 if (Tag == dwarf::DW_TAG_pointer_type) {
468 DIDerivedType DTy = DIDerivedType(Ty);
469 TmpTy = DTy.getTypeDerivedFrom();
470 isPointer = true;
471 }
472
473 DICompositeType blockStruct = DICompositeType(TmpTy);
474
475 // Find the __forwarding field and the variable field in the __Block_byref
476 // struct.
477 DIArray Fields = blockStruct.getTypeArray();
478 DIDescriptor varField = DIDescriptor();
479 DIDescriptor forwardingField = DIDescriptor();
480
481 for (unsigned i = 0, N = Fields.getNumElements(); i < N; ++i) {
482 DIDescriptor Element = Fields.getElement(i);
483 DIDerivedType DT = DIDerivedType(Element);
484 StringRef fieldName = DT.getName();
485 if (fieldName == "__forwarding")
486 forwardingField = Element;
487 else if (fieldName == varName)
488 varField = Element;
489 }
490
491 // Get the offsets for the forwarding field and the variable field.
492 unsigned forwardingFieldOffset =
493 DIDerivedType(forwardingField).getOffsetInBits() >> 3;
494 unsigned varFieldOffset =
495 DIDerivedType(varField).getOffsetInBits() >> 3;
496
497 // Decode the original location, and use that as the start of the byref
498 // variable's location.
Devang Patel161b2f42011-04-12 23:21:44 +0000499 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
500
Eric Christophercaba2632012-07-04 02:02:18 +0000501 if (Location.isReg())
502 addRegisterOp(Block, Location.getReg());
503 else
504 addRegisterOffset(Block, Location.getReg(), Location.getOffset());
Devang Patel161b2f42011-04-12 23:21:44 +0000505
506 // If we started with a pointer to the __Block_byref... struct, then
507 // the first thing we need to do is dereference the pointer (DW_OP_deref).
508 if (isPointer)
509 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
510
511 // Next add the offset for the '__forwarding' field:
512 // DW_OP_plus_uconst ForwardingFieldOffset. Note there's no point in
513 // adding the offset if it's 0.
514 if (forwardingFieldOffset > 0) {
515 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
516 addUInt(Block, 0, dwarf::DW_FORM_udata, forwardingFieldOffset);
517 }
518
519 // Now dereference the __forwarding field to get to the real __Block_byref
520 // struct: DW_OP_deref.
521 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
522
523 // Now that we've got the real __Block_byref... struct, add the offset
524 // for the variable's field to get to the location of the actual variable:
525 // DW_OP_plus_uconst varFieldOffset. Again, don't add if it's 0.
526 if (varFieldOffset > 0) {
527 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
528 addUInt(Block, 0, dwarf::DW_FORM_udata, varFieldOffset);
529 }
530
531 // Now attach the location information to the DIE.
532 addBlock(Die, Attribute, 0, Block);
533}
534
Devang Patel4ec14b02011-07-20 21:57:04 +0000535/// isTypeSigned - Return true if the type is signed.
536static bool isTypeSigned(DIType Ty, int *SizeInBits) {
537 if (Ty.isDerivedType())
538 return isTypeSigned(DIDerivedType(Ty).getTypeDerivedFrom(), SizeInBits);
539 if (Ty.isBasicType())
540 if (DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed
541 || DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed_char) {
542 *SizeInBits = Ty.getSizeInBits();
543 return true;
544 }
545 return false;
546}
547
Devang Patel161b2f42011-04-12 23:21:44 +0000548/// addConstantValue - Add constant value entry in variable DIE.
Devang Patelb58128e2011-05-27 16:45:18 +0000549bool CompileUnit::addConstantValue(DIE *Die, const MachineOperand &MO,
550 DIType Ty) {
Nick Lewycky746cb672011-10-26 22:55:33 +0000551 assert(MO.isImm() && "Invalid machine operand!");
Devang Patel161b2f42011-04-12 23:21:44 +0000552 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel4ec14b02011-07-20 21:57:04 +0000553 int SizeInBits = -1;
554 bool SignedConstant = isTypeSigned(Ty, &SizeInBits);
555 unsigned Form = SignedConstant ? dwarf::DW_FORM_sdata : dwarf::DW_FORM_udata;
556 switch (SizeInBits) {
557 case 8: Form = dwarf::DW_FORM_data1; break;
558 case 16: Form = dwarf::DW_FORM_data2; break;
559 case 32: Form = dwarf::DW_FORM_data4; break;
560 case 64: Form = dwarf::DW_FORM_data8; break;
Devang Patel045c1d42011-05-27 19:13:26 +0000561 default: break;
562 }
Eric Christopher8b4310b2012-11-21 00:34:38 +0000563 SignedConstant ? addSInt(Block, 0, Form, MO.getImm())
Devang Patel4ec14b02011-07-20 21:57:04 +0000564 : addUInt(Block, 0, Form, MO.getImm());
Devang Patel72f0d9c2011-05-27 18:15:52 +0000565
Devang Patel161b2f42011-04-12 23:21:44 +0000566 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
567 return true;
568}
569
570/// addConstantFPValue - Add constant value entry in variable DIE.
571bool CompileUnit::addConstantFPValue(DIE *Die, const MachineOperand &MO) {
Nick Lewycky390c40d2011-10-27 06:44:11 +0000572 assert (MO.isFPImm() && "Invalid machine operand!");
Devang Patel161b2f42011-04-12 23:21:44 +0000573 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
574 APFloat FPImm = MO.getFPImm()->getValueAPF();
575
576 // Get the raw data form of the floating point.
577 const APInt FltVal = FPImm.bitcastToAPInt();
578 const char *FltPtr = (const char*)FltVal.getRawData();
579
580 int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte.
Micah Villmow3574eca2012-10-08 16:38:25 +0000581 bool LittleEndian = Asm->getDataLayout().isLittleEndian();
Devang Patel161b2f42011-04-12 23:21:44 +0000582 int Incr = (LittleEndian ? 1 : -1);
583 int Start = (LittleEndian ? 0 : NumBytes - 1);
584 int Stop = (LittleEndian ? NumBytes : -1);
585
586 // Output the constant to DWARF one byte at a time.
587 for (; Start != Stop; Start += Incr)
588 addUInt(Block, 0, dwarf::DW_FORM_data1,
589 (unsigned char)0xFF & FltPtr[Start]);
590
591 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
592 return true;
593}
594
595/// addConstantValue - Add constant value entry in variable DIE.
Devang Patel8594d422011-06-24 20:46:11 +0000596bool CompileUnit::addConstantValue(DIE *Die, const ConstantInt *CI,
Devang Patel161b2f42011-04-12 23:21:44 +0000597 bool Unsigned) {
Devang Pateld6a81362011-05-28 00:39:18 +0000598 unsigned CIBitWidth = CI->getBitWidth();
599 if (CIBitWidth <= 64) {
600 unsigned form = 0;
601 switch (CIBitWidth) {
602 case 8: form = dwarf::DW_FORM_data1; break;
603 case 16: form = dwarf::DW_FORM_data2; break;
604 case 32: form = dwarf::DW_FORM_data4; break;
605 case 64: form = dwarf::DW_FORM_data8; break;
Eric Christopher8b4310b2012-11-21 00:34:38 +0000606 default:
Devang Pateld6a81362011-05-28 00:39:18 +0000607 form = Unsigned ? dwarf::DW_FORM_udata : dwarf::DW_FORM_sdata;
608 }
Devang Patel161b2f42011-04-12 23:21:44 +0000609 if (Unsigned)
Devang Pateld6a81362011-05-28 00:39:18 +0000610 addUInt(Die, dwarf::DW_AT_const_value, form, CI->getZExtValue());
Devang Patel161b2f42011-04-12 23:21:44 +0000611 else
Devang Pateld6a81362011-05-28 00:39:18 +0000612 addSInt(Die, dwarf::DW_AT_const_value, form, CI->getSExtValue());
Devang Patel161b2f42011-04-12 23:21:44 +0000613 return true;
614 }
615
616 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
617
618 // Get the raw data form of the large APInt.
619 const APInt Val = CI->getValue();
NAKAMURA Takumic3e48c32011-10-28 14:12:22 +0000620 const uint64_t *Ptr64 = Val.getRawData();
Devang Patel161b2f42011-04-12 23:21:44 +0000621
622 int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte.
Micah Villmow3574eca2012-10-08 16:38:25 +0000623 bool LittleEndian = Asm->getDataLayout().isLittleEndian();
Devang Patel161b2f42011-04-12 23:21:44 +0000624
625 // Output the constant to DWARF one byte at a time.
NAKAMURA Takumic3e48c32011-10-28 14:12:22 +0000626 for (int i = 0; i < NumBytes; i++) {
627 uint8_t c;
628 if (LittleEndian)
629 c = Ptr64[i / 8] >> (8 * (i & 7));
630 else
631 c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7));
632 addUInt(Block, 0, dwarf::DW_FORM_data1, c);
633 }
Devang Patel161b2f42011-04-12 23:21:44 +0000634
635 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
636 return true;
637}
638
639/// addTemplateParams - Add template parameters in buffer.
640void CompileUnit::addTemplateParams(DIE &Buffer, DIArray TParams) {
641 // Add template parameters.
642 for (unsigned i = 0, e = TParams.getNumElements(); i != e; ++i) {
643 DIDescriptor Element = TParams.getElement(i);
644 if (Element.isTemplateTypeParameter())
645 Buffer.addChild(getOrCreateTemplateTypeParameterDIE(
646 DITemplateTypeParameter(Element)));
647 else if (Element.isTemplateValueParameter())
648 Buffer.addChild(getOrCreateTemplateValueParameterDIE(
649 DITemplateValueParameter(Element)));
650 }
Devang Patel161b2f42011-04-12 23:21:44 +0000651}
Nick Lewycky746cb672011-10-26 22:55:33 +0000652
Devang Patel161b2f42011-04-12 23:21:44 +0000653/// addToContextOwner - Add Die into the list of its context owner's children.
654void CompileUnit::addToContextOwner(DIE *Die, DIDescriptor Context) {
655 if (Context.isType()) {
656 DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context));
657 ContextDIE->addChild(Die);
658 } else if (Context.isNameSpace()) {
659 DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context));
660 ContextDIE->addChild(Die);
661 } else if (Context.isSubprogram()) {
Devang Pateldbc64af2011-08-15 17:24:54 +0000662 DIE *ContextDIE = getOrCreateSubprogramDIE(DISubprogram(Context));
Devang Patel161b2f42011-04-12 23:21:44 +0000663 ContextDIE->addChild(Die);
664 } else if (DIE *ContextDIE = getDIE(Context))
665 ContextDIE->addChild(Die);
666 else
667 addDie(Die);
668}
669
670/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
671/// given DIType.
Devang Patel94c7ddb2011-08-16 22:09:43 +0000672DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
673 DIType Ty(TyNode);
674 if (!Ty.Verify())
675 return NULL;
Devang Patel161b2f42011-04-12 23:21:44 +0000676 DIE *TyDIE = getDIE(Ty);
677 if (TyDIE)
678 return TyDIE;
679
680 // Create new type.
681 TyDIE = new DIE(dwarf::DW_TAG_base_type);
682 insertDIE(Ty, TyDIE);
683 if (Ty.isBasicType())
684 constructTypeDIE(*TyDIE, DIBasicType(Ty));
685 else if (Ty.isCompositeType())
686 constructTypeDIE(*TyDIE, DICompositeType(Ty));
687 else {
688 assert(Ty.isDerivedType() && "Unknown kind of DIType");
689 constructTypeDIE(*TyDIE, DIDerivedType(Ty));
690 }
Eric Christopher1b3f9192011-11-10 19:52:58 +0000691 // If this is a named finished type then include it in the list of types
692 // for the accelerator tables.
Eric Christopherc36145f2012-01-06 04:35:23 +0000693 if (!Ty.getName().empty() && !Ty.isForwardDecl()) {
694 bool IsImplementation = 0;
695 if (Ty.isCompositeType()) {
696 DICompositeType CT(Ty);
Eric Christophere0167892012-01-06 23:03:37 +0000697 // A runtime language of 0 actually means C/C++ and that any
698 // non-negative value is some version of Objective-C/C++.
Eric Christopherc36145f2012-01-06 04:35:23 +0000699 IsImplementation = (CT.getRunTimeLang() == 0) ||
Eric Christophere2dc9332012-02-22 08:46:02 +0000700 CT.isObjcClassComplete();
Eric Christopherc36145f2012-01-06 04:35:23 +0000701 }
Eric Christophere0167892012-01-06 23:03:37 +0000702 unsigned Flags = IsImplementation ?
703 DwarfAccelTable::eTypeFlagClassIsImplementation : 0;
704 addAccelType(Ty.getName(), std::make_pair(TyDIE, Flags));
Eric Christopherc36145f2012-01-06 04:35:23 +0000705 }
Eric Christopher8b4310b2012-11-21 00:34:38 +0000706
Devang Patel161b2f42011-04-12 23:21:44 +0000707 addToContextOwner(TyDIE, Ty.getContext());
708 return TyDIE;
709}
710
711/// addType - Add a new type attribute to the specified entity.
Eric Christopher4d069bf2012-05-22 18:45:24 +0000712void CompileUnit::addType(DIE *Entity, DIType Ty, unsigned Attribute) {
Devang Patel161b2f42011-04-12 23:21:44 +0000713 if (!Ty.Verify())
714 return;
715
716 // Check for pre-existence.
717 DIEEntry *Entry = getDIEEntry(Ty);
718 // If it exists then use the existing value.
719 if (Entry) {
Eric Christopher663e0cf2012-03-28 07:34:31 +0000720 Entity->addValue(Attribute, dwarf::DW_FORM_ref4, Entry);
Devang Patel161b2f42011-04-12 23:21:44 +0000721 return;
722 }
723
724 // Construct type.
725 DIE *Buffer = getOrCreateTypeDIE(Ty);
726
727 // Set up proxy.
728 Entry = createDIEEntry(Buffer);
729 insertDIEEntry(Ty, Entry);
Eric Christopher663e0cf2012-03-28 07:34:31 +0000730 Entity->addValue(Attribute, dwarf::DW_FORM_ref4, Entry);
Devang Patele9ae06c2011-05-31 22:56:51 +0000731
732 // If this is a complete composite type then include it in the
733 // list of global types.
Devang Patelc20bdf12011-06-01 00:23:24 +0000734 addGlobalType(Ty);
Devang Patel66658e42011-05-31 23:30:30 +0000735}
736
737/// addGlobalType - Add a new global type to the compile unit.
738///
Devang Patelc20bdf12011-06-01 00:23:24 +0000739void CompileUnit::addGlobalType(DIType Ty) {
Devang Patele9ae06c2011-05-31 22:56:51 +0000740 DIDescriptor Context = Ty.getContext();
Eric Christopher8b4310b2012-11-21 00:34:38 +0000741 if (Ty.isCompositeType() && !Ty.getName().empty() && !Ty.isForwardDecl()
742 && (!Context || Context.isCompileUnit() || Context.isFile()
Devang Patel94c7ddb2011-08-16 22:09:43 +0000743 || Context.isNameSpace()))
Devang Patelc20bdf12011-06-01 00:23:24 +0000744 if (DIEEntry *Entry = getDIEEntry(Ty))
745 GlobalTypes[Ty.getName()] = Entry->getEntry();
Devang Patel161b2f42011-04-12 23:21:44 +0000746}
747
Devang Patel31c5d052011-05-06 16:57:54 +0000748/// addPubTypes - Add type for pubtypes section.
749void CompileUnit::addPubTypes(DISubprogram SP) {
750 DICompositeType SPTy = SP.getType();
751 unsigned SPTag = SPTy.getTag();
752 if (SPTag != dwarf::DW_TAG_subroutine_type)
753 return;
754
755 DIArray Args = SPTy.getTypeArray();
756 for (unsigned i = 0, e = Args.getNumElements(); i != e; ++i) {
757 DIType ATy(Args.getElement(i));
758 if (!ATy.Verify())
759 continue;
Devang Patelc20bdf12011-06-01 00:23:24 +0000760 addGlobalType(ATy);
Devang Patel31c5d052011-05-06 16:57:54 +0000761 }
762}
763
Devang Patel161b2f42011-04-12 23:21:44 +0000764/// constructTypeDIE - Construct basic type die from DIBasicType.
765void CompileUnit::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
766 // Get core information.
767 StringRef Name = BTy.getName();
Devang Patel161b2f42011-04-12 23:21:44 +0000768 // Add name if not anonymous or intermediate type.
769 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000770 addString(&Buffer, dwarf::DW_AT_name, Name);
Devang Patel734a67c2011-09-14 23:13:28 +0000771
772 if (BTy.getTag() == dwarf::DW_TAG_unspecified_type) {
773 Buffer.setTag(dwarf::DW_TAG_unspecified_type);
774 // Unspecified types has only name, nothing else.
775 return;
776 }
777
778 Buffer.setTag(dwarf::DW_TAG_base_type);
Nick Lewycky746cb672011-10-26 22:55:33 +0000779 addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
Devang Patel30d409c2012-02-07 23:33:58 +0000780 BTy.getEncoding());
Devang Patel734a67c2011-09-14 23:13:28 +0000781
Devang Patel161b2f42011-04-12 23:21:44 +0000782 uint64_t Size = BTy.getSizeInBits() >> 3;
783 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
784}
785
786/// constructTypeDIE - Construct derived type die from DIDerivedType.
787void CompileUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
788 // Get core information.
789 StringRef Name = DTy.getName();
790 uint64_t Size = DTy.getSizeInBits() >> 3;
791 unsigned Tag = DTy.getTag();
792
793 // FIXME - Workaround for templates.
794 if (Tag == dwarf::DW_TAG_inheritance) Tag = dwarf::DW_TAG_reference_type;
795
796 Buffer.setTag(Tag);
797
798 // Map to main type, void will not have a type.
799 DIType FromTy = DTy.getTypeDerivedFrom();
800 addType(&Buffer, FromTy);
801
802 // Add name if not anonymous or intermediate type.
803 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000804 addString(&Buffer, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +0000805
806 // Add size if non-zero (derived types might be zero-sized.)
Eric Christopher35f225a2012-02-21 22:25:53 +0000807 if (Size && Tag != dwarf::DW_TAG_pointer_type)
Devang Patel161b2f42011-04-12 23:21:44 +0000808 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
809
David Blaikie62fdfb52013-01-07 05:51:15 +0000810 if (Tag == dwarf::DW_TAG_ptr_to_member_type)
811 addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
812 getOrCreateTypeDIE(DTy.getClassType()));
Devang Patel161b2f42011-04-12 23:21:44 +0000813 // Add source line info if available and TyDesc is not a forward declaration.
814 if (!DTy.isForwardDecl())
815 addSourceLine(&Buffer, DTy);
816}
817
818/// constructTypeDIE - Construct type DIE from DICompositeType.
819void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
820 // Get core information.
821 StringRef Name = CTy.getName();
822
823 uint64_t Size = CTy.getSizeInBits() >> 3;
824 unsigned Tag = CTy.getTag();
825 Buffer.setTag(Tag);
826
827 switch (Tag) {
Devang Patel161b2f42011-04-12 23:21:44 +0000828 case dwarf::DW_TAG_array_type:
829 constructArrayTypeDIE(Buffer, &CTy);
830 break;
831 case dwarf::DW_TAG_enumeration_type: {
832 DIArray Elements = CTy.getTypeArray();
833
834 // Add enumerators to enumeration type.
835 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
836 DIE *ElemDie = NULL;
837 DIDescriptor Enum(Elements.getElement(i));
838 if (Enum.isEnumerator()) {
839 ElemDie = constructEnumTypeDIE(DIEnumerator(Enum));
840 Buffer.addChild(ElemDie);
841 }
842 }
Eric Christopherbb0f6ea2012-05-23 00:09:20 +0000843 DIType DTy = CTy.getTypeDerivedFrom();
844 if (DTy.Verify()) {
845 addType(&Buffer, DTy);
846 addUInt(&Buffer, dwarf::DW_AT_enum_class, dwarf::DW_FORM_flag, 1);
847 }
Devang Patel161b2f42011-04-12 23:21:44 +0000848 }
849 break;
850 case dwarf::DW_TAG_subroutine_type: {
851 // Add return type.
852 DIArray Elements = CTy.getTypeArray();
853 DIDescriptor RTy = Elements.getElement(0);
854 addType(&Buffer, DIType(RTy));
855
856 bool isPrototyped = true;
857 // Add arguments.
858 for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
859 DIDescriptor Ty = Elements.getElement(i);
860 if (Ty.isUnspecifiedParameter()) {
861 DIE *Arg = new DIE(dwarf::DW_TAG_unspecified_parameters);
862 Buffer.addChild(Arg);
863 isPrototyped = false;
864 } else {
865 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
866 addType(Arg, DIType(Ty));
867 Buffer.addChild(Arg);
868 }
869 }
Eric Christopher8b6fe6b2012-02-22 08:46:21 +0000870 // Add prototype flag if we're dealing with a C language and the
871 // function has been prototyped.
872 if (isPrototyped &&
Eric Christopher4d069bf2012-05-22 18:45:24 +0000873 (Language == dwarf::DW_LANG_C89 ||
874 Language == dwarf::DW_LANG_C99 ||
875 Language == dwarf::DW_LANG_ObjC))
Eric Christopher873cf0a2012-08-24 01:14:27 +0000876 addFlag(&Buffer, dwarf::DW_AT_prototyped);
Devang Patel161b2f42011-04-12 23:21:44 +0000877 }
878 break;
879 case dwarf::DW_TAG_structure_type:
880 case dwarf::DW_TAG_union_type:
881 case dwarf::DW_TAG_class_type: {
882 // Add elements to structure type.
883 DIArray Elements = CTy.getTypeArray();
884
885 // A forward struct declared type may not have elements available.
886 unsigned N = Elements.getNumElements();
887 if (N == 0)
888 break;
889
890 // Add elements to structure type.
891 for (unsigned i = 0; i < N; ++i) {
892 DIDescriptor Element = Elements.getElement(i);
893 DIE *ElemDie = NULL;
894 if (Element.isSubprogram()) {
895 DISubprogram SP(Element);
Devang Pateldbc64af2011-08-15 17:24:54 +0000896 ElemDie = getOrCreateSubprogramDIE(DISubprogram(Element));
Devang Patel161b2f42011-04-12 23:21:44 +0000897 if (SP.isProtected())
Nick Lewycky13aaca52011-12-13 05:09:11 +0000898 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +0000899 dwarf::DW_ACCESS_protected);
900 else if (SP.isPrivate())
Nick Lewycky13aaca52011-12-13 05:09:11 +0000901 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +0000902 dwarf::DW_ACCESS_private);
Eric Christopher8b4310b2012-11-21 00:34:38 +0000903 else
Nick Lewycky13aaca52011-12-13 05:09:11 +0000904 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +0000905 dwarf::DW_ACCESS_public);
906 if (SP.isExplicit())
Eric Christopher873cf0a2012-08-24 01:14:27 +0000907 addFlag(ElemDie, dwarf::DW_AT_explicit);
Devang Patel161b2f42011-04-12 23:21:44 +0000908 }
909 else if (Element.isVariable()) {
910 DIVariable DV(Element);
911 ElemDie = new DIE(dwarf::DW_TAG_variable);
Nick Lewycky390c40d2011-10-27 06:44:11 +0000912 addString(ElemDie, dwarf::DW_AT_name, DV.getName());
Devang Patel161b2f42011-04-12 23:21:44 +0000913 addType(ElemDie, DV.getType());
Eric Christopher873cf0a2012-08-24 01:14:27 +0000914 addFlag(ElemDie, dwarf::DW_AT_declaration);
915 addFlag(ElemDie, dwarf::DW_AT_external);
Devang Patel161b2f42011-04-12 23:21:44 +0000916 addSourceLine(ElemDie, DV);
Eric Christopher663e0cf2012-03-28 07:34:31 +0000917 } else if (Element.isDerivedType()) {
Eric Christopher4d069bf2012-05-22 18:45:24 +0000918 DIDerivedType DDTy(Element);
919 if (DDTy.getTag() == dwarf::DW_TAG_friend) {
920 ElemDie = new DIE(dwarf::DW_TAG_friend);
921 addType(ElemDie, DDTy.getTypeDerivedFrom(), dwarf::DW_AT_friend);
922 } else
923 ElemDie = createMemberDIE(DIDerivedType(Element));
Eric Christopher663e0cf2012-03-28 07:34:31 +0000924 } else if (Element.isObjCProperty()) {
Devang Patel30d409c2012-02-07 23:33:58 +0000925 DIObjCProperty Property(Element);
926 ElemDie = new DIE(Property.getTag());
927 StringRef PropertyName = Property.getObjCPropertyName();
928 addString(ElemDie, dwarf::DW_AT_APPLE_property_name, PropertyName);
Eric Christopher4d069bf2012-05-22 18:45:24 +0000929 addType(ElemDie, Property.getType());
930 addSourceLine(ElemDie, Property);
Devang Patel30d409c2012-02-07 23:33:58 +0000931 StringRef GetterName = Property.getObjCPropertyGetterName();
932 if (!GetterName.empty())
933 addString(ElemDie, dwarf::DW_AT_APPLE_property_getter, GetterName);
934 StringRef SetterName = Property.getObjCPropertySetterName();
935 if (!SetterName.empty())
936 addString(ElemDie, dwarf::DW_AT_APPLE_property_setter, SetterName);
937 unsigned PropertyAttributes = 0;
Devang Patel9e11eb12012-02-04 01:30:32 +0000938 if (Property.isReadOnlyObjCProperty())
939 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readonly;
940 if (Property.isReadWriteObjCProperty())
941 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readwrite;
942 if (Property.isAssignObjCProperty())
943 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_assign;
944 if (Property.isRetainObjCProperty())
945 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_retain;
946 if (Property.isCopyObjCProperty())
947 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_copy;
948 if (Property.isNonAtomicObjCProperty())
949 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_nonatomic;
950 if (PropertyAttributes)
Eric Christopher8b4310b2012-11-21 00:34:38 +0000951 addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute, 0,
Devang Patel9e11eb12012-02-04 01:30:32 +0000952 PropertyAttributes);
Devang Patel6588abf2012-02-06 17:49:43 +0000953
Devang Patel30d409c2012-02-07 23:33:58 +0000954 DIEEntry *Entry = getDIEEntry(Element);
955 if (!Entry) {
956 Entry = createDIEEntry(ElemDie);
957 insertDIEEntry(Element, Entry);
958 }
Devang Patel9e11eb12012-02-04 01:30:32 +0000959 } else
Devang Patel161b2f42011-04-12 23:21:44 +0000960 continue;
961 Buffer.addChild(ElemDie);
962 }
963
964 if (CTy.isAppleBlockExtension())
Eric Christopher873cf0a2012-08-24 01:14:27 +0000965 addFlag(&Buffer, dwarf::DW_AT_APPLE_block);
Devang Patel161b2f42011-04-12 23:21:44 +0000966
Devang Patel161b2f42011-04-12 23:21:44 +0000967 DICompositeType ContainingType = CTy.getContainingType();
968 if (DIDescriptor(ContainingType).isCompositeType())
969 addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
970 getOrCreateTypeDIE(DIType(ContainingType)));
971 else {
972 DIDescriptor Context = CTy.getContext();
973 addToContextOwner(&Buffer, Context);
974 }
975
Devang Patel201e6cd2011-05-12 21:29:42 +0000976 if (CTy.isObjcClassComplete())
Eric Christopher873cf0a2012-08-24 01:14:27 +0000977 addFlag(&Buffer, dwarf::DW_AT_APPLE_objc_complete_type);
Devang Patelb11f80e2011-05-12 19:06:16 +0000978
Eric Christopher1a8e8862011-12-16 23:42:42 +0000979 // Add template parameters to a class, structure or union types.
980 // FIXME: The support isn't in the metadata for this yet.
981 if (Tag == dwarf::DW_TAG_class_type ||
982 Tag == dwarf::DW_TAG_structure_type ||
983 Tag == dwarf::DW_TAG_union_type)
Devang Patel161b2f42011-04-12 23:21:44 +0000984 addTemplateParams(Buffer, CTy.getTemplateParams());
985
986 break;
987 }
988 default:
989 break;
990 }
991
992 // Add name if not anonymous or intermediate type.
993 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000994 addString(&Buffer, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +0000995
Eric Christopher4a5d8392012-05-22 18:45:18 +0000996 if (Tag == dwarf::DW_TAG_enumeration_type ||
997 Tag == dwarf::DW_TAG_class_type ||
998 Tag == dwarf::DW_TAG_structure_type ||
999 Tag == dwarf::DW_TAG_union_type) {
Devang Patel161b2f42011-04-12 23:21:44 +00001000 // Add size if non-zero (derived types might be zero-sized.)
Eric Christopherfc4199b2012-06-01 00:22:32 +00001001 // TODO: Do we care about size for enum forward declarations?
Devang Patel161b2f42011-04-12 23:21:44 +00001002 if (Size)
1003 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
Eric Christopherfc4199b2012-06-01 00:22:32 +00001004 else if (!CTy.isForwardDecl())
Devang Patel161b2f42011-04-12 23:21:44 +00001005 // Add zero size if it is not a forward declaration.
Eric Christopherfc4199b2012-06-01 00:22:32 +00001006 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, 0);
1007
1008 // If we're a forward decl, say so.
1009 if (CTy.isForwardDecl())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001010 addFlag(&Buffer, dwarf::DW_AT_declaration);
Devang Patel161b2f42011-04-12 23:21:44 +00001011
1012 // Add source line info if available.
1013 if (!CTy.isForwardDecl())
1014 addSourceLine(&Buffer, CTy);
Eric Christopher89388952012-03-07 00:15:19 +00001015
1016 // No harm in adding the runtime language to the declaration.
1017 unsigned RLang = CTy.getRunTimeLang();
1018 if (RLang)
1019 addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class,
1020 dwarf::DW_FORM_data1, RLang);
Devang Patel161b2f42011-04-12 23:21:44 +00001021 }
1022}
1023
Eric Christopher8b4310b2012-11-21 00:34:38 +00001024/// getOrCreateTemplateTypeParameterDIE - Find existing DIE or create new DIE
Devang Patel161b2f42011-04-12 23:21:44 +00001025/// for the given DITemplateTypeParameter.
1026DIE *
1027CompileUnit::getOrCreateTemplateTypeParameterDIE(DITemplateTypeParameter TP) {
1028 DIE *ParamDIE = getDIE(TP);
1029 if (ParamDIE)
1030 return ParamDIE;
1031
1032 ParamDIE = new DIE(dwarf::DW_TAG_template_type_parameter);
1033 addType(ParamDIE, TP.getType());
Nick Lewycky390c40d2011-10-27 06:44:11 +00001034 addString(ParamDIE, dwarf::DW_AT_name, TP.getName());
Devang Patel161b2f42011-04-12 23:21:44 +00001035 return ParamDIE;
1036}
1037
Eric Christopher8b4310b2012-11-21 00:34:38 +00001038/// getOrCreateTemplateValueParameterDIE - Find existing DIE or create new DIE
Devang Patel161b2f42011-04-12 23:21:44 +00001039/// for the given DITemplateValueParameter.
1040DIE *
Eric Christopher4d069bf2012-05-22 18:45:24 +00001041CompileUnit::getOrCreateTemplateValueParameterDIE(DITemplateValueParameter TPV){
Devang Patel161b2f42011-04-12 23:21:44 +00001042 DIE *ParamDIE = getDIE(TPV);
1043 if (ParamDIE)
1044 return ParamDIE;
1045
1046 ParamDIE = new DIE(dwarf::DW_TAG_template_value_parameter);
1047 addType(ParamDIE, TPV.getType());
1048 if (!TPV.getName().empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001049 addString(ParamDIE, dwarf::DW_AT_name, TPV.getName());
Eric Christopher8b4310b2012-11-21 00:34:38 +00001050 addUInt(ParamDIE, dwarf::DW_AT_const_value, dwarf::DW_FORM_udata,
Devang Patel161b2f42011-04-12 23:21:44 +00001051 TPV.getValue());
1052 return ParamDIE;
1053}
1054
Devang Patel31c5d052011-05-06 16:57:54 +00001055/// getOrCreateNameSpace - Create a DIE for DINameSpace.
1056DIE *CompileUnit::getOrCreateNameSpace(DINameSpace NS) {
1057 DIE *NDie = getDIE(NS);
1058 if (NDie)
1059 return NDie;
1060 NDie = new DIE(dwarf::DW_TAG_namespace);
1061 insertDIE(NS, NDie);
Eric Christopher09ac3d82011-11-07 09:24:32 +00001062 if (!NS.getName().empty()) {
Nick Lewycky390c40d2011-10-27 06:44:11 +00001063 addString(NDie, dwarf::DW_AT_name, NS.getName());
Eric Christopher09ac3d82011-11-07 09:24:32 +00001064 addAccelNamespace(NS.getName(), NDie);
1065 } else
1066 addAccelNamespace("(anonymous namespace)", NDie);
Devang Patel31c5d052011-05-06 16:57:54 +00001067 addSourceLine(NDie, NS);
1068 addToContextOwner(NDie, NS.getContext());
1069 return NDie;
1070}
1071
Devang Pateldbc64af2011-08-15 17:24:54 +00001072/// getRealLinkageName - If special LLVM prefix that is used to inform the asm
1073/// printer to not emit usual symbol prefix before the symbol name is used then
1074/// return linkage name after skipping this special LLVM prefix.
1075static StringRef getRealLinkageName(StringRef LinkageName) {
1076 char One = '\1';
1077 if (LinkageName.startswith(StringRef(&One, 1)))
1078 return LinkageName.substr(1);
1079 return LinkageName;
1080}
1081
1082/// getOrCreateSubprogramDIE - Create new DIE using SP.
1083DIE *CompileUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
1084 DIE *SPDie = getDIE(SP);
1085 if (SPDie)
1086 return SPDie;
1087
Peter Collingbourne27302f02012-05-27 18:36:44 +00001088 SPDie = new DIE(dwarf::DW_TAG_subprogram);
1089
1090 // DW_TAG_inlined_subroutine may refer to this DIE.
1091 insertDIE(SP, SPDie);
1092
Rafael Espindola01b55b42011-11-10 22:34:29 +00001093 DISubprogram SPDecl = SP.getFunctionDeclaration();
1094 DIE *DeclDie = NULL;
1095 if (SPDecl.isSubprogram()) {
1096 DeclDie = getOrCreateSubprogramDIE(SPDecl);
1097 }
1098
Devang Pateldbc64af2011-08-15 17:24:54 +00001099 // Add to context owner.
1100 addToContextOwner(SPDie, SP.getContext());
1101
1102 // Add function template parameters.
1103 addTemplateParams(*SPDie, SP.getTemplateParams());
1104
Eric Christophere9722e12012-04-16 23:54:23 +00001105 // Unfortunately this code needs to stay here instead of below the
1106 // AT_specification code in order to work around a bug in older
1107 // gdbs that requires the linkage name to resolve multiple template
1108 // functions.
Eric Christophercbbd5b12012-08-23 22:52:55 +00001109 // TODO: Remove this set of code when we get rid of the old gdb
1110 // compatibility.
Eric Christopher8d101c32012-03-15 08:19:33 +00001111 StringRef LinkageName = SP.getLinkageName();
Eric Christophercbbd5b12012-08-23 22:52:55 +00001112 if (!LinkageName.empty() && DD->useDarwinGDBCompat())
Eric Christopher8d101c32012-03-15 08:19:33 +00001113 addString(SPDie, dwarf::DW_AT_MIPS_linkage_name,
1114 getRealLinkageName(LinkageName));
1115
Devang Pateldbc64af2011-08-15 17:24:54 +00001116 // If this DIE is going to refer declaration info using AT_specification
1117 // then there is no need to add other attributes.
Rafael Espindola01b55b42011-11-10 22:34:29 +00001118 if (DeclDie) {
1119 // Refer function declaration directly.
1120 addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
1121 DeclDie);
1122
Devang Pateldbc64af2011-08-15 17:24:54 +00001123 return SPDie;
Rafael Espindola01b55b42011-11-10 22:34:29 +00001124 }
Devang Pateldbc64af2011-08-15 17:24:54 +00001125
Eric Christophercbbd5b12012-08-23 22:52:55 +00001126 // Add the linkage name if we have one.
1127 if (!LinkageName.empty() && !DD->useDarwinGDBCompat())
1128 addString(SPDie, dwarf::DW_AT_MIPS_linkage_name,
1129 getRealLinkageName(LinkageName));
1130
Devang Pateldbc64af2011-08-15 17:24:54 +00001131 // Constructors and operators for anonymous aggregates do not have names.
1132 if (!SP.getName().empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001133 addString(SPDie, dwarf::DW_AT_name, SP.getName());
Devang Pateldbc64af2011-08-15 17:24:54 +00001134
1135 addSourceLine(SPDie, SP);
1136
Eric Christopher8b6fe6b2012-02-22 08:46:21 +00001137 // Add the prototype if we have a prototype and we have a C like
1138 // language.
1139 if (SP.isPrototyped() &&
1140 (Language == dwarf::DW_LANG_C89 ||
1141 Language == dwarf::DW_LANG_C99 ||
1142 Language == dwarf::DW_LANG_ObjC))
Eric Christopher873cf0a2012-08-24 01:14:27 +00001143 addFlag(SPDie, dwarf::DW_AT_prototyped);
Devang Pateldbc64af2011-08-15 17:24:54 +00001144
1145 // Add Return Type.
1146 DICompositeType SPTy = SP.getType();
1147 DIArray Args = SPTy.getTypeArray();
1148 unsigned SPTag = SPTy.getTag();
1149
1150 if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type)
1151 addType(SPDie, SPTy);
1152 else
1153 addType(SPDie, DIType(Args.getElement(0)));
1154
1155 unsigned VK = SP.getVirtuality();
1156 if (VK) {
Nick Lewycky798313d2011-12-14 00:56:07 +00001157 addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, VK);
Devang Pateldbc64af2011-08-15 17:24:54 +00001158 DIEBlock *Block = getDIEBlock();
1159 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1160 addUInt(Block, 0, dwarf::DW_FORM_udata, SP.getVirtualIndex());
1161 addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
1162 ContainingTypeMap.insert(std::make_pair(SPDie,
1163 SP.getContainingType()));
1164 }
1165
1166 if (!SP.isDefinition()) {
Eric Christopher873cf0a2012-08-24 01:14:27 +00001167 addFlag(SPDie, dwarf::DW_AT_declaration);
Eric Christopher8b4310b2012-11-21 00:34:38 +00001168
Devang Pateldbc64af2011-08-15 17:24:54 +00001169 // Add arguments. Do not add arguments for subprogram definition. They will
1170 // be handled while processing variables.
1171 DICompositeType SPTy = SP.getType();
1172 DIArray Args = SPTy.getTypeArray();
1173 unsigned SPTag = SPTy.getTag();
1174
1175 if (SPTag == dwarf::DW_TAG_subroutine_type)
1176 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
1177 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
Eric Christopher5c38de92012-09-10 23:33:57 +00001178 DIType ATy = DIType(Args.getElement(i));
Devang Pateldbc64af2011-08-15 17:24:54 +00001179 addType(Arg, ATy);
1180 if (ATy.isArtificial())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001181 addFlag(Arg, dwarf::DW_AT_artificial);
Devang Pateldbc64af2011-08-15 17:24:54 +00001182 SPDie->addChild(Arg);
1183 }
1184 }
1185
1186 if (SP.isArtificial())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001187 addFlag(SPDie, dwarf::DW_AT_artificial);
Devang Pateldbc64af2011-08-15 17:24:54 +00001188
1189 if (!SP.isLocalToUnit())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001190 addFlag(SPDie, dwarf::DW_AT_external);
Devang Pateldbc64af2011-08-15 17:24:54 +00001191
1192 if (SP.isOptimized())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001193 addFlag(SPDie, dwarf::DW_AT_APPLE_optimized);
Devang Pateldbc64af2011-08-15 17:24:54 +00001194
1195 if (unsigned isa = Asm->getISAEncoding()) {
1196 addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa);
1197 }
1198
1199 return SPDie;
1200}
1201
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001202// Return const expression if value is a GEP to access merged global
1203// constant. e.g.
1204// i8* getelementptr ({ i8, i8, i8, i8 }* @_MergedGlobals, i32 0, i32 0)
1205static const ConstantExpr *getMergedGlobalExpr(const Value *V) {
1206 const ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(V);
1207 if (!CE || CE->getNumOperands() != 3 ||
1208 CE->getOpcode() != Instruction::GetElementPtr)
1209 return NULL;
1210
1211 // First operand points to a global struct.
1212 Value *Ptr = CE->getOperand(0);
1213 if (!isa<GlobalValue>(Ptr) ||
1214 !isa<StructType>(cast<PointerType>(Ptr->getType())->getElementType()))
1215 return NULL;
1216
1217 // Second operand is zero.
1218 const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CE->getOperand(1));
1219 if (!CI || !CI->isZero())
1220 return NULL;
1221
1222 // Third operand is offset.
1223 if (!isa<ConstantInt>(CE->getOperand(2)))
1224 return NULL;
1225
1226 return CE;
1227}
1228
1229/// createGlobalVariableDIE - create global variable DIE.
1230void CompileUnit::createGlobalVariableDIE(const MDNode *N) {
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001231 // Check for pre-existence.
Devang Patel49e2f032011-08-18 22:21:50 +00001232 if (getDIE(N))
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001233 return;
1234
Devang Patel49e2f032011-08-18 22:21:50 +00001235 DIGlobalVariable GV(N);
Devang Patel28bea082011-08-18 23:17:55 +00001236 if (!GV.Verify())
1237 return;
1238
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001239 DIE *VariableDIE = new DIE(GV.getTag());
Devang Patel49e2f032011-08-18 22:21:50 +00001240 // Add to map.
1241 insertDIE(N, VariableDIE);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001242
1243 // Add name.
Nick Lewycky390c40d2011-10-27 06:44:11 +00001244 addString(VariableDIE, dwarf::DW_AT_name, GV.getDisplayName());
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001245 StringRef LinkageName = GV.getLinkageName();
Devang Patel49e2f032011-08-18 22:21:50 +00001246 bool isGlobalVariable = GV.getGlobal() != NULL;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001247 if (!LinkageName.empty() && isGlobalVariable)
Nick Lewycky746cb672011-10-26 22:55:33 +00001248 addString(VariableDIE, dwarf::DW_AT_MIPS_linkage_name,
Nick Lewycky390c40d2011-10-27 06:44:11 +00001249 getRealLinkageName(LinkageName));
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001250 // Add type.
Devang Patel49e2f032011-08-18 22:21:50 +00001251 DIType GTy = GV.getType();
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001252 addType(VariableDIE, GTy);
1253
1254 // Add scoping info.
Eric Christopherdfa30e12011-11-09 05:24:07 +00001255 if (!GV.isLocalToUnit())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001256 addFlag(VariableDIE, dwarf::DW_AT_external);
Eric Christopherdfa30e12011-11-09 05:24:07 +00001257
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001258 // Add line number info.
1259 addSourceLine(VariableDIE, GV);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001260 // Add to context owner.
1261 DIDescriptor GVContext = GV.getContext();
1262 addToContextOwner(VariableDIE, GVContext);
1263 // Add location.
Eric Christopher09ac3d82011-11-07 09:24:32 +00001264 bool addToAccelTable = false;
Eric Christopherd61c34b2011-11-11 03:16:32 +00001265 DIE *VariableSpecDIE = NULL;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001266 if (isGlobalVariable) {
Eric Christopher09ac3d82011-11-07 09:24:32 +00001267 addToAccelTable = true;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001268 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
1269 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
1270 addLabel(Block, 0, dwarf::DW_FORM_udata,
1271 Asm->Mang->getSymbol(GV.getGlobal()));
1272 // Do not create specification DIE if context is either compile unit
1273 // or a subprogram.
Devang Patel1dd4e562011-09-21 23:41:11 +00001274 if (GVContext && GV.isDefinition() && !GVContext.isCompileUnit() &&
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001275 !GVContext.isFile() && !isSubprogramContext(GVContext)) {
1276 // Create specification DIE.
Eric Christopherd117fbb2011-11-11 01:55:22 +00001277 VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001278 addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
1279 dwarf::DW_FORM_ref4, VariableDIE);
1280 addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
Eric Christopher873cf0a2012-08-24 01:14:27 +00001281 addFlag(VariableDIE, dwarf::DW_AT_declaration);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001282 addDie(VariableSpecDIE);
1283 } else {
1284 addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
Eric Christopher09ac3d82011-11-07 09:24:32 +00001285 }
Eric Christopher8b4310b2012-11-21 00:34:38 +00001286 } else if (const ConstantInt *CI =
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001287 dyn_cast_or_null<ConstantInt>(GV.getConstant()))
1288 addConstantValue(VariableDIE, CI, GTy.isUnsignedDIType());
1289 else if (const ConstantExpr *CE = getMergedGlobalExpr(N->getOperand(11))) {
Eric Christopher09ac3d82011-11-07 09:24:32 +00001290 addToAccelTable = true;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001291 // GV is a merged global.
1292 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
1293 Value *Ptr = CE->getOperand(0);
1294 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
1295 addLabel(Block, 0, dwarf::DW_FORM_udata,
1296 Asm->Mang->getSymbol(cast<GlobalValue>(Ptr)));
1297 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1298 SmallVector<Value*, 3> Idx(CE->op_begin()+1, CE->op_end());
Eric Christopher8b4310b2012-11-21 00:34:38 +00001299 addUInt(Block, 0, dwarf::DW_FORM_udata,
Micah Villmow3574eca2012-10-08 16:38:25 +00001300 Asm->getDataLayout().getIndexedOffset(Ptr->getType(), Idx));
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001301 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1302 addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
1303 }
1304
Eric Christopherd117fbb2011-11-11 01:55:22 +00001305 if (addToAccelTable) {
1306 DIE *AddrDIE = VariableSpecDIE ? VariableSpecDIE : VariableDIE;
1307 addAccelName(GV.getName(), AddrDIE);
Eric Christopher09ac3d82011-11-07 09:24:32 +00001308
Eric Christopherd117fbb2011-11-11 01:55:22 +00001309 // If the linkage name is different than the name, go ahead and output
1310 // that as well into the name table.
1311 if (GV.getLinkageName() != "" && GV.getName() != GV.getLinkageName())
1312 addAccelName(GV.getLinkageName(), AddrDIE);
1313 }
Eric Christopher74d8a872011-11-08 21:56:23 +00001314
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001315 return;
1316}
1317
Devang Patel161b2f42011-04-12 23:21:44 +00001318/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
Eric Christopher4d069bf2012-05-22 18:45:24 +00001319void CompileUnit::constructSubrangeDIE(DIE &Buffer, DISubrange SR,
1320 DIE *IndexTy) {
Devang Patel161b2f42011-04-12 23:21:44 +00001321 DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type);
1322 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IndexTy);
Devang Patel161b2f42011-04-12 23:21:44 +00001323
Bill Wendling222c2fd2012-12-06 07:38:10 +00001324 // The LowerBound value defines the lower bounds which is typically zero for
1325 // C/C++. The Count value is the number of elements. Values are 64 bit. If
1326 // Count == -1 then the array is unbounded and we do not emit
1327 // DW_AT_lower_bound and DW_AT_upper_bound attributes. If LowerBound == 0 and
1328 // Count == 0, then the array has zero elements in which case we do not emit
1329 // an upper bound.
1330 int64_t LowerBound = SR.getLo();
Bill Wendling6afe4782012-12-06 07:55:19 +00001331 int64_t DefaultLowerBound = getDefaultLowerBound();
Bill Wendling9493dae2012-12-04 21:34:03 +00001332 int64_t Count = SR.getCount();
Devang Patel161b2f42011-04-12 23:21:44 +00001333
Bill Wendling6afe4782012-12-06 07:55:19 +00001334 if (DefaultLowerBound == -1 || LowerBound != DefaultLowerBound)
Bill Wendling222c2fd2012-12-06 07:38:10 +00001335 addUInt(DW_Subrange, dwarf::DW_AT_lower_bound, 0, LowerBound);
1336
1337 if (Count != -1 && Count != 0)
Bill Wendling9493dae2012-12-04 21:34:03 +00001338 // FIXME: An unbounded array should reference the expression that defines
1339 // the array.
Bill Wendling222c2fd2012-12-06 07:38:10 +00001340 addUInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, LowerBound + Count - 1);
Bill Wendling9493dae2012-12-04 21:34:03 +00001341
Devang Patel161b2f42011-04-12 23:21:44 +00001342 Buffer.addChild(DW_Subrange);
1343}
1344
1345/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
1346void CompileUnit::constructArrayTypeDIE(DIE &Buffer,
1347 DICompositeType *CTy) {
1348 Buffer.setTag(dwarf::DW_TAG_array_type);
Eric Christopher9a1e0e22013-01-08 01:53:52 +00001349 if (CTy->isVector())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001350 addFlag(&Buffer, dwarf::DW_AT_GNU_vector);
Devang Patel161b2f42011-04-12 23:21:44 +00001351
1352 // Emit derived type.
1353 addType(&Buffer, CTy->getTypeDerivedFrom());
1354 DIArray Elements = CTy->getTypeArray();
1355
1356 // Get an anonymous type for index type.
Eric Christopher8cab6ed2013-01-04 21:51:53 +00001357 // FIXME: This type should be passed down from the front end
1358 // as different languages may have different sizes for indexes.
Devang Patel161b2f42011-04-12 23:21:44 +00001359 DIE *IdxTy = getIndexTyDie();
1360 if (!IdxTy) {
1361 // Construct an anonymous type for index type.
1362 IdxTy = new DIE(dwarf::DW_TAG_base_type);
Eric Christopher8cab6ed2013-01-04 21:51:53 +00001363 addString(IdxTy, dwarf::DW_AT_name, "int");
Devang Patel161b2f42011-04-12 23:21:44 +00001364 addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t));
1365 addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
1366 dwarf::DW_ATE_signed);
1367 addDie(IdxTy);
1368 setIndexTyDie(IdxTy);
1369 }
1370
1371 // Add subranges to array type.
1372 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
1373 DIDescriptor Element = Elements.getElement(i);
1374 if (Element.getTag() == dwarf::DW_TAG_subrange_type)
1375 constructSubrangeDIE(Buffer, DISubrange(Element), IdxTy);
1376 }
1377}
1378
1379/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
1380DIE *CompileUnit::constructEnumTypeDIE(DIEnumerator ETy) {
1381 DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator);
1382 StringRef Name = ETy.getName();
Nick Lewycky390c40d2011-10-27 06:44:11 +00001383 addString(Enumerator, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +00001384 int64_t Value = ETy.getEnumValue();
1385 addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value);
1386 return Enumerator;
1387}
1388
Devang Pateldbc64af2011-08-15 17:24:54 +00001389/// constructContainingTypeDIEs - Construct DIEs for types that contain
1390/// vtables.
1391void CompileUnit::constructContainingTypeDIEs() {
1392 for (DenseMap<DIE *, const MDNode *>::iterator CI = ContainingTypeMap.begin(),
1393 CE = ContainingTypeMap.end(); CI != CE; ++CI) {
1394 DIE *SPDie = CI->first;
1395 const MDNode *N = CI->second;
1396 if (!N) continue;
1397 DIE *NDie = getDIE(N);
1398 if (!NDie) continue;
1399 addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
1400 }
1401}
1402
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001403/// constructVariableDIE - Construct a DIE for the given DbgVariable.
1404DIE *CompileUnit::constructVariableDIE(DbgVariable *DV, bool isScopeAbstract) {
1405 StringRef Name = DV->getName();
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001406
1407 // Translate tag to proper Dwarf tag.
1408 unsigned Tag = DV->getTag();
1409
1410 // Define variable debug information entry.
1411 DIE *VariableDie = new DIE(Tag);
1412 DbgVariable *AbsVar = DV->getAbstractVariable();
1413 DIE *AbsDIE = AbsVar ? AbsVar->getDIE() : NULL;
1414 if (AbsDIE)
1415 addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin,
1416 dwarf::DW_FORM_ref4, AbsDIE);
1417 else {
Nick Lewycky390c40d2011-10-27 06:44:11 +00001418 addString(VariableDie, dwarf::DW_AT_name, Name);
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001419 addSourceLine(VariableDie, DV->getVariable());
1420 addType(VariableDie, DV->getType());
1421 }
1422
1423 if (DV->isArtificial())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001424 addFlag(VariableDie, dwarf::DW_AT_artificial);
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001425
1426 if (isScopeAbstract) {
1427 DV->setDIE(VariableDie);
1428 return VariableDie;
1429 }
1430
1431 // Add variable address.
1432
1433 unsigned Offset = DV->getDotDebugLocOffset();
1434 if (Offset != ~0U) {
1435 addLabel(VariableDie, dwarf::DW_AT_location,
1436 dwarf::DW_FORM_data4,
1437 Asm->GetTempSymbol("debug_loc", Offset));
1438 DV->setDIE(VariableDie);
1439 return VariableDie;
1440 }
1441
Eric Christopher8cf5e742011-10-03 15:49:20 +00001442 // Check if variable is described by a DBG_VALUE instruction.
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001443 if (const MachineInstr *DVInsn = DV->getMInsn()) {
1444 bool updated = false;
1445 if (DVInsn->getNumOperands() == 3) {
1446 if (DVInsn->getOperand(0).isReg()) {
1447 const MachineOperand RegOp = DVInsn->getOperand(0);
1448 const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
1449 if (DVInsn->getOperand(1).isImm() &&
1450 TRI->getFrameRegister(*Asm->MF) == RegOp.getReg()) {
1451 unsigned FrameReg = 0;
1452 const TargetFrameLowering *TFI = Asm->TM.getFrameLowering();
Eric Christopher8b4310b2012-11-21 00:34:38 +00001453 int Offset =
1454 TFI->getFrameIndexReference(*Asm->MF,
1455 DVInsn->getOperand(1).getImm(),
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001456 FrameReg);
1457 MachineLocation Location(FrameReg, Offset);
1458 addVariableAddress(DV, VariableDie, Location);
Eric Christopher8b4310b2012-11-21 00:34:38 +00001459
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001460 } else if (RegOp.getReg())
Eric Christopher8b4310b2012-11-21 00:34:38 +00001461 addVariableAddress(DV, VariableDie,
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001462 MachineLocation(RegOp.getReg()));
1463 updated = true;
1464 }
1465 else if (DVInsn->getOperand(0).isImm())
Eric Christopher8b4310b2012-11-21 00:34:38 +00001466 updated =
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001467 addConstantValue(VariableDie, DVInsn->getOperand(0),
1468 DV->getType());
1469 else if (DVInsn->getOperand(0).isFPImm())
1470 updated =
1471 addConstantFPValue(VariableDie, DVInsn->getOperand(0));
1472 else if (DVInsn->getOperand(0).isCImm())
1473 updated =
Eric Christopher8b4310b2012-11-21 00:34:38 +00001474 addConstantValue(VariableDie,
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001475 DVInsn->getOperand(0).getCImm(),
1476 DV->getType().isUnsignedDIType());
1477 } else {
Eric Christopher8b4310b2012-11-21 00:34:38 +00001478 addVariableAddress(DV, VariableDie,
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001479 Asm->getDebugValueLocation(DVInsn));
1480 updated = true;
1481 }
1482 if (!updated) {
1483 // If variableDie is not updated then DBG_VALUE instruction does not
1484 // have valid variable info.
1485 delete VariableDie;
1486 return NULL;
1487 }
1488 DV->setDIE(VariableDie);
1489 return VariableDie;
1490 } else {
1491 // .. else use frame index.
1492 int FI = DV->getFrameIndex();
1493 if (FI != ~0) {
1494 unsigned FrameReg = 0;
1495 const TargetFrameLowering *TFI = Asm->TM.getFrameLowering();
Eric Christopher8b4310b2012-11-21 00:34:38 +00001496 int Offset =
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001497 TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg);
1498 MachineLocation Location(FrameReg, Offset);
1499 addVariableAddress(DV, VariableDie, Location);
1500 }
1501 }
1502
1503 DV->setDIE(VariableDie);
1504 return VariableDie;
1505}
1506
Devang Patel161b2f42011-04-12 23:21:44 +00001507/// createMemberDIE - Create new member DIE.
1508DIE *CompileUnit::createMemberDIE(DIDerivedType DT) {
1509 DIE *MemberDie = new DIE(DT.getTag());
1510 StringRef Name = DT.getName();
1511 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001512 addString(MemberDie, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +00001513
1514 addType(MemberDie, DT.getTypeDerivedFrom());
1515
1516 addSourceLine(MemberDie, DT);
1517
1518 DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
1519 addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
1520
1521 uint64_t Size = DT.getSizeInBits();
1522 uint64_t FieldSize = DT.getOriginalTypeSize();
1523
1524 if (Size != FieldSize) {
1525 // Handle bitfield.
1526 addUInt(MemberDie, dwarf::DW_AT_byte_size, 0, DT.getOriginalTypeSize()>>3);
1527 addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits());
1528
1529 uint64_t Offset = DT.getOffsetInBits();
1530 uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
1531 uint64_t HiMark = (Offset + FieldSize) & AlignMask;
1532 uint64_t FieldOffset = (HiMark - FieldSize);
1533 Offset -= FieldOffset;
1534
1535 // Maybe we need to work from the other end.
Micah Villmow3574eca2012-10-08 16:38:25 +00001536 if (Asm->getDataLayout().isLittleEndian())
Devang Patel161b2f42011-04-12 23:21:44 +00001537 Offset = FieldSize - (Offset + Size);
1538 addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
1539
1540 // Here WD_AT_data_member_location points to the anonymous
1541 // field that includes this bit field.
1542 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, FieldOffset >> 3);
1543
1544 } else
1545 // This is not a bitfield.
1546 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);
1547
1548 if (DT.getTag() == dwarf::DW_TAG_inheritance
1549 && DT.isVirtual()) {
1550
1551 // For C++, virtual base classes are not at fixed offset. Use following
1552 // expression to extract appropriate offset from vtable.
1553 // BaseAddr = ObAddr + *((*ObAddr) - Offset)
1554
1555 DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock();
1556 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
1557 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1558 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1559 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits());
1560 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
1561 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1562 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1563
1564 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0,
1565 VBaseLocationDie);
1566 } else
1567 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
1568
1569 if (DT.isProtected())
Nick Lewycky13aaca52011-12-13 05:09:11 +00001570 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +00001571 dwarf::DW_ACCESS_protected);
1572 else if (DT.isPrivate())
Nick Lewycky13aaca52011-12-13 05:09:11 +00001573 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +00001574 dwarf::DW_ACCESS_private);
1575 // Otherwise C++ member and base classes are considered public.
Eric Christopher8b4310b2012-11-21 00:34:38 +00001576 else
Nick Lewycky13aaca52011-12-13 05:09:11 +00001577 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +00001578 dwarf::DW_ACCESS_public);
1579 if (DT.isVirtual())
Nick Lewycky798313d2011-12-14 00:56:07 +00001580 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +00001581 dwarf::DW_VIRTUALITY_virtual);
Devang Patele9db5e22011-04-16 00:11:51 +00001582
1583 // Objective-C properties.
Devang Patel6588abf2012-02-06 17:49:43 +00001584 if (MDNode *PNode = DT.getObjCProperty())
1585 if (DIEEntry *PropertyDie = getDIEEntry(PNode))
Eric Christopher8b4310b2012-11-21 00:34:38 +00001586 MemberDie->addValue(dwarf::DW_AT_APPLE_property, dwarf::DW_FORM_ref4,
Devang Patel6588abf2012-02-06 17:49:43 +00001587 PropertyDie);
1588
David Blaikie01bc2b32012-12-13 22:43:07 +00001589 if (DT.isArtificial())
1590 addFlag(MemberDie, dwarf::DW_AT_artificial);
1591
Devang Patel9e11eb12012-02-04 01:30:32 +00001592 // This is only for backward compatibility.
Devang Patele9db5e22011-04-16 00:11:51 +00001593 StringRef PropertyName = DT.getObjCPropertyName();
1594 if (!PropertyName.empty()) {
Nick Lewycky390c40d2011-10-27 06:44:11 +00001595 addString(MemberDie, dwarf::DW_AT_APPLE_property_name, PropertyName);
Devang Patele9db5e22011-04-16 00:11:51 +00001596 StringRef GetterName = DT.getObjCPropertyGetterName();
1597 if (!GetterName.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001598 addString(MemberDie, dwarf::DW_AT_APPLE_property_getter, GetterName);
Devang Patele9db5e22011-04-16 00:11:51 +00001599 StringRef SetterName = DT.getObjCPropertySetterName();
1600 if (!SetterName.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001601 addString(MemberDie, dwarf::DW_AT_APPLE_property_setter, SetterName);
Devang Patele9db5e22011-04-16 00:11:51 +00001602 unsigned PropertyAttributes = 0;
1603 if (DT.isReadOnlyObjCProperty())
1604 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readonly;
1605 if (DT.isReadWriteObjCProperty())
1606 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readwrite;
1607 if (DT.isAssignObjCProperty())
1608 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_assign;
1609 if (DT.isRetainObjCProperty())
1610 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_retain;
1611 if (DT.isCopyObjCProperty())
1612 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_copy;
1613 if (DT.isNonAtomicObjCProperty())
1614 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_nonatomic;
1615 if (PropertyAttributes)
Eric Christopher8b4310b2012-11-21 00:34:38 +00001616 addUInt(MemberDie, dwarf::DW_AT_APPLE_property_attribute, 0,
Devang Patele9db5e22011-04-16 00:11:51 +00001617 PropertyAttributes);
1618 }
Devang Patel161b2f42011-04-12 23:21:44 +00001619 return MemberDie;
1620}