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