template <PrimType OpType>
bool EvalEmitter::emitCall(const Function *Func, const SourceInfo &Info) {
- S.Current = new InterpFrame(S, const_cast<Function *>(Func), {});
+ S.Current = new InterpFrame(S, Func, {});
// Result of call will be on the stack and needs to be handled by the caller.
return Interpret(S, Result);
}
APValue VoidResult;
InterpFrame *before = S.Current;
(void)before;
- S.Current = new InterpFrame(S, const_cast<Function *>(Func), {});
+ S.Current = new InterpFrame(S, Func, {});
bool Success = Interpret(S, VoidResult);
assert(VoidResult.isAbsent());
assert(S.Current == before);
Local createLocal(Descriptor *D);
/// Returns the source location of the current opcode.
- SourceInfo getSource(Function *F, CodePtr PC) const override {
+ SourceInfo getSource(const Function *F, CodePtr PC) const override {
return F ? F->getSource(PC) : CurrentSource;
}
Scope(LocalVectorTy &&Descriptors) : Descriptors(std::move(Descriptors)) {}
- llvm::iterator_range<LocalVectorTy::iterator> locals() {
+ llvm::iterator_range<LocalVectorTy::const_iterator> locals() const {
return llvm::make_range(Descriptors.begin(), Descriptors.end());
}
bool hasRVO() const { return HasRVO; }
/// Range over the scope blocks.
- llvm::iterator_range<llvm::SmallVector<Scope, 2>::iterator> scopes() {
+ llvm::iterator_range<llvm::SmallVector<Scope, 2>::const_iterator>
+ scopes() const {
return llvm::make_range(Scopes.begin(), Scopes.end());
}
/// Range over argument types.
- using arg_reverse_iterator = SmallVectorImpl<PrimType>::reverse_iterator;
- llvm::iterator_range<arg_reverse_iterator> args_reverse() {
+ using arg_reverse_iterator =
+ SmallVectorImpl<PrimType>::const_reverse_iterator;
+ llvm::iterator_range<arg_reverse_iterator> args_reverse() const {
return llvm::make_range(ParamTypes.rbegin(), ParamTypes.rend());
}
/// Returns a specific scope.
Scope &getScope(unsigned Idx) { return Scopes[Idx]; }
+ const Scope &getScope(unsigned Idx) const { return Scopes[Idx]; }
/// Returns the source information at a given PC.
SourceInfo getSource(CodePtr PC) const;
using namespace clang;
using namespace clang::interp;
-InterpFrame::InterpFrame(InterpState &S, Function *Func, InterpFrame *Caller,
- CodePtr RetPC, Pointer &&This)
+InterpFrame::InterpFrame(InterpState &S, const Function *Func,
+ InterpFrame *Caller, CodePtr RetPC, Pointer &&This)
: Caller(Caller), S(S), Func(Func), This(std::move(This)), RetPC(RetPC),
ArgSize(Func ? Func->getArgSize() : 0),
Args(static_cast<char *>(S.Stk.top())), FrameOffset(S.Stk.size()) {
}
}
-InterpFrame::InterpFrame(InterpState &S, Function *Func, CodePtr RetPC)
+InterpFrame::InterpFrame(InterpState &S, const Function *Func, CodePtr RetPC)
: Caller(S.Current), S(S), Func(Func), RetPC(RetPC),
ArgSize(Func ? Func->getArgSize() : 0),
Args(static_cast<char *>(S.Stk.top())), FrameOffset(S.Stk.size()) {
InterpFrame *Caller;
/// Creates a new frame for a method call.
- InterpFrame(InterpState &S, Function *Func, InterpFrame *Caller,
+ InterpFrame(InterpState &S, const Function *Func, InterpFrame *Caller,
CodePtr RetPC, Pointer &&This);
/// Creates a new frame with the values that make sense.
/// I.e., the caller is the current frame of S,
/// and the This() pointer is the current Pointer on the top of S's stack,
- InterpFrame(InterpState &S, Function *Func, CodePtr RetPC);
+ InterpFrame(InterpState &S, const Function *Func, CodePtr RetPC);
/// Destroys the frame, killing all live pointers to stack slots.
~InterpFrame();
const FunctionDecl *getCallee() const override;
/// Returns the current function.
- Function *getFunction() const { return Func; }
+ const Function *getFunction() const { return Func; }
/// Returns the offset on the stack at which the frame starts.
size_t getFrameOffset() const { return FrameOffset; }
/// Reference to the interpreter state.
InterpState &S;
/// Reference to the function being executed.
- Function *Func;
+ const Function *Func;
/// Current object pointer for methods.
Pointer This;
/// Return address.
void deallocate(Block *B);
/// Delegates source mapping to the mapper.
- SourceInfo getSource(Function *F, CodePtr PC) const override {
+ SourceInfo getSource(const Function *F, CodePtr PC) const override {
return M ? M->getSource(F, PC) : F->getSource(PC);
}
return nullptr;
}
-const Expr *SourceMapper::getExpr(Function *F, CodePtr PC) const {
+const Expr *SourceMapper::getExpr(const Function *F, CodePtr PC) const {
if (const Expr *E = getSource(F, PC).asExpr())
return E;
llvm::report_fatal_error("missing source expression");
}
-SourceLocation SourceMapper::getLocation(Function *F, CodePtr PC) const {
+SourceLocation SourceMapper::getLocation(const Function *F, CodePtr PC) const {
return getSource(F, PC).getLoc();
}
virtual ~SourceMapper() {}
/// Returns source information for a given PC in a function.
- virtual SourceInfo getSource(Function *F, CodePtr PC) const = 0;
+ virtual SourceInfo getSource(const Function *F, CodePtr PC) const = 0;
/// Returns the expression if an opcode belongs to one, null otherwise.
- const Expr *getExpr(Function *F, CodePtr PC) const;
+ const Expr *getExpr(const Function *F, CodePtr PC) const;
/// Returns the location from which an opcode originates.
- SourceLocation getLocation(Function *F, CodePtr PC) const;
+ SourceLocation getLocation(const Function *F, CodePtr PC) const;
};
} // namespace interp