Write most of the isa, cast, dyn_cast section. It's not done yet though.
authorChris Lattner <sabre@nondot.org>
Tue, 10 Sep 2002 00:39:05 +0000 (00:39 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 10 Sep 2002 00:39:05 +0000 (00:39 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3639 91177308-0d34-0410-b5e6-96231b3b80d8

docs/ProgrammersManual.html

index 20340c29812e02fd12e0205cf2013b121991cd2d..07675ab9d4db61c5cbf81a33febbc353b99f572e 100644 (file)
@@ -187,7 +187,68 @@ to write maintainable code more than where to put your curly braces.<p>
 <a name="isa">The isa&lt;&gt;, cast&lt;&gt; and dyn_cast&lt;&gt; templates</a>
 </b></font></td></tr></table><ul>
 
 <a name="isa">The isa&lt;&gt;, cast&lt;&gt; and dyn_cast&lt;&gt; templates</a>
 </b></font></td></tr></table><ul>
 
+The LLVM source-base makes extensive use of a custom form of RTTI.  These
+templates have many similarities to the C++ <tt>dynamic_cast&lt;&gt;</tt>
+operator, but they don't have some drawbacks (primarily stemming from the fact
+that <tt>dynamic_cast&lt;&gt;</tt> only works on classes that have a v-table).
+Because they are used so often, you must know what they do and how they work.
+All of these templates are defined in the <a
+href="/doxygen/Casting_8h-source.html"><tt>Support/Casting.h</tt></a> file (note
+that you very rarely have to include this file directly).<p>
 
 
+<dl>
+
+<dt><tt>isa&lt;&gt;</tt>:
+
+<dd>The <tt>isa&lt;&gt;</tt> operator works exactly like the Java
+"<tt>instanceof</tt>" operator.  It returns true or false depending on whether a
+reference or pointer points to an instance of the specified class.  This can be
+very useful for constraint checking of various sorts (example below).<p>
+
+
+<dt><tt>cast&lt;&gt;</tt>:
+
+<dd>The <tt>cast&lt;&gt;</tt> operator is a "checked cast" operation.  It
+converts a pointer or reference from a base class to a derived cast, causing an
+assertion failure if it is not really an instance of the right type.  This
+should be used in cases where you have some information that makes you believe
+that something is of the right type.  An example of the <tt>isa&lt;&gt;</tt> and
+<tt>cast&lt;&gt;</tt> template is:<p>
+
+<pre>
+static bool isLoopInvariant(const <a href="#Value">Value</a> *V, const Loop *L) {
+  if (isa&lt;<a href="#Constant">Constant</a>&gt;(V) || isa&lt;<a href="#Argument">Argument</a>&gt;(V) || isa&lt;<a href="#GlobalValue">GlobalValue</a>&gt;(V))
+    return true;
+
+  <i>// Otherwise, it must be an instruction...</i>
+  return !L->contains(cast&lt;<a href="#Instruction">Instruction</a>&gt;(V)->getParent());
+</pre><p>
+
+Note that you should <b>not</b> use an <tt>isa&lt;&gt;</tt> test followed by a
+<tt>cast&lt;&gt;</tt>, for that use the <tt>dyn_cast&lt;&gt;</tt> operator.<p>
+
+
+<dt><tt>dyn_cast&lt;&gt;</tt>:
+
+<dd>The <tt>dyn_cast&lt;&gt;</tt> operator is a "checking cast" operation.  It
+checks to see if the operand is of the specified type, and if so, returns a
+pointer to it (this operator does not work with references).  If the operand is
+not of the correct type, a null pointer is returned.  Thus, this works very much
+like the <tt>dynamic_cast</tt> operator in C++, and should be used in the same
+circumstances.  An example is:<p>
+
+<pre>
+  <i>// Loop over all of the phi nodes in a basic block</i>
+  BasicBlock::iterator BBI = BB->begin();
+  for (; <a href="#PhiNode">PHINode</a> *PN = dyn_cast&lt;<a href="#PHINode">PHINode</a>&gt;(&amp;*BBI); ++BBI)
+    cerr &lt;&lt; *PN;
+</pre><p>
+
+Note that you should not use the <tt>dyn_cast&lt;&gt;</tt> operator in a series
+of chained if statements, use an visitor instead... FIXME: continue.<p>
+
+
+</dl>
 
 
 
 
 
 
@@ -361,9 +422,9 @@ is semantically equivalent to
 
 <pre>Instruction* pinst = i;</pre>
 
 
 <pre>Instruction* pinst = i;</pre>
 
-<b>Caveat emptor</b>: The above syntax works <i>only</i> when you're
-<i>not</i> working with <tt>dyn_cast</tt>.  The template definition of
-<tt>dyn_cast</tt> isn't implemented to handle this yet, so you'll
+<b>Caveat emptor</b>: The above syntax works <i>only</i> when you're <i>not</i>
+working with <tt>dyn_cast</tt>.  The template definition of <tt><a
+href="#isa">dyn_cast</a></tt> isn't implemented to handle this yet, so you'll
 still need the following in order for things to work properly:
 
 <pre>
 still need the following in order for things to work properly:
 
 <pre>
@@ -388,10 +449,6 @@ void printNextInstruction(Instruction* inst) {
 Of course, this example is strictly pedagogical, because it'd be much
 better to explicitly grab the next instruction directly from inst.
 
 Of course, this example is strictly pedagogical, because it'd be much
 better to explicitly grab the next instruction directly from inst.
 
-<!--   dereferenced iterator = Class &
-       iterators have converting constructor for 'Class *'
-       iterators automatically convert to 'Class *' except in dyn_cast<> case
- -->
 
 <!--_______________________________________________________________________-->
 </ul><h4><a name="iterate_complex"><hr size=0>Finding call sites: a slightly
 
 <!--_______________________________________________________________________-->
 </ul><h4><a name="iterate_complex"><hr size=0>Finding call sites: a slightly
@@ -420,7 +477,6 @@ And the actual code is (remember, since we're writing a
 has to override the <tt>runOnFunction</tt> method...):
 
 <pre>
 has to override the <tt>runOnFunction</tt> method...):
 
 <pre>
-
 Function* targetFunc = ...;
 
 class OurFunctionPass : public FunctionPass {
 Function* targetFunc = ...;
 
 class OurFunctionPass : public FunctionPass {
@@ -430,7 +486,7 @@ class OurFunctionPass : public FunctionPass {
     virtual runOnFunction(Function&amp; F) {
        for(Function::iterator b = F.begin(), be = F.end(); b != be; ++b) {
            for(BasicBlock::iterator i = b-&gt;begin(); ie = b-&gt;end(); i != ie; ++i) {
     virtual runOnFunction(Function&amp; F) {
        for(Function::iterator b = F.begin(), be = F.end(); b != be; ++b) {
            for(BasicBlock::iterator i = b-&gt;begin(); ie = b-&gt;end(); i != ie; ++i) {
-               if (<a href="#CallInst">CallInst</a>* callInst = dyn_cast&lt;<a href="#CallInst">CallInst</a>&gt;(&amp;*inst)) {
+               if (<a href="#CallInst">CallInst</a>* callInst = <a href="#isa">dyn_cast</a>&lt;<a href="#CallInst">CallInst</a>&gt;(&amp;*inst)) {
                    // we know we've encountered a call instruction, so we
                    // need to determine if it's a call to the
                    // function pointed to by m_func or not.
                    // we know we've encountered a call instruction, so we
                    // need to determine if it's a call to the
                    // function pointed to by m_func or not.
@@ -1296,6 +1352,6 @@ pointer to the parent Function.
 <a href="mailto:sabre@nondot.org">Chris Lattner</a></address>
 <!-- Created: Tue Aug  6 15:00:33 CDT 2002 -->
 <!-- hhmts start -->
 <a href="mailto:sabre@nondot.org">Chris Lattner</a></address>
 <!-- Created: Tue Aug  6 15:00:33 CDT 2002 -->
 <!-- hhmts start -->
-Last modified: Mon Sep  9 14:56:55 CDT 2002
+Last modified: Mon Sep  9 19:38:23 CDT 2002
 <!-- hhmts end -->
 </font></body></html>
 <!-- hhmts end -->
 </font></body></html>