blob: e573965ebe76bd7fc8adc649f4bfc491484caab0 [file] [log] [blame]
Devang Patel161b2f42011-04-12 23:21:44 +00001//===-- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Unit ------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains support for writing dwarf compile unit.
11//
12//===----------------------------------------------------------------------===//
13
14#define DEBUG_TYPE "dwarfdebug"
15
16#include "DwarfCompileUnit.h"
17#include "DwarfDebug.h"
18#include "llvm/Constants.h"
19#include "llvm/Analysis/DIBuilder.h"
20#include "llvm/Target/TargetData.h"
21#include "llvm/Target/TargetFrameLowering.h"
22#include "llvm/Target/TargetMachine.h"
23#include "llvm/Target/TargetRegisterInfo.h"
24#include "llvm/ADT/APFloat.h"
25#include "llvm/Support/ErrorHandling.h"
26
27using namespace llvm;
28
29/// CompileUnit - Compile unit constructor.
30CompileUnit::CompileUnit(unsigned I, DIE *D, AsmPrinter *A, DwarfDebug *DW)
31 : ID(I), CUDie(D), Asm(A), DD(DW), IndexTyDie(0) {
32 DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1);
33}
34
35/// ~CompileUnit - Destructor for compile unit.
36CompileUnit::~CompileUnit() {
37 for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
38 DIEBlocks[j]->~DIEBlock();
39}
40
41/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug
42/// information entry.
43DIEEntry *CompileUnit::createDIEEntry(DIE *Entry) {
44 DIEEntry *Value = new (DIEValueAllocator) DIEEntry(Entry);
45 return Value;
46}
47
48/// addUInt - Add an unsigned integer attribute data and value.
49///
50void CompileUnit::addUInt(DIE *Die, unsigned Attribute,
51 unsigned Form, uint64_t Integer) {
52 if (!Form) Form = DIEInteger::BestForm(false, Integer);
53 DIEValue *Value = Integer == 1 ?
54 DIEIntegerOne : new (DIEValueAllocator) DIEInteger(Integer);
55 Die->addValue(Attribute, Form, Value);
56}
57
58/// addSInt - Add an signed integer attribute data and value.
59///
60void CompileUnit::addSInt(DIE *Die, unsigned Attribute,
61 unsigned Form, int64_t Integer) {
62 if (!Form) Form = DIEInteger::BestForm(true, Integer);
63 DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
64 Die->addValue(Attribute, Form, Value);
65}
66
67/// addString - Add a string attribute data and value. DIEString only
68/// keeps string reference.
69void CompileUnit::addString(DIE *Die, unsigned Attribute, unsigned Form,
70 StringRef String) {
71 DIEValue *Value = new (DIEValueAllocator) DIEString(String);
72 Die->addValue(Attribute, Form, Value);
73}
74
75/// addLabel - Add a Dwarf label attribute data and value.
76///
77void CompileUnit::addLabel(DIE *Die, unsigned Attribute, unsigned Form,
78 const MCSymbol *Label) {
79 DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
80 Die->addValue(Attribute, Form, Value);
81}
82
83/// addDelta - Add a label delta attribute data and value.
84///
85void CompileUnit::addDelta(DIE *Die, unsigned Attribute, unsigned Form,
86 const MCSymbol *Hi, const MCSymbol *Lo) {
87 DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo);
88 Die->addValue(Attribute, Form, Value);
89}
90
91/// addDIEEntry - Add a DIE attribute data and value.
92///
93void CompileUnit::addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form,
94 DIE *Entry) {
95 Die->addValue(Attribute, Form, createDIEEntry(Entry));
96}
97
98
99/// addBlock - Add block data.
100///
101void CompileUnit::addBlock(DIE *Die, unsigned Attribute, unsigned Form,
102 DIEBlock *Block) {
103 Block->ComputeSize(Asm);
104 DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.
105 Die->addValue(Attribute, Block->BestForm(), Block);
106}
107
108/// addSourceLine - Add location information to specified debug information
109/// entry.
110void CompileUnit::addSourceLine(DIE *Die, DIVariable V) {
111 // Verify variable.
112 if (!V.Verify())
113 return;
114
115 unsigned Line = V.getLineNumber();
116 if (Line == 0)
117 return;
118 unsigned FileID = DD->GetOrCreateSourceID(V.getContext().getFilename(),
119 V.getContext().getDirectory());
120 assert(FileID && "Invalid file id");
121 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
122 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
123}
124
125/// addSourceLine - Add location information to specified debug information
126/// entry.
127void CompileUnit::addSourceLine(DIE *Die, DIGlobalVariable G) {
128 // Verify global variable.
129 if (!G.Verify())
130 return;
131
132 unsigned Line = G.getLineNumber();
133 if (Line == 0)
134 return;
135 unsigned FileID = DD->GetOrCreateSourceID(G.getContext().getFilename(),
136 G.getContext().getDirectory());
137 assert(FileID && "Invalid file id");
138 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
139 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
140}
141
142/// addSourceLine - Add location information to specified debug information
143/// entry.
144void CompileUnit::addSourceLine(DIE *Die, DISubprogram SP) {
145 // Verify subprogram.
146 if (!SP.Verify())
147 return;
148 // If the line number is 0, don't add it.
149 if (SP.getLineNumber() == 0)
150 return;
151
152 unsigned Line = SP.getLineNumber();
153 if (!SP.getContext().Verify())
154 return;
155 unsigned FileID = DD->GetOrCreateSourceID(SP.getFilename(), SP.getDirectory());
156 assert(FileID && "Invalid file id");
157 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
158 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
159}
160
161/// addSourceLine - Add location information to specified debug information
162/// entry.
163void CompileUnit::addSourceLine(DIE *Die, DIType Ty) {
164 // Verify type.
165 if (!Ty.Verify())
166 return;
167
168 unsigned Line = Ty.getLineNumber();
169 if (Line == 0 || !Ty.getContext().Verify())
170 return;
171 unsigned FileID = DD->GetOrCreateSourceID(Ty.getFilename(), Ty.getDirectory());
172 assert(FileID && "Invalid file id");
173 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
174 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
175}
176
177/// addSourceLine - Add location information to specified debug information
178/// entry.
179void CompileUnit::addSourceLine(DIE *Die, DINameSpace NS) {
180 // Verify namespace.
181 if (!NS.Verify())
182 return;
183
184 unsigned Line = NS.getLineNumber();
185 if (Line == 0)
186 return;
187 StringRef FN = NS.getFilename();
188
189 unsigned FileID = DD->GetOrCreateSourceID(FN, NS.getDirectory());
190 assert(FileID && "Invalid file id");
191 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
192 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
193}
194
Devang Patele1cdf842011-04-27 22:45:24 +0000195/// addVariableAddress - Add DW_AT_location attribute for a
196/// DbgVariable based on provided MachineLocation.
197void CompileUnit::addVariableAddress(DbgVariable *&DV, DIE *Die,
198 MachineLocation Location) {
Devang Patel161b2f42011-04-12 23:21:44 +0000199 if (DV->variableHasComplexAddress())
200 addComplexAddress(DV, Die, dwarf::DW_AT_location, Location);
201 else if (DV->isBlockByrefVariable())
202 addBlockByrefAddress(DV, Die, dwarf::DW_AT_location, Location);
203 else
204 addAddress(Die, dwarf::DW_AT_location, Location);
205}
206
Devang Patel116da2f2011-04-26 19:06:18 +0000207/// addRegisterOp - Add register operand.
208void CompileUnit::addRegisterOp(DIE *TheDie, unsigned Reg) {
209 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
210 unsigned DWReg = RI->getDwarfRegNum(Reg, false);
211 if (DWReg < 32)
212 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + DWReg);
213 else {
214 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx);
215 addUInt(TheDie, 0, dwarf::DW_FORM_udata, DWReg);
216 }
217}
218
219/// addRegisterOffset - Add register offset.
220void CompileUnit::addRegisterOffset(DIE *TheDie, unsigned Reg,
221 int64_t Offset) {
222 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
223 unsigned DWReg = RI->getDwarfRegNum(Reg, false);
224 const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
225 if (Reg == TRI->getFrameRegister(*Asm->MF))
226 // If variable offset is based in frame register then use fbreg.
227 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_fbreg);
228 else if (DWReg < 32)
229 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + DWReg);
230 else {
231 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
232 addUInt(TheDie, 0, dwarf::DW_FORM_udata, DWReg);
233 }
234 addSInt(TheDie, 0, dwarf::DW_FORM_sdata, Offset);
235}
236
237/// addAddress - Add an address attribute to a die based on the location
238/// provided.
239void CompileUnit::addAddress(DIE *Die, unsigned Attribute,
240 const MachineLocation &Location) {
241 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
242
243 if (Location.isReg())
244 addRegisterOp(Block, Location.getReg());
245 else
246 addRegisterOffset(Block, Location.getReg(), Location.getOffset());
247
248 // Now attach the location information to the DIE.
249 addBlock(Die, Attribute, 0, Block);
250}
251
Devang Patel161b2f42011-04-12 23:21:44 +0000252/// addComplexAddress - Start with the address based on the location provided,
253/// and generate the DWARF information necessary to find the actual variable
254/// given the extra address information encoded in the DIVariable, starting from
255/// the starting location. Add the DWARF information to the die.
256///
257void CompileUnit::addComplexAddress(DbgVariable *&DV, DIE *Die,
258 unsigned Attribute,
259 const MachineLocation &Location) {
Devang Patel161b2f42011-04-12 23:21:44 +0000260 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patelc26f5442011-04-28 02:22:40 +0000261 unsigned N = DV->getNumAddrElements();
262 unsigned i = 0;
263 if (Location.isReg()) {
264 if (N >= 2 && DV->getAddrElement(0) == DIBuilder::OpPlus) {
265 // If first address element is OpPlus then emit
266 // DW_OP_breg + Offset instead of DW_OP_reg + Offset.
267 addRegisterOffset(Block, Location.getReg(), DV->getAddrElement(1));
268 i = 2;
269 } else
270 addRegisterOp(Block, Location.getReg());
271 }
Devang Patel116da2f2011-04-26 19:06:18 +0000272 else
273 addRegisterOffset(Block, Location.getReg(), Location.getOffset());
Devang Patel161b2f42011-04-12 23:21:44 +0000274
Devang Patelc26f5442011-04-28 02:22:40 +0000275 for (;i < N; ++i) {
Devang Patel161b2f42011-04-12 23:21:44 +0000276 uint64_t Element = DV->getAddrElement(i);
Devang Patel161b2f42011-04-12 23:21:44 +0000277 if (Element == DIBuilder::OpPlus) {
278 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
279 addUInt(Block, 0, dwarf::DW_FORM_udata, DV->getAddrElement(++i));
280 } else if (Element == DIBuilder::OpDeref) {
281 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
282 } else llvm_unreachable("unknown DIBuilder Opcode");
283 }
284
285 // Now attach the location information to the DIE.
286 addBlock(Die, Attribute, 0, Block);
287}
288
289/* Byref variables, in Blocks, are declared by the programmer as "SomeType
290 VarName;", but the compiler creates a __Block_byref_x_VarName struct, and
291 gives the variable VarName either the struct, or a pointer to the struct, as
292 its type. This is necessary for various behind-the-scenes things the
293 compiler needs to do with by-reference variables in Blocks.
294
295 However, as far as the original *programmer* is concerned, the variable
296 should still have type 'SomeType', as originally declared.
297
298 The function getBlockByrefType dives into the __Block_byref_x_VarName
299 struct to find the original type of the variable, which is then assigned to
300 the variable's Debug Information Entry as its real type. So far, so good.
301 However now the debugger will expect the variable VarName to have the type
302 SomeType. So we need the location attribute for the variable to be an
303 expression that explains to the debugger how to navigate through the
304 pointers and struct to find the actual variable of type SomeType.
305
306 The following function does just that. We start by getting
307 the "normal" location for the variable. This will be the location
308 of either the struct __Block_byref_x_VarName or the pointer to the
309 struct __Block_byref_x_VarName.
310
311 The struct will look something like:
312
313 struct __Block_byref_x_VarName {
314 ... <various fields>
315 struct __Block_byref_x_VarName *forwarding;
316 ... <various other fields>
317 SomeType VarName;
318 ... <maybe more fields>
319 };
320
321 If we are given the struct directly (as our starting point) we
322 need to tell the debugger to:
323
324 1). Add the offset of the forwarding field.
325
326 2). Follow that pointer to get the real __Block_byref_x_VarName
327 struct to use (the real one may have been copied onto the heap).
328
329 3). Add the offset for the field VarName, to find the actual variable.
330
331 If we started with a pointer to the struct, then we need to
332 dereference that pointer first, before the other steps.
333 Translating this into DWARF ops, we will need to append the following
334 to the current location description for the variable:
335
336 DW_OP_deref -- optional, if we start with a pointer
337 DW_OP_plus_uconst <forward_fld_offset>
338 DW_OP_deref
339 DW_OP_plus_uconst <varName_fld_offset>
340
341 That is what this function does. */
342
343/// addBlockByrefAddress - Start with the address based on the location
344/// provided, and generate the DWARF information necessary to find the
345/// actual Block variable (navigating the Block struct) based on the
346/// starting location. Add the DWARF information to the die. For
347/// more information, read large comment just above here.
348///
349void CompileUnit::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
350 unsigned Attribute,
351 const MachineLocation &Location) {
352 DIType Ty = DV->getType();
353 DIType TmpTy = Ty;
354 unsigned Tag = Ty.getTag();
355 bool isPointer = false;
356
357 StringRef varName = DV->getName();
358
359 if (Tag == dwarf::DW_TAG_pointer_type) {
360 DIDerivedType DTy = DIDerivedType(Ty);
361 TmpTy = DTy.getTypeDerivedFrom();
362 isPointer = true;
363 }
364
365 DICompositeType blockStruct = DICompositeType(TmpTy);
366
367 // Find the __forwarding field and the variable field in the __Block_byref
368 // struct.
369 DIArray Fields = blockStruct.getTypeArray();
370 DIDescriptor varField = DIDescriptor();
371 DIDescriptor forwardingField = DIDescriptor();
372
373 for (unsigned i = 0, N = Fields.getNumElements(); i < N; ++i) {
374 DIDescriptor Element = Fields.getElement(i);
375 DIDerivedType DT = DIDerivedType(Element);
376 StringRef fieldName = DT.getName();
377 if (fieldName == "__forwarding")
378 forwardingField = Element;
379 else if (fieldName == varName)
380 varField = Element;
381 }
382
383 // Get the offsets for the forwarding field and the variable field.
384 unsigned forwardingFieldOffset =
385 DIDerivedType(forwardingField).getOffsetInBits() >> 3;
386 unsigned varFieldOffset =
387 DIDerivedType(varField).getOffsetInBits() >> 3;
388
389 // Decode the original location, and use that as the start of the byref
390 // variable's location.
391 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
392 unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
393 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
394
395 if (Location.isReg()) {
396 if (Reg < 32)
397 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
398 else {
399 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx);
400 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
401 }
402 } else {
403 if (Reg < 32)
404 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
405 else {
406 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
407 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
408 }
409
410 addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
411 }
412
413 // If we started with a pointer to the __Block_byref... struct, then
414 // the first thing we need to do is dereference the pointer (DW_OP_deref).
415 if (isPointer)
416 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
417
418 // Next add the offset for the '__forwarding' field:
419 // DW_OP_plus_uconst ForwardingFieldOffset. Note there's no point in
420 // adding the offset if it's 0.
421 if (forwardingFieldOffset > 0) {
422 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
423 addUInt(Block, 0, dwarf::DW_FORM_udata, forwardingFieldOffset);
424 }
425
426 // Now dereference the __forwarding field to get to the real __Block_byref
427 // struct: DW_OP_deref.
428 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
429
430 // Now that we've got the real __Block_byref... struct, add the offset
431 // for the variable's field to get to the location of the actual variable:
432 // DW_OP_plus_uconst varFieldOffset. Again, don't add if it's 0.
433 if (varFieldOffset > 0) {
434 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
435 addUInt(Block, 0, dwarf::DW_FORM_udata, varFieldOffset);
436 }
437
438 // Now attach the location information to the DIE.
439 addBlock(Die, Attribute, 0, Block);
440}
441
Devang Patel161b2f42011-04-12 23:21:44 +0000442/// addConstantValue - Add constant value entry in variable DIE.
Devang Patelb58128e2011-05-27 16:45:18 +0000443bool CompileUnit::addConstantValue(DIE *Die, const MachineOperand &MO,
444 DIType Ty) {
Devang Patel161b2f42011-04-12 23:21:44 +0000445 assert (MO.isImm() && "Invalid machine operand!");
446 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patelb58128e2011-05-27 16:45:18 +0000447 unsigned form = dwarf::DW_FORM_udata;
Devang Patel72f0d9c2011-05-27 18:15:52 +0000448 DIBasicType BTy(Ty);
449 if (BTy.Verify()) {
450 unsigned Encoding = BTy.getEncoding();
451 if (Encoding == dwarf::DW_ATE_signed ||
452 Encoding == dwarf::DW_ATE_signed_char) {
453 form = dwarf::DW_FORM_sdata;
454 addSInt(Block, 0, dwarf::DW_FORM_sdata, MO.getImm());
455 } else {
456 switch (Ty.getSizeInBits()) {
457 case 8: form = dwarf::DW_FORM_data1; break;
458 case 16: form = dwarf::DW_FORM_data2; break;
459 case 32: form = dwarf::DW_FORM_data4; break;
460 case 64: form = dwarf::DW_FORM_data8; break;
461 default: break;
462 }
463 addUInt(Block, 0, form, MO.getImm());
464 }
465 } else
466 //if this is not basic type then just use _udata.
467 addUInt(Block, 0, form, MO.getImm());
468
Devang Patel161b2f42011-04-12 23:21:44 +0000469 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
470 return true;
471}
472
473/// addConstantFPValue - Add constant value entry in variable DIE.
474bool CompileUnit::addConstantFPValue(DIE *Die, const MachineOperand &MO) {
475 assert (MO.isFPImm() && "Invalid machine operand!");
476 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
477 APFloat FPImm = MO.getFPImm()->getValueAPF();
478
479 // Get the raw data form of the floating point.
480 const APInt FltVal = FPImm.bitcastToAPInt();
481 const char *FltPtr = (const char*)FltVal.getRawData();
482
483 int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte.
484 bool LittleEndian = Asm->getTargetData().isLittleEndian();
485 int Incr = (LittleEndian ? 1 : -1);
486 int Start = (LittleEndian ? 0 : NumBytes - 1);
487 int Stop = (LittleEndian ? NumBytes : -1);
488
489 // Output the constant to DWARF one byte at a time.
490 for (; Start != Stop; Start += Incr)
491 addUInt(Block, 0, dwarf::DW_FORM_data1,
492 (unsigned char)0xFF & FltPtr[Start]);
493
494 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
495 return true;
496}
497
498/// addConstantValue - Add constant value entry in variable DIE.
499bool CompileUnit::addConstantValue(DIE *Die, ConstantInt *CI,
500 bool Unsigned) {
501 if (CI->getBitWidth() <= 64) {
502 if (Unsigned)
503 addUInt(Die, dwarf::DW_AT_const_value, dwarf::DW_FORM_udata,
504 CI->getZExtValue());
505 else
506 addSInt(Die, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata,
507 CI->getSExtValue());
508 return true;
509 }
510
511 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
512
513 // Get the raw data form of the large APInt.
514 const APInt Val = CI->getValue();
515 const char *Ptr = (const char*)Val.getRawData();
516
517 int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte.
518 bool LittleEndian = Asm->getTargetData().isLittleEndian();
519 int Incr = (LittleEndian ? 1 : -1);
520 int Start = (LittleEndian ? 0 : NumBytes - 1);
521 int Stop = (LittleEndian ? NumBytes : -1);
522
523 // Output the constant to DWARF one byte at a time.
524 for (; Start != Stop; Start += Incr)
525 addUInt(Block, 0, dwarf::DW_FORM_data1,
526 (unsigned char)0xFF & Ptr[Start]);
527
528 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
529 return true;
530}
531
532/// addTemplateParams - Add template parameters in buffer.
533void CompileUnit::addTemplateParams(DIE &Buffer, DIArray TParams) {
534 // Add template parameters.
535 for (unsigned i = 0, e = TParams.getNumElements(); i != e; ++i) {
536 DIDescriptor Element = TParams.getElement(i);
537 if (Element.isTemplateTypeParameter())
538 Buffer.addChild(getOrCreateTemplateTypeParameterDIE(
539 DITemplateTypeParameter(Element)));
540 else if (Element.isTemplateValueParameter())
541 Buffer.addChild(getOrCreateTemplateValueParameterDIE(
542 DITemplateValueParameter(Element)));
543 }
544
545}
546/// addToContextOwner - Add Die into the list of its context owner's children.
547void CompileUnit::addToContextOwner(DIE *Die, DIDescriptor Context) {
548 if (Context.isType()) {
549 DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context));
550 ContextDIE->addChild(Die);
551 } else if (Context.isNameSpace()) {
552 DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context));
553 ContextDIE->addChild(Die);
554 } else if (Context.isSubprogram()) {
555 DIE *ContextDIE = DD->createSubprogramDIE(DISubprogram(Context));
556 ContextDIE->addChild(Die);
557 } else if (DIE *ContextDIE = getDIE(Context))
558 ContextDIE->addChild(Die);
559 else
560 addDie(Die);
561}
562
563/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
564/// given DIType.
565DIE *CompileUnit::getOrCreateTypeDIE(DIType Ty) {
566 DIE *TyDIE = getDIE(Ty);
567 if (TyDIE)
568 return TyDIE;
569
570 // Create new type.
571 TyDIE = new DIE(dwarf::DW_TAG_base_type);
572 insertDIE(Ty, TyDIE);
573 if (Ty.isBasicType())
574 constructTypeDIE(*TyDIE, DIBasicType(Ty));
575 else if (Ty.isCompositeType())
576 constructTypeDIE(*TyDIE, DICompositeType(Ty));
577 else {
578 assert(Ty.isDerivedType() && "Unknown kind of DIType");
579 constructTypeDIE(*TyDIE, DIDerivedType(Ty));
580 }
581
582 addToContextOwner(TyDIE, Ty.getContext());
583 return TyDIE;
584}
585
586/// addType - Add a new type attribute to the specified entity.
587void CompileUnit::addType(DIE *Entity, DIType Ty) {
588 if (!Ty.Verify())
589 return;
590
591 // Check for pre-existence.
592 DIEEntry *Entry = getDIEEntry(Ty);
593 // If it exists then use the existing value.
594 if (Entry) {
595 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
596 return;
597 }
598
599 // Construct type.
600 DIE *Buffer = getOrCreateTypeDIE(Ty);
601
602 // Set up proxy.
603 Entry = createDIEEntry(Buffer);
604 insertDIEEntry(Ty, Entry);
605
606 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
607}
608
Devang Patel31c5d052011-05-06 16:57:54 +0000609/// addPubTypes - Add type for pubtypes section.
610void CompileUnit::addPubTypes(DISubprogram SP) {
611 DICompositeType SPTy = SP.getType();
612 unsigned SPTag = SPTy.getTag();
613 if (SPTag != dwarf::DW_TAG_subroutine_type)
614 return;
615
616 DIArray Args = SPTy.getTypeArray();
617 for (unsigned i = 0, e = Args.getNumElements(); i != e; ++i) {
618 DIType ATy(Args.getElement(i));
619 if (!ATy.Verify())
620 continue;
621 DICompositeType CATy = getDICompositeType(ATy);
622 if (DIDescriptor(CATy).Verify() && !CATy.getName().empty()
623 && !CATy.isForwardDecl()) {
624 if (DIEEntry *Entry = getDIEEntry(CATy))
625 addGlobalType(CATy.getName(), Entry->getEntry());
626 }
627 }
628}
629
Devang Patel161b2f42011-04-12 23:21:44 +0000630/// constructTypeDIE - Construct basic type die from DIBasicType.
631void CompileUnit::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
632 // Get core information.
633 StringRef Name = BTy.getName();
634 Buffer.setTag(dwarf::DW_TAG_base_type);
635 addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
636 BTy.getEncoding());
637
638 // Add name if not anonymous or intermediate type.
639 if (!Name.empty())
640 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
641 uint64_t Size = BTy.getSizeInBits() >> 3;
642 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
643}
644
645/// constructTypeDIE - Construct derived type die from DIDerivedType.
646void CompileUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
647 // Get core information.
648 StringRef Name = DTy.getName();
649 uint64_t Size = DTy.getSizeInBits() >> 3;
650 unsigned Tag = DTy.getTag();
651
652 // FIXME - Workaround for templates.
653 if (Tag == dwarf::DW_TAG_inheritance) Tag = dwarf::DW_TAG_reference_type;
654
655 Buffer.setTag(Tag);
656
657 // Map to main type, void will not have a type.
658 DIType FromTy = DTy.getTypeDerivedFrom();
659 addType(&Buffer, FromTy);
660
661 // Add name if not anonymous or intermediate type.
662 if (!Name.empty())
663 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
664
665 // Add size if non-zero (derived types might be zero-sized.)
666 if (Size)
667 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
668
669 // Add source line info if available and TyDesc is not a forward declaration.
670 if (!DTy.isForwardDecl())
671 addSourceLine(&Buffer, DTy);
672}
673
674/// constructTypeDIE - Construct type DIE from DICompositeType.
675void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
676 // Get core information.
677 StringRef Name = CTy.getName();
678
679 uint64_t Size = CTy.getSizeInBits() >> 3;
680 unsigned Tag = CTy.getTag();
681 Buffer.setTag(Tag);
682
683 switch (Tag) {
684 case dwarf::DW_TAG_vector_type:
685 case dwarf::DW_TAG_array_type:
686 constructArrayTypeDIE(Buffer, &CTy);
687 break;
688 case dwarf::DW_TAG_enumeration_type: {
689 DIArray Elements = CTy.getTypeArray();
690
691 // Add enumerators to enumeration type.
692 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
693 DIE *ElemDie = NULL;
694 DIDescriptor Enum(Elements.getElement(i));
695 if (Enum.isEnumerator()) {
696 ElemDie = constructEnumTypeDIE(DIEnumerator(Enum));
697 Buffer.addChild(ElemDie);
698 }
699 }
700 }
701 break;
702 case dwarf::DW_TAG_subroutine_type: {
703 // Add return type.
704 DIArray Elements = CTy.getTypeArray();
705 DIDescriptor RTy = Elements.getElement(0);
706 addType(&Buffer, DIType(RTy));
707
708 bool isPrototyped = true;
709 // Add arguments.
710 for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
711 DIDescriptor Ty = Elements.getElement(i);
712 if (Ty.isUnspecifiedParameter()) {
713 DIE *Arg = new DIE(dwarf::DW_TAG_unspecified_parameters);
714 Buffer.addChild(Arg);
715 isPrototyped = false;
716 } else {
717 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
718 addType(Arg, DIType(Ty));
719 Buffer.addChild(Arg);
720 }
721 }
722 // Add prototype flag.
723 if (isPrototyped)
724 addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
725 }
726 break;
727 case dwarf::DW_TAG_structure_type:
728 case dwarf::DW_TAG_union_type:
729 case dwarf::DW_TAG_class_type: {
730 // Add elements to structure type.
731 DIArray Elements = CTy.getTypeArray();
732
733 // A forward struct declared type may not have elements available.
734 unsigned N = Elements.getNumElements();
735 if (N == 0)
736 break;
737
738 // Add elements to structure type.
739 for (unsigned i = 0; i < N; ++i) {
740 DIDescriptor Element = Elements.getElement(i);
741 DIE *ElemDie = NULL;
742 if (Element.isSubprogram()) {
743 DISubprogram SP(Element);
744 ElemDie = DD->createSubprogramDIE(DISubprogram(Element));
745 if (SP.isProtected())
746 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
747 dwarf::DW_ACCESS_protected);
748 else if (SP.isPrivate())
749 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
750 dwarf::DW_ACCESS_private);
751 else
752 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
753 dwarf::DW_ACCESS_public);
754 if (SP.isExplicit())
755 addUInt(ElemDie, dwarf::DW_AT_explicit, dwarf::DW_FORM_flag, 1);
756 }
757 else if (Element.isVariable()) {
758 DIVariable DV(Element);
759 ElemDie = new DIE(dwarf::DW_TAG_variable);
760 addString(ElemDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,
761 DV.getName());
762 addType(ElemDie, DV.getType());
763 addUInt(ElemDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
764 addUInt(ElemDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
765 addSourceLine(ElemDie, DV);
766 } else if (Element.isDerivedType())
767 ElemDie = createMemberDIE(DIDerivedType(Element));
768 else
769 continue;
770 Buffer.addChild(ElemDie);
771 }
772
773 if (CTy.isAppleBlockExtension())
774 addUInt(&Buffer, dwarf::DW_AT_APPLE_block, dwarf::DW_FORM_flag, 1);
775
776 unsigned RLang = CTy.getRunTimeLang();
777 if (RLang)
778 addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class,
779 dwarf::DW_FORM_data1, RLang);
780
781 DICompositeType ContainingType = CTy.getContainingType();
782 if (DIDescriptor(ContainingType).isCompositeType())
783 addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
784 getOrCreateTypeDIE(DIType(ContainingType)));
785 else {
786 DIDescriptor Context = CTy.getContext();
787 addToContextOwner(&Buffer, Context);
788 }
789
Devang Patel201e6cd2011-05-12 21:29:42 +0000790 if (CTy.isObjcClassComplete())
791 addUInt(&Buffer, dwarf::DW_AT_APPLE_objc_complete_type,
Devang Patelb11f80e2011-05-12 19:06:16 +0000792 dwarf::DW_FORM_flag, 1);
793
Devang Patel161b2f42011-04-12 23:21:44 +0000794 if (Tag == dwarf::DW_TAG_class_type)
795 addTemplateParams(Buffer, CTy.getTemplateParams());
796
797 break;
798 }
799 default:
800 break;
801 }
802
803 // Add name if not anonymous or intermediate type.
804 if (!Name.empty())
805 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
806
807 if (Tag == dwarf::DW_TAG_enumeration_type || Tag == dwarf::DW_TAG_class_type
808 || Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type)
809 {
810 // Add size if non-zero (derived types might be zero-sized.)
811 if (Size)
812 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
813 else {
814 // Add zero size if it is not a forward declaration.
815 if (CTy.isForwardDecl())
816 addUInt(&Buffer, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
817 else
818 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, 0);
819 }
820
821 // Add source line info if available.
822 if (!CTy.isForwardDecl())
823 addSourceLine(&Buffer, CTy);
824 }
825}
826
827/// getOrCreateTemplateTypeParameterDIE - Find existing DIE or create new DIE
828/// for the given DITemplateTypeParameter.
829DIE *
830CompileUnit::getOrCreateTemplateTypeParameterDIE(DITemplateTypeParameter TP) {
831 DIE *ParamDIE = getDIE(TP);
832 if (ParamDIE)
833 return ParamDIE;
834
835 ParamDIE = new DIE(dwarf::DW_TAG_template_type_parameter);
836 addType(ParamDIE, TP.getType());
837 addString(ParamDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string, TP.getName());
838 return ParamDIE;
839}
840
841/// getOrCreateTemplateValueParameterDIE - Find existing DIE or create new DIE
842/// for the given DITemplateValueParameter.
843DIE *
844CompileUnit::getOrCreateTemplateValueParameterDIE(DITemplateValueParameter TPV) {
845 DIE *ParamDIE = getDIE(TPV);
846 if (ParamDIE)
847 return ParamDIE;
848
849 ParamDIE = new DIE(dwarf::DW_TAG_template_value_parameter);
850 addType(ParamDIE, TPV.getType());
851 if (!TPV.getName().empty())
852 addString(ParamDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string, TPV.getName());
853 addUInt(ParamDIE, dwarf::DW_AT_const_value, dwarf::DW_FORM_udata,
854 TPV.getValue());
855 return ParamDIE;
856}
857
Devang Patel31c5d052011-05-06 16:57:54 +0000858/// getOrCreateNameSpace - Create a DIE for DINameSpace.
859DIE *CompileUnit::getOrCreateNameSpace(DINameSpace NS) {
860 DIE *NDie = getDIE(NS);
861 if (NDie)
862 return NDie;
863 NDie = new DIE(dwarf::DW_TAG_namespace);
864 insertDIE(NS, NDie);
865 if (!NS.getName().empty())
866 addString(NDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, NS.getName());
867 addSourceLine(NDie, NS);
868 addToContextOwner(NDie, NS.getContext());
869 return NDie;
870}
871
Devang Patel161b2f42011-04-12 23:21:44 +0000872/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
873void CompileUnit::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){
874 DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type);
875 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IndexTy);
876 int64_t L = SR.getLo();
877 int64_t H = SR.getHi();
878
879 // The L value defines the lower bounds which is typically zero for C/C++. The
880 // H value is the upper bounds. Values are 64 bit. H - L + 1 is the size
881 // of the array. If L > H then do not emit DW_AT_lower_bound and
882 // DW_AT_upper_bound attributes. If L is zero and H is also zero then the
883 // array has one element and in such case do not emit lower bound.
884
885 if (L > H) {
886 Buffer.addChild(DW_Subrange);
887 return;
888 }
889 if (L)
890 addSInt(DW_Subrange, dwarf::DW_AT_lower_bound, 0, L);
891 addSInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, H);
892 Buffer.addChild(DW_Subrange);
893}
894
895/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
896void CompileUnit::constructArrayTypeDIE(DIE &Buffer,
897 DICompositeType *CTy) {
898 Buffer.setTag(dwarf::DW_TAG_array_type);
899 if (CTy->getTag() == dwarf::DW_TAG_vector_type)
900 addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1);
901
902 // Emit derived type.
903 addType(&Buffer, CTy->getTypeDerivedFrom());
904 DIArray Elements = CTy->getTypeArray();
905
906 // Get an anonymous type for index type.
907 DIE *IdxTy = getIndexTyDie();
908 if (!IdxTy) {
909 // Construct an anonymous type for index type.
910 IdxTy = new DIE(dwarf::DW_TAG_base_type);
911 addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t));
912 addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
913 dwarf::DW_ATE_signed);
914 addDie(IdxTy);
915 setIndexTyDie(IdxTy);
916 }
917
918 // Add subranges to array type.
919 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
920 DIDescriptor Element = Elements.getElement(i);
921 if (Element.getTag() == dwarf::DW_TAG_subrange_type)
922 constructSubrangeDIE(Buffer, DISubrange(Element), IdxTy);
923 }
924}
925
926/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
927DIE *CompileUnit::constructEnumTypeDIE(DIEnumerator ETy) {
928 DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator);
929 StringRef Name = ETy.getName();
930 addString(Enumerator, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
931 int64_t Value = ETy.getEnumValue();
932 addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value);
933 return Enumerator;
934}
935
936/// createMemberDIE - Create new member DIE.
937DIE *CompileUnit::createMemberDIE(DIDerivedType DT) {
938 DIE *MemberDie = new DIE(DT.getTag());
939 StringRef Name = DT.getName();
940 if (!Name.empty())
941 addString(MemberDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
942
943 addType(MemberDie, DT.getTypeDerivedFrom());
944
945 addSourceLine(MemberDie, DT);
946
947 DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
948 addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
949
950 uint64_t Size = DT.getSizeInBits();
951 uint64_t FieldSize = DT.getOriginalTypeSize();
952
953 if (Size != FieldSize) {
954 // Handle bitfield.
955 addUInt(MemberDie, dwarf::DW_AT_byte_size, 0, DT.getOriginalTypeSize()>>3);
956 addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits());
957
958 uint64_t Offset = DT.getOffsetInBits();
959 uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
960 uint64_t HiMark = (Offset + FieldSize) & AlignMask;
961 uint64_t FieldOffset = (HiMark - FieldSize);
962 Offset -= FieldOffset;
963
964 // Maybe we need to work from the other end.
965 if (Asm->getTargetData().isLittleEndian())
966 Offset = FieldSize - (Offset + Size);
967 addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
968
969 // Here WD_AT_data_member_location points to the anonymous
970 // field that includes this bit field.
971 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, FieldOffset >> 3);
972
973 } else
974 // This is not a bitfield.
975 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);
976
977 if (DT.getTag() == dwarf::DW_TAG_inheritance
978 && DT.isVirtual()) {
979
980 // For C++, virtual base classes are not at fixed offset. Use following
981 // expression to extract appropriate offset from vtable.
982 // BaseAddr = ObAddr + *((*ObAddr) - Offset)
983
984 DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock();
985 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
986 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
987 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
988 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits());
989 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
990 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
991 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
992
993 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0,
994 VBaseLocationDie);
995 } else
996 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
997
998 if (DT.isProtected())
999 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1000 dwarf::DW_ACCESS_protected);
1001 else if (DT.isPrivate())
1002 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1003 dwarf::DW_ACCESS_private);
1004 // Otherwise C++ member and base classes are considered public.
1005 else if (DT.getCompileUnit().getLanguage() == dwarf::DW_LANG_C_plus_plus)
1006 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1007 dwarf::DW_ACCESS_public);
1008 if (DT.isVirtual())
1009 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag,
1010 dwarf::DW_VIRTUALITY_virtual);
Devang Patele9db5e22011-04-16 00:11:51 +00001011
1012 // Objective-C properties.
1013 StringRef PropertyName = DT.getObjCPropertyName();
1014 if (!PropertyName.empty()) {
1015 addString(MemberDie, dwarf::DW_AT_APPLE_property_name, dwarf::DW_FORM_string,
1016 PropertyName);
1017 StringRef GetterName = DT.getObjCPropertyGetterName();
1018 if (!GetterName.empty())
1019 addString(MemberDie, dwarf::DW_AT_APPLE_property_getter,
1020 dwarf::DW_FORM_string, GetterName);
1021 StringRef SetterName = DT.getObjCPropertySetterName();
1022 if (!SetterName.empty())
1023 addString(MemberDie, dwarf::DW_AT_APPLE_property_setter,
1024 dwarf::DW_FORM_string, SetterName);
1025 unsigned PropertyAttributes = 0;
1026 if (DT.isReadOnlyObjCProperty())
1027 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readonly;
1028 if (DT.isReadWriteObjCProperty())
1029 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readwrite;
1030 if (DT.isAssignObjCProperty())
1031 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_assign;
1032 if (DT.isRetainObjCProperty())
1033 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_retain;
1034 if (DT.isCopyObjCProperty())
1035 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_copy;
1036 if (DT.isNonAtomicObjCProperty())
1037 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_nonatomic;
1038 if (PropertyAttributes)
1039 addUInt(MemberDie, dwarf::DW_AT_APPLE_property_attribute, 0,
1040 PropertyAttributes);
1041 }
Devang Patel161b2f42011-04-12 23:21:44 +00001042 return MemberDie;
1043}