25 #include "llvm/Support/Compiler.h"
26 #include "llvm/Support/Format.h"
28 using namespace clang;
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>();
64 ColorScope SC(OS,
true, {llvm::raw_ostream::BRIGHT_GREEN,
true});
65 OS <<
getName() <<
" " << (
const void *)
this <<
"\n";
69 OS <<
"rvo: " <<
hasRVO() <<
"\n";
72 auto PrintName = [&OS](
const char *Name) {
74 long N = 30 - strlen(Name);
80 size_t Addr = PC - Start;
81 auto Op = PC.read<
Opcode>();
82 OS << llvm::format(
"%8d", Addr) <<
" ";
85 #include "Opcodes.inc"
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";
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";
256 LLVM_DUMP_METHOD
void Record::dump(llvm::raw_ostream &OS,
unsigned Indentation,
258 unsigned Indent = Indentation * 2;
261 ColorScope SC(OS,
true, {llvm::raw_ostream::BLUE,
true});
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";
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static const char * primTypeToString(PrimType T)
#define TYPE_SWITCH(Expr, B)
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
CodePtr getCodeBegin() const
Returns a pointer to the start of the code.
CodePtr getCodeEnd() const
Returns a pointer to the end of the code.
const std::string getName() const
Returns the name of the function decl this code was generated for.
unsigned getFrameSize() const
Returns the size of the function's local stack.
bool hasThisPointer() const
void dump() const
Dumps the disassembled bytecode to llvm::errs().
unsigned getArgSize() const
Returns the size of the argument stack.
bool hasRVO() const
Checks if the first argument is a RVO pointer.
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.
unsigned getDepth() const
const FunctionDecl * getCallee() const override
Returns the caller.
const Function * getFunction() const
Returns the current function.
const Pointer & getRVOPtr() const
Returns the RVO pointer, if the Function has one.
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_base_iter > bases() const
llvm::iterator_range< const_field_iter > fields() const
llvm::iterator_range< const_virtual_iter > virtual_bases() const
Floating ReadArg< Floating >(InterpState &S, CodePtr &OpPC)
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
T ReadArg(InterpState &S, CodePtr &OpPC)
PrimType
Enumeration of the primitive types of the VM.
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
Describes a memory block created by an allocation site.
bool isPrimitive() const
Checks if the descriptor is of a primitive.
const Expr * asExpr() const
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.
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).