diff --git a/include/llvm/BasicBlock.h b/include/llvm/BasicBlock.h index 11c76a36472..08516c8ca83 100644 --- a/include/llvm/BasicBlock.h +++ b/include/llvm/BasicBlock.h @@ -163,7 +163,7 @@ public: // TODO: This is bad // Loop to ignore constant pool references while (It != BB->use_end() && - ((!(*It)->isInstruction()) || + ((!isa(*It)) || !(((Instruction*)(*It))->isTerminator()))) ++It; } @@ -177,7 +177,7 @@ public: inline bool operator!=(const _Self& x) const { return !operator==(x); } inline pointer operator*() const { - return (*It)->castInstructionAsserting()->getParent(); + return cast(*It)->getParent(); } inline pointer *operator->() const { return &(operator*()); } diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h index 3bbb8e7031e..93b68a2c628 100644 --- a/include/llvm/Instruction.h +++ b/include/llvm/Instruction.h @@ -85,6 +85,13 @@ public: // and then drops all references to its operands. // void dropAllReferences(); + + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool isa(const Instruction *I) { return true; } + static inline bool isa(const Value *V) { + return V->getValueType() == Value::InstructionVal; + } //---------------------------------------------------------------------- // Exported enumerations... diff --git a/include/llvm/Type.h b/include/llvm/Type.h index 5854062df0c..2a43153acd0 100644 --- a/include/llvm/Type.h +++ b/include/llvm/Type.h @@ -195,6 +195,12 @@ public: return (const DerivedType*)this; } + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool isa(const Type *T) { return true; } + static inline bool isa(const Value *V) { + return V->getValueType() == Value::TypeVal; + } + // Methods for determining the subtype of this Type. The cast*() methods are // equilivent to using dynamic_cast<>... if the cast is successful, this is // returned, otherwise you get a null pointer, allowing expressions like this: diff --git a/include/llvm/Value.h b/include/llvm/Value.h index 7d214e2ab49..14794dc4c92 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -3,6 +3,10 @@ // This file defines the very important Value class. This is subclassed by a // bunch of other important classes, like Def, Method, Module, Type, etc... // +// This file also defines the Use<> template for users of value. +// +// This file also defines the isa(), cast(), and dyn_cast() templates. +// //===----------------------------------------------------------------------===// #ifndef LLVM_VALUE_H @@ -156,6 +160,11 @@ public: void killUse(User *I); }; + +//===----------------------------------------------------------------------===// +// UseTy Class +//===----------------------------------------------------------------------===// + // UseTy and it's friendly typedefs (Use) are here to make keeping the "use" // list of a definition node up-to-date really easy. // @@ -196,6 +205,46 @@ public: } }; -typedef UseTy Use; +typedef UseTy Use; // Provide Use as a common UseTy type + + +//===----------------------------------------------------------------------===// +// Type Checking Templates +//===----------------------------------------------------------------------===// + +// isa - Return true if the parameter to the template is an instance of the +// template type argument. Used like this: +// +// if (isa(myVal)) { ... } +// +template +bool isa(Y *Val) { return X::isa(Val); } + + +// cast - Return the argument parameter cast to the specified type. This +// casting operator asserts that the type is correct, so it does not return null +// on failure. Used Like this: +// +// cast< Instruction>(myVal)->getParent() +// cast(myVal)->getParent() +// +template +X *cast(Y *Val) { + assert(isa(Val) && "Invalid cast argument type!"); + return (X*)Val; +} + + +// dyn_cast - Return the argument parameter cast to the specified type. This +// casting operator returns null if the argument is of the wrong type, so it can +// be used to test for a type as well as cast if successful. This should be +// used in the context of an if statement like this: +// +// if (const Instruction *I = dyn_cast(myVal)) { ... } +// +template +X *dyn_cast(Y *Val) { + return isa(Val) ? (X*)Val : 0; +} #endif