eliminate some uses of AsmPrinter::EmitIntXXX
[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/ADT/Twine.h"
17 #include "llvm/CodeGen/AsmPrinter.h"
18 #include "llvm/MC/MCAsmInfo.h"
19 #include "llvm/MC/MCStreamer.h"
20 #include "llvm/MC/MCSymbol.h"
21 #include "llvm/Target/TargetData.h"
22 #include "llvm/Support/Debug.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/Format.h"
25 using namespace llvm;
26
27 //===----------------------------------------------------------------------===//
28 // DIEAbbrevData Implementation
29 //===----------------------------------------------------------------------===//
30
31 /// Profile - Used to gather unique data for the abbreviation folding set.
32 ///
33 void DIEAbbrevData::Profile(FoldingSetNodeID &ID) const {
34   ID.AddInteger(Attribute);
35   ID.AddInteger(Form);
36 }
37
38 //===----------------------------------------------------------------------===//
39 // DIEAbbrev Implementation
40 //===----------------------------------------------------------------------===//
41
42 /// Profile - Used to gather unique data for the abbreviation folding set.
43 ///
44 void DIEAbbrev::Profile(FoldingSetNodeID &ID) const {
45   ID.AddInteger(Tag);
46   ID.AddInteger(ChildrenFlag);
47
48   // For each attribute description.
49   for (unsigned i = 0, N = Data.size(); i < N; ++i)
50     Data[i].Profile(ID);
51 }
52
53 /// Emit - Print the abbreviation using the specified asm printer.
54 ///
55 void DIEAbbrev::Emit(const AsmPrinter *Asm) const {
56   // Emit its Dwarf tag type.
57   Asm->EmitULEB128Bytes(Tag);
58   Asm->EOL(dwarf::TagString(Tag));
59
60   // Emit whether it has children DIEs.
61   Asm->EmitULEB128Bytes(ChildrenFlag);
62   Asm->EOL(dwarf::ChildrenString(ChildrenFlag));
63
64   // For each attribute description.
65   for (unsigned i = 0, N = Data.size(); i < N; ++i) {
66     const DIEAbbrevData &AttrData = Data[i];
67
68     // Emit attribute type.
69     Asm->EmitULEB128Bytes(AttrData.getAttribute());
70     Asm->EOL(dwarf::AttributeString(AttrData.getAttribute()));
71
72     // Emit form type.
73     Asm->EmitULEB128Bytes(AttrData.getForm());
74     Asm->EOL(dwarf::FormEncodingString(AttrData.getForm()));
75   }
76
77   // Mark end of abbreviation.
78   Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(1)");
79   Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(2)");
80 }
81
82 #ifndef NDEBUG
83 void DIEAbbrev::print(raw_ostream &O) {
84   O << "Abbreviation @"
85     << format("0x%lx", (long)(intptr_t)this)
86     << "  "
87     << dwarf::TagString(Tag)
88     << " "
89     << dwarf::ChildrenString(ChildrenFlag)
90     << '\n';
91
92   for (unsigned i = 0, N = Data.size(); i < N; ++i) {
93     O << "  "
94       << dwarf::AttributeString(Data[i].getAttribute())
95       << "  "
96       << dwarf::FormEncodingString(Data[i].getForm())
97       << '\n';
98   }
99 }
100 void DIEAbbrev::dump() { print(dbgs()); }
101 #endif
102
103 //===----------------------------------------------------------------------===//
104 // DIE Implementation
105 //===----------------------------------------------------------------------===//
106
107 DIE::~DIE() {
108   for (unsigned i = 0, N = Children.size(); i < N; ++i)
109     delete Children[i];
110 }
111
112 /// addSiblingOffset - Add a sibling offset field to the front of the DIE.
113 ///
114 void DIE::addSiblingOffset() {
115   DIEInteger *DI = new DIEInteger(0);
116   Values.insert(Values.begin(), DI);
117   Abbrev.AddFirstAttribute(dwarf::DW_AT_sibling, dwarf::DW_FORM_ref4);
118 }
119
120 #ifndef NDEBUG
121 void DIE::print(raw_ostream &O, unsigned IncIndent) {
122   IndentCount += IncIndent;
123   const std::string Indent(IndentCount, ' ');
124   bool isBlock = Abbrev.getTag() == 0;
125
126   if (!isBlock) {
127     O << Indent
128       << "Die: "
129       << format("0x%lx", (long)(intptr_t)this)
130       << ", Offset: " << Offset
131       << ", Size: " << Size
132       << "\n";
133
134     O << Indent
135       << dwarf::TagString(Abbrev.getTag())
136       << " "
137       << dwarf::ChildrenString(Abbrev.getChildrenFlag());
138   } else {
139     O << "Size: " << Size;
140   }
141   O << "\n";
142
143   const SmallVector<DIEAbbrevData, 8> &Data = Abbrev.getData();
144
145   IndentCount += 2;
146   for (unsigned i = 0, N = Data.size(); i < N; ++i) {
147     O << Indent;
148
149     if (!isBlock)
150       O << dwarf::AttributeString(Data[i].getAttribute());
151     else
152       O << "Blk[" << i << "]";
153
154     O <<  "  "
155       << dwarf::FormEncodingString(Data[i].getForm())
156       << " ";
157     Values[i]->print(O);
158     O << "\n";
159   }
160   IndentCount -= 2;
161
162   for (unsigned j = 0, M = Children.size(); j < M; ++j) {
163     Children[j]->print(O, 4);
164   }
165
166   if (!isBlock) O << "\n";
167   IndentCount -= IncIndent;
168 }
169
170 void DIE::dump() {
171   print(dbgs());
172 }
173 #endif
174
175
176 #ifndef NDEBUG
177 void DIEValue::dump() {
178   print(dbgs());
179 }
180 #endif
181
182 //===----------------------------------------------------------------------===//
183 // DIEInteger Implementation
184 //===----------------------------------------------------------------------===//
185
186 /// EmitValue - Emit integer of appropriate size.
187 ///
188 void DIEInteger::EmitValue(Dwarf *D, unsigned Form) const {
189   const AsmPrinter *Asm = D->getAsm();
190   unsigned Size = ~0U;
191   switch (Form) {
192   case dwarf::DW_FORM_flag:  // Fall thru
193   case dwarf::DW_FORM_ref1:  // Fall thru
194   case dwarf::DW_FORM_data1: Size = 1; break;
195   case dwarf::DW_FORM_ref2:  // Fall thru
196   case dwarf::DW_FORM_data2: Size = 2; break;
197   case dwarf::DW_FORM_ref4:  // Fall thru
198   case dwarf::DW_FORM_data4: Size = 4; break;
199   case dwarf::DW_FORM_ref8:  // Fall thru
200   case dwarf::DW_FORM_data8: Size = 8; break;
201   case dwarf::DW_FORM_udata: Asm->EmitULEB128Bytes(Integer); return;
202   case dwarf::DW_FORM_sdata: Asm->EmitSLEB128Bytes(Integer); return;
203   default: llvm_unreachable("DIE Value form not supported yet");
204   }
205   Asm->OutStreamer.EmitIntValue(Integer, Size, 0/*addrspace*/);
206 }
207
208 /// SizeOf - Determine size of integer value in bytes.
209 ///
210 unsigned DIEInteger::SizeOf(const TargetData *TD, unsigned Form) const {
211   switch (Form) {
212   case dwarf::DW_FORM_flag:  // Fall thru
213   case dwarf::DW_FORM_ref1:  // Fall thru
214   case dwarf::DW_FORM_data1: return sizeof(int8_t);
215   case dwarf::DW_FORM_ref2:  // Fall thru
216   case dwarf::DW_FORM_data2: return sizeof(int16_t);
217   case dwarf::DW_FORM_ref4:  // Fall thru
218   case dwarf::DW_FORM_data4: return sizeof(int32_t);
219   case dwarf::DW_FORM_ref8:  // Fall thru
220   case dwarf::DW_FORM_data8: return sizeof(int64_t);
221   case dwarf::DW_FORM_udata: return MCAsmInfo::getULEB128Size(Integer);
222   case dwarf::DW_FORM_sdata: return MCAsmInfo::getSLEB128Size(Integer);
223   default: llvm_unreachable("DIE Value form not supported yet"); break;
224   }
225   return 0;
226 }
227
228 #ifndef NDEBUG
229 void DIEInteger::print(raw_ostream &O) {
230   O << "Int: " << (int64_t)Integer
231     << format("  0x%llx", (unsigned long long)Integer);
232 }
233 #endif
234
235 //===----------------------------------------------------------------------===//
236 // DIEString Implementation
237 //===----------------------------------------------------------------------===//
238
239 /// EmitValue - Emit string value.
240 ///
241 void DIEString::EmitValue(Dwarf *D, unsigned Form) const {
242   D->getAsm()->EmitString(Str);
243 }
244
245 #ifndef NDEBUG
246 void DIEString::print(raw_ostream &O) {
247   O << "Str: \"" << Str << "\"";
248 }
249 #endif
250
251 //===----------------------------------------------------------------------===//
252 // DIEDwarfLabel Implementation
253 //===----------------------------------------------------------------------===//
254
255 /// EmitValue - Emit label value.
256 ///
257 void DIEDwarfLabel::EmitValue(Dwarf *D, unsigned Form) const {
258   bool IsSmall = Form == dwarf::DW_FORM_data4;
259   D->EmitReference(Label, false, IsSmall);
260 }
261
262 /// SizeOf - Determine size of label value in bytes.
263 ///
264 unsigned DIEDwarfLabel::SizeOf(const TargetData *TD, unsigned Form) const {
265   if (Form == dwarf::DW_FORM_data4) return 4;
266   return TD->getPointerSize();
267 }
268
269 #ifndef NDEBUG
270 void DIEDwarfLabel::print(raw_ostream &O) {
271   O << "Lbl: ";
272   Label.print(O);
273 }
274 #endif
275
276 //===----------------------------------------------------------------------===//
277 // DIEObjectLabel Implementation
278 //===----------------------------------------------------------------------===//
279
280 /// EmitValue - Emit label value.
281 ///
282 void DIEObjectLabel::EmitValue(Dwarf *D, unsigned Form) const {
283   bool IsSmall = Form == dwarf::DW_FORM_data4;
284   D->EmitReference(Sym, false, IsSmall);
285 }
286
287 /// SizeOf - Determine size of label value in bytes.
288 ///
289 unsigned DIEObjectLabel::SizeOf(const TargetData *TD, unsigned Form) const {
290   if (Form == dwarf::DW_FORM_data4) return 4;
291   return TD->getPointerSize();
292 }
293
294 #ifndef NDEBUG
295 void DIEObjectLabel::print(raw_ostream &O) {
296   O << "Obj: " << Sym->getName();
297 }
298 #endif
299
300 //===----------------------------------------------------------------------===//
301 // DIESectionOffset Implementation
302 //===----------------------------------------------------------------------===//
303
304 /// EmitValue - Emit delta value.
305 ///
306 void DIESectionOffset::EmitValue(Dwarf *D, unsigned Form) const {
307   bool IsSmall = Form == dwarf::DW_FORM_data4;
308   D->EmitSectionOffset(Label.getTag(), Section.getTag(),
309                        Label.getNumber(), Section.getNumber(),
310                        IsSmall, IsEH, UseSet);
311 }
312
313 /// SizeOf - Determine size of delta value in bytes.
314 ///
315 unsigned DIESectionOffset::SizeOf(const TargetData *TD, unsigned Form) const {
316   if (Form == dwarf::DW_FORM_data4) return 4;
317   return TD->getPointerSize();
318 }
319
320 #ifndef NDEBUG
321 void DIESectionOffset::print(raw_ostream &O) {
322   O << "Off: ";
323   Label.print(O);
324   O << "-";
325   Section.print(O);
326   O << "-" << IsEH << "-" << UseSet;
327 }
328 #endif
329
330 //===----------------------------------------------------------------------===//
331 // DIEDelta Implementation
332 //===----------------------------------------------------------------------===//
333
334 /// EmitValue - Emit delta value.
335 ///
336 void DIEDelta::EmitValue(Dwarf *D, unsigned Form) const {
337   bool IsSmall = Form == dwarf::DW_FORM_data4;
338   D->EmitDifference(LabelHi, LabelLo, IsSmall);
339 }
340
341 /// SizeOf - Determine size of delta value in bytes.
342 ///
343 unsigned DIEDelta::SizeOf(const TargetData *TD, unsigned Form) const {
344   if (Form == dwarf::DW_FORM_data4) return 4;
345   return TD->getPointerSize();
346 }
347
348 #ifndef NDEBUG
349 void DIEDelta::print(raw_ostream &O) {
350   O << "Del: ";
351   LabelHi.print(O);
352   O << "-";
353   LabelLo.print(O);
354 }
355 #endif
356
357 //===----------------------------------------------------------------------===//
358 // DIEEntry Implementation
359 //===----------------------------------------------------------------------===//
360
361 /// EmitValue - Emit debug information entry offset.
362 ///
363 void DIEEntry::EmitValue(Dwarf *D, unsigned Form) const {
364   D->getAsm()->EmitInt32(Entry->getOffset());
365 }
366
367 #ifndef NDEBUG
368 void DIEEntry::print(raw_ostream &O) {
369   O << format("Die: 0x%lx", (long)(intptr_t)Entry);
370 }
371 #endif
372
373 //===----------------------------------------------------------------------===//
374 // DIEBlock Implementation
375 //===----------------------------------------------------------------------===//
376
377 /// ComputeSize - calculate the size of the block.
378 ///
379 unsigned DIEBlock::ComputeSize(const TargetData *TD) {
380   if (!Size) {
381     const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
382     for (unsigned i = 0, N = Values.size(); i < N; ++i)
383       Size += Values[i]->SizeOf(TD, AbbrevData[i].getForm());
384   }
385
386   return Size;
387 }
388
389 /// EmitValue - Emit block data.
390 ///
391 void DIEBlock::EmitValue(Dwarf *D, unsigned Form) const {
392   const AsmPrinter *Asm = D->getAsm();
393   switch (Form) {
394   case dwarf::DW_FORM_block1: Asm->EmitInt8(Size);         break;
395   case dwarf::DW_FORM_block2: Asm->EmitInt16(Size);        break;
396   case dwarf::DW_FORM_block4: Asm->EmitInt32(Size);        break;
397   case dwarf::DW_FORM_block:  Asm->EmitULEB128Bytes(Size); break;
398   default: llvm_unreachable("Improper form for block");         break;
399   }
400
401   const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
402   for (unsigned i = 0, N = Values.size(); i < N; ++i) {
403     Asm->EOL();
404     Values[i]->EmitValue(D, AbbrevData[i].getForm());
405   }
406 }
407
408 /// SizeOf - Determine size of block data in bytes.
409 ///
410 unsigned DIEBlock::SizeOf(const TargetData *TD, unsigned Form) const {
411   switch (Form) {
412   case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
413   case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
414   case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
415   case dwarf::DW_FORM_block: return Size + MCAsmInfo::getULEB128Size(Size);
416   default: llvm_unreachable("Improper form for block"); break;
417   }
418   return 0;
419 }
420
421 #ifndef NDEBUG
422 void DIEBlock::print(raw_ostream &O) {
423   O << "Blk: ";
424   DIE::print(O, 5);
425 }
426 #endif