Add support for newer cleaner isa, cast, dyn_cast
authorChris Lattner <sabre@nondot.org>
Mon, 1 Oct 2001 13:58:13 +0000 (13:58 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 1 Oct 2001 13:58:13 +0000 (13:58 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@693 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/BasicBlock.h
include/llvm/Instruction.h
include/llvm/Type.h
include/llvm/Value.h

index 11c76a364721a2eb70c65c48cfc4eae3ee6700d0..08516c8ca83142db91ec61c958feb409d56e5bf3 100644 (file)
@@ -163,7 +163,7 @@ public:
       // TODO: This is bad
       // Loop to ignore constant pool references
       while (It != BB->use_end() && 
-             ((!(*It)->isInstruction()) ||
+             ((!isa<Instruction>(*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<Instruction>(*It)->getParent(); 
     }
     inline pointer *operator->() const { return &(operator*()); }
     
index 3bbb8e7031eb3f86ca6f84c9e0aaa245077158d7..93b68a2c628ae110045b509bece125b6e61090f7 100644 (file)
@@ -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...
index 5854062df0c8a660435822736e57cdd33fa93b1e..2a43153acd0d223bf739863b45cb0d298aef31a6 100644 (file)
@@ -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:
index 7d214e2ab49d712b21554d65a58e850cd5e5aefc..14794dc4c92ee239daf9cb47538c95242ed516e3 100644 (file)
@@ -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<X>(), cast<X>(), and dyn_cast<X>() 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<Value> Use;
+typedef UseTy<Value> Use;    // Provide Use as a common UseTy type
+
+
+//===----------------------------------------------------------------------===//
+//                          Type Checking Templates
+//===----------------------------------------------------------------------===//
+
+// isa<X> - Return true if the parameter to the template is an instance of the
+// template type argument.  Used like this:
+//
+//  if (isa<Type>(myVal)) { ... }
+//
+template <class X, class Y>
+bool isa(Y *Val) { return X::isa(Val); }
+
+
+// cast<X> - 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<const Instruction>(myVal)->getParent()
+//
+template <class X, class Y>
+X *cast(Y *Val) {
+  assert(isa<X>(Val) && "Invalid cast argument type!");
+  return (X*)Val;
+}
+
+
+// dyn_cast<X> - 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<const Instruction>(myVal)) { ... }
+//
+template <class X, class Y>
+X *dyn_cast(Y *Val) {
+  return isa<X>(Val) ? (X*)Val : 0;
+}
 
 #endif