clang 19.0.0git
InterpFrame.h
Go to the documentation of this file.
1//===--- InterpFrame.h - Call Frame implementation for the VM ---*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Defines the class storing information about stack frames in the interpreter.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_INTERP_INTERPFRAME_H
14#define LLVM_CLANG_AST_INTERP_INTERPFRAME_H
15
16#include "Frame.h"
17#include "Program.h"
18#include <cstdint>
19#include <vector>
20
21namespace clang {
22namespace interp {
23class Function;
24class InterpState;
25class Pointer;
26
27/// Frame storing local variables.
28class InterpFrame final : public Frame {
29public:
30 /// The frame of the previous function.
32
33 /// Creates a new frame for a method call.
35 CodePtr RetPC, unsigned ArgSize);
36
37 /// Creates a new frame with the values that make sense.
38 /// I.e., the caller is the current frame of S,
39 /// the This() pointer is the current Pointer on the top of S's stack,
40 /// and the RVO pointer is before that.
41 InterpFrame(InterpState &S, const Function *Func, CodePtr RetPC,
42 unsigned VarArgSize = 0);
43
44 /// Destroys the frame, killing all live pointers to stack slots.
46
47 /// Invokes the destructors for a scope.
48 void destroy(unsigned Idx);
49
50 /// Pops the arguments off the stack.
51 void popArgs();
52
53 /// Describes the frame with arguments for diagnostic purposes.
54 void describe(llvm::raw_ostream &OS) const override;
55
56 /// Returns the parent frame object.
57 Frame *getCaller() const override;
58
59 /// Returns the location of the call to the frame.
60 SourceRange getCallRange() const override;
61
62 /// Returns the caller.
63 const FunctionDecl *getCallee() const override;
64
65 /// Returns the current function.
66 const Function *getFunction() const { return Func; }
67
68 /// Returns the offset on the stack at which the frame starts.
69 size_t getFrameOffset() const { return FrameOffset; }
70
71 /// Returns the value of a local variable.
72 template <typename T> const T &getLocal(unsigned Offset) const {
73 return localRef<T>(Offset);
74 }
75
76 /// Mutates a local variable.
77 template <typename T> void setLocal(unsigned Offset, const T &Value) {
78 localRef<T>(Offset) = Value;
79 localInlineDesc(Offset)->IsInitialized = true;
80 }
81
82 /// Returns a pointer to a local variables.
83 Pointer getLocalPointer(unsigned Offset) const;
84
85 /// Returns the value of an argument.
86 template <typename T> const T &getParam(unsigned Offset) const {
87 auto Pt = Params.find(Offset);
88 if (Pt == Params.end()) {
89 return stackRef<T>(Offset);
90 } else {
91 return Pointer(reinterpret_cast<Block *>(Pt->second.get())).deref<T>();
92 }
93 }
94
95 /// Mutates a local copy of a parameter.
96 template <typename T> void setParam(unsigned Offset, const T &Value) {
97 getParamPointer(Offset).deref<T>() = Value;
98 }
99
100 /// Returns a pointer to an argument - lazily creates a block.
101 Pointer getParamPointer(unsigned Offset);
102
103 /// Returns the 'this' pointer.
104 const Pointer &getThis() const { return This; }
105
106 /// Returns the RVO pointer, if the Function has one.
107 const Pointer &getRVOPtr() const { return RVOPtr; }
108
109 /// Checks if the frame is a root frame - return should quit the interpreter.
110 bool isRoot() const { return !Func; }
111
112 /// Returns the PC of the frame's code start.
113 CodePtr getPC() const { return Func->getCodeBegin(); }
114
115 /// Returns the return address of the frame.
116 CodePtr getRetPC() const { return RetPC; }
117
118 /// Map a location to a source.
119 virtual SourceInfo getSource(CodePtr PC) const;
120 const Expr *getExpr(CodePtr PC) const;
122 SourceRange getRange(CodePtr PC) const;
123
124 unsigned getDepth() const { return Depth; }
125
126 void dump() const { dump(llvm::errs(), 0); }
127 void dump(llvm::raw_ostream &OS, unsigned Indent = 0) const;
128
129private:
130 /// Returns an original argument from the stack.
131 template <typename T> const T &stackRef(unsigned Offset) const {
132 assert(Args);
133 return *reinterpret_cast<const T *>(Args - ArgSize + Offset);
134 }
135
136 /// Returns an offset to a local.
137 template <typename T> T &localRef(unsigned Offset) const {
138 return getLocalPointer(Offset).deref<T>();
139 }
140
141 /// Returns a pointer to a local's block.
142 Block *localBlock(unsigned Offset) const {
143 return reinterpret_cast<Block *>(Locals.get() + Offset - sizeof(Block));
144 }
145
146 /// Returns the inline descriptor of the local.
147 InlineDescriptor *localInlineDesc(unsigned Offset) const {
148 return reinterpret_cast<InlineDescriptor *>(Locals.get() + Offset);
149 }
150
151private:
152 /// Reference to the interpreter state.
153 InterpState &S;
154 /// Depth of this frame.
155 unsigned Depth;
156 /// Reference to the function being executed.
157 const Function *Func;
158 /// Current object pointer for methods.
159 Pointer This;
160 /// Pointer the non-primitive return value gets constructed in.
161 Pointer RVOPtr;
162 /// Return address.
163 CodePtr RetPC;
164 /// The size of all the arguments.
165 const unsigned ArgSize;
166 /// Pointer to the arguments in the callee's frame.
167 char *Args = nullptr;
168 /// Fixed, initial storage for known local variables.
169 std::unique_ptr<char[]> Locals;
170 /// Offset on the stack at entry.
171 const size_t FrameOffset;
172 /// Mapping from arg offsets to their argument blocks.
173 llvm::DenseMap<unsigned, std::unique_ptr<char[]>> Params;
174};
175
176} // namespace interp
177} // namespace clang
178
179#endif
const CFGBlock * Block
Definition: HTMLLogger.cpp:153
This represents one expression.
Definition: Expr.h:110
Represents a function declaration or definition.
Definition: Decl.h:1971
Encodes a location in the source.
A trivial tuple used to represent a source range.
A memory block, either on the stack or in the heap.
Definition: InterpBlock.h:49
Pointer into the code segment.
Definition: Source.h:30
Base class for stack frames, shared between VM and walker.
Definition: Frame.h:25
Bytecode function.
Definition: Function.h:77
CodePtr getCodeBegin() const
Returns a pointer to the start of the code.
Definition: Function.h:87
Frame storing local variables.
Definition: InterpFrame.h:28
void popArgs()
Pops the arguments off the stack.
Definition: InterpFrame.cpp:90
const Expr * getExpr(CodePtr PC) const
InterpFrame * Caller
The frame of the previous function.
Definition: InterpFrame.h:31
virtual SourceInfo getSource(CodePtr PC) const
Map a location to a source.
CodePtr getRetPC() const
Returns the return address of the frame.
Definition: InterpFrame.h:116
CodePtr getPC() const
Returns the PC of the frame's code start.
Definition: InterpFrame.h:113
SourceLocation getLocation(CodePtr PC) const
~InterpFrame()
Destroys the frame, killing all live pointers to stack slots.
Definition: InterpFrame.cpp:66
const Pointer & getThis() const
Returns the 'this' pointer.
Definition: InterpFrame.h:104
const Function * getFunction() const
Returns the current function.
Definition: InterpFrame.h:66
size_t getFrameOffset() const
Returns the offset on the stack at which the frame starts.
Definition: InterpFrame.h:69
SourceRange getRange(CodePtr PC) const
void setLocal(unsigned Offset, const T &Value)
Mutates a local variable.
Definition: InterpFrame.h:77
const T & getParam(unsigned Offset) const
Returns the value of an argument.
Definition: InterpFrame.h:86
bool isRoot() const
Checks if the frame is a root frame - return should quit the interpreter.
Definition: InterpFrame.h:110
Pointer getLocalPointer(unsigned Offset) const
Returns a pointer to a local variables.
unsigned getDepth() const
Definition: InterpFrame.h:124
Frame * getCaller() const override
Returns the parent frame object.
void setParam(unsigned Offset, const T &Value)
Mutates a local copy of a parameter.
Definition: InterpFrame.h:96
void destroy(unsigned Idx)
Invokes the destructors for a scope.
Definition: InterpFrame.cpp:84
const Pointer & getRVOPtr() const
Returns the RVO pointer, if the Function has one.
Definition: InterpFrame.h:107
Pointer getParamPointer(unsigned Offset)
Returns a pointer to an argument - lazily creates a block.
const FunctionDecl * getCallee() const override
Returns the caller.
const T & getLocal(unsigned Offset) const
Returns the value of a local variable.
Definition: InterpFrame.h:72
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.
Interpreter context.
Definition: InterpState.h:35
A pointer to a memory block, live or dead.
Definition: Pointer.h:80
T & deref() const
Dereferences the pointer, if it's live.
Definition: Pointer.h:580
Describes the statement/declaration an opcode was generated from.
Definition: Source.h:72
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
unsigned IsInitialized
For primitive fields, it indicates if the field was initialized.
Definition: Descriptor.h:69