llvm-6502/lib/CodeGen/AsmPrinter/DIE.h
Nick Lewycky 6a7efcfc02 Always use the string pool, even when it makes the .o larger. This may help
tools that read the debug info in the .o files by making the DIE sizes more
consistent.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143186 91177308-0d34-0410-b5e6-96231b3b80d8
2011-10-28 05:29:47 +00:00

406 lines
12 KiB
C++

//===--- 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 CODEGEN_ASMPRINTER_DIE_H__
#define CODEGEN_ASMPRINTER_DIE_H__
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Dwarf.h"
#include <vector>
namespace llvm {
class AsmPrinter;
class MCSymbol;
class raw_ostream;
//===--------------------------------------------------------------------===//
/// 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;
};
//===--------------------------------------------------------------------===//
/// DIEAbbrev - Dwarf abbreviation, describes the organization of a debug
/// information object.
class 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() {}
// 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(AsmPrinter *AP) const;
#ifndef NDEBUG
void print(raw_ostream &O);
void dump();
#endif
};
//===--------------------------------------------------------------------===//
/// DIE - A structured debug information entry. Has an abbreviation which
/// describes it's organization.
class DIEValue;
class DIE {
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;
DIE *Parent;
/// Attributes values.
///
SmallVector<DIEValue*, 32> Values;
// Private data for print()
mutable unsigned IndentCount;
public:
explicit DIE(unsigned Tag)
: Abbrev(Tag, dwarf::DW_CHILDREN_no), Offset(0),
Size(0), Parent(0), IndentCount(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; }
const SmallVector<DIEValue*, 32> &getValues() const { return Values; }
DIE *getParent() const { return Parent; }
void setTag(unsigned Tag) { Abbrev.setTag(Tag); }
void setOffset(unsigned O) { Offset = O; }
void setSize(unsigned S) { Size = S; }
/// 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 getSiblingOffset() const { return Offset + Size; }
/// addSiblingOffset - Add a sibling offset field to the front of the DIE.
/// The caller is responsible for deleting the return value at or after the
/// same time it destroys this DIE.
///
DIEValue *addSiblingOffset(BumpPtrAllocator &A);
/// addChild - Add a child to the DIE.
///
void addChild(DIE *Child) {
if (Child->getParent()) {
assert (Child->getParent() == this && "Unexpected DIE Parent!");
return;
}
Abbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes);
Children.push_back(Child);
Child->Parent = this;
}
#ifndef NDEBUG
void print(raw_ostream &O, unsigned IncIndent = 0);
void dump();
#endif
};
//===--------------------------------------------------------------------===//
/// DIEValue - A debug information entry value.
///
class DIEValue {
public:
enum {
isInteger,
isString,
isLabel,
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(AsmPrinter *AP, unsigned Form) const = 0;
/// SizeOf - Return the size of a value in bytes.
///
virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const = 0;
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *) { return true; }
#ifndef NDEBUG
virtual void print(raw_ostream &O) = 0;
void dump();
#endif
};
//===--------------------------------------------------------------------===//
/// DIEInteger - An integer value DIE.
///
class 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(AsmPrinter *AP, unsigned Form) const;
uint64_t getValue() const { return Integer; }
/// SizeOf - Determine size of integer value in bytes.
///
virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const;
// 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(raw_ostream &O);
#endif
};
//===--------------------------------------------------------------------===//
/// DIELabel - A label expression DIE.
//
class DIELabel : public DIEValue {
const MCSymbol *Label;
public:
explicit DIELabel(const MCSymbol *L) : DIEValue(isLabel), Label(L) {}
/// EmitValue - Emit label value.
///
virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
/// getValue - Get MCSymbol.
///
const MCSymbol *getValue() const { return Label; }
/// SizeOf - Determine size of label value in bytes.
///
virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const;
// Implement isa/cast/dyncast.
static bool classof(const DIELabel *) { return true; }
static bool classof(const DIEValue *L) { return L->getType() == isLabel; }
#ifndef NDEBUG
virtual void print(raw_ostream &O);
#endif
};
//===--------------------------------------------------------------------===//
/// DIEDelta - A simple label difference DIE.
///
class DIEDelta : public DIEValue {
const MCSymbol *LabelHi;
const MCSymbol *LabelLo;
public:
DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo)
: DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {}
/// EmitValue - Emit delta value.
///
virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
/// SizeOf - Determine size of delta value in bytes.
///
virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const;
// 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(raw_ostream &O);
#endif
};
//===--------------------------------------------------------------------===//
/// DIEEntry - 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 DIEEntry : public DIEValue {
DIE *const Entry;
public:
explicit DIEEntry(DIE *E) : DIEValue(isEntry), Entry(E) {}
DIE *getEntry() const { return Entry; }
/// EmitValue - Emit debug information entry offset.
///
virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
/// SizeOf - Determine size of debug information entry in bytes.
///
virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const {
return sizeof(int32_t);
}
// 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(raw_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(AsmPrinter *AP);
/// 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(AsmPrinter *AP, unsigned Form) const;
/// SizeOf - Determine size of block data in bytes.
///
virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const;
// 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(raw_ostream &O);
#endif
};
} // end llvm namespace
#endif