summaryrefslogtreecommitdiff
path: root/lib/CodeGen/AsmPrinter
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2009-05-15 00:11:17 +0000
committerBill Wendling <isanbard@gmail.com>2009-05-15 00:11:17 +0000
commit88423eecd0f16d3cfa89bdf92abdb72a5dc0616a (patch)
tree14a131cd9d6a504192d16f8c7274f6353c197c2c /lib/CodeGen/AsmPrinter
parent5f00b0c5b63c30c7ad6134543318551902de5c93 (diff)
downloadllvm-88423eecd0f16d3cfa89bdf92abdb72a5dc0616a.tar.gz
llvm-88423eecd0f16d3cfa89bdf92abdb72a5dc0616a.tar.bz2
llvm-88423eecd0f16d3cfa89bdf92abdb72a5dc0616a.tar.xz
Split out the Dwarf writer stuff into separate files. This is a much more
logical/sane approach to organizing all of the stuff that goes into writing out DWARF information. Honestly? even this is too complex for what it's supposed to be doing. Trivia: It *looks* like there would be functionality changes, however there aren't! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71821 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/AsmPrinter')
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.cpp518
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.h549
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfLabel.cpp35
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfLabel.h56
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfPrinter.cpp235
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfPrinter.h153
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfWriter.cpp1316
7 files changed, 1584 insertions, 1278 deletions
diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp
new file mode 100644
index 0000000000..dc149cf8bc
--- /dev/null
+++ b/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -0,0 +1,518 @@
+//===--- lib/CodeGen/DIE.cpp - DWARF Info Entries -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Data structures for DWARF info entries.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DIE.h"
+#include "DwarfPrinter.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/Target/TargetData.h"
+#include <ostream>
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// DIEAbbrevData Implementation
+//===----------------------------------------------------------------------===//
+
+/// Profile - Used to gather unique data for the abbreviation folding set.
+///
+void DIEAbbrevData::Profile(FoldingSetNodeID &ID) const {
+ ID.AddInteger(Attribute);
+ ID.AddInteger(Form);
+}
+
+//===----------------------------------------------------------------------===//
+// DIEAbbrev Implementation
+//===----------------------------------------------------------------------===//
+
+/// Profile - Used to gather unique data for the abbreviation folding set.
+///
+void DIEAbbrev::Profile(FoldingSetNodeID &ID) const {
+ ID.AddInteger(Tag);
+ ID.AddInteger(ChildrenFlag);
+
+ // For each attribute description.
+ for (unsigned i = 0, N = Data.size(); i < N; ++i)
+ Data[i].Profile(ID);
+}
+
+/// Emit - Print the abbreviation using the specified asm printer.
+///
+void DIEAbbrev::Emit(const AsmPrinter *Asm) const {
+ // Emit its Dwarf tag type.
+ Asm->EmitULEB128Bytes(Tag);
+ Asm->EOL(dwarf::TagString(Tag));
+
+ // Emit whether it has children DIEs.
+ Asm->EmitULEB128Bytes(ChildrenFlag);
+ Asm->EOL(dwarf::ChildrenString(ChildrenFlag));
+
+ // For each attribute description.
+ for (unsigned i = 0, N = Data.size(); i < N; ++i) {
+ const DIEAbbrevData &AttrData = Data[i];
+
+ // Emit attribute type.
+ Asm->EmitULEB128Bytes(AttrData.getAttribute());
+ Asm->EOL(dwarf::AttributeString(AttrData.getAttribute()));
+
+ // Emit form type.
+ Asm->EmitULEB128Bytes(AttrData.getForm());
+ Asm->EOL(dwarf::FormEncodingString(AttrData.getForm()));
+ }
+
+ // Mark end of abbreviation.
+ Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(1)");
+ Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(2)");
+}
+
+#ifndef NDEBUG
+void DIEAbbrev::print(std::ostream &O) {
+ O << "Abbreviation @"
+ << std::hex << (intptr_t)this << std::dec
+ << " "
+ << dwarf::TagString(Tag)
+ << " "
+ << dwarf::ChildrenString(ChildrenFlag)
+ << "\n";
+
+ for (unsigned i = 0, N = Data.size(); i < N; ++i) {
+ O << " "
+ << dwarf::AttributeString(Data[i].getAttribute())
+ << " "
+ << dwarf::FormEncodingString(Data[i].getForm())
+ << "\n";
+ }
+}
+void DIEAbbrev::dump() { print(cerr); }
+#endif
+
+//===----------------------------------------------------------------------===//
+// DIE Implementation
+//===----------------------------------------------------------------------===//
+
+DIE::~DIE() {
+ for (unsigned i = 0, N = Children.size(); i < N; ++i)
+ delete Children[i];
+}
+
+/// AddSiblingOffset - Add a sibling offset field to the front of the DIE.
+///
+void DIE::AddSiblingOffset() {
+ DIEInteger *DI = new DIEInteger(0);
+ Values.insert(Values.begin(), DI);
+ Abbrev.AddFirstAttribute(dwarf::DW_AT_sibling, dwarf::DW_FORM_ref4);
+}
+
+/// Profile - Used to gather unique data for the value folding set.
+///
+void DIE::Profile(FoldingSetNodeID &ID) {
+ Abbrev.Profile(ID);
+
+ for (unsigned i = 0, N = Children.size(); i < N; ++i)
+ ID.AddPointer(Children[i]);
+
+ for (unsigned j = 0, M = Values.size(); j < M; ++j)
+ ID.AddPointer(Values[j]);
+}
+
+#ifndef NDEBUG
+void DIE::print(std::ostream &O, unsigned IncIndent) {
+ static unsigned IndentCount = 0;
+ IndentCount += IncIndent;
+ const std::string Indent(IndentCount, ' ');
+ bool isBlock = Abbrev.getTag() == 0;
+
+ if (!isBlock) {
+ O << Indent
+ << "Die: "
+ << "0x" << std::hex << (intptr_t)this << std::dec
+ << ", Offset: " << Offset
+ << ", Size: " << Size
+ << "\n";
+
+ O << Indent
+ << dwarf::TagString(Abbrev.getTag())
+ << " "
+ << dwarf::ChildrenString(Abbrev.getChildrenFlag());
+ } else {
+ O << "Size: " << Size;
+ }
+ O << "\n";
+
+ const SmallVector<DIEAbbrevData, 8> &Data = Abbrev.getData();
+
+ IndentCount += 2;
+ for (unsigned i = 0, N = Data.size(); i < N; ++i) {
+ O << Indent;
+
+ if (!isBlock)
+ O << dwarf::AttributeString(Data[i].getAttribute());
+ else
+ O << "Blk[" << i << "]";
+
+ O << " "
+ << dwarf::FormEncodingString(Data[i].getForm())
+ << " ";
+ Values[i]->print(O);
+ O << "\n";
+ }
+ IndentCount -= 2;
+
+ for (unsigned j = 0, M = Children.size(); j < M; ++j) {
+ Children[j]->print(O, 4);
+ }
+
+ if (!isBlock) O << "\n";
+ IndentCount -= IncIndent;
+}
+
+void DIE::dump() {
+ print(cerr);
+}
+#endif
+
+
+#ifndef NDEBUG
+void DIEValue::dump() {
+ print(cerr);
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+// DIEInteger Implementation
+//===----------------------------------------------------------------------===//
+
+/// EmitValue - Emit integer of appropriate size.
+///
+void DIEInteger::EmitValue(Dwarf *D, unsigned Form) const {
+ const AsmPrinter *Asm = D->getAsm();
+ switch (Form) {
+ case dwarf::DW_FORM_flag: // Fall thru
+ case dwarf::DW_FORM_ref1: // Fall thru
+ case dwarf::DW_FORM_data1: Asm->EmitInt8(Integer); break;
+ case dwarf::DW_FORM_ref2: // Fall thru
+ case dwarf::DW_FORM_data2: Asm->EmitInt16(Integer); break;
+ case dwarf::DW_FORM_ref4: // Fall thru
+ case dwarf::DW_FORM_data4: Asm->EmitInt32(Integer); break;
+ case dwarf::DW_FORM_ref8: // Fall thru
+ case dwarf::DW_FORM_data8: Asm->EmitInt64(Integer); break;
+ case dwarf::DW_FORM_udata: Asm->EmitULEB128Bytes(Integer); break;
+ case dwarf::DW_FORM_sdata: Asm->EmitSLEB128Bytes(Integer); break;
+ default: assert(0 && "DIE Value form not supported yet"); break;
+ }
+}
+
+/// SizeOf - Determine size of integer value in bytes.
+///
+unsigned DIEInteger::SizeOf(const TargetData *TD, unsigned Form) const {
+ switch (Form) {
+ case dwarf::DW_FORM_flag: // Fall thru
+ case dwarf::DW_FORM_ref1: // Fall thru
+ case dwarf::DW_FORM_data1: return sizeof(int8_t);
+ case dwarf::DW_FORM_ref2: // Fall thru
+ case dwarf::DW_FORM_data2: return sizeof(int16_t);
+ case dwarf::DW_FORM_ref4: // Fall thru
+ case dwarf::DW_FORM_data4: return sizeof(int32_t);
+ case dwarf::DW_FORM_ref8: // Fall thru
+ case dwarf::DW_FORM_data8: return sizeof(int64_t);
+ case dwarf::DW_FORM_udata: return TargetAsmInfo::getULEB128Size(Integer);
+ case dwarf::DW_FORM_sdata: return TargetAsmInfo::getSLEB128Size(Integer);
+ default: assert(0 && "DIE Value form not supported yet"); break;
+ }
+ return 0;
+}
+
+/// Profile - Used to gather unique data for the value folding set.
+///
+void DIEInteger::Profile(FoldingSetNodeID &ID, unsigned Int) {
+ ID.AddInteger(isInteger);
+ ID.AddInteger(Int);
+}
+void DIEInteger::Profile(FoldingSetNodeID &ID) {
+ Profile(ID, Integer);
+}
+
+#ifndef NDEBUG
+void DIEInteger::print(std::ostream &O) {
+ O << "Int: " << (int64_t)Integer
+ << " 0x" << std::hex << Integer << std::dec;
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+// DIEString Implementation
+//===----------------------------------------------------------------------===//
+
+/// EmitValue - Emit string value.
+///
+void DIEString::EmitValue(Dwarf *D, unsigned Form) const {
+ D->getAsm()->EmitString(Str);
+}
+
+/// Profile - Used to gather unique data for the value folding set.
+///
+void DIEString::Profile(FoldingSetNodeID &ID, const std::string &Str) {
+ ID.AddInteger(isString);
+ ID.AddString(Str);
+}
+void DIEString::Profile(FoldingSetNodeID &ID) {
+ Profile(ID, Str);
+}
+
+#ifndef NDEBUG
+void DIEString::print(std::ostream &O) {
+ O << "Str: \"" << Str << "\"";
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+// DIEDwarfLabel Implementation
+//===----------------------------------------------------------------------===//
+
+/// EmitValue - Emit label value.
+///
+void DIEDwarfLabel::EmitValue(Dwarf *D, unsigned Form) const {
+ bool IsSmall = Form == dwarf::DW_FORM_data4;
+ D->EmitReference(Label, false, IsSmall);
+}
+
+/// SizeOf - Determine size of label value in bytes.
+///
+unsigned DIEDwarfLabel::SizeOf(const TargetData *TD, unsigned Form) const {
+ if (Form == dwarf::DW_FORM_data4) return 4;
+ return TD->getPointerSize();
+}
+
+/// Profile - Used to gather unique data for the value folding set.
+///
+void DIEDwarfLabel::Profile(FoldingSetNodeID &ID, const DWLabel &Label) {
+ ID.AddInteger(isLabel);
+ Label.Profile(ID);
+}
+void DIEDwarfLabel::Profile(FoldingSetNodeID &ID) {
+ Profile(ID, Label);
+}
+
+#ifndef NDEBUG
+void DIEDwarfLabel::print(std::ostream &O) {
+ O << "Lbl: ";
+ Label.print(O);
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+// DIEObjectLabel Implementation
+//===----------------------------------------------------------------------===//
+
+/// EmitValue - Emit label value.
+///
+void DIEObjectLabel::EmitValue(Dwarf *D, unsigned Form) const {
+ bool IsSmall = Form == dwarf::DW_FORM_data4;
+ D->EmitReference(Label, false, IsSmall);
+}
+
+/// SizeOf - Determine size of label value in bytes.
+///
+unsigned DIEObjectLabel::SizeOf(const TargetData *TD, unsigned Form) const {
+ if (Form == dwarf::DW_FORM_data4) return 4;
+ return TD->getPointerSize();
+}
+
+/// Profile - Used to gather unique data for the value folding set.
+///
+void DIEObjectLabel::Profile(FoldingSetNodeID &ID, const std::string &Label) {
+ ID.AddInteger(isAsIsLabel);
+ ID.AddString(Label);
+}
+void DIEObjectLabel::Profile(FoldingSetNodeID &ID) {
+ Profile(ID, Label.c_str());
+}
+
+#ifndef NDEBUG
+void DIEObjectLabel::print(std::ostream &O) {
+ O << "Obj: " << Label;
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+// DIESectionOffset Implementation
+//===----------------------------------------------------------------------===//
+
+/// EmitValue - Emit delta value.
+///
+void DIESectionOffset::EmitValue(Dwarf *D, unsigned Form) const {
+ bool IsSmall = Form == dwarf::DW_FORM_data4;
+ D->EmitSectionOffset(Label.getTag(), Section.getTag(),
+ Label.getNumber(), Section.getNumber(),
+ IsSmall, IsEH, UseSet);
+}
+
+/// SizeOf - Determine size of delta value in bytes.
+///
+unsigned DIESectionOffset::SizeOf(const TargetData *TD, unsigned Form) const {
+ if (Form == dwarf::DW_FORM_data4) return 4;
+ return TD->getPointerSize();
+}
+
+/// Profile - Used to gather unique data for the value folding set.
+///
+void DIESectionOffset::Profile(FoldingSetNodeID &ID, const DWLabel &Label,
+ const DWLabel &Section) {
+ ID.AddInteger(isSectionOffset);
+ Label.Profile(ID);
+ Section.Profile(ID);
+ // IsEH and UseSet are specific to the Label/Section that we will emit the
+ // offset for; so Label/Section are enough for uniqueness.
+}
+void DIESectionOffset::Profile(FoldingSetNodeID &ID) {
+ Profile(ID, Label, Section);
+}
+
+#ifndef NDEBUG
+void DIESectionOffset::print(std::ostream &O) {
+ O << "Off: ";
+ Label.print(O);
+ O << "-";
+ Section.print(O);
+ O << "-" << IsEH << "-" << UseSet;
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+// DIEDelta Implementation
+//===----------------------------------------------------------------------===//
+
+/// EmitValue - Emit delta value.
+///
+void DIEDelta::EmitValue(Dwarf *D, unsigned Form) const {
+ bool IsSmall = Form == dwarf::DW_FORM_data4;
+ D->EmitDifference(LabelHi, LabelLo, IsSmall);
+}
+
+/// SizeOf - Determine size of delta value in bytes.
+///
+unsigned DIEDelta::SizeOf(const TargetData *TD, unsigned Form) const {
+ if (Form == dwarf::DW_FORM_data4) return 4;
+ return TD->getPointerSize();
+}
+
+/// Profile - Used to gather unique data for the value folding set.
+///
+void DIEDelta::Profile(FoldingSetNodeID &ID, const DWLabel &LabelHi,
+ const DWLabel &LabelLo) {
+ ID.AddInteger(isDelta);
+ LabelHi.Profile(ID);
+ LabelLo.Profile(ID);
+}
+void DIEDelta::Profile(FoldingSetNodeID &ID) {
+ Profile(ID, LabelHi, LabelLo);
+}
+
+#ifndef NDEBUG
+void DIEDelta::print(std::ostream &O) {
+ O << "Del: ";
+ LabelHi.print(O);
+ O << "-";
+ LabelLo.print(O);
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+// DIEEntry Implementation
+//===----------------------------------------------------------------------===//
+
+/// EmitValue - Emit debug information entry offset.
+///
+void DIEEntry::EmitValue(Dwarf *D, unsigned Form) const {
+ D->getAsm()->EmitInt32(Entry->getOffset());
+}
+
+/// Profile - Used to gather unique data for the value folding set.
+///
+void DIEEntry::Profile(FoldingSetNodeID &ID, DIE *Entry) {
+ ID.AddInteger(isEntry);
+ ID.AddPointer(Entry);
+}
+void DIEEntry::Profile(FoldingSetNodeID &ID) {
+ ID.AddInteger(isEntry);
+
+ if (Entry)
+ ID.AddPointer(Entry);
+ else
+ ID.AddPointer(this);
+}
+
+#ifndef NDEBUG
+void DIEEntry::print(std::ostream &O) {
+ O << "Die: 0x" << std::hex << (intptr_t)Entry << std::dec;
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+// DIEBlock Implementation
+//===----------------------------------------------------------------------===//
+
+/// ComputeSize - calculate the size of the block.
+///
+unsigned DIEBlock::ComputeSize(const TargetData *TD) {
+ if (!Size) {
+ const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
+ for (unsigned i = 0, N = Values.size(); i < N; ++i)
+ Size += Values[i]->SizeOf(TD, AbbrevData[i].getForm());
+ }
+
+ return Size;
+}
+
+/// EmitValue - Emit block data.
+///
+void DIEBlock::EmitValue(Dwarf *D, unsigned Form) const {
+ const AsmPrinter *Asm = D->getAsm();
+ switch (Form) {
+ case dwarf::DW_FORM_block1: Asm->EmitInt8(Size); break;
+ case dwarf::DW_FORM_block2: Asm->EmitInt16(Size); break;
+ case dwarf::DW_FORM_block4: Asm->EmitInt32(Size); break;
+ case dwarf::DW_FORM_block: Asm->EmitULEB128Bytes(Size); break;
+ default: assert(0 && "Improper form for block"); break;
+ }
+
+ const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
+ for (unsigned i = 0, N = Values.size(); i < N; ++i) {
+ Asm->EOL();
+ Values[i]->EmitValue(D, AbbrevData[i].getForm());
+ }
+}
+
+/// SizeOf - Determine size of block data in bytes.
+///
+unsigned DIEBlock::SizeOf(const TargetData *TD, unsigned Form) const {
+ switch (Form) {
+ case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
+ case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
+ case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
+ case dwarf::DW_FORM_block: return Size + TargetAsmInfo::getULEB128Size(Size);
+ default: assert(0 && "Improper form for block"); break;
+ }
+ return 0;
+}
+
+void DIEBlock::Profile(FoldingSetNodeID &ID) {
+ ID.AddInteger(isBlock);
+ DIE::Profile(ID);
+}
+
+#ifndef NDEBUG
+void DIEBlock::print(std::ostream &O) {
+ O << "Blk: ";
+ DIE::print(O, 5);
+}
+#endif
diff --git a/lib/CodeGen/AsmPrinter/DIE.h b/lib/CodeGen/AsmPrinter/DIE.h
new file mode 100644
index 0000000000..7b4346665f
--- /dev/null
+++ b/lib/CodeGen/AsmPrinter/DIE.h
@@ -0,0 +1,549 @@
+//===--- lib/CodeGen/DIE.h - DWARF Info Entries -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Data structures for DWARF info entries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef DIE_H__
+#define DIE_H__
+
+#include "DwarfLabel.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/raw_ostream.h"
+#include <iosfwd>
+
+namespace llvm {
+ class AsmPrinter;
+ class Dwarf;
+ class TargetData;
+
+ //===--------------------------------------------------------------------===//
+ /// DIEAbbrevData - Dwarf abbreviation data, describes the one attribute of a
+ /// Dwarf abbreviation.
+ class VISIBILITY_HIDDEN DIEAbbrevData {
+ /// Attribute - Dwarf attribute code.
+ ///
+ unsigned Attribute;
+
+ /// Form - Dwarf form code.
+ ///
+ unsigned Form;
+ public:
+ DIEAbbrevData(unsigned A, unsigned F) : Attribute(A), Form(F) {}
+
+ // Accessors.
+ unsigned getAttribute() const { return Attribute; }
+ unsigned getForm() const { return Form; }
+
+ /// Profile - Used to gather unique data for the abbreviation folding set.
+ ///
+ void Profile(FoldingSetNodeID &ID) const;
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// DIEAbbrev - Dwarf abbreviation, describes the organization of a debug
+ /// information object.
+ class VISIBILITY_HIDDEN DIEAbbrev : public FoldingSetNode {
+ /// Tag - Dwarf tag code.
+ ///
+ unsigned Tag;
+
+ /// Unique number for node.
+ ///
+ unsigned Number;
+
+ /// ChildrenFlag - Dwarf children flag.
+ ///
+ unsigned ChildrenFlag;
+
+ /// Data - Raw data bytes for abbreviation.
+ ///
+ SmallVector<DIEAbbrevData, 8> Data;
+ public:
+ DIEAbbrev(unsigned T, unsigned C) : Tag(T), ChildrenFlag(C), Data() {}
+ virtual ~DIEAbbrev() {}
+
+ // Accessors.
+ unsigned getTag() const { return Tag; }
+ unsigned getNumber() const { return Number; }
+ unsigned getChildrenFlag() const { return ChildrenFlag; }
+ const SmallVector<DIEAbbrevData, 8> &getData() const { return Data; }
+ void setTag(unsigned T) { Tag = T; }
+ void setChildrenFlag(unsigned CF) { ChildrenFlag = CF; }
+ void setNumber(unsigned N) { Number = N; }
+
+ /// AddAttribute - Adds another set of attribute information to the
+ /// abbreviation.
+ void AddAttribute(unsigned Attribute, unsigned Form) {
+ Data.push_back(DIEAbbrevData(Attribute, Form));
+ }
+
+ /// AddFirstAttribute - Adds a set of attribute information to the front
+ /// of the abbreviation.
+ void AddFirstAttribute(unsigned Attribute, unsigned Form) {
+ Data.insert(Data.begin(), DIEAbbrevData(Attribute, Form));
+ }
+
+ /// Profile - Used to gather unique data for the abbreviation folding set.
+ ///
+ void Profile(FoldingSetNodeID &ID) const;
+
+ /// Emit - Print the abbreviation using the specified asm printer.
+ ///
+ void Emit(const AsmPrinter *Asm) const;
+
+#ifndef NDEBUG
+ void print(std::ostream *O) {
+ if (O) print(*O);
+ }
+ void print(std::ostream &O);
+ void dump();
+#endif
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// DIE - A structured debug information entry. Has an abbreviation which
+ /// describes it's organization.
+ class CompileUnit;
+ class DIEValue;
+
+ class VISIBILITY_HIDDEN DIE : public FoldingSetNode {
+ protected:
+ /// Abbrev - Buffer for constructing abbreviation.
+ ///
+ DIEAbbrev Abbrev;
+
+ /// Offset - Offset in debug info section.
+ ///
+ unsigned Offset;
+
+ /// Size - Size of instance + children.
+ ///
+ unsigned Size;
+
+ /// Children DIEs.
+ ///
+ std::vector<DIE *> Children;
+
+ /// Attributes values.
+ ///
+ SmallVector<DIEValue*, 32> Values;
+
+ /// Abstract compile unit.
+ CompileUnit *AbstractCU;
+ public:
+ explicit DIE(unsigned Tag)
+ : Abbrev(Tag, dwarf::DW_CHILDREN_no), Offset(0), Size(0) {}
+ virtual ~DIE();
+
+ // Accessors.
+ DIEAbbrev &getAbbrev() { return Abbrev; }
+ unsigned getAbbrevNumber() const { return Abbrev.getNumber(); }
+ unsigned getTag() const { return Abbrev.getTag(); }
+ unsigned getOffset() const { return Offset; }
+ unsigned getSize() const { return Size; }
+ const std::vector<DIE *> &getChildren() const { return Children; }
+ SmallVector<DIEValue*, 32> &getValues() { return Values; }
+ CompileUnit *getAbstractCompileUnit() const { return AbstractCU; }
+
+ void setTag(unsigned Tag) { Abbrev.setTag(Tag); }
+ void setOffset(unsigned O) { Offset = O; }
+ void setSize(unsigned S) { Size = S; }
+ void setAbstractCompileUnit(CompileUnit *CU) { AbstractCU = CU; }
+
+ /// AddValue - Add a value and attributes to a DIE.
+ ///
+ void AddValue(unsigned Attribute, unsigned Form, DIEValue *Value) {
+ Abbrev.AddAttribute(Attribute, Form);
+ Values.push_back(Value);
+ }
+
+ /// SiblingOffset - Return the offset of the debug information entry's
+ /// sibling.
+ unsigned SiblingOffset() const { return Offset + Size; }
+
+ /// AddSiblingOffset - Add a sibling offset field to the front of the DIE.
+ ///
+ void AddSiblingOffset();
+
+ /// AddChild - Add a child to the DIE.
+ ///
+ void AddChild(DIE *Child) {
+ Abbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes);
+ Children.push_back(Child);
+ }
+
+ /// Detach - Detaches objects connected to it after copying.
+ ///
+ void Detach() {
+ Children.clear();
+ }
+
+ /// Profile - Used to gather unique data for the value folding set.
+ ///
+ void Profile(FoldingSetNodeID &ID) ;
+
+#ifndef NDEBUG
+ void print(std::ostream *O, unsigned IncIndent = 0) {
+ if (O) print(*O, IncIndent);
+ }
+ void print(std::ostream &O, unsigned IncIndent = 0);
+ void dump();
+#endif
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// DIEValue - A debug information entry value.
+ ///
+ class VISIBILITY_HIDDEN DIEValue : public FoldingSetNode {
+ public:
+ enum {
+ isInteger,
+ isString,
+ isLabel,
+ isAsIsLabel,
+ isSectionOffset,
+ isDelta,
+ isEntry,
+ isBlock
+ };
+ protected:
+ /// Type - Type of data stored in the value.
+ ///
+ unsigned Type;
+ public:
+ explicit DIEValue(unsigned T) : Type(T) {}
+ virtual ~DIEValue() {}
+
+ // Accessors
+ unsigned getType() const { return Type; }
+
+ /// EmitValue - Emit value via the Dwarf writer.
+ ///
+ virtual void EmitValue(Dwarf *D, unsigned Form) const = 0;
+
+ /// SizeOf - Return the size of a value in bytes.
+ ///
+ virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const = 0;
+
+ /// Profile - Used to gather unique data for the value folding set.
+ ///
+ virtual void Profile(FoldingSetNodeID &ID) = 0;
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const DIEValue *) { return true; }
+
+#ifndef NDEBUG
+ void print(std::ostream *O) {
+ if (O) print(*O);
+ }
+ virtual void print(std::ostream &O) = 0;
+ void dump();
+#endif
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// DIEInteger - An integer value DIE.
+ ///
+ class VISIBILITY_HIDDEN DIEInteger : public DIEValue {
+ uint64_t Integer;
+ public:
+ explicit DIEInteger(uint64_t I) : DIEValue(isInteger), Integer(I) {}
+
+ /// BestForm - Choose the best form for integer.
+ ///
+ static unsigned BestForm(bool IsSigned, uint64_t Int) {
+ if (IsSigned) {
+ if ((char)Int == (signed)Int) return dwarf::DW_FORM_data1;
+ if ((short)Int == (signed)Int) return dwarf::DW_FORM_data2;
+ if ((int)Int == (signed)Int) return dwarf::DW_FORM_data4;
+ } else {
+ if ((unsigned char)Int == Int) return dwarf::DW_FORM_data1;
+ if ((unsigned short)Int == Int) return dwarf::DW_FORM_data2;
+ if ((unsigned int)Int == Int) return dwarf::DW_FORM_data4;
+ }
+ return dwarf::DW_FORM_data8;
+ }
+
+ /// EmitValue - Emit integer of appropriate size.
+ ///
+ virtual void EmitValue(Dwarf *D, unsigned Form) const;
+
+ /// SizeOf - Determine size of integer value in bytes.
+ ///
+ virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
+
+ /// Profile - Used to gather unique data for the value folding set.
+ ///
+ static void Profile(FoldingSetNodeID &ID, unsigned Int);
+ virtual void Profile(FoldingSetNodeID &ID);
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const DIEInteger *) { return true; }
+ static bool classof(const DIEValue *I) { return I->getType() == isInteger; }
+
+#ifndef NDEBUG
+ virtual void print(std::ostream &O);
+#endif
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// DIEString - A string value DIE.
+ ///
+ class VISIBILITY_HIDDEN DIEString : public DIEValue {
+ const std::string Str;
+ public:
+ explicit DIEString(const std::string &S) : DIEValue(isString), Str(S) {}
+
+ /// EmitValue - Emit string value.
+ ///
+ virtual void EmitValue(Dwarf *D, unsigned Form) const;
+
+ /// SizeOf - Determine size of string value in bytes.
+ ///
+ virtual unsigned SizeOf(const TargetData *, unsigned /*Form*/) const {
+ return Str.size() + sizeof(char); // sizeof('\0');
+ }
+
+ /// Profile - Used to gather unique data for the value folding set.
+ ///
+ static void Profile(FoldingSetNodeID &ID, const std::string &Str);
+ virtual void Profile(FoldingSetNodeID &ID);
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const DIEString *) { return true; }
+ static bool classof(const DIEValue *S) { return S->getType() == isString; }
+
+#ifndef NDEBUG
+ virtual void print(std::ostream &O);
+#endif
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// DIEDwarfLabel - A Dwarf internal label expression DIE.
+ //
+ class VISIBILITY_HIDDEN DIEDwarfLabel : public DIEValue {
+ const DWLabel Label;
+ public:
+ explicit DIEDwarfLabel(const DWLabel &L) : DIEValue(isLabel), Label(L) {}
+
+ /// EmitValue - Emit label value.
+ ///
+ virtual void EmitValue(Dwarf *D, unsigned Form) const;
+
+ /// SizeOf - Determine size of label value in bytes.
+ ///
+ virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
+
+ /// Profile - Used to gather unique data for the value folding set.
+ ///
+ static void Profile(FoldingSetNodeID &ID, const DWLabel &Label);
+ virtual void Profile(FoldingSetNodeID &ID);
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const DIEDwarfLabel *) { return true; }
+ static bool classof(const DIEValue *L) { return L->getType() == isLabel; }
+
+#ifndef NDEBUG
+ virtual void print(std::ostream &O);
+#endif
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// DIEObjectLabel - A label to an object in code or data.
+ //
+ class VISIBILITY_HIDDEN DIEObjectLabel : public DIEValue {
+ const std::string Label;
+ public:
+ explicit DIEObjectLabel(const std::string &L)
+ : DIEValue(isAsIsLabel), Label(L) {}
+
+ /// EmitValue - Emit label value.
+ ///
+ virtual void EmitValue(Dwarf *D, unsigned Form) const;
+
+ /// SizeOf - Determine size of label value in bytes.
+ ///
+ virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
+
+ /// Profile - Used to gather unique data for the value folding set.
+ ///
+ static void Profile(FoldingSetNodeID &ID, const std::string &Label);
+ virtual void Profile(FoldingSetNodeID &ID);
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const DIEObjectLabel *) { return true; }
+ static bool classof(const DIEValue *L) {
+ return L->getType() == isAsIsLabel;
+ }
+
+#ifndef NDEBUG
+ virtual void print(std::ostream &O);
+#endif
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// DIESectionOffset - A section offset DIE.
+ ///
+ class VISIBILITY_HIDDEN DIESectionOffset : public DIEValue {
+ const DWLabel Label;
+ const DWLabel Section;
+ bool IsEH : 1;
+ bool UseSet : 1;
+ public:
+ DIESectionOffset(const DWLabel &Lab, const DWLabel &Sec,
+ bool isEH = false, bool useSet = true)
+ : DIEValue(isSectionOffset), Label(Lab), Section(Sec),
+ IsEH(isEH), UseSet(useSet) {}
+
+ /// EmitValue - Emit section offset.
+ ///
+ virtual void EmitValue(Dwarf *D, unsigned Form) const;
+
+ /// SizeOf - Determine size of section offset value in bytes.
+ ///
+ virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
+
+ /// Profile - Used to gather unique data for the value folding set.
+ ///
+ static void Profile(FoldingSetNodeID &ID, const DWLabel &Label,
+ const DWLabel &Section);
+ virtual void Profile(FoldingSetNodeID &ID);
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const DIESectionOffset *) { return true; }
+ static bool classof(const DIEValue *D) {
+ return D->getType() == isSectionOffset;
+ }
+
+#ifndef NDEBUG
+ virtual void print(std::ostream &O);
+#endif
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// DIEDelta - A simple label difference DIE.
+ ///
+ class VISIBILITY_HIDDEN DIEDelta : public DIEValue {
+ const DWLabel LabelHi;
+ const DWLabel LabelLo;
+ public:
+ DIEDelta(const DWLabel &Hi, const DWLabel &Lo)
+ : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {}
+
+ /// EmitValue - Emit delta value.
+ ///
+ virtual void EmitValue(Dwarf *D, unsigned Form) const;
+
+ /// SizeOf - Determine size of delta value in bytes.
+ ///
+ virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
+
+ /// Profile - Used to gather unique data for the value folding set.
+ ///
+ static void Profile(FoldingSetNodeID &ID, const DWLabel &LabelHi,
+ const DWLabel &LabelLo);
+ virtual void Profile(FoldingSetNodeID &ID);
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const DIEDelta *) { return true; }
+ static bool classof(const DIEValue *D) { return D->getType() == isDelta; }
+
+#ifndef NDEBUG
+ virtual void print(std::ostream &O);
+#endif
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// DIEntry - A pointer to another debug information entry. An instance of
+ /// this class can also be used as a proxy for a debug information entry not
+ /// yet defined (ie. types.)
+ class VISIBILITY_HIDDEN DIEEntry : public DIEValue {
+ DIE *Entry;
+ public:
+ explicit DIEEntry(DIE *E) : DIEValue(isEntry), Entry(E) {}
+
+ DIE *getEntry() const { return Entry; }
+ void setEntry(DIE *E) { Entry = E; }
+
+ /// EmitValue - Emit debug information entry offset.
+ ///
+ virtual void EmitValue(Dwarf *D, unsigned Form) const;
+
+ /// SizeOf - Determine size of debug information entry in bytes.
+ ///
+ virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const {
+ return sizeof(int32_t);
+ }
+
+ /// Profile - Used to gather unique data for the value folding set.
+ ///
+ static void Profile(FoldingSetNodeID &ID, DIE *Entry);
+ virtual void Profile(FoldingSetNodeID &ID);
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const DIEEntry *) { return true; }
+ static bool classof(const DIEValue *E) { return E->getType() == isEntry; }
+
+#ifndef NDEBUG
+ virtual void print(std::ostream &O);
+#endif
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// DIEBlock - A block of values. Primarily used for location expressions.
+ //
+ class DIEBlock : public DIEValue, public DIE {
+ unsigned Size; // Size in bytes excluding size header.
+ public:
+ DIEBlock()
+ : DIEValue(isBlock), DIE(0), Size(0) {}
+ virtual ~DIEBlock() {}
+
+ /// ComputeSize - calculate the size of the block.
+ ///
+ unsigned ComputeSize(const TargetData *TD);
+
+ /// BestForm - Choose the best form for data.
+ ///
+ unsigned BestForm() const {
+ if ((unsigned char)Size == Size) return dwarf::DW_FORM_block1;
+ if ((unsigned short)Size == Size) return dwarf::DW_FORM_block2;
+ if ((unsigned int)Size == Size) return dwarf::DW_FORM_block4;
+ return dwarf::DW_FORM_block;
+ }
+
+ /// EmitValue - Emit block data.
+ ///
+ virtual void EmitValue(Dwarf *D, unsigned Form) const;
+
+ /// SizeOf - Determine size of block data in bytes.
+ ///
+ virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
+
+ /// Profile - Used to gather unique data for the value folding set.
+ ///
+ virtual void Profile(FoldingSetNodeID &ID);
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const DIEBlock *) { return true; }
+ static bool classof(const DIEValue *E) { return E->getType() == isBlock; }
+
+#ifndef NDEBUG
+ virtual void print(std::ostream &O);
+#endif
+ };
+
+} // end llvm namespace
+
+#endif
diff --git a/lib/CodeGen/AsmPrinter/DwarfLabel.cpp b/lib/CodeGen/AsmPrinter/DwarfLabel.cpp
new file mode 100644
index 0000000000..8021b7c97b
--- /dev/null
+++ b/lib/CodeGen/AsmPrinter/DwarfLabel.cpp
@@ -0,0 +1,35 @@
+//===--- lib/CodeGen/DwarfLabel.cpp - Dwarf Label -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// DWARF Labels
+//
+//===----------------------------------------------------------------------===//
+
+#include "DwarfLabel.h"
+#include "llvm/ADT/FoldingSet.h"
+#include <ostream>
+
+using namespace llvm;
+
+/// Profile - Used to gather unique data for the folding set.
+///
+void DWLabel::Profile(FoldingSetNodeID &ID) const {
+ ID.AddString(Tag);
+ ID.AddInteger(Number);
+}
+
+#ifndef NDEBUG
+void DWLabel::print(std::ostream *O) const {
+ if (O) print(*O);
+}
+void DWLabel::print(std::ostream &O) const {
+ O << "." << Tag;
+ if (Number) O << Number;
+}
+#endif
diff --git a/lib/CodeGen/AsmPrinter/DwarfLabel.h b/lib/CodeGen/AsmPrinter/DwarfLabel.h
new file mode 100644
index 0000000000..ee093d9bbf
--- /dev/null
+++ b/lib/CodeGen/AsmPrinter/DwarfLabel.h
@@ -0,0 +1,56 @@
+//===--- lib/CodeGen/DwarfLabel.h - Dwarf Label -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// DWARF Labels.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef DWARFLABEL_H__
+#define DWARFLABEL_H__
+
+#include "llvm/Support/Compiler.h"
+#include <iosfwd>
+#include <vector>
+
+namespace llvm {
+ class FoldingSetNodeID;
+
+ //===--------------------------------------------------------------------===//
+ /// DWLabel - Labels are used to track locations in the assembler file.
+ /// Labels appear in the form @verbatim <prefix><Tag><Number> @endverbatim,
+ /// where the tag is a category of label (Ex. location) and number is a value
+ /// unique in that category.
+ class VISIBILITY_HIDDEN DWLabel {
+ /// Tag - Label category tag. Should always be a statically declared C
+ /// string.
+ ///
+ const char *Tag;
+
+ /// Number - Value to make label unique.
+ ///
+ unsigned Number;
+ public:
+ DWLabel(const char *T, unsigned N) : Tag(T), Number(N) {}
+
+ // Accessors.
+ const char *getTag() const { return Tag; }
+ unsigned getNumber() const { return Number; }
+
+ /// Profile - Used to gather unique data for the folding set.
+ ///
+ void Profile(FoldingSetNodeID &ID) const;
+
+#ifndef NDEBUG
+ void print(std::ostream *O) const;
+ void print(std::ostream &O) const;
+#endif
+ };
+} // end llvm namespace
+
+#endif
diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
new file mode 100644
index 0000000000..45e7dd3058
--- /dev/null
+++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
@@ -0,0 +1,235 @@
+//===--- lib/CodeGen/DwarfPrinter.cpp - Dwarf Printer ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Emit general DWARF directives.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DwarfPrinter.h"
+#include "llvm/Module.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetFrameInfo.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include <ostream>
+
+using namespace llvm;
+
+Dwarf::Dwarf(raw_ostream &OS, AsmPrinter *A, const TargetAsmInfo *T,
+ const char *flavor)
+: O(OS), Asm(A), TAI(T), TD(Asm->TM.getTargetData()),
+ RI(Asm->TM.getRegisterInfo()), M(NULL), MF(NULL), MMI(NULL),
+ SubprogramCount(0), Flavor(flavor), SetCounter(1) {}
+
+void Dwarf::PrintRelDirective(bool Force32Bit, bool isInSection) const {
+ if (isInSection && TAI->getDwarfSectionOffsetDirective())
+ O << TAI->getDwarfSectionOffsetDirective();
+ else if (Force32Bit || TD->getPointerSize() == sizeof(int32_t))
+ O << TAI->getData32bitsDirective();
+ else
+ O << TAI->getData64bitsDirective();
+}
+
+/// PrintLabelName - Print label name in form used by Dwarf writer.
+///
+void Dwarf::PrintLabelName(const char *Tag, unsigned Number) const {
+ O << TAI->getPrivateGlobalPrefix() << Tag;
+ if (Number) O << Number;
+}
+void Dwarf::PrintLabelName(const char *Tag, unsigned Number,
+ const char *Suffix) const {
+ O << TAI->getPrivateGlobalPrefix() << Tag;
+ if (Number) O << Number;
+ O << Suffix;
+}
+
+/// EmitLabel - Emit location label for internal use by Dwarf.
+///
+void Dwarf::EmitLabel(const char *Tag, unsigned Number) const {
+ PrintLabelName(Tag, Number);
+ O << ":\n";
+}
+
+/// EmitReference - Emit a reference to a label.
+///
+void Dwarf::EmitReference(const char *Tag, unsigned Number,
+ bool IsPCRelative, bool Force32Bit) const {
+ PrintRelDirective(Force32Bit);
+ PrintLabelName(Tag, Number);
+ if (IsPCRelative) O << "-" << TAI->getPCSymbol();
+}
+void Dwarf::EmitReference(const std::string &Name, bool IsPCRelative,
+ bool Force32Bit) const {
+ PrintRelDirective(Force32Bit);
+ O << Name;
+ if (IsPCRelative) O << "-" << TAI->getPCSymbol();
+}
+
+/// EmitDifference - Emit the difference between two labels. Some assemblers do
+/// not behave with absolute expressions with data directives, so there is an
+/// option (needsSet) to use an intermediary set expression.
+void Dwarf::EmitDifference(const char *TagHi, unsigned NumberHi,
+ const char *TagLo, unsigned NumberLo,
+ bool IsSmall) {
+ if (TAI->needsSet()) {
+ O << "\t.set\t";
+ PrintLabelName("set", SetCounter, Flavor);
+ O << ",";
+ PrintLabelName(TagHi, NumberHi);
+ O << "-";
+ PrintLabelName(TagLo, NumberLo);
+ O << "\n";
+
+ PrintRelDirective(IsSmall);
+ PrintLabelName("set", SetCounter, Flavor);
+ ++SetCounter;
+ } else {
+ PrintRelDirective(IsSmall);
+ PrintLabelName(TagHi, NumberHi);
+ O << "-";
+ PrintLabelName(TagLo, NumberLo);
+ }
+}
+
+void Dwarf::EmitSectionOffset(const char* Label, const char* Section,
+ unsigned LabelNumber, unsigned SectionNumber,
+ bool IsSmall, bool isEH,
+ bool useSet) {
+ bool printAbsolute = false;
+ if (isEH)
+ printAbsolute = TAI->isAbsoluteEHSectionOffsets();
+ else
+ printAbsolute = TAI->isAbsoluteDebugSectionOffsets();
+
+ if (TAI->needsSet() && useSet) {
+ O << "\t.set\t";
+ PrintLabelName("set", SetCounter, Flavor);
+ O << ",";
+ PrintLabelName(Label, LabelNumber);
+
+ if (!printAbsolute) {
+ O << "-";
+ PrintLabelName(Section, SectionNumber);
+ }
+
+ O << "\n";
+ PrintRelDirective(IsSmall);
+ PrintLabelName("set", SetCounter, Flavor);
+ ++SetCounter;
+ } else {
+ PrintRelDirective(IsSmall, true);
+ PrintLabelName(Label, LabelNumber);
+
+ if (!printAbsolute) {
+ O << "-";
+ PrintLabelName(Section, SectionNumber);
+ }
+ }
+}
+
+/// EmitFrameMoves - Emit frame instructions to describe the layout of the
+/// frame.
+void Dwarf::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,
+ const std::vector<MachineMove> &Moves, bool isEH) {
+ int stackGrowth =
+ Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
+ TargetFrameInfo::StackGrowsUp ?
+ TD->getPointerSize() : -TD->getPointerSize();
+ bool IsLocal = BaseLabel && strcmp(BaseLabel, "label") == 0;
+
+ for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
+ const MachineMove &Move = Moves[i];
+ unsigned LabelID = Move.getLabelID();
+
+ if (LabelID) {
+ LabelID = MMI->MappedLabel(LabelID);
+
+ // Throw out move if the label is invalid.
+ if (!LabelID) continue;
+ }
+
+ const MachineLocation &Dst = Move.getDestination();
+ const MachineLocation &Src = Move.getSource();
+
+ // Advance row if new location.
+ if (BaseLabel && LabelID && (BaseLabelID != LabelID || !IsLocal)) {
+ Asm->EmitInt8(dwarf::DW_CFA_advance_loc4);
+ Asm->EOL("DW_CFA_advance_loc4");
+ EmitDifference("label", LabelID, BaseLabel, BaseLabelID, true);
+ Asm->EOL();
+
+ BaseLabelID = LabelID;
+ BaseLabel = "label";
+ IsLocal = true;
+ }
+
+ // If advancing cfa.
+ if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
+ if (!Src.isReg()) {
+ if (Src.getReg() == MachineLocation::VirtualFP) {
+ Asm->EmitInt8(dwarf::DW_CFA_def_cfa_offset);
+ Asm->EOL("DW_CFA_def_cfa_offset");
+ } else {
+ Asm->EmitInt8(dwarf::DW_CFA_def_cfa);
+ Asm->EOL("DW_CFA_def_cfa");
+ Asm->EmitULEB128Bytes(RI->getDwarfRegNum(Src.getReg(), isEH));
+ Asm->EOL("Register");
+ }
+
+ int Offset = -Src.getOffset();
+
+ Asm->EmitULEB128Bytes(Offset);
+ Asm->EOL("Offset");
+ } else {
+ assert(0 && "Machine move no supported yet.");
+ }
+ } else if (Src.isReg() &&
+ Src.getReg() == MachineLocation::VirtualFP) {
+ if (Dst.isReg()) {
+ Asm->EmitInt8(dwarf::DW_CFA_def_cfa_register);
+ Asm->EOL("DW_CFA_def_cfa_register");
+ Asm->EmitULEB128Bytes(RI->getDwarfRegNum(Dst.getReg(), isEH));
+ Asm->EOL("Register");
+ } else {
+ assert(0 && "Machine move no supported yet.");
+ }
+ } else {
+ unsigned Reg = RI->getDwarfRegNum(Src.getReg(), isEH);
+ int Offset = Dst.getOffset() / stackGrowth;
+
+ if (Offset < 0) {
+ Asm->EmitInt8(dwarf::DW_CFA_offset_extended_sf);
+ Asm->EOL("DW_CFA_offset_extended_sf");
+ Asm->EmitULEB128Bytes(Reg);
+ Asm->EOL("Reg");
+ Asm->EmitSLEB128Bytes(Offset);
+ Asm->EOL("Offset");
+ } else if (Reg < 64) {
+ Asm->EmitInt8(dwarf::DW_CFA_offset + Reg);
+ if (Asm->isVerbose())
+ Asm->EOL("DW_CFA_offset + Reg (" + utostr(Reg) + ")");
+ else
+ Asm->EOL();
+ Asm->EmitULEB128Bytes(Offset);
+ Asm->EOL("Offset");
+ } else {
+ Asm->EmitInt8(dwarf::DW_CFA_offset_extended);
+ Asm->EOL("DW_CFA_offset_extended");
+ Asm->EmitULEB128Bytes(Reg);
+ Asm->EOL("Reg");
+ Asm->EmitULEB128Bytes(Offset);
+ Asm->EOL("Offset");
+ }
+ }
+ }
+}
diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.h b/lib/CodeGen/AsmPrinter/DwarfPrinter.h
new file mode 100644
index 0000000000..1ca72f4e63
--- /dev/null
+++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.h
@@ -0,0 +1,153 @@
+//===--- lib/CodeGen/DwarfPrinter.h - Dwarf Printer -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Emit general DWARF directives.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef DWARFPRINTER_H__
+#define DWARFPRINTER_H__
+
+#include "DwarfLabel.h"
+#include "llvm/CodeGen/MachineLocation.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/raw_ostream.h"
+#include <vector>
+
+namespace llvm {
+ class AsmPrinter;
+ class MachineFunction;
+ class MachineModuleInfo;
+ class Module;
+ class TargetAsmInfo;
+ class TargetData;
+ class TargetRegisterInfo;
+
+ class VISIBILITY_HIDDEN Dwarf {
+ protected:
+ //===-------------------------------------------------------------==---===//
+ // Core attributes used by the DWARF printer.
+ //
+
+ /// O - Stream to .s file.
+ ///
+ raw_ostream &O;
+
+ /// Asm - Target of Dwarf emission.
+ ///
+ AsmPrinter *Asm;
+
+ /// TAI - Target asm information.
+ ///
+ const TargetAsmInfo *TAI;
+
+ /// TD - Target data.
+ ///
+ const TargetData *TD;
+
+ /// RI - Register Information.
+ ///
+ const TargetRegisterInfo *RI;
+
+ /// M - Current module.
+ ///
+ Module *M;
+
+ /// MF - Current machine function.
+ ///
+ MachineFunction *MF;
+
+ /// MMI - Collected machine module information.
+ ///
+ MachineModuleInfo *MMI;
+
+ /// SubprogramCount - The running count of functions being compiled.
+ ///
+ unsigned SubprogramCount;
+
+ /// Flavor - A unique string indicating what dwarf producer this is, used to
+ /// unique labels.
+ ///
+ const char * const Flavor;
+
+ /// SetCounter - A unique number for each '.set' directive.
+ ///
+ unsigned SetCounter;
+
+ Dwarf(raw_ostream &OS, AsmPrinter *A, const TargetAsmInfo *T,
+ const char *flavor);
+ public:
+ //===------------------------------------------------------------------===//
+ // Accessors.
+ //
+ const AsmPrinter *getAsm() const { return Asm; }
+ MachineModuleInfo *getMMI() const { return MMI; }
+ const TargetAsmInfo *getTargetAsmInfo() const { return TAI; }
+ const TargetData *getTargetData() const { return TD; }
+
+ void PrintRelDirective(bool Force32Bit = false,
+ bool isInSection = false) const;
+
+
+ /// PrintLabelName - Print label name in form used by Dwarf writer.
+ ///
+ void PrintLabelName(const DWLabel &Label) const {
+ PrintLabelName(Label.getTag(), Label.getNumber());
+ }
+ void PrintLabelName(const char *Tag, unsigned Number) const;
+ void PrintLabelName(const char *Tag, unsigned Number,
+ const char *Suffix) const;
+
+ /// EmitLabel - Emit location label for internal use by Dwarf.
+ ///
+ void EmitLabel(const DWLabel &Label) const {
+ EmitLabel(Label.getTag(), Label.getNumber());
+ }
+ void EmitLabel(const char *Tag, unsigned Number) const;
+
+ /// EmitReference - Emit a reference to a label.
+ ///
+ void EmitReference(const DWLabel &Label, bool IsPCRelative = false,
+ bool Force32Bit = false) const {
+ EmitReference(Label.getTag(), Label.getNumber(),
+ IsPCRelative, Force32Bit);
+ }
+ void EmitReference(const char *Tag, unsigned Number,
+ bool IsPCRelative = false,
+ bool Force32Bit = false) const;
+ void EmitReference(const std::string &Name, bool IsPCRelative = false,
+ bool Force32Bit = false) const;
+
+ /// EmitDifference - Emit the difference between two labels. Some
+ /// assemblers do not behave with absolute expressions with data directives,
+ /// so there is an option (needsSet) to use an intermediary set expression.
+ void EmitDifference(const DWLabel &LabelHi, const DWLabel &LabelLo,
+ bool IsSmall = false) {
+ EmitDifference(LabelHi.getTag(), LabelHi.getNumber(),
+ LabelLo.getTag(), LabelLo.getNumber(),
+ IsSmall);
+ }
+ void EmitDifference(const char *TagHi, unsigned NumberHi,
+ const char *TagLo, unsigned NumberLo,
+ bool IsSmall = false);
+
+ void EmitSectionOffset(const char* Label, const char* Section,
+ unsigned LabelNumber, unsigned SectionNumber,
+ bool IsSmall = false, bool isEH = false,
+ bool useSet = true);
+
+ /// EmitFrameMoves - Emit frame instructions to describe the layout of the
+ /// frame.
+ void EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,
+ const std::vector<MachineMove> &Moves, bool isEH);
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
index c77a7537cb..83275fb92e 100644
--- a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
@@ -12,6 +12,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/DwarfWriter.h"
+#include "DIE.h"
+#include "DwarfPrinter.h"
#include "llvm/Module.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"
@@ -64,633 +66,6 @@ static const unsigned InitAbbreviationsSetSize = 9; // log2(512)
static const unsigned InitValuesSetSize = 9; // log2(512)
//===----------------------------------------------------------------------===//
-/// Forward declarations.
-///
-class DIE;
-class DIEValue;
-
-//===----------------------------------------------------------------------===//
-/// DWLabel - Labels are used to track locations in the assembler file.
-/// Labels appear in the form @verbatim <prefix><Tag><Number> @endverbatim,
-/// where the tag is a category of label (Ex. location) and number is a value
-/// unique in that category.
-class DWLabel {
-public:
- /// Tag - Label category tag. Should always be a staticly declared C string.
- ///
- const char *Tag;
-
- /// Number - Value to make label unique.
- ///
- unsigned Number;
-
- DWLabel(const char *T, unsigned N) : Tag(T), Number(N) {}
-
- void Profile(FoldingSetNodeID &ID) const {
- ID.AddString(Tag);
- ID.AddInteger(Number);
- }
-
-#ifndef NDEBUG
- void print(std::ostream *O) const {
- if (O) print(*O);
- }
- void print(std::ostream &O) const {
- O << "." << Tag;
- if (Number) O << Number;
- }
-#endif
-};
-
-//===----------------------------------------------------------------------===//
-/// DIEAbbrevData - Dwarf abbreviation data, describes the one attribute of a
-/// Dwarf abbreviation.
-class DIEAbbrevData {
- /// Attribute - Dwarf attribute code.
- ///
- unsigned Attribute;
-
- /// Form - Dwarf form code.
- ///
- unsigned Form;
-public:
- DIEAbbrevData(unsigned A, unsigned F) : Attribute(A), Form(F) {}
-
- // Accessors.
- unsigned getAttribute() const { return Attribute; }
- unsigned getForm() const { return Form; }
-
- /// Profile - Used to gather unique data for the abbreviation folding set.
- ///
- void Profile(FoldingSetNodeID &ID)const {
- ID.AddInteger(Attribute);
- ID.AddInteger(Form);
- }
-};
-
-//===----------------------------------------------------------------------===//
-/// DIEAbbrev - Dwarf abbreviation, describes the organization of a debug
-/// information object.
-class DIEAbbrev : public FoldingSetNode {
-private:
- /// Tag - Dwarf tag code.
- ///
- unsigned Tag;
-
- /// Unique number for node.
- ///
- unsigned Number;
-
- /// ChildrenFlag - Dwarf children flag.
- ///
- unsigned ChildrenFlag;
-
- /// Data - Raw data bytes for abbreviation.
- ///
- SmallVector<DIEAbbrevData, 8> Data;
-public:
- DIEAbbrev(unsigned T, unsigned C) : Tag(T), ChildrenFlag(C), Data() {}
- virtual ~DIEAbbrev() {}
-
- // Accessors.
- unsigned getTag() const { return Tag; }
- unsigned getNumber() const { return Number; }
- unsigned getChildrenFlag() const { return ChildrenFlag; }
- const SmallVector<DIEAbbrevData, 8> &getData() const { return Data; }
- void setTag(unsigned T) { Tag = T; }
- void setChildrenFlag(unsigned CF) { ChildrenFlag = CF; }
- void setNumber(unsigned N) { Number = N; }
-
- /// AddAttribute - Adds another set of attribute information to the
- /// abbreviation.
- void AddAttribute(unsigned Attribute, unsigned Form) {
- Data.push_back(DIEAbbrevData(Attribute, Form));
- }
-
- /// AddFirstAttribute - Adds a set of attribute information to the front
- /// of the abbreviation.
- void AddFirstAttribute(unsigned Attribute, unsigned Form) {
- Data.insert(Data.begin(), DIEAbbrevData(Attribute, Form));
- }
-
- /// Profile - Used to gather unique data for the abbreviation folding set.
- ///
- void Profile(FoldingSetNodeID &ID) {
- ID.AddInteger(Tag);
- ID.AddInteger(ChildrenFlag);
-
- // For each attribute description.
- for (unsigned i = 0, N = Data.size(); i < N; ++i)
- Data[i].Profile(ID);
- }
-
- /// Emit - Print the abbreviation using the specified Dwarf writer.
- ///
- void Emit(const DwarfDebug &DD) const;
-
-#ifndef NDEBUG
- void print(std::ostream *O) {
- if (O) print(*O);
- }
- void print(std::ostream &O);
- void dump();
-#endif
-};
-
-//===----------------------------------------------------------------------===//
-/// DIE - A structured debug information entry. Has an abbreviation which
-/// describes it's organization.
-class CompileUnit;
-class DIE : public FoldingSetNode {
-protected:
- /// Abbrev - Buffer for constructing abbreviation.
- ///
- DIEAbbrev Abbrev;
-
- /// Offset - Offset in debug info section.
- ///
- unsigned Offset;
-
- /// Size - Size of instance + children.
- ///
- unsigned Size;
-
- /// Children DIEs.
- ///
- std::vector<DIE *> Children;
-
- /// Attributes values.
- ///
- SmallVector<DIEValue*, 32> Values;
-
- /// Abstract compile unit.
- CompileUnit *AbstractCU;
-public:
- explicit DIE(unsigned Tag)
- : Abbrev(Tag, DW_CHILDREN_no), Offset(0), Size(0) {}
- virtual ~DIE();
-
- // Accessors.
- DIEAbbrev &getAbbrev() { return Abbrev; }
- unsigned getAbbrevNumber() const {
- return Abbrev.getNumber();
- }
- unsigned getTag() const { return Abbrev.getTag(); }
- unsigned getOffset() const { return Offset; }
- unsigned getSize() const { return Size; }
- const std::vector<DIE *> &getChildren() const { return Children; }
- SmallVector<DIEValue*, 32> &getValues() { return Values; }
- CompileUnit *getAbstractCompileUnit() const { return AbstractCU; }
-
- void setTag(unsigned Tag) { Abbrev.setTag(Tag); }
- void setOffset(unsigned O) { Offset = O; }
- void setSize(unsigned S) { Size = S; }
- void setAbstractCompileUnit(CompileUnit *CU) { AbstractCU = CU; }
-
- /// AddValue - Add a value and attributes to a DIE.
- ///
- void AddValue(unsigned Attribute, unsigned Form, DIEValue *Value) {
- Abbrev.AddAttribute(Attribute, Form);
- Values.push_back(Value);
- }
-
- /// SiblingOffset - Return the offset of the debug information entry's
- /// sibling.
- unsigned SiblingOffset() const { return Offset + Size; }
-
- /// AddSiblingOffset - Add a sibling offset field to the front of the DIE.
- ///
- void AddSiblingOffset();
-
- /// AddChild - Add a child to the DIE.
- ///
- void AddChild(DIE *Child) {
- Abbrev.setChildrenFlag(DW_CHILDREN_yes);
- Children.push_back(Child);
- }
-
- /// Detach - Detaches objects connected to it after copying.
- ///
- void Detach() {
- Children.clear();
- }
-
- /// Profile - Used to gather unique data for the value folding set.
- ///
- void Profile(FoldingSetNodeID &ID) ;
-
-#ifndef NDEBUG
- void print(std::ostream *O, unsigned IncIndent = 0) {
- if (O) print(*O, IncIndent);
- }
- void print(std::ostream &O, unsigned IncIndent = 0);
- void dump();
-#endif
-};
-
-//===----------------------------------------------------------------------===//
-/// DIEValue - A debug information entry value.
-///
-class DIEValue : public FoldingSetNode {
-public:
- enum {
- isInteger,
- isString,
- isLabel,
- isAsIsLabel,
- isSectionOffset,
- isDelta,
- isEntry,
- isBlock
- };
-
- /// Type - Type of data stored in the value.
- ///
- unsigned Type;
-
- explicit DIEValue(unsigned T) : Type(T) {}
- virtual ~DIEValue() {}
-
- // Accessors
- unsigned getType() const { return Type; }
-
- // Implement isa/cast/dyncast.
- static bool classof(const DIEValue *) { return true; }
-
- /// EmitValue - Emit value via the Dwarf writer.
- ///
- virtual void EmitValue(DwarfDebug &DD, unsigned Form) = 0;
-
- /// SizeOf - Return the size of a value in bytes.
- ///
- virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const = 0;
-
- /// Profile - Used to gather unique data for the value folding set.
- ///
- virtual void Profile(FoldingSetNodeID &ID) = 0;
-
-#ifndef NDEBUG
- void print(std::ostream *O) {
- if (O) print(*O);
- }
- virtual void print(std::ostream &O) = 0;
- void dump();
-#endif
-};
-
-//===----------------------------------------------------------------------===//
-/// DWInteger - An integer value DIE.
-///
-class DIEInteger : public DIEValue {
-private:
- uint64_t Integer;
-
-public:
- explicit DIEInteger(uint64_t I) : DIEValue(isInteger), Integer(I) {}
-
- // Implement isa/cast/dyncast.
- static bool classof(const DIEInteger *) { return true; }
- static bool classof(const DIEValue *I) { return I->Type == isInteger; }
-
- /// BestForm - Choose the best form for integer.
- ///
- static unsigned BestForm(bool IsSigned, uint64_t Integer) {
- if (IsSigned) {
- if ((char)Integer == (signed)Integer) return DW_FORM_data1;
- if ((short)Integer == (signed)Integer) return DW_FORM_data2;
- if ((int)Integer == (signed)Integer) return DW_FORM_data4;
- } else {
- if ((unsigned char)Integer == Integer) return DW_FORM_data1;
- if ((unsigned short)Integer == Integer) return DW_FORM_data2;
- if ((unsigned int)Integer == Integer) return DW_FORM_data4;
- }
- return DW_FORM_data8;
- }
-
- /// EmitValue - Emit integer of appropriate size.
- ///
- virtual void EmitValue(DwarfDebug &DD, unsigned Form);
-
- /// SizeOf - Determine size of integer value in bytes.
- ///
- virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const;
-
- /// Profile - Used to gather unique data for the value folding set.
- ///
- static void Profile(FoldingSetNodeID &ID, unsigned Integer) {
- ID.AddInteger(isInteger);
- ID.AddInteger(Integer);
- }
- virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, Integer); }
-
-#ifndef NDEBUG
- virtual void print(std::ostream &O) {
- O << "Int: " << (int64_t)Integer
- << " 0x" << std::hex << Integer << std::dec;
- }
-#endif
-};
-
-//===----------------------------------------------------------------------===//
-/// DIEString - A string value DIE.
-///
-class DIEString : public DIEValue {
- const std::string Str;
-public:
- explicit DIEString(const std::string &S) : DIEValue(isString), Str(S) {}
-
- // Implement isa/cast/dyncast.
- static bool classof(const DIEString *) { return true; }
- static bool classof(const DIEValue *S) { return S->Type == isString; }
-
- /// EmitValue - Emit string value.
- ///
- virtual void EmitValue(DwarfDebug &DD, unsigned Form);
-
- /// SizeOf - Determine size of string value in bytes.
- ///
- virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const {
- return Str.size() + sizeof(char); // sizeof('\0');
- }
-
- /// Profile - Used to gather unique data for the value folding set.
- ///
- static void Profile(FoldingSetNodeID &ID, const std::string &Str) {
- ID.AddInteger(isString);
- ID.AddString(Str);
- }
- virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, Str); }
-
-#ifndef NDEBUG
- virtual void print(std::ostream &O) {
- O << "Str: \"" << Str << "\"";
- }
-#endif
-};
-
-//===----------------------------------------------------------------------===//
-/// DIEDwarfLabel - A Dwarf internal label expression DIE.
-//
-class DIEDwarfLabel : public DIEValue {
- const DWLabel Label;
-public:
- explicit DIEDwarfLabel(const DWLabel &L) : DIEValue(isLabel), Label(L) {}
-
- // Implement isa/cast/dyncast.
- static bool classof(const DIEDwarfLabel *) { return true; }
- static bool classof(const DIEValue *L) { return L->Type == isLabel; }
-
- /// EmitValue - Emit label value.
- ///
- virtual void EmitValue(DwarfDebug &DD, unsigned Form);
-
- /// SizeOf - Determine size of label value in bytes.
- ///
- virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const;
-
- /// Profile - Used to gather unique data for the value folding set.
- ///
- static void Profile(FoldingSetNodeID &ID, const DWLabel &Label) {
- ID.AddInteger(isLabel);
- Label.Profile(ID);
- }
- virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, Label); }
-
-#ifndef NDEBUG
- virtual void print(std::ostream &O) {
- O << "Lbl: ";
- Label.print(O);
- }
-#endif
-};
-
-//===----------------------------------------------------------------------===//
-/// DIEObjectLabel - A label to an object in code or data.
-//
-class DIEObjectLabel : public DIEValue {
- const std::string Label;
-public:
- explicit DIEObjectLabel(const std::string &L)
- : DIEValue(isAsIsLabel), Label(L) {}
-
- // Implement isa/cast/dyncast.
- static bool classof(const DIEObjectLabel *) { return true; }
- static bool classof(const DIEValue *L) { return L->Type == isAsIsLabel; }
-
- /// EmitValue - Emit label value.
- ///
- virtual void EmitValue(DwarfDebug &DD, unsigned Form);
-
- /// SizeOf - Determine size of label value in bytes.
- ///
- virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const;
-
- /// Profile - Used to gather unique data for the value folding set.
- ///
- static void Profile(FoldingSetNodeID &ID, const std::string &Label) {
- ID.AddInteger(isAsIsLabel);
- ID.AddString(Label);
- }
- virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, Label.c_str()); }
-
-#ifndef NDEBUG
- virtual void print(std::ostream &O) {
- O << "Obj: " << Label;
- }
-#endif
-};
-
-//===----------------------------------------------------------------------===//
-/// DIESectionOffset - A section offset DIE.
-//
-class DIESectionOffset : public DIEValue {
- const DWLabel Label;
- const DWLabel Section;
- bool IsEH : 1;
- bool UseSet : 1;
-public:
- DIESectionOffset(const DWLabel &Lab, const DWLabel &Sec,
- bool isEH = false, bool useSet = true)
- : DIEValue(isSectionOffset), Label(Lab), Section(Sec),
- IsEH(isEH), UseSet(useSet) {}
-
- // Implement isa/cast/dyncast.
- static bool classof(const DIESectionOffset *) { return true; }
- static bool classof(const DIEValue *D) { return D->Type == isSectionOffset; }
-
- /// EmitValue - Emit section offset.
- ///
- virtual void EmitValue(DwarfDebug &DD, unsigned Form);
-
- /// SizeOf - Determine size of section offset value in bytes.
- ///
- virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const;
-
- /// Profile - Used to gather unique data for the value folding set.
- ///
- static void Profile(FoldingSetNodeID &ID, const DWLabel &Label,
- const DWLabel &Section) {
- ID.AddInteger(isSectionOffset);
- Label.Profile(ID);
- Section.Profile(ID);
- // IsEH and UseSet are specific to the Label/Section that we will emit
- // the offset for; so Label/Section are enough for uniqueness.
- }
- virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, Label, Section); }
-
-#ifndef NDEBUG
- virtual void print(std::ostream &O) {
- O << "Off: ";
- Label.print(O);
- O << "-";
- Section.print(O);
- O << "-" << IsEH << "-" << UseSet;
- }
-#endif
-};
-
-//===----------------------------------------------------------------------===//
-/// DIEDelta - A simple label difference DIE.
-///
-class DIEDelta : public DIEValue {
- const DWLabel LabelHi;
- const DWLabel LabelLo;
-public:
- DIEDelta(const DWLabel &Hi, const DWLabel &Lo)
- : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {}
-
- // Implement isa/cast/dyncast.
- static bool classof(const DIEDelta *) { return true; }
- static bool classof(const DIEValue *D) { return D->Type == isDelta; }
-
- /// EmitValue - Emit delta value.
- ///
- virtual void EmitValue(DwarfDebug &DD, unsigned Form);
-
- /// SizeOf - Determine size of delta value in bytes.
- ///
- virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const;
-
- /// Profile - Used to gather unique data for the value folding set.
- ///
- static void Profile(FoldingSetNodeID &ID, const DWLabel &LabelHi,
- const DWLabel &LabelLo) {
- ID.AddInteger(isDelta);
- LabelHi.Profile(ID);
- LabelLo.Profile(ID);
- }
- virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, LabelHi, LabelLo); }
-
-#ifndef NDEBUG
- virtual void print(std::ostream &O) {
- O << "Del: ";
- LabelHi.print(O);
- O << "-";
- LabelLo.print(O);
- }
-#endif
-};
-
-//===----------------------------------------------------------------------===//
-/// DIEntry - A pointer to another debug information entry. An instance of this
-/// class can also be used as a proxy for a debug information entry not yet
-/// defined (ie. types.)
-class DIEntry : public DIEValue {
- DIE *Entry;
-public:
- explicit DIEntry(DIE *E) : DIEValue(isEntry), Entry(E) {}
-
- DIE *getEntry() const { return Entry; }
- void setEntry(DIE *E) { Entry = E; }
-
- // Implement isa/cast/dyncast.
- static bool classof(const DIEntry *) { return true; }
- static bool classof(const DIEValue *E) { return E->Type == isEntry; }
-
- /// EmitValue - Emit debug information entry offset.
- ///
- virtual void EmitValue(DwarfDebug &DD, unsigned Form);
-
- /// SizeOf - Determine size of debug information entry in bytes.
- ///
- virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const {
- return sizeof(int32_t);
- }
-
- /// Profile - Used to gather unique data for the value folding set.
- ///
- static void Profile(FoldingSetNodeID &ID, DIE *Entry) {
- ID.AddInteger(isEntry);
- ID.AddPointer(Entry);
- }
- virtual void Profile(FoldingSetNodeID &ID) {
- ID.AddInteger(isEntry);
-
- if (Entry) {
- ID.AddPointer(Entry);
- } else {
- ID.AddPointer(this);
- }
- }
-
-#ifndef NDEBUG
- virtual void print(std::ostream &O) {
- O << "Die: 0x" << std::hex << (intptr_t)Entry << std::dec;
- }
-#endif
-};
-
-//===----------------------------------------------------------------------===//
-/// DIEBlock - A block of values. Primarily used for location expressions.
-//
-class DIEBlock : public DIEValue, public DIE {
- unsigned Size; // Size in bytes excluding size header.
-public:
- DIEBlock()
- : DIEValue(isBlock), DIE(0), Size(0) {}
- virtual ~DIEBlock() {}
-
- // Implement isa/cast/dyncast.
- static bool classof(const DIEBlock *) { return true; }
- static bool classof(const DIEValue *E) { return E->Type == isBlock; }
-
- /// ComputeSize - calculate the size of the block.
- ///
- unsigned ComputeSize(DwarfDebug &DD);
-
- /// BestForm - Choose the best form for data.
- ///
- unsigned BestForm() const {
- if ((unsigned char)Size == Size) return DW_FORM_block1;
- if ((unsigned short)Size == Size) return DW_FORM_block2;
- if ((unsigned int)Size == Size) return DW_FORM_block4;
- return DW_FORM_block;
- }
-
- /// EmitValue - Emit block data.
- ///
- virtual void EmitValue(DwarfDebug &DD, unsigned Form);
-
- /// SizeOf - Determine size of block data in bytes.
- ///
- virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const;
-
- /// Profile - Used to gather unique data for the value folding set.
- ///
- virtual void Profile(FoldingSetNodeID &ID) {
- ID.AddInteger(isBlock);
- DIE::Profile(ID);
- }
-
-#ifndef NDEBUG
- virtual void print(std::ostream &O) {
- O << "Blk: ";
- DIE::print(O, 5);
- }
-#endif
-};
-
-//===----------------------------------------------------------------------===//
/// CompileUnit - This dwarf writer support class manages information associate
/// with a source file.
class CompileUnit {
@@ -706,9 +81,9 @@ class CompileUnit {
/// variables to debug information entries.
std::map<GlobalVariable *, DIE *> GVToDieMap;
- /// GVToDIEntryMap - Tracks the mapping of unit level debug informaton
- /// descriptors to debug information entries using a DIEntry proxy.
- std::map<GlobalVariable *, DIEntry *> GVToDIEntryMap;
+ /// GVToDIEEntryMap - Tracks the mapping of unit level debug informaton
+ /// descriptors to debug information entries using a DIEEntry proxy.
+ std::map<GlobalVariable *, DIEEntry *> GVToDIEEntryMap;
/// Globals - A map of globally visible named entities for this unit.
///
@@ -720,7 +95,7 @@ class CompileUnit {
public:
CompileUnit(unsigned I, DIE *D)
: ID(I), Die(D), GVToDieMap(),
- GVToDIEntryMap(), Globals(), DiesSet(InitDiesSetSize)
+ GVToDIEEntryMap(), Globals(), DiesSet(InitDiesSetSize)
{}
~CompileUnit() {
@@ -750,10 +125,10 @@ public:
return GVToDieMap[GV];
}
- /// getDIEntrySlotFor - Returns the debug information entry proxy slot for the
+ /// getDIEEntrySlotFor - Returns the debug information entry proxy slot for the
/// specified debug variable.
- DIEntry *&getDIEntrySlotFor(GlobalVariable *GV) {
- return GVToDIEntryMap[GV];
+ DIEEntry *&getDIEEntrySlotFor(GlobalVariable *GV) {
+ return GVToDIEEntryMap[GV];
}
/// AddDie - Adds or interns the DIE to the compile unit.
@@ -776,315 +151,13 @@ public:
};
//===----------------------------------------------------------------------===//
-/// Dwarf - Emits general Dwarf directives.
-///
-class Dwarf {
-protected:
- //===--------------------------------------------------------------------===//
- // Core attributes used by the Dwarf writer.
- //
-
- //
- /// O - Stream to .s file.
- ///
- raw_ostream &O;
-
- /// Asm - Target of Dwarf emission.
- ///
- AsmPrinter *Asm;
-
- /// TAI - Target asm information.
- const TargetAsmInfo *TAI;
-
- /// TD - Target data.
- const TargetData *TD;
-
- /// RI - Register Information.
- const TargetRegisterInfo *RI;
-
- /// M - Current module.
- ///
- Module *M;
-
- /// MF - Current machine function.
- ///
- MachineFunction *MF;
-
- /// MMI - Collected machine module information.
- ///
- MachineModuleInfo *MMI;
-
- /// SubprogramCount - The running count of functions being compiled.
- ///
- unsigned SubprogramCount;
-
- /// Flavor - A unique string indicating what dwarf producer this is, used to
- /// unique labels.
- const char * const Flavor;
-
- unsigned SetCounter;
- Dwarf(raw_ostream &OS, AsmPrinter *A, const TargetAsmInfo *T,
- const char *flavor)
- : O(OS)
- , Asm(A)
- , TAI(T)
- , TD(Asm->TM.getTargetData())
- , RI(Asm->TM.getRegisterInfo())
- , M(NULL)
- , MF(NULL)
- , MMI(NULL)
- , SubprogramCount(0)
- , Flavor(flavor)
- , SetCounter(1)
- {
- }
-
-public:
- //===--------------------------------------------------------------------===//
- // Accessors.
- //
- const AsmPrinter *getAsm() const { return Asm; }
- MachineModuleInfo *getMMI() const { return MMI; }
- const TargetAsmInfo *getTargetAsmInfo() const { return TAI; }
- const TargetData *getTargetData() const { return TD; }
-
- void PrintRelDirective(bool Force32Bit = false, bool isInSection = false)
- const {
- if (isInSection && TAI->getDwarfSectionOffsetDirective())
- O << TAI->getDwarfSectionOffsetDirective();
- else if (Force32Bit || TD->getPointerSize() == sizeof(int32_t))
- O << TAI->getData32bitsDirective();
- else
- O << TAI->getData64bitsDirective();
- }
-
- /// PrintLabelName - Print label name in form used by Dwarf writer.
- ///
- void PrintLabelName(DWLabel Label) const {
- PrintLabelName(Label.Tag, Label.Number);
- }
- void PrintLabelName(const char *Tag, unsigned Number) const {
- O << TAI->getPrivateGlobalPrefix() << Tag;
- if (Number) O << Number;
- }
-
- void PrintLabelName(const char *Tag, unsigned Number,
- const char *Suffix) const {
- O << TAI->getPrivateGlobalPrefix() << Tag;
- if (Number) O << Number;
- O << Suffix;
- }
-
- /// EmitLabel - Emit location label for internal use by Dwarf.
- ///
- void EmitLabel(DWLabel Label) const {
- EmitLabel(Label.Tag, Label.Number);
- }
- void EmitLabel(const char *Tag, unsigned Number) const {
- PrintLabelName(Tag, Number);
- O << ":\n";
- }
-
- /// EmitReference - Emit a reference to a label.
- ///
- void EmitReference(DWLabel Label, bool IsPCRelative = false,
- bool Force32Bit = false) const {
- EmitReference(Label.Tag, Label.Number, IsPCRelative, Force32Bit);
- }
- void EmitReference(const char *Tag, unsigned Number,
- bool IsPCRelative = false, bool Force32Bit = false) const {
- PrintRelDirective(Force32Bit);
- PrintLabelName(Tag, Number);
-
- if (IsPCRelative) O << "-" << TAI->getPCSymbol();
- }
- void EmitReference(const std::string &Name, bool IsPCRelative = false,
- bool Force32Bit = false) const {
- PrintRelDirective(Force32Bit);
-
- O << Name;
-
- if (IsPCRelative) O << "-" << TAI->getPCSymbol();
- }
-
- /// EmitDifference - Emit the difference between two labels. Some
- /// assemblers do not behave with absolute expressions with data directives,
- /// so there is an option (needsSet) to use an intermediary set expression.
- void EmitDifference(DWLabel LabelHi, DWLabel LabelLo,
- bool IsSmall = false) {
- EmitDifference(LabelHi.Tag, LabelHi.Number,
- LabelLo.Tag, LabelLo.Number,
- IsSmall);
- }
- void EmitDifference(const char *TagHi, unsigned NumberHi,
- const char *TagLo, unsigned NumberLo,
- bool IsSmall = false) {
- if (TAI->needsSet()) {
- O << "\t.set\t";
- PrintLabelName("set", SetCounter, Flavor);
- O << ",";
- PrintLabelName(TagHi, NumberHi);
- O << "-";
- PrintLabelName(TagLo, NumberLo);
- O << "\n";
-
- PrintRelDirective(IsSmall);
- PrintLabelName("set", SetCounter, Flavor);
- ++SetCounter;
- } else {
- PrintRelDirective(IsSmall);
-
- PrintLabelName(TagHi, NumberHi);
- O << "-";
- PrintLabelName(TagLo, NumberLo);
- }
- }
-
- void EmitSectionOffset(const char* Label, const char* Section,
- unsigned LabelNumber, unsigned SectionNumber,
- bool IsSmall = false, bool isEH = false,
- bool useSet = true) {
- bool printAbsolute = false;
- if (isEH)
- printAbsolute = TAI->isAbsoluteEHSectionOffsets();
- else
- printAbsolute = TAI->isAbsoluteDebugSectionOffsets();
-
- if (TAI->needsSet() && useSet) {
- O << "\t.set\t";
- PrintLabelName("set", SetCounter, Flavor);
- O << ",";
- PrintLabelName(Label, LabelNumber);
-
- if (!printAbsolute) {
- O << "-";
- PrintLabelName(Section, SectionNumber);
- }
- O << "\n";
-
- PrintRelDirective(IsSmall);
-
- PrintLabelName("set", SetCounter, Flavor);
- ++SetCounter;
- } else {
- PrintRelDirective(IsSmall, true);
-
- PrintLabelName(Label, LabelNumber);
-
- if (!printAbsolute) {
- O << "-";
- PrintLabelName(Section, SectionNumber);
- }
- }
- }
-
- /// EmitFrameMoves - Emit frame instructions to describe the layout of the
- /// frame.
- void EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,
- const std::vector<MachineMove> &Moves, bool isEH) {
- int stackGrowth =
- Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
- TargetFrameInfo::StackGrowsUp ?
- TD->getPointerSize() : -TD->getPointerSize();
- bool IsLocal = BaseLabel && strcmp(BaseLabel, "label") == 0;
-
- for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
- const MachineMove &Move = Moves[i];
- unsigned LabelID = Move.getLabelID();
-
- if (LabelID) {
- LabelID = MMI->MappedLabel(LabelID);
-
- // Throw out move if the label is invalid.
- if (!LabelID) continue;
- }
-
- const MachineLocation &Dst = Move.getDestination();
- const MachineLocation &Src = Move.getSource();
-
- // Advance row if new location.
- if (BaseLabel && LabelID && (BaseLabelID != LabelID || !IsLocal)) {
- Asm->EmitInt8(DW_CFA_advance_loc4);
- Asm->EOL("DW_CFA_advance_loc4");
- EmitDifference("label", LabelID, BaseLabel, BaseLabelID, true);
- Asm->EOL();
-
- BaseLabelID = LabelID;
- BaseLabel = "label";
- IsLocal = true;
- }
-
- // If advancing cfa.
- if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
- if (!Src.isReg()) {
- if (Src.getReg() == MachineLocation::VirtualFP) {
- Asm->EmitInt8(DW_CFA_def_cfa_offset);
- Asm->EOL("DW_CFA_def_cfa_offset");
- } else {
- Asm->EmitInt8(DW_CFA_def_cfa);
- Asm->EOL("DW_CFA_def_cfa");
- Asm->EmitULEB128Bytes(RI->getDwarfRegNum(Src.getReg(), isEH));
- Asm->EOL("Register");
- }
-
- int Offset = -Src.getOffset();
-
- Asm->EmitULEB128Bytes(Offset);
- Asm->EOL("Offset");
- } else {
- assert(0 && "Machine move no supported yet.");
- }
- } else if (Src.isReg() &&
- Src.getReg() == MachineLocation::VirtualFP) {
- if (Dst.isReg()) {
- Asm->EmitInt8(DW_CFA_def_cfa_register);
- Asm->EOL("DW_CFA_def_cfa_register");
- Asm->EmitULEB128Bytes(RI->getDwarfRegNum(Dst.getReg(), isEH));
- Asm->EOL("Register");
- } else {
- assert(0 && "Machine move no supported yet.");
- }
- } else {
- unsigned Reg = RI->getDwarfRegNum(Src.getReg(), isEH);
- int Offset = Dst.getOffset() / stackGrowth;
-
- if (Offset < 0) {
- Asm->EmitInt8(DW_CFA_offset_extended_sf);
- Asm->EOL("DW_CFA_offset_extended_sf");
- Asm->EmitULEB128Bytes(Reg);
- Asm->EOL("Reg");
- Asm->EmitSLEB128Bytes(Offset);
- Asm->EOL("Offset");
- } else if (Reg < 64) {
- Asm->EmitInt8(DW_CFA_offset + Reg);
- if (Asm->isVerbose())
- Asm->EOL("DW_CFA_offset + Reg (" + utostr(Reg) + ")");
- else
- Asm->EOL();
- Asm->EmitULEB128Bytes(Offset);
- Asm->EOL("Offset");
- } else {
- Asm->EmitInt8(DW_CFA_offset_extended);
- Asm->EOL("DW_CFA_offset_extended");
- Asm->EmitULEB128Bytes(Reg);
- Asm->EOL("Reg");
- Asm->EmitULEB128Bytes(Offset);
- Asm->EOL("Offset");
- }
- }
- }
- }
-
-};
-
-//===----------------------------------------------------------------------===//
/// SrcLineInfo - This class is used to record source line correspondence.
///
class SrcLineInfo {
- unsigned Line; // Source line number.
- unsigned Column; // Source column.
- unsigned SourceID; // Source ID number.
- unsigned LabelID; // Label in code ID number.
+ unsigned Line; // Source line number.
+ unsigned Column; // Source column.
+ unsigned SourceID; // Source ID number.
+ unsigned LabelID; // Label in code ID number.
public:
SrcLineInfo(unsigned L, unsigned C, unsigned S, unsigned I)
: Line(L), Column(C), SourceID(S), LabelID(I) {}
@@ -1100,7 +173,7 @@ public:
/// DbgVariable - This class is used to track local variable information.
///
class DbgVariable {
- DIVariable Var; // Variable Descriptor.
+ DIVariable Var; // Variable Descriptor.
unsigned FrameIndex; // Variable frame index.
public:
DbgVariable(DIVariable V, unsigned I) : Var(V), FrameIndex(I) {}
@@ -1395,32 +468,32 @@ private:
return DWLabel("string", StringID);
}
- /// NewDIEntry - Creates a new DIEntry to be a proxy for a debug information
+ /// NewDIEEntry - Creates a new DIEEntry to be a proxy for a debug information
/// entry.
- DIEntry *NewDIEntry(DIE *Entry = NULL) {
- DIEntry *Value;
+ DIEEntry *NewDIEEntry(DIE *Entry = NULL) {
+ DIEEntry *Value;
if (Entry) {
FoldingSetNodeID ID;
- DIEntry::Profile(ID, Entry);
+ DIEEntry::Profile(ID, Entry);
void *Where;
- Value = static_cast<DIEntry *>(ValuesSet.FindNodeOrInsertPos(ID, Where));
+ Value = static_cast<DIEEntry *>(ValuesSet.FindNodeOrInsertPos(ID, Where));
if (Value) return Value;
- Value = new DIEntry(Entry);
+ Value = new DIEEntry(Entry);
ValuesSet.InsertNode(Value, Where);
} else {
- Value = new DIEntry(Entry);
+ Value = new DIEEntry(Entry);
}
Values.push_back(Value);
return Value;
}
- /// SetDIEntry - Set a DIEntry once the debug information entry is defined.
+ /// SetDIEEntry - Set a DIEEntry once the debug information entry is defined.
///
- void SetDIEntry(DIEntry *Value, DIE *Entry) {
+ void SetDIEEntry(DIEEntry *Value, DIE *Entry) {
Value->setEntry(Entry);
// Add to values set if not already there. If it is, we merely have a
// duplicate in the values list (no harm.)
@@ -1483,7 +556,7 @@ private:
/// AddLabel - Add a Dwarf label attribute data and value.
///
void AddLabel(DIE *Die, unsigned Attribute, unsigned Form,
- const DWLabel &Label) {
+ const DWLabel &Label) {
FoldingSetNodeID ID;
DIEDwarfLabel::Profile(ID, Label);
void *Where;
@@ -1549,16 +622,16 @@ private:
Die->AddValue(Attribute, Form, Value);
}
- /// AddDIEntry - Add a DIE attribute data and value.
+ /// AddDIEEntry - Add a DIE attribute data and value.
///
- void AddDIEntry(DIE *Die, unsigned Attribute, unsigned Form, DIE *Entry) {
- Die->AddValue(Attribute, Form, NewDIEntry(Entry));
+ void AddDIEEntry(DIE *Die, unsigned Attribute, unsigned Form, DIE *Entry) {
+ Die->AddValue(Attribute, Form, NewDIEEntry(Entry));
}
/// AddBlock - Add block data.
///
void AddBlock(DIE *Die, unsigned Attribute, unsigned Form, DIEBlock *Block) {
- Block->ComputeSize(*this);
+ Block->ComputeSize(TD);
FoldingSetNodeID ID;
Block->Profile(ID);
void *Where;
@@ -1649,7 +722,7 @@ private:
return;
// Check for pre-existence.
- DIEntry *&Slot = DW_Unit->getDIEntrySlotFor(Ty.getGV());
+ DIEEntry *&Slot = DW_Unit->getDIEEntrySlotFor(Ty.getGV());
// If it exists then use the existing value.
if (Slot) {
Entity->AddValue(DW_AT_type, DW_FORM_ref4, Slot);
@@ -1657,7 +730,7 @@ private:
}
// Set up proxy.
- Slot = NewDIEntry();
+ Slot = NewDIEEntry();
// Construct type.
DIE Buffer(DW_TAG_base_type);
@@ -1680,10 +753,10 @@ private:
DIE *Child = new DIE(Buffer);
Die->AddChild(Child);
Buffer.Detach();
- SetDIEntry(Slot, Child);
+ SetDIEEntry(Slot, Child);
} else {
Die = DW_Unit->AddDie(Buffer);
- SetDIEntry(Slot, Die);
+ SetDIEEntry(Slot, Die);
}
Entity->AddValue(DW_AT_type, DW_FORM_ref4, Slot);
@@ -1856,7 +929,7 @@ private:
int64_t H = SR.getHi();
DIE *DW_Subrange = new DIE(DW_TAG_subrange_type);
if (L != H) {
- AddDIEntry(DW_Subrange, DW_AT_type, DW_FORM_ref4, IndexTy);
+ AddDIEEntry(DW_Subrange, DW_AT_type, DW_FORM_ref4, IndexTy);
if (L)
AddSInt(DW_Subrange, DW_AT_lower_bound, 0, L);
AddSInt(DW_Subrange, DW_AT_upper_bound, 0, H);
@@ -2363,7 +1436,7 @@ private:
Asm->EmitInt32(Die->SiblingOffset());
break;
case DW_AT_abstract_origin: {
- DIEntry *E = cast<DIEntry>(Values[i]);
+ DIEEntry *E = cast<DIEEntry>(Values[i]);
DIE *Origin = E->getEntry();
unsigned Addr =
CompileUnitOffsets[Die->getAbstractCompileUnit()] +
@@ -2374,7 +1447,7 @@ private:
}
default:
// Emit an attribute using the defined form.
- Values[i]->EmitValue(*this, Form);
+ Values[i]->EmitValue(this, Form);
break;
}
@@ -2420,7 +1493,7 @@ private:
// Size the DIE attribute values.
for (unsigned i = 0, N = Values.size(); i < N; ++i) {
// Size attribute value.
- Offset += Values[i]->SizeOf(*this, AbbrevData[i].getForm());
+ Offset += Values[i]->SizeOf(TD, AbbrevData[i].getForm());
}
// Size the DIE children if any.
@@ -2531,7 +1604,7 @@ private:
Asm->EOL("Abbreviation Code");
// Emit the abbreviations data.
- Abbrev->Emit(*this);
+ Abbrev->Emit(Asm);
Asm->EOL();
}
@@ -3646,7 +2719,7 @@ public:
ScopeDie->setAbstractCompileUnit(Unit);
DIE *Origin = Unit->getDieMapSlotFor(GV);
- AddDIEntry(ScopeDie, DW_AT_abstract_origin, DW_FORM_ref4, Origin);
+ AddDIEEntry(ScopeDie, DW_AT_abstract_origin, DW_FORM_ref4, Origin);
AddUInt(ScopeDie, DW_AT_call_file, 0, Unit->getID());
AddUInt(ScopeDie, DW_AT_call_line, 0, Line);
AddUInt(ScopeDie, DW_AT_call_column, 0, Col);
@@ -4506,319 +3579,6 @@ public:
} // End of namespace llvm
//===----------------------------------------------------------------------===//
-
-/// Emit - Print the abbreviation using the specified Dwarf writer.
-///
-void DIEAbbrev::Emit(const DwarfDebug &DD) const {
- // Emit its Dwarf tag type.
- DD.getAsm()->EmitULEB128Bytes(Tag);
- DD.getAsm()->EOL(TagString(Tag));
-
- // Emit whether it has children DIEs.
- DD.getAsm()->EmitULEB128Bytes(ChildrenFlag);
- DD.getAsm()->EOL(ChildrenString(ChildrenFlag));
-
- // For each attribute description.
- for (unsigned i = 0, N = Data.size(); i < N; ++i) {
- const DIEAbbrevData &AttrData = Data[i];
-
- // Emit attribute type.
- DD.getAsm()->EmitULEB128Bytes(AttrData.getAttribute());
- DD.getAsm()->EOL(AttributeString(AttrData.getAttribute()));
-
- // Emit form type.
- DD.getAsm()->EmitULEB128Bytes(AttrData.getForm());
- DD.getAsm()->EOL(FormEncodingString(AttrData.getForm()));
- }
-
- // Mark end of abbreviation.
- DD.getAsm()->EmitULEB128Bytes(0); DD.getAsm()->EOL("EOM(1)");
- DD.getAsm()->EmitULEB128Bytes(0); DD.getAsm()->EOL("EOM(2)");
-}
-
-#ifndef NDEBUG
-void DIEAbbrev::print(std::ostream &O) {
- O << "Abbreviation @"
- << std::hex << (intptr_t)this << std::dec
- << " "
- << TagString(Tag)
- << " "
- << ChildrenString(ChildrenFlag)
- << "\n";
-
- for (unsigned i = 0, N = Data.size(); i < N; ++i) {
- O << " "
- << AttributeString(Data[i].getAttribute())
- << " "
- << FormEncodingString(Data[i].getForm())
- << "\n";
- }
-}
-void DIEAbbrev::dump() { print(cerr); }
-#endif
-
-//===----------------------------------------------------------------------===//
-
-#ifndef NDEBUG
-void DIEValue::dump() {
- print(cerr);
-}
-#endif
-
-//===----------------------------------------------------------------------===//
-
-/// EmitValue - Emit integer of appropriate size.
-///
-void DIEInteger::EmitValue(DwarfDebug &DD, unsigned Form) {
- switch (Form) {
- case DW_FORM_flag: // Fall thru
- case DW_FORM_ref1: // Fall thru
- case DW_FORM_data1: DD.getAsm()->EmitInt8(Integer); break;
- case DW_FORM_ref2: // Fall thru
- case DW_FORM_data2: DD.getAsm()->EmitInt16(Integer); break;
- case DW_FORM_ref4: // Fall thru
- case DW_FORM_data4: DD.getAsm()->EmitInt32(Integer); break;
- case DW_FORM_ref8: // Fall thru
- case DW_FORM_data8: DD.getAsm()->EmitInt64(Integer); break;
- case DW_FORM_udata: DD.getAsm()->EmitULEB128Bytes(Integer); break;
- case DW_FORM_sdata: DD.getAsm()->EmitSLEB128Bytes(Integer); break;
- default: assert(0 && "DIE Value form not supported yet"); break;
- }
-}
-
-/// SizeOf - Determine size of integer value in bytes.
-///
-unsigned DIEInteger::SizeOf(const DwarfDebug &DD, unsigned Form) const {
- switch (Form) {
- case DW_FORM_flag: // Fall thru
- case DW_FORM_ref1: // Fall thru
- case DW_FORM_data1: return sizeof(int8_t);
- case DW_FORM_ref2: // Fall thru
- case DW_FORM_data2: return sizeof(int16_t);
- case DW_FORM_ref4: // Fall thru
- case DW_FORM_data4: return sizeof(int32_t);
- case DW_FORM_ref8: // Fall thru
- case DW_FORM_data8: return sizeof(int64_t);
- case DW_FORM_udata: return TargetAsmInfo::getULEB128Size(Integer);
- case DW_FORM_sdata: return TargetAsmInfo::getSLEB128Size(Integer);
- default: assert(0 && "DIE Value form not supported yet"); break;
- }
- return 0;
-}
-
-//===----------------------------------------------------------------------===//
-
-/// EmitValue - Emit string value.
-///
-void DIEString::EmitValue(DwarfDebug &DD, unsigned Form) {
- DD.getAsm()->EmitString(Str);
-}
-
-//===----------------------------------------------------------------------===//
-
-/// EmitValue - Emit label value.
-///
-void DIEDwarfLabel::EmitValue(DwarfDebug &DD, unsigned Form) {
- bool IsSmall = Form == DW_FORM_data4;
- DD.EmitReference(Label, false, IsSmall);
-}
-
-/// SizeOf - Determine size of label value in bytes.
-///
-unsigned DIEDwarfLabel::SizeOf(const DwarfDebug &DD, unsigned Form) const {
- if (Form == DW_FORM_data4) return 4;
- return DD.getTargetData()->getPointerSize();
-}
-
-//===----------------------------------------------------------------------===//
-
-/// EmitValue - Emit label value.
-///
-void DIEObjectLabel::EmitValue(DwarfDebug &DD, unsigned Form) {
- bool IsSmall = Form == DW_FORM_data4;
- DD.EmitReference(Label, false, IsSmall);
-}
-
-/// SizeOf - Determine size of label value in bytes.
-///
-unsigned DIEObjectLabel::SizeOf(const DwarfDebug &DD, unsigned Form) const {
- if (Form == DW_FORM_data4) return 4;
- return DD.getTargetData()->getPointerSize();
-}
-
-//===----------------------------------------------------------------------===//
-
-/// EmitValue - Emit delta value.
-///
-void DIESectionOffset::EmitValue(DwarfDebug &DD, unsigned Form) {
- bool IsSmall = Form == DW_FORM_data4;
- DD.EmitSectionOffset(Label.Tag, Section.Tag,
- Label.Number, Section.Number, IsSmall, IsEH, UseSet);
-}
-
-/// SizeOf - Determine size of delta value in bytes.
-///
-unsigned DIESectionOffset::SizeOf(const DwarfDebug &DD, unsigned Form) const {
- if (Form == DW_FORM_data4) return 4;
- return DD.getTargetData()->getPointerSize();
-}
-
-//===----------------------------------------------------------------------===//
-
-/// EmitValue - Emit delta value.
-///
-void DIEDelta::EmitValue(DwarfDebug &DD, unsigned Form) {
- bool IsSmall = Form == DW_FORM_data4;
- DD.EmitDifference(LabelHi, LabelLo, IsSmall);
-}
-
-/// SizeOf - Determine size of delta value in bytes.
-///
-unsigned DIEDelta::SizeOf(const DwarfDebug &DD, unsigned Form) const {
- if (Form == DW_FORM_data4) return 4;
- return DD.getTargetData()->getPointerSize();
-}
-
-//===----------------------------------------------------------------------===//
-
-/// EmitValue - Emit debug information entry offset.
-///
-void DIEntry::EmitValue(DwarfDebug &DD, unsigned Form) {
- DD.getAsm()->EmitInt32(Entry->getOffset());
-}
-
-//===----------------------------------------------------------------------===//
-
-/// ComputeSize - calculate the size of the block.
-///
-unsigned DIEBlock::ComputeSize(DwarfDebug &DD) {
- if (!Size) {
- const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
-
- for (unsigned i = 0, N = Values.size(); i < N; ++i) {
- Size += Values[i]->SizeOf(DD, AbbrevData[i].getForm());
- }
- }
- return Size;
-}
-
-/// EmitValue - Emit block data.
-///
-void DIEBlock::EmitValue(DwarfDebug &DD, unsigned Form) {
- switch (Form) {
- case DW_FORM_block1: DD.getAsm()->EmitInt8(Size); break;
- case DW_FORM_block2: DD.getAsm()->EmitInt16(Size); break;
- case DW_FORM_block4: DD.getAsm()->EmitInt32(Size); break;
- case DW_FORM_block: DD.getAsm()->EmitULEB128Bytes(Size); break;
- default: assert(0 && "Improper form for block"); break;
- }
-
- const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
-
- for (unsigned i = 0, N = Values.size(); i < N; ++i) {
- DD.getAsm()->EOL();
- Values[i]->EmitValue(DD, AbbrevData[i].getForm());
- }
-}
-
-/// SizeOf - Determine size of block data in bytes.
-///
-unsigned DIEBlock::SizeOf(const DwarfDebug &DD, unsigned Form) const {
- switch (Form) {
- case DW_FORM_block1: return Size + sizeof(int8_t);
- case DW_FORM_block2: return Size + sizeof(int16_t);
- case DW_FORM_block4: return Size + sizeof(int32_t);
- case DW_FORM_block: return Size + TargetAsmInfo::getULEB128Size(Size);
- default: assert(0 && "Improper form for block"); break;
- }
- return 0;
-}
-
-//===----------------------------------------------------------------------===//
-/// DIE Implementation
-
-DIE::~DIE() {
- for (unsigned i = 0, N = Children.size(); i < N; ++i)
- delete Children[i];
-}
-
-/// AddSiblingOffset - Add a sibling offset field to the front of the DIE.
-///
-void DIE::AddSiblingOffset() {
- DIEInteger *DI = new DIEInteger(0);
- Values.insert(Values.begin(), DI);
- Abbrev.AddFirstAttribute(DW_AT_sibling, DW_FORM_ref4);
-}
-
-/// Profile - Used to gather unique data for the value folding set.
-///
-void DIE::Profile(FoldingSetNodeID &ID) {
- Abbrev.Profile(ID);
-
- for (unsigned i = 0, N = Children.size(); i < N; ++i)
- ID.AddPointer(Children[i]);
-
- for (unsigned j = 0, M = Values.size(); j < M; ++j)
- ID.AddPointer(Values[j]);
-}
-
-#ifndef NDEBUG
-void DIE::print(std::ostream &O, unsigned IncIndent) {
- static unsigned IndentCount = 0;
- IndentCount += IncIndent;
- const std::string Indent(IndentCount, ' ');
- bool isBlock = Abbrev.getTag() == 0;
-
- if (!isBlock) {
- O << Indent
- << "Die: "
- << "0x" << std::hex << (intptr_t)this << std::dec
- << ", Offset: " << Offset
- << ", Size: " << Size
- << "\n";
-
- O << Indent
- << TagString(Abbrev.getTag())
- << " "
- << ChildrenString(Abbrev.getChildrenFlag());
- } else {
- O << "Size: " << Size;
- }
- O << "\n";
-
- const SmallVector<DIEAbbrevData, 8> &Data = Abbrev.getData();
-
- IndentCount += 2;
- for (unsigned i = 0, N = Data.size(); i < N; ++i) {
- O << Indent;
-
- if (!isBlock)
- O << AttributeString(Data[i].getAttribute());
- else
- O << "Blk[" << i << "]";
-
- O << " "
- << FormEncodingString(Data[i].getForm())
- << " ";
- Values[i]->print(O);
- O << "\n";
- }
- IndentCount -= 2;
-
- for (unsigned j = 0, M = Children.size(); j < M; ++j) {
- Children[j]->print(O, 4);
- }
-
- if (!isBlock) O << "\n";
- IndentCount -= IncIndent;
-}
-
-void DIE::dump() {
- print(cerr);
-}
-#endif
-
-//===----------------------------------------------------------------------===//
/// DwarfWriter Implementation
///