3333using namespace clang ;
3434using namespace clang ::interp;
3535
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) {
3738 if constexpr (std::is_pointer_v<T>) {
3839 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;
4044 } 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;
4250 }
4351}
4452
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);
4755 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;
4961}
5062
5163template <>
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 ());
5767
68+ std::string Result;
69+ llvm::raw_string_ostream SS (Result);
70+ SS << F;
71+ return Result;
72+ }
5873template <>
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;
6382}
6483
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;
69104}
70105
71106LLVM_DUMP_METHOD void Function::dump () const { dump (llvm::errs ()); }
@@ -80,23 +115,115 @@ LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS) const {
80115 OS << " rvo: " << hasRVO () << " \n " ;
81116 OS << " this arg: " << hasThisPointer () << " \n " ;
82117
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 ;
88123 };
89124
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+
90133 for (CodePtr Start = getCodeBegin (), PC = Start; PC != getCodeEnd ();) {
91134 size_t Addr = PC - Start;
135+ OpText Text;
92136 auto Op = PC.read <Opcode>();
93- OS << llvm::format (" %8d" , Addr) << " " ;
137+ Text.Addr = Addr;
138+ Text.IsJump = isJumpOpcode (Op);
94139 switch (Op) {
95140#define GET_DISASM
96141#include " Opcodes.inc"
97142#undef GET_DISASM
98143 }
144+ Code.push_back (Text);
145+ LongestOp = std::max (Text.Op .size (), LongestOp);
146+ LongestAddr = std::max (getNumDisplayWidth (Addr), LongestAddr);
99147 }
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 ' ;
100227}
101228
102229LLVM_DUMP_METHOD void Program::dump () const { dump (llvm::errs ()); }
0 commit comments