[clang] 7a3767e - [clang][bytecode] Only pass OpPC if needed (#207479)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Jul 4 10:56:57 PDT 2026
Author: Timm Baeder
Date: 2026-07-04T19:56:52+02:00
New Revision: 7a3767e361cc0d6acc8e1568727a54d9b0d0b525
URL: https://github.com/llvm/llvm-project/commit/7a3767e361cc0d6acc8e1568727a54d9b0d0b525
DIFF: https://github.com/llvm/llvm-project/commit/7a3767e361cc0d6acc8e1568727a54d9b0d0b525.diff
LOG: [clang][bytecode] Only pass OpPC if needed (#207479)
Quite a few opcode implementations don't ever report a diagnostic, so
they don't need the `OpPC` at all. Add a tablegen bit to disable passing
`OpPC` altogether.
Added:
Modified:
clang/lib/AST/ByteCode/EvalEmitter.cpp
clang/lib/AST/ByteCode/Interp.cpp
clang/lib/AST/ByteCode/Interp.h
clang/lib/AST/ByteCode/Opcodes.td
clang/utils/TableGen/ClangOpcodesEmitter.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/EvalEmitter.cpp b/clang/lib/AST/ByteCode/EvalEmitter.cpp
index dbec700c80d44..34c85c7c66bdd 100644
--- a/clang/lib/AST/ByteCode/EvalEmitter.cpp
+++ b/clang/lib/AST/ByteCode/EvalEmitter.cpp
@@ -209,8 +209,8 @@ bool EvalEmitter::speculate(const CallExpr *E, const LabelTy &EndLabel) {
if (!isActive())
return true;
- PushIgnoreDiags(S, OpPC);
- auto _ = llvm::scope_exit([&]() { PopIgnoreDiags(S, OpPC); });
+ PushIgnoreDiags(S);
+ auto _ = llvm::scope_exit([&]() { PopIgnoreDiags(S); });
size_t StackSizeBefore = S.Stk.size();
const Expr *Arg = E->getArg(0);
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 4a7259b91a7f9..7884aa5b5b745 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -2365,7 +2365,7 @@ static void startLifetimeRecurse(PtrView Ptr) {
Ptr.startLifetime();
}
-bool StartThisLifetime(InterpState &S, CodePtr OpPC) {
+bool StartThisLifetime(InterpState &S) {
if (S.checkingPotentialConstantExpression())
return true;
@@ -2376,7 +2376,7 @@ bool StartThisLifetime(InterpState &S, CodePtr OpPC) {
return true;
}
-bool StartThisLifetime1(InterpState &S, CodePtr OpPC) {
+bool StartThisLifetime1(InterpState &S) {
if (S.checkingPotentialConstantExpression())
return true;
@@ -2695,8 +2695,7 @@ bool handleReference(InterpState &S, CodePtr OpPC, Block *B) {
return true;
}
-bool GetTypeid(InterpState &S, CodePtr OpPC, const Type *TypePtr,
- const Type *TypeInfoType) {
+bool GetTypeid(InterpState &S, const Type *TypePtr, const Type *TypeInfoType) {
S.Stk.push<Pointer>(TypePtr, TypeInfoType);
return true;
}
@@ -2891,7 +2890,7 @@ static void finishGlobalRecurse(InterpState &S, const Pointer &Ptr) {
}
}
-bool FinishInitGlobal(InterpState &S, CodePtr OpPC) {
+bool FinishInitGlobal(InterpState &S) {
const Pointer &Ptr = S.Stk.pop<Pointer>();
finishGlobalRecurse(S, Ptr);
@@ -3006,7 +3005,7 @@ static bool appendToMemberPointer(InterpState &S,
}
/// DerivedToBaseMemberPointer
-bool CastMemberPtrBasePop(InterpState &S, CodePtr OpPC, int32_t Off,
+bool CastMemberPtrBasePop(InterpState &S, int32_t Off,
const RecordDecl *BaseDecl) {
const auto &Ptr = S.Stk.pop<MemberPointer>();
@@ -3018,7 +3017,7 @@ bool CastMemberPtrBasePop(InterpState &S, CodePtr OpPC, int32_t Off,
}
/// BaseToDerivedMemberPointer
-bool CastMemberPtrDerivedPop(InterpState &S, CodePtr OpPC, int32_t Off,
+bool CastMemberPtrDerivedPop(InterpState &S, int32_t Off,
const RecordDecl *BaseDecl) {
const auto &Ptr = S.Stk.pop<MemberPointer>();
@@ -3031,12 +3030,12 @@ bool CastMemberPtrDerivedPop(InterpState &S, CodePtr OpPC, int32_t Off,
return castBackMemberPointer(S, Ptr, Off, BaseDecl);
}
-bool GetMemberPtr(InterpState &S, CodePtr OpPC, const ValueDecl *D) {
+bool GetMemberPtr(InterpState &S, const ValueDecl *D) {
S.Stk.push<MemberPointer>(D);
return true;
}
-bool GetMemberPtrBase(InterpState &S, CodePtr OpPC) {
+bool GetMemberPtrBase(InterpState &S) {
const auto &MP = S.Stk.pop<MemberPointer>();
if (!MP.isBaseCastPossible())
@@ -3046,7 +3045,7 @@ bool GetMemberPtrBase(InterpState &S, CodePtr OpPC) {
return true;
}
-bool GetMemberPtrDecl(InterpState &S, CodePtr OpPC) {
+bool GetMemberPtrDecl(InterpState &S) {
const auto &MP = S.Stk.pop<MemberPointer>();
const ValueDecl *D = MP.getDecl();
@@ -3073,7 +3072,7 @@ bool GetMemberPtrDecl(InterpState &S, CodePtr OpPC) {
/// Just append the given Entry to the MemberPointer's path.
/// This is used to re-inject APValues into the bytecode interpreter.
-bool CopyMemberPtrPath(InterpState &S, CodePtr OpPC, const RecordDecl *Entry,
+bool CopyMemberPtrPath(InterpState &S, const RecordDecl *Entry,
bool IsDerived) {
const auto &MemberPtr = S.Stk.pop<MemberPointer>();
@@ -3175,10 +3174,10 @@ PRESERVE_NONE static bool BCP(InterpState &S, CodePtr OpPC, int32_t Offset,
assert(DepthBefore >= 1);
#endif
- auto SpeculativeInterp = [&S, OpPC]() -> bool {
+ auto SpeculativeInterp = [&S]() -> bool {
// Ignore diagnostics during speculative execution.
- PushIgnoreDiags(S, OpPC);
- auto _ = llvm::scope_exit([&]() { PopIgnoreDiags(S, OpPC); });
+ PushIgnoreDiags(S);
+ auto _ = llvm::scope_exit([&]() { PopIgnoreDiags(S); });
#if USE_TAILCALLS
auto Op = S.PC.read<Opcode>();
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 61c2b0a5e5960..13e7798fcf365 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -243,10 +243,10 @@ bool InvalidDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR,
bool InitializerFailed);
/// DerivedToBaseMemberPointer
-bool CastMemberPtrBasePop(InterpState &S, CodePtr OpPC, int32_t Off,
+bool CastMemberPtrBasePop(InterpState &S, int32_t Off,
const RecordDecl *BaseDecl);
/// BaseToDerivedMemberPointer
-bool CastMemberPtrDerivedPop(InterpState &S, CodePtr OpPC, int32_t Off,
+bool CastMemberPtrDerivedPop(InterpState &S, int32_t Off,
const RecordDecl *BaseDecl);
enum class ArithOp { Add, Sub };
@@ -502,7 +502,7 @@ inline bool Mulf(InterpState &S, CodePtr OpPC, uint32_t FPOI) {
}
template <PrimType Name, class T = typename PrimConv<Name>::T>
-inline bool Mulc(InterpState &S, CodePtr OpPC) {
+inline bool Mulc(InterpState &S) {
const Pointer &RHS = S.Stk.pop<Pointer>();
const Pointer &LHS = S.Stk.pop<Pointer>();
const Pointer &Result = S.Stk.peek<Pointer>();
@@ -668,7 +668,7 @@ inline bool Divc(InterpState &S, CodePtr OpPC) {
/// 2) Pops the LHS from the stack.
/// 3) Pushes 'LHS & RHS' on the stack
template <PrimType Name, class T = typename PrimConv<Name>::T>
-bool BitAnd(InterpState &S, CodePtr OpPC) {
+bool BitAnd(InterpState &S) {
const T &RHS = S.Stk.pop<T>();
const T &LHS = S.Stk.pop<T>();
unsigned Bits = RHS.bitWidth();
@@ -693,7 +693,7 @@ bool BitAnd(InterpState &S, CodePtr OpPC) {
/// 2) Pops the LHS from the stack.
/// 3) Pushes 'LHS | RHS' on the stack
template <PrimType Name, class T = typename PrimConv<Name>::T>
-bool BitOr(InterpState &S, CodePtr OpPC) {
+bool BitOr(InterpState &S) {
const T &RHS = S.Stk.pop<T>();
const T &LHS = S.Stk.pop<T>();
unsigned Bits = RHS.bitWidth();
@@ -718,7 +718,7 @@ bool BitOr(InterpState &S, CodePtr OpPC) {
/// 2) Pops the LHS from the stack.
/// 3) Pushes 'LHS ^ RHS' on the stack
template <PrimType Name, class T = typename PrimConv<Name>::T>
-bool BitXor(InterpState &S, CodePtr OpPC) {
+bool BitXor(InterpState &S) {
const T &RHS = S.Stk.pop<T>();
const T &LHS = S.Stk.pop<T>();
unsigned Bits = RHS.bitWidth();
@@ -812,7 +812,7 @@ inline bool Divf(InterpState &S, CodePtr OpPC, uint32_t FPOI) {
// Inv
//===----------------------------------------------------------------------===//
-inline bool Inv(InterpState &S, CodePtr OpPC) {
+inline bool Inv(InterpState &S) {
const auto &Val = S.Stk.pop<Boolean>();
S.Stk.push<Boolean>(!Val);
return true;
@@ -1176,7 +1176,7 @@ inline bool DecfPop(InterpState &S, CodePtr OpPC, uint32_t FPOI) {
/// 1) Pops the value from the stack.
/// 2) Pushes the bitwise complemented value on the stack (~V).
template <PrimType Name, class T = typename PrimConv<Name>::T>
-bool Comp(InterpState &S, CodePtr OpPC) {
+bool Comp(InterpState &S) {
const T &Val = S.Stk.pop<T>();
T Result;
@@ -1537,20 +1537,19 @@ bool GE(InterpState &S, CodePtr OpPC) {
//===----------------------------------------------------------------------===//
template <PrimType Name, class T = typename PrimConv<Name>::T>
-bool Dup(InterpState &S, CodePtr OpPC) {
+bool Dup(InterpState &S) {
S.Stk.push<T>(S.Stk.peek<T>());
return true;
}
template <PrimType Name, class T = typename PrimConv<Name>::T>
-bool Pop(InterpState &S, CodePtr OpPC) {
+bool Pop(InterpState &S) {
S.Stk.discard<T>();
return true;
}
/// [Value1, Value2] -> [Value2, Value1]
-template <PrimType TopName, PrimType BottomName>
-bool Flip(InterpState &S, CodePtr OpPC) {
+template <PrimType TopName, PrimType BottomName> bool Flip(InterpState &S) {
using TopT = typename PrimConv<TopName>::T;
using BottomT = typename PrimConv<BottomName>::T;
@@ -1568,7 +1567,7 @@ bool Flip(InterpState &S, CodePtr OpPC) {
//===----------------------------------------------------------------------===//
template <PrimType Name, class T = typename PrimConv<Name>::T>
-bool Const(InterpState &S, CodePtr OpPC, const T &Arg) {
+bool Const(InterpState &S, const T &Arg) {
if constexpr (needsAlloc<T>()) {
T Result = S.allocAP<T>(Arg.bitWidth());
Result.copy(Arg.toAPSInt());
@@ -1596,7 +1595,7 @@ bool Const(InterpState &S, CodePtr OpPC, const T &Arg) {
return true;
}
-inline bool ConstFloat(InterpState &S, CodePtr OpPC, const Floating &F) {
+inline bool ConstFloat(InterpState &S, const Floating &F) {
Floating Result = S.allocFloat(F.getSemantics());
Result.copy(F.getAPFloat());
S.Stk.push<Floating>(Result);
@@ -1618,21 +1617,21 @@ bool GetLocal(InterpState &S, CodePtr OpPC, uint32_t I) {
bool EndLifetime(InterpState &S, CodePtr OpPC);
bool EndLifetimePop(InterpState &S, CodePtr OpPC);
-bool StartThisLifetime(InterpState &S, CodePtr OpPC);
-bool StartThisLifetime1(InterpState &S, CodePtr OpPC);
+bool StartThisLifetime(InterpState &S);
+bool StartThisLifetime1(InterpState &S);
bool MarkDestroyed(InterpState &S, CodePtr OpPC);
/// 1) Pops the value from the stack.
/// 2) Writes the value to the local variable with the
/// given offset.
template <PrimType Name, class T = typename PrimConv<Name>::T>
-bool SetLocal(InterpState &S, CodePtr OpPC, uint32_t I) {
+bool SetLocal(InterpState &S, uint32_t I) {
S.Current->setLocal<T>(I, S.Stk.pop<T>());
return true;
}
template <PrimType Name, class T = typename PrimConv<Name>::T>
-bool GetParam(InterpState &S, CodePtr OpPC, uint32_t Index) {
+bool GetParam(InterpState &S, uint32_t Index) {
if (S.checkingPotentialConstantExpression()) {
return false;
}
@@ -1641,7 +1640,7 @@ bool GetParam(InterpState &S, CodePtr OpPC, uint32_t Index) {
}
template <PrimType Name, class T = typename PrimConv<Name>::T>
-bool SetParam(InterpState &S, CodePtr OpPC, uint32_t I) {
+bool SetParam(InterpState &S, uint32_t I) {
S.Current->setParam<T>(I, S.Stk.pop<T>());
return true;
}
@@ -1767,7 +1766,7 @@ bool SetGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
}
template <PrimType Name, class T = typename PrimConv<Name>::T>
-bool InitGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
+bool InitGlobal(InterpState &S, uint32_t I) {
const Pointer &P = S.P.getGlobal(I);
P.deref<T>() = S.Stk.pop<T>();
@@ -1803,7 +1802,7 @@ bool InitGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
/// 2) Sets that APValue on \Temp
/// 3) Initializes global with index \I with that
template <PrimType Name, class T = typename PrimConv<Name>::T>
-bool InitGlobalTemp(InterpState &S, CodePtr OpPC, uint32_t I,
+bool InitGlobalTemp(InterpState &S, uint32_t I,
const LifetimeExtendedTemporaryDecl *Temp) {
if (S.EvalMode == EvaluationMode::ConstantFold)
return false;
@@ -1822,7 +1821,7 @@ bool InitGlobalTemp(InterpState &S, CodePtr OpPC, uint32_t I,
/// 1) Converts the value on top of the stack to an APValue
/// 2) Sets that APValue on \Temp
/// 3) Initialized global with index \I with that
-inline bool InitGlobalTempComp(InterpState &S, CodePtr OpPC,
+inline bool InitGlobalTempComp(InterpState &S,
const LifetimeExtendedTemporaryDecl *Temp) {
if (S.EvalMode == EvaluationMode::ConstantFold)
return false;
@@ -2038,7 +2037,7 @@ bool InitBitFieldActivate(InterpState &S, CodePtr OpPC, uint32_t FieldOffset,
// GetPtr Local/Param/Global/Field/This
//===----------------------------------------------------------------------===//
-inline bool GetPtrLocal(InterpState &S, CodePtr OpPC, uint32_t I) {
+inline bool GetPtrLocal(InterpState &S, uint32_t I) {
S.Stk.push<Pointer>(S.Current->getLocalPointer(I));
return true;
}
@@ -2077,14 +2076,14 @@ inline bool CheckRefInit(InterpState &S, CodePtr OpPC) {
return CheckRange(S, OpPC, Ptr, AK_Read);
}
-inline bool GetPtrParam(InterpState &S, CodePtr OpPC, uint32_t Index) {
+inline bool GetPtrParam(InterpState &S, uint32_t Index) {
if (S.Current->isBottomFrame())
return false;
S.Stk.push<Pointer>(S.Current->getParamPointer(Index));
return true;
}
-inline bool GetPtrGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
+inline bool GetPtrGlobal(InterpState &S, uint32_t I) {
S.Stk.push<Pointer>(S.P.getPtrGlobal(I));
return true;
}
@@ -2120,21 +2119,21 @@ inline bool GetPtrThisBase(InterpState &S, CodePtr OpPC, uint32_t Off) {
return true;
}
-inline bool FinishInitPop(InterpState &S, CodePtr OpPC) {
+inline bool FinishInitPop(InterpState &S) {
const Pointer &Ptr = S.Stk.pop<Pointer>();
if (Ptr.canBeInitialized())
Ptr.initialize();
return true;
}
-inline bool FinishInit(InterpState &S, CodePtr OpPC) {
+inline bool FinishInit(InterpState &S) {
const Pointer &Ptr = S.Stk.peek<Pointer>();
if (Ptr.canBeInitialized())
Ptr.initialize();
return true;
}
-inline bool FinishInitActivate(InterpState &S, CodePtr OpPC) {
+inline bool FinishInitActivate(InterpState &S) {
const Pointer &Ptr = S.Stk.peek<Pointer>();
if (Ptr.canBeInitialized()) {
Ptr.initialize();
@@ -2143,7 +2142,7 @@ inline bool FinishInitActivate(InterpState &S, CodePtr OpPC) {
return true;
}
-inline bool FinishInitActivatePop(InterpState &S, CodePtr OpPC) {
+inline bool FinishInitActivatePop(InterpState &S) {
const Pointer &Ptr = S.Stk.pop<Pointer>();
if (Ptr.canBeInitialized()) {
Ptr.initialize();
@@ -2152,9 +2151,9 @@ inline bool FinishInitActivatePop(InterpState &S, CodePtr OpPC) {
return true;
}
-bool FinishInitGlobal(InterpState &S, CodePtr OpPC);
+bool FinishInitGlobal(InterpState &S);
-inline bool Dump(InterpState &S, CodePtr OpPC) {
+inline bool Dump(InterpState &S) {
S.Stk.dump();
return true;
}
@@ -2169,7 +2168,7 @@ inline bool CheckNull(InterpState &S, CodePtr OpPC) {
return true;
}
-inline bool VirtBaseHelper(InterpState &S, CodePtr OpPC, const RecordDecl *Decl,
+inline bool VirtBaseHelper(InterpState &S, const RecordDecl *Decl,
const Pointer &Ptr) {
if (!Ptr.isBlockPointer())
return false;
@@ -2189,7 +2188,7 @@ inline bool GetPtrVirtBasePop(InterpState &S, CodePtr OpPC,
const Pointer &Ptr = S.Stk.pop<Pointer>();
if (!CheckNull(S, OpPC, Ptr, CSK_Base))
return false;
- return VirtBaseHelper(S, OpPC, D, Ptr);
+ return VirtBaseHelper(S, D, Ptr);
}
inline bool GetPtrThisVirtBase(InterpState &S, CodePtr OpPC,
@@ -2200,7 +2199,7 @@ inline bool GetPtrThisVirtBase(InterpState &S, CodePtr OpPC,
if (!CheckThis(S, OpPC))
return false;
const Pointer &This = S.Current->getThis();
- return VirtBaseHelper(S, OpPC, D, This);
+ return VirtBaseHelper(S, D, This);
}
//===----------------------------------------------------------------------===//
@@ -2261,14 +2260,14 @@ bool StorePop(InterpState &S, CodePtr OpPC) {
return true;
}
-static inline bool Activate(InterpState &S, CodePtr OpPC) {
+static inline bool Activate(InterpState &S) {
const Pointer &Ptr = S.Stk.peek<Pointer>();
if (Ptr.canBeInitialized())
Ptr.activate();
return true;
}
-static inline bool ActivateThisField(InterpState &S, CodePtr OpPC, uint32_t I) {
+static inline bool ActivateThisField(InterpState &S, uint32_t I) {
if (S.checkingPotentialConstantExpression())
return false;
if (!S.Current->hasThisPointer())
@@ -2487,7 +2486,7 @@ inline bool Memcpy(InterpState &S, CodePtr OpPC) {
return DoMemcpy(S, OpPC, Src, Dest);
}
-inline bool ToMemberPtr(InterpState &S, CodePtr OpPC) {
+inline bool ToMemberPtr(InterpState &S) {
const auto &Member = S.Stk.pop<MemberPointer>();
const auto &Base = S.Stk.pop<Pointer>();
@@ -2769,18 +2768,18 @@ inline bool SubPtr(InterpState &S, CodePtr OpPC, uint32_t ElemSize) {
return true;
}
-inline bool InitScope(InterpState &S, CodePtr OpPC, uint32_t I) {
+inline bool InitScope(InterpState &S, uint32_t I) {
S.Current->initScope(I);
return true;
}
-inline bool EnableLocal(InterpState &S, CodePtr OpPC, uint32_t I) {
+inline bool EnableLocal(InterpState &S, uint32_t I) {
assert(!S.Current->isLocalEnabled(I));
S.Current->enableLocal(I);
return true;
}
-inline bool GetLocalEnabled(InterpState &S, CodePtr OpPC, uint32_t I) {
+inline bool GetLocalEnabled(InterpState &S, uint32_t I) {
assert(S.Current);
S.Stk.push<bool>(S.Current->isLocalEnabled(I));
return true;
@@ -2819,7 +2818,7 @@ template <PrimType TIn, PrimType TOut> bool Cast(InterpState &S, CodePtr OpPC) {
/// 1) Pops a Floating from the stack.
/// 2) Pushes a new floating on the stack that uses the given semantics.
-inline bool CastFP(InterpState &S, CodePtr OpPC, const llvm::fltSemantics *Sem,
+inline bool CastFP(InterpState &S, const llvm::fltSemantics *Sem,
llvm::RoundingMode RM) {
Floating F = S.Stk.pop<Floating>();
Floating Result = S.allocFloat(*Sem);
@@ -2846,7 +2845,7 @@ inline bool CastFixedPoint(InterpState &S, CodePtr OpPC, uint32_t FPS) {
/// Like Cast(), but we cast to an arbitrary-bitwidth integral, so we need
/// to know what bitwidth the result should be.
template <PrimType Name, class T = typename PrimConv<Name>::T>
-bool CastAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
+bool CastAP(InterpState &S, uint32_t BitWidth) {
T Source = S.Stk.pop<T>();
if constexpr (isIntegralOrPointer<T>()) {
@@ -2865,7 +2864,7 @@ bool CastAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
}
template <PrimType Name, class T = typename PrimConv<Name>::T>
-bool CastAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
+bool CastAPS(InterpState &S, uint32_t BitWidth) {
T Source = S.Stk.pop<T>();
if constexpr (isIntegralOrPointer<T>()) {
@@ -3068,7 +3067,7 @@ static inline bool CastFloatingFixedPoint(InterpState &S, CodePtr OpPC,
return true;
}
-static inline bool CastFixedPointFloating(InterpState &S, CodePtr OpPC,
+static inline bool CastFixedPointFloating(InterpState &S,
const llvm::fltSemantics *Sem) {
const auto &Fixed = S.Stk.pop<FixedPoint>();
Floating Result = S.allocFloat(*Sem);
@@ -3139,12 +3138,12 @@ static inline bool PtrPtrCast(InterpState &S, CodePtr OpPC, bool SrcIsVoidPtr) {
//===----------------------------------------------------------------------===//
template <PrimType Name, class T = typename PrimConv<Name>::T>
-bool Zero(InterpState &S, CodePtr OpPC) {
+bool Zero(InterpState &S) {
S.Stk.push<T>(T::zero());
return true;
}
-static inline bool ZeroIntAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
+static inline bool ZeroIntAP(InterpState &S, uint32_t BitWidth) {
auto Result = S.allocAP<IntegralAP<false>>(BitWidth);
if (!Result.singleWord())
std::memset(Result.Memory, 0, Result.numWords() * sizeof(uint64_t));
@@ -3152,7 +3151,7 @@ static inline bool ZeroIntAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
return true;
}
-static inline bool ZeroIntAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
+static inline bool ZeroIntAPS(InterpState &S, uint32_t BitWidth) {
auto Result = S.allocAP<IntegralAP<true>>(BitWidth);
if (!Result.singleWord())
std::memset(Result.Memory, 0, Result.numWords() * sizeof(uint64_t));
@@ -3161,7 +3160,7 @@ static inline bool ZeroIntAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth) {
}
template <PrimType Name, class T = typename PrimConv<Name>::T>
-inline bool Null(InterpState &S, CodePtr OpPC, uint64_t Value, const Type *Ty) {
+inline bool Null(InterpState &S, uint64_t Value, const Type *Ty) {
// FIXME(perf): This is a somewhat often-used function and the value of a
// null pointer is almost always 0.
S.Stk.push<T>(Value, Ty);
@@ -3169,7 +3168,7 @@ inline bool Null(InterpState &S, CodePtr OpPC, uint64_t Value, const Type *Ty) {
}
template <PrimType Name, class T = typename PrimConv<Name>::T>
-inline bool IsNonNull(InterpState &S, CodePtr OpPC) {
+inline bool IsNonNull(InterpState &S) {
const auto &P = S.Stk.pop<T>();
if (P.isWeak())
return false;
@@ -3208,7 +3207,7 @@ inline bool This(InterpState &S, CodePtr OpPC) {
return true;
}
-inline bool RVOPtr(InterpState &S, CodePtr OpPC) {
+inline bool RVOPtr(InterpState &S) {
assert(S.Current->getFunction()->hasRVO());
if (S.checkingPotentialConstantExpression())
return false;
@@ -3423,7 +3422,7 @@ static inline bool ShiftFixedPoint(InterpState &S, CodePtr OpPC, bool Left) {
//===----------------------------------------------------------------------===//
// NoRet
//===----------------------------------------------------------------------===//
-PRESERVE_NONE inline bool NoRet(InterpState &S, CodePtr OpPC) {
+PRESERVE_NONE inline bool NoRet(InterpState &S) {
SourceLocation EndLoc = S.Current->getCallee()->getEndLoc();
S.FFDiag(EndLoc, diag::note_constexpr_no_return);
return false;
@@ -3433,13 +3432,13 @@ PRESERVE_NONE inline bool NoRet(InterpState &S, CodePtr OpPC) {
// NarrowPtr, ExpandPtr
//===----------------------------------------------------------------------===//
-inline bool NarrowPtr(InterpState &S, CodePtr OpPC) {
+inline bool NarrowPtr(InterpState &S) {
const Pointer &Ptr = S.Stk.pop<Pointer>();
S.Stk.push<Pointer>(Ptr.narrow());
return true;
}
-inline bool ExpandPtr(InterpState &S, CodePtr OpPC) {
+inline bool ExpandPtr(InterpState &S) {
const Pointer &Ptr = S.Stk.pop<Pointer>();
if (Ptr.isBlockPointer())
S.Stk.push<Pointer>(Ptr.expand());
@@ -3597,7 +3596,7 @@ inline bool ArrayDecay(InterpState &S, CodePtr OpPC) {
return false;
}
-inline bool GetFnPtr(InterpState &S, CodePtr OpPC, const Function *Func) {
+inline bool GetFnPtr(InterpState &S, const Function *Func) {
assert(Func);
S.Stk.push<Pointer>(Func);
return true;
@@ -3638,11 +3637,10 @@ inline bool GetIntPtr(InterpState &S, CodePtr OpPC, const Type *Ty) {
return true;
}
-bool GetMemberPtr(InterpState &S, CodePtr OpPC, const ValueDecl *D);
-bool GetMemberPtrBase(InterpState &S, CodePtr OpPC);
-bool GetMemberPtrDecl(InterpState &S, CodePtr OpPC);
-bool CopyMemberPtrPath(InterpState &S, CodePtr OpPC, const RecordDecl *Entry,
- bool IsDerived);
+bool GetMemberPtr(InterpState &S, const ValueDecl *D);
+bool GetMemberPtrBase(InterpState &S);
+bool GetMemberPtrDecl(InterpState &S);
+bool CopyMemberPtrPath(InterpState &S, const RecordDecl *Entry, bool IsDerived);
/// Just emit a diagnostic. The expression that caused emission of this
/// op is not valid in a constant context.
@@ -3654,7 +3652,7 @@ inline bool Unsupported(InterpState &S, CodePtr OpPC) {
return false;
}
-inline bool PushIgnoreDiags(InterpState &S, CodePtr OpPC) {
+inline bool PushIgnoreDiags(InterpState &S) {
++S.DiagIgnoreDepth;
if (S.DiagIgnoreDepth != 1)
return true;
@@ -3666,7 +3664,7 @@ inline bool PushIgnoreDiags(InterpState &S, CodePtr OpPC) {
return true;
}
-inline bool PopIgnoreDiags(InterpState &S, CodePtr OpPC) {
+inline bool PopIgnoreDiags(InterpState &S) {
assert(S.DiagIgnoreDepth != 0);
--S.DiagIgnoreDepth;
if (S.DiagIgnoreDepth == 0) {
@@ -3677,20 +3675,20 @@ inline bool PopIgnoreDiags(InterpState &S, CodePtr OpPC) {
return true;
}
-inline bool StartSpeculation(InterpState &S, CodePtr OpPC) {
+inline bool StartSpeculation(InterpState &S) {
#ifndef NDEBUG
++S.SpeculationDepth;
#endif
return true;
}
-inline bool StartInit(InterpState &S, CodePtr OpPC) {
+inline bool StartInit(InterpState &S) {
const Pointer &Ptr = S.Stk.peek<Pointer>();
S.InitializingPtrs.push_back(Ptr.view());
return true;
}
-inline bool EndInit(InterpState &S, CodePtr OpPC) {
+inline bool EndInit(InterpState &S) {
S.InitializingPtrs.pop_back();
return true;
}
@@ -3706,22 +3704,22 @@ PRESERVE_NONE inline bool EndSpeculation(InterpState &S) {
return true;
}
-inline bool PushCC(InterpState &S, CodePtr OpPC, bool Value) {
+inline bool PushCC(InterpState &S, bool Value) {
S.ConstantContextOverride = Value;
return true;
}
-inline bool PopCC(InterpState &S, CodePtr OpPC) {
+inline bool PopCC(InterpState &S) {
S.ConstantContextOverride = std::nullopt;
return true;
}
-inline bool PushMSVCCE(InterpState &S, CodePtr OpPC) {
+inline bool PushMSVCCE(InterpState &S) {
// This is a per-frame property.
++S.Current->MSVCConstexprAllowed;
return true;
}
-inline bool PopMSVCCE(InterpState &S, CodePtr OpPC) {
+inline bool PopMSVCCE(InterpState &S) {
assert(S.Current->MSVCConstexprAllowed >= 1);
// This is a per-frame property.
--S.Current->MSVCConstexprAllowed;
@@ -3729,17 +3727,15 @@ inline bool PopMSVCCE(InterpState &S, CodePtr OpPC) {
}
/// Do nothing and just abort execution.
-inline bool Error(InterpState &S, CodePtr OpPC) { return false; }
+inline bool Error(InterpState &S) { return false; }
-inline bool SideEffect(InterpState &S, CodePtr OpPC) {
- return S.noteSideEffect();
-}
+inline bool SideEffect(InterpState &S) { return S.noteSideEffect(); }
/// Abort without a diagnostic if we're checking for a potential constant
/// expression and this is not the bottom frame. This is used in constructors to
/// allow evaluating their initializers but abort if we encounter anything in
/// their body.
-inline bool CtorCheck(InterpState &S, CodePtr OpPC) {
+inline bool CtorCheck(InterpState &S) {
if (S.checkingPotentialConstantExpression() && !S.Current->isBottomFrame())
return false;
return true;
@@ -3829,8 +3825,7 @@ inline bool CheckEnumValue(InterpState &S, CodePtr OpPC, const EnumDecl *ED) {
}
/// OldPtr -> Integer -> NewPtr.
-template <PrimType TIn, PrimType TOut>
-inline bool DecayPtr(InterpState &S, CodePtr OpPC) {
+template <PrimType TIn, PrimType TOut> inline bool DecayPtr(InterpState &S) {
static_assert(isPtrType(TIn) && isPtrType(TOut));
using FromT = typename PrimConv<TIn>::T;
using ToT = typename PrimConv<TOut>::T;
@@ -3854,7 +3849,7 @@ inline bool DecayPtr(InterpState &S, CodePtr OpPC) {
return true;
}
-inline bool CheckDecl(InterpState &S, CodePtr OpPC, const VarDecl *VD) {
+inline bool CheckDecl(InterpState &S, const VarDecl *VD) {
// An expression E is a core constant expression unless the evaluation of E
// would evaluate one of the following: [C++23] - a control flow that passes
// through a declaration of a variable with static or thread storage duration
@@ -3989,12 +3984,12 @@ inline bool AllocCN(InterpState &S, CodePtr OpPC, const Descriptor *ElementDesc,
bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm,
bool IsGlobalDelete);
-static inline bool IsConstantContext(InterpState &S, CodePtr OpPC) {
+static inline bool IsConstantContext(InterpState &S) {
S.Stk.push<Boolean>(Boolean::from(S.inConstantContext()));
return true;
}
-static inline bool CheckAllocations(InterpState &S, CodePtr OpPC) {
+static inline bool CheckAllocations(InterpState &S) {
return S.maybeDiagnoseDanglingAllocations();
}
@@ -4102,8 +4097,7 @@ inline bool BitCast(InterpState &S, CodePtr OpPC) {
}
/// Typeid support.
-bool GetTypeid(InterpState &S, CodePtr OpPC, const Type *TypePtr,
- const Type *TypeInfoType);
+bool GetTypeid(InterpState &S, const Type *TypePtr, const Type *TypeInfoType);
bool GetTypeidPtr(InterpState &S, CodePtr OpPC, const Type *TypeInfoType);
bool DiagTypeid(InterpState &S, CodePtr OpPC);
diff --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td
index 8123ca7497335..577c8523ab6c3 100644
--- a/clang/lib/AST/ByteCode/Opcodes.td
+++ b/clang/lib/AST/ByteCode/Opcodes.td
@@ -145,10 +145,12 @@ class Opcode {
bit HasCustomEval = 0;
bit HasGroup = 0;
bit CanFail = 1;
+ bit NeedsOpPC = 1;
}
class SuccessOpcode : Opcode {
let CanFail = 0;
+ let NeedsOpPC = 0;
}
class AluOpcode : Opcode {
@@ -218,7 +220,9 @@ def RetValue : Opcode {
let HasCustomEval = 1;
}
// [] -> EXIT
-def NoRet : Opcode {}
+def NoRet : Opcode {
+ let NeedsOpPC = 0;
+}
def Call : Opcode {
@@ -254,16 +258,16 @@ def Destroy : Opcode {
let Args = [ArgUint32];
let HasCustomEval = 1;
}
-def InitScope : Opcode {
+def InitScope : SuccessOpcode {
let Args = [ArgUint32];
}
-def GetLocalEnabled : Opcode {
+def GetLocalEnabled : SuccessOpcode {
let Args = [ArgUint32];
let HasCustomEval = 1;
}
-def EnableLocal : Opcode {
+def EnableLocal : SuccessOpcode {
let Args = [ArgUint32];
let HasCustomEval = 1;
}
@@ -272,11 +276,10 @@ def EnableLocal : Opcode {
// Constants
//===----------------------------------------------------------------------===//
-class ConstOpcode<Type Ty, ArgType ArgTy> : Opcode {
+class ConstOpcode<Type Ty, ArgType ArgTy> : SuccessOpcode {
let Types = [SingletonTypeClass<Ty>];
let Args = [ArgTy];
let Name = "Const";
- let CanFail = 0;
}
// [] -> [Integer]
@@ -293,35 +296,29 @@ def ConstIntAPS : ConstOpcode<IntAPS, ArgIntAPS>;
def ConstBool : ConstOpcode<Bool, ArgBool>;
def ConstFixedPoint : ConstOpcode<FixedPoint, ArgFixedPoint>;
-def ConstFloat : Opcode {
+def ConstFloat : SuccessOpcode {
let Args = [ArgFloat];
- let CanFail = 0;
}
// [] -> [Integer]
-def Zero : Opcode {
+def Zero : SuccessOpcode {
let Types = [FixedSizeIntegralTypeClass];
let HasGroup = 1;
- let CanFail = 0;
-
}
-def ZeroIntAP : Opcode {
+def ZeroIntAP : SuccessOpcode {
let Args = [ArgUint32];
- let CanFail = 0;
}
-def ZeroIntAPS : Opcode {
+def ZeroIntAPS : SuccessOpcode {
let Args = [ArgUint32];
- let CanFail = 0;
}
// [] -> [Pointer]
-def Null : Opcode {
+def Null : SuccessOpcode {
let Types = [PtrTypeClass];
let Args = [ArgUint64, ArgTypePtr];
let HasGroup = 1;
- let CanFail = 0;
}
//===----------------------------------------------------------------------===//
@@ -334,6 +331,7 @@ class OffsetOpcode : Opcode {
// [] -> [Pointer]
def GetPtrLocal : OffsetOpcode {
bit HasCustomEval = 1;
+ let NeedsOpPC = 0;
}
def GetRefLocal : OffsetOpcode {
bit HasCustomEval = 1;
@@ -343,9 +341,13 @@ def GetRefGlobal : OffsetOpcode;
def CheckRefInit : Opcode {}
// [] -> [Pointer]
-def GetPtrParam : OffsetOpcode;
+def GetPtrParam : OffsetOpcode {
+ let NeedsOpPC = 0;
+}
// [] -> [Pointer]
-def GetPtrGlobal : OffsetOpcode;
+def GetPtrGlobal : OffsetOpcode {
+ let NeedsOpPC = 0;
+}
// [Pointer] -> [Pointer]
def GetPtrField : OffsetOpcode;
def GetPtrFieldPop : OffsetOpcode;
@@ -358,10 +360,12 @@ def GetPtrBasePop : OffsetOpcode { let Args = [ArgUint32, ArgBool]; }
def CastMemberPtrBasePop : Opcode {
// Offset of field, which is a base.
let Args = [ArgSint32, ArgRecordDecl];
+ let NeedsOpPC = 0;
}
def CastMemberPtrDerivedPop : Opcode {
// Offset of field, which is a base.
let Args = [ArgSint32, ArgRecordDecl];
+ let NeedsOpPC = 0;
}
def FinishInitPop : SuccessOpcode;
@@ -391,7 +395,9 @@ def GetPtrThisVirtBase : Opcode {
def This : Opcode;
// [] -> [Pointer]
-def RVOPtr : Opcode;
+def RVOPtr : Opcode {
+ let NeedsOpPC = 0;
+}
// [Pointer] -> [Pointer]
def NarrowPtr : SuccessOpcode;
@@ -445,16 +451,25 @@ class BitFieldOpcode : Opcode {
// [] -> [Pointer]
def GetLocal : AccessOpcode { let HasCustomEval = 1; }
// [] -> [Pointer]
-def SetLocal : AccessOpcode { let HasCustomEval = 1; }
+def SetLocal : AccessOpcode {
+ let HasCustomEval = 1;
+ let CanFail = 0;
+ let NeedsOpPC = 0;
+}
def EndLifetimePop : Opcode;
def EndLifetime : Opcode;
def MarkDestroyed : Opcode;
-def StartThisLifetime : Opcode;
-def StartThisLifetime1 : Opcode;
+def StartThisLifetime : Opcode {
+ let NeedsOpPC = 0;
+}
+def StartThisLifetime1 : Opcode {
+ let NeedsOpPC = 0;
+}
def CheckDecl : Opcode {
let Args = [ArgVarDecl];
+ let NeedsOpPC = 0;
}
def CheckEnumValue : Opcode {
@@ -477,22 +492,32 @@ def CheckBitCast : Opcode { let Args = [ArgTypePtr, ArgBool]; }
def GetGlobal : AccessOpcode;
def GetGlobalUnchecked : AccessOpcode;
// [Value] -> []
-def InitGlobal : AccessOpcode;
+def InitGlobal : AccessOpcode {
+ let CanFail = 0;
+ let NeedsOpPC = 0;
+}
// [Value] -> []
def InitGlobalTemp : AccessOpcode {
let Args = [ArgUint32, ArgLETD];
+ let NeedsOpPC = 0;
}
// [Pointer] -> [Pointer]
def InitGlobalTempComp : Opcode {
let Args = [ArgLETD];
+ let NeedsOpPC = 0;
}
// [Value] -> []
def SetGlobal : AccessOpcode;
// [] -> [Value]
-def GetParam : AccessOpcode;
+def GetParam : AccessOpcode {
+ let NeedsOpPC = 0;
+}
// [Value] -> []
-def SetParam : AccessOpcode;
+def SetParam : AccessOpcode {
+ let NeedsOpPC = 0;
+ let CanFail = 0;
+}
// [Pointer] -> [Pointer, Value]
def GetField : AccessOpcode;
@@ -551,8 +576,13 @@ def StoreBitFieldPop : StoreBitFieldOpcode {}
def StoreBitFieldActivate : StoreBitFieldOpcode {}
def StoreBitFieldActivatePop : StoreBitFieldOpcode {}
-def Activate : SuccessOpcode;
-def ActivateThisField : Opcode { let Args = [ArgUint32]; }
+def Activate : SuccessOpcode {
+ let NeedsOpPC = 0;
+}
+def ActivateThisField : Opcode {
+ let Args = [ArgUint32];
+ let NeedsOpPC = 0;
+}
// [Pointer, Value] -> []
def Init : StoreOpcode {}
@@ -600,9 +630,8 @@ def DecPtr : Opcode;
//===----------------------------------------------------------------------===//
// Function pointers.
//===----------------------------------------------------------------------===//
-def GetFnPtr : Opcode {
+def GetFnPtr : SuccessOpcode {
let Args = [ArgFunction];
- let CanFail = 0;
}
def GetIntPtr : Opcode {
@@ -625,6 +654,7 @@ def Mulf : FloatOpcode;
def Mulc : Opcode {
let Types = [NumberTypeClass];
let HasGroup = 1;
+ let NeedsOpPC = 0;
}
def Rem : IntegerOpcode;
def Div : IntegerOpcode;
@@ -634,9 +664,15 @@ def Divc : Opcode {
let HasGroup = 1;
}
-def BitAnd : IntegerOpcode;
-def BitOr : IntegerOpcode;
-def BitXor : IntegerOpcode;
+def BitAnd : IntegerOpcode {
+ let NeedsOpPC = 0;
+}
+def BitOr : IntegerOpcode {
+ let NeedsOpPC = 0;
+}
+def BitXor : IntegerOpcode {
+ let NeedsOpPC = 0;
+}
def Shl : Opcode {
let Types = [IntegerTypeClass, IntegerTypeClass];
@@ -653,7 +689,7 @@ def Shr : Opcode {
//===----------------------------------------------------------------------===//
// [Bool] -> [Bool]
-def Inv: Opcode;
+def Inv: SuccessOpcode;
// Increment and decrement.
class OverflowOpcode : Opcode {
@@ -698,11 +734,13 @@ def Neg: Opcode {
def Comp: Opcode {
let Types = [IntegerTypeClass];
let HasGroup = 1;
+ let NeedsOpPC = 0;
}
def IsNonNull : Opcode {
let Types = [PtrTypeClass];
let HasGroup = 1;
+ let NeedsOpPC = 0;
}
//===----------------------------------------------------------------------===//
@@ -724,6 +762,7 @@ def Cast: Opcode {
def CastFP : Opcode {
let Args = [ArgFltSemantics, ArgRoundingMode];
+ let NeedsOpPC = 0;
}
def CastFixedPoint : Opcode {
@@ -734,12 +773,14 @@ def CastAP : Opcode {
let Types = [AluTypeClass];
let Args = [ArgUint32];
let HasGroup = 1;
+ let NeedsOpPC = 0;
}
def CastAPS : Opcode {
let Types = [AluTypeClass];
let Args = [ArgUint32];
let HasGroup = 1;
+ let NeedsOpPC = 0;
}
def APOnlyTypeClass : TypeClass {
@@ -794,6 +835,7 @@ def CastFloatingFixedPoint : Opcode {
}
def CastFixedPointFloating : Opcode {
let Args = [ArgFltSemantics];
+ let NeedsOpPC = 0;
}
def CastFixedPointIntegral : Opcode {
let Types = [FixedSizeIntegralNoBoolTypeClass];
@@ -813,6 +855,7 @@ def FnPtrCast : Opcode;
def DecayPtr : Opcode {
let Types = [PtrTypeClass, PtrTypeClass];
let HasGroup = 1;
+ let NeedsOpPC = 0;
}
//===----------------------------------------------------------------------===//
@@ -846,30 +889,31 @@ def GE : ComparisonOpcode;
//===----------------------------------------------------------------------===//
// [Value] -> []
-def Pop : Opcode {
+def Pop : SuccessOpcode {
let Types = [AllTypeClass];
let HasGroup = 1;
- let CanFail = 0;
}
// [Value] -> [Value, Value]
-def Dup : Opcode {
+def Dup : SuccessOpcode {
let Types = [AllTypeClass];
let HasGroup = 1;
- let CanFail = 0;
}
-def Flip : Opcode {
+def Flip : SuccessOpcode {
let Types = [AllTypeClass, AllTypeClass];
let HasGroup = 1;
- let CanFail = 0;
}
// [] -> []
def Invalid : Opcode {}
def Unsupported : Opcode {}
-def Error : Opcode {}
-def SideEffect : Opcode {}
+def Error : Opcode {
+ let NeedsOpPC = 0;
+}
+def SideEffect : Opcode {
+ let NeedsOpPC = 0;
+}
def InvalidCast : Opcode {
let Args = [ArgCastKind, ArgBool];
}
@@ -878,7 +922,9 @@ def DynamicCast : Opcode {
}
def InvalidStore : Opcode { let Args = [ArgTypePtr]; }
-def CheckPseudoDtor : SuccessOpcode;
+def CheckPseudoDtor : SuccessOpcode {
+ let NeedsOpPC = 1;
+}
def InvalidDeclRef : Opcode {
let Args = [ArgDeclRef, ArgBool];
@@ -900,22 +946,28 @@ def CheckNonNullArg : Opcode {
def Memcpy : Opcode;
-def ToMemberPtr : Opcode;
+def ToMemberPtr : SuccessOpcode;
def CastMemberPtrPtr : Opcode;
-def GetMemberPtr : Opcode {
+def GetMemberPtr : SuccessOpcode {
let Args = [ArgValueDecl];
- let CanFail = 0;
}
-def GetMemberPtrBase : Opcode;
-def GetMemberPtrDecl : Opcode;
-def CopyMemberPtrPath : Opcode {
+def GetMemberPtrBase : Opcode {
+ let NeedsOpPC = 0;
+}
+def GetMemberPtrDecl : Opcode{
+ let NeedsOpPC = 0;
+}
+def CopyMemberPtrPath : SuccessOpcode {
let Args = [ArgRecordDecl, ArgBool];
+
}
//===----------------------------------------------------------------------===//
// Debugging.
//===----------------------------------------------------------------------===//
-def Dump : Opcode;
+def Dump : Opcode {
+ let NeedsOpPC = 0;
+}
def Alloc : Opcode {
let Args = [ArgDesc];
@@ -945,8 +997,10 @@ def CheckNewTypeMismatchArray : Opcode {
}
def InvalidNewDeleteExpr : Opcode { let Args = [ArgExpr]; }
-def IsConstantContext: Opcode;
-def CheckAllocations : Opcode;
+def IsConstantContext: SuccessOpcode;
+def CheckAllocations : Opcode {
+ let NeedsOpPC = 0;
+}
def CheckNull : Opcode;
def BitCastTypeClass : TypeClass {
@@ -962,17 +1016,20 @@ def BitCastPrim : Opcode {
def BitCast : Opcode;
-def GetTypeid : Opcode { let Args = [ArgTypePtr, ArgTypePtr]; }
+def GetTypeid : SuccessOpcode {
+ let Args = [ArgTypePtr, ArgTypePtr];
+}
def GetTypeidPtr : Opcode { let Args = [ArgTypePtr]; }
def DiagTypeid : Opcode;
def CheckDestruction : Opcode;
-def CtorCheck : Opcode;
+def CtorCheck : Opcode {
+ let NeedsOpPC = 0;
+}
-def PushCC : Opcode {
+def PushCC : SuccessOpcode {
let Args = [ArgBool];
- let CanFail = 0;
}
def PopCC : SuccessOpcode;
def PushMSVCCE : SuccessOpcode;
diff --git a/clang/utils/TableGen/ClangOpcodesEmitter.cpp b/clang/utils/TableGen/ClangOpcodesEmitter.cpp
index 13a99900bc9ec..4a3c901d2de7f 100644
--- a/clang/utils/TableGen/ClangOpcodesEmitter.cpp
+++ b/clang/utils/TableGen/ClangOpcodesEmitter.cpp
@@ -126,6 +126,7 @@ void ClangOpcodesEmitter::EmitInterpFnDispatchers(raw_ostream &OS, StringRef N,
bool CanReturn = R->getValueAsBit("CanReturn");
const auto &Args = R->getValueAsListOfDefs("Args");
bool CanFail = R->getValueAsBit("CanFail");
+ bool PassOpPC = R->getValueAsBit("NeedsOpPC");
if (Args.empty()) {
if (CanReturn) {
@@ -142,7 +143,11 @@ void ClangOpcodesEmitter::EmitInterpFnDispatchers(raw_ostream &OS, StringRef N,
OS << N;
PrintTypes(OS, TS);
- OS << "(S, S.PC)";
+ OS << "(S";
+ if (PassOpPC)
+ OS << ", S.PC)";
+ else
+ OS << ")";
if (CanFail)
OS << ") return false";
@@ -160,7 +165,8 @@ void ClangOpcodesEmitter::EmitInterpFnDispatchers(raw_ostream &OS, StringRef N,
OS << " {\n";
- OS << " CodePtr OpPC = S.PC;\n";
+ if (PassOpPC)
+ OS << " CodePtr OpPC = S.PC;\n";
// Emit calls to read arguments.
for (size_t I = 0, N = Args.size(); I < N; ++I) {
@@ -182,7 +188,8 @@ void ClangOpcodesEmitter::EmitInterpFnDispatchers(raw_ostream &OS, StringRef N,
OS << N;
PrintTypes(OS, TS);
OS << "(S";
- OS << ", OpPC";
+ if (PassOpPC)
+ OS << ", OpPC";
for (size_t I = 0, N = Args.size(); I < N; ++I)
OS << ", V" << I;
@@ -431,10 +438,13 @@ void ClangOpcodesEmitter::EmitEval(raw_ostream &OS, StringRef N,
if (N == "EndSpeculation") {
OS << "return EndSpeculation(S);\n";
} else {
+ bool PassOpPC = R->getValueAsBit("NeedsOpPC");
OS << " return " << N;
PrintTypes(OS, TS);
- OS << "(S, OpPC";
+ OS << "(S";
+ if (PassOpPC)
+ OS << ", OpPC";
for (size_t I = 0, N = Args.size(); I < N; ++I)
OS << ", A" << I;
OS << ");\n";
More information about the cfe-commits
mailing list