mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-19 04:29:21 +00:00
Reworked how Dwarf debug info entries and abbreviations are handled. Added
pubnames and debuy str sections. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25487 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
bea99471c7
commit
d18e28964b
@ -437,6 +437,15 @@ namespace llvm {
|
|||||||
DW_CFA_hi_user = 0x3f
|
DW_CFA_hi_user = 0x3f
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//===--------------------------------------------------------------------===//
|
||||||
|
// Forward declarations.
|
||||||
|
//
|
||||||
|
class AsmPrinter;
|
||||||
|
class DIE;
|
||||||
|
class DwarfWriter;
|
||||||
|
class DWContext;
|
||||||
|
class MachineDebugInfo;
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// DWLabel - Labels are used to track locations in the assembler file.
|
// DWLabel - Labels are used to track locations in the assembler file.
|
||||||
// Labels appear in the form <prefix>debug_<Tag><Number>, where the tag is a
|
// Labels appear in the form <prefix>debug_<Tag><Number>, where the tag is a
|
||||||
@ -445,57 +454,89 @@ namespace llvm {
|
|||||||
struct DWLabel {
|
struct DWLabel {
|
||||||
const char *Tag; // Label category tag. Should always be
|
const char *Tag; // Label category tag. Should always be
|
||||||
// a staticly declared C string.
|
// a staticly declared C string.
|
||||||
unsigned Number; // Unique number
|
unsigned Number; // Unique number.
|
||||||
|
|
||||||
DWLabel() : Tag(NULL), Number(0) {}
|
|
||||||
DWLabel(const char *T, unsigned N) : Tag(T), Number(N) {}
|
DWLabel(const char *T, unsigned N) : Tag(T), Number(N) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//===--------------------------------------------------------------------===//
|
||||||
|
// DIEAbbrevData - Dwarf abbreviation data, describes the one attribute of a
|
||||||
|
// Dwarf abbreviation.
|
||||||
|
class DIEAbbrevData {
|
||||||
|
private:
|
||||||
|
unsigned Attribute; // Dwarf attribute code.
|
||||||
|
unsigned Form; // Dwarf form code.
|
||||||
|
|
||||||
|
public:
|
||||||
|
DIEAbbrevData(unsigned A, unsigned F)
|
||||||
|
: Attribute(A)
|
||||||
|
, Form(F)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// Accessors
|
||||||
|
unsigned getAttribute() const { return Attribute; }
|
||||||
|
unsigned getForm() const { return Form; }
|
||||||
|
};
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// DIEAbbrev - Dwarf abbreviation, describes the organization of a debug
|
// DIEAbbrev - Dwarf abbreviation, describes the organization of a debug
|
||||||
// information object.
|
// information object.
|
||||||
//
|
|
||||||
class DIEAbbrev {
|
class DIEAbbrev {
|
||||||
private:
|
private:
|
||||||
const unsigned char *Data; // Static array of bytes containing the
|
unsigned Tag; // Dwarf tag code.
|
||||||
// image of the raw abbreviation data.
|
unsigned ChildrenFlag; // Dwarf children flag.
|
||||||
|
std::vector<DIEAbbrevData> Data; // Raw data bytes for abbreviation.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DIEAbbrev(const unsigned char *D)
|
DIEAbbrev(unsigned T, unsigned C)
|
||||||
: Data(D)
|
: Tag(T)
|
||||||
|
, ChildrenFlag(C)
|
||||||
|
, Data()
|
||||||
{}
|
{}
|
||||||
|
~DIEAbbrev() {}
|
||||||
|
|
||||||
|
// Accessors
|
||||||
|
unsigned getTag() const { return Tag; }
|
||||||
|
unsigned getChildrenFlag() const { return ChildrenFlag; }
|
||||||
|
const std::vector<DIEAbbrevData> &getData() const { return Data; }
|
||||||
|
|
||||||
/// operator== - Used by UniqueVector to locate entry.
|
/// operator== - Used by UniqueVector to locate entry.
|
||||||
///
|
///
|
||||||
bool operator==(const DIEAbbrev &DA) const {
|
bool operator==(const DIEAbbrev &DA) const;
|
||||||
return Data == DA.Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// operator< - Used by UniqueVector to locate entry.
|
/// operator< - Used by UniqueVector to locate entry.
|
||||||
///
|
///
|
||||||
bool operator<(const DIEAbbrev &DA) const {
|
bool operator<(const DIEAbbrev &DA) const;
|
||||||
return Data < DA.Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Accessors
|
/// AddAttribute - Adds another set of attribute information to the
|
||||||
unsigned getTag() const { return Data[0]; }
|
/// abbreviation.
|
||||||
unsigned getChildrenFlag() const { return Data[1]; }
|
void AddAttribute(unsigned Attribute, unsigned Form) {
|
||||||
unsigned getAttribute(unsigned i) const { return Data[2 + 2 * i + 0]; }
|
Data.push_back(DIEAbbrevData(Attribute, Form));
|
||||||
unsigned getForm(unsigned i) const { return Data[2 + 2 * i + 1]; }
|
}
|
||||||
|
|
||||||
|
/// Emit - Print the abbreviation using the specified Dwarf writer.
|
||||||
|
///
|
||||||
|
void Emit(const DwarfWriter &DW) const;
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
void print(std::ostream &O);
|
||||||
|
void dump();
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// DIEValue - A debug information entry value.
|
// DIEValue - A debug information entry value.
|
||||||
//
|
//
|
||||||
class DwarfWriter;
|
|
||||||
class DIEValue {
|
class DIEValue {
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
isInteger,
|
isInteger,
|
||||||
isString,
|
isString,
|
||||||
isLabel,
|
isLabel,
|
||||||
isDelta
|
isAsIsLabel,
|
||||||
|
isDelta,
|
||||||
|
isEntry
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned Type; // Type of the value
|
unsigned Type; // Type of the value
|
||||||
@ -520,14 +561,14 @@ namespace llvm {
|
|||||||
//
|
//
|
||||||
class DIEInteger : public DIEValue {
|
class DIEInteger : public DIEValue {
|
||||||
private:
|
private:
|
||||||
int Value;
|
int Integer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DIEInteger(int V) : DIEValue(isInteger), Value(V) {}
|
DIEInteger(int I) : DIEValue(isInteger), Integer(I) {}
|
||||||
|
|
||||||
// Implement isa/cast/dyncast.
|
// Implement isa/cast/dyncast.
|
||||||
static bool classof(const DIEInteger *) { return true; }
|
static bool classof(const DIEInteger *) { return true; }
|
||||||
static bool classof(const DIEValue *V) { return V->Type == isInteger; }
|
static bool classof(const DIEValue *I) { return I->Type == isInteger; }
|
||||||
|
|
||||||
/// EmitValue - Emit integer of appropriate size.
|
/// EmitValue - Emit integer of appropriate size.
|
||||||
///
|
///
|
||||||
@ -542,13 +583,13 @@ namespace llvm {
|
|||||||
// DIEString - A string value DIE.
|
// DIEString - A string value DIE.
|
||||||
//
|
//
|
||||||
struct DIEString : public DIEValue {
|
struct DIEString : public DIEValue {
|
||||||
const std::string Value;
|
const std::string String;
|
||||||
|
|
||||||
DIEString(const std::string &V) : DIEValue(isString), Value(V) {}
|
DIEString(const std::string &S) : DIEValue(isString), String(S) {}
|
||||||
|
|
||||||
// Implement isa/cast/dyncast.
|
// Implement isa/cast/dyncast.
|
||||||
static bool classof(const DIEString *) { return true; }
|
static bool classof(const DIEString *) { return true; }
|
||||||
static bool classof(const DIEValue *V) { return V->Type == isString; }
|
static bool classof(const DIEValue *S) { return S->Type == isString; }
|
||||||
|
|
||||||
/// EmitValue - Emit string value.
|
/// EmitValue - Emit string value.
|
||||||
///
|
///
|
||||||
@ -563,13 +604,35 @@ namespace llvm {
|
|||||||
// DIELabel - A simple label expression DIE.
|
// DIELabel - A simple label expression DIE.
|
||||||
//
|
//
|
||||||
struct DIELabel : public DIEValue {
|
struct DIELabel : public DIEValue {
|
||||||
const DWLabel Value;
|
const DWLabel Label;
|
||||||
|
|
||||||
DIELabel(const DWLabel &V) : DIEValue(isLabel), Value(V) {}
|
DIELabel(const DWLabel &L) : DIEValue(isLabel), Label(L) {}
|
||||||
|
|
||||||
// Implement isa/cast/dyncast.
|
// Implement isa/cast/dyncast.
|
||||||
static bool classof(const DWLabel *) { return true; }
|
static bool classof(const DIELabel *) { return true; }
|
||||||
static bool classof(const DIEValue *V) { return V->Type == isLabel; }
|
static bool classof(const DIEValue *L) { return L->Type == isLabel; }
|
||||||
|
|
||||||
|
/// EmitValue - Emit label value.
|
||||||
|
///
|
||||||
|
virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const;
|
||||||
|
|
||||||
|
/// SizeOf - Determine size of label value in bytes.
|
||||||
|
///
|
||||||
|
virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//===--------------------------------------------------------------------===//
|
||||||
|
// DIEAsIsLabel - An exact name of a label.
|
||||||
|
//
|
||||||
|
struct DIEAsIsLabel : public DIEValue {
|
||||||
|
const std::string Label;
|
||||||
|
|
||||||
|
DIEAsIsLabel(const std::string &L) : DIEValue(isAsIsLabel), Label(L) {}
|
||||||
|
|
||||||
|
// Implement isa/cast/dyncast.
|
||||||
|
static bool classof(const DIEAsIsLabel *) { return true; }
|
||||||
|
static bool classof(const DIEValue *L) { return L->Type == isAsIsLabel; }
|
||||||
|
|
||||||
/// EmitValue - Emit label value.
|
/// EmitValue - Emit label value.
|
||||||
///
|
///
|
||||||
@ -584,15 +647,36 @@ namespace llvm {
|
|||||||
// DIEDelta - A simple label difference DIE.
|
// DIEDelta - A simple label difference DIE.
|
||||||
//
|
//
|
||||||
struct DIEDelta : public DIEValue {
|
struct DIEDelta : public DIEValue {
|
||||||
const DWLabel Value1;
|
const DWLabel LabelHi;
|
||||||
const DWLabel Value2;
|
const DWLabel LabelLo;
|
||||||
|
|
||||||
DIEDelta(const DWLabel &V1, const DWLabel &V2)
|
DIEDelta(const DWLabel &Hi, const DWLabel &Lo)
|
||||||
: DIEValue(isDelta), Value1(V1), Value2(V2) {}
|
: DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {}
|
||||||
|
|
||||||
// Implement isa/cast/dyncast.
|
// Implement isa/cast/dyncast.
|
||||||
static bool classof(const DIEDelta *) { return true; }
|
static bool classof(const DIEDelta *) { return true; }
|
||||||
static bool classof(const DIEValue *V) { return V->Type == isDelta; }
|
static bool classof(const DIEValue *D) { return D->Type == isDelta; }
|
||||||
|
|
||||||
|
/// EmitValue - Emit delta value.
|
||||||
|
///
|
||||||
|
virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const;
|
||||||
|
|
||||||
|
/// SizeOf - Determine size of delta value in bytes.
|
||||||
|
///
|
||||||
|
virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
//===--------------------------------------------------------------------===//
|
||||||
|
// DIEntry - A pointer to a debug information entry.
|
||||||
|
//
|
||||||
|
struct DIEntry : public DIEValue {
|
||||||
|
DIE *Entry;
|
||||||
|
|
||||||
|
DIEntry(DIE *E) : DIEValue(isEntry), 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 delta value.
|
/// EmitValue - Emit delta value.
|
||||||
///
|
///
|
||||||
@ -608,70 +692,106 @@ namespace llvm {
|
|||||||
// describes it's organization.
|
// describes it's organization.
|
||||||
class DIE {
|
class DIE {
|
||||||
private:
|
private:
|
||||||
|
DIEAbbrev *Abbrev; // Temporary buffer for abbreviation.
|
||||||
unsigned AbbrevID; // Decribing abbreviation ID.
|
unsigned AbbrevID; // Decribing abbreviation ID.
|
||||||
unsigned Offset; // Offset in debug info section
|
unsigned Offset; // Offset in debug info section.
|
||||||
unsigned Size; // Size of instance + children
|
unsigned Size; // Size of instance + children.
|
||||||
std::vector<DIE *> Children; // Children DIEs
|
DWContext *Context; // Context for types and values.
|
||||||
std::vector<DIEValue *> Values; // Attributes values
|
std::vector<DIE *> Children; // Children DIEs.
|
||||||
|
std::vector<DIEValue *> Values; // Attributes values.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DIE(unsigned AbbrevID)
|
DIE(unsigned Tag, unsigned ChildrenFlag);
|
||||||
: AbbrevID(AbbrevID)
|
~DIE();
|
||||||
, Offset(0)
|
|
||||||
, Size(0)
|
|
||||||
, Children()
|
|
||||||
, Values()
|
|
||||||
{}
|
|
||||||
~DIE() {
|
|
||||||
for (unsigned i = 0, N = Children.size(); i < N; i++) {
|
|
||||||
delete Children[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned j = 0, M = Children.size(); j < M; j++) {
|
|
||||||
delete Children[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
unsigned getAbbrevID() const { return AbbrevID; }
|
unsigned getAbbrevID() const { return AbbrevID; }
|
||||||
unsigned getOffset() const { return Offset; }
|
unsigned getOffset() const { return Offset; }
|
||||||
unsigned getSize() const { return Size; }
|
unsigned getSize() const { return Size; }
|
||||||
|
DWContext *getContext() const { return Context; }
|
||||||
const std::vector<DIE *> &getChildren() const { return Children; }
|
const std::vector<DIE *> &getChildren() const { return Children; }
|
||||||
const std::vector<DIEValue *> &getValues() const { return Values; }
|
const std::vector<DIEValue *> &getValues() const { return Values; }
|
||||||
void setOffset(unsigned O) { Offset = O; }
|
void setOffset(unsigned O) { Offset = O; }
|
||||||
void setSize(unsigned S) { Size = S; }
|
void setSize(unsigned S) { Size = S; }
|
||||||
|
void setContext(DWContext *C) { Context = C; }
|
||||||
/// AddValue - Add an attribute value of appropriate type.
|
|
||||||
///
|
|
||||||
void AddValue(int Value) {
|
|
||||||
Values.push_back(new DIEInteger(Value));
|
|
||||||
}
|
|
||||||
void AddValue(const std::string &Value) {
|
|
||||||
Values.push_back(new DIEString(Value));
|
|
||||||
}
|
|
||||||
void AddValue(const DWLabel &Value) {
|
|
||||||
Values.push_back(new DIELabel(Value));
|
|
||||||
}
|
|
||||||
void AddValue(const DWLabel &Value1, const DWLabel &Value2) {
|
|
||||||
Values.push_back(new DIEDelta(Value1, Value2));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// SiblingOffset - Return the offset of the debug information entry's
|
/// SiblingOffset - Return the offset of the debug information entry's
|
||||||
/// sibling.
|
/// sibling.
|
||||||
unsigned SiblingOffset() const { return Offset + Size; }
|
unsigned SiblingOffset() const { return Offset + Size; }
|
||||||
|
|
||||||
|
/// AddInt - Add a simple integer attribute data and value.
|
||||||
|
///
|
||||||
|
void AddInt(unsigned Attribute, unsigned Form, int Integer);
|
||||||
|
|
||||||
|
/// AddString - Add a std::string attribute data and value.
|
||||||
|
///
|
||||||
|
void AddString(unsigned Attribute, unsigned Form,
|
||||||
|
const std::string &String);
|
||||||
|
|
||||||
|
/// AddLabel - Add a Dwarf label attribute data and value.
|
||||||
|
///
|
||||||
|
void AddLabel(unsigned Attribute, unsigned Form, const DWLabel &Label);
|
||||||
|
|
||||||
|
/// AddAsIsLabel - Add a non-Dwarf label attribute data and value.
|
||||||
|
///
|
||||||
|
void AddAsIsLabel(unsigned Attribute, unsigned Form,
|
||||||
|
const std::string &Label);
|
||||||
|
|
||||||
|
/// AddDelta - Add a label delta attribute data and value.
|
||||||
|
///
|
||||||
|
void AddDelta(unsigned Attribute, unsigned Form,
|
||||||
|
const DWLabel &Hi, const DWLabel &Lo);
|
||||||
|
|
||||||
|
/// AddDIEntry - Add a DIE attribute data and value.
|
||||||
|
///
|
||||||
|
void AddDIEntry(unsigned Attribute, unsigned Form, DIE *Entry);
|
||||||
|
|
||||||
|
/// Complete - Indicate that all attributes have been added and
|
||||||
|
/// ready to get an abbreviation ID.
|
||||||
|
///
|
||||||
|
void Complete(DwarfWriter &DW);
|
||||||
|
|
||||||
|
/// AddChild - Add a child to the DIE.
|
||||||
|
void AddChild(DIE *Child);
|
||||||
|
};
|
||||||
|
|
||||||
|
//===--------------------------------------------------------------------===//
|
||||||
|
/// DWContext - Name context for types and values.
|
||||||
|
///
|
||||||
|
class DWContext {
|
||||||
|
private:
|
||||||
|
DwarfWriter &DW; // DwarfWriter for global information.
|
||||||
|
DIE *Owner; // Owning debug information entry.
|
||||||
|
std::map<std::string, DIE*> Types; // Named types in context.
|
||||||
|
std::map<std::string, DIE*> Variables;// Named variables in context.
|
||||||
|
|
||||||
|
public:
|
||||||
|
DWContext(DwarfWriter &D, DIE *O)
|
||||||
|
: DW(D)
|
||||||
|
, Owner(O)
|
||||||
|
, Types()
|
||||||
|
, Variables()
|
||||||
|
{
|
||||||
|
Owner->setContext(this);
|
||||||
|
}
|
||||||
|
~DWContext() {}
|
||||||
|
|
||||||
|
/// NewBasicType - Creates a new basic type, if necessary, then adds in the
|
||||||
|
/// context and owner.
|
||||||
|
DIE *NewBasicType(const std::string &Name, unsigned Size,
|
||||||
|
unsigned Encoding);
|
||||||
|
|
||||||
|
/// NewVariable - Creates a basic variable, if necessary, then adds in the
|
||||||
|
/// context and owner.
|
||||||
|
DIE *NewVariable(const std::string &Name,
|
||||||
|
unsigned SourceFileID, unsigned Line,
|
||||||
|
DIE *Type, bool IsExternal);
|
||||||
};
|
};
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Forward declarations.
|
// DwarfWriter - Emits Dwarf debug and exception handling directives.
|
||||||
//
|
|
||||||
class AsmPrinter;
|
|
||||||
class MachineDebugInfo;
|
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
|
||||||
// DwarfWriter - emits Dwarf debug and exception handling directives.
|
|
||||||
//
|
//
|
||||||
class DwarfWriter {
|
class DwarfWriter {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
//===------------------------------------------------------------------===//
|
//===------------------------------------------------------------------===//
|
||||||
@ -707,6 +827,18 @@ namespace llvm {
|
|||||||
///
|
///
|
||||||
UniqueVector<DIEAbbrev> Abbreviations;
|
UniqueVector<DIEAbbrev> Abbreviations;
|
||||||
|
|
||||||
|
/// GlobalTypes - A map of globally visible named types.
|
||||||
|
///
|
||||||
|
std::map<std::string, DIE *> GlobalTypes;
|
||||||
|
|
||||||
|
/// GlobalEntities - A map of globally visible named entities.
|
||||||
|
///
|
||||||
|
std::map<std::string, DIE *> GlobalEntities;
|
||||||
|
|
||||||
|
/// StringPool - A UniqueVector of strings used by indirect references.
|
||||||
|
///
|
||||||
|
UniqueVector<std::string> StringPool;
|
||||||
|
|
||||||
//===------------------------------------------------------------------===//
|
//===------------------------------------------------------------------===//
|
||||||
// Properties to be set by the derived class ctor, used to configure the
|
// Properties to be set by the derived class ctor, used to configure the
|
||||||
// Dwarf writer.
|
// Dwarf writer.
|
||||||
@ -861,21 +993,34 @@ public:
|
|||||||
EmitReference(Label.Tag, Label.Number);
|
EmitReference(Label.Tag, Label.Number);
|
||||||
}
|
}
|
||||||
void EmitReference(const char *Tag, unsigned Number) const;
|
void EmitReference(const char *Tag, unsigned Number) const;
|
||||||
|
void EmitReference(const std::string Name) const;
|
||||||
|
|
||||||
/// EmitDifference - Emit the difference between two labels. Some
|
/// EmitDifference - Emit the difference between two labels. Some
|
||||||
/// assemblers do not behave with absolute expressions with data directives,
|
/// assemblers do not behave with absolute expressions with data directives,
|
||||||
/// so there is an option (needsSet) to use an intermediary set expression.
|
/// so there is an option (needsSet) to use an intermediary set expression.
|
||||||
void EmitDifference(DWLabel Label1, DWLabel Label2) const {
|
void EmitDifference(DWLabel LabelHi, DWLabel LabelLo) const {
|
||||||
EmitDifference(Label1.Tag, Label1.Number, Label2.Tag, Label2.Number);
|
EmitDifference(LabelHi.Tag, LabelHi.Number, LabelLo.Tag, LabelLo.Number);
|
||||||
}
|
}
|
||||||
void EmitDifference(const char *Tag1, unsigned Number1,
|
void EmitDifference(const char *TagHi, unsigned NumberHi,
|
||||||
const char *Tag2, unsigned Number2) const;
|
const char *TagLo, unsigned NumberLo) const;
|
||||||
|
|
||||||
private:
|
/// NewAbbreviation - Add the abbreviation to the Abbreviation vector.
|
||||||
/// NewDIE - Construct a new structured debug information entry.
|
|
||||||
///
|
///
|
||||||
DIE *NewDIE(const unsigned char *AbbrevData);
|
unsigned NewAbbreviation(DIEAbbrev *Abbrev);
|
||||||
|
|
||||||
|
/// NewString - Add a string to the constant pool and returns a label.
|
||||||
|
///
|
||||||
|
DWLabel NewString(const std::string &String);
|
||||||
|
|
||||||
|
/// NewGlobalType - Make the type visible globally using the given name.
|
||||||
|
///
|
||||||
|
void NewGlobalType(const std::string &Name, DIE *Type);
|
||||||
|
|
||||||
|
/// NewGlobalEntity - Make the entity visible globally using the given name.
|
||||||
|
///
|
||||||
|
void NewGlobalEntity(const std::string &Name, DIE *Entity);
|
||||||
|
|
||||||
|
private:
|
||||||
/// NewCompileUnit - Create new compile unit information.
|
/// NewCompileUnit - Create new compile unit information.
|
||||||
///
|
///
|
||||||
DIE *NewCompileUnit(const std::string &Directory,
|
DIE *NewCompileUnit(const std::string &Directory,
|
||||||
@ -956,7 +1101,7 @@ private:
|
|||||||
void SetDebugInfo(MachineDebugInfo *di) { DebugInfo = di; }
|
void SetDebugInfo(MachineDebugInfo *di) { DebugInfo = di; }
|
||||||
|
|
||||||
//===------------------------------------------------------------------===//
|
//===------------------------------------------------------------------===//
|
||||||
// Main enties.
|
// Main entry points.
|
||||||
//
|
//
|
||||||
|
|
||||||
/// BeginModule - Emit all Dwarf sections that should come prior to the
|
/// BeginModule - Emit all Dwarf sections that should come prior to the
|
||||||
|
@ -26,84 +26,6 @@ static cl::opt<bool>
|
|||||||
DwarfVerbose("dwarf-verbose", cl::Hidden,
|
DwarfVerbose("dwarf-verbose", cl::Hidden,
|
||||||
cl::desc("Add comments to Dwarf directives."));
|
cl::desc("Add comments to Dwarf directives."));
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// Dwarf abbreviations used by this emitter.
|
|
||||||
//
|
|
||||||
|
|
||||||
static const unsigned char AbbrevTAG_compile_unit[] = {
|
|
||||||
DW_TAG_compile_unit, DW_CHILDREN_yes,
|
|
||||||
DW_AT_stmt_list, DW_FORM_data4,
|
|
||||||
DW_AT_high_pc, DW_FORM_addr,
|
|
||||||
DW_AT_low_pc, DW_FORM_addr,
|
|
||||||
DW_AT_producer, DW_FORM_string,
|
|
||||||
DW_AT_language, DW_FORM_data1,
|
|
||||||
DW_AT_name, DW_FORM_string,
|
|
||||||
DW_AT_comp_dir, DW_FORM_string,
|
|
||||||
0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned char AbbrevTAG_subprogram[] = {
|
|
||||||
DW_TAG_subprogram, DW_CHILDREN_yes,
|
|
||||||
DW_AT_sibling, DW_FORM_ref4,
|
|
||||||
DW_AT_external, DW_FORM_flag,
|
|
||||||
DW_AT_name, DW_FORM_string,
|
|
||||||
DW_AT_decl_file, DW_FORM_data1,
|
|
||||||
DW_AT_decl_line, DW_FORM_data1,
|
|
||||||
DW_AT_prototyped, DW_FORM_flag,
|
|
||||||
DW_AT_type, DW_FORM_ref4,
|
|
||||||
DW_AT_low_pc, DW_FORM_addr,
|
|
||||||
DW_AT_high_pc, DW_FORM_addr,
|
|
||||||
DW_AT_frame_base, DW_FORM_block1,
|
|
||||||
0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned char AbbrevTAG_formal_parameter[] = {
|
|
||||||
DW_TAG_formal_parameter, DW_CHILDREN_no,
|
|
||||||
DW_AT_name, DW_FORM_string,
|
|
||||||
DW_AT_decl_file, DW_FORM_data1,
|
|
||||||
DW_AT_decl_line, DW_FORM_data1,
|
|
||||||
DW_AT_type, DW_FORM_ref4,
|
|
||||||
DW_AT_location, DW_FORM_block1,
|
|
||||||
0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned char AbbrevTAG_base_type[] = {
|
|
||||||
DW_TAG_base_type, DW_CHILDREN_no,
|
|
||||||
DW_AT_name, DW_FORM_string,
|
|
||||||
DW_AT_byte_size, DW_FORM_data1,
|
|
||||||
DW_AT_encoding, DW_FORM_data1,
|
|
||||||
0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned char AbbrevTAG_pointer_type[] = {
|
|
||||||
DW_TAG_pointer_type, DW_CHILDREN_no,
|
|
||||||
DW_AT_byte_size, DW_FORM_data1,
|
|
||||||
DW_AT_type, DW_FORM_ref4,
|
|
||||||
0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned char AbbrevTAG_array_type[] = {
|
|
||||||
DW_TAG_array_type, DW_CHILDREN_yes,
|
|
||||||
DW_AT_sibling, DW_FORM_ref4,
|
|
||||||
DW_AT_type, DW_FORM_ref4,
|
|
||||||
0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned char AbbrevTAG_subrange_type[] = {
|
|
||||||
DW_TAG_subrange_type, DW_CHILDREN_no,
|
|
||||||
0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned char AbbrevTAG_variable[] = {
|
|
||||||
DW_TAG_variable, DW_CHILDREN_no,
|
|
||||||
DW_AT_name, DW_FORM_string,
|
|
||||||
DW_AT_type, DW_FORM_ref4,
|
|
||||||
DW_AT_external, DW_FORM_flag,
|
|
||||||
DW_AT_artificial, DW_FORM_flag,
|
|
||||||
DW_AT_declaration, DW_FORM_flag,
|
|
||||||
0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// TagString - Return the string for the specified tag.
|
/// TagString - Return the string for the specified tag.
|
||||||
@ -659,13 +581,102 @@ static const char *CallFrameString(unsigned Encoding) {
|
|||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
/// operator== - Used by UniqueVector to locate entry.
|
||||||
|
///
|
||||||
|
bool DIEAbbrev::operator==(const DIEAbbrev &DA) const {
|
||||||
|
if (Tag != DA.Tag) return false;
|
||||||
|
if (ChildrenFlag != DA.ChildrenFlag) return false;
|
||||||
|
if (Data.size() != DA.Data.size()) return false;
|
||||||
|
|
||||||
|
for (unsigned i = 0, N = Data.size(); i < N; i++) {
|
||||||
|
const DIEAbbrevData &AttrData = Data[i];
|
||||||
|
const DIEAbbrevData &DAAttrData = Data[i];
|
||||||
|
if (AttrData.getAttribute() != DAAttrData.getAttribute()) return false;
|
||||||
|
if (AttrData.getForm() != DAAttrData.getForm()) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// operator< - Used by UniqueVector to locate entry.
|
||||||
|
///
|
||||||
|
bool DIEAbbrev::operator<(const DIEAbbrev &DA) const {
|
||||||
|
if (Tag != DA.Tag) return Tag < DA.Tag;
|
||||||
|
if (ChildrenFlag != DA.ChildrenFlag) return ChildrenFlag < DA.ChildrenFlag;
|
||||||
|
if (Data.size() != DA.Data.size()) return Data.size() < DA.Data.size();
|
||||||
|
|
||||||
|
for (unsigned i = 0, N = Data.size(); i < N; i++) {
|
||||||
|
const DIEAbbrevData &AttrData = Data[i];
|
||||||
|
const DIEAbbrevData &DAAttrData = DA.Data[i];
|
||||||
|
if (AttrData.getAttribute() != DAAttrData.getAttribute())
|
||||||
|
return AttrData.getAttribute() < DAAttrData.getAttribute();
|
||||||
|
if (AttrData.getForm() != DAAttrData.getForm())
|
||||||
|
return AttrData.getForm() < DAAttrData.getForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Emit - Print the abbreviation using the specified Dwarf writer.
|
||||||
|
///
|
||||||
|
void DIEAbbrev::Emit(const DwarfWriter &DW) const {
|
||||||
|
// Emit its Dwarf tag type.
|
||||||
|
DW.EmitULEB128Bytes(Tag);
|
||||||
|
DW.EOL(TagString(Tag));
|
||||||
|
|
||||||
|
// Emit whether it has children DIEs.
|
||||||
|
DW.EmitULEB128Bytes(ChildrenFlag);
|
||||||
|
DW.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.
|
||||||
|
DW.EmitULEB128Bytes(AttrData.getAttribute());
|
||||||
|
DW.EOL(AttributeString(AttrData.getAttribute()));
|
||||||
|
|
||||||
|
// Emit form type.
|
||||||
|
DW.EmitULEB128Bytes(AttrData.getForm());
|
||||||
|
DW.EOL(FormEncodingString(AttrData.getForm()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark end of abbreviation.
|
||||||
|
DW.EmitULEB128Bytes(0); DW.EOL("EOM(1)");
|
||||||
|
DW.EmitULEB128Bytes(0); DW.EOL("EOM(2)");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
void DIEAbbrev::print(std::ostream &O) {
|
||||||
|
O << "Abbreviation @"
|
||||||
|
<< std::hex << (unsigned)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(std::cerr); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// EmitValue - Emit integer of appropriate size.
|
/// EmitValue - Emit integer of appropriate size.
|
||||||
///
|
///
|
||||||
void DIEInteger::EmitValue(const DwarfWriter &DW, unsigned Form) const {
|
void DIEInteger::EmitValue(const DwarfWriter &DW, unsigned Form) const {
|
||||||
switch (Form) {
|
switch (Form) {
|
||||||
case DW_FORM_data1: DW.EmitByte(Value); break;
|
case DW_FORM_data1: // Fall thru
|
||||||
case DW_FORM_data2: DW.EmitShort(Value); break;
|
case DW_FORM_flag: DW.EmitByte(Integer); break;
|
||||||
case DW_FORM_data4: DW.EmitLong(Value); break;
|
case DW_FORM_data2: DW.EmitShort(Integer); break;
|
||||||
|
case DW_FORM_data4: DW.EmitLong(Integer); break;
|
||||||
default: assert(0 && "DIE Value form not supported yet"); break;
|
default: assert(0 && "DIE Value form not supported yet"); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -674,6 +685,7 @@ void DIEInteger::EmitValue(const DwarfWriter &DW, unsigned Form) const {
|
|||||||
///
|
///
|
||||||
unsigned DIEInteger::SizeOf(const DwarfWriter &DW, unsigned Form) const {
|
unsigned DIEInteger::SizeOf(const DwarfWriter &DW, unsigned Form) const {
|
||||||
switch (Form) {
|
switch (Form) {
|
||||||
|
case DW_FORM_flag: // Fall thru
|
||||||
case DW_FORM_data1: return sizeof(int8_t);
|
case DW_FORM_data1: return sizeof(int8_t);
|
||||||
case DW_FORM_data2: return sizeof(int16_t);
|
case DW_FORM_data2: return sizeof(int16_t);
|
||||||
case DW_FORM_data4: return sizeof(int32_t);
|
case DW_FORM_data4: return sizeof(int32_t);
|
||||||
@ -687,13 +699,13 @@ unsigned DIEInteger::SizeOf(const DwarfWriter &DW, unsigned Form) const {
|
|||||||
/// EmitValue - Emit string value.
|
/// EmitValue - Emit string value.
|
||||||
///
|
///
|
||||||
void DIEString::EmitValue(const DwarfWriter &DW, unsigned Form) const {
|
void DIEString::EmitValue(const DwarfWriter &DW, unsigned Form) const {
|
||||||
DW.EmitString(Value);
|
DW.EmitString(String);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SizeOf - Determine size of string value in bytes.
|
/// SizeOf - Determine size of string value in bytes.
|
||||||
///
|
///
|
||||||
unsigned DIEString::SizeOf(const DwarfWriter &DW, unsigned Form) const {
|
unsigned DIEString::SizeOf(const DwarfWriter &DW, unsigned Form) const {
|
||||||
return Value.size() + sizeof(int8_t);
|
return String.size() + sizeof('\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -701,7 +713,7 @@ unsigned DIEString::SizeOf(const DwarfWriter &DW, unsigned Form) const {
|
|||||||
/// EmitValue - Emit label value.
|
/// EmitValue - Emit label value.
|
||||||
///
|
///
|
||||||
void DIELabel::EmitValue(const DwarfWriter &DW, unsigned Form) const {
|
void DIELabel::EmitValue(const DwarfWriter &DW, unsigned Form) const {
|
||||||
DW.EmitReference(Value);
|
DW.EmitReference(Label);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SizeOf - Determine size of label value in bytes.
|
/// SizeOf - Determine size of label value in bytes.
|
||||||
@ -712,10 +724,24 @@ unsigned DIELabel::SizeOf(const DwarfWriter &DW, unsigned Form) const {
|
|||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
/// EmitValue - Emit label value.
|
||||||
|
///
|
||||||
|
void DIEAsIsLabel::EmitValue(const DwarfWriter &DW, unsigned Form) const {
|
||||||
|
DW.EmitReference(Label);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// SizeOf - Determine size of label value in bytes.
|
||||||
|
///
|
||||||
|
unsigned DIEAsIsLabel::SizeOf(const DwarfWriter &DW, unsigned Form) const {
|
||||||
|
return DW.getAddressSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// EmitValue - Emit delta value.
|
/// EmitValue - Emit delta value.
|
||||||
///
|
///
|
||||||
void DIEDelta::EmitValue(const DwarfWriter &DW, unsigned Form) const {
|
void DIEDelta::EmitValue(const DwarfWriter &DW, unsigned Form) const {
|
||||||
DW.EmitDifference(Value1, Value2);
|
DW.EmitDifference(LabelHi, LabelLo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SizeOf - Determine size of delta value in bytes.
|
/// SizeOf - Determine size of delta value in bytes.
|
||||||
@ -724,6 +750,171 @@ unsigned DIEDelta::SizeOf(const DwarfWriter &DW, unsigned Form) const {
|
|||||||
return DW.getAddressSize();
|
return DW.getAddressSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
/// EmitValue - Emit extry offset.
|
||||||
|
///
|
||||||
|
void DIEntry::EmitValue(const DwarfWriter &DW, unsigned Form) const {
|
||||||
|
DW.EmitLong(Entry->getOffset());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// SizeOf - Determine size of label value in bytes.
|
||||||
|
///
|
||||||
|
unsigned DIEntry::SizeOf(const DwarfWriter &DW, unsigned Form) const {
|
||||||
|
return sizeof(int32_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
DIE::DIE(unsigned Tag, unsigned ChildrenFlag)
|
||||||
|
: Abbrev(new DIEAbbrev(Tag, ChildrenFlag))
|
||||||
|
, AbbrevID(0)
|
||||||
|
, Offset(0)
|
||||||
|
, Size(0)
|
||||||
|
, Context(NULL)
|
||||||
|
, Children()
|
||||||
|
, Values()
|
||||||
|
{}
|
||||||
|
|
||||||
|
DIE::~DIE() {
|
||||||
|
if (Abbrev) delete Abbrev;
|
||||||
|
|
||||||
|
for (unsigned i = 0, N = Children.size(); i < N; i++) {
|
||||||
|
delete Children[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned j = 0, M = Values.size(); j < M; j++) {
|
||||||
|
delete Values[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Context) delete Context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// AddInt - Add a simple integer attribute data and value.
|
||||||
|
///
|
||||||
|
void DIE::AddInt(unsigned Attribute, unsigned Form,
|
||||||
|
int Integer) {
|
||||||
|
Abbrev->AddAttribute(Attribute, Form);
|
||||||
|
Values.push_back(new DIEInteger(Integer));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// AddString - Add a std::string attribute data and value.
|
||||||
|
///
|
||||||
|
void DIE::AddString(unsigned Attribute, unsigned Form,
|
||||||
|
const std::string &String) {
|
||||||
|
Abbrev->AddAttribute(Attribute, Form);
|
||||||
|
Values.push_back(new DIEString(String));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// AddLabel - Add a Dwarf label attribute data and value.
|
||||||
|
///
|
||||||
|
void DIE::AddLabel(unsigned Attribute, unsigned Form,
|
||||||
|
const DWLabel &Label) {
|
||||||
|
Abbrev->AddAttribute(Attribute, Form);
|
||||||
|
Values.push_back(new DIELabel(Label));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// AddAsIsLabel - Add an non-Dwarf label attribute data and value.
|
||||||
|
///
|
||||||
|
void DIE::AddAsIsLabel(unsigned Attribute, unsigned Form,
|
||||||
|
const std::string &Label) {
|
||||||
|
Abbrev->AddAttribute(Attribute, Form);
|
||||||
|
Values.push_back(new DIEAsIsLabel(Label));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// AddDelta - Add a label delta attribute data and value.
|
||||||
|
///
|
||||||
|
void DIE::AddDelta(unsigned Attribute, unsigned Form,
|
||||||
|
const DWLabel &Hi, const DWLabel &Lo) {
|
||||||
|
Abbrev->AddAttribute(Attribute, Form);
|
||||||
|
Values.push_back(new DIEDelta(Hi, Lo));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// AddDIEntry - Add a DIE attribute data and value.
|
||||||
|
///
|
||||||
|
void DIE::AddDIEntry(unsigned Attribute,
|
||||||
|
unsigned Form, DIE *Entry) {
|
||||||
|
Abbrev->AddAttribute(Attribute, Form);
|
||||||
|
Values.push_back(new DIEntry(Entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Complete - Indicate that all attributes have been added and ready to get an
|
||||||
|
/// abbreviation ID.
|
||||||
|
void DIE::Complete(DwarfWriter &DW) {
|
||||||
|
AbbrevID = DW.NewAbbreviation(Abbrev);
|
||||||
|
delete Abbrev;
|
||||||
|
Abbrev = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// AddChild - Add a child to the DIE.
|
||||||
|
///
|
||||||
|
void DIE::AddChild(DIE *Child) {
|
||||||
|
Children.push_back(Child);
|
||||||
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
/// NewBasicType - Creates a new basic type if necessary, then adds in the
|
||||||
|
/// context and owner.
|
||||||
|
DIE *DWContext::NewBasicType(const std::string &Name, unsigned Size,
|
||||||
|
unsigned Encoding) {
|
||||||
|
// FIXME - Just a prototype.
|
||||||
|
DIE *Type = Types[Name];
|
||||||
|
|
||||||
|
// If first occurance of type.
|
||||||
|
if (!Type) {
|
||||||
|
// construct the type DIE.
|
||||||
|
Type = new DIE(DW_TAG_base_type, DW_CHILDREN_no);
|
||||||
|
Type->AddString(DW_AT_name, DW_FORM_string, Name);
|
||||||
|
Type->AddInt (DW_AT_byte_size, DW_FORM_data1, Size);
|
||||||
|
Type->AddInt (DW_AT_encoding, DW_FORM_data1, Encoding);
|
||||||
|
Type->Complete(DW);
|
||||||
|
|
||||||
|
// Add to context owner.
|
||||||
|
Owner->AddChild(Type);
|
||||||
|
|
||||||
|
// Add to map.
|
||||||
|
Types[Name] = Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// NewVariable - Creates a basic variable, if necessary, then adds in the
|
||||||
|
/// context and owner.
|
||||||
|
DIE *DWContext::NewVariable(const std::string &Name,
|
||||||
|
unsigned SourceFileID, unsigned Line,
|
||||||
|
DIE *Type, bool IsExternal) {
|
||||||
|
// FIXME - Just a prototype.
|
||||||
|
DIE *Variable = Variables[Name];
|
||||||
|
|
||||||
|
// If first occurance of variable.
|
||||||
|
if (!Variable) {
|
||||||
|
assert(IsExternal && "Internal variables not handled yet");
|
||||||
|
Variable = new DIE(DW_TAG_variable, DW_CHILDREN_no);
|
||||||
|
Variable->AddString (DW_AT_name, DW_FORM_string, Name);
|
||||||
|
Variable->AddInt (DW_AT_decl_file, DW_FORM_data1, SourceFileID);
|
||||||
|
Variable->AddInt (DW_AT_decl_line, DW_FORM_data1, Line);
|
||||||
|
Variable->AddDIEntry (DW_AT_type, DW_FORM_ref4, Type);
|
||||||
|
Variable->AddInt (DW_AT_external, DW_FORM_flag, (int)IsExternal);
|
||||||
|
Variable->AddAsIsLabel(DW_AT_location, DW_FORM_block1,
|
||||||
|
std::string("_")+Name+".b");
|
||||||
|
Variable->Complete(DW);
|
||||||
|
|
||||||
|
// Add to context owner.
|
||||||
|
Owner->AddChild(Variable);
|
||||||
|
|
||||||
|
// Add to map.
|
||||||
|
Variables[Name] = Variable;
|
||||||
|
|
||||||
|
// If external add to visible names.
|
||||||
|
if (IsExternal) {
|
||||||
|
DW.NewGlobalEntity(Name, Variable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Variable;
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// PrintHex - Print a value as a hexidecimal value.
|
/// PrintHex - Print a value as a hexidecimal value.
|
||||||
@ -903,20 +1094,29 @@ void DwarfWriter::EmitReference(const char *Tag, unsigned Number) const {
|
|||||||
|
|
||||||
PrintLabelName(Tag, Number);
|
PrintLabelName(Tag, Number);
|
||||||
}
|
}
|
||||||
|
void DwarfWriter::EmitReference(const std::string Name) const {
|
||||||
|
if (AddressSize == 4)
|
||||||
|
O << Asm->Data32bitsDirective;
|
||||||
|
else
|
||||||
|
O << Asm->Data64bitsDirective;
|
||||||
|
|
||||||
|
O << Name;
|
||||||
|
}
|
||||||
|
|
||||||
/// EmitDifference - Emit an label difference as sizeof(pointer) value. Some
|
/// EmitDifference - Emit an label difference as sizeof(pointer) value. Some
|
||||||
/// assemblers do not accept absolute expressions with data directives, so there
|
/// assemblers do not accept absolute expressions with data directives, so there
|
||||||
/// is an option (needsSet) to use an intermediary 'set' expression.
|
/// is an option (needsSet) to use an intermediary 'set' expression.
|
||||||
void DwarfWriter::EmitDifference(const char *Tag1, unsigned Number1,
|
void DwarfWriter::EmitDifference(const char *TagHi, unsigned NumberHi,
|
||||||
const char *Tag2, unsigned Number2) const {
|
const char *TagLo, unsigned NumberLo) const {
|
||||||
if (needsSet) {
|
if (needsSet) {
|
||||||
static unsigned SetCounter = 0;
|
static unsigned SetCounter = 0;
|
||||||
|
|
||||||
O << "\t.set\t";
|
O << "\t.set\t";
|
||||||
PrintLabelName("set", SetCounter);
|
PrintLabelName("set", SetCounter);
|
||||||
O << ",";
|
O << ",";
|
||||||
PrintLabelName(Tag1, Number1);
|
PrintLabelName(TagHi, NumberHi);
|
||||||
O << "-";
|
O << "-";
|
||||||
PrintLabelName(Tag2, Number2);
|
PrintLabelName(TagLo, NumberLo);
|
||||||
O << "\n";
|
O << "\n";
|
||||||
|
|
||||||
if (AddressSize == sizeof(int32_t))
|
if (AddressSize == sizeof(int32_t))
|
||||||
@ -933,40 +1133,58 @@ void DwarfWriter::EmitDifference(const char *Tag1, unsigned Number1,
|
|||||||
else
|
else
|
||||||
O << Asm->Data64bitsDirective;
|
O << Asm->Data64bitsDirective;
|
||||||
|
|
||||||
PrintLabelName(Tag1, Number1);
|
PrintLabelName(TagHi, NumberHi);
|
||||||
O << "-";
|
O << "-";
|
||||||
PrintLabelName(Tag2, Number2);
|
PrintLabelName(TagLo, NumberLo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// NewDIE - Construct a new structured debug information entry.
|
/// NewAbbreviation - Add the abbreviation to the Abbreviation vector.
|
||||||
///
|
///
|
||||||
DIE *DwarfWriter::NewDIE(const unsigned char *AbbrevData) {
|
unsigned DwarfWriter::NewAbbreviation(DIEAbbrev *Abbrev) {
|
||||||
// Get the abbreviation ID.
|
return Abbreviations.insert(*Abbrev);
|
||||||
unsigned AbbrevID = Abbreviations.insert(DIEAbbrev(AbbrevData));
|
}
|
||||||
// Allocate new new structured DIE.
|
|
||||||
DIE *Die = new DIE(AbbrevID);
|
/// NewString - Add a string to the constant pool and returns a label.
|
||||||
// Return structured DIE.
|
///
|
||||||
return Die;
|
DWLabel DwarfWriter::NewString(const std::string &String) {
|
||||||
|
unsigned StringID = StringPool.insert(String);
|
||||||
|
return DWLabel("string", StringID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// NewGlobalType - Make the type visible globally using the given name.
|
||||||
|
///
|
||||||
|
void DwarfWriter::NewGlobalType(const std::string &Name, DIE *Type) {
|
||||||
|
// FIXME - check for duplication.
|
||||||
|
GlobalTypes[Name] = Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// NewGlobalEntity - Make the entity visible globally using the given name.
|
||||||
|
///
|
||||||
|
void DwarfWriter::NewGlobalEntity(const std::string &Name, DIE *Entity) {
|
||||||
|
// FIXME - check for duplication.
|
||||||
|
GlobalEntities[Name] = Entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// NewCompileUnit - Create new compile unit information.
|
/// NewCompileUnit - Create new compile unit information.
|
||||||
///
|
///
|
||||||
DIE *DwarfWriter::NewCompileUnit(const std::string &Directory,
|
DIE *DwarfWriter::NewCompileUnit(const std::string &Directory,
|
||||||
const std::string &SourceName) {
|
const std::string &SourceName) {
|
||||||
DIE *Die = NewDIE(AbbrevTAG_compile_unit);
|
DIE *Unit = new DIE(DW_TAG_compile_unit, DW_CHILDREN_yes);
|
||||||
// FIXME - use the correct line set.
|
// FIXME - use the correct line set.
|
||||||
Die->AddValue(DWLabel("line", 0));
|
Unit->AddLabel (DW_AT_stmt_list, DW_FORM_data4, DWLabel("line", 0));
|
||||||
Die->AddValue(DWLabel("text_end", 0));
|
Unit->AddLabel (DW_AT_high_pc, DW_FORM_addr, DWLabel("text_end", 0));
|
||||||
Die->AddValue(DWLabel("text_begin", 0));
|
Unit->AddLabel (DW_AT_low_pc, DW_FORM_addr, DWLabel("text_begin", 0));
|
||||||
// FIXME - The producer needs to be in this form, but should come from
|
// FIXME - The producer needs to be in this form, but should come from
|
||||||
// an appropriate source.
|
// an appropriate source.
|
||||||
Die->AddValue("llvm 3.4.x (LLVM Research Group)");
|
Unit->AddString(DW_AT_producer, DW_FORM_string,
|
||||||
Die->AddValue(DW_LANG_C89);
|
"llvm 3.4.x (LLVM Research Group)");
|
||||||
Die->AddValue(SourceName);
|
Unit->AddInt (DW_AT_language, DW_FORM_data1, DW_LANG_C89);
|
||||||
Die->AddValue(Directory);
|
Unit->AddString(DW_AT_name, DW_FORM_string, SourceName);
|
||||||
|
Unit->AddString(DW_AT_comp_dir, DW_FORM_string, Directory);
|
||||||
|
Unit->Complete(*this);
|
||||||
|
|
||||||
return Die;
|
return Unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EmitInitial - Emit initial Dwarf declarations. This is necessary for cc
|
/// EmitInitial - Emit initial Dwarf declarations. This is necessary for cc
|
||||||
@ -1003,11 +1221,12 @@ void DwarfWriter::EmitDIE(DIE *Die) const {
|
|||||||
" ");
|
" ");
|
||||||
|
|
||||||
const std::vector<DIEValue *> &Values = Die->getValues();
|
const std::vector<DIEValue *> &Values = Die->getValues();
|
||||||
|
const std::vector<DIEAbbrevData> &AbbrevData = Abbrev.getData();
|
||||||
|
|
||||||
// Emit the DIE attribute values.
|
// Emit the DIE attribute values.
|
||||||
for (unsigned i = 0, N = Values.size(); i < N; i++) {
|
for (unsigned i = 0, N = Values.size(); i < N; i++) {
|
||||||
unsigned Attr = Abbrev.getAttribute(i);
|
unsigned Attr = AbbrevData[i].getAttribute();
|
||||||
unsigned Form = Abbrev.getForm(i);
|
unsigned Form = AbbrevData[i].getForm();
|
||||||
assert(Form && "Too many attributes for DIE (check abbreviation)");
|
assert(Form && "Too many attributes for DIE (check abbreviation)");
|
||||||
|
|
||||||
switch (Attr) {
|
switch (Attr) {
|
||||||
@ -1053,11 +1272,12 @@ unsigned DwarfWriter::SizeAndOffsetDie(DIE *Die, unsigned Offset) const {
|
|||||||
Offset += SizeULEB128(AbbrevID);
|
Offset += SizeULEB128(AbbrevID);
|
||||||
|
|
||||||
const std::vector<DIEValue *> &Values = Die->getValues();
|
const std::vector<DIEValue *> &Values = Die->getValues();
|
||||||
|
const std::vector<DIEAbbrevData> &AbbrevData = Abbrev.getData();
|
||||||
|
|
||||||
// Emit the DIE attribute values.
|
// Emit the DIE attribute values.
|
||||||
for (unsigned i = 0, N = Values.size(); i < N; i++) {
|
for (unsigned i = 0, N = Values.size(); i < N; i++) {
|
||||||
// Size attribute value.
|
// Size attribute value.
|
||||||
Offset += Values[i]->SizeOf(*this, Abbrev.getForm(i));
|
Offset += Values[i]->SizeOf(*this, AbbrevData[i].getForm());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit the DIE children if any.
|
// Emit the DIE children if any.
|
||||||
@ -1085,7 +1305,7 @@ void DwarfWriter::SizeAndOffsets() {
|
|||||||
unsigned Offset = sizeof(int32_t) + // Length of Compilation Unit Info
|
unsigned Offset = sizeof(int32_t) + // Length of Compilation Unit Info
|
||||||
sizeof(int16_t) + // DWARF version number
|
sizeof(int16_t) + // DWARF version number
|
||||||
sizeof(int32_t) + // Offset Into Abbrev. Section
|
sizeof(int32_t) + // Offset Into Abbrev. Section
|
||||||
sizeof(int8_t); // Pointer Size (in bytes)
|
sizeof(int8_t); // Pointer Size (in bytes)
|
||||||
|
|
||||||
// Process each compile unit.
|
// Process each compile unit.
|
||||||
for (unsigned i = 0, N = CompileUnits.size(); i < N; i++) {
|
for (unsigned i = 0, N = CompileUnits.size(); i < N; i++) {
|
||||||
@ -1104,6 +1324,8 @@ void DwarfWriter::EmitDebugInfo() const {
|
|||||||
|
|
||||||
// If there are any compile units.
|
// If there are any compile units.
|
||||||
if (N) {
|
if (N) {
|
||||||
|
EmitLabel("info_begin", 0);
|
||||||
|
|
||||||
// Emit the compile units header.
|
// Emit the compile units header.
|
||||||
|
|
||||||
// Emit size of content not including length itself
|
// Emit size of content not including length itself
|
||||||
@ -1113,7 +1335,7 @@ void DwarfWriter::EmitDebugInfo() const {
|
|||||||
|
|
||||||
EmitShort(DWARF_VERSION); EOL("DWARF version number");
|
EmitShort(DWARF_VERSION); EOL("DWARF version number");
|
||||||
|
|
||||||
EmitReference("abbrev", 0); EOL("Offset Into Abbrev. Section");
|
EmitReference("abbrev_begin", 0); EOL("Offset Into Abbrev. Section");
|
||||||
|
|
||||||
EmitByte(AddressSize); EOL("Address Size (in bytes)");
|
EmitByte(AddressSize); EOL("Address Size (in bytes)");
|
||||||
|
|
||||||
@ -1121,52 +1343,35 @@ void DwarfWriter::EmitDebugInfo() const {
|
|||||||
for (unsigned i = 0; i < N; i++) {
|
for (unsigned i = 0; i < N; i++) {
|
||||||
EmitDIE(CompileUnits[i]);
|
EmitDIE(CompileUnits[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EmitLabel("info_end", 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EmitAbbreviations - Emit the abbreviation section.
|
/// EmitAbbreviations - Emit the abbreviation section.
|
||||||
///
|
///
|
||||||
void DwarfWriter::EmitAbbreviations() const {
|
void DwarfWriter::EmitAbbreviations() const {
|
||||||
// Start the debug abbrev section.
|
// Check to see if it is worth the effort.
|
||||||
Asm->SwitchSection(DwarfAbbrevSection, 0);
|
if (!Abbreviations.empty()) {
|
||||||
|
// Start the debug abbrev section.
|
||||||
// For each abbrevation.
|
Asm->SwitchSection(DwarfAbbrevSection, 0);
|
||||||
for (unsigned AbbrevID = 1, NAID = Abbreviations.size();
|
|
||||||
AbbrevID <= NAID; AbbrevID++) {
|
|
||||||
// Get abbreviation data
|
|
||||||
const DIEAbbrev &Abbrev = Abbreviations[AbbrevID];
|
|
||||||
|
|
||||||
// Emit the abbrevations code (base 1 index.)
|
EmitLabel("abbrev_begin", 0);
|
||||||
EmitULEB128Bytes(AbbrevID); EOL("Abbreviation Code");
|
|
||||||
|
|
||||||
// Emit its Dwarf tag type.
|
// For each abbrevation.
|
||||||
EmitULEB128Bytes(Abbrev.getTag());
|
for (unsigned AbbrevID = 1, NAID = Abbreviations.size();
|
||||||
EOL(TagString(Abbrev.getTag()));
|
AbbrevID <= NAID; AbbrevID++) {
|
||||||
|
// Get abbreviation data
|
||||||
// Emit whether it has children DIEs.
|
const DIEAbbrev &Abbrev = Abbreviations[AbbrevID];
|
||||||
EmitULEB128Bytes(Abbrev.getChildrenFlag());
|
|
||||||
EOL(ChildrenString(Abbrev.getChildrenFlag()));
|
|
||||||
|
|
||||||
// For each attribute description.
|
|
||||||
for (unsigned i = 0; ; i++) {
|
|
||||||
unsigned Attr = Abbrev.getAttribute(i);
|
|
||||||
unsigned Form = Abbrev.getForm(i);
|
|
||||||
|
|
||||||
// Attributes are null terminated.
|
// Emit the abbrevations code (base 1 index.)
|
||||||
if (!Attr) break;
|
EmitULEB128Bytes(AbbrevID); EOL("Abbreviation Code");
|
||||||
|
|
||||||
// Emit attribute type.
|
// Emit the abbreviations data.
|
||||||
EmitULEB128Bytes(Attr);
|
Abbrev.Emit(*this);
|
||||||
EOL(AttributeString(Attr));
|
|
||||||
|
|
||||||
// Emit form type.
|
|
||||||
EmitULEB128Bytes(Form);
|
|
||||||
EOL(FormEncodingString(Form));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark end of abbreviation.
|
EmitLabel("abbrev_end", 0);
|
||||||
EmitULEB128Bytes(0); EOL("EOM(1)");
|
|
||||||
EmitULEB128Bytes(0); EOL("EOM(2)");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1303,22 +1508,67 @@ void DwarfWriter::EmitDebugFrame() {
|
|||||||
/// EmitDebugPubNames - Emit visible names into a debug pubnames section.
|
/// EmitDebugPubNames - Emit visible names into a debug pubnames section.
|
||||||
///
|
///
|
||||||
void DwarfWriter::EmitDebugPubNames() {
|
void DwarfWriter::EmitDebugPubNames() {
|
||||||
// Start the dwarf pubnames section.
|
// Check to see if it is worth the effort.
|
||||||
Asm->SwitchSection(DwarfPubNamesSection, 0);
|
if (!GlobalEntities.empty()) {
|
||||||
|
// Start the dwarf pubnames section.
|
||||||
|
Asm->SwitchSection(DwarfPubNamesSection, 0);
|
||||||
|
|
||||||
|
EmitDifference("pubnames_end", 0, "pubnames_begin", 0);
|
||||||
|
EOL("Length of Public Names Info");
|
||||||
|
|
||||||
|
EmitLabel("pubnames_begin", 0);
|
||||||
|
|
||||||
|
EmitShort(DWARF_VERSION); EOL("DWARF Version");
|
||||||
|
|
||||||
|
EmitReference("info_begin", 0); EOL("Offset of Compilation Unit Info");
|
||||||
|
|
||||||
|
EmitDifference("info_end", 0, "info_begin", 0);
|
||||||
|
EOL("Compilation Unit Length");
|
||||||
|
|
||||||
|
for (std::map<std::string, DIE *>::iterator G = GlobalTypes.begin(),
|
||||||
|
GE = GlobalTypes.begin();
|
||||||
|
G != GE; G++) {
|
||||||
|
const std::string &Name = (*G).first;
|
||||||
|
DIE * Entity = (*G).second;
|
||||||
|
|
||||||
|
EmitLong(Entity->getOffset()); EOL("DIE offset");
|
||||||
|
EmitString(Name); EOL("External Name");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
EmitLong(0); EOL("End Mark");
|
||||||
|
EmitLabel("pubnames_end", 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EmitDebugPubTypes - Emit visible names into a debug pubtypes section.
|
/// EmitDebugPubTypes - Emit visible names into a debug pubtypes section.
|
||||||
///
|
///
|
||||||
void DwarfWriter::EmitDebugPubTypes() {
|
void DwarfWriter::EmitDebugPubTypes() {
|
||||||
// Start the dwarf pubtypes section.
|
// Check to see if it is worth the effort.
|
||||||
Asm->SwitchSection(DwarfPubTypesSection, 0);
|
if (!GlobalTypes.empty()) {
|
||||||
|
// Start the dwarf pubtypes section.
|
||||||
|
Asm->SwitchSection(DwarfPubTypesSection, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EmitDebugStr - Emit visible names into a debug str section.
|
/// EmitDebugStr - Emit visible names into a debug str section.
|
||||||
///
|
///
|
||||||
void DwarfWriter::EmitDebugStr() {
|
void DwarfWriter::EmitDebugStr() {
|
||||||
// Start the dwarf str section.
|
// Check to see if it is worth the effort.
|
||||||
Asm->SwitchSection(DwarfStrSection, 0);
|
if (!StringPool.empty()) {
|
||||||
|
// Start the dwarf str section.
|
||||||
|
Asm->SwitchSection(DwarfStrSection, 0);
|
||||||
|
|
||||||
|
// For each of strings in teh string pool.
|
||||||
|
for (unsigned StringID = 1, N = StringPool.size();
|
||||||
|
StringID <= N; StringID++) {
|
||||||
|
// Emit a label for reference from debug information entries.
|
||||||
|
EmitLabel("string", StringID);
|
||||||
|
// Emit the string itself.
|
||||||
|
const std::string &String = StringPool[StringID];
|
||||||
|
EmitString(String); O << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EmitDebugLoc - Emit visible names into a debug loc section.
|
/// EmitDebugLoc - Emit visible names into a debug loc section.
|
||||||
@ -1341,7 +1591,7 @@ void DwarfWriter::EmitDebugARanges() {
|
|||||||
|
|
||||||
EmitShort(DWARF_VERSION); EOL("Dwarf Version");
|
EmitShort(DWARF_VERSION); EOL("Dwarf Version");
|
||||||
|
|
||||||
EmitReference("info", 0); EOL("Offset of Compilation Unit Info");
|
EmitReference("info_begin", 0); EOL("Offset of Compilation Unit Info");
|
||||||
|
|
||||||
EmitByte(AddressSize); EOL("Size of Address");
|
EmitByte(AddressSize); EOL("Size of Address");
|
||||||
|
|
||||||
@ -1389,7 +1639,7 @@ bool DwarfWriter::ShouldEmitDwarf() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Main enties.
|
// Main entry points.
|
||||||
//
|
//
|
||||||
|
|
||||||
DwarfWriter::DwarfWriter(std::ostream &o, AsmPrinter *ap)
|
DwarfWriter::DwarfWriter(std::ostream &o, AsmPrinter *ap)
|
||||||
@ -1399,6 +1649,9 @@ bool DwarfWriter::ShouldEmitDwarf() {
|
|||||||
, didInitial(false)
|
, didInitial(false)
|
||||||
, CompileUnits()
|
, CompileUnits()
|
||||||
, Abbreviations()
|
, Abbreviations()
|
||||||
|
, GlobalTypes()
|
||||||
|
, GlobalEntities()
|
||||||
|
, StringPool()
|
||||||
, AddressSize(sizeof(int32_t))
|
, AddressSize(sizeof(int32_t))
|
||||||
, hasLEB128(false)
|
, hasLEB128(false)
|
||||||
, hasDotLoc(false)
|
, hasDotLoc(false)
|
||||||
@ -1419,6 +1672,9 @@ bool DwarfWriter::ShouldEmitDwarf() {
|
|||||||
, DataSection(".data")
|
, DataSection(".data")
|
||||||
{}
|
{}
|
||||||
DwarfWriter::~DwarfWriter() {
|
DwarfWriter::~DwarfWriter() {
|
||||||
|
for (unsigned i = 0, N = CompileUnits.size(); i < N; i++) {
|
||||||
|
delete CompileUnits[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// BeginModule - Emit all Dwarf sections that should come prior to the content.
|
/// BeginModule - Emit all Dwarf sections that should come prior to the content.
|
||||||
@ -1439,7 +1695,7 @@ void DwarfWriter::EndModule() {
|
|||||||
EmitLabel("text_end", 0);
|
EmitLabel("text_end", 0);
|
||||||
Asm->SwitchSection(DataSection, 0);
|
Asm->SwitchSection(DataSection, 0);
|
||||||
EmitLabel("data_end", 0);
|
EmitLabel("data_end", 0);
|
||||||
|
|
||||||
// Get directory and source information.
|
// Get directory and source information.
|
||||||
const UniqueVector<std::string> &Directories = DebugInfo->getDirectories();
|
const UniqueVector<std::string> &Directories = DebugInfo->getDirectories();
|
||||||
const UniqueVector<SourceFileInfo> &SourceFiles = DebugInfo->getSourceFiles();
|
const UniqueVector<SourceFileInfo> &SourceFiles = DebugInfo->getSourceFiles();
|
||||||
@ -1450,8 +1706,16 @@ void DwarfWriter::EndModule() {
|
|||||||
const SourceFileInfo &SourceFile = SourceFiles[SourceID];
|
const SourceFileInfo &SourceFile = SourceFiles[SourceID];
|
||||||
const std::string &Directory = Directories[SourceFile.getDirectoryID()];
|
const std::string &Directory = Directories[SourceFile.getDirectoryID()];
|
||||||
const std::string &SourceName = SourceFile.getName();
|
const std::string &SourceName = SourceFile.getName();
|
||||||
DIE *CompileUnit = NewCompileUnit(Directory, SourceName);
|
DIE *Unit = NewCompileUnit(Directory, SourceName);
|
||||||
CompileUnits.push_back(CompileUnit);
|
|
||||||
|
#if 0
|
||||||
|
// FIXME - just testing.
|
||||||
|
DWContext *Context = new DWContext(*this, Unit);
|
||||||
|
DIE *TypeInt = Context->NewBasicType("int", sizeof(int32_t), DW_ATE_signed);
|
||||||
|
Context->NewVariable("MyGlobal", SourceID, 1, TypeInt, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CompileUnits.push_back(Unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute DIE offsets and sizes.
|
// Compute DIE offsets and sizes.
|
||||||
|
Loading…
Reference in New Issue
Block a user