1 //===--- Disasm.cpp - Disassembler for bytecode functions -------*- 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 // Dump method for Function which disassembles the bytecode.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "Function.h"
14 #include "Opcode.h"
15 #include "PrimType.h"
16 #include "Program.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "llvm/Support/Compiler.h"
19 
20 using namespace clang;
21 using namespace clang::interp;
22 
23 LLVM_DUMP_METHOD void Function::dump() const { dump(llvm::errs()); }
24 
25 LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS) const {
26   if (F) {
27     if (auto *Cons = dyn_cast<CXXConstructorDecl>(F)) {
28       const std::string &Name = Cons->getParent()->getNameAsString();
29       OS << Name << "::" << Name << ":\n";
30     } else {
31       OS << F->getNameAsString() << ":\n";
32     }
33   } else {
34     OS << "<<expr>>\n";
35   }
36 
37   OS << "frame size: " << getFrameSize() << "\n";
38   OS << "arg size:   " << getArgSize() << "\n";
39   OS << "rvo:        " << hasRVO() << "\n";
40 
41   auto PrintName = [&OS](const char *Name) {
42     OS << Name;
43     for (long I = 0, N = strlen(Name); I < 30 - N; ++I) {
44       OS << ' ';
45     }
46   };
47 
48   for (CodePtr Start = getCodeBegin(), PC = Start; PC != getCodeEnd();) {
49     size_t Addr = PC - Start;
50     auto Op = PC.read<Opcode>();
51     OS << llvm::format("%8d", Addr) << " ";
52     switch (Op) {
53 #define GET_DISASM
54 #include "Opcodes.inc"
55 #undef GET_DISASM
56     }
57   }
58 }
59 
60 LLVM_DUMP_METHOD void Program::dump() const { dump(llvm::errs()); }
61 
62 LLVM_DUMP_METHOD void Program::dump(llvm::raw_ostream &OS) const {
63   for (auto &Func : Funcs) {
64     Func.second->dump();
65   }
66   for (auto &Anon : AnonFuncs) {
67     Anon->dump();
68   }
69 }
70