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
This commit is contained in:
Bill Wendling 2009-05-15 00:11:17 +00:00
parent 5f00b0c5b6
commit 88423eecd0
7 changed files with 1584 additions and 1278 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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");
}
}
}
}

View File

@ -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

File diff suppressed because it is too large Load Diff