diff options
author | Chris Lattner <sabre@nondot.org> | 2002-09-10 00:39:05 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2002-09-10 00:39:05 +0000 |
commit | 979d9b7a5740f627dc8b8ea4f98d81f10f95eb6a (patch) | |
tree | f76666092df2762ba199320eb9ff577a346e2625 /docs | |
parent | 1a143aef993a95e1caef2c8196d0b2f3f5f52c63 (diff) | |
download | llvm-979d9b7a5740f627dc8b8ea4f98d81f10f95eb6a.tar.gz llvm-979d9b7a5740f627dc8b8ea4f98d81f10f95eb6a.tar.bz2 llvm-979d9b7a5740f627dc8b8ea4f98d81f10f95eb6a.tar.xz |
Write most of the isa, cast, dyn_cast section. It's not done yet though.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3639 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'docs')
-rw-r--r-- | docs/ProgrammersManual.html | 76 |
1 files changed, 66 insertions, 10 deletions
diff --git a/docs/ProgrammersManual.html b/docs/ProgrammersManual.html index 20340c2981..07675ab9d4 100644 --- a/docs/ProgrammersManual.html +++ b/docs/ProgrammersManual.html @@ -187,7 +187,68 @@ to write maintainable code more than where to put your curly braces.<p> <a name="isa">The isa<>, cast<> and dyn_cast<> 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<></tt> +operator, but they don't have some drawbacks (primarily stemming from the fact +that <tt>dynamic_cast<></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<></tt>: + +<dd>The <tt>isa<></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<></tt>: + +<dd>The <tt>cast<></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<></tt> and +<tt>cast<></tt> template is:<p> + +<pre> +static bool isLoopInvariant(const <a href="#Value">Value</a> *V, const Loop *L) { + if (isa<<a href="#Constant">Constant</a>>(V) || isa<<a href="#Argument">Argument</a>>(V) || isa<<a href="#GlobalValue">GlobalValue</a>>(V)) + return true; + + <i>// Otherwise, it must be an instruction...</i> + return !L->contains(cast<<a href="#Instruction">Instruction</a>>(V)->getParent()); +</pre><p> + +Note that you should <b>not</b> use an <tt>isa<></tt> test followed by a +<tt>cast<></tt>, for that use the <tt>dyn_cast<></tt> operator.<p> + + +<dt><tt>dyn_cast<></tt>: + +<dd>The <tt>dyn_cast<></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<<a href="#PHINode">PHINode</a>>(&*BBI); ++BBI) + cerr << *PN; +</pre><p> + +Note that you should not use the <tt>dyn_cast<></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> -<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> @@ -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. -<!-- 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 @@ -420,7 +477,6 @@ And the actual code is (remember, since we're writing a has to override the <tt>runOnFunction</tt> method...): <pre> - Function* targetFunc = ...; class OurFunctionPass : public FunctionPass { @@ -430,7 +486,7 @@ class OurFunctionPass : public FunctionPass { virtual runOnFunction(Function& F) { for(Function::iterator b = F.begin(), be = F.end(); b != be; ++b) { for(BasicBlock::iterator i = b->begin(); ie = b->end(); i != ie; ++i) { - if (<a href="#CallInst">CallInst</a>* callInst = dyn_cast<<a href="#CallInst">CallInst</a>>(&*inst)) { + if (<a href="#CallInst">CallInst</a>* callInst = <a href="#isa">dyn_cast</a><<a href="#CallInst">CallInst</a>>(&*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. @@ -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 --> -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> |