25#include "llvm/Support/Compiler.h"
26#include "llvm/Support/Format.h"
32 if constexpr (std::is_pointer_v<T>) {
33 uint32_t ID = OpPC.
read<uint32_t>();
34 return reinterpret_cast<T>(
P.getNativePointer(ID));
36 return OpPC.
read<
T>();
60LLVM_DUMP_METHOD
void Function::dump()
const {
dump(llvm::errs()); }
62LLVM_DUMP_METHOD
void Function::dump(llvm::raw_ostream &OS)
const {
64 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_GREEN,
true});
65 OS <<
getName() <<
" " << (
const void *)
this <<
"\n";
67 OS <<
"frame size: " << getFrameSize() <<
"\n";
68 OS <<
"arg size: " << getArgSize() <<
"\n";
69 OS <<
"rvo: " << hasRVO() <<
"\n";
70 OS <<
"this arg: " << hasThisPointer() <<
"\n";
72 auto PrintName = [&OS](
const char *Name) {
74 long N = 30 - strlen(Name);
79 for (
CodePtr Start = getCodeBegin(), PC = Start; PC != getCodeEnd();) {
80 size_t Addr = PC - Start;
81 auto Op = PC.read<
Opcode>();
82 OS << llvm::format(
"%8d", Addr) <<
" ";
124 llvm_unreachable(
"Unhandled PrimType");
129 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_RED,
true});
130 OS <<
"\n:: Program\n";
134 ColorScope SC(OS,
true, {llvm::raw_ostream::WHITE,
true});
135 OS <<
"Total memory : " << Allocator.getTotalMemory() <<
" bytes\n";
136 OS <<
"Global Variables: " << Globals.size() <<
"\n";
139 for (
const Global *G : Globals) {
140 const Descriptor *Desc = G->block()->getDescriptor();
143 OS << GI <<
": " << (
const void *)G->block() <<
" ";
149 OS << (GP.
isInitialized() ?
"initialized " :
"uninitialized ");
156 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_CYAN,
false});
166 ColorScope SC(OS,
true, {llvm::raw_ostream::WHITE,
true});
167 OS <<
"Functions: " << Funcs.size() <<
"\n";
169 for (
const auto &
Func : Funcs) {
172 for (
const auto &Anon : AnonFuncs) {
179 llvm::errs() <<
'\n';
185 ColorScope SC(OS,
true, {llvm::raw_ostream::BLUE,
true});
186 if (
const auto *ND = dyn_cast_if_present<NamedDecl>(
asDecl()))
187 ND->printQualifiedName(OS);
194 OS <<
" primitive-array";
196 OS <<
" composite-array";
203 OS <<
" zero-size-array";
205 OS <<
" unknown-size-array";
213 ColorScope SC(OS,
true, {llvm::raw_ostream::BLUE,
true});
214 OS <<
"InlineDescriptor " << (
const void *)
this <<
"\n";
216 OS <<
"Offset: " <<
Offset <<
"\n";
217 OS <<
"IsConst: " <<
IsConst <<
"\n";
219 OS <<
"IsBase: " <<
IsBase <<
"\n";
220 OS <<
"IsActive: " <<
IsActive <<
"\n";
231 unsigned Indent)
const {
232 unsigned Spaces = Indent * 2;
234 ColorScope SC(OS,
true, {llvm::raw_ostream::BLUE,
true});
239 OS <<
"Frame (Depth: " <<
getDepth() <<
")";
242 OS.indent(Spaces) <<
"Function: " <<
getFunction();
244 OS <<
" (" << F->getName() <<
")";
247 OS.indent(Spaces) <<
"This: " <<
getThis() <<
"\n";
248 OS.indent(Spaces) <<
"RVO: " <<
getRVOPtr() <<
"\n";
251 F->dump(OS, Indent + 1);
256LLVM_DUMP_METHOD
void Record::dump(llvm::raw_ostream &OS,
unsigned Indentation,
257 unsigned Offset)
const {
258 unsigned Indent = Indentation * 2;
261 ColorScope SC(OS,
true, {llvm::raw_ostream::BLUE,
true});
266 for (
const Record::Base &B :
bases()) {
267 OS.indent(Indent) <<
"- Base " << I <<
". Offset " << (Offset + B.Offset)
269 B.R->dump(OS, Indentation + 1, Offset + B.Offset);
274 for (
const Record::Field &F :
fields()) {
275 OS.indent(Indent) <<
"- Field " << I <<
": ";
277 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_RED,
true});
278 OS << F.Decl->getName();
280 OS <<
". Offset " << (Offset + F.Offset) <<
"\n";
286 OS.indent(Indent) <<
"- Virtual Base " << I <<
". Offset "
287 << (Offset + B.Offset) <<
"\n";
288 B.R->dump(OS, Indentation + 1, Offset + B.Offset);
295 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_BLUE,
true});
296 OS <<
"Block " << (
const void *)
this <<
"\n";
298 unsigned NPointers = 0;
302 OS <<
" Pointers: " << NPointers <<
"\n";
303 OS <<
" Dead: " <<
IsDead <<
"\n";
304 OS <<
" Static: " <<
IsStatic <<
"\n";
305 OS <<
" Extern: " <<
IsExtern <<
"\n";
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static const char * primTypeToString(PrimType T)
Floating ReadArg< Floating >(Program &P, CodePtr &OpPC)
T ReadArg(Program &P, CodePtr &OpPC)
#define TYPE_SWITCH(Expr, B)
static std::string getName(const CallEvent &Call)
bool IsExtern
Flag indicating if the block is an extern.
bool IsInitialized
Flag indicating if the block contents have been initialized via invokeCtor.
bool IsStatic
Flag indicating if the block has static storage duration.
Pointer * Pointers
Start of the chain of pointers.
bool IsDead
Flag indicating if the pointer is dead.
Pointer into the code segment.
std::enable_if_t<!std::is_pointer< T >::value, T > read()
Reads data and advances the pointer.
static Floating deserialize(const std::byte *Buff)
size_t bytesToSerialize() const
static IntegralAP< Signed > deserialize(const std::byte *Buff)
size_t bytesToSerialize() const
Frame storing local variables.
InterpFrame * Caller
The frame of the previous function.
const Pointer & getThis() const
Returns the 'this' pointer.
const Function * getFunction() const
Returns the current function.
unsigned getDepth() const
const Pointer & getRVOPtr() const
Returns the RVO pointer, if the Function has one.
const FunctionDecl * getCallee() const override
Returns the caller.
void describe(llvm::raw_ostream &OS) const override
Describes the frame with arguments for diagnostic purposes.
A pointer to a memory block, live or dead.
bool isInitialized() const
Checks if an object was initialized.
The program contains and links the bytecode for all functions.
Pointer getPtrGlobal(unsigned Idx) const
Returns a pointer to a global.
void dump() const
Dumps the disassembled bytecode to llvm::errs().
const std::string getName() const
Returns the name of the underlying declaration.
llvm::iterator_range< const_virtual_iter > virtual_bases() const
llvm::iterator_range< const_base_iter > bases() const
llvm::iterator_range< const_field_iter > fields() const
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
PrimType
Enumeration of the primitive types of the VM.
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
Describes a memory block created by an allocation site.
bool isPrimitive() const
Checks if the descriptor is of a primitive.
bool isCompositeArray() const
Checks if the descriptor is of an array of composites.
const Decl * asDecl() const
bool isDummy() const
Checks if this is a dummy descriptor.
bool isUnknownSizeArray() const
Checks if the descriptor is of an array of unknown size.
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
bool isZeroSizeArray() const
Checks if the descriptor is of an array of zero size.
PrimType getPrimType() const
bool isRecord() const
Checks if the descriptor is of a record.
const Expr * asExpr() const
unsigned IsActive
Flag indicating if the field is the active member of a union.
unsigned IsBase
Flag indicating if the field is an embedded base class.
unsigned Offset
Offset inside the structure/array.
unsigned IsInitialized
For primitive fields, it indicates if the field was initialized.
unsigned IsConst
Flag indicating if the storage is constant or not.
unsigned IsFieldMutable
Flag indicating if the field is mutable (if in a record).