Disasm.cpp 2.4 KB

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