30#include "llvm/Support/Compiler.h"
31#include "llvm/Support/Format.h"
37 if constexpr (std::is_pointer_v<T>) {
38 uint32_t ID = OpPC.
read<uint32_t>();
39 return reinterpret_cast<T>(
P.getNativePointer(ID));
41 return OpPC.
read<
T>();
65LLVM_DUMP_METHOD
void Function::dump()
const {
dump(llvm::errs()); }
67LLVM_DUMP_METHOD
void Function::dump(llvm::raw_ostream &OS)
const {
69 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_GREEN,
true});
70 OS <<
getName() <<
" " << (
const void *)
this <<
"\n";
72 OS <<
"frame size: " << getFrameSize() <<
"\n";
73 OS <<
"arg size: " << getArgSize() <<
"\n";
74 OS <<
"rvo: " << hasRVO() <<
"\n";
75 OS <<
"this arg: " << hasThisPointer() <<
"\n";
77 auto PrintName = [&OS](
const char *Name) {
79 long N = 30 - strlen(Name);
84 for (
CodePtr Start = getCodeBegin(), PC = Start; PC != getCodeEnd();) {
85 size_t Addr = PC - Start;
86 auto Op = PC.read<
Opcode>();
87 OS << llvm::format(
"%8d", Addr) <<
" ";
133 llvm_unreachable(
"Unhandled PrimType");
138 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_RED,
true});
139 OS <<
"\n:: Program\n";
143 ColorScope SC(OS,
true, {llvm::raw_ostream::WHITE,
true});
144 OS <<
"Total memory : " << Allocator.getTotalMemory() <<
" bytes\n";
145 OS <<
"Global Variables: " << Globals.size() <<
"\n";
148 for (
const Global *G : Globals) {
149 const Descriptor *Desc = G->block()->getDescriptor();
152 OS << GI <<
": " << (
const void *)G->block() <<
" ";
158 OS << (GP.
isInitialized() ?
"initialized " :
"uninitialized ");
163 if (
const auto *MTE =
164 dyn_cast_if_present<MaterializeTemporaryExpr>(Desc->
asExpr());
165 MTE && MTE->getLifetimeExtendedTemporaryDecl()) {
167 MTE->getLifetimeExtendedTemporaryDecl()->getValue()) {
168 OS <<
" (global temporary value: ";
170 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_MAGENTA,
true});
172 llvm::raw_string_ostream SS(VStr);
175 for (
unsigned I = 0; I != VStr.size(); ++I) {
191 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_CYAN,
false});
201 ColorScope SC(OS,
true, {llvm::raw_ostream::WHITE,
true});
202 OS <<
"Functions: " << Funcs.size() <<
"\n";
204 for (
const auto &
Func : Funcs) {
207 for (
const auto &Anon : AnonFuncs) {
214 llvm::errs() <<
'\n';
220 ColorScope SC(OS,
true, {llvm::raw_ostream::BLUE,
true});
221 if (
const auto *ND = dyn_cast_if_present<NamedDecl>(
asDecl()))
222 ND->printQualifiedName(OS);
224 OS <<
"Expr " << (
const void *)
asExpr();
229 OS <<
" primitive-array";
231 OS <<
" composite-array";
240 OS <<
" zero-size-array";
242 OS <<
" unknown-size-array";
250 ColorScope SC(OS,
true, {llvm::raw_ostream::BLUE,
true});
251 OS <<
"InlineDescriptor " << (
const void *)
this <<
"\n";
253 OS <<
"Offset: " <<
Offset <<
"\n";
254 OS <<
"IsConst: " <<
IsConst <<
"\n";
256 OS <<
"IsBase: " <<
IsBase <<
"\n";
257 OS <<
"IsActive: " <<
IsActive <<
"\n";
258 OS <<
"InUnion: " <<
InUnion <<
"\n";
269 unsigned Indent)
const {
270 unsigned Spaces = Indent * 2;
272 ColorScope SC(OS,
true, {llvm::raw_ostream::BLUE,
true});
277 OS <<
"Frame (Depth: " <<
getDepth() <<
")";
280 OS.indent(Spaces) <<
"Function: " <<
getFunction();
282 OS <<
" (" << F->getName() <<
")";
285 OS.indent(Spaces) <<
"This: " <<
getThis() <<
"\n";
286 OS.indent(Spaces) <<
"RVO: " <<
getRVOPtr() <<
"\n";
287 OS.indent(Spaces) <<
"Depth: " << Depth <<
"\n";
288 OS.indent(Spaces) <<
"ArgSize: " << ArgSize <<
"\n";
289 OS.indent(Spaces) <<
"Args: " << (
void *)Args <<
"\n";
290 OS.indent(Spaces) <<
"FrameOffset: " << FrameOffset <<
"\n";
291 OS.indent(Spaces) <<
"FrameSize: " << (Func ? Func->
getFrameSize() : 0)
295 F->dump(OS, Indent + 1);
299LLVM_DUMP_METHOD
void Record::dump(llvm::raw_ostream &OS,
unsigned Indentation,
300 unsigned Offset)
const {
301 unsigned Indent = Indentation * 2;
304 ColorScope SC(OS,
true, {llvm::raw_ostream::BLUE,
true});
309 for (
const Record::Base &B :
bases()) {
310 OS.indent(Indent) <<
"- Base " << I <<
". Offset " << (Offset + B.Offset)
312 B.R->dump(OS, Indentation + 1, Offset + B.Offset);
317 for (
const Record::Field &F :
fields()) {
318 OS.indent(Indent) <<
"- Field " << I <<
": ";
320 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_RED,
true});
321 OS << F.Decl->getName();
323 OS <<
". Offset " << (Offset + F.Offset) <<
"\n";
329 OS.indent(Indent) <<
"- Virtual Base " << I <<
". Offset "
330 << (Offset + B.Offset) <<
"\n";
331 B.R->dump(OS, Indentation + 1, Offset + B.Offset);
338 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_BLUE,
true});
339 OS <<
"Block " << (
const void *)
this;
344 unsigned NPointers = 0;
345 for (
const Pointer *
P = Pointers;
P;
P =
P->Next) {
348 OS <<
" Pointers: " << NPointers <<
"\n";
349 OS <<
" Dead: " << IsDead <<
"\n";
350 OS <<
" Static: " << IsStatic <<
"\n";
351 OS <<
" Extern: " << IsExtern <<
"\n";
352 OS <<
" Initialized: " << IsInitialized <<
"\n";
357 auto &OS = llvm::errs();
366 std::get<APValue>(
Value).dump(OS, ASTCtx);
371 if (
const auto *
D = Source.dyn_cast<
const Decl *>()) {
372 if (
const auto *VD = dyn_cast<ValueDecl>(
D))
373 SourceType = VD->getType();
374 }
else if (
const auto *
E = Source.dyn_cast<
const Expr *>()) {
379 if (
const auto *
P = std::get_if<Pointer>(&
Value))
380 P->toAPValue(ASTCtx).printPretty(OS, ASTCtx, SourceType);
381 else if (
const auto *FP = std::get_if<FunctionPointer>(&
Value))
382 FP->toAPValue(ASTCtx).printPretty(OS, ASTCtx, SourceType);
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)
static T ReadArg(Program &P, CodePtr &OpPC)
Defines the clang::Expr interface and subclasses for C++ expressions.
#define TYPE_SWITCH(Expr, B)
static std::string getName(const CallEvent &Call)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Decl - This represents one declaration (or definition), e.g.
This represents one expression.
A (possibly-)qualified type.
Pointer into the code segment.
std::enable_if_t<!std::is_pointer< T >::value, T > read()
Reads data and advances the pointer.
ASTContext & getASTContext() const
Returns the AST context.
void dump() const
Dump to stderr.
static Floating deserialize(const std::byte *Buff)
size_t bytesToSerialize() const
unsigned getFrameSize() const
Returns the size of the function's local stack.
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 bool IsTemporary
Flag indicating if the block is a temporary.
bool isUnion() const
Checks if the descriptor is of a union.
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 InUnion
Flat indicating if this field is in a union (even if nested).
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).