diff options
author | Bill Wendling <isanbard@gmail.com> | 2009-05-15 00:11:17 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2009-05-15 00:11:17 +0000 |
commit | 88423eecd0f16d3cfa89bdf92abdb72a5dc0616a (patch) | |
tree | 14a131cd9d6a504192d16f8c7274f6353c197c2c /lib/CodeGen/AsmPrinter/DwarfWriter.cpp | |
parent | 5f00b0c5b63c30c7ad6134543318551902de5c93 (diff) |
Split out the Dwarf writer stuff into separate files. This is a much more
logical/sane approach to organizing all of the stuff that goes into writing out
DWARF information. Honestly? even this is too complex for what it's supposed to
be doing.
Trivia: It *looks* like there would be functionality changes, however there aren't!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71821 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/AsmPrinter/DwarfWriter.cpp')
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfWriter.cpp | 1316 |
1 files changed, 38 insertions, 1278 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp index c77a7537cb..83275fb92e 100644 --- a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp @@ -12,6 +12,8 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/DwarfWriter.h" +#include "DIE.h" +#include "DwarfPrinter.h" #include "llvm/Module.h" #include "llvm/DerivedTypes.h" #include "llvm/Constants.h" @@ -64,633 +66,6 @@ static const unsigned InitAbbreviationsSetSize = 9; // log2(512) static const unsigned InitValuesSetSize = 9; // log2(512) //===----------------------------------------------------------------------===// -/// Forward declarations. -/// -class DIE; -class DIEValue; - -//===----------------------------------------------------------------------===// -/// DWLabel - Labels are used to track locations in the assembler file. -/// Labels appear in the form @verbatim <prefix><Tag><Number> @endverbatim, -/// where the tag is a category of label (Ex. location) and number is a value -/// unique in that category. -class DWLabel { -public: - /// Tag - Label category tag. Should always be a staticly declared C string. - /// - const char *Tag; - - /// Number - Value to make label unique. - /// - unsigned Number; - - DWLabel(const char *T, unsigned N) : Tag(T), Number(N) {} - - void Profile(FoldingSetNodeID &ID) const { - ID.AddString(Tag); - ID.AddInteger(Number); - } - -#ifndef NDEBUG - void print(std::ostream *O) const { - if (O) print(*O); - } - void print(std::ostream &O) const { - O << "." << Tag; - if (Number) O << Number; - } -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIEAbbrevData - Dwarf abbreviation data, describes the one attribute of a -/// Dwarf abbreviation. -class DIEAbbrevData { - /// Attribute - Dwarf attribute code. - /// - unsigned Attribute; - - /// Form - Dwarf form code. - /// - unsigned Form; -public: - DIEAbbrevData(unsigned A, unsigned F) : Attribute(A), Form(F) {} - - // Accessors. - unsigned getAttribute() const { return Attribute; } - unsigned getForm() const { return Form; } - - /// Profile - Used to gather unique data for the abbreviation folding set. - /// - void Profile(FoldingSetNodeID &ID)const { - ID.AddInteger(Attribute); - ID.AddInteger(Form); - } -}; - -//===----------------------------------------------------------------------===// -/// DIEAbbrev - Dwarf abbreviation, describes the organization of a debug -/// information object. -class DIEAbbrev : public FoldingSetNode { -private: - /// Tag - Dwarf tag code. - /// - unsigned Tag; - - /// Unique number for node. - /// - unsigned Number; - - /// ChildrenFlag - Dwarf children flag. - /// - unsigned ChildrenFlag; - - /// Data - Raw data bytes for abbreviation. - /// - SmallVector<DIEAbbrevData, 8> Data; -public: - DIEAbbrev(unsigned T, unsigned C) : Tag(T), ChildrenFlag(C), Data() {} - virtual ~DIEAbbrev() {} - - // Accessors. - unsigned getTag() const { return Tag; } - unsigned getNumber() const { return Number; } - unsigned getChildrenFlag() const { return ChildrenFlag; } - const SmallVector<DIEAbbrevData, 8> &getData() const { return Data; } - void setTag(unsigned T) { Tag = T; } - void setChildrenFlag(unsigned CF) { ChildrenFlag = CF; } - void setNumber(unsigned N) { Number = N; } - - /// AddAttribute - Adds another set of attribute information to the - /// abbreviation. - void AddAttribute(unsigned Attribute, unsigned Form) { - Data.push_back(DIEAbbrevData(Attribute, Form)); - } - - /// AddFirstAttribute - Adds a set of attribute information to the front - /// of the abbreviation. - void AddFirstAttribute(unsigned Attribute, unsigned Form) { - Data.insert(Data.begin(), DIEAbbrevData(Attribute, Form)); - } - - /// Profile - Used to gather unique data for the abbreviation folding set. - /// - void Profile(FoldingSetNodeID &ID) { - ID.AddInteger(Tag); - ID.AddInteger(ChildrenFlag); - - // For each attribute description. - for (unsigned i = 0, N = Data.size(); i < N; ++i) - Data[i].Profile(ID); - } - - /// Emit - Print the abbreviation using the specified Dwarf writer. - /// - void Emit(const DwarfDebug &DD) const; - -#ifndef NDEBUG - void print(std::ostream *O) { - if (O) print(*O); - } - void print(std::ostream &O); - void dump(); -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIE - A structured debug information entry. Has an abbreviation which -/// describes it's organization. -class CompileUnit; -class DIE : public FoldingSetNode { -protected: - /// Abbrev - Buffer for constructing abbreviation. - /// - DIEAbbrev Abbrev; - - /// Offset - Offset in debug info section. - /// - unsigned Offset; - - /// Size - Size of instance + children. - /// - unsigned Size; - - /// Children DIEs. - /// - std::vector<DIE *> Children; - - /// Attributes values. - /// - SmallVector<DIEValue*, 32> Values; - - /// Abstract compile unit. - CompileUnit *AbstractCU; -public: - explicit DIE(unsigned Tag) - : Abbrev(Tag, DW_CHILDREN_no), Offset(0), Size(0) {} - virtual ~DIE(); - - // Accessors. - DIEAbbrev &getAbbrev() { return Abbrev; } - unsigned getAbbrevNumber() const { - return Abbrev.getNumber(); - } - unsigned getTag() const { return Abbrev.getTag(); } - unsigned getOffset() const { return Offset; } - unsigned getSize() const { return Size; } - const std::vector<DIE *> &getChildren() const { return Children; } - SmallVector<DIEValue*, 32> &getValues() { return Values; } - CompileUnit *getAbstractCompileUnit() const { return AbstractCU; } - - void setTag(unsigned Tag) { Abbrev.setTag(Tag); } - void setOffset(unsigned O) { Offset = O; } - void setSize(unsigned S) { Size = S; } - void setAbstractCompileUnit(CompileUnit *CU) { AbstractCU = CU; } - - /// AddValue - Add a value and attributes to a DIE. - /// - void AddValue(unsigned Attribute, unsigned Form, DIEValue *Value) { - Abbrev.AddAttribute(Attribute, Form); - Values.push_back(Value); - } - - /// SiblingOffset - Return the offset of the debug information entry's - /// sibling. - unsigned SiblingOffset() const { return Offset + Size; } - - /// AddSiblingOffset - Add a sibling offset field to the front of the DIE. - /// - void AddSiblingOffset(); - - /// AddChild - Add a child to the DIE. - /// - void AddChild(DIE *Child) { - Abbrev.setChildrenFlag(DW_CHILDREN_yes); - Children.push_back(Child); - } - - /// Detach - Detaches objects connected to it after copying. - /// - void Detach() { - Children.clear(); - } - - /// Profile - Used to gather unique data for the value folding set. - /// - void Profile(FoldingSetNodeID &ID) ; - -#ifndef NDEBUG - void print(std::ostream *O, unsigned IncIndent = 0) { - if (O) print(*O, IncIndent); - } - void print(std::ostream &O, unsigned IncIndent = 0); - void dump(); -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIEValue - A debug information entry value. -/// -class DIEValue : public FoldingSetNode { -public: - enum { - isInteger, - isString, - isLabel, - isAsIsLabel, - isSectionOffset, - isDelta, - isEntry, - isBlock - }; - - /// Type - Type of data stored in the value. - /// - unsigned Type; - - explicit DIEValue(unsigned T) : Type(T) {} - virtual ~DIEValue() {} - - // Accessors - unsigned getType() const { return Type; } - - // Implement isa/cast/dyncast. - static bool classof(const DIEValue *) { return true; } - - /// EmitValue - Emit value via the Dwarf writer. - /// - virtual void EmitValue(DwarfDebug &DD, unsigned Form) = 0; - - /// SizeOf - Return the size of a value in bytes. - /// - virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const = 0; - - /// Profile - Used to gather unique data for the value folding set. - /// - virtual void Profile(FoldingSetNodeID &ID) = 0; - -#ifndef NDEBUG - void print(std::ostream *O) { - if (O) print(*O); - } - virtual void print(std::ostream &O) = 0; - void dump(); -#endif -}; - -//===----------------------------------------------------------------------===// -/// DWInteger - An integer value DIE. -/// -class DIEInteger : public DIEValue { -private: - uint64_t Integer; - -public: - explicit DIEInteger(uint64_t I) : DIEValue(isInteger), Integer(I) {} - - // Implement isa/cast/dyncast. - static bool classof(const DIEInteger *) { return true; } - static bool classof(const DIEValue *I) { return I->Type == isInteger; } - - /// BestForm - Choose the best form for integer. - /// - static unsigned BestForm(bool IsSigned, uint64_t Integer) { - if (IsSigned) { - if ((char)Integer == (signed)Integer) return DW_FORM_data1; - if ((short)Integer == (signed)Integer) return DW_FORM_data2; - if ((int)Integer == (signed)Integer) return DW_FORM_data4; - } else { - if ((unsigned char)Integer == Integer) return DW_FORM_data1; - if ((unsigned short)Integer == Integer) return DW_FORM_data2; - if ((unsigned int)Integer == Integer) return DW_FORM_data4; - } - return DW_FORM_data8; - } - - /// EmitValue - Emit integer of appropriate size. - /// - virtual void EmitValue(DwarfDebug &DD, unsigned Form); - - /// SizeOf - Determine size of integer value in bytes. - /// - virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const; - - /// Profile - Used to gather unique data for the value folding set. - /// - static void Profile(FoldingSetNodeID &ID, unsigned Integer) { - ID.AddInteger(isInteger); - ID.AddInteger(Integer); - } - virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, Integer); } - -#ifndef NDEBUG - virtual void print(std::ostream &O) { - O << "Int: " << (int64_t)Integer - << " 0x" << std::hex << Integer << std::dec; - } -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIEString - A string value DIE. -/// -class DIEString : public DIEValue { - const std::string Str; -public: - explicit DIEString(const std::string &S) : DIEValue(isString), Str(S) {} - - // Implement isa/cast/dyncast. - static bool classof(const DIEString *) { return true; } - static bool classof(const DIEValue *S) { return S->Type == isString; } - - /// EmitValue - Emit string value. - /// - virtual void EmitValue(DwarfDebug &DD, unsigned Form); - - /// SizeOf - Determine size of string value in bytes. - /// - virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const { - return Str.size() + sizeof(char); // sizeof('\0'); - } - - /// Profile - Used to gather unique data for the value folding set. - /// - static void Profile(FoldingSetNodeID &ID, const std::string &Str) { - ID.AddInteger(isString); - ID.AddString(Str); - } - virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, Str); } - -#ifndef NDEBUG - virtual void print(std::ostream &O) { - O << "Str: \"" << Str << "\""; - } -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIEDwarfLabel - A Dwarf internal label expression DIE. -// -class DIEDwarfLabel : public DIEValue { - const DWLabel Label; -public: - explicit DIEDwarfLabel(const DWLabel &L) : DIEValue(isLabel), Label(L) {} - - // Implement isa/cast/dyncast. - static bool classof(const DIEDwarfLabel *) { return true; } - static bool classof(const DIEValue *L) { return L->Type == isLabel; } - - /// EmitValue - Emit label value. - /// - virtual void EmitValue(DwarfDebug &DD, unsigned Form); - - /// SizeOf - Determine size of label value in bytes. - /// - virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const; - - /// Profile - Used to gather unique data for the value folding set. - /// - static void Profile(FoldingSetNodeID &ID, const DWLabel &Label) { - ID.AddInteger(isLabel); - Label.Profile(ID); - } - virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, Label); } - -#ifndef NDEBUG - virtual void print(std::ostream &O) { - O << "Lbl: "; - Label.print(O); - } -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIEObjectLabel - A label to an object in code or data. -// -class DIEObjectLabel : public DIEValue { - const std::string Label; -public: - explicit DIEObjectLabel(const std::string &L) - : DIEValue(isAsIsLabel), Label(L) {} - - // Implement isa/cast/dyncast. - static bool classof(const DIEObjectLabel *) { return true; } - static bool classof(const DIEValue *L) { return L->Type == isAsIsLabel; } - - /// EmitValue - Emit label value. - /// - virtual void EmitValue(DwarfDebug &DD, unsigned Form); - - /// SizeOf - Determine size of label value in bytes. - /// - virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const; - - /// Profile - Used to gather unique data for the value folding set. - /// - static void Profile(FoldingSetNodeID &ID, const std::string &Label) { - ID.AddInteger(isAsIsLabel); - ID.AddString(Label); - } - virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, Label.c_str()); } - -#ifndef NDEBUG - virtual void print(std::ostream &O) { - O << "Obj: " << Label; - } -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIESectionOffset - A section offset DIE. -// -class DIESectionOffset : public DIEValue { - const DWLabel Label; - const DWLabel Section; - bool IsEH : 1; - bool UseSet : 1; -public: - DIESectionOffset(const DWLabel &Lab, const DWLabel &Sec, - bool isEH = false, bool useSet = true) - : DIEValue(isSectionOffset), Label(Lab), Section(Sec), - IsEH(isEH), UseSet(useSet) {} - - // Implement isa/cast/dyncast. - static bool classof(const DIESectionOffset *) { return true; } - static bool classof(const DIEValue *D) { return D->Type == isSectionOffset; } - - /// EmitValue - Emit section offset. - /// - virtual void EmitValue(DwarfDebug &DD, unsigned Form); - - /// SizeOf - Determine size of section offset value in bytes. - /// - virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const; - - /// Profile - Used to gather unique data for the value folding set. - /// - static void Profile(FoldingSetNodeID &ID, const DWLabel &Label, - const DWLabel &Section) { - ID.AddInteger(isSectionOffset); - Label.Profile(ID); - Section.Profile(ID); - // IsEH and UseSet are specific to the Label/Section that we will emit - // the offset for; so Label/Section are enough for uniqueness. - } - virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, Label, Section); } - -#ifndef NDEBUG - virtual void print(std::ostream &O) { - O << "Off: "; - Label.print(O); - O << "-"; - Section.print(O); - O << "-" << IsEH << "-" << UseSet; - } -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIEDelta - A simple label difference DIE. -/// -class DIEDelta : public DIEValue { - const DWLabel LabelHi; - const DWLabel LabelLo; -public: - DIEDelta(const DWLabel &Hi, const DWLabel &Lo) - : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {} - - // Implement isa/cast/dyncast. - static bool classof(const DIEDelta *) { return true; } - static bool classof(const DIEValue *D) { return D->Type == isDelta; } - - /// EmitValue - Emit delta value. - /// - virtual void EmitValue(DwarfDebug &DD, unsigned Form); - - /// SizeOf - Determine size of delta value in bytes. - /// - virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const; - - /// Profile - Used to gather unique data for the value folding set. - /// - static void Profile(FoldingSetNodeID &ID, const DWLabel &LabelHi, - const DWLabel &LabelLo) { - ID.AddInteger(isDelta); - LabelHi.Profile(ID); - LabelLo.Profile(ID); - } - virtual void Profile(FoldingSetNodeID &ID) { Profile(ID, LabelHi, LabelLo); } - -#ifndef NDEBUG - virtual void print(std::ostream &O) { - O << "Del: "; - LabelHi.print(O); - O << "-"; - LabelLo.print(O); - } -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIEntry - A pointer to another debug information entry. An instance of this -/// class can also be used as a proxy for a debug information entry not yet -/// defined (ie. types.) -class DIEntry : public DIEValue { - DIE *Entry; -public: - explicit DIEntry(DIE *E) : DIEValue(isEntry), Entry(E) {} - - DIE *getEntry() const { return Entry; } - void setEntry(DIE *E) { Entry = E; } - - // Implement isa/cast/dyncast. - static bool classof(const DIEntry *) { return true; } - static bool classof(const DIEValue *E) { return E->Type == isEntry; } - - /// EmitValue - Emit debug information entry offset. - /// - virtual void EmitValue(DwarfDebug &DD, unsigned Form); - - /// SizeOf - Determine size of debug information entry in bytes. - /// - virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const { - return sizeof(int32_t); - } - - /// Profile - Used to gather unique data for the value folding set. - /// - static void Profile(FoldingSetNodeID &ID, DIE *Entry) { - ID.AddInteger(isEntry); - ID.AddPointer(Entry); - } - virtual void Profile(FoldingSetNodeID &ID) { - ID.AddInteger(isEntry); - - if (Entry) { - ID.AddPointer(Entry); - } else { - ID.AddPointer(this); - } - } - -#ifndef NDEBUG - virtual void print(std::ostream &O) { - O << "Die: 0x" << std::hex << (intptr_t)Entry << std::dec; - } -#endif -}; - -//===----------------------------------------------------------------------===// -/// DIEBlock - A block of values. Primarily used for location expressions. -// -class DIEBlock : public DIEValue, public DIE { - unsigned Size; // Size in bytes excluding size header. -public: - DIEBlock() - : DIEValue(isBlock), DIE(0), Size(0) {} - virtual ~DIEBlock() {} - - // Implement isa/cast/dyncast. - static bool classof(const DIEBlock *) { return true; } - static bool classof(const DIEValue *E) { return E->Type == isBlock; } - - /// ComputeSize - calculate the size of the block. - /// - unsigned ComputeSize(DwarfDebug &DD); - - /// BestForm - Choose the best form for data. - /// - unsigned BestForm() const { - if ((unsigned char)Size == Size) return DW_FORM_block1; - if ((unsigned short)Size == Size) return DW_FORM_block2; - if ((unsigned int)Size == Size) return DW_FORM_block4; - return DW_FORM_block; - } - - /// EmitValue - Emit block data. - /// - virtual void EmitValue(DwarfDebug &DD, unsigned Form); - - /// SizeOf - Determine size of block data in bytes. - /// - virtual unsigned SizeOf(const DwarfDebug &DD, unsigned Form) const; - - /// Profile - Used to gather unique data for the value folding set. - /// - virtual void Profile(FoldingSetNodeID &ID) { - ID.AddInteger(isBlock); - DIE::Profile(ID); - } - -#ifndef NDEBUG - virtual void print(std::ostream &O) { - O << "Blk: "; - DIE::print(O, 5); - } -#endif -}; - -//===----------------------------------------------------------------------===// /// CompileUnit - This dwarf writer support class manages information associate /// with a source file. class CompileUnit { @@ -706,9 +81,9 @@ class CompileUnit { /// variables to debug information entries. std::map<GlobalVariable *, DIE *> GVToDieMap; - /// GVToDIEntryMap - Tracks the mapping of unit level debug informaton - /// descriptors to debug information entries using a DIEntry proxy. - std::map<GlobalVariable *, DIEntry *> GVToDIEntryMap; + /// GVToDIEEntryMap - Tracks the mapping of unit level debug informaton + /// descriptors to debug information entries using a DIEEntry proxy. + std::map<GlobalVariable *, DIEEntry *> GVToDIEEntryMap; /// Globals - A map of globally visible named entities for this unit. /// @@ -720,7 +95,7 @@ class CompileUnit { public: CompileUnit(unsigned I, DIE *D) : ID(I), Die(D), GVToDieMap(), - GVToDIEntryMap(), Globals(), DiesSet(InitDiesSetSize) + GVToDIEEntryMap(), Globals(), DiesSet(InitDiesSetSize) {} ~CompileUnit() { @@ -750,10 +125,10 @@ public: return GVToDieMap[GV]; } - /// getDIEntrySlotFor - Returns the debug information entry proxy slot for the + /// getDIEEntrySlotFor - Returns the debug information entry proxy slot for the /// specified debug variable. - DIEntry *&getDIEntrySlotFor(GlobalVariable *GV) { - return GVToDIEntryMap[GV]; + DIEEntry *&getDIEEntrySlotFor(GlobalVariable *GV) { + return GVToDIEEntryMap[GV]; } /// AddDie - Adds or interns the DIE to the compile unit. @@ -776,315 +151,13 @@ public: }; //===----------------------------------------------------------------------===// -/// Dwarf - Emits general Dwarf directives. -/// -class Dwarf { -protected: - //===--------------------------------------------------------------------===// - // Core attributes used by the Dwarf writer. - // - - // - /// O - Stream to .s file. - /// - raw_ostream &O; - - /// Asm - Target of Dwarf emission. - /// - AsmPrinter *Asm; - - /// TAI - Target asm information. - const TargetAsmInfo *TAI; - - /// TD - Target data. - const TargetData *TD; - - /// RI - Register Information. - const TargetRegisterInfo *RI; - - /// M - Current module. - /// - Module *M; - - /// MF - Current machine function. - /// - MachineFunction *MF; - - /// MMI - Collected machine module information. - /// - MachineModuleInfo *MMI; - - /// SubprogramCount - The running count of functions being compiled. - /// - unsigned SubprogramCount; - - /// Flavor - A unique string indicating what dwarf producer this is, used to - /// unique labels. - const char * const Flavor; - - unsigned SetCounter; - Dwarf(raw_ostream &OS, AsmPrinter *A, const TargetAsmInfo *T, - const char *flavor) - : O(OS) - , Asm(A) - , TAI(T) - , TD(Asm->TM.getTargetData()) - , RI(Asm->TM.getRegisterInfo()) - , M(NULL) - , MF(NULL) - , MMI(NULL) - , SubprogramCount(0) - , Flavor(flavor) - , SetCounter(1) - { - } - -public: - //===--------------------------------------------------------------------===// - // Accessors. - // - const AsmPrinter *getAsm() const { return Asm; } - MachineModuleInfo *getMMI() const { return MMI; } - const TargetAsmInfo *getTargetAsmInfo() const { return TAI; } - const TargetData *getTargetData() const { return TD; } - - void PrintRelDirective(bool Force32Bit = false, bool isInSection = false) - const { - if (isInSection && TAI->getDwarfSectionOffsetDirective()) - O << TAI->getDwarfSectionOffsetDirective(); - else if (Force32Bit || TD->getPointerSize() == sizeof(int32_t)) - O << TAI->getData32bitsDirective(); - else - O << TAI->getData64bitsDirective(); - } - - /// PrintLabelName - Print label name in form used by Dwarf writer. - /// - void PrintLabelName(DWLabel Label) const { - PrintLabelName(Label.Tag, Label.Number); - } - void PrintLabelName(const char *Tag, unsigned Number) const { - O << TAI->getPrivateGlobalPrefix() << Tag; - if (Number) O << Number; - } - - void PrintLabelName(const char *Tag, unsigned Number, - const char *Suffix) const { - O << TAI->getPrivateGlobalPrefix() << Tag; - if (Number) O << Number; - O << Suffix; - } - - /// EmitLabel - Emit location label for internal use by Dwarf. - /// - void EmitLabel(DWLabel Label) const { - EmitLabel(Label.Tag, Label.Number); - } - void EmitLabel(const char *Tag, unsigned Number) const { - PrintLabelName(Tag, Number); - O << ":\n"; - } - - /// EmitReference - Emit a reference to a label. - /// - void EmitReference(DWLabel Label, bool IsPCRelative = false, - bool Force32Bit = false) const { - EmitReference(Label.Tag, Label.Number, IsPCRelative, Force32Bit); - } - void EmitReference(const char *Tag, unsigned Number, - bool IsPCRelative = false, bool Force32Bit = false) const { - PrintRelDirective(Force32Bit); - PrintLabelName(Tag, Number); - - if (IsPCRelative) O << "-" << TAI->getPCSymbol(); - } - void EmitReference(const std::string &Name, bool IsPCRelative = false, - bool Force32Bit = false) const { - PrintRelDirective(Force32Bit); - - O << Name; - - if (IsPCRelative) O << "-" << TAI->getPCSymbol(); - } - - /// EmitDifference - Emit the difference between two labels. Some - /// assemblers do not behave with absolute expressions with data directives, - /// so there is an option (needsSet) to use an intermediary set expression. - void EmitDifference(DWLabel LabelHi, DWLabel LabelLo, - bool IsSmall = false) { - EmitDifference(LabelHi.Tag, LabelHi.Number, - LabelLo.Tag, LabelLo.Number, - IsSmall); - } - void EmitDifference(const char *TagHi, unsigned NumberHi, - const char *TagLo, unsigned NumberLo, - bool IsSmall = false) { - if (TAI->needsSet()) { - O << "\t.set\t"; - PrintLabelName("set", SetCounter, Flavor); - O << ","; - PrintLabelName(TagHi, NumberHi); - O << "-"; - PrintLabelName(TagLo, NumberLo); - O << "\n"; - - PrintRelDirective(IsSmall); - PrintLabelName("set", SetCounter, Flavor); - ++SetCounter; - } else { - PrintRelDirective(IsSmall); - - PrintLabelName(TagHi, NumberHi); - O << "-"; - PrintLabelName(TagLo, NumberLo); - } - } - - void EmitSectionOffset(const char* Label, const char* Section, - unsigned LabelNumber, unsigned SectionNumber, - bool IsSmall = false, bool isEH = false, - bool useSet = true) { - bool printAbsolute = false; - if (isEH) - printAbsolute = TAI->isAbsoluteEHSectionOffsets(); - else - printAbsolute = TAI->isAbsoluteDebugSectionOffsets(); - - if (TAI->needsSet() && useSet) { - O << "\t.set\t"; - PrintLabelName("set", SetCounter, Flavor); - O << ","; - PrintLabelName(Label, LabelNumber); - - if (!printAbsolute) { - O << "-"; - PrintLabelName(Section, SectionNumber); - } - O << "\n"; - - PrintRelDirective(IsSmall); - - PrintLabelName("set", SetCounter, Flavor); - ++SetCounter; - } else { - PrintRelDirective(IsSmall, true); - - PrintLabelName(Label, LabelNumber); - - if (!printAbsolute) { - O << "-"; - PrintLabelName(Section, SectionNumber); - } - } - } - - /// EmitFrameMoves - Emit frame instructions to describe the layout of the - /// frame. - void EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID, - const std::vector<MachineMove> &Moves, bool isEH) { - int stackGrowth = - Asm->TM.getFrameInfo()->getStackGrowthDirection() == - TargetFrameInfo::StackGrowsUp ? - TD->getPointerSize() : -TD->getPointerSize(); - bool IsLocal = BaseLabel && strcmp(BaseLabel, "label") == 0; - - for (unsigned i = 0, N = Moves.size(); i < N; ++i) { - const MachineMove &Move = Moves[i]; - unsigned LabelID = Move.getLabelID(); - - if (LabelID) { - LabelID = MMI->MappedLabel(LabelID); - - // Throw out move if the label is invalid. - if (!LabelID) continue; - } - - const MachineLocation &Dst = Move.getDestination(); - const MachineLocation &Src = Move.getSource(); - - // Advance row if new location. - if (BaseLabel && LabelID && (BaseLabelID != LabelID || !IsLocal)) { - Asm->EmitInt8(DW_CFA_advance_loc4); - Asm->EOL("DW_CFA_advance_loc4"); - EmitDifference("label", LabelID, BaseLabel, BaseLabelID, true); - Asm->EOL(); - - BaseLabelID = LabelID; - BaseLabel = "label"; - IsLocal = true; - } - - // If advancing cfa. - if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) { - if (!Src.isReg()) { - if (Src.getReg() == MachineLocation::VirtualFP) { - Asm->EmitInt8(DW_CFA_def_cfa_offset); - Asm->EOL("DW_CFA_def_cfa_offset"); - } else { - Asm->EmitInt8(DW_CFA_def_cfa); - Asm->EOL("DW_CFA_def_cfa"); - Asm->EmitULEB128Bytes(RI->getDwarfRegNum(Src.getReg(), isEH)); - Asm->EOL("Register"); - } - - int Offset = -Src.getOffset(); - - Asm->EmitULEB128Bytes(Offset); - Asm->EOL("Offset"); - } else { - assert(0 && "Machine move no supported yet."); - } - } else if (Src.isReg() && - Src.getReg() == MachineLocation::VirtualFP) { - if (Dst.isReg()) { - Asm->EmitInt8(DW_CFA_def_cfa_register); - Asm->EOL("DW_CFA_def_cfa_register"); - Asm->EmitULEB128Bytes(RI->getDwarfRegNum(Dst.getReg(), isEH)); - Asm->EOL("Register"); - } else { - assert(0 && "Machine move no supported yet."); - } - } else { - unsigned Reg = RI->getDwarfRegNum(Src.getReg(), isEH); - int Offset = Dst.getOffset() / stackGrowth; - - if (Offset < 0) { - Asm->EmitInt8(DW_CFA_offset_extended_sf); - Asm->EOL("DW_CFA_offset_extended_sf"); - Asm->EmitULEB128Bytes(Reg); - Asm->EOL("Reg"); - Asm->EmitSLEB128Bytes(Offset); - Asm->EOL("Offset"); - } else if (Reg < 64) { - Asm->EmitInt8(DW_CFA_offset + Reg); - if (Asm->isVerbose()) - Asm->EOL("DW_CFA_offset + Reg (" + utostr(Reg) + ")"); - else - Asm->EOL(); - Asm->EmitULEB128Bytes(Offset); - Asm->EOL("Offset"); - } else { - Asm->EmitInt8(DW_CFA_offset_extended); - Asm->EOL("DW_CFA_offset_extended"); - Asm->EmitULEB128Bytes(Reg); - Asm->EOL("Reg"); - Asm->EmitULEB128Bytes(Offset); - Asm->EOL("Offset"); - } - } - } - } - -}; - -//===----------------------------------------------------------------------===// /// SrcLineInfo - This class is used to record source line correspondence. /// class SrcLineInfo { - unsigned Line; // Source line number. - unsigned Column; // Source column. - unsigned SourceID; // Source ID number. - unsigned LabelID; // Label in code ID number. + unsigned Line; // Source line number. + unsigned Column; // Source column. + unsigned SourceID; // Source ID number. + unsigned LabelID; // Label in code ID number. public: SrcLineInfo(unsigned L, unsigned C, unsigned S, unsigned I) : Line(L), Column(C), SourceID(S), LabelID(I) {} @@ -1100,7 +173,7 @@ public: /// DbgVariable - This class is used to track local variable information. /// class DbgVariable { - DIVariable Var; // Variable Descriptor. + DIVariable Var; // Variable Descriptor. unsigned FrameIndex; // Variable frame index. public: DbgVariable(DIVariable V, unsigned I) : Var(V), FrameIndex(I) {} @@ -1395,32 +468,32 @@ private: return DWLabel("string", StringID); } - /// NewDIEntry - Creates a new DIEntry to be a proxy for a debug information + /// NewDIEEntry - Creates a new DIEEntry to be a proxy for a debug information /// entry. - DIEntry *NewDIEntry(DIE *Entry = NULL) { - DIEntry *Value; + DIEEntry *NewDIEEntry(DIE *Entry = NULL) { + DIEEntry *Value; if (Entry) { FoldingSetNodeID ID; - DIEntry::Profile(ID, Entry); + DIEEntry::Profile(ID, Entry); void *Where; - Value = static_cast<DIEntry *>(ValuesSet.FindNodeOrInsertPos(ID, Where)); + Value = static_cast<DIEEntry *>(ValuesSet.FindNodeOrInsertPos(ID, Where)); if (Value) return Value; |