33
33
using namespace clang ;
34
34
using namespace clang ::interp;
35
35
36
- template <typename T> inline static T ReadArg (Program &P, CodePtr &OpPC) {
36
+ template <typename T>
37
+ inline static std::string printArg (Program &P, CodePtr &OpPC) {
37
38
if constexpr (std::is_pointer_v<T>) {
38
39
uint32_t ID = OpPC.read <uint32_t >();
39
- return reinterpret_cast <T>(P.getNativePointer (ID));
40
+ std::string Result;
41
+ llvm::raw_string_ostream SS (Result);
42
+ SS << reinterpret_cast <T>(P.getNativePointer (ID));
43
+ return Result;
40
44
} else {
41
- return OpPC.read <T>();
45
+ std::string Result;
46
+ llvm::raw_string_ostream SS (Result);
47
+ auto Arg = OpPC.read <T>();
48
+ SS << Arg;
49
+ return Result;
42
50
}
43
51
}
44
52
45
- template <> inline Floating ReadArg <Floating>(Program &P, CodePtr &OpPC) {
46
- Floating F = Floating::deserialize (*OpPC);
53
+ template <> inline std::string printArg <Floating>(Program &P, CodePtr &OpPC) {
54
+ auto F = Floating::deserialize (*OpPC);
47
55
OpPC += align (F.bytesToSerialize ());
48
- return F;
56
+
57
+ std::string Result;
58
+ llvm::raw_string_ostream SS (Result);
59
+ SS << F;
60
+ return Result;
49
61
}
50
62
51
63
template <>
52
- inline IntegralAP<false > ReadArg<IntegralAP<false >>(Program &P, CodePtr &OpPC) {
53
- IntegralAP<false > I = IntegralAP<false >::deserialize (*OpPC);
54
- OpPC += align (I.bytesToSerialize ());
55
- return I;
56
- }
64
+ inline std::string printArg<IntegralAP<false >>(Program &P, CodePtr &OpPC) {
65
+ auto F = IntegralAP<false >::deserialize (*OpPC);
66
+ OpPC += align (F.bytesToSerialize ());
57
67
68
+ std::string Result;
69
+ llvm::raw_string_ostream SS (Result);
70
+ SS << F;
71
+ return Result;
72
+ }
58
73
template <>
59
- inline IntegralAP<true > ReadArg<IntegralAP<true >>(Program &P, CodePtr &OpPC) {
60
- IntegralAP<true > I = IntegralAP<true >::deserialize (*OpPC);
61
- OpPC += align (I.bytesToSerialize ());
62
- return I;
74
+ inline std::string printArg<IntegralAP<true >>(Program &P, CodePtr &OpPC) {
75
+ auto F = IntegralAP<true >::deserialize (*OpPC);
76
+ OpPC += align (F.bytesToSerialize ());
77
+
78
+ std::string Result;
79
+ llvm::raw_string_ostream SS (Result);
80
+ SS << F;
81
+ return Result;
63
82
}
64
83
65
- template <> inline FixedPoint ReadArg<FixedPoint>(Program &P, CodePtr &OpPC) {
66
- FixedPoint I = FixedPoint::deserialize (*OpPC);
67
- OpPC += align (I.bytesToSerialize ());
68
- return I;
84
+ template <> inline std::string printArg<FixedPoint>(Program &P, CodePtr &OpPC) {
85
+ auto F = FixedPoint::deserialize (*OpPC);
86
+ OpPC += align (F.bytesToSerialize ());
87
+
88
+ std::string Result;
89
+ llvm::raw_string_ostream SS (Result);
90
+ SS << F;
91
+ return Result;
92
+ }
93
+
94
+ static bool isJumpOpcode (Opcode Op) {
95
+ return Op == OP_Jmp || Op == OP_Jf || Op == OP_Jt;
96
+ }
97
+
98
+ static size_t getNumDisplayWidth (size_t N) {
99
+ unsigned L = 1u , M = 10u ;
100
+ while (M <= N && ++L != std::numeric_limits<size_t >::digits10 + 1 )
101
+ M *= 10u ;
102
+
103
+ return L;
69
104
}
70
105
71
106
LLVM_DUMP_METHOD void Function::dump () const { dump (llvm::errs ()); }
@@ -80,23 +115,115 @@ LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS) const {
80
115
OS << " rvo: " << hasRVO () << " \n " ;
81
116
OS << " this arg: " << hasThisPointer () << " \n " ;
82
117
83
- auto PrintName = [&OS]( const char *Name) {
84
- OS << Name ;
85
- long N = 30 - strlen (Name) ;
86
- if (N > 0 )
87
- OS. indent (N) ;
118
+ struct OpText {
119
+ size_t Addr ;
120
+ std::string Op ;
121
+ bool IsJump;
122
+ llvm::SmallVector<std::string> Args ;
88
123
};
89
124
125
+ auto PrintName = [](const char *Name) -> std::string {
126
+ return std::string (Name);
127
+ };
128
+
129
+ llvm::SmallVector<OpText> Code;
130
+ size_t LongestAddr = 0 ;
131
+ size_t LongestOp = 0 ;
132
+
90
133
for (CodePtr Start = getCodeBegin (), PC = Start; PC != getCodeEnd ();) {
91
134
size_t Addr = PC - Start;
135
+ OpText Text;
92
136
auto Op = PC.read <Opcode>();
93
- OS << llvm::format (" %8d" , Addr) << " " ;
137
+ Text.Addr = Addr;
138
+ Text.IsJump = isJumpOpcode (Op);
94
139
switch (Op) {
95
140
#define GET_DISASM
96
141
#include " Opcodes.inc"
97
142
#undef GET_DISASM
98
143
}
144
+ Code.push_back (Text);
145
+ LongestOp = std::max (Text.Op .size (), LongestOp);
146
+ LongestAddr = std::max (getNumDisplayWidth (Addr), LongestAddr);
99
147
}
148
+
149
+ // Record jumps and their targets.
150
+ struct JmpData {
151
+ size_t From;
152
+ size_t To;
153
+ };
154
+ llvm::SmallVector<JmpData> Jumps;
155
+ for (auto &Text : Code) {
156
+ if (Text.IsJump )
157
+ Jumps.push_back ({Text.Addr , Text.Addr + std::stoi (Text.Args [0 ]) +
158
+ align (sizeof (Opcode)) +
159
+ align (sizeof (int32_t ))});
160
+ }
161
+
162
+ llvm::SmallVector<std::string> Text;
163
+ Text.reserve (Code.size ());
164
+ size_t LongestLine = 0 ;
165
+ // Print code to a string, one at a time.
166
+ for (auto C : Code) {
167
+ std::string Line;
168
+ llvm::raw_string_ostream LS (Line);
169
+ LS << C.Addr ;
170
+ LS.indent (LongestAddr - getNumDisplayWidth (C.Addr ) + 4 );
171
+ LS << C.Op ;
172
+ LS.indent (LongestOp - C.Op .size () + 4 );
173
+ for (auto &Arg : C.Args ) {
174
+ LS << Arg << ' ' ;
175
+ }
176
+ Text.push_back (Line);
177
+ LongestLine = std::max (Line.size (), LongestLine);
178
+ }
179
+
180
+ assert (Code.size () == Text.size ());
181
+
182
+ auto spaces = [](unsigned N) -> std::string {
183
+ std::string S;
184
+ for (unsigned I = 0 ; I != N; ++I)
185
+ S += ' ' ;
186
+ return S;
187
+ };
188
+
189
+ // Now, draw the jump lines.
190
+ for (auto &J : Jumps) {
191
+ if (J.To > J.From ) {
192
+ bool FoundStart = false ;
193
+ for (size_t LineIndex = 0 ; LineIndex != Text.size (); ++LineIndex) {
194
+ Text[LineIndex] += spaces (LongestLine - Text[LineIndex].size ());
195
+
196
+ if (Code[LineIndex].Addr == J.From ) {
197
+ Text[LineIndex] += " --+" ;
198
+ FoundStart = true ;
199
+ } else if (Code[LineIndex].Addr == J.To ) {
200
+ Text[LineIndex] += " <-+" ;
201
+ break ;
202
+ } else if (FoundStart) {
203
+ Text[LineIndex] += " |" ;
204
+ }
205
+ }
206
+ LongestLine += 5 ;
207
+ } else {
208
+ bool FoundStart = false ;
209
+ for (ssize_t LineIndex = Text.size () - 1 ; LineIndex >= 0 ; --LineIndex) {
210
+ Text[LineIndex] += spaces (LongestLine - Text[LineIndex].size ());
211
+ if (Code[LineIndex].Addr == J.From ) {
212
+ Text[LineIndex] += " --+" ;
213
+ FoundStart = true ;
214
+ } else if (Code[LineIndex].Addr == J.To ) {
215
+ Text[LineIndex] += " <-+" ;
216
+ break ;
217
+ } else if (FoundStart) {
218
+ Text[LineIndex] += " |" ;
219
+ }
220
+ }
221
+ LongestLine += 5 ;
222
+ }
223
+ }
224
+
225
+ for (auto &Line : Text)
226
+ OS << Line << ' \n ' ;
100
227
}
101
228
102
229
LLVM_DUMP_METHOD void Program::dump () const { dump (llvm::errs ()); }
0 commit comments