blob: 372f98da3d9f197b54a5d6228fbbda7a4ed32c13 [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) {
828 case dwarf::DW_TAG_vector_type:
829 case dwarf::DW_TAG_array_type:
830 constructArrayTypeDIE(Buffer, &CTy);
831 break;
832 case dwarf::DW_TAG_enumeration_type: {
833 DIArray Elements = CTy.getTypeArray();
834
835 // Add enumerators to enumeration type.
836 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
837 DIE *ElemDie = NULL;
838 DIDescriptor Enum(Elements.getElement(i));
839 if (Enum.isEnumerator()) {
840 ElemDie = constructEnumTypeDIE(DIEnumerator(Enum));
841 Buffer.addChild(ElemDie);
842 }
843 }
Eric Christopherbb0f6ea2012-05-23 00:09:20 +0000844 DIType DTy = CTy.getTypeDerivedFrom();
845 if (DTy.Verify()) {
846 addType(&Buffer, DTy);
847 addUInt(&Buffer, dwarf::DW_AT_enum_class, dwarf::DW_FORM_flag, 1);
848 }
Devang Patel161b2f42011-04-12 23:21:44 +0000849 }
850 break;
851 case dwarf::DW_TAG_subroutine_type: {
852 // Add return type.
853 DIArray Elements = CTy.getTypeArray();
854 DIDescriptor RTy = Elements.getElement(0);
855 addType(&Buffer, DIType(RTy));
856
857 bool isPrototyped = true;
858 // Add arguments.
859 for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
860 DIDescriptor Ty = Elements.getElement(i);
861 if (Ty.isUnspecifiedParameter()) {
862 DIE *Arg = new DIE(dwarf::DW_TAG_unspecified_parameters);
863 Buffer.addChild(Arg);
864 isPrototyped = false;
865 } else {
866 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
867 addType(Arg, DIType(Ty));
868 Buffer.addChild(Arg);
869 }
870 }
Eric Christopher8b6fe6b2012-02-22 08:46:21 +0000871 // Add prototype flag if we're dealing with a C language and the
872 // function has been prototyped.
873 if (isPrototyped &&
Eric Christopher4d069bf2012-05-22 18:45:24 +0000874 (Language == dwarf::DW_LANG_C89 ||
875 Language == dwarf::DW_LANG_C99 ||
876 Language == dwarf::DW_LANG_ObjC))
Eric Christopher873cf0a2012-08-24 01:14:27 +0000877 addFlag(&Buffer, dwarf::DW_AT_prototyped);
Devang Patel161b2f42011-04-12 23:21:44 +0000878 }
879 break;
880 case dwarf::DW_TAG_structure_type:
881 case dwarf::DW_TAG_union_type:
882 case dwarf::DW_TAG_class_type: {
883 // Add elements to structure type.
884 DIArray Elements = CTy.getTypeArray();
885
886 // A forward struct declared type may not have elements available.
887 unsigned N = Elements.getNumElements();
888 if (N == 0)
889 break;
890
891 // Add elements to structure type.
892 for (unsigned i = 0; i < N; ++i) {
893 DIDescriptor Element = Elements.getElement(i);
894 DIE *ElemDie = NULL;
895 if (Element.isSubprogram()) {
896 DISubprogram SP(Element);
Devang Pateldbc64af2011-08-15 17:24:54 +0000897 ElemDie = getOrCreateSubprogramDIE(DISubprogram(Element));
Devang Patel161b2f42011-04-12 23:21:44 +0000898 if (SP.isProtected())
Nick Lewycky13aaca52011-12-13 05:09:11 +0000899 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +0000900 dwarf::DW_ACCESS_protected);
901 else if (SP.isPrivate())
Nick Lewycky13aaca52011-12-13 05:09:11 +0000902 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +0000903 dwarf::DW_ACCESS_private);
Eric Christopher8b4310b2012-11-21 00:34:38 +0000904 else
Nick Lewycky13aaca52011-12-13 05:09:11 +0000905 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +0000906 dwarf::DW_ACCESS_public);
907 if (SP.isExplicit())
Eric Christopher873cf0a2012-08-24 01:14:27 +0000908 addFlag(ElemDie, dwarf::DW_AT_explicit);
Devang Patel161b2f42011-04-12 23:21:44 +0000909 }
910 else if (Element.isVariable()) {
911 DIVariable DV(Element);
912 ElemDie = new DIE(dwarf::DW_TAG_variable);
Nick Lewycky390c40d2011-10-27 06:44:11 +0000913 addString(ElemDie, dwarf::DW_AT_name, DV.getName());
Devang Patel161b2f42011-04-12 23:21:44 +0000914 addType(ElemDie, DV.getType());
Eric Christopher873cf0a2012-08-24 01:14:27 +0000915 addFlag(ElemDie, dwarf::DW_AT_declaration);
916 addFlag(ElemDie, dwarf::DW_AT_external);
Devang Patel161b2f42011-04-12 23:21:44 +0000917 addSourceLine(ElemDie, DV);
Eric Christopher663e0cf2012-03-28 07:34:31 +0000918 } else if (Element.isDerivedType()) {
Eric Christopher4d069bf2012-05-22 18:45:24 +0000919 DIDerivedType DDTy(Element);
920 if (DDTy.getTag() == dwarf::DW_TAG_friend) {
921 ElemDie = new DIE(dwarf::DW_TAG_friend);
922 addType(ElemDie, DDTy.getTypeDerivedFrom(), dwarf::DW_AT_friend);
923 } else
924 ElemDie = createMemberDIE(DIDerivedType(Element));
Eric Christopher663e0cf2012-03-28 07:34:31 +0000925 } else if (Element.isObjCProperty()) {
Devang Patel30d409c2012-02-07 23:33:58 +0000926 DIObjCProperty Property(Element);
927 ElemDie = new DIE(Property.getTag());
928 StringRef PropertyName = Property.getObjCPropertyName();
929 addString(ElemDie, dwarf::DW_AT_APPLE_property_name, PropertyName);
Eric Christopher4d069bf2012-05-22 18:45:24 +0000930 addType(ElemDie, Property.getType());
931 addSourceLine(ElemDie, Property);
Devang Patel30d409c2012-02-07 23:33:58 +0000932 StringRef GetterName = Property.getObjCPropertyGetterName();
933 if (!GetterName.empty())
934 addString(ElemDie, dwarf::DW_AT_APPLE_property_getter, GetterName);
935 StringRef SetterName = Property.getObjCPropertySetterName();
936 if (!SetterName.empty())
937 addString(ElemDie, dwarf::DW_AT_APPLE_property_setter, SetterName);
938 unsigned PropertyAttributes = 0;
Devang Patel9e11eb12012-02-04 01:30:32 +0000939 if (Property.isReadOnlyObjCProperty())
940 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readonly;
941 if (Property.isReadWriteObjCProperty())
942 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readwrite;
943 if (Property.isAssignObjCProperty())
944 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_assign;
945 if (Property.isRetainObjCProperty())
946 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_retain;
947 if (Property.isCopyObjCProperty())
948 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_copy;
949 if (Property.isNonAtomicObjCProperty())
950 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_nonatomic;
951 if (PropertyAttributes)
Eric Christopher8b4310b2012-11-21 00:34:38 +0000952 addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute, 0,
Devang Patel9e11eb12012-02-04 01:30:32 +0000953 PropertyAttributes);
Devang Patel6588abf2012-02-06 17:49:43 +0000954
Devang Patel30d409c2012-02-07 23:33:58 +0000955 DIEEntry *Entry = getDIEEntry(Element);
956 if (!Entry) {
957 Entry = createDIEEntry(ElemDie);
958 insertDIEEntry(Element, Entry);
959 }
Devang Patel9e11eb12012-02-04 01:30:32 +0000960 } else
Devang Patel161b2f42011-04-12 23:21:44 +0000961 continue;
962 Buffer.addChild(ElemDie);
963 }
964
965 if (CTy.isAppleBlockExtension())
Eric Christopher873cf0a2012-08-24 01:14:27 +0000966 addFlag(&Buffer, dwarf::DW_AT_APPLE_block);
Devang Patel161b2f42011-04-12 23:21:44 +0000967
Devang Patel161b2f42011-04-12 23:21:44 +0000968 DICompositeType ContainingType = CTy.getContainingType();
969 if (DIDescriptor(ContainingType).isCompositeType())
970 addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
971 getOrCreateTypeDIE(DIType(ContainingType)));
972 else {
973 DIDescriptor Context = CTy.getContext();
974 addToContextOwner(&Buffer, Context);
975 }
976
Devang Patel201e6cd2011-05-12 21:29:42 +0000977 if (CTy.isObjcClassComplete())
Eric Christopher873cf0a2012-08-24 01:14:27 +0000978 addFlag(&Buffer, dwarf::DW_AT_APPLE_objc_complete_type);
Devang Patelb11f80e2011-05-12 19:06:16 +0000979
Eric Christopher1a8e8862011-12-16 23:42:42 +0000980 // Add template parameters to a class, structure or union types.
981 // FIXME: The support isn't in the metadata for this yet.
982 if (Tag == dwarf::DW_TAG_class_type ||
983 Tag == dwarf::DW_TAG_structure_type ||
984 Tag == dwarf::DW_TAG_union_type)
Devang Patel161b2f42011-04-12 23:21:44 +0000985 addTemplateParams(Buffer, CTy.getTemplateParams());
986
987 break;
988 }
989 default:
990 break;
991 }
992
993 // Add name if not anonymous or intermediate type.
994 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000995 addString(&Buffer, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +0000996
Eric Christopher4a5d8392012-05-22 18:45:18 +0000997 if (Tag == dwarf::DW_TAG_enumeration_type ||
998 Tag == dwarf::DW_TAG_class_type ||
999 Tag == dwarf::DW_TAG_structure_type ||
1000 Tag == dwarf::DW_TAG_union_type) {
Devang Patel161b2f42011-04-12 23:21:44 +00001001 // Add size if non-zero (derived types might be zero-sized.)
Eric Christopherfc4199b2012-06-01 00:22:32 +00001002 // TODO: Do we care about size for enum forward declarations?
Devang Patel161b2f42011-04-12 23:21:44 +00001003 if (Size)
1004 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
Eric Christopherfc4199b2012-06-01 00:22:32 +00001005 else if (!CTy.isForwardDecl())
Devang Patel161b2f42011-04-12 23:21:44 +00001006 // Add zero size if it is not a forward declaration.
Eric Christopherfc4199b2012-06-01 00:22:32 +00001007 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, 0);
1008
1009 // If we're a forward decl, say so.
1010 if (CTy.isForwardDecl())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001011 addFlag(&Buffer, dwarf::DW_AT_declaration);
Devang Patel161b2f42011-04-12 23:21:44 +00001012
1013 // Add source line info if available.
1014 if (!CTy.isForwardDecl())
1015 addSourceLine(&Buffer, CTy);
Eric Christopher89388952012-03-07 00:15:19 +00001016
1017 // No harm in adding the runtime language to the declaration.
1018 unsigned RLang = CTy.getRunTimeLang();
1019 if (RLang)
1020 addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class,
1021 dwarf::DW_FORM_data1, RLang);
Devang Patel161b2f42011-04-12 23:21:44 +00001022 }
1023}
1024
Eric Christopher8b4310b2012-11-21 00:34:38 +00001025/// getOrCreateTemplateTypeParameterDIE - Find existing DIE or create new DIE
Devang Patel161b2f42011-04-12 23:21:44 +00001026/// for the given DITemplateTypeParameter.
1027DIE *
1028CompileUnit::getOrCreateTemplateTypeParameterDIE(DITemplateTypeParameter TP) {
1029 DIE *ParamDIE = getDIE(TP);
1030 if (ParamDIE)
1031 return ParamDIE;
1032
1033 ParamDIE = new DIE(dwarf::DW_TAG_template_type_parameter);
1034 addType(ParamDIE, TP.getType());
Nick Lewycky390c40d2011-10-27 06:44:11 +00001035 addString(ParamDIE, dwarf::DW_AT_name, TP.getName());
Devang Patel161b2f42011-04-12 23:21:44 +00001036 return ParamDIE;
1037}
1038
Eric Christopher8b4310b2012-11-21 00:34:38 +00001039/// getOrCreateTemplateValueParameterDIE - Find existing DIE or create new DIE
Devang Patel161b2f42011-04-12 23:21:44 +00001040/// for the given DITemplateValueParameter.
1041DIE *
Eric Christopher4d069bf2012-05-22 18:45:24 +00001042CompileUnit::getOrCreateTemplateValueParameterDIE(DITemplateValueParameter TPV){
Devang Patel161b2f42011-04-12 23:21:44 +00001043 DIE *ParamDIE = getDIE(TPV);
1044 if (ParamDIE)
1045 return ParamDIE;
1046
1047 ParamDIE = new DIE(dwarf::DW_TAG_template_value_parameter);
1048 addType(ParamDIE, TPV.getType());
1049 if (!TPV.getName().empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001050 addString(ParamDIE, dwarf::DW_AT_name, TPV.getName());
Eric Christopher8b4310b2012-11-21 00:34:38 +00001051 addUInt(ParamDIE, dwarf::DW_AT_const_value, dwarf::DW_FORM_udata,
Devang Patel161b2f42011-04-12 23:21:44 +00001052 TPV.getValue());
1053 return ParamDIE;
1054}
1055
Devang Patel31c5d052011-05-06 16:57:54 +00001056/// getOrCreateNameSpace - Create a DIE for DINameSpace.
1057DIE *CompileUnit::getOrCreateNameSpace(DINameSpace NS) {
1058 DIE *NDie = getDIE(NS);
1059 if (NDie)
1060 return NDie;
1061 NDie = new DIE(dwarf::DW_TAG_namespace);
1062 insertDIE(NS, NDie);
Eric Christopher09ac3d82011-11-07 09:24:32 +00001063 if (!NS.getName().empty()) {
Nick Lewycky390c40d2011-10-27 06:44:11 +00001064 addString(NDie, dwarf::DW_AT_name, NS.getName());
Eric Christopher09ac3d82011-11-07 09:24:32 +00001065 addAccelNamespace(NS.getName(), NDie);
1066 } else
1067 addAccelNamespace("(anonymous namespace)", NDie);
Devang Patel31c5d052011-05-06 16:57:54 +00001068 addSourceLine(NDie, NS);
1069 addToContextOwner(NDie, NS.getContext());
1070 return NDie;
1071}
1072
Devang Pateldbc64af2011-08-15 17:24:54 +00001073/// getRealLinkageName - If special LLVM prefix that is used to inform the asm
1074/// printer to not emit usual symbol prefix before the symbol name is used then
1075/// return linkage name after skipping this special LLVM prefix.
1076static StringRef getRealLinkageName(StringRef LinkageName) {
1077 char One = '\1';
1078 if (LinkageName.startswith(StringRef(&One, 1)))
1079 return LinkageName.substr(1);
1080 return LinkageName;
1081}
1082
1083/// getOrCreateSubprogramDIE - Create new DIE using SP.
1084DIE *CompileUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
1085 DIE *SPDie = getDIE(SP);
1086 if (SPDie)
1087 return SPDie;
1088
Peter Collingbourne27302f02012-05-27 18:36:44 +00001089 SPDie = new DIE(dwarf::DW_TAG_subprogram);
1090
1091 // DW_TAG_inlined_subroutine may refer to this DIE.
1092 insertDIE(SP, SPDie);
1093
Rafael Espindola01b55b42011-11-10 22:34:29 +00001094 DISubprogram SPDecl = SP.getFunctionDeclaration();
1095 DIE *DeclDie = NULL;
1096 if (SPDecl.isSubprogram()) {
1097 DeclDie = getOrCreateSubprogramDIE(SPDecl);
1098 }
1099
Devang Pateldbc64af2011-08-15 17:24:54 +00001100 // Add to context owner.
1101 addToContextOwner(SPDie, SP.getContext());
1102
1103 // Add function template parameters.
1104 addTemplateParams(*SPDie, SP.getTemplateParams());
1105
Eric Christophere9722e12012-04-16 23:54:23 +00001106 // Unfortunately this code needs to stay here instead of below the
1107 // AT_specification code in order to work around a bug in older
1108 // gdbs that requires the linkage name to resolve multiple template
1109 // functions.
Eric Christophercbbd5b12012-08-23 22:52:55 +00001110 // TODO: Remove this set of code when we get rid of the old gdb
1111 // compatibility.
Eric Christopher8d101c32012-03-15 08:19:33 +00001112 StringRef LinkageName = SP.getLinkageName();
Eric Christophercbbd5b12012-08-23 22:52:55 +00001113 if (!LinkageName.empty() && DD->useDarwinGDBCompat())
Eric Christopher8d101c32012-03-15 08:19:33 +00001114 addString(SPDie, dwarf::DW_AT_MIPS_linkage_name,
1115 getRealLinkageName(LinkageName));
1116
Devang Pateldbc64af2011-08-15 17:24:54 +00001117 // If this DIE is going to refer declaration info using AT_specification
1118 // then there is no need to add other attributes.
Rafael Espindola01b55b42011-11-10 22:34:29 +00001119 if (DeclDie) {
1120 // Refer function declaration directly.
1121 addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
1122 DeclDie);
1123
Devang Pateldbc64af2011-08-15 17:24:54 +00001124 return SPDie;
Rafael Espindola01b55b42011-11-10 22:34:29 +00001125 }
Devang Pateldbc64af2011-08-15 17:24:54 +00001126
Eric Christophercbbd5b12012-08-23 22:52:55 +00001127 // Add the linkage name if we have one.
1128 if (!LinkageName.empty() && !DD->useDarwinGDBCompat())
1129 addString(SPDie, dwarf::DW_AT_MIPS_linkage_name,
1130 getRealLinkageName(LinkageName));
1131
Devang Pateldbc64af2011-08-15 17:24:54 +00001132 // Constructors and operators for anonymous aggregates do not have names.
1133 if (!SP.getName().empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001134 addString(SPDie, dwarf::DW_AT_name, SP.getName());
Devang Pateldbc64af2011-08-15 17:24:54 +00001135
1136 addSourceLine(SPDie, SP);
1137
Eric Christopher8b6fe6b2012-02-22 08:46:21 +00001138 // Add the prototype if we have a prototype and we have a C like
1139 // language.
1140 if (SP.isPrototyped() &&
1141 (Language == dwarf::DW_LANG_C89 ||
1142 Language == dwarf::DW_LANG_C99 ||
1143 Language == dwarf::DW_LANG_ObjC))
Eric Christopher873cf0a2012-08-24 01:14:27 +00001144 addFlag(SPDie, dwarf::DW_AT_prototyped);
Devang Pateldbc64af2011-08-15 17:24:54 +00001145
1146 // Add Return Type.
1147 DICompositeType SPTy = SP.getType();
1148 DIArray Args = SPTy.getTypeArray();
1149 unsigned SPTag = SPTy.getTag();
1150
1151 if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type)
1152 addType(SPDie, SPTy);
1153 else
1154 addType(SPDie, DIType(Args.getElement(0)));
1155
1156 unsigned VK = SP.getVirtuality();
1157 if (VK) {
Nick Lewycky798313d2011-12-14 00:56:07 +00001158 addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, VK);
Devang Pateldbc64af2011-08-15 17:24:54 +00001159 DIEBlock *Block = getDIEBlock();
1160 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1161 addUInt(Block, 0, dwarf::DW_FORM_udata, SP.getVirtualIndex());
1162 addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
1163 ContainingTypeMap.insert(std::make_pair(SPDie,
1164 SP.getContainingType()));
1165 }
1166
1167 if (!SP.isDefinition()) {
Eric Christopher873cf0a2012-08-24 01:14:27 +00001168 addFlag(SPDie, dwarf::DW_AT_declaration);
Eric Christopher8b4310b2012-11-21 00:34:38 +00001169
Devang Pateldbc64af2011-08-15 17:24:54 +00001170 // Add arguments. Do not add arguments for subprogram definition. They will
1171 // be handled while processing variables.
1172 DICompositeType SPTy = SP.getType();
1173 DIArray Args = SPTy.getTypeArray();
1174 unsigned SPTag = SPTy.getTag();
1175
1176 if (SPTag == dwarf::DW_TAG_subroutine_type)
1177 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
1178 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
Eric Christopher5c38de92012-09-10 23:33:57 +00001179 DIType ATy = DIType(Args.getElement(i));
Devang Pateldbc64af2011-08-15 17:24:54 +00001180 addType(Arg, ATy);
1181 if (ATy.isArtificial())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001182 addFlag(Arg, dwarf::DW_AT_artificial);
Devang Pateldbc64af2011-08-15 17:24:54 +00001183 SPDie->addChild(Arg);
1184 }
1185 }
1186
1187 if (SP.isArtificial())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001188 addFlag(SPDie, dwarf::DW_AT_artificial);
Devang Pateldbc64af2011-08-15 17:24:54 +00001189
1190 if (!SP.isLocalToUnit())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001191 addFlag(SPDie, dwarf::DW_AT_external);
Devang Pateldbc64af2011-08-15 17:24:54 +00001192
1193 if (SP.isOptimized())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001194 addFlag(SPDie, dwarf::DW_AT_APPLE_optimized);
Devang Pateldbc64af2011-08-15 17:24:54 +00001195
1196 if (unsigned isa = Asm->getISAEncoding()) {
1197 addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa);
1198 }
1199
1200 return SPDie;
1201}
1202
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001203// Return const expression if value is a GEP to access merged global
1204// constant. e.g.
1205// i8* getelementptr ({ i8, i8, i8, i8 }* @_MergedGlobals, i32 0, i32 0)
1206static const ConstantExpr *getMergedGlobalExpr(const Value *V) {
1207 const ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(V);
1208 if (!CE || CE->getNumOperands() != 3 ||
1209 CE->getOpcode() != Instruction::GetElementPtr)
1210 return NULL;
1211
1212 // First operand points to a global struct.
1213 Value *Ptr = CE->getOperand(0);
1214 if (!isa<GlobalValue>(Ptr) ||
1215 !isa<StructType>(cast<PointerType>(Ptr->getType())->getElementType()))
1216 return NULL;
1217
1218 // Second operand is zero.
1219 const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CE->getOperand(1));
1220 if (!CI || !CI->isZero())
1221 return NULL;
1222
1223 // Third operand is offset.
1224 if (!isa<ConstantInt>(CE->getOperand(2)))
1225 return NULL;
1226
1227 return CE;
1228}
1229
1230/// createGlobalVariableDIE - create global variable DIE.
1231void CompileUnit::createGlobalVariableDIE(const MDNode *N) {
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001232 // Check for pre-existence.
Devang Patel49e2f032011-08-18 22:21:50 +00001233 if (getDIE(N))
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001234 return;
1235
Devang Patel49e2f032011-08-18 22:21:50 +00001236 DIGlobalVariable GV(N);
Devang Patel28bea082011-08-18 23:17:55 +00001237 if (!GV.Verify())
1238 return;
1239
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001240 DIE *VariableDIE = new DIE(GV.getTag());
Devang Patel49e2f032011-08-18 22:21:50 +00001241 // Add to map.
1242 insertDIE(N, VariableDIE);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001243
1244 // Add name.
Nick Lewycky390c40d2011-10-27 06:44:11 +00001245 addString(VariableDIE, dwarf::DW_AT_name, GV.getDisplayName());
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001246 StringRef LinkageName = GV.getLinkageName();
Devang Patel49e2f032011-08-18 22:21:50 +00001247 bool isGlobalVariable = GV.getGlobal() != NULL;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001248 if (!LinkageName.empty() && isGlobalVariable)
Nick Lewycky746cb672011-10-26 22:55:33 +00001249 addString(VariableDIE, dwarf::DW_AT_MIPS_linkage_name,
Nick Lewycky390c40d2011-10-27 06:44:11 +00001250 getRealLinkageName(LinkageName));
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001251 // Add type.
Devang Patel49e2f032011-08-18 22:21:50 +00001252 DIType GTy = GV.getType();
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001253 addType(VariableDIE, GTy);
1254
1255 // Add scoping info.
Eric Christopherdfa30e12011-11-09 05:24:07 +00001256 if (!GV.isLocalToUnit())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001257 addFlag(VariableDIE, dwarf::DW_AT_external);
Eric Christopherdfa30e12011-11-09 05:24:07 +00001258
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001259 // Add line number info.
1260 addSourceLine(VariableDIE, GV);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001261 // Add to context owner.
1262 DIDescriptor GVContext = GV.getContext();
1263 addToContextOwner(VariableDIE, GVContext);
1264 // Add location.
Eric Christopher09ac3d82011-11-07 09:24:32 +00001265 bool addToAccelTable = false;
Eric Christopherd61c34b2011-11-11 03:16:32 +00001266 DIE *VariableSpecDIE = NULL;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001267 if (isGlobalVariable) {
Eric Christopher09ac3d82011-11-07 09:24:32 +00001268 addToAccelTable = true;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001269 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
1270 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
1271 addLabel(Block, 0, dwarf::DW_FORM_udata,
1272 Asm->Mang->getSymbol(GV.getGlobal()));
1273 // Do not create specification DIE if context is either compile unit
1274 // or a subprogram.
Devang Patel1dd4e562011-09-21 23:41:11 +00001275 if (GVContext && GV.isDefinition() && !GVContext.isCompileUnit() &&
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001276 !GVContext.isFile() && !isSubprogramContext(GVContext)) {
1277 // Create specification DIE.
Eric Christopherd117fbb2011-11-11 01:55:22 +00001278 VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001279 addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
1280 dwarf::DW_FORM_ref4, VariableDIE);
1281 addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
Eric Christopher873cf0a2012-08-24 01:14:27 +00001282 addFlag(VariableDIE, dwarf::DW_AT_declaration);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001283 addDie(VariableSpecDIE);
1284 } else {
1285 addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
Eric Christopher09ac3d82011-11-07 09:24:32 +00001286 }
Eric Christopher8b4310b2012-11-21 00:34:38 +00001287 } else if (const ConstantInt *CI =
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001288 dyn_cast_or_null<ConstantInt>(GV.getConstant()))
1289 addConstantValue(VariableDIE, CI, GTy.isUnsignedDIType());
1290 else if (const ConstantExpr *CE = getMergedGlobalExpr(N->getOperand(11))) {
Eric Christopher09ac3d82011-11-07 09:24:32 +00001291 addToAccelTable = true;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001292 // GV is a merged global.
1293 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
1294 Value *Ptr = CE->getOperand(0);
1295 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
1296 addLabel(Block, 0, dwarf::DW_FORM_udata,
1297 Asm->Mang->getSymbol(cast<GlobalValue>(Ptr)));
1298 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1299 SmallVector<Value*, 3> Idx(CE->op_begin()+1, CE->op_end());
Eric Christopher8b4310b2012-11-21 00:34:38 +00001300 addUInt(Block, 0, dwarf::DW_FORM_udata,
Micah Villmow3574eca2012-10-08 16:38:25 +00001301 Asm->getDataLayout().getIndexedOffset(Ptr->getType(), Idx));
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001302 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1303 addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
1304 }
1305
Eric Christopherd117fbb2011-11-11 01:55:22 +00001306 if (addToAccelTable) {
1307 DIE *AddrDIE = VariableSpecDIE ? VariableSpecDIE : VariableDIE;
1308 addAccelName(GV.getName(), AddrDIE);
Eric Christopher09ac3d82011-11-07 09:24:32 +00001309
Eric Christopherd117fbb2011-11-11 01:55:22 +00001310 // If the linkage name is different than the name, go ahead and output
1311 // that as well into the name table.
1312 if (GV.getLinkageName() != "" && GV.getName() != GV.getLinkageName())
1313 addAccelName(GV.getLinkageName(), AddrDIE);
1314 }
Eric Christopher74d8a872011-11-08 21:56:23 +00001315
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001316 return;
1317}
1318
Devang Patel161b2f42011-04-12 23:21:44 +00001319/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
Eric Christopher4d069bf2012-05-22 18:45:24 +00001320void CompileUnit::constructSubrangeDIE(DIE &Buffer, DISubrange SR,
1321 DIE *IndexTy) {
Devang Patel161b2f42011-04-12 23:21:44 +00001322 DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type);
1323 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IndexTy);
Devang Patel161b2f42011-04-12 23:21:44 +00001324
Bill Wendling222c2fd2012-12-06 07:38:10 +00001325 // The LowerBound value defines the lower bounds which is typically zero for
1326 // C/C++. The Count value is the number of elements. Values are 64 bit. If
1327 // Count == -1 then the array is unbounded and we do not emit
1328 // DW_AT_lower_bound and DW_AT_upper_bound attributes. If LowerBound == 0 and
1329 // Count == 0, then the array has zero elements in which case we do not emit
1330 // an upper bound.
1331 int64_t LowerBound = SR.getLo();
Bill Wendling6afe4782012-12-06 07:55:19 +00001332 int64_t DefaultLowerBound = getDefaultLowerBound();
Bill Wendling9493dae2012-12-04 21:34:03 +00001333 int64_t Count = SR.getCount();
Devang Patel161b2f42011-04-12 23:21:44 +00001334
Bill Wendling6afe4782012-12-06 07:55:19 +00001335 if (DefaultLowerBound == -1 || LowerBound != DefaultLowerBound)
Bill Wendling222c2fd2012-12-06 07:38:10 +00001336 addUInt(DW_Subrange, dwarf::DW_AT_lower_bound, 0, LowerBound);
1337
1338 if (Count != -1 && Count != 0)
Bill Wendling9493dae2012-12-04 21:34:03 +00001339 // FIXME: An unbounded array should reference the expression that defines
1340 // the array.
Bill Wendling222c2fd2012-12-06 07:38:10 +00001341 addUInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, LowerBound + Count - 1);
Bill Wendling9493dae2012-12-04 21:34:03 +00001342
Devang Patel161b2f42011-04-12 23:21:44 +00001343 Buffer.addChild(DW_Subrange);
1344}
1345
1346/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
1347void CompileUnit::constructArrayTypeDIE(DIE &Buffer,
1348 DICompositeType *CTy) {
1349 Buffer.setTag(dwarf::DW_TAG_array_type);
1350 if (CTy->getTag() == dwarf::DW_TAG_vector_type)
Eric Christopher873cf0a2012-08-24 01:14:27 +00001351 addFlag(&Buffer, dwarf::DW_AT_GNU_vector);
Devang Patel161b2f42011-04-12 23:21:44 +00001352
1353 // Emit derived type.
1354 addType(&Buffer, CTy->getTypeDerivedFrom());
1355 DIArray Elements = CTy->getTypeArray();
1356
1357 // Get an anonymous type for index type.
Eric Christopher8cab6ed2013-01-04 21:51:53 +00001358 // FIXME: This type should be passed down from the front end
1359 // as different languages may have different sizes for indexes.
Devang Patel161b2f42011-04-12 23:21:44 +00001360 DIE *IdxTy = getIndexTyDie();
1361 if (!IdxTy) {
1362 // Construct an anonymous type for index type.
1363 IdxTy = new DIE(dwarf::DW_TAG_base_type);
Eric Christopher8cab6ed2013-01-04 21:51:53 +00001364 addString(IdxTy, dwarf::DW_AT_name, "int");
Devang Patel161b2f42011-04-12 23:21:44 +00001365 addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t));
1366 addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
1367 dwarf::DW_ATE_signed);
1368 addDie(IdxTy);
1369 setIndexTyDie(IdxTy);
1370 }
1371
1372 // Add subranges to array type.
1373 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
1374 DIDescriptor Element = Elements.getElement(i);
1375 if (Element.getTag() == dwarf::DW_TAG_subrange_type)
1376 constructSubrangeDIE(Buffer, DISubrange(Element), IdxTy);
1377 }
1378}
1379
1380/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
1381DIE *CompileUnit::constructEnumTypeDIE(DIEnumerator ETy) {
1382 DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator);
1383 StringRef Name = ETy.getName();
Nick Lewycky390c40d2011-10-27 06:44:11 +00001384 addString(Enumerator, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +00001385 int64_t Value = ETy.getEnumValue();
1386 addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value);
1387 return Enumerator;
1388}
1389
Devang Pateldbc64af2011-08-15 17:24:54 +00001390/// constructContainingTypeDIEs - Construct DIEs for types that contain
1391/// vtables.
1392void CompileUnit::constructContainingTypeDIEs() {
1393 for (DenseMap<DIE *, const MDNode *>::iterator CI = ContainingTypeMap.begin(),
1394 CE = ContainingTypeMap.end(); CI != CE; ++CI) {
1395 DIE *SPDie = CI->first;
1396 const MDNode *N = CI->second;
1397 if (!N) continue;
1398 DIE *NDie = getDIE(N);
1399 if (!NDie) continue;
1400 addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
1401 }
1402}
1403
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001404/// constructVariableDIE - Construct a DIE for the given DbgVariable.
1405DIE *CompileUnit::constructVariableDIE(DbgVariable *DV, bool isScopeAbstract) {
1406 StringRef Name = DV->getName();
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001407
1408 // Translate tag to proper Dwarf tag.
1409 unsigned Tag = DV->getTag();
1410
1411 // Define variable debug information entry.
1412 DIE *VariableDie = new DIE(Tag);
1413 DbgVariable *AbsVar = DV->getAbstractVariable();
1414 DIE *AbsDIE = AbsVar ? AbsVar->getDIE() : NULL;
1415 if (AbsDIE)
1416 addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin,
1417 dwarf::DW_FORM_ref4, AbsDIE);
1418 else {
Nick Lewycky390c40d2011-10-27 06:44:11 +00001419 addString(VariableDie, dwarf::DW_AT_name, Name);
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001420 addSourceLine(VariableDie, DV->getVariable());
1421 addType(VariableDie, DV->getType());
1422 }
1423
1424 if (DV->isArtificial())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001425 addFlag(VariableDie, dwarf::DW_AT_artificial);
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001426
1427 if (isScopeAbstract) {
1428 DV->setDIE(VariableDie);
1429 return VariableDie;
1430 }
1431
1432 // Add variable address.
1433
1434 unsigned Offset = DV->getDotDebugLocOffset();
1435 if (Offset != ~0U) {
1436 addLabel(VariableDie, dwarf::DW_AT_location,
1437 dwarf::DW_FORM_data4,
1438 Asm->GetTempSymbol("debug_loc", Offset));
1439 DV->setDIE(VariableDie);
1440 return VariableDie;
1441 }
1442
Eric Christopher8cf5e742011-10-03 15:49:20 +00001443 // Check if variable is described by a DBG_VALUE instruction.
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001444 if (const MachineInstr *DVInsn = DV->getMInsn()) {
1445 bool updated = false;
1446 if (DVInsn->getNumOperands() == 3) {
1447 if (DVInsn->getOperand(0).isReg()) {
1448 const MachineOperand RegOp = DVInsn->getOperand(0);
1449 const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
1450 if (DVInsn->getOperand(1).isImm() &&
1451 TRI->getFrameRegister(*Asm->MF) == RegOp.getReg()) {
1452 unsigned FrameReg = 0;
1453 const TargetFrameLowering *TFI = Asm->TM.getFrameLowering();
Eric Christopher8b4310b2012-11-21 00:34:38 +00001454 int Offset =
1455 TFI->getFrameIndexReference(*Asm->MF,
1456 DVInsn->getOperand(1).getImm(),
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001457 FrameReg);
1458 MachineLocation Location(FrameReg, Offset);
1459 addVariableAddress(DV, VariableDie, Location);
Eric Christopher8b4310b2012-11-21 00:34:38 +00001460
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001461 } else if (RegOp.getReg())
Eric Christopher8b4310b2012-11-21 00:34:38 +00001462 addVariableAddress(DV, VariableDie,
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001463 MachineLocation(RegOp.getReg()));
1464 updated = true;
1465 }
1466 else if (DVInsn->getOperand(0).isImm())
Eric Christopher8b4310b2012-11-21 00:34:38 +00001467 updated =
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001468 addConstantValue(VariableDie, DVInsn->getOperand(0),
1469 DV->getType());
1470 else if (DVInsn->getOperand(0).isFPImm())
1471 updated =
1472 addConstantFPValue(VariableDie, DVInsn->getOperand(0));
1473 else if (DVInsn->getOperand(0).isCImm())
1474 updated =
Eric Christopher8b4310b2012-11-21 00:34:38 +00001475 addConstantValue(VariableDie,
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001476 DVInsn->getOperand(0).getCImm(),
1477 DV->getType().isUnsignedDIType());
1478 } else {
Eric Christopher8b4310b2012-11-21 00:34:38 +00001479 addVariableAddress(DV, VariableDie,
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001480 Asm->getDebugValueLocation(DVInsn));
1481 updated = true;
1482 }
1483 if (!updated) {
1484 // If variableDie is not updated then DBG_VALUE instruction does not
1485 // have valid variable info.
1486 delete VariableDie;
1487 return NULL;
1488 }
1489 DV->setDIE(VariableDie);
1490 return VariableDie;
1491 } else {
1492 // .. else use frame index.
1493 int FI = DV->getFrameIndex();
1494 if (FI != ~0) {
1495 unsigned FrameReg = 0;
1496 const TargetFrameLowering *TFI = Asm->TM.getFrameLowering();
Eric Christopher8b4310b2012-11-21 00:34:38 +00001497 int Offset =
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001498 TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg);
1499 MachineLocation Location(FrameReg, Offset);
1500 addVariableAddress(DV, VariableDie, Location);
1501 }
1502 }
1503
1504 DV->setDIE(VariableDie);
1505 return VariableDie;
1506}
1507
Devang Patel161b2f42011-04-12 23:21:44 +00001508/// createMemberDIE - Create new member DIE.
1509DIE *CompileUnit::createMemberDIE(DIDerivedType DT) {
1510 DIE *MemberDie = new DIE(DT.getTag());
1511 StringRef Name = DT.getName();
1512 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001513 addString(MemberDie, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +00001514
1515 addType(MemberDie, DT.getTypeDerivedFrom());
1516
1517 addSourceLine(MemberDie, DT);
1518
1519 DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
1520 addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
1521
1522 uint64_t Size = DT.getSizeInBits();
1523 uint64_t FieldSize = DT.getOriginalTypeSize();
1524
1525 if (Size != FieldSize) {
1526 // Handle bitfield.
1527 addUInt(MemberDie, dwarf::DW_AT_byte_size, 0, DT.getOriginalTypeSize()>>3);
1528 addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits());
1529
1530 uint64_t Offset = DT.getOffsetInBits();
1531 uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
1532 uint64_t HiMark = (Offset + FieldSize) & AlignMask;
1533 uint64_t FieldOffset = (HiMark - FieldSize);
1534 Offset -= FieldOffset;
1535
1536 // Maybe we need to work from the other end.
Micah Villmow3574eca2012-10-08 16:38:25 +00001537 if (Asm->getDataLayout().isLittleEndian())
Devang Patel161b2f42011-04-12 23:21:44 +00001538 Offset = FieldSize - (Offset + Size);
1539 addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
1540
1541 // Here WD_AT_data_member_location points to the anonymous
1542 // field that includes this bit field.
1543 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, FieldOffset >> 3);
1544
1545 } else
1546 // This is not a bitfield.
1547 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);
1548
1549 if (DT.getTag() == dwarf::DW_TAG_inheritance
1550 && DT.isVirtual()) {
1551
1552 // For C++, virtual base classes are not at fixed offset. Use following
1553 // expression to extract appropriate offset from vtable.
1554 // BaseAddr = ObAddr + *((*ObAddr) - Offset)
1555
1556 DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock();
1557 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
1558 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1559 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1560 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits());
1561 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
1562 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1563 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1564
1565 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0,
1566 VBaseLocationDie);
1567 } else
1568 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
1569
1570 if (DT.isProtected())
Nick Lewycky13aaca52011-12-13 05:09:11 +00001571 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +00001572 dwarf::DW_ACCESS_protected);
1573 else if (DT.isPrivate())
Nick Lewycky13aaca52011-12-13 05:09:11 +00001574 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +00001575 dwarf::DW_ACCESS_private);
1576 // Otherwise C++ member and base classes are considered public.
Eric Christopher8b4310b2012-11-21 00:34:38 +00001577 else
Nick Lewycky13aaca52011-12-13 05:09:11 +00001578 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +00001579 dwarf::DW_ACCESS_public);
1580 if (DT.isVirtual())
Nick Lewycky798313d2011-12-14 00:56:07 +00001581 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +00001582 dwarf::DW_VIRTUALITY_virtual);
Devang Patele9db5e22011-04-16 00:11:51 +00001583
1584 // Objective-C properties.
Devang Patel6588abf2012-02-06 17:49:43 +00001585 if (MDNode *PNode = DT.getObjCProperty())
1586 if (DIEEntry *PropertyDie = getDIEEntry(PNode))
Eric Christopher8b4310b2012-11-21 00:34:38 +00001587 MemberDie->addValue(dwarf::DW_AT_APPLE_property, dwarf::DW_FORM_ref4,
Devang Patel6588abf2012-02-06 17:49:43 +00001588 PropertyDie);
1589
David Blaikie01bc2b32012-12-13 22:43:07 +00001590 if (DT.isArtificial())
1591 addFlag(MemberDie, dwarf::DW_AT_artificial);
1592
Devang Patel9e11eb12012-02-04 01:30:32 +00001593 // This is only for backward compatibility.
Devang Patele9db5e22011-04-16 00:11:51 +00001594 StringRef PropertyName = DT.getObjCPropertyName();
1595 if (!PropertyName.empty()) {
Nick Lewycky390c40d2011-10-27 06:44:11 +00001596 addString(MemberDie, dwarf::DW_AT_APPLE_property_name, PropertyName);
Devang Patele9db5e22011-04-16 00:11:51 +00001597 StringRef GetterName = DT.getObjCPropertyGetterName();
1598 if (!GetterName.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001599 addString(MemberDie, dwarf::DW_AT_APPLE_property_getter, GetterName);
Devang Patele9db5e22011-04-16 00:11:51 +00001600 StringRef SetterName = DT.getObjCPropertySetterName();
1601 if (!SetterName.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001602 addString(MemberDie, dwarf::DW_AT_APPLE_property_setter, SetterName);
Devang Patele9db5e22011-04-16 00:11:51 +00001603 unsigned PropertyAttributes = 0;
1604 if (DT.isReadOnlyObjCProperty())
1605 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readonly;
1606 if (DT.isReadWriteObjCProperty())
1607 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readwrite;
1608 if (DT.isAssignObjCProperty())
1609 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_assign;
1610 if (DT.isRetainObjCProperty())
1611 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_retain;
1612 if (DT.isCopyObjCProperty())
1613 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_copy;
1614 if (DT.isNonAtomicObjCProperty())
1615 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_nonatomic;
1616 if (PropertyAttributes)
Eric Christopher8b4310b2012-11-21 00:34:38 +00001617 addUInt(MemberDie, dwarf::DW_AT_APPLE_property_attribute, 0,
Devang Patele9db5e22011-04-16 00:11:51 +00001618 PropertyAttributes);
1619 }
Devang Patel161b2f42011-04-12 23:21:44 +00001620 return MemberDie;
1621}