summaryrefslogtreecommitdiffstats
path: root/lib/DebugInfo
diff options
context:
space:
mode:
Diffstat (limited to 'lib/DebugInfo')
-rw-r--r--lib/DebugInfo/DWARFCompileUnit.cpp25
-rw-r--r--lib/DebugInfo/DWARFCompileUnit.h9
-rw-r--r--lib/DebugInfo/DWARFContext.cpp74
-rw-r--r--lib/DebugInfo/DWARFContext.h3
-rw-r--r--lib/DebugInfo/DWARFDebugAranges.cpp2
-rw-r--r--lib/DebugInfo/DWARFDebugInfoEntry.cpp51
-rw-r--r--lib/DebugInfo/DWARFDebugInfoEntry.h9
-rw-r--r--lib/DebugInfo/DWARFDebugLine.cpp117
-rw-r--r--lib/DebugInfo/DWARFDebugLine.h68
9 files changed, 283 insertions, 75 deletions
diff --git a/lib/DebugInfo/DWARFCompileUnit.cpp b/lib/DebugInfo/DWARFCompileUnit.cpp
index 24bf97f..b27d57b 100644
--- a/lib/DebugInfo/DWARFCompileUnit.cpp
+++ b/lib/DebugInfo/DWARFCompileUnit.cpp
@@ -82,7 +82,7 @@ void DWARFCompileUnit::clear() {
Abbrevs = 0;
AddrSize = 0;
BaseAddr = 0;
- DieArray.clear();
+ clearDIEs(false);
}
void DWARFCompileUnit::dump(raw_ostream &OS) {
@@ -97,6 +97,13 @@ void DWARFCompileUnit::dump(raw_ostream &OS) {
getCompileUnitDIE(false)->dump(OS, this, -1U);
}
+const char *DWARFCompileUnit::getCompilationDir() {
+ extractDIEsIfNeeded(true);
+ if (DieArray.empty())
+ return 0;
+ return DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, 0);
+}
+
void DWARFCompileUnit::setDIERelations() {
if (DieArray.empty())
return;
@@ -201,7 +208,7 @@ size_t DWARFCompileUnit::extractDIEsIfNeeded(bool cu_die_only) {
}
void DWARFCompileUnit::clearDIEs(bool keep_compile_unit_die) {
- if (DieArray.size() > 1) {
+ if (DieArray.size() > (unsigned)keep_compile_unit_die) {
// std::vectors never get any smaller when resized to a smaller size,
// or when clear() or erase() are called, the size will report that it
// is smaller, but the memory allocated remains intact (call capacity()
@@ -227,8 +234,8 @@ DWARFCompileUnit::buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
// all compile units to stay loaded when they weren't needed. So we can end
// up parsing the DWARF and then throwing them all away to keep memory usage
// down.
- const bool clear_dies = extractDIEsIfNeeded(false) > 1;
-
+ const bool clear_dies = extractDIEsIfNeeded(false) > 1 &&
+ clear_dies_if_already_not_parsed;
DieArray[0].buildAddressRangeTable(this, debug_aranges);
// Keep memory down by clearing DIEs if this generate function
@@ -236,3 +243,13 @@ DWARFCompileUnit::buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
if (clear_dies)
clearDIEs(true);
}
+
+const DWARFDebugInfoEntryMinimal*
+DWARFCompileUnit::getFunctionDIEForAddress(int64_t address) {
+ extractDIEsIfNeeded(false);
+ for (size_t i = 0, n = DieArray.size(); i != n; i++) {
+ if (DieArray[i].addressRangeContainsAddress(this, address))
+ return &DieArray[i];
+ }
+ return 0;
+}
diff --git a/lib/DebugInfo/DWARFCompileUnit.h b/lib/DebugInfo/DWARFCompileUnit.h
index d916729..b34a596 100644
--- a/lib/DebugInfo/DWARFCompileUnit.h
+++ b/lib/DebugInfo/DWARFCompileUnit.h
@@ -43,7 +43,7 @@ public:
const DWARFAbbreviationDeclarationSet *abbrevs);
/// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it
- /// hasn't already been done.
+ /// hasn't already been done. Returns the number of DIEs parsed at this call.
size_t extractDIEsIfNeeded(bool cu_die_only);
void clear();
void dump(raw_ostream &OS);
@@ -78,6 +78,8 @@ public:
return &DieArray[0];
}
+ const char *getCompilationDir();
+
/// setDIERelations - We read in all of the DIE entries into our flat list
/// of DIE entries and now we need to go back through all of them and set the
/// parent, sibling and child pointers for quick DIE navigation.
@@ -104,6 +106,11 @@ public:
void buildAddressRangeTable(DWARFDebugAranges *debug_aranges,
bool clear_dies_if_already_not_parsed);
+ /// getFunctionDIEForAddress - Returns pointer to parsed subprogram DIE,
+ /// address ranges of which contain the provided address,
+ /// or NULL if there is no such subprogram. The pointer
+ /// is valid until DWARFCompileUnit::clear() or clearDIEs() is called.
+ const DWARFDebugInfoEntryMinimal *getFunctionDIEForAddress(int64_t address);
};
}
diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp
index dccadc4..797662b 100644
--- a/lib/DebugInfo/DWARFContext.cpp
+++ b/lib/DebugInfo/DWARFContext.cpp
@@ -8,8 +8,10 @@
//===----------------------------------------------------------------------===//
#include "DWARFContext.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
using namespace llvm;
@@ -140,30 +142,64 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t offset) {
return 0;
}
-DILineInfo DWARFContext::getLineInfoForAddress(uint64_t address) {
+DILineInfo DWARFContext::getLineInfoForAddress(uint64_t address,
+ DILineInfoSpecifier specifier) {
// First, get the offset of the compile unit.
uint32_t cuOffset = getDebugAranges()->findAddress(address);
// Retrieve the compile unit.
DWARFCompileUnit *cu = getCompileUnitForOffset(cuOffset);
if (!cu)
- return DILineInfo("<invalid>", 0, 0);
- // Get the line table for this compile unit.
- const DWARFDebugLine::LineTable *lineTable = getLineTableForCompileUnit(cu);
- if (!lineTable)
- return DILineInfo("<invalid>", 0, 0);
- // Get the index of the row we're looking for in the line table.
- uint64_t hiPC =
- cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_high_pc,
- -1ULL);
- uint32_t rowIndex = lineTable->lookupAddress(address, hiPC);
- if (rowIndex == -1U)
- return DILineInfo("<invalid>", 0, 0);
-
- // From here, contruct the DILineInfo.
- const DWARFDebugLine::Row &row = lineTable->Rows[rowIndex];
- const std::string &fileName = lineTable->Prologue.FileNames[row.File-1].Name;
-
- return DILineInfo(fileName.c_str(), row.Line, row.Column);
+ return DILineInfo();
+ SmallString<16> fileName("<invalid>");
+ SmallString<16> functionName("<invalid>");
+ uint32_t line = 0;
+ uint32_t column = 0;
+ if (specifier.needs(DILineInfoSpecifier::FunctionName)) {
+ const DWARFDebugInfoEntryMinimal *function_die =
+ cu->getFunctionDIEForAddress(address);
+ if (function_die) {
+ if (const char *name = function_die->getSubprogramName(cu))
+ functionName = name;
+ }
+ }
+ if (specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
+ // Get the line table for this compile unit.
+ const DWARFDebugLine::LineTable *lineTable = getLineTableForCompileUnit(cu);
+ if (lineTable) {
+ // Get the index of the row we're looking for in the line table.
+ uint32_t rowIndex = lineTable->lookupAddress(address);
+ if (rowIndex != -1U) {
+ const DWARFDebugLine::Row &row = lineTable->Rows[rowIndex];
+ // Take file/line info from the line table.
+ const DWARFDebugLine::FileNameEntry &fileNameEntry =
+ lineTable->Prologue.FileNames[row.File - 1];
+ fileName = fileNameEntry.Name;
+ if (specifier.needs(DILineInfoSpecifier::AbsoluteFilePath) &&
+ sys::path::is_relative(fileName.str())) {
+ // Append include directory of file (if it is present in line table)
+ // and compilation directory of compile unit to make path absolute.
+ const char *includeDir = 0;
+ if (uint64_t includeDirIndex = fileNameEntry.DirIdx) {
+ includeDir = lineTable->Prologue
+ .IncludeDirectories[includeDirIndex - 1];
+ }
+ SmallString<16> absFileName;
+ if (includeDir == 0 || sys::path::is_relative(includeDir)) {
+ if (const char *compilationDir = cu->getCompilationDir())
+ sys::path::append(absFileName, compilationDir);
+ }
+ if (includeDir) {
+ sys::path::append(absFileName, includeDir);
+ }
+ sys::path::append(absFileName, fileName.str());
+ fileName = absFileName;
+ }
+ line = row.Line;
+ column = row.Column;
+ }
+ }
+ }
+ return DILineInfo(fileName, functionName, line, column);
}
void DWARFContextInMemory::anchor() { }
diff --git a/lib/DebugInfo/DWARFContext.h b/lib/DebugInfo/DWARFContext.h
index d2e763a..e55a27e 100644
--- a/lib/DebugInfo/DWARFContext.h
+++ b/lib/DebugInfo/DWARFContext.h
@@ -66,7 +66,8 @@ public:
const DWARFDebugLine::LineTable *
getLineTableForCompileUnit(DWARFCompileUnit *cu);
- virtual DILineInfo getLineInfoForAddress(uint64_t address);
+ virtual DILineInfo getLineInfoForAddress(uint64_t address,
+ DILineInfoSpecifier specifier = DILineInfoSpecifier());
bool isLittleEndian() const { return IsLittleEndian; }
diff --git a/lib/DebugInfo/DWARFDebugAranges.cpp b/lib/DebugInfo/DWARFDebugAranges.cpp
index 1788145..ef470e5 100644
--- a/lib/DebugInfo/DWARFDebugAranges.cpp
+++ b/lib/DebugInfo/DWARFDebugAranges.cpp
@@ -93,6 +93,7 @@ bool DWARFDebugAranges::generate(DWARFContext *ctx) {
cu->buildAddressRangeTable(this, true);
}
}
+ sort(true, /* overlap size */ 0);
return !isEmpty();
}
@@ -221,4 +222,3 @@ bool DWARFDebugAranges::getMaxRange(uint64_t &LoPC, uint64_t &HiPC) const {
HiPC = Aranges.back().HiPC();
return true;
}
-
diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.cpp b/lib/DebugInfo/DWARFDebugInfoEntry.cpp
index 236db97..429a36c 100644
--- a/lib/DebugInfo/DWARFDebugInfoEntry.cpp
+++ b/lib/DebugInfo/DWARFDebugInfoEntry.cpp
@@ -440,3 +440,54 @@ DWARFDebugInfoEntryMinimal::buildAddressRangeTable(const DWARFCompileUnit *cu,
}
}
}
+
+bool
+DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
+ const DWARFCompileUnit *cu, const uint64_t address) const {
+ if (!isNULL() && getTag() == DW_TAG_subprogram) {
+ uint64_t hi_pc = -1ULL;
+ uint64_t lo_pc = getAttributeValueAsUnsigned(cu, DW_AT_low_pc, -1ULL);
+ if (lo_pc != -1ULL)
+ hi_pc = getAttributeValueAsUnsigned(cu, DW_AT_high_pc, -1ULL);
+ if (hi_pc != -1ULL) {
+ return (lo_pc <= address && address < hi_pc);
+ }
+ }
+ return false;
+}
+
+const char*
+DWARFDebugInfoEntryMinimal::getSubprogramName(
+ const DWARFCompileUnit *cu) const {
+ if (isNULL() || getTag() != DW_TAG_subprogram)
+ return 0;
+ // Try to get mangled name if possible.
+ if (const char *name =
+ getAttributeValueAsString(cu, DW_AT_MIPS_linkage_name, 0))
+ return name;
+ if (const char *name = getAttributeValueAsString(cu, DW_AT_linkage_name, 0))
+ return name;
+ if (const char *name = getAttributeValueAsString(cu, DW_AT_name, 0))
+ return name;
+ // Try to get name from specification DIE.
+ uint32_t spec_ref =
+ getAttributeValueAsReference(cu, DW_AT_specification, -1U);
+ if (spec_ref != -1U) {
+ DWARFDebugInfoEntryMinimal spec_die;
+ if (spec_die.extract(cu, &spec_ref)) {
+ if (const char *name = spec_die.getSubprogramName(cu))
+ return name;
+ }
+ }
+ // Try to get name from abstract origin DIE.
+ uint32_t abs_origin_ref =
+ getAttributeValueAsReference(cu, DW_AT_abstract_origin, -1U);
+ if (abs_origin_ref != -1U) {
+ DWARFDebugInfoEntryMinimal abs_origin_die;
+ if (abs_origin_die.extract(cu, &abs_origin_ref)) {
+ if (const char *name = abs_origin_die.getSubprogramName(cu))
+ return name;
+ }
+ }
+ return 0;
+}
diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.h b/lib/DebugInfo/DWARFDebugInfoEntry.h
index 37b3bcd..d5d86b9 100644
--- a/lib/DebugInfo/DWARFDebugInfoEntry.h
+++ b/lib/DebugInfo/DWARFDebugInfoEntry.h
@@ -128,6 +128,15 @@ public:
void buildAddressRangeTable(const DWARFCompileUnit *cu,
DWARFDebugAranges *debug_aranges) const;
+
+ bool addressRangeContainsAddress(const DWARFCompileUnit *cu,
+ const uint64_t address) const;
+
+ // If a DIE represents a subprogram, returns its mangled name
+ // (or short name, if mangled is missing). This name may be fetched
+ // from specification or abstract origin for this subprogram.
+ // Returns null if no name is found.
+ const char* getSubprogramName(const DWARFCompileUnit *cu) const;
};
}
diff --git a/lib/DebugInfo/DWARFDebugLine.cpp b/lib/DebugInfo/DWARFDebugLine.cpp
index 117fa31..d99575d 100644
--- a/lib/DebugInfo/DWARFDebugLine.cpp
+++ b/lib/DebugInfo/DWARFDebugLine.cpp
@@ -95,14 +95,46 @@ void DWARFDebugLine::LineTable::dump(raw_ostream &OS) const {
DWARFDebugLine::State::~State() {}
void DWARFDebugLine::State::appendRowToMatrix(uint32_t offset) {
+ if (Sequence::Empty) {
+ // Record the beginning of instruction sequence.
+ Sequence::Empty = false;
+ Sequence::LowPC = Address;
+ Sequence::FirstRowIndex = row;
+ }
++row; // Increase the row number.
LineTable::appendRow(*this);
+ if (EndSequence) {
+ // Record the end of instruction sequence.
+ Sequence::HighPC = Address;
+ Sequence::LastRowIndex = row;
+ if (Sequence::isValid())
+ LineTable::appendSequence(*this);
+ Sequence::reset();
+ }
Row::postAppend();
}
+void DWARFDebugLine::State::finalize() {
+ row = DoneParsingLineTable;
+ if (!Sequence::Empty) {
+ fprintf(stderr, "warning: last sequence in debug line table is not"
+ "terminated!\n");
+ }
+ // Sort all sequences so that address lookup will work faster.
+ if (!Sequences.empty()) {
+ std::sort(Sequences.begin(), Sequences.end(), Sequence::orderByLowPC);
+ // Note: actually, instruction address ranges of sequences should not
+ // overlap (in shared objects and executables). If they do, the address
+ // lookup would still work, though, but result would be ambiguous.
+ // We don't report warning in this case. For example,
+ // sometimes .so compiled from multiple object files contains a few
+ // rudimentary sequences for address ranges [0x0, 0xsomething).
+ }
+}
+
DWARFDebugLine::DumpingState::~DumpingState() {}
-void DWARFDebugLine::DumpingState::finalize(uint32_t offset) {
+void DWARFDebugLine::DumpingState::finalize() {
LineTable::dump(OS);
}
@@ -180,8 +212,9 @@ DWARFDebugLine::parsePrologue(DataExtractor debug_line_data,
fprintf(stderr, "warning: parsing line table prologue at 0x%8.8x should"
" have ended at 0x%8.8x but it ended ad 0x%8.8x\n",
prologue_offset, end_prologue_offset, *offset_ptr);
+ return false;
}
- return end_prologue_offset;
+ return true;
}
bool
@@ -430,47 +463,53 @@ DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data,
}
}
- state.finalize(*offset_ptr);
+ state.finalize();
return end_offset;
}
-static bool findMatchingAddress(const DWARFDebugLine::Row& row1,
- const DWARFDebugLine::Row& row2) {
- return row1.Address < row2.Address;
-}
-
uint32_t
-DWARFDebugLine::LineTable::lookupAddress(uint64_t address,
- uint64_t cu_high_pc) const {
- uint32_t index = UINT32_MAX;
- if (!Rows.empty()) {
- // Use the lower_bound algorithm to perform a binary search since we know
- // that our line table data is ordered by address.
- DWARFDebugLine::Row row;
- row.Address = address;
- typedef std::vector<Row>::const_iterator iterator;
- iterator begin_pos = Rows.begin();
- iterator end_pos = Rows.end();
- iterator pos = std::lower_bound(begin_pos, end_pos, row,
- findMatchingAddress);
- if (pos == end_pos) {
- if (address < cu_high_pc)
- return Rows.size()-1;
- } else {
- // Rely on fact that we are using a std::vector and we can do
- // pointer arithmetic to find the row index (which will be one less
- // that what we found since it will find the first position after
- // the current address) since std::vector iterators are just
- // pointers to the container type.
- index = pos - begin_pos;
- if (pos->Address > address) {
- if (index > 0)
- --index;
- else
- index = UINT32_MAX;
- }
- }
+DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const {
+ uint32_t unknown_index = UINT32_MAX;
+ if (Sequences.empty())
+ return unknown_index;
+ // First, find an instruction sequence containing the given address.
+ DWARFDebugLine::Sequence sequence;
+ sequence.LowPC = address;
+ SequenceIter first_seq = Sequences.begin();
+ SequenceIter last_seq = Sequences.end();
+ SequenceIter seq_pos = std::lower_bound(first_seq, last_seq, sequence,
+ DWARFDebugLine::Sequence::orderByLowPC);
+ DWARFDebugLine::Sequence found_seq;
+ if (seq_pos == last_seq) {
+ found_seq = Sequences.back();
+ } else if (seq_pos->LowPC == address) {
+ found_seq = *seq_pos;
+ } else {
+ if (seq_pos == first_seq)
+ return unknown_index;
+ found_seq = *(seq_pos - 1);
+ }
+ if (!found_seq.containsPC(address))
+ return unknown_index;
+ // Search for instruction address in the rows describing the sequence.
+ // Rows are stored in a vector, so we may use arithmetical operations with
+ // iterators.
+ DWARFDebugLine::Row row;
+ row.Address = address;
+ RowIter first_row = Rows.begin() + found_seq.FirstRowIndex;
+ RowIter last_row = Rows.begin() + found_seq.LastRowIndex;
+ RowIter row_pos = std::lower_bound(first_row, last_row, row,
+ DWARFDebugLine::Row::orderByAddress);
+ if (row_pos == last_row) {
+ return found_seq.LastRowIndex - 1;
+ }
+ uint32_t index = found_seq.FirstRowIndex + (row_pos - first_row);
+ if (row_pos->Address > address) {
+ if (row_pos == first_row)
+ return unknown_index;
+ else
+ index--;
}
- return index; // Failed to find address.
+ return index;
}
diff --git a/lib/DebugInfo/DWARFDebugLine.h b/lib/DebugInfo/DWARFDebugLine.h
index bc6a70b..6382b45 100644
--- a/lib/DebugInfo/DWARFDebugLine.h
+++ b/lib/DebugInfo/DWARFDebugLine.h
@@ -12,7 +12,6 @@
#include "llvm/Support/DataExtractor.h"
#include <map>
-#include <string>
#include <vector>
namespace llvm {
@@ -22,9 +21,9 @@ class raw_ostream;
class DWARFDebugLine {
public:
struct FileNameEntry {
- FileNameEntry() : DirIdx(0), ModTime(0), Length(0) {}
+ FileNameEntry() : Name(0), DirIdx(0), ModTime(0), Length(0) {}
- std::string Name;
+ const char *Name;
uint64_t DirIdx;
uint64_t ModTime;
uint64_t Length;
@@ -56,7 +55,7 @@ public:
// The number assigned to the first special opcode.
uint8_t OpcodeBase;
std::vector<uint8_t> StandardOpcodeLengths;
- std::vector<std::string> IncludeDirectories;
+ std::vector<const char*> IncludeDirectories;
std::vector<FileNameEntry> FileNames;
// Length of the prologue in bytes.
@@ -89,6 +88,10 @@ public:
void reset(bool default_is_stmt);
void dump(raw_ostream &OS) const;
+ static bool orderByAddress(const Row& LHS, const Row& RHS) {
+ return LHS.Address < RHS.Address;
+ }
+
// The program-counter value corresponding to a machine instruction
// generated by the compiler.
uint64_t Address;
@@ -126,21 +129,63 @@ public:
EpilogueBegin:1;
};
+ // Represents a series of contiguous machine instructions. Line table for each
+ // compilation unit may consist of multiple sequences, which are not
+ // guaranteed to be in the order of ascending instruction address.
+ struct Sequence {
+ // Sequence describes instructions at address range [LowPC, HighPC)
+ // and is described by line table rows [FirstRowIndex, LastRowIndex).
+ uint64_t LowPC;
+ uint64_t HighPC;
+ unsigned FirstRowIndex;
+ unsigned LastRowIndex;
+ bool Empty;
+
+ Sequence() { reset(); }
+ void reset() {
+ LowPC = 0;
+ HighPC = 0;
+ FirstRowIndex = 0;
+ LastRowIndex = 0;
+ Empty = true;
+ }
+ static bool orderByLowPC(const Sequence& LHS, const Sequence& RHS) {
+ return LHS.LowPC < RHS.LowPC;
+ }
+ bool isValid() const {
+ return !Empty && (LowPC < HighPC) && (FirstRowIndex < LastRowIndex);
+ }
+ bool containsPC(uint64_t pc) const {
+ return (LowPC <= pc && pc < HighPC);
+ }
+ };
+
struct LineTable {
void appendRow(const DWARFDebugLine::Row &state) { Rows.push_back(state); }
+ void appendSequence(const DWARFDebugLine::Sequence &sequence) {
+ Sequences.push_back(sequence);
+ }
void clear() {
Prologue.clear();
Rows.clear();
+ Sequences.clear();
}
- uint32_t lookupAddress(uint64_t address, uint64_t cu_high_pc) const;
+ // Returns the index of the row with file/line info for a given address,
+ // or -1 if there is no such row.
+ uint32_t lookupAddress(uint64_t address) const;
void dump(raw_ostream &OS) const;
struct Prologue Prologue;
- std::vector<Row> Rows;
+ typedef std::vector<Row> RowVector;
+ typedef RowVector::const_iterator RowIter;
+ typedef std::vector<Sequence> SequenceVector;
+ typedef SequenceVector::const_iterator SequenceIter;
+ RowVector Rows;
+ SequenceVector Sequences;
};
- struct State : public Row, public LineTable {
+ struct State : public Row, public Sequence, public LineTable {
// Special row codes.
enum {
StartParsingLineTable = 0,
@@ -151,8 +196,11 @@ public:
virtual ~State();
virtual void appendRowToMatrix(uint32_t offset);
- virtual void finalize(uint32_t offset) { row = DoneParsingLineTable; }
- virtual void reset() { Row::reset(Prologue.DefaultIsStmt); }
+ virtual void finalize();
+ virtual void reset() {
+ Row::reset(Prologue.DefaultIsStmt);
+ Sequence::reset();
+ }
// The row number that starts at zero for the prologue, and increases for
// each row added to the matrix.
@@ -162,7 +210,7 @@ public:
struct DumpingState : public State {
DumpingState(raw_ostream &OS) : OS(OS) {}
virtual ~DumpingState();
- virtual void finalize(uint32_t offset);
+ virtual void finalize();
private:
raw_ostream &OS;
};
OpenPOWER on IntegriCloud