1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-25 14:02:52 +02:00
llvm-mirror/include/llvm/DebugInfo/CodeView/Line.h
Dave Bartolomeo 5c39fdd192 LLVM CodeView library
Summary: This diff is the initial implementation of the LLVM CodeView library. There is much more work to be done, namely a CodeView dumper and tests. This patch should help others make progress on the LLVM->CodeView debug info emission while I continue with the implementation of the dumper and tests.

This library implements support for emitting debug info in the CodeView format. This phase of the implementation only includes support for CodeView type records. Clients that need to emit type records will use a class derived from TypeTableBuilder. TypeTableBuilder provides member functions for writing each kind of type record; each of these functions eventually calls the writeRecord virtual function to emit the actual bits of the record. Derived classes override writeRecord to implement the folding of duplicate records and the actual emission to the appropriate destination. LLVMCodeView provides MemoryTypeTableBuilder, which creates the table in memory. In the future, other classes derived from TypeTableBuilder will write to other destinations, such as the type stream in a PDB.

The rest of the types in LLVMCodeView define the actual CodeView type records and all of the supporting enums and other types used in the type records. The TypeIndex class is of particular interest, because it is used by clients as a handle to a type in the type table.

The library provides a relatively low-level interface based on the actual on-disk format of CodeView. For example, type records refer to other type records by TypeIndex, rather than by an actual pointer to the referent record. This allows clients to emit type records one at a time, rather than having to keep the entire transitive closure of type records in memory until everything has been emitted. At some point, having a higher-level interface layered on top of this one may be useful for debuggers and other tools that want a more holistic view of the debug info. The lower-level interface should be sufficient for compilers and linkers to do the debug info manipulation that they need to do efficiently.

Reviewers: rnk, majnemer

Subscribers: silvas, rnk, jevinskie, llvm-commits

Differential Revision: http://reviews.llvm.org/D14961

llvm-svn: 256385
2015-12-24 18:12:38 +00:00

125 lines
3.4 KiB
C++

//===- Line.h ---------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_CODEVIEW_LINE_H
#define LLVM_DEBUGINFO_CODEVIEW_LINE_H
#include <cinttypes>
namespace llvm {
namespace codeview {
class LineInfo {
public:
static const int32_t AlwaysStepIntoLineNumber = 0xfeefee;
static const int32_t NeverStepIntoLineNumber = 0xf00f00;
private:
static const uint32_t StartLineMask = 0x00ffffff;
static const uint32_t EndLineDeltaMask = 0x7f000000;
static const int EndLineDeltaShift = 24;
static const uint32_t StatementFlag = 0x80000000u;
public:
LineInfo(uint32_t StartLine, uint32_t EndLine, bool IsStatement);
uint32_t getStartLine() const { return LineData & StartLineMask; }
uint32_t getLineDelta() const {
return (LineData & EndLineDeltaMask) >> EndLineDeltaShift;
}
uint32_t getEndLine() const { return getStartLine() + getLineDelta(); }
bool isStatement() const { return (LineData & StatementFlag) != 0; }
uint32_t getRawData() const { return LineData; }
bool isAlwaysStepInto() const {
return getStartLine() == AlwaysStepIntoLineNumber;
}
bool isNeverStepInto() const {
return getStartLine() == NeverStepIntoLineNumber;
}
private:
uint32_t LineData;
};
class ColumnInfo {
private:
static const uint32_t StartColumnMask = 0x0000ffffu;
static const uint32_t EndColumnMask = 0xffff0000u;
static const int EndColumnShift = 16;
public:
ColumnInfo(uint16_t StartColumn, uint16_t EndColumn) {
ColumnData =
(static_cast<uint32_t>(StartColumn) & StartColumnMask) |
((static_cast<uint32_t>(EndColumn) << EndColumnShift) & EndColumnMask);
}
uint16_t getStartColumn() const {
return static_cast<uint16_t>(ColumnData & StartColumnMask);
}
uint16_t getEndColumn() const {
return static_cast<uint16_t>((ColumnData & EndColumnMask) >>
EndColumnShift);
}
uint32_t getRawData() const { return ColumnData; }
private:
uint32_t ColumnData;
};
class Line {
private:
int32_t CodeOffset;
LineInfo LineInf;
ColumnInfo ColumnInf;
public:
Line(int32_t CodeOffset, uint32_t StartLine, uint32_t EndLine,
uint16_t StartColumn, uint16_t EndColumn, bool IsStatement)
: CodeOffset(CodeOffset), LineInf(StartLine, EndLine, IsStatement),
ColumnInf(StartColumn, EndColumn) {}
Line(int32_t CodeOffset, LineInfo LineInf, ColumnInfo ColumnInf)
: CodeOffset(CodeOffset), LineInf(LineInf), ColumnInf(ColumnInf) {}
LineInfo getLineInfo() const { return LineInf; }
ColumnInfo getColumnInfo() const { return ColumnInf; }
int32_t getCodeOffset() const { return CodeOffset; }
uint32_t getStartLine() const { return LineInf.getStartLine(); }
uint32_t getLineDelta() const { return LineInf.getLineDelta(); }
uint32_t getEndLine() const { return LineInf.getEndLine(); }
uint16_t getStartColumn() const { return ColumnInf.getStartColumn(); }
uint16_t getEndColumn() const { return ColumnInf.getEndColumn(); }
bool isStatement() const { return LineInf.isStatement(); }
bool isAlwaysStepInto() const { return LineInf.isAlwaysStepInto(); }
bool isNeverStepInto() const { return LineInf.isNeverStepInto(); }
};
}
}
#endif