1 | //===- Line.h ---------------------------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLVM_DEBUGINFO_CODEVIEW_LINE_H |
10 | #define LLVM_DEBUGINFO_CODEVIEW_LINE_H |
11 | |
12 | #include "llvm/Support/Endian.h" |
13 | #include <cinttypes> |
14 | |
15 | namespace llvm { |
16 | namespace codeview { |
17 | |
18 | using llvm::support::ulittle32_t; |
19 | |
20 | class LineInfo { |
21 | public: |
22 | enum : uint32_t { |
23 | AlwaysStepIntoLineNumber = 0xfeefee, |
24 | NeverStepIntoLineNumber = 0xf00f00 |
25 | }; |
26 | |
27 | enum : int { EndLineDeltaShift = 24 }; |
28 | |
29 | enum : uint32_t { |
30 | StartLineMask = 0x00ffffff, |
31 | EndLineDeltaMask = 0x7f000000, |
32 | StatementFlag = 0x80000000u |
33 | }; |
34 | |
35 | LineInfo(uint32_t StartLine, uint32_t EndLine, bool IsStatement); |
36 | LineInfo(uint32_t LineData) : LineData(LineData) {} |
37 | |
38 | uint32_t getStartLine() const { return LineData & StartLineMask; } |
39 | |
40 | uint32_t getLineDelta() const { |
41 | return (LineData & EndLineDeltaMask) >> EndLineDeltaShift; |
42 | } |
43 | |
44 | uint32_t getEndLine() const { return getStartLine() + getLineDelta(); } |
45 | |
46 | bool isStatement() const { return (LineData & StatementFlag) != 0; } |
47 | |
48 | uint32_t getRawData() const { return LineData; } |
49 | |
50 | bool isAlwaysStepInto() const { |
51 | return getStartLine() == AlwaysStepIntoLineNumber; |
52 | } |
53 | |
54 | bool isNeverStepInto() const { |
55 | return getStartLine() == NeverStepIntoLineNumber; |
56 | } |
57 | |
58 | private: |
59 | uint32_t LineData; |
60 | }; |
61 | |
62 | class ColumnInfo { |
63 | private: |
64 | static const uint32_t StartColumnMask = 0x0000ffffu; |
65 | static const uint32_t EndColumnMask = 0xffff0000u; |
66 | static const int EndColumnShift = 16; |
67 | |
68 | public: |
69 | ColumnInfo(uint16_t StartColumn, uint16_t EndColumn) { |
70 | ColumnData = |
71 | (static_cast<uint32_t>(StartColumn) & StartColumnMask) | |
72 | ((static_cast<uint32_t>(EndColumn) << EndColumnShift) & EndColumnMask); |
73 | } |
74 | |
75 | uint16_t getStartColumn() const { |
76 | return static_cast<uint16_t>(ColumnData & StartColumnMask); |
77 | } |
78 | |
79 | uint16_t getEndColumn() const { |
80 | return static_cast<uint16_t>((ColumnData & EndColumnMask) >> |
81 | EndColumnShift); |
82 | } |
83 | |
84 | uint32_t getRawData() const { return ColumnData; } |
85 | |
86 | private: |
87 | uint32_t ColumnData; |
88 | }; |
89 | |
90 | class Line { |
91 | private: |
92 | int32_t CodeOffset; |
93 | LineInfo LineInf; |
94 | ColumnInfo ColumnInf; |
95 | |
96 | public: |
97 | Line(int32_t CodeOffset, uint32_t StartLine, uint32_t EndLine, |
98 | uint16_t StartColumn, uint16_t EndColumn, bool IsStatement) |
99 | : CodeOffset(CodeOffset), LineInf(StartLine, EndLine, IsStatement), |
100 | ColumnInf(StartColumn, EndColumn) {} |
101 | |
102 | Line(int32_t CodeOffset, LineInfo LineInf, ColumnInfo ColumnInf) |
103 | : CodeOffset(CodeOffset), LineInf(LineInf), ColumnInf(ColumnInf) {} |
104 | |
105 | LineInfo getLineInfo() const { return LineInf; } |
106 | |
107 | ColumnInfo getColumnInfo() const { return ColumnInf; } |
108 | |
109 | int32_t getCodeOffset() const { return CodeOffset; } |
110 | |
111 | uint32_t getStartLine() const { return LineInf.getStartLine(); } |
112 | |
113 | uint32_t getLineDelta() const { return LineInf.getLineDelta(); } |
114 | |
115 | uint32_t getEndLine() const { return LineInf.getEndLine(); } |
116 | |
117 | uint16_t getStartColumn() const { return ColumnInf.getStartColumn(); } |
118 | |
119 | uint16_t getEndColumn() const { return ColumnInf.getEndColumn(); } |
120 | |
121 | bool isStatement() const { return LineInf.isStatement(); } |
122 | |
123 | bool isAlwaysStepInto() const { return LineInf.isAlwaysStepInto(); } |
124 | |
125 | bool isNeverStepInto() const { return LineInf.isNeverStepInto(); } |
126 | }; |
127 | |
128 | } // namespace codeview |
129 | } // namespace llvm |
130 | |
131 | #endif |
132 | |