//===-- Support/Casting.h - Allow flexible, checked, casts -------*- C++ -*--=// // // This file defines the isa(), cast(), dyn_cast(), cast_or_null(), // and dyn_cast_or_null() templates. // //===----------------------------------------------------------------------===// #ifndef SUPPORT_CASTING_H #define SUPPORT_CASTING_H // real_type - Provide a macro to get the real type of a value that might be // a use. This provides a typedef 'Type' that is the argument type for all // non UseTy types, and is the contained pointer type of the use if it is a // UseTy. // template class real_type { typedef X 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 inline bool isa(Y Val) { assert(Val && "isa(NULL) invoked!"); return X::classof(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. But it will correctly return NULL when the input is NULL. // Used Like this: // // cast< Instruction>(myVal)->getParent() // cast(myVal)->getParent() // template inline X *cast(Y Val) { assert(isa(Val) && "cast() argument of uncompatible type!"); return (X*)(real_type::Type)Val; } // cast_or_null - Functionally identical to cast, except that a null value is // accepted. // template inline X *cast_or_null(Y Val) { assert((Val == 0 || isa(Val)) && "cast_or_null() argument of uncompatible type!"); return (X*)(real_type::Type)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 inline X *dyn_cast(Y Val) { return isa(Val) ? cast(Val) : 0; } // dyn_cast_or_null - Functionally identical to dyn_cast, except that a null // value is accepted. // template inline X *dyn_cast_or_null(Y Val) { return (Val && isa(Val)) ? cast(Val) : 0; } #endif