blob: 589606522a430fd9b243517916c8afa4c90c7fa0 [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
Eric Christopher72f7bfb2013-01-15 23:56:56 +0000173/// addLabelAddress - Add a dwarf label attribute data and value using
174/// DW_FORM_addr or DW_FORM_GNU_addr_index.
175///
176void CompileUnit::addLabelAddress(DIE *Die, unsigned Attribute,
177 MCSymbol *Label) {
178 if (!DD->useSplitDwarf()) {
179 if (Label != NULL) {
180 DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
181 Die->addValue(Attribute, dwarf::DW_FORM_addr, Value);
182 } else {
183 DIEValue *Value = new (DIEValueAllocator) DIEInteger(0);
184 Die->addValue(Attribute, dwarf::DW_FORM_addr, Value);
185 }
186 } else {
187 unsigned idx = DU->getAddrPoolIndex(Label);
188 DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx);
189 Die->addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, Value);
190 }
191}
192
Devang Patel161b2f42011-04-12 23:21:44 +0000193/// addDelta - Add a label delta attribute data and value.
194///
195void CompileUnit::addDelta(DIE *Die, unsigned Attribute, unsigned Form,
196 const MCSymbol *Hi, const MCSymbol *Lo) {
197 DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo);
198 Die->addValue(Attribute, Form, Value);
199}
200
201/// addDIEEntry - Add a DIE attribute data and value.
202///
203void CompileUnit::addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form,
204 DIE *Entry) {
205 Die->addValue(Attribute, Form, createDIEEntry(Entry));
206}
207
Devang Patel161b2f42011-04-12 23:21:44 +0000208/// addBlock - Add block data.
209///
210void CompileUnit::addBlock(DIE *Die, unsigned Attribute, unsigned Form,
211 DIEBlock *Block) {
212 Block->ComputeSize(Asm);
213 DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.
214 Die->addValue(Attribute, Block->BestForm(), Block);
215}
216
217/// addSourceLine - Add location information to specified debug information
218/// entry.
219void CompileUnit::addSourceLine(DIE *Die, DIVariable V) {
220 // Verify variable.
221 if (!V.Verify())
222 return;
Eric Christopher8b4310b2012-11-21 00:34:38 +0000223
Devang Patel161b2f42011-04-12 23:21:44 +0000224 unsigned Line = V.getLineNumber();
225 if (Line == 0)
226 return;
Eric Christopher7ee5f5d2012-11-21 00:34:35 +0000227 unsigned FileID = DD->getOrCreateSourceID(V.getContext().getFilename(),
Devang Patel161b2f42011-04-12 23:21:44 +0000228 V.getContext().getDirectory());
229 assert(FileID && "Invalid file id");
230 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
231 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
232}
233
234/// addSourceLine - Add location information to specified debug information
235/// entry.
236void CompileUnit::addSourceLine(DIE *Die, DIGlobalVariable G) {
237 // Verify global variable.
238 if (!G.Verify())
239 return;
240
241 unsigned Line = G.getLineNumber();
242 if (Line == 0)
243 return;
Eric Christopher7ee5f5d2012-11-21 00:34:35 +0000244 unsigned FileID = DD->getOrCreateSourceID(G.getFilename(), G.getDirectory());
Devang Patel161b2f42011-04-12 23:21:44 +0000245 assert(FileID && "Invalid file id");
246 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
247 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
248}
249
250/// addSourceLine - Add location information to specified debug information
251/// entry.
252void CompileUnit::addSourceLine(DIE *Die, DISubprogram SP) {
253 // Verify subprogram.
254 if (!SP.Verify())
255 return;
Eric Christopher2125d5a2012-03-15 23:55:40 +0000256
Devang Patel161b2f42011-04-12 23:21:44 +0000257 // If the line number is 0, don't add it.
Eric Christopher2125d5a2012-03-15 23:55:40 +0000258 unsigned Line = SP.getLineNumber();
259 if (Line == 0)
Devang Patel161b2f42011-04-12 23:21:44 +0000260 return;
261
Eric Christopher7ee5f5d2012-11-21 00:34:35 +0000262 unsigned FileID = DD->getOrCreateSourceID(SP.getFilename(),
Nick Lewycky746cb672011-10-26 22:55:33 +0000263 SP.getDirectory());
Devang Patel161b2f42011-04-12 23:21:44 +0000264 assert(FileID && "Invalid file id");
265 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
266 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
267}
268
269/// addSourceLine - Add location information to specified debug information
270/// entry.
271void CompileUnit::addSourceLine(DIE *Die, DIType Ty) {
272 // Verify type.
273 if (!Ty.Verify())
274 return;
275
276 unsigned Line = Ty.getLineNumber();
Eric Christopher2125d5a2012-03-15 23:55:40 +0000277 if (Line == 0)
Devang Patel161b2f42011-04-12 23:21:44 +0000278 return;
Eric Christopher7ee5f5d2012-11-21 00:34:35 +0000279 unsigned FileID = DD->getOrCreateSourceID(Ty.getFilename(),
Nick Lewycky746cb672011-10-26 22:55:33 +0000280 Ty.getDirectory());
Devang Patel161b2f42011-04-12 23:21:44 +0000281 assert(FileID && "Invalid file id");
282 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
283 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
284}
285
286/// addSourceLine - Add location information to specified debug information
287/// entry.
Eric Christopherb8ca9882012-03-29 08:42:56 +0000288void CompileUnit::addSourceLine(DIE *Die, DIObjCProperty Ty) {
289 // Verify type.
290 if (!Ty.Verify())
291 return;
292
293 unsigned Line = Ty.getLineNumber();
294 if (Line == 0)
295 return;
296 DIFile File = Ty.getFile();
Eric Christopher7ee5f5d2012-11-21 00:34:35 +0000297 unsigned FileID = DD->getOrCreateSourceID(File.getFilename(),
Eric Christopher4d069bf2012-05-22 18:45:24 +0000298 File.getDirectory());
Eric Christopherb8ca9882012-03-29 08:42:56 +0000299 assert(FileID && "Invalid file id");
300 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
301 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
302}
303
304/// addSourceLine - Add location information to specified debug information
305/// entry.
Devang Patel161b2f42011-04-12 23:21:44 +0000306void CompileUnit::addSourceLine(DIE *Die, DINameSpace NS) {
307 // Verify namespace.
308 if (!NS.Verify())
309 return;
310
311 unsigned Line = NS.getLineNumber();
312 if (Line == 0)
313 return;
314 StringRef FN = NS.getFilename();
315
Eric Christopher7ee5f5d2012-11-21 00:34:35 +0000316 unsigned FileID = DD->getOrCreateSourceID(FN, NS.getDirectory());
Devang Patel161b2f42011-04-12 23:21:44 +0000317 assert(FileID && "Invalid file id");
318 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
319 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
320}
321
Eric Christopher8b4310b2012-11-21 00:34:38 +0000322/// addVariableAddress - Add DW_AT_location attribute for a
Devang Patele1cdf842011-04-27 22:45:24 +0000323/// DbgVariable based on provided MachineLocation.
Eric Christopher8b4310b2012-11-21 00:34:38 +0000324void CompileUnit::addVariableAddress(DbgVariable *&DV, DIE *Die,
Devang Patele1cdf842011-04-27 22:45:24 +0000325 MachineLocation Location) {
Devang Patel161b2f42011-04-12 23:21:44 +0000326 if (DV->variableHasComplexAddress())
327 addComplexAddress(DV, Die, dwarf::DW_AT_location, Location);
328 else if (DV->isBlockByrefVariable())
329 addBlockByrefAddress(DV, Die, dwarf::DW_AT_location, Location);
330 else
331 addAddress(Die, dwarf::DW_AT_location, Location);
332}
333
Devang Patel116da2f2011-04-26 19:06:18 +0000334/// addRegisterOp - Add register operand.
335void CompileUnit::addRegisterOp(DIE *TheDie, unsigned Reg) {
336 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
337 unsigned DWReg = RI->getDwarfRegNum(Reg, false);
338 if (DWReg < 32)
339 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + DWReg);
340 else {
341 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx);
342 addUInt(TheDie, 0, dwarf::DW_FORM_udata, DWReg);
343 }
344}
345
346/// addRegisterOffset - Add register offset.
347void CompileUnit::addRegisterOffset(DIE *TheDie, unsigned Reg,
348 int64_t Offset) {
349 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
350 unsigned DWReg = RI->getDwarfRegNum(Reg, false);
351 const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
352 if (Reg == TRI->getFrameRegister(*Asm->MF))
353 // If variable offset is based in frame register then use fbreg.
354 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_fbreg);
355 else if (DWReg < 32)
356 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + DWReg);
357 else {
358 addUInt(TheDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
359 addUInt(TheDie, 0, dwarf::DW_FORM_udata, DWReg);
360 }
361 addSInt(TheDie, 0, dwarf::DW_FORM_sdata, Offset);
362}
363
364/// addAddress - Add an address attribute to a die based on the location
365/// provided.
366void CompileUnit::addAddress(DIE *Die, unsigned Attribute,
367 const MachineLocation &Location) {
368 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
369
370 if (Location.isReg())
371 addRegisterOp(Block, Location.getReg());
372 else
373 addRegisterOffset(Block, Location.getReg(), Location.getOffset());
374
375 // Now attach the location information to the DIE.
376 addBlock(Die, Attribute, 0, Block);
377}
378
Devang Patel161b2f42011-04-12 23:21:44 +0000379/// addComplexAddress - Start with the address based on the location provided,
380/// and generate the DWARF information necessary to find the actual variable
381/// given the extra address information encoded in the DIVariable, starting from
382/// the starting location. Add the DWARF information to the die.
383///
384void CompileUnit::addComplexAddress(DbgVariable *&DV, DIE *Die,
385 unsigned Attribute,
386 const MachineLocation &Location) {
Devang Patel161b2f42011-04-12 23:21:44 +0000387 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patelc26f5442011-04-28 02:22:40 +0000388 unsigned N = DV->getNumAddrElements();
389 unsigned i = 0;
390 if (Location.isReg()) {
391 if (N >= 2 && DV->getAddrElement(0) == DIBuilder::OpPlus) {
392 // If first address element is OpPlus then emit
393 // DW_OP_breg + Offset instead of DW_OP_reg + Offset.
394 addRegisterOffset(Block, Location.getReg(), DV->getAddrElement(1));
395 i = 2;
396 } else
397 addRegisterOp(Block, Location.getReg());
398 }
Devang Patel116da2f2011-04-26 19:06:18 +0000399 else
400 addRegisterOffset(Block, Location.getReg(), Location.getOffset());
Devang Patel161b2f42011-04-12 23:21:44 +0000401
Devang Patelc26f5442011-04-28 02:22:40 +0000402 for (;i < N; ++i) {
Devang Patel161b2f42011-04-12 23:21:44 +0000403 uint64_t Element = DV->getAddrElement(i);
Devang Patel161b2f42011-04-12 23:21:44 +0000404 if (Element == DIBuilder::OpPlus) {
405 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
406 addUInt(Block, 0, dwarf::DW_FORM_udata, DV->getAddrElement(++i));
407 } else if (Element == DIBuilder::OpDeref) {
Eric Christopher50120762012-05-08 18:56:00 +0000408 if (!Location.isReg())
409 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
Devang Patel161b2f42011-04-12 23:21:44 +0000410 } else llvm_unreachable("unknown DIBuilder Opcode");
411 }
412
413 // Now attach the location information to the DIE.
414 addBlock(Die, Attribute, 0, Block);
415}
416
417/* Byref variables, in Blocks, are declared by the programmer as "SomeType
418 VarName;", but the compiler creates a __Block_byref_x_VarName struct, and
419 gives the variable VarName either the struct, or a pointer to the struct, as
420 its type. This is necessary for various behind-the-scenes things the
421 compiler needs to do with by-reference variables in Blocks.
422
423 However, as far as the original *programmer* is concerned, the variable
424 should still have type 'SomeType', as originally declared.
425
426 The function getBlockByrefType dives into the __Block_byref_x_VarName
427 struct to find the original type of the variable, which is then assigned to
428 the variable's Debug Information Entry as its real type. So far, so good.
429 However now the debugger will expect the variable VarName to have the type
430 SomeType. So we need the location attribute for the variable to be an
431 expression that explains to the debugger how to navigate through the
432 pointers and struct to find the actual variable of type SomeType.
433
434 The following function does just that. We start by getting
435 the "normal" location for the variable. This will be the location
436 of either the struct __Block_byref_x_VarName or the pointer to the
437 struct __Block_byref_x_VarName.
438
439 The struct will look something like:
440
441 struct __Block_byref_x_VarName {
442 ... <various fields>
443 struct __Block_byref_x_VarName *forwarding;
444 ... <various other fields>
445 SomeType VarName;
446 ... <maybe more fields>
447 };
448
449 If we are given the struct directly (as our starting point) we
450 need to tell the debugger to:
451
452 1). Add the offset of the forwarding field.
453
454 2). Follow that pointer to get the real __Block_byref_x_VarName
455 struct to use (the real one may have been copied onto the heap).
456
457 3). Add the offset for the field VarName, to find the actual variable.
458
459 If we started with a pointer to the struct, then we need to
460 dereference that pointer first, before the other steps.
461 Translating this into DWARF ops, we will need to append the following
462 to the current location description for the variable:
463
464 DW_OP_deref -- optional, if we start with a pointer
465 DW_OP_plus_uconst <forward_fld_offset>
466 DW_OP_deref
467 DW_OP_plus_uconst <varName_fld_offset>
468
469 That is what this function does. */
470
471/// addBlockByrefAddress - Start with the address based on the location
472/// provided, and generate the DWARF information necessary to find the
473/// actual Block variable (navigating the Block struct) based on the
474/// starting location. Add the DWARF information to the die. For
475/// more information, read large comment just above here.
476///
477void CompileUnit::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
478 unsigned Attribute,
479 const MachineLocation &Location) {
480 DIType Ty = DV->getType();
481 DIType TmpTy = Ty;
482 unsigned Tag = Ty.getTag();
483 bool isPointer = false;
484
485 StringRef varName = DV->getName();
486
487 if (Tag == dwarf::DW_TAG_pointer_type) {
488 DIDerivedType DTy = DIDerivedType(Ty);
489 TmpTy = DTy.getTypeDerivedFrom();
490 isPointer = true;
491 }
492
493 DICompositeType blockStruct = DICompositeType(TmpTy);
494
495 // Find the __forwarding field and the variable field in the __Block_byref
496 // struct.
497 DIArray Fields = blockStruct.getTypeArray();
498 DIDescriptor varField = DIDescriptor();
499 DIDescriptor forwardingField = DIDescriptor();
500
501 for (unsigned i = 0, N = Fields.getNumElements(); i < N; ++i) {
502 DIDescriptor Element = Fields.getElement(i);
503 DIDerivedType DT = DIDerivedType(Element);
504 StringRef fieldName = DT.getName();
505 if (fieldName == "__forwarding")
506 forwardingField = Element;
507 else if (fieldName == varName)
508 varField = Element;
509 }
510
511 // Get the offsets for the forwarding field and the variable field.
512 unsigned forwardingFieldOffset =
513 DIDerivedType(forwardingField).getOffsetInBits() >> 3;
514 unsigned varFieldOffset =
515 DIDerivedType(varField).getOffsetInBits() >> 3;
516
517 // Decode the original location, and use that as the start of the byref
518 // variable's location.
Devang Patel161b2f42011-04-12 23:21:44 +0000519 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
520
Eric Christophercaba2632012-07-04 02:02:18 +0000521 if (Location.isReg())
522 addRegisterOp(Block, Location.getReg());
523 else
524 addRegisterOffset(Block, Location.getReg(), Location.getOffset());
Devang Patel161b2f42011-04-12 23:21:44 +0000525
526 // If we started with a pointer to the __Block_byref... struct, then
527 // the first thing we need to do is dereference the pointer (DW_OP_deref).
528 if (isPointer)
529 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
530
531 // Next add the offset for the '__forwarding' field:
532 // DW_OP_plus_uconst ForwardingFieldOffset. Note there's no point in
533 // adding the offset if it's 0.
534 if (forwardingFieldOffset > 0) {
535 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
536 addUInt(Block, 0, dwarf::DW_FORM_udata, forwardingFieldOffset);
537 }
538
539 // Now dereference the __forwarding field to get to the real __Block_byref
540 // struct: DW_OP_deref.
541 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
542
543 // Now that we've got the real __Block_byref... struct, add the offset
544 // for the variable's field to get to the location of the actual variable:
545 // DW_OP_plus_uconst varFieldOffset. Again, don't add if it's 0.
546 if (varFieldOffset > 0) {
547 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
548 addUInt(Block, 0, dwarf::DW_FORM_udata, varFieldOffset);
549 }
550
551 // Now attach the location information to the DIE.
552 addBlock(Die, Attribute, 0, Block);
553}
554
Devang Patel4ec14b02011-07-20 21:57:04 +0000555/// isTypeSigned - Return true if the type is signed.
556static bool isTypeSigned(DIType Ty, int *SizeInBits) {
557 if (Ty.isDerivedType())
558 return isTypeSigned(DIDerivedType(Ty).getTypeDerivedFrom(), SizeInBits);
559 if (Ty.isBasicType())
560 if (DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed
561 || DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed_char) {
562 *SizeInBits = Ty.getSizeInBits();
563 return true;
564 }
565 return false;
566}
567
Devang Patel161b2f42011-04-12 23:21:44 +0000568/// addConstantValue - Add constant value entry in variable DIE.
Devang Patelb58128e2011-05-27 16:45:18 +0000569bool CompileUnit::addConstantValue(DIE *Die, const MachineOperand &MO,
570 DIType Ty) {
Nick Lewycky746cb672011-10-26 22:55:33 +0000571 assert(MO.isImm() && "Invalid machine operand!");
Devang Patel161b2f42011-04-12 23:21:44 +0000572 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel4ec14b02011-07-20 21:57:04 +0000573 int SizeInBits = -1;
574 bool SignedConstant = isTypeSigned(Ty, &SizeInBits);
575 unsigned Form = SignedConstant ? dwarf::DW_FORM_sdata : dwarf::DW_FORM_udata;
576 switch (SizeInBits) {
577 case 8: Form = dwarf::DW_FORM_data1; break;
578 case 16: Form = dwarf::DW_FORM_data2; break;
579 case 32: Form = dwarf::DW_FORM_data4; break;
580 case 64: Form = dwarf::DW_FORM_data8; break;
Devang Patel045c1d42011-05-27 19:13:26 +0000581 default: break;
582 }
Eric Christopher8b4310b2012-11-21 00:34:38 +0000583 SignedConstant ? addSInt(Block, 0, Form, MO.getImm())
Devang Patel4ec14b02011-07-20 21:57:04 +0000584 : addUInt(Block, 0, Form, MO.getImm());
Devang Patel72f0d9c2011-05-27 18:15:52 +0000585
Devang Patel161b2f42011-04-12 23:21:44 +0000586 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
587 return true;
588}
589
590/// addConstantFPValue - Add constant value entry in variable DIE.
591bool CompileUnit::addConstantFPValue(DIE *Die, const MachineOperand &MO) {
Nick Lewycky390c40d2011-10-27 06:44:11 +0000592 assert (MO.isFPImm() && "Invalid machine operand!");
Devang Patel161b2f42011-04-12 23:21:44 +0000593 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
594 APFloat FPImm = MO.getFPImm()->getValueAPF();
595
596 // Get the raw data form of the floating point.
597 const APInt FltVal = FPImm.bitcastToAPInt();
598 const char *FltPtr = (const char*)FltVal.getRawData();
599
600 int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte.
Micah Villmow3574eca2012-10-08 16:38:25 +0000601 bool LittleEndian = Asm->getDataLayout().isLittleEndian();
Devang Patel161b2f42011-04-12 23:21:44 +0000602 int Incr = (LittleEndian ? 1 : -1);
603 int Start = (LittleEndian ? 0 : NumBytes - 1);
604 int Stop = (LittleEndian ? NumBytes : -1);
605
606 // Output the constant to DWARF one byte at a time.
607 for (; Start != Stop; Start += Incr)
608 addUInt(Block, 0, dwarf::DW_FORM_data1,
609 (unsigned char)0xFF & FltPtr[Start]);
610
611 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
612 return true;
613}
614
615/// addConstantValue - Add constant value entry in variable DIE.
Devang Patel8594d422011-06-24 20:46:11 +0000616bool CompileUnit::addConstantValue(DIE *Die, const ConstantInt *CI,
Devang Patel161b2f42011-04-12 23:21:44 +0000617 bool Unsigned) {
Devang Pateld6a81362011-05-28 00:39:18 +0000618 unsigned CIBitWidth = CI->getBitWidth();
619 if (CIBitWidth <= 64) {
620 unsigned form = 0;
621 switch (CIBitWidth) {
622 case 8: form = dwarf::DW_FORM_data1; break;
623 case 16: form = dwarf::DW_FORM_data2; break;
624 case 32: form = dwarf::DW_FORM_data4; break;
625 case 64: form = dwarf::DW_FORM_data8; break;
Eric Christopher8b4310b2012-11-21 00:34:38 +0000626 default:
Devang Pateld6a81362011-05-28 00:39:18 +0000627 form = Unsigned ? dwarf::DW_FORM_udata : dwarf::DW_FORM_sdata;
628 }
Devang Patel161b2f42011-04-12 23:21:44 +0000629 if (Unsigned)
Devang Pateld6a81362011-05-28 00:39:18 +0000630 addUInt(Die, dwarf::DW_AT_const_value, form, CI->getZExtValue());
Devang Patel161b2f42011-04-12 23:21:44 +0000631 else
Devang Pateld6a81362011-05-28 00:39:18 +0000632 addSInt(Die, dwarf::DW_AT_const_value, form, CI->getSExtValue());
Devang Patel161b2f42011-04-12 23:21:44 +0000633 return true;
634 }
635
636 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
637
638 // Get the raw data form of the large APInt.
639 const APInt Val = CI->getValue();
NAKAMURA Takumic3e48c32011-10-28 14:12:22 +0000640 const uint64_t *Ptr64 = Val.getRawData();
Devang Patel161b2f42011-04-12 23:21:44 +0000641
642 int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte.
Micah Villmow3574eca2012-10-08 16:38:25 +0000643 bool LittleEndian = Asm->getDataLayout().isLittleEndian();
Devang Patel161b2f42011-04-12 23:21:44 +0000644
645 // Output the constant to DWARF one byte at a time.
NAKAMURA Takumic3e48c32011-10-28 14:12:22 +0000646 for (int i = 0; i < NumBytes; i++) {
647 uint8_t c;
648 if (LittleEndian)
649 c = Ptr64[i / 8] >> (8 * (i & 7));
650 else
651 c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7));
652 addUInt(Block, 0, dwarf::DW_FORM_data1, c);
653 }
Devang Patel161b2f42011-04-12 23:21:44 +0000654
655 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
656 return true;
657}
658
659/// addTemplateParams - Add template parameters in buffer.
660void CompileUnit::addTemplateParams(DIE &Buffer, DIArray TParams) {
661 // Add template parameters.
662 for (unsigned i = 0, e = TParams.getNumElements(); i != e; ++i) {
663 DIDescriptor Element = TParams.getElement(i);
664 if (Element.isTemplateTypeParameter())
665 Buffer.addChild(getOrCreateTemplateTypeParameterDIE(
666 DITemplateTypeParameter(Element)));
667 else if (Element.isTemplateValueParameter())
668 Buffer.addChild(getOrCreateTemplateValueParameterDIE(
669 DITemplateValueParameter(Element)));
670 }
Devang Patel161b2f42011-04-12 23:21:44 +0000671}
Nick Lewycky746cb672011-10-26 22:55:33 +0000672
Devang Patel161b2f42011-04-12 23:21:44 +0000673/// addToContextOwner - Add Die into the list of its context owner's children.
674void CompileUnit::addToContextOwner(DIE *Die, DIDescriptor Context) {
675 if (Context.isType()) {
676 DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context));
677 ContextDIE->addChild(Die);
678 } else if (Context.isNameSpace()) {
679 DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context));
680 ContextDIE->addChild(Die);
681 } else if (Context.isSubprogram()) {
Devang Pateldbc64af2011-08-15 17:24:54 +0000682 DIE *ContextDIE = getOrCreateSubprogramDIE(DISubprogram(Context));
Devang Patel161b2f42011-04-12 23:21:44 +0000683 ContextDIE->addChild(Die);
684 } else if (DIE *ContextDIE = getDIE(Context))
685 ContextDIE->addChild(Die);
686 else
687 addDie(Die);
688}
689
690/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
691/// given DIType.
Devang Patel94c7ddb2011-08-16 22:09:43 +0000692DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
693 DIType Ty(TyNode);
694 if (!Ty.Verify())
695 return NULL;
Devang Patel161b2f42011-04-12 23:21:44 +0000696 DIE *TyDIE = getDIE(Ty);
697 if (TyDIE)
698 return TyDIE;
699
700 // Create new type.
701 TyDIE = new DIE(dwarf::DW_TAG_base_type);
702 insertDIE(Ty, TyDIE);
703 if (Ty.isBasicType())
704 constructTypeDIE(*TyDIE, DIBasicType(Ty));
705 else if (Ty.isCompositeType())
706 constructTypeDIE(*TyDIE, DICompositeType(Ty));
707 else {
708 assert(Ty.isDerivedType() && "Unknown kind of DIType");
709 constructTypeDIE(*TyDIE, DIDerivedType(Ty));
710 }
Eric Christopher1b3f9192011-11-10 19:52:58 +0000711 // If this is a named finished type then include it in the list of types
712 // for the accelerator tables.
Eric Christopherc36145f2012-01-06 04:35:23 +0000713 if (!Ty.getName().empty() && !Ty.isForwardDecl()) {
714 bool IsImplementation = 0;
715 if (Ty.isCompositeType()) {
716 DICompositeType CT(Ty);
Eric Christophere0167892012-01-06 23:03:37 +0000717 // A runtime language of 0 actually means C/C++ and that any
718 // non-negative value is some version of Objective-C/C++.
Eric Christopherc36145f2012-01-06 04:35:23 +0000719 IsImplementation = (CT.getRunTimeLang() == 0) ||
Eric Christophere2dc9332012-02-22 08:46:02 +0000720 CT.isObjcClassComplete();
Eric Christopherc36145f2012-01-06 04:35:23 +0000721 }
Eric Christophere0167892012-01-06 23:03:37 +0000722 unsigned Flags = IsImplementation ?
723 DwarfAccelTable::eTypeFlagClassIsImplementation : 0;
724 addAccelType(Ty.getName(), std::make_pair(TyDIE, Flags));
Eric Christopherc36145f2012-01-06 04:35:23 +0000725 }
Eric Christopher8b4310b2012-11-21 00:34:38 +0000726
Devang Patel161b2f42011-04-12 23:21:44 +0000727 addToContextOwner(TyDIE, Ty.getContext());
728 return TyDIE;
729}
730
731/// addType - Add a new type attribute to the specified entity.
Eric Christopher4d069bf2012-05-22 18:45:24 +0000732void CompileUnit::addType(DIE *Entity, DIType Ty, unsigned Attribute) {
Devang Patel161b2f42011-04-12 23:21:44 +0000733 if (!Ty.Verify())
734 return;
735
736 // Check for pre-existence.
737 DIEEntry *Entry = getDIEEntry(Ty);
738 // If it exists then use the existing value.
739 if (Entry) {
Eric Christopher663e0cf2012-03-28 07:34:31 +0000740 Entity->addValue(Attribute, dwarf::DW_FORM_ref4, Entry);
Devang Patel161b2f42011-04-12 23:21:44 +0000741 return;
742 }
743
744 // Construct type.
745 DIE *Buffer = getOrCreateTypeDIE(Ty);
746
747 // Set up proxy.
748 Entry = createDIEEntry(Buffer);
749 insertDIEEntry(Ty, Entry);
Eric Christopher663e0cf2012-03-28 07:34:31 +0000750 Entity->addValue(Attribute, dwarf::DW_FORM_ref4, Entry);
Devang Patele9ae06c2011-05-31 22:56:51 +0000751
752 // If this is a complete composite type then include it in the
753 // list of global types.
Devang Patelc20bdf12011-06-01 00:23:24 +0000754 addGlobalType(Ty);
Devang Patel66658e42011-05-31 23:30:30 +0000755}
756
757/// addGlobalType - Add a new global type to the compile unit.
758///
Devang Patelc20bdf12011-06-01 00:23:24 +0000759void CompileUnit::addGlobalType(DIType Ty) {
Devang Patele9ae06c2011-05-31 22:56:51 +0000760 DIDescriptor Context = Ty.getContext();
Eric Christopher8b4310b2012-11-21 00:34:38 +0000761 if (Ty.isCompositeType() && !Ty.getName().empty() && !Ty.isForwardDecl()
762 && (!Context || Context.isCompileUnit() || Context.isFile()
Devang Patel94c7ddb2011-08-16 22:09:43 +0000763 || Context.isNameSpace()))
Devang Patelc20bdf12011-06-01 00:23:24 +0000764 if (DIEEntry *Entry = getDIEEntry(Ty))
765 GlobalTypes[Ty.getName()] = Entry->getEntry();
Devang Patel161b2f42011-04-12 23:21:44 +0000766}
767
Devang Patel31c5d052011-05-06 16:57:54 +0000768/// addPubTypes - Add type for pubtypes section.
769void CompileUnit::addPubTypes(DISubprogram SP) {
770 DICompositeType SPTy = SP.getType();
771 unsigned SPTag = SPTy.getTag();
772 if (SPTag != dwarf::DW_TAG_subroutine_type)
773 return;
774
775 DIArray Args = SPTy.getTypeArray();
776 for (unsigned i = 0, e = Args.getNumElements(); i != e; ++i) {
777 DIType ATy(Args.getElement(i));
778 if (!ATy.Verify())
779 continue;
Devang Patelc20bdf12011-06-01 00:23:24 +0000780 addGlobalType(ATy);
Devang Patel31c5d052011-05-06 16:57:54 +0000781 }
782}
783
Devang Patel161b2f42011-04-12 23:21:44 +0000784/// constructTypeDIE - Construct basic type die from DIBasicType.
785void CompileUnit::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
786 // Get core information.
787 StringRef Name = BTy.getName();
Devang Patel161b2f42011-04-12 23:21:44 +0000788 // Add name if not anonymous or intermediate type.
789 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000790 addString(&Buffer, dwarf::DW_AT_name, Name);
Devang Patel734a67c2011-09-14 23:13:28 +0000791
792 if (BTy.getTag() == dwarf::DW_TAG_unspecified_type) {
793 Buffer.setTag(dwarf::DW_TAG_unspecified_type);
794 // Unspecified types has only name, nothing else.
795 return;
796 }
797
798 Buffer.setTag(dwarf::DW_TAG_base_type);
Nick Lewycky746cb672011-10-26 22:55:33 +0000799 addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
Devang Patel30d409c2012-02-07 23:33:58 +0000800 BTy.getEncoding());
Devang Patel734a67c2011-09-14 23:13:28 +0000801
Devang Patel161b2f42011-04-12 23:21:44 +0000802 uint64_t Size = BTy.getSizeInBits() >> 3;
803 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
804}
805
806/// constructTypeDIE - Construct derived type die from DIDerivedType.
807void CompileUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
808 // Get core information.
809 StringRef Name = DTy.getName();
810 uint64_t Size = DTy.getSizeInBits() >> 3;
811 unsigned Tag = DTy.getTag();
812
813 // FIXME - Workaround for templates.
814 if (Tag == dwarf::DW_TAG_inheritance) Tag = dwarf::DW_TAG_reference_type;
815
816 Buffer.setTag(Tag);
817
818 // Map to main type, void will not have a type.
819 DIType FromTy = DTy.getTypeDerivedFrom();
820 addType(&Buffer, FromTy);
821
822 // Add name if not anonymous or intermediate type.
823 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +0000824 addString(&Buffer, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +0000825
826 // Add size if non-zero (derived types might be zero-sized.)
Eric Christopher35f225a2012-02-21 22:25:53 +0000827 if (Size && Tag != dwarf::DW_TAG_pointer_type)
Devang Patel161b2f42011-04-12 23:21:44 +0000828 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
829
David Blaikie62fdfb52013-01-07 05:51:15 +0000830 if (Tag == dwarf::DW_TAG_ptr_to_member_type)
831 addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
832 getOrCreateTypeDIE(DTy.getClassType()));
Devang Patel161b2f42011-04-12 23:21:44 +0000833 // Add source line info if available and TyDesc is not a forward declaration.
834 if (!DTy.isForwardDecl())
835 addSourceLine(&Buffer, DTy);
836}
837
838/// constructTypeDIE - Construct type DIE from DICompositeType.
839void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
840 // Get core information.
841 StringRef Name = CTy.getName();
842
843 uint64_t Size = CTy.getSizeInBits() >> 3;
844 unsigned Tag = CTy.getTag();
845 Buffer.setTag(Tag);
846
847 switch (Tag) {
Devang Patel161b2f42011-04-12 23:21:44 +0000848 case dwarf::DW_TAG_array_type:
849 constructArrayTypeDIE(Buffer, &CTy);
850 break;
851 case dwarf::DW_TAG_enumeration_type: {
852 DIArray Elements = CTy.getTypeArray();
853
854 // Add enumerators to enumeration type.
855 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
856 DIE *ElemDie = NULL;
857 DIDescriptor Enum(Elements.getElement(i));
858 if (Enum.isEnumerator()) {
859 ElemDie = constructEnumTypeDIE(DIEnumerator(Enum));
860 Buffer.addChild(ElemDie);
861 }
862 }
Eric Christopherbb0f6ea2012-05-23 00:09:20 +0000863 DIType DTy = CTy.getTypeDerivedFrom();
864 if (DTy.Verify()) {
865 addType(&Buffer, DTy);
866 addUInt(&Buffer, dwarf::DW_AT_enum_class, dwarf::DW_FORM_flag, 1);
867 }
Devang Patel161b2f42011-04-12 23:21:44 +0000868 }
869 break;
870 case dwarf::DW_TAG_subroutine_type: {
871 // Add return type.
872 DIArray Elements = CTy.getTypeArray();
873 DIDescriptor RTy = Elements.getElement(0);
874 addType(&Buffer, DIType(RTy));
875
876 bool isPrototyped = true;
877 // Add arguments.
878 for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
879 DIDescriptor Ty = Elements.getElement(i);
880 if (Ty.isUnspecifiedParameter()) {
881 DIE *Arg = new DIE(dwarf::DW_TAG_unspecified_parameters);
882 Buffer.addChild(Arg);
883 isPrototyped = false;
884 } else {
885 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
886 addType(Arg, DIType(Ty));
887 Buffer.addChild(Arg);
888 }
889 }
Eric Christopher8b6fe6b2012-02-22 08:46:21 +0000890 // Add prototype flag if we're dealing with a C language and the
891 // function has been prototyped.
892 if (isPrototyped &&
Eric Christopher4d069bf2012-05-22 18:45:24 +0000893 (Language == dwarf::DW_LANG_C89 ||
894 Language == dwarf::DW_LANG_C99 ||
895 Language == dwarf::DW_LANG_ObjC))
Eric Christopher873cf0a2012-08-24 01:14:27 +0000896 addFlag(&Buffer, dwarf::DW_AT_prototyped);
Devang Patel161b2f42011-04-12 23:21:44 +0000897 }
898 break;
899 case dwarf::DW_TAG_structure_type:
900 case dwarf::DW_TAG_union_type:
901 case dwarf::DW_TAG_class_type: {
902 // Add elements to structure type.
903 DIArray Elements = CTy.getTypeArray();
904
905 // A forward struct declared type may not have elements available.
906 unsigned N = Elements.getNumElements();
907 if (N == 0)
908 break;
909
910 // Add elements to structure type.
911 for (unsigned i = 0; i < N; ++i) {
912 DIDescriptor Element = Elements.getElement(i);
913 DIE *ElemDie = NULL;
914 if (Element.isSubprogram()) {
915 DISubprogram SP(Element);
Devang Pateldbc64af2011-08-15 17:24:54 +0000916 ElemDie = getOrCreateSubprogramDIE(DISubprogram(Element));
Devang Patel161b2f42011-04-12 23:21:44 +0000917 if (SP.isProtected())
Nick Lewycky13aaca52011-12-13 05:09:11 +0000918 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +0000919 dwarf::DW_ACCESS_protected);
920 else if (SP.isPrivate())
Nick Lewycky13aaca52011-12-13 05:09:11 +0000921 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +0000922 dwarf::DW_ACCESS_private);
Eric Christopher8b4310b2012-11-21 00:34:38 +0000923 else
Nick Lewycky13aaca52011-12-13 05:09:11 +0000924 addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +0000925 dwarf::DW_ACCESS_public);
926 if (SP.isExplicit())
Eric Christopher873cf0a2012-08-24 01:14:27 +0000927 addFlag(ElemDie, dwarf::DW_AT_explicit);
Devang Patel161b2f42011-04-12 23:21:44 +0000928 }
929 else if (Element.isVariable()) {
930 DIVariable DV(Element);
931 ElemDie = new DIE(dwarf::DW_TAG_variable);
Nick Lewycky390c40d2011-10-27 06:44:11 +0000932 addString(ElemDie, dwarf::DW_AT_name, DV.getName());
Devang Patel161b2f42011-04-12 23:21:44 +0000933 addType(ElemDie, DV.getType());
Eric Christopher873cf0a2012-08-24 01:14:27 +0000934 addFlag(ElemDie, dwarf::DW_AT_declaration);
935 addFlag(ElemDie, dwarf::DW_AT_external);
Devang Patel161b2f42011-04-12 23:21:44 +0000936 addSourceLine(ElemDie, DV);
Eric Christopher663e0cf2012-03-28 07:34:31 +0000937 } else if (Element.isDerivedType()) {
Eric Christopher4d069bf2012-05-22 18:45:24 +0000938 DIDerivedType DDTy(Element);
939 if (DDTy.getTag() == dwarf::DW_TAG_friend) {
940 ElemDie = new DIE(dwarf::DW_TAG_friend);
941 addType(ElemDie, DDTy.getTypeDerivedFrom(), dwarf::DW_AT_friend);
942 } else
943 ElemDie = createMemberDIE(DIDerivedType(Element));
Eric Christopher663e0cf2012-03-28 07:34:31 +0000944 } else if (Element.isObjCProperty()) {
Devang Patel30d409c2012-02-07 23:33:58 +0000945 DIObjCProperty Property(Element);
946 ElemDie = new DIE(Property.getTag());
947 StringRef PropertyName = Property.getObjCPropertyName();
948 addString(ElemDie, dwarf::DW_AT_APPLE_property_name, PropertyName);
Eric Christopher4d069bf2012-05-22 18:45:24 +0000949 addType(ElemDie, Property.getType());
950 addSourceLine(ElemDie, Property);
Devang Patel30d409c2012-02-07 23:33:58 +0000951 StringRef GetterName = Property.getObjCPropertyGetterName();
952 if (!GetterName.empty())
953 addString(ElemDie, dwarf::DW_AT_APPLE_property_getter, GetterName);
954 StringRef SetterName = Property.getObjCPropertySetterName();
955 if (!SetterName.empty())
956 addString(ElemDie, dwarf::DW_AT_APPLE_property_setter, SetterName);
957 unsigned PropertyAttributes = 0;
Devang Patel9e11eb12012-02-04 01:30:32 +0000958 if (Property.isReadOnlyObjCProperty())
959 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readonly;
960 if (Property.isReadWriteObjCProperty())
961 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readwrite;
962 if (Property.isAssignObjCProperty())
963 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_assign;
964 if (Property.isRetainObjCProperty())
965 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_retain;
966 if (Property.isCopyObjCProperty())
967 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_copy;
968 if (Property.isNonAtomicObjCProperty())
969 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_nonatomic;
970 if (PropertyAttributes)
Eric Christopher8b4310b2012-11-21 00:34:38 +0000971 addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute, 0,
Devang Patel9e11eb12012-02-04 01:30:32 +0000972 PropertyAttributes);
Devang Patel6588abf2012-02-06 17:49:43 +0000973
Devang Patel30d409c2012-02-07 23:33:58 +0000974 DIEEntry *Entry = getDIEEntry(Element);
975 if (!Entry) {
976 Entry = createDIEEntry(ElemDie);
977 insertDIEEntry(Element, Entry);
978 }
Devang Patel9e11eb12012-02-04 01:30:32 +0000979 } else
Devang Patel161b2f42011-04-12 23:21:44 +0000980 continue;
981 Buffer.addChild(ElemDie);
982 }
983
984 if (CTy.isAppleBlockExtension())
Eric Christopher873cf0a2012-08-24 01:14:27 +0000985 addFlag(&Buffer, dwarf::DW_AT_APPLE_block);
Devang Patel161b2f42011-04-12 23:21:44 +0000986
Devang Patel161b2f42011-04-12 23:21:44 +0000987 DICompositeType ContainingType = CTy.getContainingType();
988 if (DIDescriptor(ContainingType).isCompositeType())
989 addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
990 getOrCreateTypeDIE(DIType(ContainingType)));
991 else {
992 DIDescriptor Context = CTy.getContext();
993 addToContextOwner(&Buffer, Context);
994 }
995
Devang Patel201e6cd2011-05-12 21:29:42 +0000996 if (CTy.isObjcClassComplete())
Eric Christopher873cf0a2012-08-24 01:14:27 +0000997 addFlag(&Buffer, dwarf::DW_AT_APPLE_objc_complete_type);
Devang Patelb11f80e2011-05-12 19:06:16 +0000998
Eric Christopher1a8e8862011-12-16 23:42:42 +0000999 // Add template parameters to a class, structure or union types.
1000 // FIXME: The support isn't in the metadata for this yet.
1001 if (Tag == dwarf::DW_TAG_class_type ||
1002 Tag == dwarf::DW_TAG_structure_type ||
1003 Tag == dwarf::DW_TAG_union_type)
Devang Patel161b2f42011-04-12 23:21:44 +00001004 addTemplateParams(Buffer, CTy.getTemplateParams());
1005
1006 break;
1007 }
1008 default:
1009 break;
1010 }
1011
1012 // Add name if not anonymous or intermediate type.
1013 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001014 addString(&Buffer, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +00001015
Eric Christopher4a5d8392012-05-22 18:45:18 +00001016 if (Tag == dwarf::DW_TAG_enumeration_type ||
1017 Tag == dwarf::DW_TAG_class_type ||
1018 Tag == dwarf::DW_TAG_structure_type ||
1019 Tag == dwarf::DW_TAG_union_type) {
Devang Patel161b2f42011-04-12 23:21:44 +00001020 // Add size if non-zero (derived types might be zero-sized.)
Eric Christopherfc4199b2012-06-01 00:22:32 +00001021 // TODO: Do we care about size for enum forward declarations?
Devang Patel161b2f42011-04-12 23:21:44 +00001022 if (Size)
1023 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
Eric Christopherfc4199b2012-06-01 00:22:32 +00001024 else if (!CTy.isForwardDecl())
Devang Patel161b2f42011-04-12 23:21:44 +00001025 // Add zero size if it is not a forward declaration.
Eric Christopherfc4199b2012-06-01 00:22:32 +00001026 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, 0);
1027
1028 // If we're a forward decl, say so.
1029 if (CTy.isForwardDecl())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001030 addFlag(&Buffer, dwarf::DW_AT_declaration);
Devang Patel161b2f42011-04-12 23:21:44 +00001031
1032 // Add source line info if available.
1033 if (!CTy.isForwardDecl())
1034 addSourceLine(&Buffer, CTy);
Eric Christopher89388952012-03-07 00:15:19 +00001035
1036 // No harm in adding the runtime language to the declaration.
1037 unsigned RLang = CTy.getRunTimeLang();
1038 if (RLang)
1039 addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class,
1040 dwarf::DW_FORM_data1, RLang);
Devang Patel161b2f42011-04-12 23:21:44 +00001041 }
1042}
1043
Eric Christopher8b4310b2012-11-21 00:34:38 +00001044/// getOrCreateTemplateTypeParameterDIE - Find existing DIE or create new DIE
Devang Patel161b2f42011-04-12 23:21:44 +00001045/// for the given DITemplateTypeParameter.
1046DIE *
1047CompileUnit::getOrCreateTemplateTypeParameterDIE(DITemplateTypeParameter TP) {
1048 DIE *ParamDIE = getDIE(TP);
1049 if (ParamDIE)
1050 return ParamDIE;
1051
1052 ParamDIE = new DIE(dwarf::DW_TAG_template_type_parameter);
1053 addType(ParamDIE, TP.getType());
Nick Lewycky390c40d2011-10-27 06:44:11 +00001054 addString(ParamDIE, dwarf::DW_AT_name, TP.getName());
Devang Patel161b2f42011-04-12 23:21:44 +00001055 return ParamDIE;
1056}
1057
Eric Christopher8b4310b2012-11-21 00:34:38 +00001058/// getOrCreateTemplateValueParameterDIE - Find existing DIE or create new DIE
Devang Patel161b2f42011-04-12 23:21:44 +00001059/// for the given DITemplateValueParameter.
1060DIE *
Eric Christopher4d069bf2012-05-22 18:45:24 +00001061CompileUnit::getOrCreateTemplateValueParameterDIE(DITemplateValueParameter TPV){
Devang Patel161b2f42011-04-12 23:21:44 +00001062 DIE *ParamDIE = getDIE(TPV);
1063 if (ParamDIE)
1064 return ParamDIE;
1065
1066 ParamDIE = new DIE(dwarf::DW_TAG_template_value_parameter);
1067 addType(ParamDIE, TPV.getType());
1068 if (!TPV.getName().empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001069 addString(ParamDIE, dwarf::DW_AT_name, TPV.getName());
Eric Christopher8b4310b2012-11-21 00:34:38 +00001070 addUInt(ParamDIE, dwarf::DW_AT_const_value, dwarf::DW_FORM_udata,
Devang Patel161b2f42011-04-12 23:21:44 +00001071 TPV.getValue());
1072 return ParamDIE;
1073}
1074
Devang Patel31c5d052011-05-06 16:57:54 +00001075/// getOrCreateNameSpace - Create a DIE for DINameSpace.
1076DIE *CompileUnit::getOrCreateNameSpace(DINameSpace NS) {
1077 DIE *NDie = getDIE(NS);
1078 if (NDie)
1079 return NDie;
1080 NDie = new DIE(dwarf::DW_TAG_namespace);
1081 insertDIE(NS, NDie);
Eric Christopher09ac3d82011-11-07 09:24:32 +00001082 if (!NS.getName().empty()) {
Nick Lewycky390c40d2011-10-27 06:44:11 +00001083 addString(NDie, dwarf::DW_AT_name, NS.getName());
Eric Christopher09ac3d82011-11-07 09:24:32 +00001084 addAccelNamespace(NS.getName(), NDie);
1085 } else
1086 addAccelNamespace("(anonymous namespace)", NDie);
Devang Patel31c5d052011-05-06 16:57:54 +00001087 addSourceLine(NDie, NS);
1088 addToContextOwner(NDie, NS.getContext());
1089 return NDie;
1090}
1091
Devang Pateldbc64af2011-08-15 17:24:54 +00001092/// getRealLinkageName - If special LLVM prefix that is used to inform the asm
1093/// printer to not emit usual symbol prefix before the symbol name is used then
1094/// return linkage name after skipping this special LLVM prefix.
1095static StringRef getRealLinkageName(StringRef LinkageName) {
1096 char One = '\1';
1097 if (LinkageName.startswith(StringRef(&One, 1)))
1098 return LinkageName.substr(1);
1099 return LinkageName;
1100}
1101
1102/// getOrCreateSubprogramDIE - Create new DIE using SP.
1103DIE *CompileUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
1104 DIE *SPDie = getDIE(SP);
1105 if (SPDie)
1106 return SPDie;
1107
Peter Collingbourne27302f02012-05-27 18:36:44 +00001108 SPDie = new DIE(dwarf::DW_TAG_subprogram);
1109
1110 // DW_TAG_inlined_subroutine may refer to this DIE.
1111 insertDIE(SP, SPDie);
1112
Rafael Espindola01b55b42011-11-10 22:34:29 +00001113 DISubprogram SPDecl = SP.getFunctionDeclaration();
1114 DIE *DeclDie = NULL;
1115 if (SPDecl.isSubprogram()) {
1116 DeclDie = getOrCreateSubprogramDIE(SPDecl);
1117 }
1118
Devang Pateldbc64af2011-08-15 17:24:54 +00001119 // Add to context owner.
1120 addToContextOwner(SPDie, SP.getContext());
1121
1122 // Add function template parameters.
1123 addTemplateParams(*SPDie, SP.getTemplateParams());
1124
Eric Christophere9722e12012-04-16 23:54:23 +00001125 // Unfortunately this code needs to stay here instead of below the
1126 // AT_specification code in order to work around a bug in older
1127 // gdbs that requires the linkage name to resolve multiple template
1128 // functions.
Eric Christophercbbd5b12012-08-23 22:52:55 +00001129 // TODO: Remove this set of code when we get rid of the old gdb
1130 // compatibility.
Eric Christopher8d101c32012-03-15 08:19:33 +00001131 StringRef LinkageName = SP.getLinkageName();
Eric Christophercbbd5b12012-08-23 22:52:55 +00001132 if (!LinkageName.empty() && DD->useDarwinGDBCompat())
Eric Christopher8d101c32012-03-15 08:19:33 +00001133 addString(SPDie, dwarf::DW_AT_MIPS_linkage_name,
1134 getRealLinkageName(LinkageName));
1135
Devang Pateldbc64af2011-08-15 17:24:54 +00001136 // If this DIE is going to refer declaration info using AT_specification
1137 // then there is no need to add other attributes.
Rafael Espindola01b55b42011-11-10 22:34:29 +00001138 if (DeclDie) {
1139 // Refer function declaration directly.
1140 addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
1141 DeclDie);
1142
Devang Pateldbc64af2011-08-15 17:24:54 +00001143 return SPDie;
Rafael Espindola01b55b42011-11-10 22:34:29 +00001144 }
Devang Pateldbc64af2011-08-15 17:24:54 +00001145
Eric Christophercbbd5b12012-08-23 22:52:55 +00001146 // Add the linkage name if we have one.
1147 if (!LinkageName.empty() && !DD->useDarwinGDBCompat())
1148 addString(SPDie, dwarf::DW_AT_MIPS_linkage_name,
1149 getRealLinkageName(LinkageName));
1150
Devang Pateldbc64af2011-08-15 17:24:54 +00001151 // Constructors and operators for anonymous aggregates do not have names.
1152 if (!SP.getName().empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001153 addString(SPDie, dwarf::DW_AT_name, SP.getName());
Devang Pateldbc64af2011-08-15 17:24:54 +00001154
1155 addSourceLine(SPDie, SP);
1156
Eric Christopher8b6fe6b2012-02-22 08:46:21 +00001157 // Add the prototype if we have a prototype and we have a C like
1158 // language.
1159 if (SP.isPrototyped() &&
1160 (Language == dwarf::DW_LANG_C89 ||
1161 Language == dwarf::DW_LANG_C99 ||
1162 Language == dwarf::DW_LANG_ObjC))
Eric Christopher873cf0a2012-08-24 01:14:27 +00001163 addFlag(SPDie, dwarf::DW_AT_prototyped);
Devang Pateldbc64af2011-08-15 17:24:54 +00001164
1165 // Add Return Type.
1166 DICompositeType SPTy = SP.getType();
1167 DIArray Args = SPTy.getTypeArray();
1168 unsigned SPTag = SPTy.getTag();
1169
1170 if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type)
1171 addType(SPDie, SPTy);
1172 else
1173 addType(SPDie, DIType(Args.getElement(0)));
1174
1175 unsigned VK = SP.getVirtuality();
1176 if (VK) {
Nick Lewycky798313d2011-12-14 00:56:07 +00001177 addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, VK);
Devang Pateldbc64af2011-08-15 17:24:54 +00001178 DIEBlock *Block = getDIEBlock();
1179 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1180 addUInt(Block, 0, dwarf::DW_FORM_udata, SP.getVirtualIndex());
1181 addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
1182 ContainingTypeMap.insert(std::make_pair(SPDie,
1183 SP.getContainingType()));
1184 }
1185
1186 if (!SP.isDefinition()) {
Eric Christopher873cf0a2012-08-24 01:14:27 +00001187 addFlag(SPDie, dwarf::DW_AT_declaration);
Eric Christopher8b4310b2012-11-21 00:34:38 +00001188
Devang Pateldbc64af2011-08-15 17:24:54 +00001189 // Add arguments. Do not add arguments for subprogram definition. They will
1190 // be handled while processing variables.
1191 DICompositeType SPTy = SP.getType();
1192 DIArray Args = SPTy.getTypeArray();
1193 unsigned SPTag = SPTy.getTag();
1194
1195 if (SPTag == dwarf::DW_TAG_subroutine_type)
1196 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
1197 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
Eric Christopher5c38de92012-09-10 23:33:57 +00001198 DIType ATy = DIType(Args.getElement(i));
Devang Pateldbc64af2011-08-15 17:24:54 +00001199 addType(Arg, ATy);
1200 if (ATy.isArtificial())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001201 addFlag(Arg, dwarf::DW_AT_artificial);
Devang Pateldbc64af2011-08-15 17:24:54 +00001202 SPDie->addChild(Arg);
1203 }
1204 }
1205
1206 if (SP.isArtificial())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001207 addFlag(SPDie, dwarf::DW_AT_artificial);
Devang Pateldbc64af2011-08-15 17:24:54 +00001208
1209 if (!SP.isLocalToUnit())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001210 addFlag(SPDie, dwarf::DW_AT_external);
Devang Pateldbc64af2011-08-15 17:24:54 +00001211
1212 if (SP.isOptimized())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001213 addFlag(SPDie, dwarf::DW_AT_APPLE_optimized);
Devang Pateldbc64af2011-08-15 17:24:54 +00001214
1215 if (unsigned isa = Asm->getISAEncoding()) {
1216 addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa);
1217 }
1218
1219 return SPDie;
1220}
1221
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001222// Return const expression if value is a GEP to access merged global
1223// constant. e.g.
1224// i8* getelementptr ({ i8, i8, i8, i8 }* @_MergedGlobals, i32 0, i32 0)
1225static const ConstantExpr *getMergedGlobalExpr(const Value *V) {
1226 const ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(V);
1227 if (!CE || CE->getNumOperands() != 3 ||
1228 CE->getOpcode() != Instruction::GetElementPtr)
1229 return NULL;
1230
1231 // First operand points to a global struct.
1232 Value *Ptr = CE->getOperand(0);
1233 if (!isa<GlobalValue>(Ptr) ||
1234 !isa<StructType>(cast<PointerType>(Ptr->getType())->getElementType()))
1235 return NULL;
1236
1237 // Second operand is zero.
1238 const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CE->getOperand(1));
1239 if (!CI || !CI->isZero())
1240 return NULL;
1241
1242 // Third operand is offset.
1243 if (!isa<ConstantInt>(CE->getOperand(2)))
1244 return NULL;
1245
1246 return CE;
1247}
1248
1249/// createGlobalVariableDIE - create global variable DIE.
1250void CompileUnit::createGlobalVariableDIE(const MDNode *N) {
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001251 // Check for pre-existence.
Devang Patel49e2f032011-08-18 22:21:50 +00001252 if (getDIE(N))
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001253 return;
1254
Devang Patel49e2f032011-08-18 22:21:50 +00001255 DIGlobalVariable GV(N);
Devang Patel28bea082011-08-18 23:17:55 +00001256 if (!GV.Verify())
1257 return;
1258
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001259 DIE *VariableDIE = new DIE(GV.getTag());
Devang Patel49e2f032011-08-18 22:21:50 +00001260 // Add to map.
1261 insertDIE(N, VariableDIE);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001262
1263 // Add name.
Nick Lewycky390c40d2011-10-27 06:44:11 +00001264 addString(VariableDIE, dwarf::DW_AT_name, GV.getDisplayName());
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001265 StringRef LinkageName = GV.getLinkageName();
Devang Patel49e2f032011-08-18 22:21:50 +00001266 bool isGlobalVariable = GV.getGlobal() != NULL;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001267 if (!LinkageName.empty() && isGlobalVariable)
Nick Lewycky746cb672011-10-26 22:55:33 +00001268 addString(VariableDIE, dwarf::DW_AT_MIPS_linkage_name,
Nick Lewycky390c40d2011-10-27 06:44:11 +00001269 getRealLinkageName(LinkageName));
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001270 // Add type.
Devang Patel49e2f032011-08-18 22:21:50 +00001271 DIType GTy = GV.getType();
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001272 addType(VariableDIE, GTy);
1273
1274 // Add scoping info.
Eric Christopherdfa30e12011-11-09 05:24:07 +00001275 if (!GV.isLocalToUnit())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001276 addFlag(VariableDIE, dwarf::DW_AT_external);
Eric Christopherdfa30e12011-11-09 05:24:07 +00001277
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001278 // Add line number info.
1279 addSourceLine(VariableDIE, GV);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001280 // Add to context owner.
1281 DIDescriptor GVContext = GV.getContext();
1282 addToContextOwner(VariableDIE, GVContext);
1283 // Add location.
Eric Christopher09ac3d82011-11-07 09:24:32 +00001284 bool addToAccelTable = false;
Eric Christopherd61c34b2011-11-11 03:16:32 +00001285 DIE *VariableSpecDIE = NULL;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001286 if (isGlobalVariable) {
Eric Christopher09ac3d82011-11-07 09:24:32 +00001287 addToAccelTable = true;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001288 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
1289 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
1290 addLabel(Block, 0, dwarf::DW_FORM_udata,
1291 Asm->Mang->getSymbol(GV.getGlobal()));
1292 // Do not create specification DIE if context is either compile unit
1293 // or a subprogram.
Devang Patel1dd4e562011-09-21 23:41:11 +00001294 if (GVContext && GV.isDefinition() && !GVContext.isCompileUnit() &&
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001295 !GVContext.isFile() && !isSubprogramContext(GVContext)) {
1296 // Create specification DIE.
Eric Christopherd117fbb2011-11-11 01:55:22 +00001297 VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001298 addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
1299 dwarf::DW_FORM_ref4, VariableDIE);
1300 addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
Eric Christopher873cf0a2012-08-24 01:14:27 +00001301 addFlag(VariableDIE, dwarf::DW_AT_declaration);
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001302 addDie(VariableSpecDIE);
1303 } else {
1304 addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
Eric Christopher09ac3d82011-11-07 09:24:32 +00001305 }
Eric Christopher8b4310b2012-11-21 00:34:38 +00001306 } else if (const ConstantInt *CI =
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001307 dyn_cast_or_null<ConstantInt>(GV.getConstant()))
1308 addConstantValue(VariableDIE, CI, GTy.isUnsignedDIType());
1309 else if (const ConstantExpr *CE = getMergedGlobalExpr(N->getOperand(11))) {
Eric Christopher09ac3d82011-11-07 09:24:32 +00001310 addToAccelTable = true;
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001311 // GV is a merged global.
1312 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
1313 Value *Ptr = CE->getOperand(0);
1314 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
1315 addLabel(Block, 0, dwarf::DW_FORM_udata,
1316 Asm->Mang->getSymbol(cast<GlobalValue>(Ptr)));
1317 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1318 SmallVector<Value*, 3> Idx(CE->op_begin()+1, CE->op_end());
Eric Christopher8b4310b2012-11-21 00:34:38 +00001319 addUInt(Block, 0, dwarf::DW_FORM_udata,
Micah Villmow3574eca2012-10-08 16:38:25 +00001320 Asm->getDataLayout().getIndexedOffset(Ptr->getType(), Idx));
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001321 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1322 addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block);
1323 }
1324
Eric Christopherd117fbb2011-11-11 01:55:22 +00001325 if (addToAccelTable) {
1326 DIE *AddrDIE = VariableSpecDIE ? VariableSpecDIE : VariableDIE;
1327 addAccelName(GV.getName(), AddrDIE);
Eric Christopher09ac3d82011-11-07 09:24:32 +00001328
Eric Christopherd117fbb2011-11-11 01:55:22 +00001329 // If the linkage name is different than the name, go ahead and output
1330 // that as well into the name table.
1331 if (GV.getLinkageName() != "" && GV.getName() != GV.getLinkageName())
1332 addAccelName(GV.getLinkageName(), AddrDIE);
1333 }
Eric Christopher74d8a872011-11-08 21:56:23 +00001334
Devang Patel6f9d8ff2011-08-15 17:57:41 +00001335 return;
1336}
1337
Devang Patel161b2f42011-04-12 23:21:44 +00001338/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
Eric Christopher4d069bf2012-05-22 18:45:24 +00001339void CompileUnit::constructSubrangeDIE(DIE &Buffer, DISubrange SR,
1340 DIE *IndexTy) {
Devang Patel161b2f42011-04-12 23:21:44 +00001341 DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type);
1342 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IndexTy);
Devang Patel161b2f42011-04-12 23:21:44 +00001343
Bill Wendling222c2fd2012-12-06 07:38:10 +00001344 // The LowerBound value defines the lower bounds which is typically zero for
1345 // C/C++. The Count value is the number of elements. Values are 64 bit. If
1346 // Count == -1 then the array is unbounded and we do not emit
1347 // DW_AT_lower_bound and DW_AT_upper_bound attributes. If LowerBound == 0 and
1348 // Count == 0, then the array has zero elements in which case we do not emit
1349 // an upper bound.
1350 int64_t LowerBound = SR.getLo();
Bill Wendling6afe4782012-12-06 07:55:19 +00001351 int64_t DefaultLowerBound = getDefaultLowerBound();
Bill Wendling9493dae2012-12-04 21:34:03 +00001352 int64_t Count = SR.getCount();
Devang Patel161b2f42011-04-12 23:21:44 +00001353
Bill Wendling6afe4782012-12-06 07:55:19 +00001354 if (DefaultLowerBound == -1 || LowerBound != DefaultLowerBound)
Bill Wendling222c2fd2012-12-06 07:38:10 +00001355 addUInt(DW_Subrange, dwarf::DW_AT_lower_bound, 0, LowerBound);
1356
1357 if (Count != -1 && Count != 0)
Bill Wendling9493dae2012-12-04 21:34:03 +00001358 // FIXME: An unbounded array should reference the expression that defines
1359 // the array.
Bill Wendling222c2fd2012-12-06 07:38:10 +00001360 addUInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, LowerBound + Count - 1);
Bill Wendling9493dae2012-12-04 21:34:03 +00001361
Devang Patel161b2f42011-04-12 23:21:44 +00001362 Buffer.addChild(DW_Subrange);
1363}
1364
1365/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
1366void CompileUnit::constructArrayTypeDIE(DIE &Buffer,
1367 DICompositeType *CTy) {
1368 Buffer.setTag(dwarf::DW_TAG_array_type);
Eric Christopher9a1e0e22013-01-08 01:53:52 +00001369 if (CTy->isVector())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001370 addFlag(&Buffer, dwarf::DW_AT_GNU_vector);
Devang Patel161b2f42011-04-12 23:21:44 +00001371
1372 // Emit derived type.
1373 addType(&Buffer, CTy->getTypeDerivedFrom());
1374 DIArray Elements = CTy->getTypeArray();
1375
1376 // Get an anonymous type for index type.
Eric Christopher8cab6ed2013-01-04 21:51:53 +00001377 // FIXME: This type should be passed down from the front end
1378 // as different languages may have different sizes for indexes.
Devang Patel161b2f42011-04-12 23:21:44 +00001379 DIE *IdxTy = getIndexTyDie();
1380 if (!IdxTy) {
1381 // Construct an anonymous type for index type.
1382 IdxTy = new DIE(dwarf::DW_TAG_base_type);
Eric Christopher8cab6ed2013-01-04 21:51:53 +00001383 addString(IdxTy, dwarf::DW_AT_name, "int");
Devang Patel161b2f42011-04-12 23:21:44 +00001384 addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t));
1385 addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
1386 dwarf::DW_ATE_signed);
1387 addDie(IdxTy);
1388 setIndexTyDie(IdxTy);
1389 }
1390
1391 // Add subranges to array type.
1392 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
1393 DIDescriptor Element = Elements.getElement(i);
1394 if (Element.getTag() == dwarf::DW_TAG_subrange_type)
1395 constructSubrangeDIE(Buffer, DISubrange(Element), IdxTy);
1396 }
1397}
1398
1399/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
1400DIE *CompileUnit::constructEnumTypeDIE(DIEnumerator ETy) {
1401 DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator);
1402 StringRef Name = ETy.getName();
Nick Lewycky390c40d2011-10-27 06:44:11 +00001403 addString(Enumerator, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +00001404 int64_t Value = ETy.getEnumValue();
1405 addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value);
1406 return Enumerator;
1407}
1408
Devang Pateldbc64af2011-08-15 17:24:54 +00001409/// constructContainingTypeDIEs - Construct DIEs for types that contain
1410/// vtables.
1411void CompileUnit::constructContainingTypeDIEs() {
1412 for (DenseMap<DIE *, const MDNode *>::iterator CI = ContainingTypeMap.begin(),
1413 CE = ContainingTypeMap.end(); CI != CE; ++CI) {
1414 DIE *SPDie = CI->first;
1415 const MDNode *N = CI->second;
1416 if (!N) continue;
1417 DIE *NDie = getDIE(N);
1418 if (!NDie) continue;
1419 addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
1420 }
1421}
1422
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001423/// constructVariableDIE - Construct a DIE for the given DbgVariable.
1424DIE *CompileUnit::constructVariableDIE(DbgVariable *DV, bool isScopeAbstract) {
1425 StringRef Name = DV->getName();
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001426
1427 // Translate tag to proper Dwarf tag.
1428 unsigned Tag = DV->getTag();
1429
1430 // Define variable debug information entry.
1431 DIE *VariableDie = new DIE(Tag);
1432 DbgVariable *AbsVar = DV->getAbstractVariable();
1433 DIE *AbsDIE = AbsVar ? AbsVar->getDIE() : NULL;
1434 if (AbsDIE)
1435 addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin,
1436 dwarf::DW_FORM_ref4, AbsDIE);
1437 else {
Nick Lewycky390c40d2011-10-27 06:44:11 +00001438 addString(VariableDie, dwarf::DW_AT_name, Name);
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001439 addSourceLine(VariableDie, DV->getVariable());
1440 addType(VariableDie, DV->getType());
1441 }
1442
1443 if (DV->isArtificial())
Eric Christopher873cf0a2012-08-24 01:14:27 +00001444 addFlag(VariableDie, dwarf::DW_AT_artificial);
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001445
1446 if (isScopeAbstract) {
1447 DV->setDIE(VariableDie);
1448 return VariableDie;
1449 }
1450
1451 // Add variable address.
1452
1453 unsigned Offset = DV->getDotDebugLocOffset();
1454 if (Offset != ~0U) {
1455 addLabel(VariableDie, dwarf::DW_AT_location,
1456 dwarf::DW_FORM_data4,
1457 Asm->GetTempSymbol("debug_loc", Offset));
1458 DV->setDIE(VariableDie);
1459 return VariableDie;
1460 }
1461
Eric Christopher8cf5e742011-10-03 15:49:20 +00001462 // Check if variable is described by a DBG_VALUE instruction.
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001463 if (const MachineInstr *DVInsn = DV->getMInsn()) {
1464 bool updated = false;
1465 if (DVInsn->getNumOperands() == 3) {
1466 if (DVInsn->getOperand(0).isReg()) {
1467 const MachineOperand RegOp = DVInsn->getOperand(0);
1468 const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
1469 if (DVInsn->getOperand(1).isImm() &&
1470 TRI->getFrameRegister(*Asm->MF) == RegOp.getReg()) {
1471 unsigned FrameReg = 0;
1472 const TargetFrameLowering *TFI = Asm->TM.getFrameLowering();
Eric Christopher8b4310b2012-11-21 00:34:38 +00001473 int Offset =
1474 TFI->getFrameIndexReference(*Asm->MF,
1475 DVInsn->getOperand(1).getImm(),
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001476 FrameReg);
1477 MachineLocation Location(FrameReg, Offset);
1478 addVariableAddress(DV, VariableDie, Location);
Eric Christopher8b4310b2012-11-21 00:34:38 +00001479
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001480 } else if (RegOp.getReg())
Eric Christopher8b4310b2012-11-21 00:34:38 +00001481 addVariableAddress(DV, VariableDie,
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001482 MachineLocation(RegOp.getReg()));
1483 updated = true;
1484 }
1485 else if (DVInsn->getOperand(0).isImm())
Eric Christopher8b4310b2012-11-21 00:34:38 +00001486 updated =
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001487 addConstantValue(VariableDie, DVInsn->getOperand(0),
1488 DV->getType());
1489 else if (DVInsn->getOperand(0).isFPImm())
1490 updated =
1491 addConstantFPValue(VariableDie, DVInsn->getOperand(0));
1492 else if (DVInsn->getOperand(0).isCImm())
1493 updated =
Eric Christopher8b4310b2012-11-21 00:34:38 +00001494 addConstantValue(VariableDie,
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001495 DVInsn->getOperand(0).getCImm(),
1496 DV->getType().isUnsignedDIType());
1497 } else {
Eric Christopher8b4310b2012-11-21 00:34:38 +00001498 addVariableAddress(DV, VariableDie,
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001499 Asm->getDebugValueLocation(DVInsn));
1500 updated = true;
1501 }
1502 if (!updated) {
1503 // If variableDie is not updated then DBG_VALUE instruction does not
1504 // have valid variable info.
1505 delete VariableDie;
1506 return NULL;
1507 }
1508 DV->setDIE(VariableDie);
1509 return VariableDie;
1510 } else {
1511 // .. else use frame index.
1512 int FI = DV->getFrameIndex();
1513 if (FI != ~0) {
1514 unsigned FrameReg = 0;
1515 const TargetFrameLowering *TFI = Asm->TM.getFrameLowering();
Eric Christopher8b4310b2012-11-21 00:34:38 +00001516 int Offset =
Devang Pateld0b5a5e2011-08-15 22:04:40 +00001517 TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg);
1518 MachineLocation Location(FrameReg, Offset);
1519 addVariableAddress(DV, VariableDie, Location);
1520 }
1521 }
1522
1523 DV->setDIE(VariableDie);
1524 return VariableDie;
1525}
1526
Devang Patel161b2f42011-04-12 23:21:44 +00001527/// createMemberDIE - Create new member DIE.
1528DIE *CompileUnit::createMemberDIE(DIDerivedType DT) {
1529 DIE *MemberDie = new DIE(DT.getTag());
1530 StringRef Name = DT.getName();
1531 if (!Name.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001532 addString(MemberDie, dwarf::DW_AT_name, Name);
Devang Patel161b2f42011-04-12 23:21:44 +00001533
1534 addType(MemberDie, DT.getTypeDerivedFrom());
1535
1536 addSourceLine(MemberDie, DT);
1537
1538 DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
1539 addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
1540
1541 uint64_t Size = DT.getSizeInBits();
1542 uint64_t FieldSize = DT.getOriginalTypeSize();
1543
1544 if (Size != FieldSize) {
1545 // Handle bitfield.
1546 addUInt(MemberDie, dwarf::DW_AT_byte_size, 0, DT.getOriginalTypeSize()>>3);
1547 addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits());
1548
1549 uint64_t Offset = DT.getOffsetInBits();
1550 uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
1551 uint64_t HiMark = (Offset + FieldSize) & AlignMask;
1552 uint64_t FieldOffset = (HiMark - FieldSize);
1553 Offset -= FieldOffset;
1554
1555 // Maybe we need to work from the other end.
Micah Villmow3574eca2012-10-08 16:38:25 +00001556 if (Asm->getDataLayout().isLittleEndian())
Devang Patel161b2f42011-04-12 23:21:44 +00001557 Offset = FieldSize - (Offset + Size);
1558 addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
1559
1560 // Here WD_AT_data_member_location points to the anonymous
1561 // field that includes this bit field.
1562 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, FieldOffset >> 3);
1563
1564 } else
1565 // This is not a bitfield.
1566 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);
1567
1568 if (DT.getTag() == dwarf::DW_TAG_inheritance
1569 && DT.isVirtual()) {
1570
1571 // For C++, virtual base classes are not at fixed offset. Use following
1572 // expression to extract appropriate offset from vtable.
1573 // BaseAddr = ObAddr + *((*ObAddr) - Offset)
1574
1575 DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock();
1576 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
1577 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1578 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1579 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits());
1580 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
1581 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1582 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1583
1584 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0,
1585 VBaseLocationDie);
1586 } else
1587 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
1588
1589 if (DT.isProtected())
Nick Lewycky13aaca52011-12-13 05:09:11 +00001590 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +00001591 dwarf::DW_ACCESS_protected);
1592 else if (DT.isPrivate())
Nick Lewycky13aaca52011-12-13 05:09:11 +00001593 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +00001594 dwarf::DW_ACCESS_private);
1595 // Otherwise C++ member and base classes are considered public.
Eric Christopher8b4310b2012-11-21 00:34:38 +00001596 else
Nick Lewycky13aaca52011-12-13 05:09:11 +00001597 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +00001598 dwarf::DW_ACCESS_public);
1599 if (DT.isVirtual())
Nick Lewycky798313d2011-12-14 00:56:07 +00001600 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1,
Devang Patel161b2f42011-04-12 23:21:44 +00001601 dwarf::DW_VIRTUALITY_virtual);
Devang Patele9db5e22011-04-16 00:11:51 +00001602
1603 // Objective-C properties.
Devang Patel6588abf2012-02-06 17:49:43 +00001604 if (MDNode *PNode = DT.getObjCProperty())
1605 if (DIEEntry *PropertyDie = getDIEEntry(PNode))
Eric Christopher8b4310b2012-11-21 00:34:38 +00001606 MemberDie->addValue(dwarf::DW_AT_APPLE_property, dwarf::DW_FORM_ref4,
Devang Patel6588abf2012-02-06 17:49:43 +00001607 PropertyDie);
1608
David Blaikie01bc2b32012-12-13 22:43:07 +00001609 if (DT.isArtificial())
1610 addFlag(MemberDie, dwarf::DW_AT_artificial);
1611
Devang Patel9e11eb12012-02-04 01:30:32 +00001612 // This is only for backward compatibility.
Devang Patele9db5e22011-04-16 00:11:51 +00001613 StringRef PropertyName = DT.getObjCPropertyName();
1614 if (!PropertyName.empty()) {
Nick Lewycky390c40d2011-10-27 06:44:11 +00001615 addString(MemberDie, dwarf::DW_AT_APPLE_property_name, PropertyName);
Devang Patele9db5e22011-04-16 00:11:51 +00001616 StringRef GetterName = DT.getObjCPropertyGetterName();
1617 if (!GetterName.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001618 addString(MemberDie, dwarf::DW_AT_APPLE_property_getter, GetterName);
Devang Patele9db5e22011-04-16 00:11:51 +00001619 StringRef SetterName = DT.getObjCPropertySetterName();
1620 if (!SetterName.empty())
Nick Lewycky390c40d2011-10-27 06:44:11 +00001621 addString(MemberDie, dwarf::DW_AT_APPLE_property_setter, SetterName);
Devang Patele9db5e22011-04-16 00:11:51 +00001622 unsigned PropertyAttributes = 0;
1623 if (DT.isReadOnlyObjCProperty())
1624 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readonly;
1625 if (DT.isReadWriteObjCProperty())
1626 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readwrite;
1627 if (DT.isAssignObjCProperty())
1628 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_assign;
1629 if (DT.isRetainObjCProperty())
1630 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_retain;
1631 if (DT.isCopyObjCProperty())
1632 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_copy;
1633 if (DT.isNonAtomicObjCProperty())
1634 PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_nonatomic;
1635 if (PropertyAttributes)
Eric Christopher8b4310b2012-11-21 00:34:38 +00001636 addUInt(MemberDie, dwarf::DW_AT_APPLE_property_attribute, 0,
Devang Patele9db5e22011-04-16 00:11:51 +00001637 PropertyAttributes);
1638 }
Devang Patel161b2f42011-04-12 23:21:44 +00001639 return MemberDie;
1640}