28 : Caller(Caller), S(S), Depth(Caller ? Caller->Depth + 1 : 0),
Func(
Func),
29 RetPC(RetPC), ArgSize(ArgSize), Args(static_cast<char *>(S.Stk.top())),
30 FrameOffset(S.Stk.size()) {
34 unsigned FrameSize =
Func->getFrameSize();
38 Locals = std::make_unique<char[]>(FrameSize);
41 new (localBlock(Local.Offset))
Block(S.Ctx.getEvalID(), Local.Desc);
59 RVOPtr = stackRef<Pointer>(0);
61 if (
Func->hasThisPointer()) {
63 This = stackRef<Pointer>(
sizeof(
Pointer));
65 This = stackRef<Pointer>(0);
70 for (
auto &Param : Params)
107 V.toAPValue(ASTCtx).printPretty(OS, ASTCtx, Ty);
118 auto printDesc = [&OS, &Ctx](
const Descriptor *Desc) {
119 if (
const auto *
D = Desc->asDecl()) {
121 if (
const auto *VD = dyn_cast<ValueDecl>(
D)) {
126 if (isa<RecordDecl>(
D))
130 if (
const auto *
E = Desc->asExpr()) {
134 llvm_unreachable(
"Invalid descriptor type");
142 F = F.isArrayElement() ? F.getArray().expand() : F.getBase();
147 Levels.erase(Levels.begin());
149 printDesc(
P.getDeclDesc());
150 for (
const auto &It : Levels) {
152 OS <<
"[" << It.expand().getIndex() <<
"]";
155 if (
auto Index = It.getIndex()) {
156 OS <<
" + " << Index;
160 printDesc(It.getFieldDesc());
171 F && (F->isBuiltin() || F->isLambdaStaticInvoker()))
176 bool IsMemberCall = isa<CXXMethodDecl>(F) && !isa<CXXConstructorDecl>(F) &&
177 cast<CXXMethodDecl>(F)->isImplicitObjectMemberFunction();
179 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(
CallExpr)) {
180 const Expr *Object = MCE->getImplicitObjectArgument();
181 Object->printPretty(OS,
nullptr,
184 if (Object->getType()->isPointerType())
188 }
else if (
const auto *OCE =
189 dyn_cast_if_present<CXXOperatorCallExpr>(
CallExpr)) {
190 OCE->getArg(0)->printPretty(OS,
nullptr,
194 }
else if (
const auto *M = dyn_cast<CXXMethodDecl>(F)) {
210 for (
unsigned I = 0, N = F->
getNumParams(); I < N; ++I) {
245 assert(Offset < Func->getFrameSize() &&
"Invalid local offset.");
246 return Pointer(localBlock(Offset));
251 if (
auto Pt = Params.find(Off); Pt != Params.end())
252 return Pointer(
reinterpret_cast<Block *
>(Pt->second.get()));
256 size_t BlockSize =
sizeof(
Block) + Desc.second->getAllocSize();
257 auto Memory = std::make_unique<char[]>(BlockSize);
262 TYPE_SWITCH(Desc.first, new (B->data())
T(stackRef<T>(Off)));
265 Params.insert({Off, std::move(Memory)});
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
static void print(llvm::raw_ostream &OS, const T &V, ASTContext &ASTCtx, QualType Ty)
#define TYPE_SWITCH(Expr, B)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getRecordType(const RecordDecl *Decl) const
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
const clang::PrintingPolicy & getPrintingPolicy() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
This represents one expression.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
A (possibly-)qualified type.
Encodes a location in the source.
A trivial tuple used to represent a source range.
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
bool isReferenceType() const
A memory block, either on the stack or in the heap.
void invokeCtor()
Invokes the constructor.
Pointer into the code segment.
std::optional< PrimType > classify(QualType T) const
Classifies a type.
unsigned getEvalID() const
Base class for stack frames, shared between VM and walker.
Scope & getScope(unsigned Idx)
Returns a specific scope.
const FunctionDecl * getDecl() const
Returns the original FunctionDecl.
bool hasBody() const
Checks if the function already has a body attached.
bool hasThisPointer() const
llvm::iterator_range< arg_reverse_iterator > args_reverse() const
ParamDescriptor getParamDescriptor(unsigned Offset) const
Returns a parameter descriptor.
llvm::iterator_range< llvm::SmallVector< Scope, 2 >::const_iterator > scopes() const
Range over the scope blocks.
bool hasRVO() const
Checks if the first argument is a RVO pointer.
Frame storing local variables.
void popArgs()
Pops the arguments off the stack.
const Expr * getExpr(CodePtr PC) const
InterpFrame * Caller
The frame of the previous function.
virtual SourceInfo getSource(CodePtr PC) const
Map a location to a source.
CodePtr getRetPC() const
Returns the return address of the frame.
SourceLocation getLocation(CodePtr PC) const
~InterpFrame()
Destroys the frame, killing all live pointers to stack slots.
const Function * getFunction() const
Returns the current function.
SourceRange getRange(CodePtr PC) const
Pointer getLocalPointer(unsigned Offset) const
Returns a pointer to a local variables.
Frame * getCaller() const override
Returns the parent frame object.
InterpFrame(InterpState &S, const Function *Func, InterpFrame *Caller, CodePtr RetPC, unsigned ArgSize)
Creates a new frame for a method call.
void destroy(unsigned Idx)
Invokes the destructors for a scope.
Pointer getParamPointer(unsigned Offset)
Returns a pointer to an argument - lazily creates a block.
const FunctionDecl * getCallee() const override
Returns the caller.
void initScope(unsigned Idx)
SourceRange getCallRange() const override
Returns the location of the call to the frame.
void describe(llvm::raw_ostream &OS) const override
Describes the frame with arguments for diagnostic purposes.
void discard()
Discards the top value from the stack.
Context & Ctx
Interpreter Context.
SourceInfo getSource(const Function *F, CodePtr PC) const override
Delegates source mapping to the mapper.
InterpStack & Stk
Temporary stack.
SourceLocation EvalLocation
Source location of the evaluating expression.
void deallocate(Block *B)
Deallocates a pointer.
ASTContext & getCtx() const override
A pointer to a memory block, live or dead.
llvm::iterator_range< LocalVectorTy::const_iterator > locals() const
Describes the statement/declaration an opcode was generated from.
SourceLocation getLocation(const Function *F, CodePtr PC) const
Returns the location from which an opcode originates.
SourceRange getRange(const Function *F, CodePtr PC) const
const Expr * getExpr(const Function *F, CodePtr PC) const
Returns the expression if an opcode belongs to one, null otherwise.
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
PrimType
Enumeration of the primitive types of the VM.
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
Describes a memory block created by an allocation site.
Inline descriptor embedded in structures and arrays.