Timm =?utf-8?q?Bäder?= <[email protected]> Message-ID: In-Reply-To: <llvm.org/llvm/llvm-project/pull/[email protected]>
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/207479 >From ce81375b8b793624e39a629aef52c51dd7e05bcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]> Date: Fri, 3 Jul 2026 16:10:39 +0200 Subject: [PATCH 1/2] PassOpPC --- clang/lib/AST/ByteCode/EvalEmitter.cpp | 4 +- clang/lib/AST/ByteCode/Interp.cpp | 8 +-- clang/lib/AST/ByteCode/Interp.h | 55 ++++++++++---------- clang/lib/AST/ByteCode/Opcodes.td | 46 ++++++++-------- clang/utils/TableGen/ClangOpcodesEmitter.cpp | 18 +++++-- 5 files changed, 69 insertions(+), 62 deletions(-) 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 dc93cc4fd698c..6d9b8bc78668f 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -2891,7 +2891,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); @@ -3175,10 +3175,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..26cada1685186 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -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); @@ -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,7 +2151,7 @@ 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) { S.Stk.dump(); @@ -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()) @@ -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); @@ -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()); @@ -3654,7 +3653,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 +3665,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 +3676,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 +3705,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; diff --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td index 8123ca7497335..cf99c1f056527 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 { @@ -272,11 +274,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 +294,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; } //===----------------------------------------------------------------------===// @@ -551,8 +546,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 {} @@ -846,23 +846,20 @@ 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; } // [] -> [] @@ -878,7 +875,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]; @@ -970,9 +969,8 @@ def CheckDestruction : Opcode; def CtorCheck : Opcode; -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"; >From 27f46239114c0b336aa0dfd93952ff15020d3f10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]> Date: Sat, 4 Jul 2026 06:21:42 +0200 Subject: [PATCH 2/2] More opcodes --- clang/lib/AST/ByteCode/Interp.cpp | 19 +++-- clang/lib/AST/ByteCode/Interp.h | 99 ++++++++++++------------ clang/lib/AST/ByteCode/Opcodes.td | 123 ++++++++++++++++++++++-------- 3 files changed, 147 insertions(+), 94 deletions(-) diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 6d9b8bc78668f..22052dc12d0aa 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; } @@ -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>(); diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 26cada1685186..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; @@ -1617,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; } @@ -1640,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; } @@ -1766,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>(); @@ -1802,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; @@ -1821,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; @@ -2037,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; } @@ -2076,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; } @@ -2153,7 +2153,7 @@ inline bool FinishInitActivatePop(InterpState &S) { bool FinishInitGlobal(InterpState &S); -inline bool Dump(InterpState &S, CodePtr OpPC) { +inline bool Dump(InterpState &S) { S.Stk.dump(); return true; } @@ -2168,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; @@ -2188,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, @@ -2199,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); } //===----------------------------------------------------------------------===// @@ -2486,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>(); @@ -2768,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; @@ -2818,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); @@ -2845,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>()) { @@ -2864,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>()) { @@ -3067,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); @@ -3168,7 +3168,7 @@ inline bool Null(InterpState &S, 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; @@ -3207,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; @@ -3422,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; @@ -3596,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; @@ -3637,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. @@ -3728,17 +3727,15 @@ inline bool PopMSVCCE(InterpState &S) { } /// 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; @@ -3828,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; @@ -3853,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 @@ -3988,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(); } @@ -4101,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 cf99c1f056527..577c8523ab6c3 100644 --- a/clang/lib/AST/ByteCode/Opcodes.td +++ b/clang/lib/AST/ByteCode/Opcodes.td @@ -220,7 +220,9 @@ def RetValue : Opcode { let HasCustomEval = 1; } // [] -> EXIT -def NoRet : Opcode {} +def NoRet : Opcode { + let NeedsOpPC = 0; +} def Call : Opcode { @@ -256,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; } @@ -329,6 +331,7 @@ class OffsetOpcode : Opcode { // [] -> [Pointer] def GetPtrLocal : OffsetOpcode { bit HasCustomEval = 1; + let NeedsOpPC = 0; } def GetRefLocal : OffsetOpcode { bit HasCustomEval = 1; @@ -338,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; @@ -353,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; @@ -386,7 +395,9 @@ def GetPtrThisVirtBase : Opcode { def This : Opcode; // [] -> [Pointer] -def RVOPtr : Opcode; +def RVOPtr : Opcode { + let NeedsOpPC = 0; +} // [Pointer] -> [Pointer] def NarrowPtr : SuccessOpcode; @@ -440,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 { @@ -472,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; @@ -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; } //===----------------------------------------------------------------------===// @@ -865,8 +908,12 @@ def Flip : SuccessOpcode { // [] -> [] 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]; } @@ -899,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]; @@ -944,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 { @@ -961,13 +1016,17 @@ 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 : SuccessOpcode { let Args = [ArgBool]; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
