From: Devang Patel Date: Tue, 27 Oct 2009 22:16:29 +0000 (+0000) Subject: Factor out redundancy from clone() implementations. X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=50b6e33584f4e4cf75c7795b1f1a90731861c825;ds=sidebyside Factor out redundancy from clone() implementations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85327 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index e83acba82e8..df7eb43edf8 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -51,10 +51,9 @@ protected: virtual BasicBlock *getSuccessorV(unsigned idx) const = 0; virtual unsigned getNumSuccessorsV() const = 0; virtual void setSuccessorV(unsigned idx, BasicBlock *B) = 0; + virtual TerminatorInst *clone_impl() const = 0; public: - virtual TerminatorInst *clone() const = 0; - /// getNumSuccessors - Return the number of successors that this terminator /// has. unsigned getNumSuccessors() const { @@ -145,6 +144,7 @@ protected: const Twine &Name, Instruction *InsertBefore); BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd); + virtual BinaryOperator *clone_impl() const; public: // allocate space for exactly two operands void *operator new(size_t s) { @@ -297,8 +297,6 @@ public: return static_cast(Instruction::getOpcode()); } - virtual BinaryOperator *clone() const; - /// swapOperands - Exchange the two operands to this instruction. /// This instruction is safe to use on any binary instruction and /// does not modify the semantics of the instruction. If the instruction diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h index fdae3d7d744..07b3231aa14 100644 --- a/include/llvm/Instruction.h +++ b/include/llvm/Instruction.h @@ -38,6 +38,7 @@ protected: Instruction *InsertBefore = 0); Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd); + virtual Instruction *clone_impl() const = 0; public: // Out of line virtual method, so the vtable, etc has a home. ~Instruction(); @@ -47,7 +48,7 @@ public: /// * The instruction has no parent /// * The instruction has no name /// - virtual Instruction *clone() const = 0; + Instruction *clone() const; /// isIdenticalTo - Return true if the specified instruction is exactly /// identical to the current one. This means that all operands match and any diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 9a9d718b00f..ac194337357 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -38,6 +38,8 @@ class DominatorTree; /// AllocaInst - an instruction to allocate memory on the stack /// class AllocaInst : public UnaryInstruction { +protected: + virtual AllocaInst *clone_impl() const; public: explicit AllocaInst(const Type *Ty, Value *ArraySize = 0, const Twine &Name = "", Instruction *InsertBefore = 0); @@ -88,8 +90,6 @@ public: /// into the prolog/epilog code, so it is basically free. bool isStaticAlloca() const; - virtual AllocaInst *clone() const; - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const AllocaInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -110,6 +110,8 @@ public: /// class LoadInst : public UnaryInstruction { void AssertOK(); +protected: + virtual LoadInst *clone_impl() const; public: LoadInst(Value *Ptr, const Twine &NameStr, Instruction *InsertBefore); LoadInst(Value *Ptr, const Twine &NameStr, BasicBlock *InsertAtEnd); @@ -140,8 +142,6 @@ public: SubclassData = (SubclassData & ~1) | (V ? 1 : 0); } - virtual LoadInst *clone() const; - /// getAlignment - Return the alignment of the access that is being performed /// unsigned getAlignment() const { @@ -179,6 +179,8 @@ public: class StoreInst : public Instruction { void *operator new(size_t, unsigned); // DO NOT IMPLEMENT void AssertOK(); +protected: + virtual StoreInst *clone_impl() const; public: // allocate space for exactly two operands void *operator new(size_t s) { @@ -217,8 +219,6 @@ public: void setAlignment(unsigned Align); - virtual StoreInst *clone() const; - Value *getPointerOperand() { return getOperand(1); } const Value *getPointerOperand() const { return getOperand(1); } static unsigned getPointerOperandIndex() { return 1U; } @@ -327,6 +327,8 @@ class GetElementPtrInst : public Instruction { Instruction *InsertBefore = 0); GetElementPtrInst(Value *Ptr, Value *Idx, const Twine &NameStr, BasicBlock *InsertAtEnd); +protected: + virtual GetElementPtrInst *clone_impl() const; public: template static GetElementPtrInst *Create(Value *Ptr, InputIterator IdxBegin, @@ -400,8 +402,6 @@ public: return GEP; } - virtual GetElementPtrInst *clone() const; - /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -548,6 +548,9 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value) /// must be identical types. /// @brief Represent an integer comparison operator. class ICmpInst: public CmpInst { +protected: + /// @brief Clone an indentical ICmpInst + virtual ICmpInst *clone_impl() const; public: /// @brief Constructor with insert-before-instruction semantics. ICmpInst( @@ -676,8 +679,6 @@ public: Op<0>().swap(Op<1>()); } - virtual ICmpInst *clone() const; - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ICmpInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -698,6 +699,9 @@ public: /// vectors of floating point values. The operands must be identical types. /// @brief Represents a floating point comparison operator. class FCmpInst: public CmpInst { +protected: + /// @brief Clone an indentical FCmpInst + virtual FCmpInst *clone_impl() const; public: /// @brief Constructor with insert-before-instruction semantics. FCmpInst( @@ -785,8 +789,6 @@ public: Op<0>().swap(Op<1>()); } - virtual FCmpInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const FCmpInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -854,6 +856,8 @@ class CallInst : public Instruction { explicit CallInst(Value *F, const Twine &NameStr, Instruction *InsertBefore); CallInst(Value *F, const Twine &NameStr, BasicBlock *InsertAtEnd); +protected: + virtual CallInst *clone_impl() const; public: template static CallInst *Create(Value *Func, @@ -912,8 +916,6 @@ public: SubclassData = (SubclassData & ~1) | unsigned(isTC); } - virtual CallInst *clone() const; - /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -1081,6 +1083,8 @@ class SelectInst : public Instruction { init(C, S1, S2); setName(NameStr); } +protected: + virtual SelectInst *clone_impl() const; public: static SelectInst *Create(Value *C, Value *S1, Value *S2, const Twine &NameStr = "", @@ -1111,8 +1115,6 @@ public: return static_cast(Instruction::getOpcode()); } - virtual SelectInst *clone() const; - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const SelectInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -1137,6 +1139,9 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectInst, Value) /// an argument of the specified type given a va_list and increments that list /// class VAArgInst : public UnaryInstruction { +protected: + virtual VAArgInst *clone_impl() const; + public: VAArgInst(Value *List, const Type *Ty, const Twine &NameStr = "", Instruction *InsertBefore = 0) @@ -1149,8 +1154,6 @@ public: setName(NameStr); } - virtual VAArgInst *clone() const; - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const VAArgInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -1173,6 +1176,9 @@ class ExtractElementInst : public Instruction { Instruction *InsertBefore = 0); ExtractElementInst(Value *Vec, Value *Idx, const Twine &NameStr, BasicBlock *InsertAtEnd); +protected: + virtual ExtractElementInst *clone_impl() const; + public: static ExtractElementInst *Create(Value *Vec, Value *Idx, const Twine &NameStr = "", @@ -1189,8 +1195,6 @@ public: /// formed with the specified operands. static bool isValidOperands(const Value *Vec, const Value *Idx); - virtual ExtractElementInst *clone() const; - Value *getVectorOperand() { return Op<0>(); } Value *getIndexOperand() { return Op<1>(); } const Value *getVectorOperand() const { return Op<0>(); } @@ -1233,6 +1237,9 @@ class InsertElementInst : public Instruction { Instruction *InsertBefore = 0); InsertElementInst(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr, BasicBlock *InsertAtEnd); +protected: + virtual InsertElementInst *clone_impl() const; + public: static InsertElementInst *Create(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr = "", @@ -1250,8 +1257,6 @@ public: static bool isValidOperands(const Value *Vec, const Value *NewElt, const Value *Idx); - virtual InsertElementInst *clone() const; - /// getType - Overload to return most specific vector type. /// const VectorType *getType() const { @@ -1285,6 +1290,9 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementInst, Value) /// input vectors. /// class ShuffleVectorInst : public Instruction { +protected: + virtual ShuffleVectorInst *clone_impl() const; + public: // allocate space for exactly three operands void *operator new(size_t s) { @@ -1301,8 +1309,6 @@ public: static bool isValidOperands(const Value *V1, const Value *V2, const Value *Mask); - virtual ShuffleVectorInst *clone() const; - /// getType - Overload to return most specific vector type. /// const VectorType *getType() const { @@ -1411,6 +1417,8 @@ class ExtractValueInst : public UnaryInstruction { void *operator new(size_t s) { return User::operator new(s, 1); } +protected: + virtual ExtractValueInst *clone_impl() const; public: template @@ -1445,8 +1453,6 @@ public: return new ExtractValueInst(Agg, Idxs, Idxs + 1, NameStr, InsertAtEnd); } - virtual ExtractValueInst *clone() const; - /// getIndexedType - Returns the type of the element that would be extracted /// with an extractvalue instruction with the specified parameters. /// @@ -1578,6 +1584,8 @@ class InsertValueInst : public Instruction { Instruction *InsertBefore = 0); InsertValueInst(Value *Agg, Value *Val, unsigned Idx, const Twine &NameStr, BasicBlock *InsertAtEnd); +protected: + virtual InsertValueInst *clone_impl() const; public: // allocate space for exactly two operands void *operator new(size_t s) { @@ -1615,8 +1623,6 @@ public: return new InsertValueInst(Agg, Val, Idx, NameStr, InsertAtEnd); } - virtual InsertValueInst *clone() const; - /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -1725,6 +1731,8 @@ class PHINode : public Instruction { ReservedSpace(0) { setName(NameStr); } +protected: + virtual PHINode *clone_impl() const; public: static PHINode *Create(const Type *Ty, const Twine &NameStr = "", Instruction *InsertBefore = 0) { @@ -1744,8 +1752,6 @@ public: resizeOperands(NumValues*2); } - virtual PHINode *clone() const; - /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -1907,6 +1913,8 @@ private: Instruction *InsertBefore = 0); ReturnInst(LLVMContext &C, Value *retVal, BasicBlock *InsertAtEnd); explicit ReturnInst(LLVMContext &C, BasicBlock *InsertAtEnd); +protected: + virtual ReturnInst *clone_impl() const; public: static ReturnInst* Create(LLVMContext &C, Value *retVal = 0, Instruction *InsertBefore = 0) { @@ -1921,8 +1929,6 @@ public: } virtual ~ReturnInst(); - virtual ReturnInst *clone() const; - /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -1982,6 +1988,8 @@ class BranchInst : public TerminatorInst { BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd); BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, BasicBlock *InsertAtEnd); +protected: + virtual BranchInst *clone_impl() const; public: static BranchInst *Create(BasicBlock *IfTrue, Instruction *InsertBefore = 0) { return new(1, true) BranchInst(IfTrue, InsertBefore); @@ -2003,8 +2011,6 @@ public: /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - virtual BranchInst *clone() const; - bool isUnconditional() const { return getNumOperands() == 1; } bool isConditional() const { return getNumOperands() == 3; } @@ -2096,6 +2102,8 @@ class SwitchInst : public TerminatorInst { /// constructor also autoinserts at the end of the specified BasicBlock. SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, BasicBlock *InsertAtEnd); +protected: + virtual SwitchInst *clone_impl() const; public: static SwitchInst *Create(Value *Value, BasicBlock *Default, unsigned NumCases, Instruction *InsertBefore = 0) { @@ -2173,8 +2181,6 @@ public: /// void removeCase(unsigned idx); - virtual SwitchInst *clone() const; - unsigned getNumSuccessors() const { return getNumOperands()/2; } BasicBlock *getSuccessor(unsigned idx) const { assert(idx < getNumSuccessors() &&"Successor idx out of range for switch!"); @@ -2245,6 +2251,8 @@ class IndBrInst : public TerminatorInst { /// make memory allocation more efficient. This constructor also autoinserts /// at the end of the specified BasicBlock. IndBrInst(Value *Address, unsigned NumDests, BasicBlock *InsertAtEnd); +protected: + virtual IndBrInst *clone_impl() const; public: static IndBrInst *Create(Value *Address, unsigned NumDests, Instruction *InsertBefore = 0) { @@ -2281,8 +2289,6 @@ public: /// indbr instruction. void removeDestination(unsigned i); - virtual IndBrInst *clone() const; - unsigned getNumSuccessors() const { return getNumOperands()-1; } BasicBlock *getSuccessor(unsigned i) const { return cast(getOperand(i+1)); @@ -2364,6 +2370,8 @@ class InvokeInst : public TerminatorInst { InputIterator ArgBegin, InputIterator ArgEnd, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd); +protected: + virtual InvokeInst *clone_impl() const; public: template static InvokeInst *Create(Value *Func, @@ -2386,8 +2394,6 @@ public: Values, NameStr, InsertAtEnd); } - virtual InvokeInst *clone() const; - /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -2568,6 +2574,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InvokeInst, Value) /// class UnwindInst : public TerminatorInst { void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +protected: + virtual UnwindInst *clone_impl() const; public: // allocate space for exactly zero operands void *operator new(size_t s) { @@ -2576,8 +2584,6 @@ public: explicit UnwindInst(LLVMContext &C, Instruction *InsertBefore = 0); explicit UnwindInst(LLVMContext &C, BasicBlock *InsertAtEnd); - virtual UnwindInst *clone() const; - unsigned getNumSuccessors() const { return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -2605,6 +2611,9 @@ private: /// class UnreachableInst : public TerminatorInst { void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +protected: + virtual UnreachableInst *clone_impl() const; + public: // allocate space for exactly zero operands void *operator new(size_t s) { @@ -2613,8 +2622,6 @@ public: explicit UnreachableInst(LLVMContext &C, Instruction *InsertBefore = 0); explicit UnreachableInst(LLVMContext &C, BasicBlock *InsertAtEnd); - virtual UnreachableInst *clone() const; - unsigned getNumSuccessors() const { return 0; } // Methods for support type inquiry through isa, cast, and dyn_cast: @@ -2637,6 +2644,10 @@ private: /// @brief This class represents a truncation of integer types. class TruncInst : public CastInst { +protected: + /// @brief Clone an identical TruncInst + virtual TruncInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics TruncInst( @@ -2654,9 +2665,6 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical TruncInst - virtual TruncInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const TruncInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2673,6 +2681,10 @@ public: /// @brief This class represents zero extension of integer types. class ZExtInst : public CastInst { +protected: + /// @brief Clone an identical ZExtInst + virtual ZExtInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics ZExtInst( @@ -2690,9 +2702,6 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical ZExtInst - virtual ZExtInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ZExtInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2709,6 +2718,10 @@ public: /// @brief This class represents a sign extension of integer types. class SExtInst : public CastInst { +protected: + /// @brief Clone an identical SExtInst + virtual SExtInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics SExtInst( @@ -2726,9 +2739,6 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical SExtInst - virtual SExtInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const SExtInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2745,6 +2755,10 @@ public: /// @brief This class represents a truncation of floating point types. class FPTruncInst : public CastInst { +protected: + /// @brief Clone an identical FPTruncInst + virtual FPTruncInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics FPTruncInst( @@ -2762,9 +2776,6 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical FPTruncInst - virtual FPTruncInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const FPTruncInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2781,6 +2792,10 @@ public: /// @brief This class represents an extension of floating point types. class FPExtInst : public CastInst { +protected: + /// @brief Clone an identical FPExtInst + virtual FPExtInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics FPExtInst( @@ -2798,9 +2813,6 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical FPExtInst - virtual FPExtInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const FPExtInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2817,6 +2829,10 @@ public: /// @brief This class represents a cast unsigned integer to floating point. class UIToFPInst : public CastInst { +protected: + /// @brief Clone an identical UIToFPInst + virtual UIToFPInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics UIToFPInst( @@ -2834,9 +2850,6 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical UIToFPInst - virtual UIToFPInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const UIToFPInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2853,6 +2866,10 @@ public: /// @brief This class represents a cast from signed integer to floating point. class SIToFPInst : public CastInst { +protected: + /// @brief Clone an identical SIToFPInst + virtual SIToFPInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics SIToFPInst( @@ -2870,9 +2887,6 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical SIToFPInst - virtual SIToFPInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const SIToFPInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2889,6 +2903,10 @@ public: /// @brief This class represents a cast from floating point to unsigned integer class FPToUIInst : public CastInst { +protected: + /// @brief Clone an identical FPToUIInst + virtual FPToUIInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics FPToUIInst( @@ -2906,9 +2924,6 @@ public: BasicBlock *InsertAtEnd ///< Where to insert the new instruction ); - /// @brief Clone an identical FPToUIInst - virtual FPToUIInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const FPToUIInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2925,6 +2940,10 @@ public: /// @brief This class represents a cast from floating point to signed integer. class FPToSIInst : public CastInst { +protected: + /// @brief Clone an identical FPToSIInst + virtual FPToSIInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics FPToSIInst( @@ -2942,9 +2961,6 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical FPToSIInst - virtual FPToSIInst *clone() const; - /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const FPToSIInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2979,7 +2995,7 @@ public: ); /// @brief Clone an identical IntToPtrInst - virtual IntToPtrInst *clone() const; + virtual IntToPtrInst *clone_impl() const; // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const IntToPtrInst *) { return true; } @@ -2997,6 +3013,10 @@ public: /// @brief This class represents a cast from a pointer to an integer class PtrToIntInst : public CastInst { +protected: + /// @brief Clone an identical PtrToIntInst + virtual PtrToIntInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics PtrToIntInst( @@ -3014,9 +3034,6 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical PtrToIntInst - virtual PtrToIntInst *clone() const; - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const PtrToIntInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -3033,6 +3050,10 @@ public: /// @brief This class represents a no-op cast from one type to another. class BitCastInst : public CastInst { +protected: + /// @brief Clone an identical BitCastInst + virtual BitCastInst *clone_impl() const; + public: /// @brief Constructor with insert-before-instruction semantics BitCastInst( @@ -3050,9 +3071,6 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Clone an identical BitCastInst - virtual BitCastInst *clone() const; - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const BitCastInst *) { return true; } static inline bool classof(const Instruction *I) { diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp index e2d9e0b9ec4..931759a86a0 100644 --- a/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -292,7 +292,7 @@ void IndVarSimplify::RewriteLoopExitValues(Loop *L, if (NumPreds != 1) { // Clone the PHI and delete the original one. This lets IVUsers and // any other maps purge the original user from their records. - PHINode *NewPN = PN->clone(); + PHINode *NewPN = cast(PN->clone()); NewPN->takeName(PN); NewPN->insertBefore(PN); PN->replaceAllUsesWith(NewPN); diff --git a/lib/Transforms/Utils/BasicBlockUtils.cpp b/lib/Transforms/Utils/BasicBlockUtils.cpp index 35907fdcc1a..c2c662fb14d 100644 --- a/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -675,7 +675,7 @@ void llvm::CopyPrecedingStopPoint(Instruction *I, if (I != I->getParent()->begin()) { BasicBlock::iterator BBI = I; --BBI; if (DbgStopPointInst *DSPI = dyn_cast(BBI)) { - CallInst *newDSPI = DSPI->clone(); + CallInst *newDSPI = cast(DSPI->clone()); newDSPI->insertBefore(InsertPos); } } diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index 4dbb4020ded..c48e75c4453 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -492,3 +492,11 @@ bool Instruction::isSafeToSpeculativelyExecute() const { return false; // Misc instructions which have effects } } + +Instruction *Instruction::clone() const { + Instruction *New = clone_impl(); + New->SubclassOptionalData = SubclassOptionalData; + if (hasMetadata()) + getContext().pImpl->TheMetadata.ValueIsCloned(this, New); + return New; +} diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 61b8044ead3..5a6d3764d5e 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -3195,366 +3195,161 @@ void IndBrInst::setSuccessorV(unsigned idx, BasicBlock *B) { } //===----------------------------------------------------------------------===// -// clone() implementations +// clone_impl() implementations //===----------------------------------------------------------------------===// // Define these methods here so vtables don't get emitted into every translation // unit that uses these classes. -GetElementPtrInst *GetElementPtrInst::clone() const { - GetElementPtrInst *New = new(getNumOperands()) GetElementPtrInst(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +GetElementPtrInst *GetElementPtrInst::clone_impl() const { + return new (getNumOperands()) GetElementPtrInst(*this); } -BinaryOperator *BinaryOperator::clone() const { - BinaryOperator *New = Create(getOpcode(), Op<0>(), Op<1>()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +BinaryOperator *BinaryOperator::clone_impl() const { + return Create(getOpcode(), Op<0>(), Op<1>()); } -FCmpInst* FCmpInst::clone() const { - FCmpInst *New = new FCmpInst(getPredicate(), Op<0>(), Op<1>()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} -ICmpInst* ICmpInst::clone() const { - ICmpInst *New = new ICmpInst(getPredicate(), Op<0>(), Op<1>()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +FCmpInst* FCmpInst::clone_impl() const { + return new FCmpInst(getPredicate(), Op<0>(), Op<1>()); } -ExtractValueInst *ExtractValueInst::clone() const { - ExtractValueInst *New = new ExtractValueInst(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; -} -InsertValueInst *InsertValueInst::clone() const { - InsertValueInst *New = new InsertValueInst(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +ICmpInst* ICmpInst::clone_impl() const { + return new ICmpInst(getPredicate(), Op<0>(), Op<1>()); } -AllocaInst *AllocaInst::clone() const { - AllocaInst *New = new AllocaInst(getAllocatedType(), - (Value*)getOperand(0), - getAlignment()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +ExtractValueInst *ExtractValueInst::clone_impl() const { + return new ExtractValueInst(*this); } -LoadInst *LoadInst::clone() const { - LoadInst *New = new LoadInst(getOperand(0), - Twine(), isVolatile(), - getAlignment()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +InsertValueInst *InsertValueInst::clone_impl() const { + return new InsertValueInst(*this); } -StoreInst *StoreInst::clone() const { - StoreInst *New = new StoreInst(getOperand(0), getOperand(1), - isVolatile(), getAlignment()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +AllocaInst *AllocaInst::clone_impl() const { + return new AllocaInst(getAllocatedType(), + (Value*)getOperand(0), + getAlignment()); } -TruncInst *TruncInst::clone() const { - TruncInst *New = new TruncInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +LoadInst *LoadInst::clone_impl() const { + return new LoadInst(getOperand(0), + Twine(), isVolatile(), + getAlignment()); } -ZExtInst *ZExtInst::clone() const { - ZExtInst *New = new ZExtInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +StoreInst *StoreInst::clone_impl() const { + return new StoreInst(getOperand(0), getOperand(1), + isVolatile(), getAlignment()); } -SExtInst *SExtInst::clone() const { - SExtInst *New = new SExtInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +TruncInst *TruncInst::clone_impl() const { + return new TruncInst(getOperand(0), getType()); } -FPTruncInst *FPTruncInst::clone() const { - FPTruncInst *New = new FPTruncInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +ZExtInst *ZExtInst::clone_impl() const { + return new ZExtInst(getOperand(0), getType()); } -FPExtInst *FPExtInst::clone() const { - FPExtInst *New = new FPExtInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +SExtInst *SExtInst::clone_impl() const { + return new SExtInst(getOperand(0), getType()); } -UIToFPInst *UIToFPInst::clone() const { - UIToFPInst *New = new UIToFPInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +FPTruncInst *FPTruncInst::clone_impl() const { + return new FPTruncInst(getOperand(0), getType()); } -SIToFPInst *SIToFPInst::clone() const { - SIToFPInst *New = new SIToFPInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +FPExtInst *FPExtInst::clone_impl() const { + return new FPExtInst(getOperand(0), getType()); } -FPToUIInst *FPToUIInst::clone() const { - FPToUIInst *New = new FPToUIInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +UIToFPInst *UIToFPInst::clone_impl() const { + return new UIToFPInst(getOperand(0), getType()); } -FPToSIInst *FPToSIInst::clone() const { - FPToSIInst *New = new FPToSIInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +SIToFPInst *SIToFPInst::clone_impl() const { + return new SIToFPInst(getOperand(0), getType()); } -PtrToIntInst *PtrToIntInst::clone() const { - PtrToIntInst *New = new PtrToIntInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +FPToUIInst *FPToUIInst::clone_impl() const { + return new FPToUIInst(getOperand(0), getType()); } -IntToPtrInst *IntToPtrInst::clone() const { - IntToPtrInst *New = new IntToPtrInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +FPToSIInst *FPToSIInst::clone_impl() const { + return new FPToSIInst(getOperand(0), getType()); } -BitCastInst *BitCastInst::clone() const { - BitCastInst *New = new BitCastInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +PtrToIntInst *PtrToIntInst::clone_impl() const { + return new PtrToIntInst(getOperand(0), getType()); } -CallInst *CallInst::clone() const { - CallInst *New = new(getNumOperands()) CallInst(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +IntToPtrInst *IntToPtrInst::clone_impl() const { + return new IntToPtrInst(getOperand(0), getType()); } -SelectInst *SelectInst::clone() const { - SelectInst *New = SelectInst::Create(getOperand(0), - getOperand(1), - getOperand(2)); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +BitCastInst *BitCastInst::clone_impl() const { + return new BitCastInst(getOperand(0), getType()); } -VAArgInst *VAArgInst::clone() const { - VAArgInst *New = new VAArgInst(getOperand(0), getType()); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +CallInst *CallInst::clone_impl() const { + return new(getNumOperands()) CallInst(*this); } -ExtractElementInst *ExtractElementInst::clone() const { - ExtractElementInst *New = ExtractElementInst::Create(getOperand(0), - getOperand(1)); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +SelectInst *SelectInst::clone_impl() const { + return SelectInst::Create(getOperand(0), getOperand(1), getOperand(2)); } -InsertElementInst *InsertElementInst::clone() const { - InsertElementInst *New = InsertElementInst::Create(getOperand(0), - getOperand(1), - getOperand(2)); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +VAArgInst *VAArgInst::clone_impl() const { + return new VAArgInst(getOperand(0), getType()); } -ShuffleVectorInst *ShuffleVectorInst::clone() const { - ShuffleVectorInst *New = new ShuffleVectorInst(getOperand(0), - getOperand(1), - getOperand(2)); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +ExtractElementInst *ExtractElementInst::clone_impl() const { + return ExtractElementInst::Create(getOperand(0), getOperand(1)); } -PHINode *PHINode::clone() const { - PHINode *New = new PHINode(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +InsertElementInst *InsertElementInst::clone_impl() const { + return InsertElementInst::Create(getOperand(0), + getOperand(1), + getOperand(2)); } -ReturnInst *ReturnInst::clone() const { - ReturnInst *New = new(getNumOperands()) ReturnInst(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +ShuffleVectorInst *ShuffleVectorInst::clone_impl() const { + return new ShuffleVectorInst(getOperand(0), + getOperand(1), + getOperand(2)); } -BranchInst *BranchInst::clone() const { +PHINode *PHINode::clone_impl() const { + return new PHINode(*this); +} + +ReturnInst *ReturnInst::clone_impl() const { + return new(getNumOperands()) ReturnInst(*this); +} + +BranchInst *BranchInst::clone_impl() const { unsigned Ops(getNumOperands()); - BranchInst *New = new(Ops, Ops == 1) BranchInst(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; + return new(Ops, Ops == 1) BranchInst(*this); } -SwitchInst *SwitchInst::clone() const { - SwitchInst *New = new SwitchInst(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +SwitchInst *SwitchInst::clone_impl() const { + return new SwitchInst(*this); } -IndBrInst *IndBrInst::clone() const { - IndBrInst *New = new IndBrInst(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) - getContext().pImpl->TheMetadata.ValueIsCloned(this, New); - return New; +IndBrInst *IndBrInst::clone_impl() const { + return new IndBrInst(*this); } -InvokeInst *InvokeInst::clone() const { - InvokeInst *New = new(getNumOperands()) InvokeInst(*this); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) { - LLVMContext &Context = getContext(); - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - } - return New; +InvokeInst *InvokeInst::clone_impl() const { + return new(getNumOperands()) InvokeInst(*this); } -UnwindInst *UnwindInst::clone() const { +UnwindInst *UnwindInst::clone_impl() const { LLVMContext &Context = getContext(); - UnwindInst *New = new UnwindInst(Context); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - return New; + return new UnwindInst(Context); } -UnreachableInst *UnreachableInst::clone() const { +UnreachableInst *UnreachableInst::clone_impl() const { LLVMContext &Context = getContext(); - UnreachableInst *New = new UnreachableInst(Context); - New->SubclassOptionalData = SubclassOptionalData; - if (hasMetadata()) - Context.pImpl->TheMetadata.ValueIsCloned(this, New); - return New; + return new UnreachableInst(Context); } diff --git a/unittests/Transforms/Utils/Cloning.cpp b/unittests/Transforms/Utils/Cloning.cpp index 3aa796c750a..17047e7ca15 100644 --- a/unittests/Transforms/Utils/Cloning.cpp +++ b/unittests/Transforms/Utils/Cloning.cpp @@ -22,45 +22,45 @@ TEST(CloneInstruction, OverflowBits) { BinaryOperator *Sub = BinaryOperator::Create(Instruction::Sub, V, V); BinaryOperator *Mul = BinaryOperator::Create(Instruction::Mul, V, V); - EXPECT_FALSE(Add->clone()->hasNoUnsignedWrap()); - EXPECT_FALSE(Add->clone()->hasNoSignedWrap()); - EXPECT_FALSE(Sub->clone()->hasNoUnsignedWrap()); - EXPECT_FALSE(Sub->clone()->hasNoSignedWrap()); - EXPECT_FALSE(Mul->clone()->hasNoUnsignedWrap()); - EXPECT_FALSE(Mul->clone()->hasNoSignedWrap()); + EXPECT_FALSE(cast(Add->clone())->hasNoUnsignedWrap()); + EXPECT_FALSE(cast(Add->clone())->hasNoSignedWrap()); + EXPECT_FALSE(cast(Sub->clone())->hasNoUnsignedWrap()); + EXPECT_FALSE(cast(Sub->clone())->hasNoSignedWrap()); + EXPECT_FALSE(cast(Mul->clone())->hasNoUnsignedWrap()); + EXPECT_FALSE(cast(Mul->clone())->hasNoSignedWrap()); Add->setHasNoUnsignedWrap(); Sub->setHasNoUnsignedWrap(); Mul->setHasNoUnsignedWrap(); - EXPECT_TRUE(Add->clone()->hasNoUnsignedWrap()); - EXPECT_FALSE(Add->clone()->hasNoSignedWrap()); - EXPECT_TRUE(Sub->clone()->hasNoUnsignedWrap()); - EXPECT_FALSE(Sub->clone()->hasNoSignedWrap()); - EXPECT_TRUE(Mul->clone()->hasNoUnsignedWrap()); - EXPECT_FALSE(Mul->clone()->hasNoSignedWrap()); + EXPECT_TRUE(cast(Add->clone())->hasNoUnsignedWrap()); + EXPECT_FALSE(cast(Add->clone())->hasNoSignedWrap()); + EXPECT_TRUE(cast(Sub->clone())->hasNoUnsignedWrap()); + EXPECT_FALSE(cast(Sub->clone())->hasNoSignedWrap()); + EXPECT_TRUE(cast(Mul->clone())->hasNoUnsignedWrap()); + EXPECT_FALSE(cast(Mul->clone())->hasNoSignedWrap()); Add->setHasNoSignedWrap(); Sub->setHasNoSignedWrap(); Mul->setHasNoSignedWrap(); - EXPECT_TRUE(Add->clone()->hasNoUnsignedWrap()); - EXPECT_TRUE(Add->clone()->hasNoSignedWrap()); - EXPECT_TRUE(Sub->clone()->hasNoUnsignedWrap()); - EXPECT_TRUE(Sub->clone()->hasNoSignedWrap()); - EXPECT_TRUE(Mul->clone()->hasNoUnsignedWrap()); - EXPECT_TRUE(Mul->clone()->hasNoSignedWrap()); + EXPECT_TRUE(cast(Add->clone())->hasNoUnsignedWrap()); + EXPECT_TRUE(cast(Add->clone())->hasNoSignedWrap()); + EXPECT_TRUE(cast(Sub->clone())->hasNoUnsignedWrap()); + EXPECT_TRUE(cast(Sub->clone())->hasNoSignedWrap()); + EXPECT_TRUE(cast(Mul->clone())->hasNoUnsignedWrap()); + EXPECT_TRUE(cast(Mul->clone())->hasNoSignedWrap()); Add->setHasNoUnsignedWrap(false); Sub->setHasNoUnsignedWrap(false); Mul->setHasNoUnsignedWrap(false); - EXPECT_FALSE(Add->clone()->hasNoUnsignedWrap()); - EXPECT_TRUE(Add->clone()->hasNoSignedWrap()); - EXPECT_FALSE(Sub->clone()->hasNoUnsignedWrap()); - EXPECT_TRUE(Sub->clone()->hasNoSignedWrap()); - EXPECT_FALSE(Mul->clone()->hasNoUnsignedWrap()); - EXPECT_TRUE(Mul->clone()->hasNoSignedWrap()); + EXPECT_FALSE(cast(Add->clone())->hasNoUnsignedWrap()); + EXPECT_TRUE(cast(Add->clone())->hasNoSignedWrap()); + EXPECT_FALSE(cast(Sub->clone())->hasNoUnsignedWrap()); + EXPECT_TRUE(cast(Sub->clone())->hasNoSignedWrap()); + EXPECT_FALSE(cast(Mul->clone())->hasNoUnsignedWrap()); + EXPECT_TRUE(cast(Mul->clone())->hasNoSignedWrap()); } TEST(CloneInstruction, Inbounds) { @@ -70,10 +70,10 @@ TEST(CloneInstruction, Inbounds) { std::vector ops; ops.push_back(Z); GetElementPtrInst *GEP = GetElementPtrInst::Create(V, ops.begin(), ops.end()); - EXPECT_FALSE(GEP->clone()->isInBounds()); + EXPECT_FALSE(cast(GEP->clone())->isInBounds()); GEP->setIsInBounds(); - EXPECT_TRUE(GEP->clone()->isInBounds()); + EXPECT_TRUE(cast(GEP->clone())->isInBounds()); } TEST(CloneInstruction, Exact) { @@ -81,8 +81,8 @@ TEST(CloneInstruction, Exact) { Value *V = new Argument(Type::getInt32Ty(context)); BinaryOperator *SDiv = BinaryOperator::Create(Instruction::SDiv, V, V); - EXPECT_FALSE(SDiv->clone()->isExact()); + EXPECT_FALSE(cast(SDiv->clone())->isExact()); SDiv->setIsExact(true); - EXPECT_TRUE(SDiv->clone()->isExact()); + EXPECT_TRUE(cast(SDiv->clone())->isExact()); }