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#include "llvm/Support/Format.h" 20 21using namespace clang; 22using namespace clang::interp; 23 24template <typename T> inline T ReadArg(Program &P, CodePtr &OpPC) { 25 if constexpr (std::is_pointer_v<T>) { 26 uint32_t ID = OpPC.read<uint32_t>(); 27 return reinterpret_cast<T>(P.getNativePointer(ID)); 28 } else { 29 return OpPC.read<T>(); 30 } 31} 32 33LLVM_DUMP_METHOD void Function::dump() const { dump(llvm::errs()); } 34 35LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS) const { 36 if (F) { 37 if (auto *Cons = dyn_cast<CXXConstructorDecl>(F)) { 38 DeclarationName Name = Cons->getParent()->getDeclName(); 39 OS << Name << "::" << Name; 40 } else { 41 OS << F->getDeclName(); 42 } 43 OS << " " << (const void*)this << ":\n"; 44 } else { 45 OS << "<<expr>>\n"; 46 } 47 48 OS << "frame size: " << getFrameSize() << "\n"; 49 OS << "arg size: " << getArgSize() << "\n"; 50 OS << "rvo: " << hasRVO() << "\n"; 51 OS << "this arg: " << hasThisPointer() << "\n"; 52 53 auto PrintName = [&OS](const char *Name) { 54 OS << Name; 55 for (long I = 0, N = strlen(Name); I < 30 - N; ++I) { 56 OS << ' '; 57 } 58 }; 59 60 for (CodePtr Start = getCodeBegin(), PC = Start; PC != getCodeEnd();) { 61 size_t Addr = PC - Start; 62 auto Op = PC.read<Opcode>(); 63 OS << llvm::format("%8d", Addr) << " "; 64 switch (Op) { 65#define GET_DISASM 66#include "Opcodes.inc" 67#undef GET_DISASM 68 } 69 } 70} 71 72LLVM_DUMP_METHOD void Program::dump() const { dump(llvm::errs()); } 73 74LLVM_DUMP_METHOD void Program::dump(llvm::raw_ostream &OS) const { 75 OS << ":: Program\n"; 76 OS << "Global Variables: " << Globals.size() << "\n"; 77 OS << "Functions: " << Funcs.size() << "\n"; 78 OS << "\n"; 79 for (auto &Func : Funcs) { 80 Func.second->dump(); 81 } 82 for (auto &Anon : AnonFuncs) { 83 Anon->dump(); 84 } 85} 86