xref: /freebsd-src/contrib/llvm-project/clang/lib/AST/Interp/Disasm.cpp (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
1a7dea167SDimitry Andric //===--- Disasm.cpp - Disassembler for bytecode functions -------*- C++ -*-===//
2a7dea167SDimitry Andric //
3a7dea167SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4a7dea167SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5a7dea167SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a7dea167SDimitry Andric //
7a7dea167SDimitry Andric //===----------------------------------------------------------------------===//
8a7dea167SDimitry Andric //
9a7dea167SDimitry Andric // Dump method for Function which disassembles the bytecode.
10a7dea167SDimitry Andric //
11a7dea167SDimitry Andric //===----------------------------------------------------------------------===//
12a7dea167SDimitry Andric 
13a7dea167SDimitry Andric #include "Function.h"
14a7dea167SDimitry Andric #include "Opcode.h"
15a7dea167SDimitry Andric #include "PrimType.h"
16a7dea167SDimitry Andric #include "Program.h"
17a7dea167SDimitry Andric #include "clang/AST/DeclCXX.h"
18a7dea167SDimitry Andric #include "llvm/Support/Compiler.h"
195ffd83dbSDimitry Andric #include "llvm/Support/Format.h"
20a7dea167SDimitry Andric 
21a7dea167SDimitry Andric using namespace clang;
22a7dea167SDimitry Andric using namespace clang::interp;
23a7dea167SDimitry Andric 
24*349cc55cSDimitry Andric template <typename T>
25*349cc55cSDimitry Andric inline std::enable_if_t<!std::is_pointer<T>::value, T> ReadArg(Program &P,
26*349cc55cSDimitry Andric                                                                CodePtr OpPC) {
27*349cc55cSDimitry Andric   return OpPC.read<T>();
28*349cc55cSDimitry Andric }
29*349cc55cSDimitry Andric 
30*349cc55cSDimitry Andric template <typename T>
31*349cc55cSDimitry Andric inline std::enable_if_t<std::is_pointer<T>::value, T> ReadArg(Program &P,
32*349cc55cSDimitry Andric                                                               CodePtr OpPC) {
33*349cc55cSDimitry Andric   uint32_t ID = OpPC.read<uint32_t>();
34*349cc55cSDimitry Andric   return reinterpret_cast<T>(P.getNativePointer(ID));
35*349cc55cSDimitry Andric }
36*349cc55cSDimitry Andric 
37a7dea167SDimitry Andric LLVM_DUMP_METHOD void Function::dump() const { dump(llvm::errs()); }
38a7dea167SDimitry Andric 
39a7dea167SDimitry Andric LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS) const {
40a7dea167SDimitry Andric   if (F) {
41a7dea167SDimitry Andric     if (auto *Cons = dyn_cast<CXXConstructorDecl>(F)) {
42e8d8bef9SDimitry Andric       DeclarationName Name = Cons->getParent()->getDeclName();
43a7dea167SDimitry Andric       OS << Name << "::" << Name << ":\n";
44a7dea167SDimitry Andric     } else {
45e8d8bef9SDimitry Andric       OS << F->getDeclName() << ":\n";
46a7dea167SDimitry Andric     }
47a7dea167SDimitry Andric   } else {
48a7dea167SDimitry Andric     OS << "<<expr>>\n";
49a7dea167SDimitry Andric   }
50a7dea167SDimitry Andric 
51a7dea167SDimitry Andric   OS << "frame size: " << getFrameSize() << "\n";
52a7dea167SDimitry Andric   OS << "arg size:   " << getArgSize() << "\n";
53a7dea167SDimitry Andric   OS << "rvo:        " << hasRVO() << "\n";
54a7dea167SDimitry Andric 
55a7dea167SDimitry Andric   auto PrintName = [&OS](const char *Name) {
56a7dea167SDimitry Andric     OS << Name;
57a7dea167SDimitry Andric     for (long I = 0, N = strlen(Name); I < 30 - N; ++I) {
58a7dea167SDimitry Andric       OS << ' ';
59a7dea167SDimitry Andric     }
60a7dea167SDimitry Andric   };
61a7dea167SDimitry Andric 
62a7dea167SDimitry Andric   for (CodePtr Start = getCodeBegin(), PC = Start; PC != getCodeEnd();) {
63a7dea167SDimitry Andric     size_t Addr = PC - Start;
64a7dea167SDimitry Andric     auto Op = PC.read<Opcode>();
65a7dea167SDimitry Andric     OS << llvm::format("%8d", Addr) << " ";
66a7dea167SDimitry Andric     switch (Op) {
67a7dea167SDimitry Andric #define GET_DISASM
68a7dea167SDimitry Andric #include "Opcodes.inc"
69a7dea167SDimitry Andric #undef GET_DISASM
70a7dea167SDimitry Andric     }
71a7dea167SDimitry Andric   }
72a7dea167SDimitry Andric }
73a7dea167SDimitry Andric 
74a7dea167SDimitry Andric LLVM_DUMP_METHOD void Program::dump() const { dump(llvm::errs()); }
75a7dea167SDimitry Andric 
76a7dea167SDimitry Andric LLVM_DUMP_METHOD void Program::dump(llvm::raw_ostream &OS) const {
77a7dea167SDimitry Andric   for (auto &Func : Funcs) {
78a7dea167SDimitry Andric     Func.second->dump();
79a7dea167SDimitry Andric   }
80a7dea167SDimitry Andric   for (auto &Anon : AnonFuncs) {
81a7dea167SDimitry Andric     Anon->dump();
82a7dea167SDimitry Andric   }
83a7dea167SDimitry Andric }
84