17cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby//===- MCDwarf.h - Machine Code Dwarf support -------------------*- C++ -*-===//
27cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby//
37cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby//                     The LLVM Compiler Infrastructure
47cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby//
57cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby// This file is distributed under the University of Illinois Open Source
67cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby// License. See LICENSE.TXT for details.
77cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby//
87cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby//===----------------------------------------------------------------------===//
97cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby//
107cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby// This file contains the declaration of the MCDwarfFile to support the dwarf
113bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby// .file directive and the .loc directive.
127cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby//
137cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby//===----------------------------------------------------------------------===//
147cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby
157cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby#ifndef LLVM_MC_MCDWARF_H
167cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby#define LLVM_MC_MCDWARF_H
177cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby
183bce5adb32fbbe5c5549b902f4d65737f40c1499Benjamin Kramer#include "llvm/ADT/StringRef.h"
192d28617de2b0b731c08d1af9e830f31e14ac75b4Evan Cheng#include "llvm/MC/MachineLocation.h"
203bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby#include "llvm/Support/raw_ostream.h"
213bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby#include "llvm/Support/Dwarf.h"
22232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby#include <vector>
237cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby
247cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderbynamespace llvm {
257cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  class MCContext;
26f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper  class MCObjectWriter;
27232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  class MCSection;
28ad8aaa069cfdb3bdc32b1becc8881f67b5272e14Rafael Espindola  class MCStreamer;
29232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  class MCSymbol;
3094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby  class SourceMgr;
3194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby  class SMLoc;
327cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby
337cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  /// MCDwarfFile - Instances of this class represent the name of the dwarf
347cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  /// .file directive and its associated dwarf file number in the MC file,
357cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  /// and MCDwarfFile's are created and unique'd by the MCContext class where
367cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  /// the file number for each is its index into the vector of DwarfFiles (note
377cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  /// index 0 is not used and not a valid dwarf file number).
387cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  class MCDwarfFile {
397cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby    // Name - the base name of the file without its directory path.
403bce5adb32fbbe5c5549b902f4d65737f40c1499Benjamin Kramer    // The StringRef references memory allocated in the MCContext.
413bce5adb32fbbe5c5549b902f4d65737f40c1499Benjamin Kramer    StringRef Name;
427cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby
437cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby    // DirIndex - the index into the list of directory names for this file name.
447cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby    unsigned DirIndex;
457cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby
467cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  private:  // MCContext creates and uniques these.
477cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby    friend class MCContext;
483bce5adb32fbbe5c5549b902f4d65737f40c1499Benjamin Kramer    MCDwarfFile(StringRef name, unsigned dirIndex)
497cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby      : Name(name), DirIndex(dirIndex) {}
507cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby
517cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby    MCDwarfFile(const MCDwarfFile&);       // DO NOT IMPLEMENT
527cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby    void operator=(const MCDwarfFile&); // DO NOT IMPLEMENT
537cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  public:
547cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby    /// getName - Get the base name of this MCDwarfFile.
553bce5adb32fbbe5c5549b902f4d65737f40c1499Benjamin Kramer    StringRef getName() const { return Name; }
567cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby
57b07ce60981368f816af4caa3257e1e4ebf059133Kevin Enderby    /// getDirIndex - Get the dirIndex of this MCDwarfFile.
58b07ce60981368f816af4caa3257e1e4ebf059133Kevin Enderby    unsigned getDirIndex() const { return DirIndex; }
59b07ce60981368f816af4caa3257e1e4ebf059133Kevin Enderby
60b07ce60981368f816af4caa3257e1e4ebf059133Kevin Enderby
617cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby    /// print - Print the value to the stream \arg OS.
627cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby    void print(raw_ostream &OS) const;
637cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby
647cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby    /// dump - Print the value to stderr.
657cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby    void dump() const;
667cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby  };
677cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby
68232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  inline raw_ostream &operator<<(raw_ostream &OS, const MCDwarfFile &DwarfFile){
69232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby    DwarfFile.print(OS);
70232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby    return OS;
71232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  }
72232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby
73c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby  /// MCDwarfLoc - Instances of this class represent the information from a
74c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby  /// dwarf .loc directive.
75c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby  class MCDwarfLoc {
76c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    // FileNum - the file number.
77c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    unsigned FileNum;
78c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    // Line - the line number.
79c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    unsigned Line;
80c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    // Column - the column position.
81c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    unsigned Column;
82c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    // Flags (see #define's below)
83c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    unsigned Flags;
84c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    // Isa
85c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    unsigned Isa;
86c50a0fd7cb6da0e674e154205da65241f9c90e1dRafael Espindola    // Discriminator
87c50a0fd7cb6da0e674e154205da65241f9c90e1dRafael Espindola    unsigned Discriminator;
88c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby
893bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby// Flag that indicates the initial value of the is_stmt_start flag.
903bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby#define DWARF2_LINE_DEFAULT_IS_STMT     1
913bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby
92c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby#define DWARF2_FLAG_IS_STMT        (1 << 0)
93c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby#define DWARF2_FLAG_BASIC_BLOCK    (1 << 1)
94c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby#define DWARF2_FLAG_PROLOGUE_END   (1 << 2)
95c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby#define DWARF2_FLAG_EPILOGUE_BEGIN (1 << 3)
96c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby
97c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby  private:  // MCContext manages these
98c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    friend class MCContext;
99232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby    friend class MCLineEntry;
100c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags,
101c50a0fd7cb6da0e674e154205da65241f9c90e1dRafael Espindola               unsigned isa, unsigned discriminator)
102c50a0fd7cb6da0e674e154205da65241f9c90e1dRafael Espindola      : FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa),
103c50a0fd7cb6da0e674e154205da65241f9c90e1dRafael Espindola        Discriminator(discriminator) {}
104c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby
105232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby    // Allow the default copy constructor and assignment operator to be used
106232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby    // for an MCDwarfLoc object.
107232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby
108c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby  public:
1093bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby    /// getFileNum - Get the FileNum of this MCDwarfLoc.
110342e39f9e55d3f4465748c9ab84bf27df7a92478Rafael Espindola    unsigned getFileNum() const { return FileNum; }
1113bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby
1123bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby    /// getLine - Get the Line of this MCDwarfLoc.
113342e39f9e55d3f4465748c9ab84bf27df7a92478Rafael Espindola    unsigned getLine() const { return Line; }
1143bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby
1153bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby    /// getColumn - Get the Column of this MCDwarfLoc.
116342e39f9e55d3f4465748c9ab84bf27df7a92478Rafael Espindola    unsigned getColumn() const { return Column; }
1173bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby
1183bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby    /// getFlags - Get the Flags of this MCDwarfLoc.
119342e39f9e55d3f4465748c9ab84bf27df7a92478Rafael Espindola    unsigned getFlags() const { return Flags; }
1203bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby
1213bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby    /// getIsa - Get the Isa of this MCDwarfLoc.
122342e39f9e55d3f4465748c9ab84bf27df7a92478Rafael Espindola    unsigned getIsa() const { return Isa; }
1233bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby
124c50a0fd7cb6da0e674e154205da65241f9c90e1dRafael Espindola    /// getDiscriminator - Get the Discriminator of this MCDwarfLoc.
125342e39f9e55d3f4465748c9ab84bf27df7a92478Rafael Espindola    unsigned getDiscriminator() const { return Discriminator; }
126c50a0fd7cb6da0e674e154205da65241f9c90e1dRafael Espindola
127c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    /// setFileNum - Set the FileNum of this MCDwarfLoc.
128c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    void setFileNum(unsigned fileNum) { FileNum = fileNum; }
129c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby
130c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    /// setLine - Set the Line of this MCDwarfLoc.
131c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    void setLine(unsigned line) { Line = line; }
132c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby
133c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    /// setColumn - Set the Column of this MCDwarfLoc.
134c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    void setColumn(unsigned column) { Column = column; }
135c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby
136c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    /// setFlags - Set the Flags of this MCDwarfLoc.
137c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    void setFlags(unsigned flags) { Flags = flags; }
138c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby
139c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    /// setIsa - Set the Isa of this MCDwarfLoc.
140c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby    void setIsa(unsigned isa) { Isa = isa; }
141c50a0fd7cb6da0e674e154205da65241f9c90e1dRafael Espindola
142c50a0fd7cb6da0e674e154205da65241f9c90e1dRafael Espindola    /// setDiscriminator - Set the Discriminator of this MCDwarfLoc.
143c50a0fd7cb6da0e674e154205da65241f9c90e1dRafael Espindola    void setDiscriminator(unsigned discriminator) {
144c50a0fd7cb6da0e674e154205da65241f9c90e1dRafael Espindola      Discriminator = discriminator;
145c50a0fd7cb6da0e674e154205da65241f9c90e1dRafael Espindola    }
146c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby  };
147c1840b3da25222680b51f853697a871fedda51d5Kevin Enderby
148232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  /// MCLineEntry - Instances of this class represent the line information for
149232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  /// the dwarf line table entries.  Which is created after a machine
150232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  /// instruction is assembled and uses an address from a temporary label
151232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  /// created at the current address in the current section and the info from
152232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  /// the last .loc directive seen as stored in the context.
153232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  class MCLineEntry : public MCDwarfLoc {
154232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby    MCSymbol *Label;
155232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby
156232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  private:
157232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby    // Allow the default copy constructor and assignment operator to be used
158232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby    // for an MCLineEntry object.
159232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby
160232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  public:
161232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby    // Constructor to create an MCLineEntry given a symbol and the dwarf loc.
162232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby    MCLineEntry(MCSymbol *label, const MCDwarfLoc loc) : MCDwarfLoc(loc),
163232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby                Label(label) {}
1643bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby
16517fd7bda5ac08f873c063c64e1456f8960a0c765Rafael Espindola    MCSymbol *getLabel() const { return Label; }
1663bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby
1673bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby    // This is called when an instruction is assembled into the specified
1683bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby    // section and if there is information from the last .loc directive that
1693bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby    // has yet to have a line entry made for it is made.
170195a0ce484cd12a5adae9184188f6d0fb52b84c0Rafael Espindola    static void Make(MCStreamer *MCOS, const MCSection *Section);
171232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  };
172232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby
173232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  /// MCLineSection - Instances of this class represent the line information
174232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  /// for a section where machine instructions have been assembled after seeing
175232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  /// .loc directives.  This is the information used to build the dwarf line
176232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  /// table for a section.
177232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  class MCLineSection {
178232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby
179232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  private:
180232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby    MCLineSection(const MCLineSection&);  // DO NOT IMPLEMENT
181232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby    void operator=(const MCLineSection&); // DO NOT IMPLEMENT
182232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby
183232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  public:
184232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby    // Constructor to create an MCLineSection with an empty MCLineEntries
185232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby    // vector.
18647b7efc0828d9587613b2f2865a6d07ed55c5becBenjamin Kramer    MCLineSection() {}
187232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby
188232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby    // addLineEntry - adds an entry to this MCLineSection's line entries
189232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby    void addLineEntry(const MCLineEntry &LineEntry) {
190232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby      MCLineEntries.push_back(LineEntry);
191232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby    }
1923bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby
1933bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby    typedef std::vector<MCLineEntry> MCLineEntryCollection;
1943bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby    typedef MCLineEntryCollection::iterator iterator;
19517fd7bda5ac08f873c063c64e1456f8960a0c765Rafael Espindola    typedef MCLineEntryCollection::const_iterator const_iterator;
1963bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby
1973bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby  private:
1983bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby    MCLineEntryCollection MCLineEntries;
1993bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby
2003bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby  public:
20117fd7bda5ac08f873c063c64e1456f8960a0c765Rafael Espindola    const MCLineEntryCollection *getMCLineEntries() const {
20217fd7bda5ac08f873c063c64e1456f8960a0c765Rafael Espindola      return &MCLineEntries;
20317fd7bda5ac08f873c063c64e1456f8960a0c765Rafael Espindola    }
2043bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby  };
2053bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby
2063bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby  class MCDwarfFileTable {
2073bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby  public:
2083bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby    //
2093bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby    // This emits the Dwarf file and the line tables.
2103bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby    //
211489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola    static const MCSymbol *Emit(MCStreamer *MCOS);
212232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby  };
213232ab949d5ed04c4ab45c763e0597fc3fc3fa5bcKevin Enderby
2143bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby  class MCDwarfLineAddr {
2153bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby  public:
2163bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby    /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
2173bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby    static void Encode(int64_t LineDelta, uint64_t AddrDelta, raw_ostream &OS);
2183bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby
2193bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby    /// Utility function to emit the encoding to a streamer.
220195a0ce484cd12a5adae9184188f6d0fb52b84c0Rafael Espindola    static void Emit(MCStreamer *MCOS,
2213bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby                     int64_t LineDelta,uint64_t AddrDelta);
2223bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby
2233bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby    /// Utility function to write the encoding to an object writer.
2243bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby    static void Write(MCObjectWriter *OW,
2253bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby                      int64_t LineDelta, uint64_t AddrDelta);
2263bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby  };
22789b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola
22894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby  class MCGenDwarfInfo {
22994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby  public:
23094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby    //
23194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby    // When generating dwarf for assembly source files this emits the Dwarf
23294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby    // sections.
23394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby    //
234489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola    static void Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol);
23594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby  };
23694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby
23794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby  // When generating dwarf for assembly source files this is the info that is
23811c2defa9157bd589cb322218c718c4492ed5746Kevin Enderby  // needed to be gathered for each symbol that will have a dwarf label.
23911c2defa9157bd589cb322218c718c4492ed5746Kevin Enderby  class MCGenDwarfLabelEntry {
24094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby  private:
24194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby    // Name of the symbol without a leading underbar, if any.
24294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby    StringRef Name;
24394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby    // The dwarf file number this symbol is in.
24494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby    unsigned FileNumber;
24594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby    // The line number this symbol is at.
24694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby    unsigned LineNumber;
24711c2defa9157bd589cb322218c718c4492ed5746Kevin Enderby    // The low_pc for the dwarf label is taken from this symbol.
24894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby    MCSymbol *Label;
24994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby
25094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby  public:
25111c2defa9157bd589cb322218c718c4492ed5746Kevin Enderby    MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber,
25211c2defa9157bd589cb322218c718c4492ed5746Kevin Enderby                         unsigned lineNumber, MCSymbol *label) :
25394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby      Name(name), FileNumber(fileNumber), LineNumber(lineNumber), Label(label){}
25494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby
25594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby    StringRef getName() const { return Name; }
25694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby    unsigned getFileNumber() const { return FileNumber; }
25794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby    unsigned getLineNumber() const { return LineNumber; }
25894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby    MCSymbol *getLabel() const { return Label; }
25994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby
26094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby    // This is called when label is created when we are generating dwarf for
26194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby    // assembly source files.
26294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby    static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr,
26394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby                     SMLoc &Loc);
26494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby  };
26594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby
266fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola  class MCCFIInstruction {
267fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola  public:
268ed23bdb65fe86cdb7a38c8c1998ec965e6973966Rafael Espindola    enum OpType { SameValue, RememberState, RestoreState, Move, RelMove, Escape,
269ed23bdb65fe86cdb7a38c8c1998ec965e6973966Rafael Espindola                  Restore};
270fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola  private:
271fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola    OpType Operation;
272fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola    MCSymbol *Label;
273fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola    // Move to & from location.
274fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola    MachineLocation Destination;
275fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola    MachineLocation Source;
2766f0b181bc70318f8d5d4b9bdead7fc748677fe2aRafael Espindola    std::vector<char> Values;
277fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola  public:
278fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola    MCCFIInstruction(OpType Op, MCSymbol *L)
279fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola      : Operation(Op), Label(L) {
280c25680f728f89dd43939b00049ee524fbf59b7beRafael Espindola      assert(Op == RememberState || Op == RestoreState);
281fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola    }
282c57543964d1382d3d3a5005f415b6c0f49671b3aRafael Espindola    MCCFIInstruction(OpType Op, MCSymbol *L, unsigned Register)
283c57543964d1382d3d3a5005f415b6c0f49671b3aRafael Espindola      : Operation(Op), Label(L), Destination(Register) {
284ed23bdb65fe86cdb7a38c8c1998ec965e6973966Rafael Espindola      assert(Op == SameValue || Op == Restore);
285c57543964d1382d3d3a5005f415b6c0f49671b3aRafael Espindola    }
286fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola    MCCFIInstruction(MCSymbol *L, const MachineLocation &D,
287fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola                     const MachineLocation &S)
288fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola      : Operation(Move), Label(L), Destination(D), Source(S) {
289fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola    }
29025f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola    MCCFIInstruction(OpType Op, MCSymbol *L, const MachineLocation &D,
29125f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola                     const MachineLocation &S)
29225f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola      : Operation(Op), Label(L), Destination(D), Source(S) {
29325f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola      assert(Op == RelMove);
29425f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola    }
2956f0b181bc70318f8d5d4b9bdead7fc748677fe2aRafael Espindola    MCCFIInstruction(OpType Op, MCSymbol *L, StringRef Vals)
2966f0b181bc70318f8d5d4b9bdead7fc748677fe2aRafael Espindola      : Operation(Op), Label(L), Values(Vals.begin(), Vals.end()) {
2976f0b181bc70318f8d5d4b9bdead7fc748677fe2aRafael Espindola      assert(Op == Escape);
2986f0b181bc70318f8d5d4b9bdead7fc748677fe2aRafael Espindola    }
299fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola    OpType getOperation() const { return Operation; }
300fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola    MCSymbol *getLabel() const { return Label; }
301fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola    const MachineLocation &getDestination() const { return Destination; }
302fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola    const MachineLocation &getSource() const { return Source; }
3036f0b181bc70318f8d5d4b9bdead7fc748677fe2aRafael Espindola    const StringRef getValues() const {
3046f0b181bc70318f8d5d4b9bdead7fc748677fe2aRafael Espindola      return StringRef(&Values[0], Values.size());
3056f0b181bc70318f8d5d4b9bdead7fc748677fe2aRafael Espindola    }
306fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola  };
307fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola
30889b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola  struct MCDwarfFrameInfo {
309fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola    MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0),
310ed708f9c1facb9928ef2f79503e7030c8f25b00dRafael Espindola                         Function(0), Instructions(), PersonalityEncoding(),
31116d7d437e03ce87fdaef7971919302920d54a966Rafael Espindola                         LsdaEncoding(0), CompactUnwindEncoding(0),
31216d7d437e03ce87fdaef7971919302920d54a966Rafael Espindola                         IsSignalFrame(false) {}
31389b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola    MCSymbol *Begin;
31489b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola    MCSymbol *End;
31589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola    const MCSymbol *Personality;
31689b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola    const MCSymbol *Lsda;
317ed708f9c1facb9928ef2f79503e7030c8f25b00dRafael Espindola    const MCSymbol *Function;
318fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola    std::vector<MCCFIInstruction> Instructions;
3193a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola    unsigned PersonalityEncoding;
320bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola    unsigned LsdaEncoding;
32188b976060af9e33f79d146db0766d5c36757ca5bBill Wendling    uint32_t CompactUnwindEncoding;
32216d7d437e03ce87fdaef7971919302920d54a966Rafael Espindola    bool IsSignalFrame;
32389b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola  };
32489b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola
32589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola  class MCDwarfFrameEmitter {
32689b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola  public:
32789b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola    //
32889b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola    // This emits the frame info section.
32989b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola    //
33040a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola    static void Emit(MCStreamer &streamer, bool usingCFI,
33140a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola                     bool isEH);
332245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola    static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta);
3334eafe109459eb115f13f1d19c5ff3cb3678e8c7aRafael Espindola    static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS);
33489b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola  };
3357cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby} // end namespace llvm
3367cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby
3377cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby#endif
338