29#include "llvm/Support/Compiler.h"
30#include "llvm/Support/Format.h"
36 if constexpr (std::is_pointer_v<T>) {
37 uint32_t ID = OpPC.
read<uint32_t>();
38 return reinterpret_cast<T>(
P.getNativePointer(ID));
40 return OpPC.
read<
T>();
64LLVM_DUMP_METHOD
void Function::dump()
const {
dump(llvm::errs()); }
66LLVM_DUMP_METHOD
void Function::dump(llvm::raw_ostream &OS)
const {
68 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_GREEN,
true});
69 OS <<
getName() <<
" " << (
const void *)
this <<
"\n";
71 OS <<
"frame size: " << getFrameSize() <<
"\n";
72 OS <<
"arg size: " << getArgSize() <<
"\n";
73 OS <<
"rvo: " << hasRVO() <<
"\n";
74 OS <<
"this arg: " << hasThisPointer() <<
"\n";
76 auto PrintName = [&OS](
const char *Name) {
78 long N = 30 - strlen(Name);
83 for (
CodePtr Start = getCodeBegin(), PC = Start; PC != getCodeEnd();) {
84 size_t Addr = PC - Start;
85 auto Op = PC.read<
Opcode>();
86 OS << llvm::format(
"%8d", Addr) <<
" ";
130 llvm_unreachable(
"Unhandled PrimType");
135 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_RED,
true});
136 OS <<
"\n:: Program\n";
140 ColorScope SC(OS,
true, {llvm::raw_ostream::WHITE,
true});
141 OS <<
"Total memory : " << Allocator.getTotalMemory() <<
" bytes\n";
142 OS <<
"Global Variables: " << Globals.size() <<
"\n";
145 for (
const Global *G : Globals) {
146 const Descriptor *Desc = G->block()->getDescriptor();
149 OS << GI <<
": " << (
const void *)G->block() <<
" ";
155 OS << (GP.
isInitialized() ?
"initialized " :
"uninitialized ");
160 if (
const auto *MTE =
161 dyn_cast_if_present<MaterializeTemporaryExpr>(Desc->
asExpr());
162 MTE && MTE->getLifetimeExtendedTemporaryDecl()) {
164 MTE->getLifetimeExtendedTemporaryDecl()->getValue()) {
165 OS <<
" (global temporary value: ";
167 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_MAGENTA,
true});
169 llvm::raw_string_ostream SS(VStr);
172 for (
unsigned I = 0; I != VStr.size(); ++I) {
188 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_CYAN,
false});
198 ColorScope SC(OS,
true, {llvm::raw_ostream::WHITE,
true});
199 OS <<
"Functions: " << Funcs.size() <<
"\n";
201 for (
const auto &
Func : Funcs) {
204 for (
const auto &Anon : AnonFuncs) {
211 llvm::errs() <<
'\n';
217 ColorScope SC(OS,
true, {llvm::raw_ostream::BLUE,
true});
218 if (
const auto *ND = dyn_cast_if_present<NamedDecl>(
asDecl()))
219 ND->printQualifiedName(OS);
221 OS <<
"Expr " << (
const void *)
asExpr();
226 OS <<
" primitive-array";
228 OS <<
" composite-array";
237 OS <<
" zero-size-array";
239 OS <<
" unknown-size-array";
247 ColorScope SC(OS,
true, {llvm::raw_ostream::BLUE,
true});
248 OS <<
"InlineDescriptor " << (
const void *)
this <<
"\n";
250 OS <<
"Offset: " <<
Offset <<
"\n";
251 OS <<
"IsConst: " <<
IsConst <<
"\n";
253 OS <<
"IsBase: " <<
IsBase <<
"\n";
254 OS <<
"IsActive: " <<
IsActive <<
"\n";
255 OS <<
"InUnion: " <<
InUnion <<
"\n";
266 unsigned Indent)
const {
267 unsigned Spaces = Indent * 2;
269 ColorScope SC(OS,
true, {llvm::raw_ostream::BLUE,
true});
274 OS <<
"Frame (Depth: " <<
getDepth() <<
")";
277 OS.indent(Spaces) <<
"Function: " <<
getFunction();
279 OS <<
" (" << F->getName() <<
")";
282 OS.indent(Spaces) <<
"This: " <<
getThis() <<
"\n";
283 OS.indent(Spaces) <<
"RVO: " <<
getRVOPtr() <<
"\n";
284 OS.indent(Spaces) <<
"Depth: " << Depth <<
"\n";
285 OS.indent(Spaces) <<
"ArgSize: " << ArgSize <<
"\n";
286 OS.indent(Spaces) <<
"Args: " << (
void *)Args <<
"\n";
287 OS.indent(Spaces) <<
"FrameOffset: " << FrameOffset <<
"\n";
288 OS.indent(Spaces) <<
"FrameSize: " << (Func ? Func->
getFrameSize() : 0)
292 F->dump(OS, Indent + 1);
296LLVM_DUMP_METHOD
void Record::dump(llvm::raw_ostream &OS,
unsigned Indentation,
297 unsigned Offset)
const {
298 unsigned Indent = Indentation * 2;
301 ColorScope SC(OS,
true, {llvm::raw_ostream::BLUE,
true});
306 for (
const Record::Base &B :
bases()) {
307 OS.indent(Indent) <<
"- Base " << I <<
". Offset " << (Offset + B.Offset)
309 B.R->dump(OS, Indentation + 1, Offset + B.Offset);
314 for (
const Record::Field &F :
fields()) {
315 OS.indent(Indent) <<
"- Field " << I <<
": ";
317 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_RED,
true});
318 OS << F.Decl->getName();
320 OS <<
". Offset " << (Offset + F.Offset) <<
"\n";
326 OS.indent(Indent) <<
"- Virtual Base " << I <<
". Offset "
327 << (Offset + B.Offset) <<
"\n";
328 B.R->dump(OS, Indentation + 1, Offset + B.Offset);
335 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_BLUE,
true});
336 OS <<
"Block " << (
const void *)
this;
341 unsigned NPointers = 0;
342 for (
const Pointer *
P = Pointers;
P;
P =
P->Next) {
345 OS <<
" Pointers: " << NPointers <<
"\n";
346 OS <<
" Dead: " << IsDead <<
"\n";
347 OS <<
" Static: " << IsStatic <<
"\n";
348 OS <<
" Extern: " << IsExtern <<
"\n";
349 OS <<
" Initialized: " << IsInitialized <<
"\n";
354 auto &OS = llvm::errs();
363 std::get<APValue>(
Value).dump(OS, ASTCtx);
368 if (
const auto *
D = Source.dyn_cast<
const Decl *>()) {
369 if (
const auto *VD = dyn_cast<ValueDecl>(
D))
370 SourceType = VD->getType();
371 }
else if (
const auto *
E = Source.dyn_cast<
const Expr *>()) {
376 if (
const auto *
P = std::get_if<Pointer>(&
Value))
377 P->toAPValue(ASTCtx).printPretty(OS, ASTCtx, SourceType);
378 else if (
const auto *FP = std::get_if<FunctionPointer>(&
Value))
379 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)
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).