01c431c849a3c72a403883bbc52703fb274ae8fe
[oota-llvm.git] / lib / CodeGen / AsmPrinter / DIE.cpp
1 //===--- lib/CodeGen/DIE.cpp - DWARF Info Entries -------------------------===//
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 // Data structures for DWARF info entries.
11 // 
12 //===----------------------------------------------------------------------===//
13
14 #include "DIE.h"
15 #include "DwarfPrinter.h"
16 #include "llvm/CodeGen/AsmPrinter.h"
17 #include "llvm/Target/TargetAsmInfo.h"
18 #include "llvm/Target/TargetData.h"
19 #include <ostream>
20 using namespace llvm;
21
22 //===----------------------------------------------------------------------===//
23 // DIEAbbrevData Implementation
24 //===----------------------------------------------------------------------===//
25
26 /// Profile - Used to gather unique data for the abbreviation folding set.
27 ///
28 void DIEAbbrevData::Profile(FoldingSetNodeID &ID) const {
29   ID.AddInteger(Attribute);
30   ID.AddInteger(Form);
31 }
32
33 //===----------------------------------------------------------------------===//
34 // DIEAbbrev Implementation
35 //===----------------------------------------------------------------------===//
36
37 /// Profile - Used to gather unique data for the abbreviation folding set.
38 ///
39 void DIEAbbrev::Profile(FoldingSetNodeID &ID) const {
40   ID.AddInteger(Tag);
41   ID.AddInteger(ChildrenFlag);
42
43   // For each attribute description.
44   for (unsigned i = 0, N = Data.size(); i < N; ++i)
45     Data[i].Profile(ID);
46 }
47
48 /// Emit - Print the abbreviation using the specified asm printer.
49 ///
50 void DIEAbbrev::Emit(const AsmPrinter *Asm) const {
51   // Emit its Dwarf tag type.
52   Asm->EmitULEB128Bytes(Tag);
53   Asm->EOL(dwarf::TagString(Tag));
54
55   // Emit whether it has children DIEs.
56   Asm->EmitULEB128Bytes(ChildrenFlag);
57   Asm->EOL(dwarf::ChildrenString(ChildrenFlag));
58
59   // For each attribute description.
60   for (unsigned i = 0, N = Data.size(); i < N; ++i) {
61     const DIEAbbrevData &AttrData = Data[i];
62
63     // Emit attribute type.
64     Asm->EmitULEB128Bytes(AttrData.getAttribute());
65     Asm->EOL(dwarf::AttributeString(AttrData.getAttribute()));
66
67     // Emit form type.
68     Asm->EmitULEB128Bytes(AttrData.getForm());
69     Asm->EOL(dwarf::FormEncodingString(AttrData.getForm()));
70   }
71
72   // Mark end of abbreviation.
73   Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(1)");
74   Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(2)");
75 }
76
77 #ifndef NDEBUG
78 void DIEAbbrev::print(std::ostream &O) {
79   O << "Abbreviation @"
80     << std::hex << (intptr_t)this << std::dec
81     << "  "
82     << dwarf::TagString(Tag)
83     << " "
84     << dwarf::ChildrenString(ChildrenFlag)
85     << "\n";
86
87   for (unsigned i = 0, N = Data.size(); i < N; ++i) {
88     O << "  "
89       << dwarf::AttributeString(Data[i].getAttribute())
90       << "  "
91       << dwarf::FormEncodingString(Data[i].getForm())
92       << "\n";
93   }
94 }
95 void DIEAbbrev::dump() { print(cerr); }
96 #endif
97
98 //===----------------------------------------------------------------------===//
99 // DIE Implementation
100 //===----------------------------------------------------------------------===//
101
102 DIE::~DIE() {
103   for (unsigned i = 0, N = Children.size(); i < N; ++i)
104     delete Children[i];
105 }
106
107 /// AddSiblingOffset - Add a sibling offset field to the front of the DIE.
108 ///
109 void DIE::AddSiblingOffset() {
110   DIEInteger *DI = new DIEInteger(0);
111   Values.insert(Values.begin(), DI);
112   Abbrev.AddFirstAttribute(dwarf::DW_AT_sibling, dwarf::DW_FORM_ref4);
113 }
114
115 /// Profile - Used to gather unique data for the value folding set.
116 ///
117 void DIE::Profile(FoldingSetNodeID &ID) {
118   Abbrev.Profile(ID);
119
120   for (unsigned i = 0, N = Children.size(); i < N; ++i)
121     ID.AddPointer(Children[i]);
122
123   for (unsigned j = 0, M = Values.size(); j < M; ++j)
124     ID.AddPointer(Values[j]);
125 }
126
127 #ifndef NDEBUG
128 void DIE::print(std::ostream &O, unsigned IncIndent) {
129   IndentCount += IncIndent;
130   const std::string Indent(IndentCount, ' ');
131   bool isBlock = Abbrev.getTag() == 0;
132
133   if (!isBlock) {
134     O << Indent
135       << "Die: "
136       << "0x" << std::hex << (intptr_t)this << std::dec
137       << ", Offset: " << Offset
138       << ", Size: " << Size
139       << "\n";
140
141     O << Indent
142       << dwarf::TagString(Abbrev.getTag())
143       << " "
144       << dwarf::ChildrenString(Abbrev.getChildrenFlag());
145   } else {
146     O << "Size: " << Size;
147   }
148   O << "\n";
149
150   const SmallVector<DIEAbbrevData, 8> &Data = Abbrev.getData();
151
152   IndentCount += 2;
153   for (unsigned i = 0, N = Data.size(); i < N; ++i) {
154     O << Indent;
155
156     if (!isBlock)
157       O << dwarf::AttributeString(Data[i].getAttribute());
158     else
159       O << "Blk[" << i << "]";
160
161     O <<  "  "
162       << dwarf::FormEncodingString(Data[i].getForm())
163       << " ";
164     Values[i]->print(O);
165     O << "\n";
166   }
167   IndentCount -= 2;
168
169   for (unsigned j = 0, M = Children.size(); j < M; ++j) {
170     Children[j]->print(O, 4);
171   }
172
173   if (!isBlock) O << "\n";
174   IndentCount -= IncIndent;
175 }
176
177 void DIE::dump() {
178   print(cerr);
179 }
180 #endif
181
182
183 #ifndef NDEBUG
184 void DIEValue::dump() {
185   print(cerr);
186 }
187 #endif
188
189 //===----------------------------------------------------------------------===//
190 // DIEInteger Implementation
191 //===----------------------------------------------------------------------===//
192
193 /// EmitValue - Emit integer of appropriate size.
194 ///
195 void DIEInteger::EmitValue(Dwarf *D, unsigned Form) const {
196   const AsmPrinter *Asm = D->getAsm();
197   switch (Form) {
198   case dwarf::DW_FORM_flag:  // Fall thru
199   case dwarf::DW_FORM_ref1:  // Fall thru
200   case dwarf::DW_FORM_data1: Asm->EmitInt8(Integer);         break;
201   case dwarf::DW_FORM_ref2:  // Fall thru
202   case dwarf::DW_FORM_data2: Asm->EmitInt16(Integer);        break;
203   case dwarf::DW_FORM_ref4:  // Fall thru
204   case dwarf::DW_FORM_data4: Asm->EmitInt32(Integer);        break;
205   case dwarf::DW_FORM_ref8:  // Fall thru
206   case dwarf::DW_FORM_data8: Asm->EmitInt64(Integer);        break;
207   case dwarf::DW_FORM_udata: Asm->EmitULEB128Bytes(Integer); break;
208   case dwarf::DW_FORM_sdata: Asm->EmitSLEB128Bytes(Integer); break;
209   default: assert(0 && "DIE Value form not supported yet");  break;
210   }
211 }
212
213 /// SizeOf - Determine size of integer value in bytes.
214 ///
215 unsigned DIEInteger::SizeOf(const TargetData *TD, unsigned Form) const {
216   switch (Form) {
217   case dwarf::DW_FORM_flag:  // Fall thru
218   case dwarf::DW_FORM_ref1:  // Fall thru
219   case dwarf::DW_FORM_data1: return sizeof(int8_t);
220   case dwarf::DW_FORM_ref2:  // Fall thru
221   case dwarf::DW_FORM_data2: return sizeof(int16_t);
222   case dwarf::DW_FORM_ref4:  // Fall thru
223   case dwarf::DW_FORM_data4: return sizeof(int32_t);
224   case dwarf::DW_FORM_ref8:  // Fall thru
225   case dwarf::DW_FORM_data8: return sizeof(int64_t);
226   case dwarf::DW_FORM_udata: return TargetAsmInfo::getULEB128Size(Integer);
227   case dwarf::DW_FORM_sdata: return TargetAsmInfo::getSLEB128Size(Integer);
228   default: assert(0 && "DIE Value form not supported yet"); break;
229   }
230   return 0;
231 }
232
233 /// Profile - Used to gather unique data for the value folding set.
234 ///
235 void DIEInteger::Profile(FoldingSetNodeID &ID, unsigned Int) {
236   ID.AddInteger(isInteger);
237   ID.AddInteger(Int);
238 }
239 void DIEInteger::Profile(FoldingSetNodeID &ID) {
240   Profile(ID, Integer);
241 }
242
243 #ifndef NDEBUG
244 void DIEInteger::print(std::ostream &O) {
245   O << "Int: " << (int64_t)Integer
246     << "  0x" << std::hex << Integer << std::dec;
247 }
248 #endif
249
250 //===----------------------------------------------------------------------===//
251 // DIEString Implementation
252 //===----------------------------------------------------------------------===//
253
254 /// EmitValue - Emit string value.
255 ///
256 void DIEString::EmitValue(Dwarf *D, unsigned Form) const {
257   D->getAsm()->EmitString(Str);
258 }
259
260 /// Profile - Used to gather unique data for the value folding set.
261 ///
262 void DIEString::Profile(FoldingSetNodeID &ID, const std::string &Str) {
263   ID.AddInteger(isString);
264   ID.AddString(Str);
265 }
266 void DIEString::Profile(FoldingSetNodeID &ID) {
267   Profile(ID, Str);
268 }
269
270 #ifndef NDEBUG
271 void DIEString::print(std::ostream &O) {
272   O << "Str: \"" << Str << "\"";
273 }
274 #endif
275
276 //===----------------------------------------------------------------------===//
277 // DIEDwarfLabel Implementation
278 //===----------------------------------------------------------------------===//
279
280 /// EmitValue - Emit label value.
281 ///
282 void DIEDwarfLabel::EmitValue(Dwarf *D, unsigned Form) const {
283   bool IsSmall = Form == dwarf::DW_FORM_data4;
284   D->EmitReference(Label, false, IsSmall);
285 }
286
287 /// SizeOf - Determine size of label value in bytes.
288 ///
289 unsigned DIEDwarfLabel::SizeOf(const TargetData *TD, unsigned Form) const {
290   if (Form == dwarf::DW_FORM_data4) return 4;
291   return TD->getPointerSize();
292 }
293
294 /// Profile - Used to gather unique data for the value folding set.
295 ///
296 void DIEDwarfLabel::Profile(FoldingSetNodeID &ID, const DWLabel &Label) {
297   ID.AddInteger(isLabel);
298   Label.Profile(ID);
299 }
300 void DIEDwarfLabel::Profile(FoldingSetNodeID &ID) {
301   Profile(ID, Label);
302 }
303
304 #ifndef NDEBUG
305 void DIEDwarfLabel::print(std::ostream &O) {
306   O << "Lbl: ";
307   Label.print(O);
308 }
309 #endif
310
311 //===----------------------------------------------------------------------===//
312 // DIEObjectLabel Implementation
313 //===----------------------------------------------------------------------===//
314
315 /// EmitValue - Emit label value.
316 ///
317 void DIEObjectLabel::EmitValue(Dwarf *D, unsigned Form) const {
318   bool IsSmall = Form == dwarf::DW_FORM_data4;
319   D->EmitReference(Label, false, IsSmall);
320 }
321
322 /// SizeOf - Determine size of label value in bytes.
323 ///
324 unsigned DIEObjectLabel::SizeOf(const TargetData *TD, unsigned Form) const {
325   if (Form == dwarf::DW_FORM_data4) return 4;
326   return TD->getPointerSize();
327 }
328
329 /// Profile - Used to gather unique data for the value folding set.
330 ///
331 void DIEObjectLabel::Profile(FoldingSetNodeID &ID, const std::string &Label) {
332   ID.AddInteger(isAsIsLabel);
333   ID.AddString(Label);
334 }
335 void DIEObjectLabel::Profile(FoldingSetNodeID &ID) {
336   Profile(ID, Label.c_str());
337 }
338
339 #ifndef NDEBUG
340 void DIEObjectLabel::print(std::ostream &O) {
341   O << "Obj: " << Label;
342 }
343 #endif
344
345 //===----------------------------------------------------------------------===//
346 // DIESectionOffset Implementation
347 //===----------------------------------------------------------------------===//
348
349 /// EmitValue - Emit delta value.
350 ///
351 void DIESectionOffset::EmitValue(Dwarf *D, unsigned Form) const {
352   bool IsSmall = Form == dwarf::DW_FORM_data4;
353   D->EmitSectionOffset(Label.getTag(), Section.getTag(),
354                        Label.getNumber(), Section.getNumber(),
355                        IsSmall, IsEH, UseSet);
356 }
357
358 /// SizeOf - Determine size of delta value in bytes.
359 ///
360 unsigned DIESectionOffset::SizeOf(const TargetData *TD, unsigned Form) const {
361   if (Form == dwarf::DW_FORM_data4) return 4;
362   return TD->getPointerSize();
363 }
364
365 /// Profile - Used to gather unique data for the value folding set.
366 ///
367 void DIESectionOffset::Profile(FoldingSetNodeID &ID, const DWLabel &Label,
368                                const DWLabel &Section) {
369   ID.AddInteger(isSectionOffset);
370   Label.Profile(ID);
371   Section.Profile(ID);
372   // IsEH and UseSet are specific to the Label/Section that we will emit the
373   // offset for; so Label/Section are enough for uniqueness.
374 }
375 void DIESectionOffset::Profile(FoldingSetNodeID &ID) {
376   Profile(ID, Label, Section);
377 }
378
379 #ifndef NDEBUG
380 void DIESectionOffset::print(std::ostream &O) {
381   O << "Off: ";
382   Label.print(O);
383   O << "-";
384   Section.print(O);
385   O << "-" << IsEH << "-" << UseSet;
386 }
387 #endif
388
389 //===----------------------------------------------------------------------===//
390 // DIEDelta Implementation
391 //===----------------------------------------------------------------------===//
392
393 /// EmitValue - Emit delta value.
394 ///
395 void DIEDelta::EmitValue(Dwarf *D, unsigned Form) const {
396   bool IsSmall = Form == dwarf::DW_FORM_data4;
397   D->EmitDifference(LabelHi, LabelLo, IsSmall);
398 }
399
400 /// SizeOf - Determine size of delta value in bytes.
401 ///
402 unsigned DIEDelta::SizeOf(const TargetData *TD, unsigned Form) const {
403   if (Form == dwarf::DW_FORM_data4) return 4;
404   return TD->getPointerSize();
405 }
406
407 /// Profile - Used to gather unique data for the value folding set.
408 ///
409 void DIEDelta::Profile(FoldingSetNodeID &ID, const DWLabel &LabelHi,
410                        const DWLabel &LabelLo) {
411   ID.AddInteger(isDelta);
412   LabelHi.Profile(ID);
413   LabelLo.Profile(ID);
414 }
415 void DIEDelta::Profile(FoldingSetNodeID &ID) {
416   Profile(ID, LabelHi, LabelLo);
417 }
418
419 #ifndef NDEBUG
420 void DIEDelta::print(std::ostream &O) {
421   O << "Del: ";
422   LabelHi.print(O);
423   O << "-";
424   LabelLo.print(O);
425 }
426 #endif
427
428 //===----------------------------------------------------------------------===//
429 // DIEEntry Implementation
430 //===----------------------------------------------------------------------===//
431
432 /// EmitValue - Emit debug information entry offset.
433 ///
434 void DIEEntry::EmitValue(Dwarf *D, unsigned Form) const {
435   D->getAsm()->EmitInt32(Entry->getOffset());
436 }
437
438 /// Profile - Used to gather unique data for the value folding set.
439 ///
440 void DIEEntry::Profile(FoldingSetNodeID &ID, DIE *Entry) {
441   ID.AddInteger(isEntry);
442   ID.AddPointer(Entry);
443 }
444 void DIEEntry::Profile(FoldingSetNodeID &ID) {
445   ID.AddInteger(isEntry);
446
447   if (Entry)
448     ID.AddPointer(Entry);
449   else
450     ID.AddPointer(this);
451 }
452
453 #ifndef NDEBUG
454 void DIEEntry::print(std::ostream &O) {
455   O << "Die: 0x" << std::hex << (intptr_t)Entry << std::dec;
456 }
457 #endif
458
459 //===----------------------------------------------------------------------===//
460 // DIEBlock Implementation
461 //===----------------------------------------------------------------------===//
462
463 /// ComputeSize - calculate the size of the block.
464 ///
465 unsigned DIEBlock::ComputeSize(const TargetData *TD) {
466   if (!Size) {
467     const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
468     for (unsigned i = 0, N = Values.size(); i < N; ++i)
469       Size += Values[i]->SizeOf(TD, AbbrevData[i].getForm());
470   }
471
472   return Size;
473 }
474
475 /// EmitValue - Emit block data.
476 ///
477 void DIEBlock::EmitValue(Dwarf *D, unsigned Form) const {
478   const AsmPrinter *Asm = D->getAsm();
479   switch (Form) {
480   case dwarf::DW_FORM_block1: Asm->EmitInt8(Size);         break;
481   case dwarf::DW_FORM_block2: Asm->EmitInt16(Size);        break;
482   case dwarf::DW_FORM_block4: Asm->EmitInt32(Size);        break;
483   case dwarf::DW_FORM_block:  Asm->EmitULEB128Bytes(Size); break;
484   default: assert(0 && "Improper form for block");         break;
485   }
486
487   const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
488   for (unsigned i = 0, N = Values.size(); i < N; ++i) {
489     Asm->EOL();
490     Values[i]->EmitValue(D, AbbrevData[i].getForm());
491   }
492 }
493
494 /// SizeOf - Determine size of block data in bytes.
495 ///
496 unsigned DIEBlock::SizeOf(const TargetData *TD, unsigned Form) const {
497   switch (Form) {
498   case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
499   case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
500   case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
501   case dwarf::DW_FORM_block: return Size + TargetAsmInfo::getULEB128Size(Size);
502   default: assert(0 && "Improper form for block"); break;
503   }
504   return 0;
505 }
506
507 void DIEBlock::Profile(FoldingSetNodeID &ID) {
508   ID.AddInteger(isBlock);
509   DIE::Profile(ID);
510 }
511
512 #ifndef NDEBUG
513 void DIEBlock::print(std::ostream &O) {
514   O << "Blk: ";
515   DIE::print(O, 5);
516 }
517 #endif