17 using namespace clang;
22 : Caller(Caller), S(S), Func(Func),
This(
std::move(
This)), RetPC(RetPC),
23 ArgSize(Func ? Func->getArgSize() : 0),
24 Args(static_cast<char *>(S.Stk.top())), FrameOffset(S.Stk.size()) {
27 Locals = std::make_unique<char[]>(FrameSize);
30 Block *B =
new (localBlock(Local.Offset))
Block(Local.Desc);
41 for (
auto &Param : Params)
42 S.
deallocate(reinterpret_cast<Block *>(Param.second.get()));
47 S.
deallocate(reinterpret_cast<Block *>(localBlock(Local.Offset)));
69 auto printDesc = [&OS, &Ctx](
Descriptor *Desc) {
70 if (
auto *D = Desc->asDecl()) {
72 if (
auto *VD = dyn_cast<ValueDecl>(D)) {
77 if (isa<RecordDecl>(D)) {
82 if (
auto *E = Desc->asExpr()) {
86 llvm_unreachable(
"Invalid descriptor type");
94 F = F.isArrayElement() ? F.getArray().expand() : F.getBase();
98 for (
auto It = Levels.rbegin(); It != Levels.rend(); ++It) {
100 OS <<
"[" << It->expand().getIndex() <<
"]";
103 if (
auto Index = It->getIndex()) {
104 OS <<
" + " << Index;
108 printDesc(It->getFieldDesc());
115 if (M && M->isInstance() && !isa<CXXConstructorDecl>(F)) {
121 for (
unsigned I = 0, N = F->getNumParams(); I < N; ++I) {
122 QualType Ty = F->getParamDecl(I)->getType();
156 assert(Offset < Func->getFrameSize() &&
"Invalid local offset.");
158 reinterpret_cast<Block *>(Locals.get() + Offset -
sizeof(
Block)));
163 auto Pt = Params.find(Off);
164 if (Pt != Params.end()) {
165 return Pointer(reinterpret_cast<Block *>(Pt->second.get()));
170 size_t BlockSize =
sizeof(
Block) + Desc.second->getAllocSize();
171 auto Memory = std::make_unique<char[]>(BlockSize);
172 auto *B =
new (Memory.get())
Block(Desc.second);
175 TYPE_SWITCH(Desc.first, new (B->data()) T(stackRef<T>(Off)));
178 Params.insert({Off, std::move(Memory)});
llvm::iterator_range< llvm::SmallVector< Scope, 2 >::iterator > scopes()
Range over the scope blocks.
Represents a function declaration or definition.
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
A (possibly-)qualified type.
Pointer getParamPointer(unsigned Offset)
Returns a pointer to an argument - lazily creates a block.
void initialize() const
Initializes a field.
Pointer into the code segment.
SourceLocation getLocation(CodePtr PC) const
Frame storing local variables.
Pointer getLocalPointer(unsigned Offset)
Returns a pointer to a local variables.
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
const FunctionDecl * getDecl() const
Returns the original FunctionDecl.
bool This(InterpState &S, CodePtr OpPC)
bool hasRVO() const
Checks if the first argument is a RVO pointer.
Describes the statement/declaration an opcode was generated from.
llvm::Optional< PrimType > classify(QualType T)
Classifies an expression.
A pointer to a memory block, live or dead.
InterpFrame * Caller
The frame of the previous function.
Scope & getScope(unsigned Idx)
Returns a specific scope.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool isConstructor() const
Checks if the function is a constructor.
ParamDescriptor getParamDescriptor(unsigned Offset) const
Returns a parameter descriptor.
InterpStack & Stk
Temporary stack.
A memory block, either on the stack or in the heap.
bool isReferenceType() const
void destroy(unsigned Idx)
Invokes the destructors for a scope.
ASTContext & getCtx() const override
PrimType
Enumeration of the primitive types of the VM.
const clang::PrintingPolicy & getPrintingPolicy() const
bool isRoot() const
Pointer points directly to a block.
Context & Ctx
Interpreter Context.
Describes a memory block created by an allocation site.
void popArgs()
Pops the arguments off the stack.
This represents one expression.
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
void invokeCtor()
Invokes the constructor.
virtual SourceInfo getSource(CodePtr PC) const
Map a location to a source.
~InterpFrame()
Destroys the frame, killing all live pointers to stack slots.
QualType getRecordType(const RecordDecl *Decl) const
Base class for stack frames, shared between VM and walker.
Encodes a location in the source.
Represents a static or instance method of a struct/union/class.
unsigned getFrameSize() const
Returns the size of the function's local stack.
bool isBaseClass() const
Checks if a structure is a base class.
const Expr * getExpr(CodePtr PC) const
InterpFrame(InterpState &S, Function *Func, InterpFrame *Caller, CodePtr RetPC, Pointer &&This)
Creates a new frame for a method call.
SourceInfo getSource(Function *F, CodePtr PC) const override
Delegates source mapping to the mapper.
Dataflow Directional Tag Classes.
const FunctionDecl * getCallee() const
Returns the caller.
void deallocate(Block *B)
Deallocates a pointer.
llvm::iterator_range< LocalVectorTy::iterator > locals()
bool isZero() const
Checks if the pointer is null.
Descriptor * getDeclDesc() const
Accessor for information about the declaration site.
Frame * getCaller() const
Returns the parent frame object.
const Expr * getExpr(Function *F, CodePtr PC) const
Returns the expression if an opcode belongs to one, null otherwise.
#define TYPE_SWITCH(Expr, B)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
SourceLocation getCallLocation() const
Returns the location of the call to the frame.
void describe(llvm::raw_ostream &OS)
Describes the frame with arguments for diagnostic purposes.
SourceLocation getLocation(Function *F, CodePtr PC) const
Returns the location from which an opcode originates.
static void print(llvm::raw_ostream &OS, const T &V, ASTContext &, QualType)
void discard()
Discards the top value from the stack.
llvm::iterator_range< arg_reverse_iterator > args_reverse()