Adding basic support for Dwarf line number debug information.

I promise to keep future commits smaller.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25396 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Laskey 2006-01-17 17:31:53 +00:00
parent 08a0464763
commit 063e765345
6 changed files with 1802 additions and 220 deletions

View File

@ -7,14 +7,26 @@
//
//===----------------------------------------------------------------------===//
//
// This file contains support for writing dwarf debug info into asm files.
// This file contains support for writing Dwarf debug info into asm files. For
// Details on the Dwarf 3 specfication see DWARF Debugging Information Format
// V.3 reference manual http://dwarf.freestandards.org ,
//
// The role of the Dwarf Writer class is to extract debug information from the
// MachineDebugInfo object, organize it in Dwarf form and then emit it into asm
// the current asm file using data and high level Dwarf directives.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_DWARFPRINTER_H
#define LLVM_CODEGEN_DWARFPRINTER_H
#include "llvm/ADT/UniqueVector.h"
#include <iosfwd>
#include <map>
#include <string>
#include <vector>
namespace llvm {
@ -23,6 +35,8 @@ namespace llvm {
// reference manual http://dwarf.freestandards.org .
//
enum dwarf_constants {
DWARF_VERSION = 2,
// Tags
DW_TAG_array_type = 0x01,
DW_TAG_class_type = 0x02,
@ -425,23 +439,246 @@ namespace llvm {
DW_CFA_hi_user = 0x3f
};
//===--------------------------------------------------------------------===//
// 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
// category of label (Ex. location) and number is a value unique in that
// category.
struct DWLabel {
const char *Tag; // Label category tag. Should always be
// a staticly declared C string.
unsigned Number; // Unique number
DWLabel() : Tag(NULL), Number(0) {}
DWLabel(const char *T, unsigned N) : Tag(T), Number(N) {}
};
//===--------------------------------------------------------------------===//
// DIEAbbrev - Dwarf abbreviation, describes the organization of a debug
// information object.
//
class DIEAbbrev {
private:
const unsigned char *Data; // Static array of bytes containing the
// image of the raw abbreviation data.
public:
DIEAbbrev(const unsigned char *D)
: Data(D)
{}
/// operator== - Used by UniqueVector to locate entry.
///
bool operator==(const DIEAbbrev &DA) const {
return Data == DA.Data;
}
/// operator< - Used by UniqueVector to locate entry.
///
bool operator<(const DIEAbbrev &DA) const {
return Data < DA.Data;
}
// Accessors
unsigned getTag() const { return Data[0]; }
unsigned getChildrenFlag() const { return Data[1]; }
unsigned getAttribute(unsigned i) const { return Data[2 + 2 * i + 0]; }
unsigned getForm(unsigned i) const { return Data[2 + 2 * i + 1]; }
};
//===--------------------------------------------------------------------===//
// DIEValue - A debug information entry value.
//
class DwarfWriter;
class DIEValue {
public:
enum {
isInteger,
isString,
isLabel,
isDelta
};
unsigned Type; // Type of the value
DIEValue(unsigned T) : Type(T) {}
virtual ~DIEValue() {}
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *) { return true; }
/// EmitValue - Emit value via the Dwarf writer.
///
virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const = 0;
/// SizeOf - Return the size of a value in bytes.
///
virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const = 0;
};
//===--------------------------------------------------------------------===//
// DWInteger - An integer value DIE.
//
class DIEInteger : public DIEValue {
private:
int Value;
public:
DIEInteger(int V) : DIEValue(isInteger), Value(V) {}
// Implement isa/cast/dyncast.
static bool classof(const DIEInteger *) { return true; }
static bool classof(const DIEValue *V) { return V->Type == isInteger; }
/// EmitValue - Emit integer of appropriate size.
///
virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const;
/// SizeOf - Determine size of integer value in bytes.
///
virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const;
};
//===--------------------------------------------------------------------===//
// DIEString - A string value DIE.
//
struct DIEString : public DIEValue {
const std::string Value;
DIEString(const std::string &V) : DIEValue(isString), Value(V) {}
// Implement isa/cast/dyncast.
static bool classof(const DIEString *) { return true; }
static bool classof(const DIEValue *V) { return V->Type == isString; }
/// EmitValue - Emit string value.
///
virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const;
/// SizeOf - Determine size of string value in bytes.
///
virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const;
};
//===--------------------------------------------------------------------===//
// DIELabel - A simple label expression DIE.
//
struct DIELabel : public DIEValue {
const DWLabel Value;
DIELabel(const DWLabel &V) : DIEValue(DW_FORM_ref4), Value(V) {}
// Implement isa/cast/dyncast.
static bool classof(const DWLabel *) { return true; }
static bool classof(const DIEValue *V) { return V->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;
};
//===--------------------------------------------------------------------===//
// DIEDelta - A simple label difference DIE.
//
struct DIEDelta : public DIEValue {
const DWLabel Value1;
const DWLabel Value2;
DIEDelta(const DWLabel &V1, const DWLabel &V2)
: DIEValue(DW_FORM_addr), Value1(V1), Value2(V2) {}
// Implement isa/cast/dyncast.
static bool classof(const DIEDelta *) { return true; }
static bool classof(const DIEValue *V) { return V->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;
};
//===--------------------------------------------------------------------===//
// DIE - A structured debug information entry. Has an abbreviation which
// describes it's organization.
class DIE {
private:
unsigned AbbrevID; // Decribing abbreviation ID.
unsigned Offset; // Offset in debug info section
unsigned Size; // Size of instance + children
std::vector<DIE *> Children; // Children DIEs
std::vector<DIEValue *> Values; // Attributes values
public:
DIE(unsigned AbbrevID)
: AbbrevID(AbbrevID)
, Offset(0)
, Size(0)
, Children()
, Values()
{}
virtual ~DIE() {
}
// Accessors
unsigned getAbbrevID() const { return AbbrevID; }
unsigned getOffset() const { return Offset; }
unsigned getSize() const { return Size; }
const std::vector<DIE *> &getChildren() const { return Children; }
const std::vector<DIEValue *> &getValues() const { return Values; }
void setOffset(unsigned O) { Offset = O; }
void setSize(unsigned S) { Size = S; }
/// 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
/// sibling.
unsigned SiblingOffset() const { return Offset + Size; }
};
//===--------------------------------------------------------------------===//
// Forward declarations.
//
class AsmPrinter;
class MachineDebugInfo;
//===--------------------------------------------------------------------===//
// DwarfWriter - emits dwarf debug and exception handling directives.
// DwarfWriter - emits Dwarf debug and exception handling directives.
//
class DwarfWriter {
protected:
//===------------------------------------------------------------------===//
// Core attributes used by the Dwarf writer.
//
//
/// O - Stream to .s file.
///
std::ostream &O;
/// Asm - Target of dwarf emission.
/// Asm - Target of Dwarf emission.
///
AsmPrinter *Asm;
@ -453,9 +690,26 @@ namespace llvm {
///
bool didInitial;
//===------------------------------------------------------------------===//
// Attributes used to construct specific Dwarf sections.
//
/// CompileUnits - All the compile units involved in this build. The index
/// of each entry in this vector corresponds to the sources in DebugInfo.
std::vector<DIE *> CompileUnits;
/// Abbreviations - A UniqueVector of TAG structure abbreviations.
///
UniqueVector<DIEAbbrev> Abbreviations;
//===------------------------------------------------------------------===//
// Properties to be set by the derived class ctor, used to configure the
// dwarf writer.
// Dwarf writer.
//
/// AddressSize - Size of addresses used in file.
///
unsigned AddressSize;
/// hasLEB128 - True if target asm supports leb128 directives.
///
@ -473,93 +727,174 @@ namespace llvm {
/// directives.
bool needsSet; /// Defaults to false.
/// DwarfAbbrevSection - section directive arg for dwarf abbrev.
/// DwarfAbbrevSection - Section directive for Dwarf abbrev.
///
const char *DwarfAbbrevSection; /// Defaults to ".debug_abbrev".
/// DwarfInfoSection - section directive arg for dwarf info.
/// DwarfInfoSection - Section directive for Dwarf info.
///
const char *DwarfInfoSection; /// Defaults to ".debug_info".
/// DwarfLineSection - section directive arg for dwarf info.
/// DwarfLineSection - Section directive for Dwarf info.
///
const char *DwarfLineSection; /// Defaults to ".debug_line".
/// TextSection - Section directive for standard text.
///
const char *TextSection; /// Defaults to ".text".
/// DataSection - Section directive for standard data.
///
const char *DataSection; /// Defaults to ".data".
//===------------------------------------------------------------------===//
// Emission and print routines
//
public:
// Ctor.
DwarfWriter(std::ostream &o, AsmPrinter *ap)
: O(o)
, Asm(ap)
, DebugInfo(NULL)
, didInitial(false)
, hasLEB128(false)
, hasDotLoc(false)
, hasDotFile(false)
, needsSet(false)
, DwarfAbbrevSection(".debug_abbrev")
, DwarfInfoSection(".debug_info")
, DwarfLineSection(".debug_line")
{}
/// SetDebugInfo - Set DebugInfo at when it's know that pass manager
/// has created it.
void SetDebugInfo(MachineDebugInfo *di) { DebugInfo = di; }
/// EmitHex - Emit a hexidecimal string to the output stream.
public:
/// getAddressSize - Return the size of a target address in bytes.
///
void EmitHex(unsigned Value) const;
/// EmitComment - Emit a simple string comment.
///
void EmitComment(const char *Comment) const;
unsigned getAddressSize() const { return AddressSize; }
/// EmitULEB128 - Emit a series of hexidecimal values (separated by commas)
/// representing an unsigned leb128 value.
/// PrintHex - Print a value as a hexidecimal value.
///
void EmitULEB128(unsigned Value) const;
void PrintHex(int Value) const;
/// EmitSLEB128 - Emit a series of hexidecimal values (separated by commas)
/// representing a signed leb128 value.
///
void EmitSLEB128(int Value) const;
/// EmitLabelName - Emit label name for internal use by dwarf.
///
void EmitLabelName(const char *Tag, int Num) const;
/// EmitLabel - Emit location label for internal use by dwarf.
///
void EmitLabel(const char *Tag, int Num) const;
/// EOL - Print a newline character to asm stream. If a comment is present
/// then it will be printed first. Comments should not contain '\n'.
void EOL(const std::string &Comment) const;
/// EmitULEB128Bytes - Emit an assembler byte data directive to compose an
/// unsigned leb128 value. Comment is added to the end of the directive if
/// DwarfVerbose is true (should not contain any newlines.)
///
void EmitULEB128Bytes(unsigned Value, const char *Comment) const;
/// unsigned leb128 value.
void EmitULEB128Bytes(unsigned Value) const;
/// EmitSLEB128Bytes - Emit an assembler byte data directive to compose a
/// signed leb128 value. Comment is added to the end of the directive if
/// DwarfVerbose is true (should not contain any newlines.)
///
void EmitSLEB128Bytes(int Value, const char *Comment) const;
/// EmitSLEB128Bytes - print an assembler byte data directive to compose a
/// signed leb128 value.
void EmitSLEB128Bytes(int Value) const;
/// EmitInitial - Emit initial dwarf declarations.
/// PrintULEB128 - Print a series of hexidecimal values (separated by
/// commas) representing an unsigned leb128 value.
void PrintULEB128(unsigned Value) const;
/// SizeULEB128 - Compute the number of bytes required for an unsigned
/// leb128 value.
static unsigned SizeULEB128(unsigned Value);
/// PrintSLEB128 - Print a series of hexidecimal values (separated by
/// commas) representing a signed leb128 value.
void PrintSLEB128(int Value) const;
/// SizeSLEB128 - Compute the number of bytes required for a signed leb128
/// value.
static unsigned SizeSLEB128(int Value);
/// EmitByte - Emit a byte directive and value.
///
void EmitByte(int Value) const;
/// EmitShort - Emit a short directive and value.
///
void EmitShort(int Value) const;
/// EmitLong - Emit a long directive and value.
///
void EmitLong(int Value) const;
/// EmitString - Emit a string with quotes and a null terminator.
/// Special characters are emitted properly. (Eg. '\t')
void DwarfWriter::EmitString(const std::string &String) const;
/// 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;
/// 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;
/// EmitLabelReference - Emit a reference to a label.
///
void EmitLabelReference(DWLabel Label) const {
EmitLabelReference(Label.Tag, Label.Number);
}
void EmitLabelReference(const char *Tag, unsigned Number) const;
/// EmitDifference - Emit the difference between two labels. Some
/// assemblers do not behave with absolute expressions with data directives,
/// so there is an option (needsSet) to use an intermediary set expression.
void EmitDifference(DWLabel Label1, DWLabel Label2) const {
EmitDifference(Label1.Tag, Label1.Number, Label2.Tag, Label2.Number);
}
void EmitDifference(const char *Tag1, unsigned Number1,
const char *Tag2, unsigned Number2) const;
private:
/// NewDIE - Construct a new structured debug information entry.
///
DIE *NewDIE(const unsigned char *AbbrevData);
/// NewCompileUnit - Create new compile unit information.
///
DIE *NewCompileUnit(const std::string &Directory,
const std::string &SourceName);
/// EmitInitial - Emit initial Dwarf declarations.
///
void EmitInitial() const;
/// ShouldEmitDwarf - Returns true if dwarf declarations should be made.
/// When called it also checks to see if debug info is newly available. if
/// so the initial dwarf headers are emitted.
bool ShouldEmitDwarf();
/// EmitDIE - Recusively Emits a debug information entry.
///
void EmitDIE(DIE *Die) const;
/// SizeAndOffsetDie - Compute the size and offset of a DIE.
///
unsigned SizeAndOffsetDie(DIE *Die, unsigned Offset) const;
/// BeginModule - Emit all dwarf sections that should come prior to the
/// SizeAndOffsets - Compute the size and offset of all the DIEs.
///
void SizeAndOffsets();
/// EmitDebugInfo - Emit the debug info section.
///
void EmitDebugInfo() const;
/// EmitAbbreviations - Emit the abbreviation section.
///
void EmitAbbreviations() const;
/// EmitDebugLines - Emit source line information.
///
void EmitDebugLines() const;
/// ShouldEmitDwarf - Returns true if Dwarf declarations should be made.
/// When called it also checks to see if debug info is newly available. if
/// so the initial Dwarf headers are emitted.
bool ShouldEmitDwarf();
public:
DwarfWriter(std::ostream &o, AsmPrinter *ap);
virtual ~DwarfWriter();
/// SetDebugInfo - Set DebugInfo when it's known that pass manager has
/// created it. Set by the target AsmPrinter.
void SetDebugInfo(MachineDebugInfo *di) { DebugInfo = di; }
//===------------------------------------------------------------------===//
// Main enties.
//
/// BeginModule - Emit all Dwarf sections that should come prior to the
/// content.
void BeginModule();
/// EndModule - Emit all dwarf sections that should come after the content.
/// EndModule - Emit all Dwarf sections that should come after the content.
///
void EndModule();
@ -571,7 +906,6 @@ namespace llvm {
///
void EndFunction();
};
} // end llvm namespace

View File

@ -10,17 +10,83 @@
// Collect debug information for a module. This information should be in a
// neutral form that can be used by different debugging schemes.
//
// The organization of information is primarily clustered around the source
// compile units. The main exception is source line coorespondence where
// inlining may interleave code from various compile units.
//
// The following information can be retrieved from the MachineDebugInfo.
//
// -- Source directories - Directories are uniqued based on their canonical
// string and assigned a sequential numeric ID (base 1.) A directory ID - 1
// provides the index of directory information in a queried directory list.
// -- Source files - Files are also uniqued based on their name and directory
// ID. A file ID is sequential number (base 1.) A file ID - 1 provides the
// index of source information in a queried file list.
// -- Source line coorespondence - A vector of file ID, line#, column# triples.
// A DEBUG_LOCATION instruction is generated by the DAG Legalizer
// corresponding to each entry in the source line list. This allows a debug
// information emitter to generate labels to map code addressed to debug
// tables.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_MACHINEDEBUGINFO_H
#define LLVM_CODEGEN_MACHINEDEBUGINFO_H
#include "llvm/Pass.h"
#include "llvm/ADT/UniqueVector.h"
#include <string>
#include <map>
#include <vector>
namespace llvm {
//===----------------------------------------------------------------------===//
/// SourceLineInfo - This class is used to record source line correspondence.
///
class SourceLineInfo {
private:
unsigned Line; // Source line number.
unsigned Column; // Source column.
unsigned SourceID; // Source ID number.
public:
SourceLineInfo(unsigned L, unsigned C, unsigned S)
: Line(L), Column(C), SourceID(S) {}
// Accessors
unsigned getLine() const { return Line; }
unsigned getColumn() const { return Column; }
unsigned getSourceID() const { return SourceID; }
};
//===----------------------------------------------------------------------===//
/// SourceFileInfo - This class is used to track source information.
///
class SourceFileInfo {
private:
unsigned DirectoryID; // Directory ID number.
std::string Name; // File name (not including directory.)
public:
SourceFileInfo(unsigned D, const std::string &N) : DirectoryID(D), Name(N) {}
// Accessors
unsigned getDirectoryID() const { return DirectoryID; }
const std::string &getName() const { return Name; }
/// operator== - Used by UniqueVector to locate entry.
///
bool operator==(const SourceFileInfo &SI) const {
return getDirectoryID() == SI.getDirectoryID() && getName() == SI.getName();
}
/// operator< - Used by UniqueVector to locate entry.
///
bool operator<(const SourceFileInfo &SI) const {
return getDirectoryID() < SI.getDirectoryID() ||
(getDirectoryID() == SI.getDirectoryID() && getName() < SI.getName());
}
};
//===----------------------------------------------------------------------===//
/// MachineDebugInfo - This class contains debug information specific to a
/// module. Queries can be made by different debugging schemes and reformated
@ -28,48 +94,70 @@ namespace llvm {
///
class MachineDebugInfo : public ImmutablePass {
private:
std::map<std::string, unsigned> SourceMap; // Map of source file path to id
unsigned SourceCount; // Number of source files (used to
// generate id)
unsigned UniqueID; // Number used to unique labels used
// by debugger.
// DirectoryMap - UniqueVector for directories.
UniqueVector<std::string> Directories;
// SourceMap - UniqueVector for source files.
UniqueVector<SourceFileInfo> SourceFiles;
// Lines - List of of source line correspondence.
std::vector<SourceLineInfo *> Lines;
public:
// Ctor.
MachineDebugInfo()
: SourceMap()
, SourceCount(0)
, UniqueID(1)
: Directories()
, SourceFiles()
, Lines()
{}
~MachineDebugInfo() { }
/// hasInfo - Returns true if debug info is present.
/// doInitialization - Initialize the debug state for a new module.
///
// FIXME - need scheme to suppress debug output.
bool hasInfo() const { return SourceCount != 0; }
/// getNextUniqueID - Returns a unique number for labels used by debugger.
///
unsigned getNextUniqueID() { return UniqueID++; }
/// RecordLabel - Records location information and associates it with a
/// debug label. Returns unique label id.
unsigned RecordLabel(unsigned Line, unsigned Col, unsigned SrcFile) {
// FIXME - actually record.
return getNextUniqueID();
}
bool doInitialization();
/// doFinalization - Tear down the debug state after completion of a module.
///
bool doFinalization();
/// getUniqueSourceID - Register a source file with debug info. Returns an id.
/// hasInfo - Returns true if debug info is present.
///
unsigned getUniqueSourceID(const std::string &fname,
const std::string &dirname);
// FIXME - need proper scheme to suppress debug output.
bool hasInfo() const { return !SourceFiles.empty(); }
/// getSourceFiles - Return a vector of files. Vector index + 1 equals id.
/// RecordLabel - Records location information and associates it with a
/// debug label. Returns a unique label ID used to generate a label and
/// provide correspondence to the source line list.
unsigned RecordLabel(unsigned Line, unsigned Column, unsigned Source) {
Lines.push_back(new SourceLineInfo(Line, Column, Source));
return Lines.size();
}
/// RecordSource - Register a source file with debug info. Returns an source
/// ID.
unsigned RecordSource(const std::string &Directory,
const std::string &Source) {
unsigned DirectoryID = Directories.insert(Directory);
return SourceFiles.insert(SourceFileInfo(DirectoryID, Source));
}
/// getDirectories - Return the UniqueVector of std::string representing
/// directories.
const UniqueVector<std::string> &getDirectories() const {
return Directories;
}
/// getSourceFiles - Return the UniqueVector of source files.
///
std::vector<std::string> getSourceFiles() const;
const UniqueVector<SourceFileInfo> &getSourceFiles() const {
return SourceFiles;
}
/// getSourceLines - Return a vector of source lines. Vector index + 1
/// equals label ID.
const std::vector<SourceLineInfo *> &getSourceLines() const {
return Lines;
}
}; // End class MachineDebugInfo

File diff suppressed because it is too large Load Diff

View File

@ -6,11 +6,6 @@
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Collect debug information for a module. This information should be in a
// neutral form that can be used by different debugging schemes.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/MachineDebugInfo.h"
@ -20,7 +15,9 @@ using namespace llvm;
namespace {
RegisterPass<MachineDebugInfo> X("machinedebuginfo", "Debug Information");
}
//===----------------------------------------------------------------------===//
/// doInitialization - Initialize the debug state for a new module.
///
bool MachineDebugInfo::doInitialization() {
@ -32,38 +29,3 @@ bool MachineDebugInfo::doInitialization() {
bool MachineDebugInfo::doFinalization() {
return false;
}
/// getUniqueSourceID - Register a source file with debug info. Returns an id.
///
unsigned MachineDebugInfo::getUniqueSourceID(const std::string &fname,
const std::string &dirname) {
// Compose a key
const std::string path = dirname + "/" + fname;
// Check if the source file is already recorded
std::map<std::string, unsigned>::iterator
SMI = SourceMap.lower_bound(path);
// If already there return existing id
if (SMI != SourceMap.end() && SMI->first == path) return SMI->second;
// Bump up the count
++SourceCount;
// Record the count
SourceMap.insert(SMI, std::make_pair(path, SourceCount));
// Return id
return SourceCount;
}
/// getSourceFiles - Return a vector of files. Vector index + 1 equals id.
///
std::vector<std::string> MachineDebugInfo::getSourceFiles() const {
std::vector<std::string> Sources(SourceCount);
for (std::map<std::string, unsigned>::const_iterator SMI = SourceMap.begin(),
E = SourceMap.end();
SMI != E; SMI++) {
unsigned Index = SMI->second - 1;
const std::string &Path = SMI->first;
Sources[Index] = Path;
}
return Sources;
}

View File

@ -627,7 +627,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
cast<StringSDNode>(Node->getOperand(3))->getValue();
const std::string &DirName =
cast<StringSDNode>(Node->getOperand(4))->getValue();
unsigned SrcFile = DebugInfo->getUniqueSourceID(FName, DirName);
unsigned SrcFile = DebugInfo->RecordSource(DirName, FName);
std::vector<SDOperand> Ops;
Ops.push_back(Tmp1); // chain

View File

@ -215,9 +215,11 @@ namespace {
: DwarfWriter(o, ap)
{
needsSet = true;
DwarfAbbrevSection = ".section __DWARFA,__debug_abbrev,regular,debug";
DwarfInfoSection = ".section __DWARFA,__debug_info,regular,debug";
DwarfLineSection = ".section __DWARFA,__debug_line,regular,debug";
DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug";
DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug";
DwarfLineSection = ".section __DWARF,__debug_line,regular,debug";
TextSection = ".text";
DataSection = ".data";
}
};
@ -607,6 +609,9 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
}
}
// Emit initial debug information.
DW.EndModule();
// Funny Darwin hack: This flag tells the linker that no global symbols
// contain code that falls through to other global symbols (e.g. the obvious
// implementation of multiple entry points). If this doesn't occur, the
@ -614,9 +619,6 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
// code that does this, it is always safe to set.
O << "\t.subsections_via_symbols\n";
// Emit initial debug information.
DW.EndModule();
AsmPrinter::doFinalization(M);
return false; // success
}