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";
235 OS <<
" zero-size-array";
237 OS <<
" unknown-size-array";
245 ColorScope SC(OS,
true, {llvm::raw_ostream::BLUE,
true});
246 OS <<
"InlineDescriptor " << (
const void *)
this <<
"\n";
248 OS <<
"Offset: " <<
Offset <<
"\n";
249 OS <<
"IsConst: " <<
IsConst <<
"\n";
251 OS <<
"IsBase: " <<
IsBase <<
"\n";
252 OS <<
"IsActive: " <<
IsActive <<
"\n";
263 unsigned Indent)
const {
264 unsigned Spaces = Indent * 2;
266 ColorScope SC(OS,
true, {llvm::raw_ostream::BLUE,
true});
271 OS <<
"Frame (Depth: " <<
getDepth() <<
")";
274 OS.indent(Spaces) <<
"Function: " <<
getFunction();
276 OS <<
" (" << F->getName() <<
")";
279 OS.indent(Spaces) <<
"This: " <<
getThis() <<
"\n";
280 OS.indent(Spaces) <<
"RVO: " <<
getRVOPtr() <<
"\n";
283 F->dump(OS, Indent + 1);
288LLVM_DUMP_METHOD
void Record::dump(llvm::raw_ostream &OS,
unsigned Indentation,
289 unsigned Offset)
const {
290 unsigned Indent = Indentation * 2;
293 ColorScope SC(OS,
true, {llvm::raw_ostream::BLUE,
true});
298 for (
const Record::Base &B :
bases()) {
299 OS.indent(Indent) <<
"- Base " << I <<
". Offset " << (Offset + B.Offset)
301 B.R->dump(OS, Indentation + 1, Offset + B.Offset);
306 for (
const Record::Field &F :
fields()) {
307 OS.indent(Indent) <<
"- Field " << I <<
": ";
309 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_RED,
true});
310 OS << F.Decl->getName();
312 OS <<
". Offset " << (Offset + F.Offset) <<
"\n";
318 OS.indent(Indent) <<
"- Virtual Base " << I <<
". Offset "
319 << (Offset + B.Offset) <<
"\n";
320 B.R->dump(OS, Indentation + 1, Offset + B.Offset);
327 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_BLUE,
true});
328 OS <<
"Block " << (
const void *)
this;
333 unsigned NPointers = 0;
334 for (
const Pointer *
P = Pointers;
P;
P =
P->Next) {
337 OS <<
" Pointers: " << NPointers <<
"\n";
338 OS <<
" Dead: " << IsDead <<
"\n";
339 OS <<
" Static: " << IsStatic <<
"\n";
340 OS <<
" Extern: " << IsExtern <<
"\n";
341 OS <<
" Initialized: " << IsInitialized <<
"\n";
346 auto &OS = llvm::errs();
355 std::get<APValue>(
Value).dump(OS, ASTCtx);
360 if (
const auto *
D = Source.dyn_cast<
const Decl *>()) {
361 if (
const auto *VD = dyn_cast<ValueDecl>(
D))
362 SourceType = VD->getType();
363 }
else if (
const auto *
E = Source.dyn_cast<
const Expr *>()) {
368 if (
const auto *
P = std::get_if<Pointer>(&
Value))
369 P->toAPValue(ASTCtx).printPretty(OS, ASTCtx, SourceType);
370 else if (
const auto *FP = std::get_if<FunctionPointer>(&
Value))
371 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
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.
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).