https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/215528
Instead of having different `SourceMapper` implementations, just ask the `Function` directly if we have one, and fall back to the `SourceMapper` otherwise. We now only have one `SourceMapper` implementation though: `EvalEmitter`. And the only reason we have this is so we don't have a circular dependency between `InterpState` and `EvalEmitter`. >From 8b5c60c3ee4d9a726eecee1c1f67bdd974f967c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]> Date: Tue, 11 Aug 2026 13:22:38 +0200 Subject: [PATCH] source mapper mess --- clang/lib/AST/ByteCode/EvalEmitter.h | 8 +++---- clang/lib/AST/ByteCode/InterpFrame.cpp | 30 ++++++++++++++++++-------- clang/lib/AST/ByteCode/InterpState.h | 13 ++++++----- clang/lib/AST/ByteCode/Source.cpp | 20 ++++++----------- clang/lib/AST/ByteCode/Source.h | 10 ++++----- 5 files changed, 41 insertions(+), 40 deletions(-) diff --git a/clang/lib/AST/ByteCode/EvalEmitter.h b/clang/lib/AST/ByteCode/EvalEmitter.h index 6ad4f833f9dad..26bb22a71a3ce 100644 --- a/clang/lib/AST/ByteCode/EvalEmitter.h +++ b/clang/lib/AST/ByteCode/EvalEmitter.h @@ -57,6 +57,9 @@ class EvalEmitter : public SourceMapper { /// Clean up all resources. void cleanup(); + /// Returns the source location of the current opcode. + SourceInfo getSource(CodePtr PC) const override { return CurrentSource; } + protected: EvalEmitter(Context &Ctx, Program &P, State &Parent, InterpStack &Stk); @@ -99,11 +102,6 @@ class EvalEmitter : public SourceMapper { /// Callback for registering a local. Local createLocal(Descriptor *D); - /// Returns the source location of the current opcode. - SourceInfo getSource(const Function *F, CodePtr PC) const override { - return (F && F->hasBody()) ? F->getSource(PC) : CurrentSource; - } - /// Parameter indices. llvm::DenseMap<const ParmVarDecl *, FuncParam> Params; /// Local descriptors. diff --git a/clang/lib/AST/ByteCode/InterpFrame.cpp b/clang/lib/AST/ByteCode/InterpFrame.cpp index 64bad66b9b6c8..a91f6172ca9ca 100644 --- a/clang/lib/AST/ByteCode/InterpFrame.cpp +++ b/clang/lib/AST/ByteCode/InterpFrame.cpp @@ -217,7 +217,7 @@ void InterpFrame::describe(llvm::raw_ostream &OS) const { SourceRange InterpFrame::getCallRange() const { if (!Caller->Func) { - if (SourceRange NullRange = S.getRange(nullptr, {}); NullRange.isValid()) + if (SourceRange NullRange = S.getRange({}); NullRange.isValid()) return NullRange; return S.EvalLocation; } @@ -227,7 +227,8 @@ SourceRange InterpFrame::getCallRange() const { if (!C->RetPC) continue; SourceRange CallRange = - S.getRange(C->Caller->Func, C->getRetOpPC() - sizeof(uintptr_t)); + C->Caller->Func->getSource(C->getRetOpPC() - sizeof(uintptr_t)) + .getRange(); if (CallRange.isValid()) return CallRange; } @@ -277,6 +278,9 @@ static bool funcHasUsableBody(const Function *F) { } SourceInfo InterpFrame::getSource(CodePtr PC) const { + if (!Func) + return S.getSource(PC); + // Implicitly created functions don't have any code we could point at, // so return the call site. if (Func && !funcHasUsableBody(Func) && Caller) @@ -284,7 +288,7 @@ SourceInfo InterpFrame::getSource(CodePtr PC) const { // Similarly, if the resulting source location is invalid anyway, // point to the caller instead. - SourceInfo Result = S.getSource(Func, PC); + SourceInfo Result = Func->getSource(PC); if (Result.getLoc().isInvalid() && Caller) return Caller->getSource(getRetOpPC()); @@ -292,24 +296,32 @@ SourceInfo InterpFrame::getSource(CodePtr PC) const { } const Expr *InterpFrame::getExpr(CodePtr PC) const { - if (Func && !funcHasUsableBody(Func) && Caller) + if (!Func) + return S.getExpr(PC); + + if (!funcHasUsableBody(Func) && Caller) return Caller->getExpr(getRetOpPC()); - return S.getExpr(Func, PC); + return Func->getSource(PC).asExpr(); } SourceLocation InterpFrame::getLocation(CodePtr PC) const { - if (Func && !funcHasUsableBody(Func) && Caller) + if (!Func) + return S.getLocation(PC); + if (!funcHasUsableBody(Func) && Caller) return Caller->getLocation(getRetOpPC()); - return S.getLocation(Func, PC); + return Func->getSource(PC).getLoc(); } SourceRange InterpFrame::getRange(CodePtr PC) const { - if (Func && !funcHasUsableBody(Func) && Caller) + if (!Func) + return S.getRange(PC); + + if (!funcHasUsableBody(Func) && Caller) return Caller->getRange(getRetOpPC()); - return S.getRange(Func, PC); + return Func->getSource(PC).getRange(); } bool InterpFrame::isStdFunction() const { diff --git a/clang/lib/AST/ByteCode/InterpState.h b/clang/lib/AST/ByteCode/InterpState.h index 050fa4c77cd2f..36302889a499a 100644 --- a/clang/lib/AST/ByteCode/InterpState.h +++ b/clang/lib/AST/ByteCode/InterpState.h @@ -40,7 +40,7 @@ enum class EvaluationKind : uint8_t { }; /// Interpreter context. -class InterpState final : public State, public SourceMapper { +class InterpState final : public State { public: InterpState(const State &Parent, Program &P, InterpStack &Stk, Context &Ctx, SourceMapper *M = nullptr); @@ -68,13 +68,12 @@ class InterpState final : public State, public SourceMapper { void deallocate(Block *B); /// Delegates source mapping to the mapper. - SourceInfo getSource(const Function *F, CodePtr PC) const override { - if (M) - return M->getSource(F, PC); - - assert(F && "Function cannot be null"); - return F->getSource(PC); + SourceInfo getSource(CodePtr PC) const { return M->getSource(PC); } + const Expr *getExpr(CodePtr PC) const { return getSource(PC).asExpr(); } + SourceLocation getLocation(CodePtr PC) const { + return getSource(PC).getLoc(); } + SourceRange getRange(CodePtr PC) const { return getSource(PC).getRange(); } Context &getContext() const { return Ctx; } diff --git a/clang/lib/AST/ByteCode/Source.cpp b/clang/lib/AST/ByteCode/Source.cpp index d4ce7537f3d24..412fce2be5737 100644 --- a/clang/lib/AST/ByteCode/Source.cpp +++ b/clang/lib/AST/ByteCode/Source.cpp @@ -32,22 +32,14 @@ SourceRange SourceInfo::getRange() const { return SourceRange(); } -const Expr *SourceInfo::asExpr() const { - if (const auto *S = dyn_cast_if_present<const Stmt *>(Source)) - return dyn_cast<Expr>(S); - return nullptr; +const Expr *SourceMapper::getExpr(CodePtr PC) const { + return getSource(PC).asExpr(); } -const Expr *SourceMapper::getExpr(const Function *F, CodePtr PC) const { - if (const Expr *E = getSource(F, PC).asExpr()) - return E; - return nullptr; +SourceLocation SourceMapper::getLocation(CodePtr PC) const { + return getSource(PC).getLoc(); } -SourceLocation SourceMapper::getLocation(const Function *F, CodePtr PC) const { - return getSource(F, PC).getLoc(); -} - -SourceRange SourceMapper::getRange(const Function *F, CodePtr PC) const { - return getSource(F, PC).getRange(); +SourceRange SourceMapper::getRange(CodePtr PC) const { + return getSource(PC).getRange(); } diff --git a/clang/lib/AST/ByteCode/Source.h b/clang/lib/AST/ByteCode/Source.h index 464c1c8bc9811..32bc7856068fe 100644 --- a/clang/lib/AST/ByteCode/Source.h +++ b/clang/lib/AST/ByteCode/Source.h @@ -88,7 +88,7 @@ class SourceInfo final { const Decl *asDecl() const { return dyn_cast_if_present<const Decl *>(Source); } - const Expr *asExpr() const; + const Expr *asExpr() const { return dyn_cast_if_present<Expr>(asStmt()); } operator bool() const { return !Source.isNull(); } @@ -105,13 +105,13 @@ class SourceMapper { virtual ~SourceMapper() {} /// Returns source information for a given PC in a function. - virtual SourceInfo getSource(const Function *F, CodePtr PC) const = 0; + virtual SourceInfo getSource(CodePtr PC) const = 0; /// Returns the expression if an opcode belongs to one, null otherwise. - const Expr *getExpr(const Function *F, CodePtr PC) const; + const Expr *getExpr(CodePtr PC) const; /// Returns the location from which an opcode originates. - SourceLocation getLocation(const Function *F, CodePtr PC) const; - SourceRange getRange(const Function *F, CodePtr PC) const; + SourceLocation getLocation(CodePtr PC) const; + SourceRange getRange(CodePtr PC) const; }; } // namespace interp _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
