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 20using namespace clang; 21using namespace clang::interp; 22 23LLVM_DUMP_METHOD void Function::dump() const { dump(llvm::errs()); } 24 25LLVM_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 60LLVM_DUMP_METHOD void Program::dump() const { dump(llvm::errs()); } 61 62LLVM_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