27 ArgSize(0), Args(
nullptr), FrameOffset(0) {}
32 RetPC(RetPC), ArgSize(ArgSize), Args(static_cast<char *>(S.Stk.top())),
33 FrameOffset(S.Stk.size()) {
37 unsigned FrameSize = Func->getFrameSize();
41 Locals = std::make_unique<char[]>(FrameSize);
42 for (
auto &
Scope : Func->scopes()) {
44 new (localBlock(Local.Offset))
Block(S.Ctx.getEvalID(), Local.Desc);
54 :
InterpFrame(S, Func, S.Current, RetPC, Func->getArgSize() + VarArgSize) {
62 RVOPtr = stackRef<Pointer>(0);
64 if (Func->hasThisPointer()) {
66 This = stackRef<Pointer>(sizeof(Pointer));
68 This = stackRef<Pointer>(0);
73 for (
auto &Param : Params)
74 S.deallocate(
reinterpret_cast<Block *
>(Param.second.get()));
85 for (
auto &
Scope : Func->scopes()) {
87 S.deallocate(localBlock(Local.Offset));
95 for (
auto &Local : Func->getScope(Idx).locals()) {
96 localBlock(Local.Offset)->invokeCtor();
101 for (
auto &Local : Func->getScope(Idx).locals_reverse()) {
102 S.deallocate(localBlock(Local.Offset));
109 if constexpr (std::is_same_v<Pointer, T>) {
111 V.toAPValue(ASTCtx).printPretty(OS, ASTCtx, Ty);
113 if (std::optional<APValue> RValue =
V.toRValue(ASTCtx, Ty))
114 RValue->printPretty(OS, ASTCtx, Ty);
119 V.toAPValue(ASTCtx).printPretty(OS, ASTCtx, Ty);
124 if (F->isLambdaStaticInvoker())
132 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD);
133 MD && MD->getParent()->isAnonymousStructOrUnion())
136 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(FD);
137 Ctor && Ctor->isDefaulted() && Ctor->isTrivial() &&
138 Ctor->isCopyOrMoveConstructor() && Ctor->inits().empty())
153 if (Func->hasThisPointer() && IsMemberCall) {
154 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(
CallExpr)) {
155 const Expr *Object = MCE->getImplicitObjectArgument();
156 Object->printPretty(OS,
nullptr,
157 S.getASTContext().getPrintingPolicy(),
159 if (Object->getType()->isPointerType())
163 }
else if (
const auto *OCE =
164 dyn_cast_if_present<CXXOperatorCallExpr>(
CallExpr)) {
165 OCE->getArg(0)->printPretty(OS,
nullptr,
166 S.getASTContext().getPrintingPolicy(),
169 }
else if (
const auto *M = dyn_cast<CXXMethodDecl>(F)) {
170 print(OS, This, S.getASTContext(),
171 S.getASTContext().getLValueReferenceType(
172 S.getASTContext().getCanonicalTagType(M->getParent())));
185 for (
unsigned I = 0, N = F->
getNumParams(); I < N; ++I) {
202 return S.EvalLocation;
210 S.getRange(
C->Caller->Func,
C->RetPC -
sizeof(
uintptr_t));
214 return S.EvalLocation;
220 return Func->getDecl();
224 assert(Offset < Func->getFrameSize() &&
"Invalid local offset.");
225 return Pointer(localBlock(Offset));
229 return localBlock(Offset);
234 if (
auto Pt = Params.find(Off); Pt != Params.end())
235 return Pointer(
reinterpret_cast<Block *
>(Pt->second.get()));
238 const auto &Desc = Func->getParamDescriptor(Off);
239 size_t BlockSize =
sizeof(
Block) + Desc.second->getAllocSize();
240 auto Memory = std::make_unique<char[]>(BlockSize);
241 auto *B =
new (Memory.get())
Block(S.Ctx.getEvalID(), Desc.second);
245 TYPE_SWITCH(Desc.first, new (B->data())
T(stackRef<T>(Off)));
248 Params.insert({Off, std::move(Memory)});
255 if (F->isConstructor() || F->isDestructor())
258 return !F->getDecl()->isImplicit();
265 return Caller->getSource(RetPC);
271 return Caller->getSource(RetPC);
277 return Caller->getExpr(RetPC);
279 return S.getExpr(Func, PC);
284 return Caller->getLocation(RetPC);
286 return S.getLocation(Func, PC);
291 return Caller->getRange(RetPC);
293 return S.getRange(Func, PC);
300 if (DC->isStdNamespace())
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)
static bool shouldSkipInBacktrace(const Function *F)
static bool funcHasUsableBody(const Function *F)
#define TYPE_SWITCH(Expr, B)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
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.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
A (possibly-)qualified type.
Encodes a location in the source.
A trivial tuple used to represent a source range.
bool isPointerOrReferenceType() const
A memory block, either on the stack or in the heap.
Pointer into the code segment.
InterpFrame(InterpState &S)
Bottom Frame.
const Expr * getExpr(CodePtr PC) const
InterpFrame * Caller
The frame of the previous function.
SourceInfo getSource(CodePtr PC) const
Map a location to a source.
CodePtr getRetPC() const
Returns the return address of the frame.
Block * getLocalBlock(unsigned Offset) const
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.
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.
bool isStdFunction() const
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.
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.
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.
bool isa(CodeGen::Address addr)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Result
The result type of a method or function.
const FunctionProtoType * T
U cast(CodeGen::Address addr)
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
Inline descriptor embedded in structures and arrays.