Argyrios Kyrtzidis | 7240d77 | 2009-07-10 03:41:36 +0000 | [diff] [blame] | 1 | <html> |
| 2 | <head> |
| 3 | <title>The Index Library</title> |
| 4 | <link type="text/css" rel="stylesheet" href="../menu.css" /> |
| 5 | <link type="text/css" rel="stylesheet" href="../content.css" /> |
| 6 | <style type="text/css"> |
| 7 | td { |
| 8 | vertical-align: top; |
| 9 | } |
| 10 | </style> |
| 11 | </head> |
| 12 | |
| 13 | <body> |
| 14 | |
| 15 | <!--#include virtual="../menu.html.incl"--> |
| 16 | |
| 17 | <div id="content"> |
| 18 | |
| 19 | <h1>The Index Library</h1> |
| 20 | |
| 21 | <p><b>Table of Contents</b></p> |
| 22 | <ul> |
| 23 | <li><a href="#philosophy">Design Philosophy</a></li> |
| 24 | <li><a href="#classes">Classes</a> |
| 25 | <ul> |
| 26 | <li><a href="#entity">Entity</a></li> |
| 27 | <li><a href="#astlocation">ASTLocation</a></li> |
| 28 | <li><a href="#declreferencemap">DeclReferenceMap</a></li> |
| 29 | </ul> |
| 30 | </li> |
| 31 | <li><a href="#functions">Functions</a> |
| 32 | <ul> |
| 33 | <li><a href="#resolveloc">ResolveLocationInAST</a></li> |
| 34 | </ul> |
| 35 | </li> |
| 36 | <li><a href="#astfiles">AST Files</a></li> |
| 37 | <li><a href="#indextest">index-test tool</a> |
| 38 | <ul> |
| 39 | <li><a href="#indextestusage">Usage</a></li> |
| 40 | <li><a href="#indextestexamples">Examples</a></li> |
| 41 | </ul> |
| 42 | </li> |
| 43 | </ul> |
| 44 | |
| 45 | <h2 id="philosophy">Design Philosophy</h2> |
| 46 | |
| 47 | <p> The Index library is meant to provide the basic infrastructure for |
| 48 | cross-translation-unit analysis and is primarily focused on indexing |
| 49 | related functionality. It provides an API for clients that need to |
| 50 | accurately map the AST nodes of the ASTContext to the locations in the source files. |
| 51 | It also allows them to analyze information across multiple translation units.</p> |
| 52 | |
| 53 | <p>As a "general rule", ASTContexts are considered the primary source of |
| 54 | information that a client wants about a translation unit. There will be no such class as an |
| 55 | "indexing database" that stores, for example, source locations of identifiers separately from ASTContext. |
| 56 | All the information that a client needs from a translation unit will be extracted from the ASTContext.</p> |
| 57 | |
| 58 | <h2 id="classes">Classes</h2> |
| 59 | |
| 60 | <h3 id="entity">Entity</h3> |
| 61 | |
| 62 | <p>To be able to reason about semantically the same Decls that are contained in multiple ASTContexts, the 'Entity' class was introduced. |
| 63 | An Entity is an ASTContext-independent "token" that can be created from a Decl (and a typename in the future) with |
| 64 | the purpose to "resolve" it into a Decl belonging to another ASTContext. Some examples to make the concept of Entities more clear:</p> |
| 65 | |
| 66 | <p> |
| 67 | t1.c: |
| 68 | <pre class="code_example"> |
| 69 | void foo(void); |
| 70 | void bar(void); |
| 71 | </pre> |
| 72 | </p> |
| 73 | |
| 74 | <p> |
| 75 | t2.c: |
| 76 | <pre class="code_example"> |
| 77 | void foo(void) { |
| 78 | } |
| 79 | </pre> |
| 80 | </p> |
| 81 | |
| 82 | <p> |
| 83 | Translation unit <code>t1.c</code> contains 2 Entities <code>foo</code> and <code>bar</code>, while <code>t2.c</code> contains 1 Entity <code>foo</code>. |
| 84 | Entities are uniqued in such a way that the Entity* pointer for <code>t1.c/foo</code> is the same as the Entity* pointer for <code>t2.c/foo</code>. |
| 85 | An Entity doesn't convey any information about the declaration, it is more like an opaque pointer used only to get the |
| 86 | associated Decl out of an ASTContext so that the actual information for the declaration can be accessed. |
| 87 | Another important aspect of Entities is that they can only be created/associated for declarations that are visible outside the |
| 88 | translation unit. This means that for: |
| 89 | </p> |
| 90 | <p> |
| 91 | t3.c: |
| 92 | <pre class="code_example"> |
| 93 | static void foo(void); |
| 94 | </pre> |
| 95 | </p> |
| 96 | <p> |
| 97 | there can be no Entity (if you ask for the Entity* of the static function <code>foo</code> you'll get a null pointer). |
| 98 | This is for 2 reasons: |
| 99 | <ul> |
| 100 | <li>To preserve the invariant that the same Entity* pointers refer to the same semantic Decls. |
| 101 | In the above example <code>t1.c/foo</code> and <code>t2.c/foo</code> are the same, while <code>t3.c/foo</code> is different.</li> |
| 102 | <li>The purpose of Entity is to get the same semantic Decl from multiple ASTContexts. For a Decl that is not visible |
| 103 | outside of its own translation unit, you don't need an Entity since it won't appear in another ASTContext.</li> |
| 104 | </ul> |
| 105 | </p> |
| 106 | |
| 107 | <h3 id="astlocation">ASTLocation</h3> |
| 108 | |
| 109 | Encapsulates a "point" in the AST tree of the ASTContext. |
| 110 | It represents either a Decl*, or a Stmt* along with its immediate Decl* parent. |
| 111 | An example for its usage is that libIndex will provide the references of <code>foo</code> in the form of ASTLocations, |
| 112 | "pointing" at the expressions that reference <code>foo</code>. |
| 113 | |
| 114 | <h3 id="declreferencemap">DeclReferenceMap</h3> |
| 115 | |
| 116 | Accepts an ASTContext and creates a mapping from NamedDecls to the ASTLocations that reference them (in the same ASTContext). |
| 117 | |
| 118 | <h2 id="functions">Functions</h2> |
| 119 | |
| 120 | <h3 id="resolveloc">ResolveLocationInAST</h3> |
| 121 | |
| 122 | A function that accepts an ASTContext and a SourceLocation which it resolves into an ASTLocation. |
| 123 | |
| 124 | <h2 id="astfiles">AST Files</h2> |
| 125 | |
| 126 | The precompiled headers implementation of clang (<a href="http://clang.llvm.org/docs/PCHInternals.html">PCH</a>) is ideal for storing an ASTContext in a compact form that |
| 127 | will be loaded later for AST analysis. An "AST file" refers to a translation unit that was "compiled" into a precompiled header file. |
| 128 | |
| 129 | <h2 id="indextest">index-test tool</h2> |
| 130 | |
| 131 | <h3 id="indextestusage">Usage</h3> |
| 132 | |
| 133 | A command-line tool that exercises the libIndex API, useful for testing its features. |
| 134 | As input it accepts multiple AST files (representing multiple translation units) and a few options: |
| 135 | |
| 136 | <p> |
| 137 | <pre class="code_example"> |
| 138 | -point-at [file:line:column] |
| 139 | </pre> |
| 140 | Resolves a [file:line:column] triplet into a ASTLocation from the first AST file. If no other option is specified, it prints the ASTLocation. |
| 141 | It also prints a declaration's associated doxygen comment, if one is available. |
| 142 | </p> |
| 143 | |
| 144 | <p> |
| 145 | <pre class="code_example"> |
| 146 | -print-refs |
| 147 | </pre> |
| 148 | Prints the ASTLocations that reference the declaration that was resolved out of the [file:line:column] triplet |
| 149 | </p> |
| 150 | |
| 151 | <p> |
| 152 | <pre class="code_example"> |
| 153 | -print-defs |
| 154 | </pre> |
| 155 | Prints the ASTLocations that define the resolved declaration |
| 156 | </p> |
| 157 | |
| 158 | <p> |
| 159 | <pre class="code_example"> |
| 160 | -print-decls |
| 161 | </pre> |
| 162 | Prints the ASTLocations that declare the resolved declaration |
| 163 | </p> |
| 164 | |
| 165 | <h3 id="indextestexamples">Examples</h3> |
| 166 | |
| 167 | <p> |
| 168 | Here's an example of using index-test: |
| 169 | </p> |
| 170 | |
| 171 | <p> |
| 172 | We have 3 files, |
| 173 | </p> |
| 174 | |
| 175 | <p> |
| 176 | foo.h: |
| 177 | <pre class="code_example"> |
| 178 | extern int global_var; |
| 179 | |
| 180 | void foo_func(int param1); |
| 181 | void bar_func(void); |
| 182 | </pre> |
| 183 | |
| 184 | t1.c: |
| 185 | <pre class="code_example"> |
| 186 | #include "foo.h" |
| 187 | |
| 188 | void foo_func(int param1) { |
| 189 | int local_var = global_var; |
| 190 | for (int for_var = 100; for_var < 500; ++for_var) { |
| 191 | local_var = param1 + for_var; |
| 192 | } |
| 193 | bar_func(); |
| 194 | } |
| 195 | </pre> |
| 196 | |
| 197 | t2.c: |
| 198 | <pre class="code_example"> |
| 199 | #include "foo.h" |
| 200 | |
| 201 | int global_var = 10; |
| 202 | |
| 203 | void bar_func(void) { |
| 204 | global_var += 100; |
| 205 | foo_func(global_var); |
| 206 | } |
| 207 | </pre> |
| 208 | </p> |
| 209 | |
| 210 | <p> |
| 211 | You first get AST files out of <code>t1.c</code> and <code>t2.c</code>: |
| 212 | |
| 213 | <pre class="code_example"> |
Daniel Dunbar | 69cfd86 | 2009-12-11 23:17:03 +0000 | [diff] [blame] | 214 | $ clang -emit-ast t1.c -o t1.ast |
| 215 | $ clang -emit-ast t2.c -o t2.ast |
Argyrios Kyrtzidis | 7240d77 | 2009-07-10 03:41:36 +0000 | [diff] [blame] | 216 | </pre> |
| 217 | </p> |
| 218 | |
| 219 | <p> |
| 220 | Find the ASTLocation under this position of <code>t1.c</code>: |
| 221 | <pre class="code_example"> |
| 222 | [...] |
| 223 | void foo_func(int param1) { |
| 224 | int local_var = global_var; |
| 225 | ^ |
| 226 | [...] |
| 227 | </pre> |
| 228 | |
| 229 | <pre class="code_example"> |
| 230 | $ index-test t1.ast -point-at t1.c:4:23 |
| 231 | > [Decl: Var local_var | Stmt: DeclRefExpr global_var] <t1.c:4:19, t1.c:4:19> |
| 232 | </pre> |
| 233 | </p> |
| 234 | |
| 235 | <p> |
| 236 | Find the declaration: |
| 237 | |
| 238 | <pre class="code_example"> |
| 239 | $ index-test t1.ast -point-at t1.c:4:23 -print-decls |
| 240 | > [Decl: Var global_var] <foo.h:1:12, foo.h:1:12> |
| 241 | </pre> |
| 242 | </p> |
| 243 | |
| 244 | <p> |
| 245 | Find the references: |
| 246 | |
| 247 | <pre class="code_example"> |
| 248 | $ index-test t1.ast t2.ast -point-at t1.c:4:23 -print-refs |
| 249 | > [Decl: Var local_var | Stmt: DeclRefExpr global_var] <t1.c:4:19, t1.c:4:19> |
| 250 | > [Decl: Function bar_func | Stmt: DeclRefExpr global_var] <t2.c:6:3, t2.c:6:3> |
| 251 | > [Decl: Function bar_func | Stmt: DeclRefExpr global_var] <t2.c:7:12, t2.c:7:12> |
| 252 | </pre> |
| 253 | </p> |
| 254 | |
| 255 | <p> |
| 256 | Find definitions: |
| 257 | |
| 258 | <pre class="code_example"> |
| 259 | $ index-test t1.ast t2.ast -point-at t1.c:4:23 -print-defs |
| 260 | > [Decl: Var global_var] <t2.c:3:5, t2.c:3:18> |
| 261 | </pre> |
| 262 | </p> |
| 263 | |
| 264 | </div> |
| 265 | |
| 266 | </body> |
| 267 | </html> |