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