diff options
author | dim <dim@FreeBSD.org> | 2012-12-02 13:20:44 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2012-12-02 13:20:44 +0000 |
commit | 056abd2059c65a3e908193aeae16fad98017437c (patch) | |
tree | 2732d02d7d51218d6eed98ac7fcfc5b8794896b5 /docs | |
parent | cc73504950eb7b5dff2dded9bedd67bc36d64641 (diff) | |
download | FreeBSD-src-056abd2059c65a3e908193aeae16fad98017437c.zip FreeBSD-src-056abd2059c65a3e908193aeae16fad98017437c.tar.gz |
Vendor import of clang release_32 branch r168974 (effectively, 3.2 RC2):
http://llvm.org/svn/llvm-project/cfe/branches/release_32@168974
Diffstat (limited to 'docs')
-rw-r--r-- | docs/AddressSanitizer.html | 49 | ||||
-rw-r--r-- | docs/AutomaticReferenceCounting.html | 43 | ||||
-rw-r--r-- | docs/BlockLanguageSpec.txt | 24 | ||||
-rw-r--r-- | docs/ClangTools.html | 18 | ||||
-rw-r--r-- | docs/HowToSetupToolingForLLVM.html | 34 | ||||
-rw-r--r-- | docs/InternalsManual.html | 4 | ||||
-rw-r--r-- | docs/LanguageExtensions.html | 8 | ||||
-rw-r--r-- | docs/LibASTMatchers.html | 130 | ||||
-rw-r--r-- | docs/LibASTMatchersReference.html | 1938 | ||||
-rw-r--r-- | docs/LibTooling.html | 125 | ||||
-rw-r--r-- | docs/ObjectiveCLiterals.html | 2 | ||||
-rw-r--r-- | docs/PCHInternals.html | 320 | ||||
-rw-r--r-- | docs/ReleaseNotes.html | 10 | ||||
-rw-r--r-- | docs/ThreadSanitizer.html | 15 | ||||
-rw-r--r-- | docs/UsersManual.html | 82 | ||||
-rw-r--r-- | docs/analyzer/IPA.txt | 363 | ||||
-rw-r--r-- | docs/analyzer/debug-checks.txt | 89 | ||||
-rw-r--r-- | docs/tools/clang.pod | 2 | ||||
-rw-r--r-- | docs/tools/dump_ast_matchers.py | 264 |
19 files changed, 3225 insertions, 295 deletions
diff --git a/docs/AddressSanitizer.html b/docs/AddressSanitizer.html index 98ea934..397eafc 100644 --- a/docs/AddressSanitizer.html +++ b/docs/AddressSanitizer.html @@ -45,17 +45,21 @@ The tool can detect the following types of bugs: Typical slowdown introduced by AddressSanitizer is <b>2x</b>. <h2 id="howtobuild">How to build</h2> -Follow the <a href="../get_started.html">clang build instructions</a>. <BR> -Note: CMake build does not work yet. -See <a href="http://llvm.org/bugs/show_bug.cgi?id=12272">bug 12272</a>. +Follow the <a href="../get_started.html">clang build instructions</a>. +CMake build is supported.<BR> <h2 id="usage">Usage</h2> -Simply compile and link your program with <tt>-faddress-sanitizer</tt> flag. <BR> +Simply compile and link your program with <tt>-fsanitize=address</tt> flag. <BR> +The AddressSanitizer run-time library should be linked to the final executable, +so make sure to use <tt>clang</tt> (not <tt>ld</tt>) for the final link step.<BR> +When linking shared libraries, the AddressSanitizer run-time is not linked, +so <tt>-Wl,-z,defs</tt> may cause link errors (don't use it with AddressSanitizer). <BR> + To get a reasonable performance add <tt>-O1</tt> or higher. <BR> To get nicer stack traces in error messages add <tt>-fno-omit-frame-pointer</tt>. <BR> To get perfect stack traces you may need to disable inlining (just use <tt>-O1</tt>) and tail call -elimination (</tt>-fno-optimize-sibling-calls</tt>). +elimination (<tt>-fno-optimize-sibling-calls</tt>). <pre> % cat example_UseAfterFree.cc @@ -67,7 +71,15 @@ int main(int argc, char **argv) { </pre> <pre> -% clang -O1 -g -faddress-sanitizer -fno-omit-frame-pointer example_UseAfterFree.cc +# Compile and link +% clang -O1 -g -fsanitize=address -fno-omit-frame-pointer example_UseAfterFree.cc +</pre> +OR +<pre> +# Compile +% clang -O1 -g -fsanitize=address -fno-omit-frame-pointer -c example_UseAfterFree.cc +# Link +% clang -g -fsanitize=address example_UseAfterFree.o </pre> If a bug is detected, the program will print an error message to stderr and exit with a @@ -93,6 +105,13 @@ previously allocated by thread T0 here: ==9442== ABORTING </pre> +AddressSanitizer exits on the first detected error. This is by design. +One reason: it makes the generated code smaller and faster (both by ~5%). +Another reason: this makes fixing bugs unavoidable. With Valgrind, it is often +the case that users treat Valgrind warnings as false positives +(which they are not) and don't fix them. + + <h3 id="has_feature">__has_feature(address_sanitizer)</h3> In some cases one may need to execute different code depending on whether AddressSanitizer is enabled. @@ -107,8 +126,8 @@ can be used for this purpose. </pre> <h3 id="no_address_safety_analysis">__attribute__((no_address_safety_analysis))</h3> -Some code should not be instrumentated by AddressSanitizer. -One may use the function attribute +Some code should not be instrumented by AddressSanitizer. +One may use the function attribute <a href="LanguageExtensions.html#address_sanitizer"> <tt>no_address_safety_analysis</tt></a> to disable instrumentation of a particular function. @@ -118,18 +137,18 @@ Note: currently, this attribute will be lost if the function is inlined. <h2 id="platforms">Supported Platforms</h2> AddressSanitizer is supported on -<ul><li>Linux x86_64 (tested on Ubuntu 10.04). -<li>MacOS 10.6 and 10.7 (i386/x86_64). +<ul><li>Linux i386/x86_64 (tested on Ubuntu 10.04 and 12.04). +<li>MacOS 10.6, 10.7 and 10.8 (i386/x86_64). </ul> -Support for Linux i386/ARM is in progress +Support for Linux ARM (and Android ARM) is in progress (it may work, but is not guaranteed too). <h2 id="limitations">Limitations</h2> <ul> <li> AddressSanitizer uses more real memory than a native run. -How much -- depends on the allocations sizes. The smaller the -allocations you make the bigger the overhead. +Exact overhead depends on the allocations sizes. The smaller the +allocations you make the bigger the overhead is. <li> AddressSanitizer uses more stack memory. We have seen up to 3x increase. <li> On 64-bit platforms AddressSanitizer maps (but not reserves) 16+ Terabytes of virtual address space. @@ -140,8 +159,8 @@ This means that tools like <tt>ulimit</tt> may not work as usually expected. <h2 id="status">Current Status</h2> AddressSanitizer is fully functional on supported platforms starting from LLVM 3.1. -However, the test suite is not fully integrated yet and we lack the testing -process (buildbots). +The test suite is integrated into CMake build and can be run with +<tt>make check-asan</tt> command. <h2 id="moreinfo">More Information</h2> <a href="http://code.google.com/p/address-sanitizer/">http://code.google.com/p/address-sanitizer</a>. diff --git a/docs/AutomaticReferenceCounting.html b/docs/AutomaticReferenceCounting.html index 3f1ccaf..5354f8a 100644 --- a/docs/AutomaticReferenceCounting.html +++ b/docs/AutomaticReferenceCounting.html @@ -888,6 +888,15 @@ from non-ARC practice was acceptable because we had conservatively banned the synthesis in order to give ourselves exactly this leeway.</p></div> +<p>Applying <tt>__attribute__((NSObject))</tt> to a property not of +retainable object pointer type has the same behavior it does outside +of ARC: it requires the property type to be some sort of pointer and +permits the use of modifiers other than <tt>assign</tt>. These +modifiers only affect the synthesized getter and setter; direct +accesses to the ivar (even if synthesized) still have primitive +semantics, and the value in the ivar will not be automatically +released during deallocation.</p> + </div> <!-- ownership.spelling.property --> </div> <!-- ownership.spelling --> @@ -1602,6 +1611,36 @@ implementation must be very careful to do all the other work that <tt>NSObject</tt>'s <tt>dealloc</tt> would, which is outside the scope of this document to describe.</p></div> +<p>The instance variables for an ARC-compiled class will be destroyed +at some point after control enters the <tt>dealloc</tt> method for the +root class of the class. The ordering of the destruction of instance +variables is unspecified, both within a single class and between +subclasses and superclasses.</p> + +<div class="rationale"><p>Rationale: the traditional, non-ARC pattern +for destroying instance variables is to destroy them immediately +before calling <tt>[super dealloc]</tt>. Unfortunately, message +sends from the superclass are quite capable of reaching methods in the +subclass, and those methods may well read or write to those instance +variables. Making such message sends from dealloc is generally +discouraged, since the subclass may well rely on other invariants that +were broken during <tt>dealloc</tt>, but it's not so inescapably +dangerous that we felt comfortable calling it undefined behavior. +Therefore we chose to delay destroying the instance variables to a +point at which message sends are clearly disallowed: the point at +which the root class's deallocation routines take over.</p> + +<p>In most code, the difference is not observable. It can, however, +be observed if an instance variable holds a strong reference to an +object whose deallocation will trigger a side-effect which must be +carefully ordered with respect to the destruction of the super class. +Such code violates the design principle that semantically important +behavior should be explicit. A simple fix is to clear the instance +variable manually during <tt>dealloc</tt>; a more holistic solution is +to move semantically important side-effects out of +<tt>dealloc</tt> and into a separate teardown phase which can rely on +working with well-formed objects.</p></div> + </div> </div> <!-- misc.special_methods --> @@ -1865,9 +1904,9 @@ and <tt>cf_unknown_transfer</tt>.</p> <p>A pragma is provided to facilitate the mass annotation of interfaces:</p> -<pre>#pragma arc_cf_code_audited begin +<pre>#pragma clang arc_cf_code_audited begin ... -#pragma arc_cf_code_audited end</pre> +#pragma clang arc_cf_code_audited end</pre> <p>All C functions declared within the extent of this pragma are treated as if annotated with the <tt>cf_audited_transfer</tt> diff --git a/docs/BlockLanguageSpec.txt b/docs/BlockLanguageSpec.txt index f7bbda3..4cdf75a 100644 --- a/docs/BlockLanguageSpec.txt +++ b/docs/BlockLanguageSpec.txt @@ -81,6 +81,10 @@ The compound statement body establishes a new lexical scope within that of its p Local automatic (stack) variables referenced within the compound statement of a Block are imported and captured by the Block as const copies. The capture (binding) is performed at the time of the Block literal expression evaluation. +The compiler is not required to capture a variable if it can prove that no references to the variable will actually be evaluated. Programmers can force a variable to be captured by referencing it in a statement at the beginning of the Block, like so: + (void) foo; +This matters when capturing the variable has side-effects, as it can in Objective-C or C++. + The lifetime of variables declared in a Block is that of a function; each activation frame contains a new copy of variables declared within the local scope of the Block. Such variable declarations should be allowed anywhere [testme] rather than only when C99 parsing is requested, including for statements. [testme] Block literal expressions may occur within Block literal expressions (nest) and all variables captured by any nested blocks are implicitly also captured in the scopes of their enclosing Blocks. @@ -143,23 +147,25 @@ C++ Extensions Block literal expressions within functions are extended to allow const use of C++ objects, pointers, or references held in automatic storage. -For example, given class Foo with member function fighter(void): +As usual, within the block, references to captured variables become const-qualified, as if they were references to members of a const object. Note that this does not change the type of a variable of reference type. + +For example, given a class Foo: Foo foo; Foo &fooRef = foo; Foo *fooPtr = &foo; -...a Block that used foo would import the variables as const variations: - const Foo block_foo = foo; // const copy constructor - const Foo &block_fooRef = fooRef; - Foo *const block_fooPtr = fooPtr; +A Block that referenced these variables would import the variables as const variations: + const Foo block_foo = foo; + Foo &block_fooRef = fooRef; + Foo *const block_fooPtr = fooPtr; -Stack-local objects are copied into a Block via a copy const constructor. If no such constructor exists, it is considered an error to reference such objects from within the Block compound statements. A destructor is run as control leaves the compound statement that contains the Block literal expression. +Captured variables are copied into the Block at the instant of evaluating the Block literal expression. They are also copied when calling Block_copy() on a Block allocated on the stack. In both cases, they are copied as if the variable were const-qualified, and it's an error if there's no such constructor. -If a Block originates on the stack, a const copy constructor of the stack-based Block const copy is performed when a Block_copy operation is called; when the last Block_release (or subsequently GC) occurs, a destructor is run on the heap copy. +Captured variables in Blocks on the stack are destroyed when control leaves the compound statement that contains the Block literal expression. Captured variables in Blocks on the heap are destroyed when the reference count of the Block drops to zero. -Variables declared as residing in __block storage may be initially allocated in the heap or may first appear on the stack and be copied to the heap as a result of a Block_copy() operation. When copied from the stack, a normal copy constructor is used to initialize the heap-based version from the original stack version. The destructor for a const copied object is run at the normal end of scope. The destructor for any initial stack based version is also called at normal end of scope. +Variables declared as residing in __block storage may be initially allocated in the heap or may first appear on the stack and be copied to the heap as a result of a Block_copy() operation. When copied from the stack, __block variables are copied using their normal qualification (i.e. without adding const). In C++11, __block variables are copied as x-values if that is possible, then as l-values if not; if both fail, it's an error. The destructor for any initial stack-based version is called at the variable's normal end of scope. -Within a member function, access to member functions and variables is done via an implicit const copy of a this pointer. +References to 'this', as well as references to non-static members of any enclosing class, are evaluated by capturing 'this' just like a normal variable of C pointer type. Member variables that are Blocks may not be overloaded by the types of their arguments. diff --git a/docs/ClangTools.html b/docs/ClangTools.html index 0dfdc6a..4de57bd 100644 --- a/docs/ClangTools.html +++ b/docs/ClangTools.html @@ -87,22 +87,14 @@ specific functionality.</p> <h3 id="clang-check"><tt>clang-check</tt></h3> <p>This tool combines the LibTooling framework for running a Clang tool with the -basic Clang diagnostics by syntax checking specific files in a fast, command line -interface. It can also accept flags to re-display the diagnostics in different -formats with different flags, suitable for use driving an IDE or editor.</p> +basic Clang diagnostics by syntax checking specific files in a fast, command +line interface. It can also accept flags to re-display the diagnostics in +different formats with different flags, suitable for use driving an IDE or +editor. Furthermore, it can be used in fixit-mode to directly apply fixit-hints +offered by clang.</p> <p>FIXME: Link to user-oriented clang-check documentation.</p> -<h3 id="clang-fixit"><tt>clang-fixit</tt> (Not yet implemented!)</h3> -<p>A tool which specifically applies the Clang fix-it hint diagnostic technology -on top of a dedicated tool. It is designed to explore alternative interfaces for -applying fix-it hints, including automatic application, prompting users with -options for different fixes, etc.</p> - -<p><b>NB:</b> The clang-fixit tool is planned, but not yet implemented.</p> - -<p>FIXME: Link to user-oriented clang-fixit documentation.</p> - <!-- ======================================================================= --> <h2 id="registerplugin">Extra Clang Tools</h2> <!-- ======================================================================= --> diff --git a/docs/HowToSetupToolingForLLVM.html b/docs/HowToSetupToolingForLLVM.html index 493c882..022ed9c 100644 --- a/docs/HowToSetupToolingForLLVM.html +++ b/docs/HowToSetupToolingForLLVM.html @@ -77,12 +77,38 @@ $PATH. Try to run it on any .cpp file inside the LLVM source tree:</p> <p>If you're using vim, it's convenient to have clang-check integrated. Put this into your .vimrc:</p> <pre> - set makeprg=clang-check\ % - map <F5> :make<CR><CR> +function! ClangCheckImpl(cmd) + if &autowrite | wall | endif + echo "Running " . a:cmd . " ..." + let l:output = system(a:cmd) + cexpr l:output + cwindow + let w:quickfix_title = a:cmd + if v:shell_error != 0 + cc + endif + let g:clang_check_last_cmd = a:cmd +endfunction + +function! ClangCheck() + let l:filename = expand('%') + if l:filename =~ '\.\(cpp\|cxx\|cc\|c\)$' + call ClangCheckImpl("clang-check " . l:filename) + elseif exists("g:clang_check_last_cmd") + call ClangCheckImpl(g:clang_check_last_cmd) + else + echo "Can't detect file's compilation arguments and no previous clang-check invocation!" + endif +endfunction + +nmap <silent> <F5> :call ClangCheck()<CR><CR> </pre> -<p>When editing C++ code, hit F5 to reparse the current buffer. The output will -go into the error window, which you can enable with <code>:cope</code>.</p> +<p>When editing a .cpp/.cxx/.cc/.c file, hit F5 to reparse the file. In case +the current file has a different extension (for example, .h), F5 will re-run +the last clang-check invocation made from this vim instance (if any). The +output will go into the error window, which is opened automatically when +clang-check finds errors, and can be re-opened with <code>:cope</code>.</p> <p>Other <code>clang-check</code> options that can be useful when working with clang AST:</p> diff --git a/docs/InternalsManual.html b/docs/InternalsManual.html index 3f3e124..57f0631 100644 --- a/docs/InternalsManual.html +++ b/docs/InternalsManual.html @@ -502,7 +502,9 @@ code, the source ranges, and the caret. However, this behavior isn't required. Instead of formatting and printing out the diagnostics, this implementation just captures and remembers the diagnostics as they fly by. Then -verify compares the list of produced diagnostics to the list of expected ones. If they disagree, -it prints out its own output. +it prints out its own output. Full documentation for the -verify mode can be +found in the Clang API documentation for VerifyDiagnosticConsumer, <a +href="/doxygen/classclang_1_1VerifyDiagnosticConsumer.html#details">here</a>. </p> <p>There are many other possible implementations of this interface, and this is diff --git a/docs/LanguageExtensions.html b/docs/LanguageExtensions.html index 40477b8..8c0e5b7 100644 --- a/docs/LanguageExtensions.html +++ b/docs/LanguageExtensions.html @@ -1007,6 +1007,7 @@ struct is_convertible_to { <li><code>__is_convertible_to</code> (Microsoft)</li> <li><code>__is_empty</code> (GNU, Microsoft)</li> <li><code>__is_enum</code> (GNU, Microsoft)</li> + <li><code>__is_interface_class</code> (Microsoft)</li> <li><code>__is_pod</code> (GNU, Microsoft)</li> <li><code>__is_polymorphic</code> (GNU, Microsoft)</li> <li><code>__is_union</code> (GNU, Microsoft)</li> @@ -1582,7 +1583,8 @@ path between it and the next switch label.</p> <pre> // compile with -Wimplicit-fallthrough switch (n) { -case 33: +case 22: +case 33: // no warning: no statements between case labels f(); case 44: // warning: unannotated fall-through g(); @@ -1981,8 +1983,8 @@ int fcntl(int fd, int cmd, ...) <p>Use <tt>__attribute__((pointer_with_type_tag(ptr_kind, ptr_idx, type_tag_idx)))</tt> on a function declaration to specify that the -function a type tag that determines the pointee type of some other pointer -argument.</p> +function accepts a type tag that determines the pointee type of some other +pointer argument.</p> <p>For example:</p> <blockquote> diff --git a/docs/LibASTMatchers.html b/docs/LibASTMatchers.html new file mode 100644 index 0000000..8142c19 --- /dev/null +++ b/docs/LibASTMatchers.html @@ -0,0 +1,130 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> +<title>Matching the Clang AST</title> +<link type="text/css" rel="stylesheet" href="../menu.css" /> +<link type="text/css" rel="stylesheet" href="../content.css" /> +</head> +<body> + +<!--#include virtual="../menu.html.incl"--> + +<div id="content"> + +<h1>Matching the Clang AST</h1> +<p>This document explains how to use Clang's LibASTMatchers to match interesting +nodes of the AST and execute code that uses the matched nodes. Combined with +<a href="LibTooling.html">LibTooling</a>, LibASTMatchers helps to write +code-to-code transformation tools or query tools.</p> + +<p>We assume basic knowledge about the Clang AST. See the +<a href="IntroductionToTheClangAST.html">Introduction to the Clang AST</a> if +you want to learn more about how the AST is structured.</p> + +<!-- FIXME: create tutorial and link to the tutorial --> + +<!-- ======================================================================= --> +<h2 id="intro">Introduction</h2> +<!-- ======================================================================= --> + +<p>LibASTMatchers provides a domain specific language to create predicates on Clang's +AST. This DSL is written in and can be used from C++, allowing users to write +a single program to both match AST nodes and access the node's C++ interface +to extract attributes, source locations, or any other information provided on +the AST level.</p> + +<p>AST matchers are predicates on nodes in the AST. Matchers are created +by calling creator functions that allow building up a tree of matchers, where +inner matchers are used to make the match more specific.</p> + +</p>For example, to create a matcher that matches all class or union declarations +in the AST of a translation unit, you can call +<a href="LibASTMatchersReference.html#recordDecl0Anchor">recordDecl()</a>. +To narrow the match down, for example to find all class or union declarations with the name "Foo", +insert a <a href="LibASTMatchersReference.html#hasName0Anchor">hasName</a> +matcher: the call recordDecl(hasName("Foo")) returns a matcher that matches classes +or unions that are named "Foo", in any namespace. By default, matchers that accept +multiple inner matchers use an implicit <a href="LibASTMatchersReference.html#allOf0Anchor">allOf()</a>. +This allows further narrowing down the match, for example to match all classes +that are derived from "Bar": recordDecl(hasName("Foo"), isDerivedFrom("Bar")).</p> + +<!-- ======================================================================= --> +<h2 id="writing">How to create a matcher</h2> +<!-- ======================================================================= --> + +<p>With more than a thousand classes in the Clang AST, one can quickly get lost +when trying to figure out how to create a matcher for a specific pattern. This +section will teach you how to use a rigorous step-by-step pattern to build the +matcher you are interested in. Note that there will always be matchers missing +for some part of the AST. See the section about <a href="#writing">how to write +your own AST matchers</a> later in this document.</p> + +<p>The precondition to using the matchers is to understand how the AST +for what you want to match looks like. The <a href="IntroductionToTheClangAST.html">Introduction to the Clang AST</a> +teaches you how to dump a translation unit's AST into a human readable format.</p> + +<!-- FIXME: Introduce link to ASTMatchersTutorial.html --> +<!-- FIXME: Introduce link to ASTMatchersCookbook.html --> + +<p>In general, the strategy to create the right matchers is:</p> +<ol> +<li>Find the outermost class in Clang's AST you want to match.</li> +<li>Look at the <a href="LibASTMatchersReference.html">AST Matcher Reference</a> for matchers that either match the +node you're interested in or narrow down attributes on the node.</li> +<li>Create your outer match expression. Verify that it works as expected.</li> +<li>Examine the matchers for what the next inner node you want to match is.</li> +<li>Repeat until the matcher is finished.</li> +</ol> + +<!-- ======================================================================= --> +<h2 id="binding">Binding nodes in match expressions</h2> +<!-- ======================================================================= --> + +<p>Matcher expressions allow you to specify which parts of the AST are interesting +for a certain task. Often you will want to then do something with the nodes +that were matched, like building source code transformations.</p> + +<p>To that end, matchers that match specific AST nodes (so called node matchers) +are bindable; for example, recordDecl(hasName("MyClass")).bind("id") will bind +the matched recordDecl node to the string "id", to be later retrieved in the +<a href="http://clang.llvm.org/doxygen/classclang_1_1ast__matchers_1_1MatchFinder_1_1MatchCallback.html">match callback</a>.</p> + +<!-- FIXME: Introduce link to ASTMatchersTutorial.html --> +<!-- FIXME: Introduce link to ASTMatchersCookbook.html --> + +<!-- ======================================================================= --> +<h2 id="writing">Writing your own matchers</h2> +<!-- ======================================================================= --> + +<p>There are multiple different ways to define a matcher, depending on its +type and flexibility.</p> +<ul> +<li><b>VariadicDynCastAllOfMatcher<Base, Derived></b><p>Those match all nodes +of type <i>Base</i> if they can be dynamically casted to <i>Derived</i>. The +names of those matchers are nouns, which closely resemble <i>Derived</i>. +VariadicDynCastAllOfMatchers are the backbone of the matcher hierarchy. Most +often, your match expression will start with one of them, and you can +<a href="#binding">bind</a> the node they represent to ids for later processing.</p> +<p>VariadicDynCastAllOfMatchers are callable classes that model variadic +template functions in C++03. They take an aribtrary number of Matcher<Derived> +and return a Matcher<Base>.</p></li> +<li><b>AST_MATCHER_P(Type, Name, ParamType, Param)</b><p> Most matcher definitions +use the matcher creation macros. Those define both the matcher of type Matcher<Type> +itself, and a matcher-creation function named <i>Name</i> that takes a parameter +of type <i>ParamType</i> and returns the corresponding matcher.</p> +<p>There are multiple matcher definition macros that deal with polymorphic return +values and different parameter counts. See <a href="http://clang.llvm.org/doxygen/ASTMatchersMacros_8h.html">ASTMatchersMacros.h</a>. +</p></li> +<li><b>Matcher creation functions</b><p>Matchers are generated by nesting +calls to matcher creation functions. Most of the time those functions are either +created by using VariadicDynCastAllOfMatcher or the matcher creation macros +(see below). The free-standing functions are an indication that this matcher +is just a combination of other matchers, as is for example the case with +<a href="LibASTMatchersReference.html#callee1Anchor">callee</a>.</p></li> +</ul> + +</div> +</body> +</html> + diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html new file mode 100644 index 0000000..ea038e3 --- /dev/null +++ b/docs/LibASTMatchersReference.html @@ -0,0 +1,1938 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> +<title>AST Matcher Reference</title> +<link type="text/css" rel="stylesheet" href="../menu.css" /> +<link type="text/css" rel="stylesheet" href="../content.css" /> +<style type="text/css"> +td { + padding: .33em; +} +td.doc { + display: none; + border-bottom: 1px solid black; +} +td.name:hover { + color: blue; + cursor: pointer; +} +</style> +<script type="text/javascript"> +function toggle(id) { + if (!id) return; + row = document.getElementById(id); + if (row.style.display != 'table-cell') + row.style.display = 'table-cell'; + else + row.style.display = 'none'; +} +</script> +</head> +<body onLoad="toggle(location.hash.substring(1, location.hash.length - 6))"> + +<!--#include virtual="../menu.html.incl"--> + +<div id="content"> + +<h1>AST Matcher Reference</h1> + +<p>This document shows all currently implemented matchers. The matchers are grouped +by category and node type they match. You can click on matcher names to show the +matcher's source documentation.</p> + +<p>There are three different basic categories of matchers: +<ul> +<li><a href="#decl-matchers">Node Matchers:</a> Matchers that match a specific type of AST node.</li> +<li><a href="#narrowing-matchers">Narrowing Matchers:</a> Matchers that match attributes on AST nodes.</li> +<li><a href="#traversal-matchers">Traversal Matchers:</a> Matchers that allow traversal between AST nodes.</li> +</ul> +</p> + +<p>Within each category the matchers are ordered by node type they match on. +Note that if a matcher can match multiple node types, it will it will appear +multiple times. This means that by searching for Matcher<Stmt> you can +find all matchers that can be used to match on Stmt nodes.</p> + +<p>The exception to that rule are matchers that can match on any node. Those +are marked with a * and are listed in the beginning of each category.</p> + +<!-- ======================================================================= --> +<h2 id="decl-matchers">Node Matchers</h2> +<!-- ======================================================================= --> + +<p>Node matchers are at the core of matcher expressions - they specify the type +of node that is expected. Every match expression starts with a node matcher, +which can then be further refined with a narrowing or traversal matcher. All +traversal matchers take node matchers as their arguments.</p> + +<p>For convenience, all node matchers take an arbitrary number of arguments +and implicitly act as allOf matchers.</p> + +<p>Node matchers are the only matchers that support the bind("id") call to +bind the matched node to the given string, to be later retrieved from the +match callback.</p> + +<table> +<tr style="text-align:left"><th>Return type</th><th>Name</th><th>Parameters</th></tr> +<!-- START_DECL_MATCHERS --> + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('classTemplateDecl0')"><a name="classTemplateDecl0Anchor">classTemplateDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ClassTemplateDecl.html">ClassTemplateDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="classTemplateDecl0"><pre>Matches C++ class template declarations. + +Example matches Z + template<class T> class Z {}; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('classTemplateSpecializationDecl0')"><a name="classTemplateSpecializationDecl0Anchor">classTemplateSpecializationDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="classTemplateSpecializationDecl0"><pre>Matches C++ class template specializations. + +Given + template<typename T> class A {}; + template<> class A<double> {}; + A<int> a; +classTemplateSpecializationDecl() + matches the specializations A<int> and A<double> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('constructorDecl0')"><a name="constructorDecl0Anchor">constructorDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="constructorDecl0"><pre>Matches C++ constructor declarations. + +Example matches Foo::Foo() and Foo::Foo(int) + class Foo { + public: + Foo(); + Foo(int); + int DoSomething(); + }; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('decl0')"><a name="decl0Anchor">decl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="decl0"><pre>Matches declarations. + +Examples matches X, C, and the friend declaration inside C; + void X(); + class C { + friend X; + }; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('destructorDecl0')"><a name="destructorDecl0Anchor">destructorDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXDestructorDecl.html">CXXDestructorDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="destructorDecl0"><pre>Matches explicit C++ destructor declarations. + +Example matches Foo::~Foo() + class Foo { + public: + virtual ~Foo(); + }; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('enumConstantDecl0')"><a name="enumConstantDecl0Anchor">enumConstantDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumConstantDecl.html">EnumConstantDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="enumConstantDecl0"><pre>Matches enum constants. + +Example matches A, B, C + enum X { + A, B, C + }; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('enumDecl0')"><a name="enumDecl0Anchor">enumDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumDecl.html">EnumDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="enumDecl0"><pre>Matches enum declarations. + +Example matches X + enum X { + A, B, C + }; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('fieldDecl0')"><a name="fieldDecl0Anchor">fieldDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FieldDecl.html">FieldDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="fieldDecl0"><pre>Matches field declarations. + +Given + class X { int m; }; +fieldDecl() + matches 'm'. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('functionDecl0')"><a name="functionDecl0Anchor">functionDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="functionDecl0"><pre>Matches function declarations. + +Example matches f + void f(); +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('functionTemplateDecl0')"><a name="functionTemplateDecl0Anchor">functionTemplateDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionTemplateDecl.html">FunctionTemplateDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="functionTemplateDecl0"><pre>Matches C++ function template declarations. + +Example matches f + template<class T> void f(T t) {} +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('methodDecl0')"><a name="methodDecl0Anchor">methodDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="methodDecl0"><pre>Matches method declarations. + +Example matches y + class X { void y() }; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('namedDecl0')"><a name="namedDecl0Anchor">namedDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="namedDecl0"><pre>Matches a declaration of anything that could have a name. + +Example matches X, S, the anonymous union type, i, and U; + typedef int X; + struct S { + union { + int i; + } U; + }; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('recordDecl0')"><a name="recordDecl0Anchor">recordDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="recordDecl0"><pre>Matches C++ class declarations. + +Example matches X, Z + class X; + template<class T> class Z {}; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('usingDecl0')"><a name="usingDecl0Anchor">usingDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UsingDecl.html">UsingDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="usingDecl0"><pre>Matches using declarations. + +Given + namespace X { int x; } + using X::x; +usingDecl() + matches using X::x </pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('varDecl0')"><a name="varDecl0Anchor">varDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="varDecl0"><pre>Matches variable declarations. + +Note: this does not match declarations of member variables, which are +"field" declarations in Clang parlance. + +Example matches a + int a; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('boolLiteral0')"><a name="boolLiteral0Anchor">boolLiteral</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBoolLiteralExpr.html">CXXBoolLiteralExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="boolLiteral0"><pre>Matches bool literals. + +Example matches true + true +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('castExpr0')"><a name="castExpr0Anchor">castExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CastExpr.html">CastExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="castExpr0"><pre>Matches any cast nodes of Clang's AST. + +Example: castExpr() matches each of the following: + (int) 3; + const_cast<Expr *>(SubExpr); + char c = 0; +but does not match + int i = (0); + int k = 0; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('characterLiteral0')"><a name="characterLiteral0Anchor">characterLiteral</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="characterLiteral0"><pre>Matches character literals (also matches wchar_t). + +Not matching Hex-encoded chars (e.g. 0x1234, which is a IntegerLiteral), +though. + +Example matches 'a', L'a' + char ch = 'a'; wchar_t chw = L'a'; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('constCastExpr0')"><a name="constCastExpr0Anchor">constCastExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstCastExpr.html">CXXConstCastExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="constCastExpr0"><pre>Matches a const_cast expression. + +Example: Matches const_cast<int*>(&r) in + int n = 42; + const int &r(n); + int* p = const_cast<int*>(&r); +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('dynamicCastExpr0')"><a name="dynamicCastExpr0Anchor">dynamicCastExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXDynamicCastExpr.html">CXXDynamicCastExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="dynamicCastExpr0"><pre>Matches a dynamic_cast expression. + +Example: + dynamicCastExpr() +matches + dynamic_cast<D*>(&b); +in + struct B { virtual ~B() {} }; struct D : B {}; + B b; + D* p = dynamic_cast<D*>(&b); +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('explicitCastExpr0')"><a name="explicitCastExpr0Anchor">explicitCastExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="explicitCastExpr0"><pre>Matches explicit cast expressions. + +Matches any cast expression written in user code, whether it be a +C-style cast, a functional-style cast, or a keyword cast. + +Does not match implicit conversions. + +Note: the name "explicitCast" is chosen to match Clang's terminology, as +Clang uses the term "cast" to apply to implicit conversions as well as to +actual cast expressions. + +hasDestinationType. + +Example: matches all five of the casts in + int((int)(reinterpret_cast<int>(static_cast<int>(const_cast<int>(42))))) +but does not match the implicit conversion in + long ell = 42; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('functionalCastExpr0')"><a name="functionalCastExpr0Anchor">functionalCastExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXFunctionalCastExpr.html">CXXFunctionalCastExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="functionalCastExpr0"><pre>Matches functional cast expressions + +Example: Matches Foo(bar); + Foo f = bar; + Foo g = (Foo) bar; + Foo h = Foo(bar); +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('implicitCastExpr0')"><a name="implicitCastExpr0Anchor">implicitCastExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ImplicitCastExpr.html">ImplicitCastExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="implicitCastExpr0"><pre>Matches the implicit cast nodes of Clang's AST. + +This matches many different places, including function call return value +eliding, as well as any type conversions. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('integerLiteral0')"><a name="integerLiteral0Anchor">integerLiteral</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="integerLiteral0"><pre>Matches integer literals of all sizes encodings. + +Not matching character-encoded integers such as L'a'. + +Example matches 1, 1L, 0x1, 1U +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('reinterpretCastExpr0')"><a name="reinterpretCastExpr0Anchor">reinterpretCastExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXReinterpretCastExpr.html">CXXReinterpretCastExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="reinterpretCastExpr0"><pre>Matches a reinterpret_cast expression. + +Either the source expression or the destination type can be matched +using has(), but hasDestinationType() is more specific and can be +more readable. + +Example matches reinterpret_cast<char*>(&p) in + void* p = reinterpret_cast<char*>(&p); +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('staticCastExpr0')"><a name="staticCastExpr0Anchor">staticCastExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXStaticCastExpr.html">CXXStaticCastExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="staticCastExpr0"><pre>Matches a C++ static_cast expression. + +hasDestinationType +reinterpretCast + +Example: + staticCastExpr() +matches + static_cast<long>(8) +in + long eight(static_cast<long>(8)); +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('stringLiteral0')"><a name="stringLiteral0Anchor">stringLiteral</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1StringLiteral.html">StringLiteral</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="stringLiteral0"><pre>Matches string literals (also matches wide string literals). + +Example matches "abcd", L"abcd" + char *s = "abcd"; wchar_t *ws = L"abcd" +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('arraySubscriptExpr0')"><a name="arraySubscriptExpr0Anchor">arraySubscriptExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ArraySubscriptExpr.html">ArraySubscriptExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="arraySubscriptExpr0"><pre>Matches array subscript expressions. + +Given + int i = a[1]; +arraySubscriptExpr() + matches "a[1]" +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('binaryOperator0')"><a name="binaryOperator0Anchor">binaryOperator</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html">BinaryOperator</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="binaryOperator0"><pre>Matches binary operator expressions. + +Example matches a || b + !(a || b) +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('bindTemporaryExpr0')"><a name="bindTemporaryExpr0Anchor">bindTemporaryExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBindTemporaryExpr.html">CXXBindTemporaryExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="bindTemporaryExpr0"><pre>Matches nodes where temporaries are created. + +Example matches FunctionTakesString(GetStringByValue()) + (matcher = bindTemporaryExpr()) + FunctionTakesString(GetStringByValue()); + FunctionTakesStringByPointer(GetStringPointer()); +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('callExpr0')"><a name="callExpr0Anchor">callExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="callExpr0"><pre>Matches call expressions. + +Example matches x.y() and y() + X x; + x.y(); + y(); +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('compoundStmt0')"><a name="compoundStmt0Anchor">compoundStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CompoundStmt.html">CompoundStmt</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="compoundStmt0"><pre>Matches compound statements. + +Example matches '{}' and '{{}}'in 'for (;;) {{}}' + for (;;) {{}} +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('conditionalOperator0')"><a name="conditionalOperator0Anchor">conditionalOperator</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ConditionalOperator.html">ConditionalOperator</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="conditionalOperator0"><pre>Matches conditional operator expressions. + +Example matches a ? b : c + (a ? b : c) + 42 +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('constructExpr0')"><a name="constructExpr0Anchor">constructExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="constructExpr0"><pre>Matches constructor call expressions (including implicit ones). + +Example matches string(ptr, n) and ptr within arguments of f + (matcher = constructExpr()) + void f(const string &a, const string &b); + char *ptr; + int n; + f(string(ptr, n), ptr); +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('declRefExpr0')"><a name="declRefExpr0Anchor">declRefExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="declRefExpr0"><pre>Matches expressions that refer to declarations. + +Example matches x in if (x) + bool x; + if (x) {} +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('declStmt0')"><a name="declStmt0Anchor">declStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclStmt.html">DeclStmt</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="declStmt0"><pre>Matches declaration statements. + +Given + int a; +declStmt() + matches 'int a'. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('defaultArgExpr0')"><a name="defaultArgExpr0Anchor">defaultArgExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXDefaultArgExpr.html">CXXDefaultArgExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="defaultArgExpr0"><pre>Matches the value of a default argument at the call site. + +Example matches the CXXDefaultArgExpr placeholder inserted for the + default value of the second parameter in the call expression f(42) + (matcher = defaultArgExpr()) + void f(int x, int y = 0); + f(42); +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('deleteExpr0')"><a name="deleteExpr0Anchor">deleteExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXDeleteExpr.html">CXXDeleteExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="deleteExpr0"><pre>Matches delete expressions. + +Given + delete X; +deleteExpr() + matches 'delete X'. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('doStmt0')"><a name="doStmt0Anchor">doStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DoStmt.html">DoStmt</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="doStmt0"><pre>Matches do statements. + +Given + do {} while (true); +doStmt() + matches 'do {} while(true)' +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('expr0')"><a name="expr0Anchor">expr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="expr0"><pre>Matches expressions. + +Example matches x() + void f() { x(); } +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('forStmt0')"><a name="forStmt0Anchor">forStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ForStmt.html">ForStmt</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="forStmt0"><pre>Matches for statements. + +Example matches 'for (;;) {}' + for (;;) {} +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('ifStmt0')"><a name="ifStmt0Anchor">ifStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IfStmt.html">IfStmt</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="ifStmt0"><pre>Matches if statements. + +Example matches 'if (x) {}' + if (x) {} +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('initListExpr0')"><a name="initListExpr0Anchor">initListExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1InitListExpr.html">InitListExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="initListExpr0"><pre>Matches init list expressions. + +Given + int a[] = { 1, 2 }; + struct B { int x, y; }; + B b = { 5, 6 }; +initList() + matches "{ 1, 2 }" and "{ 5, 6 }" +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('materializeTemporaryExpr0')"><a name="materializeTemporaryExpr0Anchor">materializeTemporaryExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MaterializeTemporaryExpr.html">MaterializeTemporaryExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="materializeTemporaryExpr0"><pre>Matches nodes where temporaries are materialized. + +Example: Given + struct T {void func()}; + T f(); + void g(T); +materializeTemporaryExpr() matches 'f()' in these statements + T u(f()); + g(f()); +but does not match + f(); + f().func(); +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('memberCallExpr0')"><a name="memberCallExpr0Anchor">memberCallExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="memberCallExpr0"><pre>Matches member call expressions. + +Example matches x.y() + X x; + x.y(); +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('memberExpr0')"><a name="memberExpr0Anchor">memberExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="memberExpr0"><pre>Matches member expressions. + +Given + class Y { + void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; } + int a; static int b; + }; +memberExpr() + matches this->x, x, y.x, a, this->b +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('newExpr0')"><a name="newExpr0Anchor">newExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="newExpr0"><pre>Matches new expressions. + +Given + new X; +newExpr() + matches 'new X'. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('operatorCallExpr0')"><a name="operatorCallExpr0Anchor">operatorCallExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html">CXXOperatorCallExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="operatorCallExpr0"><pre>Matches overloaded operator calls. + +Note that if an operator isn't overloaded, it won't match. Instead, use +binaryOperator matcher. +Currently it does not match operators such as new delete. +FIXME: figure out why these do not match? + +Example matches both operator<<((o << b), c) and operator<<(o, b) + (matcher = operatorCallExpr()) + ostream &operator<< (ostream &out, int i) { }; + ostream &o; int b = 1, c = 1; + o << b << c; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('stmt0')"><a name="stmt0Anchor">stmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="stmt0"><pre>Matches statements. + +Given + { ++a; } +stmt() + matches both the compound statement '{ ++a; }' and '++a'. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('switchCase0')"><a name="switchCase0Anchor">switchCase</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1SwitchCase.html">SwitchCase</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="switchCase0"><pre>Matches case and default statements inside switch statements. + +Given + switch(a) { case 42: break; default: break; } +switchCase() + matches 'case 42: break;' and 'default: break;'. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('unaryExprOrTypeTraitExpr0')"><a name="unaryExprOrTypeTraitExpr0Anchor">unaryExprOrTypeTraitExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html">UnaryExprOrTypeTraitExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="unaryExprOrTypeTraitExpr0"><pre>Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL) + +Given + Foo x = bar; + int y = sizeof(x) + alignof(x); +unaryExprOrTypeTraitExpr() + matches sizeof(x) and alignof(x) +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('unaryOperator0')"><a name="unaryOperator0Anchor">unaryOperator</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnaryOperator.html">UnaryOperator</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="unaryOperator0"><pre>Matches unary operator expressions. + +Example matches !a + !a || b +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('whileStmt0')"><a name="whileStmt0Anchor">whileStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1WhileStmt.html">WhileStmt</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="whileStmt0"><pre>Matches while statements. + +Given + while (true) {} +whileStmt() + matches 'while (true) {}'. +</pre></td></tr> + +<!--END_DECL_MATCHERS --> +</table> + +<!-- ======================================================================= --> +<h2 id="narrowing-matchers">Narrowing Matchers</h2> +<!-- ======================================================================= --> + +<p>Narrowing matchers match certain attributes on the current node, thus +narrowing down the set of nodes of the current type to match on.</p> + +<p>There are special logical narrowing matchers (allOf, anyOf, anything and unless) +which allow users to create more powerful match expressions.</p> + +<table> +<tr style="text-align:left"><th>Return type</th><th>Name</th><th>Parameters</th></tr> +<!-- START_NARROWING_MATCHERS --> + +<tr><td>Matcher<*></td><td class="name" onclick="toggle('allOf0')"><a name="allOf0Anchor">allOf</a></td><td>Matcher<*> P1, Matcher<*> P2</td></tr> +<tr><td colspan="4" class="doc" id="allOf0"><pre>Matches if all given matchers match. + +Usable as: Any Matcher +</pre></td></tr> + + +<tr><td>Matcher<*></td><td class="name" onclick="toggle('anyOf0')"><a name="anyOf0Anchor">anyOf</a></td><td>Matcher<*> P1, Matcher<*> P2</td></tr> +<tr><td colspan="4" class="doc" id="anyOf0"><pre>Matches if any of the given matchers matches. + +Usable as: Any Matcher +</pre></td></tr> + + +<tr><td>Matcher<*></td><td class="name" onclick="toggle('anything0')"><a name="anything0Anchor">anything</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="anything0"><pre>Matches any node. + +Useful when another matcher requires a child matcher, but there's no +additional constraint. This will often be used with an explicit conversion +to an internal::Matcher<> type such as TypeMatcher. + +Example: DeclarationMatcher(anything()) matches all declarations, e.g., +"int* p" and "void f()" in + int* p; + void f(); + +Usable as: Any Matcher +</pre></td></tr> + + +<tr><td>Matcher<*></td><td class="name" onclick="toggle('unless0')"><a name="unless0Anchor">unless</a></td><td>Matcher<*> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="unless0"><pre>Matches if the provided matcher does not match. + +Example matches Y (matcher = recordDecl(unless(hasName("X")))) + class X {}; + class Y {}; + +Usable as: Any Matcher +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html">BinaryOperator</a>></td><td class="name" onclick="toggle('hasOperatorName0')"><a name="hasOperatorName0Anchor">hasOperatorName</a></td><td>std::string Name</td></tr> +<tr><td colspan="4" class="doc" id="hasOperatorName0"><pre>Matches the operator Name of operator expressions (binary or +unary). + +Example matches a || b (matcher = binaryOperator(hasOperatorName("||"))) + !(a || b) +</pre></td></tr> + + +<tr><td>Matcher<CXXBoolLiteral></td><td class="name" onclick="toggle('equals2')"><a name="equals2Anchor">equals</a></td><td>ValueT Value</td></tr> +<tr><td colspan="4" class="doc" id="equals2"><pre>Matches literals that are equal to the given value. + +Example matches true (matcher = boolLiteral(equals(true))) + true + +Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<CXXBoolLiteral>, + Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>></td><td class="name" onclick="toggle('isImplicit0')"><a name="isImplicit0Anchor">isImplicit</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isImplicit0"><pre>Matches a constructor declaration that has been implicitly added +by the compiler (eg. implicit defaultcopy constructors). +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>></td><td class="name" onclick="toggle('isWritten0')"><a name="isWritten0Anchor">isWritten</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isWritten0"><pre>Matches a contructor initializer if it is explicitly written in +code (as opposed to implicitly added by the compiler). + +Given + struct Foo { + Foo() { } + Foo(int) : foo_("A") { } + string foo_; + }; +constructorDecl(hasAnyConstructorInitializer(isWritten())) + will match Foo(int), but not Foo() +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html">CXXOperatorCallExpr</a>></td><td class="name" onclick="toggle('hasOverloadedOperatorName0')"><a name="hasOverloadedOperatorName0Anchor">hasOverloadedOperatorName</a></td><td>std::string Name</td></tr> +<tr><td colspan="4" class="doc" id="hasOverloadedOperatorName0"><pre>Matches overloaded operator names. + +Matches overloaded operator names specified in strings without the +"operator" prefix, such as "<<", for OverloadedOperatorCall's. + +Example matches a << b + (matcher == operatorCallExpr(hasOverloadedOperatorName("<<"))) + a << b; + c && d; assuming both operator<< + and operator&& are overloaded somewhere. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>></td><td class="name" onclick="toggle('isA1')"><a name="isA1Anchor">isA</a></td><td>StringRef BaseName</td></tr> +<tr><td colspan="4" class="doc" id="isA1"><pre>Overloaded method as shortcut for isA(hasName(...)). +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>></td><td class="name" onclick="toggle('isDerivedFrom1')"><a name="isDerivedFrom1Anchor">isDerivedFrom</a></td><td>StringRef BaseName</td></tr> +<tr><td colspan="4" class="doc" id="isDerivedFrom1"><pre>Overloaded method as shortcut for isDerivedFrom(hasName(...)). +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>></td><td class="name" onclick="toggle('isExplicitTemplateSpecialization0')"><a name="isExplicitTemplateSpecialization0Anchor">isExplicitTemplateSpecialization</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isExplicitTemplateSpecialization0"><pre>Matches explicit template specializations of function, class, or +static member variable template instantiations. + +Given + template<typename T> void A(T t) { } + template<> void A(int N) { } +functionDecl(isExplicitTemplateSpecialization()) + matches the specialization A<int>(). + +Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>></td><td class="name" onclick="toggle('isTemplateInstantiation0')"><a name="isTemplateInstantiation0Anchor">isTemplateInstantiation</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isTemplateInstantiation0"><pre>Matches template instantiations of function, class, or static +member variable template instantiations. + +Given + template <typename T> class X {}; class A {}; X<A> x; +or + template <typename T> class X {}; class A {}; template class X<A>; +recordDecl(hasName("::X"), isTemplateInstantiation()) + matches the template instantiation of X<A>. + +But given + template <typename T> class X {}; class A {}; + template <> class X<A> {}; X<A> x; +recordDecl(hasName("::X"), isTemplateInstantiation()) + does not match, as X<A> is an explicit template specialization. + +Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>></td><td class="name" onclick="toggle('argumentCountIs0')"><a name="argumentCountIs0Anchor">argumentCountIs</a></td><td>unsigned N</td></tr> +<tr><td colspan="4" class="doc" id="argumentCountIs0"><pre>Checks that a call expression or a constructor call expression has +a specific number of arguments (including absent default arguments). + +Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2))) + void f(int x, int y); + f(0, 0); +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>></td><td class="name" onclick="toggle('equals3')"><a name="equals3Anchor">equals</a></td><td>ValueT Value</td></tr> +<tr><td colspan="4" class="doc" id="equals3"><pre>Matches literals that are equal to the given value. + +Example matches true (matcher = boolLiteral(equals(true))) + true + +Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<CXXBoolLiteral>, + Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CompoundStmt.html">CompoundStmt</a>></td><td class="name" onclick="toggle('statementCountIs0')"><a name="statementCountIs0Anchor">statementCountIs</a></td><td>unsigned N</td></tr> +<tr><td colspan="4" class="doc" id="statementCountIs0"><pre>Checks that a compound statement contains a specific number of +child statements. + +Example: Given + { for (;;) {} } +compoundStmt(statementCountIs(0))) + matches '{}' + but does not match the outer compound statement. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclStmt.html">DeclStmt</a>></td><td class="name" onclick="toggle('declCountIs0')"><a name="declCountIs0Anchor">declCountIs</a></td><td>unsigned N</td></tr> +<tr><td colspan="4" class="doc" id="declCountIs0"><pre>Matches declaration statements that contain a specific number of +declarations. + +Example: Given + int a, b; + int c; + int d = 2, e; +declCountIs(2) + matches 'int a, b;' and 'int d = 2, e;', but not 'int c;'. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>></td><td class="name" onclick="toggle('equals1')"><a name="equals1Anchor">equals</a></td><td>ValueT Value</td></tr> +<tr><td colspan="4" class="doc" id="equals1"><pre>Matches literals that are equal to the given value. + +Example matches true (matcher = boolLiteral(equals(true))) + true + +Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<CXXBoolLiteral>, + Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('isDefinition0')"><a name="isDefinition0Anchor">isDefinition</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isDefinition0"><pre>Matches if a declaration has a body attached. + +Example matches A, va, fa + class A {}; + class B; Doesn't match, as it has no body. + int va; + extern int vb; Doesn't match, as it doesn't define the variable. + void fa() {} + void fb(); Doesn't match, as it has no body. + +Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagDecl.html">TagDecl</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('isExplicitTemplateSpecialization2')"><a name="isExplicitTemplateSpecialization2Anchor">isExplicitTemplateSpecialization</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isExplicitTemplateSpecialization2"><pre>Matches explicit template specializations of function, class, or +static member variable template instantiations. + +Given + template<typename T> void A(T t) { } + template<> void A(int N) { } +functionDecl(isExplicitTemplateSpecialization()) + matches the specialization A<int>(). + +Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('isExternC0')"><a name="isExternC0Anchor">isExternC</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isExternC0"><pre>Matches extern "C" function declarations. + +Given: + extern "C" void f() {} + extern "C" { void g() {} } + void h() {} +functionDecl(isExternC()) + matches the declaration of f and g, but not the declaration h +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('isTemplateInstantiation2')"><a name="isTemplateInstantiation2Anchor">isTemplateInstantiation</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isTemplateInstantiation2"><pre>Matches template instantiations of function, class, or static +member variable template instantiations. + +Given + template <typename T> class X {}; class A {}; X<A> x; +or + template <typename T> class X {}; class A {}; template class X<A>; +recordDecl(hasName("::X"), isTemplateInstantiation()) + matches the template instantiation of X<A>. + +But given + template <typename T> class X {}; class A {}; + template <> class X<A> {}; X<A> x; +recordDecl(hasName("::X"), isTemplateInstantiation()) + does not match, as X<A> is an explicit template specialization. + +Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>></td><td class="name" onclick="toggle('equals0')"><a name="equals0Anchor">equals</a></td><td>ValueT Value</td></tr> +<tr><td colspan="4" class="doc" id="equals0"><pre>Matches literals that are equal to the given value. + +Example matches true (matcher = boolLiteral(equals(true))) + true + +Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<CXXBoolLiteral>, + Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>></td><td class="name" onclick="toggle('isArrow0')"><a name="isArrow0Anchor">isArrow</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isArrow0"><pre>Matches member expressions that are called with '->' as opposed +to '.'. + +Member calls on the implicit this pointer match as called with '->'. + +Given + class Y { + void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; } + int a; + static int b; + }; +memberExpr(isArrow()) + matches this->x, x, y.x, a, this->b +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>></td><td class="name" onclick="toggle('hasName0')"><a name="hasName0Anchor">hasName</a></td><td>std::string Name</td></tr> +<tr><td colspan="4" class="doc" id="hasName0"><pre>Matches NamedDecl nodes that have the specified name. + +Supports specifying enclosing namespaces or classes by prefixing the name +with '<enclosing>::'. +Does not match typedefs of an underlying type with the given name. + +Example matches X (Name == "X") + class X; + +Example matches X (Name is one of "::a::b::X", "a::b::X", "b::X", "X") + namespace a { namespace b { class X; } } +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>></td><td class="name" onclick="toggle('matchesName0')"><a name="matchesName0Anchor">matchesName</a></td><td>std::string RegExp</td></tr> +<tr><td colspan="4" class="doc" id="matchesName0"><pre>Matches NamedDecl nodes whose full names partially match the +given RegExp. + +Supports specifying enclosing namespaces or classes by +prefixing the name with '<enclosing>::'. Does not match typedefs +of an underlying type with the given name. + +Example matches X (regexp == "::X") + class X; + +Example matches X (regexp is one of "::X", "^foo::.*X", among others) + namespace foo { namespace bar { class X; } } +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>></td><td class="name" onclick="toggle('asString0')"><a name="asString0Anchor">asString</a></td><td>std::string Name</td></tr> +<tr><td colspan="4" class="doc" id="asString0"><pre>Matches if the matched type is represented by the given string. + +Given + class Y { public: void x(); }; + void z() { Y* y; y->x(); } +callExpr(on(hasType(asString("class Y *")))) + matches y->x() +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>></td><td class="name" onclick="toggle('isConstQualified0')"><a name="isConstQualified0Anchor">isConstQualified</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isConstQualified0"><pre>Matches QualType nodes that are const-qualified, i.e., that +include "top-level" const. + +Given + void a(int); + void b(int const); + void c(const int); + void d(const int*); + void e(int const) {}; +functionDecl(hasAnyParameter(hasType(isConstQualified()))) + matches "void b(int const)", "void c(const int)" and + "void e(int const) {}". It does not match d as there + is no top-level const on the parameter type "const int *". +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>></td><td class="name" onclick="toggle('isInteger0')"><a name="isInteger0Anchor">isInteger</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isInteger0"><pre>Matches QualType nodes that are of integer type. + +Given + void a(int); + void b(long); + void c(double); +functionDecl(hasAnyParameter(hasType(isInteger()))) +matches "a(int)", "b(long)", but not "c(double)". +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagDecl.html">TagDecl</a>></td><td class="name" onclick="toggle('isDefinition2')"><a name="isDefinition2Anchor">isDefinition</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isDefinition2"><pre>Matches if a declaration has a body attached. + +Example matches A, va, fa + class A {}; + class B; Doesn't match, as it has no body. + int va; + extern int vb; Doesn't match, as it doesn't define the variable. + void fa() {} + void fb(); Doesn't match, as it has no body. + +Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagDecl.html">TagDecl</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html">UnaryExprOrTypeTraitExpr</a>></td><td class="name" onclick="toggle('ofKind0')"><a name="ofKind0Anchor">ofKind</a></td><td>UnaryExprOrTypeTrait Kind</td></tr> +<tr><td colspan="4" class="doc" id="ofKind0"><pre>Matches unary expressions of a certain kind. + +Given + int x; + int s = sizeof(x) + alignof(x) +unaryExprOrTypeTraitExpr(ofKind(UETT_SizeOf)) + matches sizeof(x) +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnaryOperator.html">UnaryOperator</a>></td><td class="name" onclick="toggle('hasOperatorName1')"><a name="hasOperatorName1Anchor">hasOperatorName</a></td><td>std::string Name</td></tr> +<tr><td colspan="4" class="doc" id="hasOperatorName1"><pre>Matches the operator Name of operator expressions (binary or +unary). + +Example matches a || b (matcher = binaryOperator(hasOperatorName("||"))) + !(a || b) +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>></td><td class="name" onclick="toggle('isDefinition1')"><a name="isDefinition1Anchor">isDefinition</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isDefinition1"><pre>Matches if a declaration has a body attached. + +Example matches A, va, fa + class A {}; + class B; Doesn't match, as it has no body. + int va; + extern int vb; Doesn't match, as it doesn't define the variable. + void fa() {} + void fb(); Doesn't match, as it has no body. + +Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagDecl.html">TagDecl</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>></td><td class="name" onclick="toggle('isExplicitTemplateSpecialization1')"><a name="isExplicitTemplateSpecialization1Anchor">isExplicitTemplateSpecialization</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isExplicitTemplateSpecialization1"><pre>Matches explicit template specializations of function, class, or +static member variable template instantiations. + +Given + template<typename T> void A(T t) { } + template<> void A(int N) { } +functionDecl(isExplicitTemplateSpecialization()) + matches the specialization A<int>(). + +Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>></td><td class="name" onclick="toggle('isTemplateInstantiation1')"><a name="isTemplateInstantiation1Anchor">isTemplateInstantiation</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isTemplateInstantiation1"><pre>Matches template instantiations of function, class, or static +member variable template instantiations. + +Given + template <typename T> class X {}; class A {}; X<A> x; +or + template <typename T> class X {}; class A {}; template class X<A>; +recordDecl(hasName("::X"), isTemplateInstantiation()) + matches the template instantiation of X<A>. + +But given + template <typename T> class X {}; class A {}; + template <> class X<A> {}; X<A> x; +recordDecl(hasName("::X"), isTemplateInstantiation()) + does not match, as X<A> is an explicit template specialization. + +Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>> +</pre></td></tr> + +<!--END_NARROWING_MATCHERS --> +</table> + +<!-- ======================================================================= --> +<h2 id="traversal-matchers">AST Traversal Matchers</h2> +<!-- ======================================================================= --> + +<p>Traversal matchers specify the relationship to other nodes that are +reachable from the current node.</p> + +<p>Note that there are special traversal matchers (has, hasDescendant, forEach and +forEachDescendant) which work on all nodes and allow users to write more generic +match expressions.</p> + +<table> +<tr style="text-align:left"><th>Return type</th><th>Name</th><th>Parameters</th></tr> +<!-- START_TRAVERSAL_MATCHERS --> + +<tr><td>Matcher<*></td><td class="name" onclick="toggle('forEach0')"><a name="forEach0Anchor">forEach</a></td><td>Matcher<ChildT> ChildMatcher</td></tr> +<tr><td colspan="4" class="doc" id="forEach0"><pre>Matches AST nodes that have child AST nodes that match the +provided matcher. + +Example matches X, Y (matcher = recordDecl(forEach(recordDecl(hasName("X"))) + class X {}; Matches X, because X::X is a class of name X inside X. + class Y { class X {}; }; + class Z { class Y { class X {}; }; }; Does not match Z. + +ChildT must be an AST base type. + +As opposed to 'has', 'forEach' will cause a match for each result that +matches instead of only on the first one. + +Usable as: Any Matcher +</pre></td></tr> + + +<tr><td>Matcher<*></td><td class="name" onclick="toggle('forEachDescendant0')"><a name="forEachDescendant0Anchor">forEachDescendant</a></td><td>Matcher<DescendantT> DescendantMatcher</td></tr> +<tr><td colspan="4" class="doc" id="forEachDescendant0"><pre>Matches AST nodes that have descendant AST nodes that match the +provided matcher. + +Example matches X, A, B, C + (matcher = recordDecl(forEachDescendant(recordDecl(hasName("X"))))) + class X {}; Matches X, because X::X is a class of name X inside X. + class A { class X {}; }; + class B { class C { class X {}; }; }; + +DescendantT must be an AST base type. + +As opposed to 'hasDescendant', 'forEachDescendant' will cause a match for +each result that matches instead of only on the first one. + +Note: Recursively combined ForEachDescendant can cause many matches: + recordDecl(forEachDescendant(recordDecl(forEachDescendant(recordDecl())))) +will match 10 times (plus injected class name matches) on: + class A { class B { class C { class D { class E {}; }; }; }; }; + +Usable as: Any Matcher +</pre></td></tr> + + +<tr><td>Matcher<*></td><td class="name" onclick="toggle('has0')"><a name="has0Anchor">has</a></td><td>Matcher<ChildT> ChildMatcher</td></tr> +<tr><td colspan="4" class="doc" id="has0"><pre>Matches AST nodes that have child AST nodes that match the +provided matcher. + +Example matches X, Y (matcher = recordDecl(has(recordDecl(hasName("X"))) + class X {}; Matches X, because X::X is a class of name X inside X. + class Y { class X {}; }; + class Z { class Y { class X {}; }; }; Does not match Z. + +ChildT must be an AST base type. + +Usable as: Any Matcher +</pre></td></tr> + + +<tr><td>Matcher<*></td><td class="name" onclick="toggle('hasAncestor0')"><a name="hasAncestor0Anchor">hasAncestor</a></td><td>Matcher<AncestorT> AncestorMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasAncestor0"><pre>Matches AST nodes that have an ancestor that matches the provided +matcher. + +Given +void f() { if (true) { int x = 42; } } +void g() { for (;;) { int x = 43; } } +expr(integerLiteral(hasAncsestor(ifStmt()))) matches 42, but not 43. + +Usable as: Any Matcher +</pre></td></tr> + + +<tr><td>Matcher<*></td><td class="name" onclick="toggle('hasDescendant0')"><a name="hasDescendant0Anchor">hasDescendant</a></td><td>Matcher<DescendantT> DescendantMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDescendant0"><pre>Matches AST nodes that have descendant AST nodes that match the +provided matcher. + +Example matches X, Y, Z + (matcher = recordDecl(hasDescendant(recordDecl(hasName("X"))))) + class X {}; Matches X, because X::X is a class of name X inside X. + class Y { class X {}; }; + class Z { class Y { class X {}; }; }; + +DescendantT must be an AST base type. + +Usable as: Any Matcher +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ArraySubscriptExpr.html">ArraySubscriptExpr</a>></td><td class="name" onclick="toggle('hasBase0')"><a name="hasBase0Anchor">hasBase</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasBase0"><pre>Matches the base expression of an array subscript expression. + +Given + int i[5]; + void f() { i[1] = 42; } +arraySubscriptExpression(hasBase(implicitCastExpr( + hasSourceExpression(declRefExpr())))) + matches i[1] with the declRefExpr() matching i +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ArraySubscriptExpr.html">ArraySubscriptExpr</a>></td><td class="name" onclick="toggle('hasIndex0')"><a name="hasIndex0Anchor">hasIndex</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasIndex0"><pre>Matches the index expression of an array subscript expression. + +Given + int i[5]; + void f() { i[1] = 42; } +arraySubscriptExpression(hasIndex(integerLiteral())) + matches i[1] with the integerLiteral() matching 1 +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html">BinaryOperator</a>></td><td class="name" onclick="toggle('hasEitherOperand0')"><a name="hasEitherOperand0Anchor">hasEitherOperand</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasEitherOperand0"><pre>Matches if either the left hand side or the right hand side of a +binary operator matches. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html">BinaryOperator</a>></td><td class="name" onclick="toggle('hasLHS0')"><a name="hasLHS0Anchor">hasLHS</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasLHS0"><pre>Matches the left hand side of binary operator expressions. + +Example matches a (matcher = binaryOperator(hasLHS())) + a || b +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html">BinaryOperator</a>></td><td class="name" onclick="toggle('hasRHS0')"><a name="hasRHS0Anchor">hasRHS</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasRHS0"><pre>Matches the right hand side of binary operator expressions. + +Example matches b (matcher = binaryOperator(hasRHS())) + a || b +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>></td><td class="name" onclick="toggle('hasDeclaration0')"><a name="hasDeclaration0Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration0"><pre>Matches a type if the declaration of the type matches the given +matcher. + +Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>></td><td class="name" onclick="toggle('hasAnyConstructorInitializer0')"><a name="hasAnyConstructorInitializer0Anchor">hasAnyConstructorInitializer</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasAnyConstructorInitializer0"><pre>Matches a constructor initializer. + +Given + struct Foo { + Foo() : foo_(1) { } + int foo_; + }; +recordDecl(has(constructorDecl(hasAnyConstructorInitializer(anything())))) + record matches Foo, hasAnyConstructorInitializer matches foo_(1) +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>></td><td class="name" onclick="toggle('forField0')"><a name="forField0Anchor">forField</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FieldDecl.html">FieldDecl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="forField0"><pre>Matches the field declaration of a constructor initializer. + +Given + struct Foo { + Foo() : foo_(1) { } + int foo_; + }; +recordDecl(has(constructorDecl(hasAnyConstructorInitializer( + forField(hasName("foo_")))))) + matches Foo +with forField matching foo_ +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>></td><td class="name" onclick="toggle('withInitializer0')"><a name="withInitializer0Anchor">withInitializer</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="withInitializer0"><pre>Matches the initializer expression of a constructor initializer. + +Given + struct Foo { + Foo() : foo_(1) { } + int foo_; + }; +recordDecl(has(constructorDecl(hasAnyConstructorInitializer( + withInitializer(integerLiteral(equals(1))))))) + matches Foo +with withInitializer matching (1) +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>></td><td class="name" onclick="toggle('on0')"><a name="on0Anchor">on</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="on0"><pre>Matches on the implicit object argument of a member call expression. + +Example matches y.x() (matcher = callExpr(on(hasType(recordDecl(hasName("Y")))))) + class Y { public: void x(); }; + void z() { Y y; y.x(); }", + +FIXME: Overload to allow directly matching types? +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>></td><td class="name" onclick="toggle('onImplicitObjectArgument0')"><a name="onImplicitObjectArgument0Anchor">onImplicitObjectArgument</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="onImplicitObjectArgument0"><pre></pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>></td><td class="name" onclick="toggle('thisPointerType1')"><a name="thisPointerType1Anchor">thisPointerType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="thisPointerType1"><pre>Overloaded to match the type's declaration. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>></td><td class="name" onclick="toggle('ofClass0')"><a name="ofClass0Anchor">ofClass</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="ofClass0"><pre>Matches the class declaration that the given method declaration +belongs to. + +FIXME: Generalize this for other kinds of declarations. +FIXME: What other kind of declarations would we need to generalize +this to? + +Example matches A() in the last line + (matcher = constructExpr(hasDeclaration(methodDecl( + ofClass(hasName("A")))))) + class A { + public: + A(); + }; + A a = A(); +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>></td><td class="name" onclick="toggle('isA0')"><a name="isA0Anchor">isA</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>> Base</td></tr> +<tr><td colspan="4" class="doc" id="isA0"><pre>Similar to isDerivedFrom(), but also matches classes that directly +match Base. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>></td><td class="name" onclick="toggle('isDerivedFrom0')"><a name="isDerivedFrom0Anchor">isDerivedFrom</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>> Base</td></tr> +<tr><td colspan="4" class="doc" id="isDerivedFrom0"><pre>Matches C++ classes that are directly or indirectly derived from +a class matching Base. + +Note that a class is not considered to be derived from itself. + +Example matches Y, Z, C (Base == hasName("X")) + class X; + class Y : public X {}; directly derived + class Z : public Y {}; indirectly derived + typedef X A; + typedef A B; + class C : public B {}; derived from a typedef of X + +In the following example, Bar matches isDerivedFrom(hasName("X")): + class Foo; + typedef Foo X; + class Bar : public Foo {}; derived from a type that X is a typedef of +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>></td><td class="name" onclick="toggle('callee1')"><a name="callee1Anchor">callee</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="callee1"><pre>Matches if the call expression's callee's declaration matches the +given matcher. + +Example matches y.x() (matcher = callExpr(callee(methodDecl(hasName("x"))))) + class Y { public: void x(); }; + void z() { Y y; y.x(); +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>></td><td class="name" onclick="toggle('hasAnyArgument0')"><a name="hasAnyArgument0Anchor">hasAnyArgument</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasAnyArgument0"><pre>Matches any argument of a call expression or a constructor call +expression. + +Given + void x(int, int, int) { int y; x(1, y, 42); } +callExpr(hasAnyArgument(declRefExpr())) + matches x(1, y, 42) +with hasAnyArgument(...) + matching y +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>></td><td class="name" onclick="toggle('hasArgument0')"><a name="hasArgument0Anchor">hasArgument</a></td><td>unsigned N, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasArgument0"><pre>Matches the n'th argument of a call expression or a constructor +call expression. + +Example matches y in x(y) + (matcher = callExpr(hasArgument(0, declRefExpr()))) + void x(int) { int y; x(y); } +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>></td><td class="name" onclick="toggle('hasDeclaration1')"><a name="hasDeclaration1Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration1"><pre>Matches a type if the declaration of the type matches the given +matcher. + +Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CastExpr.html">CastExpr</a>></td><td class="name" onclick="toggle('hasSourceExpression0')"><a name="hasSourceExpression0Anchor">hasSourceExpression</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasSourceExpression0"><pre>Matches if the cast's source expression matches the given matcher. + +Example: matches "a string" (matcher = + hasSourceExpression(constructExpr())) +class URL { URL(string); }; +URL url = "a string"; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>></td><td class="name" onclick="toggle('hasAnyTemplateArgument0')"><a name="hasAnyTemplateArgument0Anchor">hasAnyTemplateArgument</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasAnyTemplateArgument0"><pre>Matches classTemplateSpecializations that have at least one +TemplateArgument matching the given InnerMatcher. + +Given + template<typename T> class A {}; + template<> class A<double> {}; + A<int> a; +classTemplateSpecializationDecl(hasAnyTemplateArgument( + refersToType(asString("int")))) + matches the specialization A<int> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>></td><td class="name" onclick="toggle('hasTemplateArgument0')"><a name="hasTemplateArgument0Anchor">hasTemplateArgument</a></td><td>unsigned N, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasTemplateArgument0"><pre>Matches classTemplateSpecializations where the n'th TemplateArgument +matches the given InnerMatcher. + +Given + template<typename T, typename U> class A {}; + A<bool, int> b; + A<int, bool> c; +classTemplateSpecializationDecl(hasTemplateArgument( + 1, refersToType(asString("int")))) + matches the specialization A<bool, int> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CompoundStmt.html">CompoundStmt</a>></td><td class="name" onclick="toggle('hasAnySubstatement0')"><a name="hasAnySubstatement0Anchor">hasAnySubstatement</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasAnySubstatement0"><pre>Matches compound statements where at least one substatement matches +a given matcher. + +Given + { {}; 1+2; } +hasAnySubstatement(compoundStmt()) + matches '{ {}; 1+2; }' +with compoundStmt() + matching '{}' +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ConditionalOperator.html">ConditionalOperator</a>></td><td class="name" onclick="toggle('hasCondition4')"><a name="hasCondition4Anchor">hasCondition</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasCondition4"><pre>Matches the condition expression of an if statement, for loop, +or conditional operator. + +Example matches true (matcher = hasCondition(boolLiteral(equals(true)))) + if (true) {} +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ConditionalOperator.html">ConditionalOperator</a>></td><td class="name" onclick="toggle('hasFalseExpression0')"><a name="hasFalseExpression0Anchor">hasFalseExpression</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasFalseExpression0"><pre>Matches the false branch expression of a conditional operator. + +Example matches b + condition ? a : b +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ConditionalOperator.html">ConditionalOperator</a>></td><td class="name" onclick="toggle('hasTrueExpression0')"><a name="hasTrueExpression0Anchor">hasTrueExpression</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasTrueExpression0"><pre>Matches the true branch expression of a conditional operator. + +Example matches a + condition ? a : b +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>></td><td class="name" onclick="toggle('throughUsingDecl0')"><a name="throughUsingDecl0Anchor">throughUsingDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UsingShadowDecl.html">UsingShadowDecl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="throughUsingDecl0"><pre>Matches a DeclRefExpr that refers to a declaration through a +specific using shadow declaration. + +FIXME: This currently only works for functions. Fix. + +Given + namespace a { void f() {} } + using a::f; + void g() { + f(); Matches this .. + a::f(); .. but not this. + } +declRefExpr(throughUsingDeclaration(anything())) + matches f() +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>></td><td class="name" onclick="toggle('to0')"><a name="to0Anchor">to</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="to0"><pre>Matches a DeclRefExpr that refers to a declaration that matches the +specified matcher. + +Example matches x in if(x) + (matcher = declRefExpr(to(varDecl(hasName("x"))))) + bool x; + if (x) {} +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclStmt.html">DeclStmt</a>></td><td class="name" onclick="toggle('containsDeclaration0')"><a name="containsDeclaration0Anchor">containsDeclaration</a></td><td>unsigned N, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="containsDeclaration0"><pre>Matches the n'th declaration of a declaration statement. + +Note that this does not work for global declarations because the AST +breaks up multiple-declaration DeclStmt's into multiple single-declaration +DeclStmt's. +Example: Given non-global declarations + int a, b = 0; + int c; + int d = 2, e; +declStmt(containsDeclaration( + 0, varDecl(hasInitializer(anything())))) + matches only 'int d = 2, e;', and +declStmt(containsDeclaration(1, varDecl())) + matches 'int a, b = 0' as well as 'int d = 2, e;' + but 'int c;' is not matched. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclStmt.html">DeclStmt</a>></td><td class="name" onclick="toggle('hasSingleDecl0')"><a name="hasSingleDecl0Anchor">hasSingleDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasSingleDecl0"><pre>Matches the Decl of a DeclStmt which has a single declaration. + +Given + int a, b; + int c; +declStmt(hasSingleDecl(anything())) + matches 'int c;' but not 'int a, b;'. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DoStmt.html">DoStmt</a>></td><td class="name" onclick="toggle('hasBody0')"><a name="hasBody0Anchor">hasBody</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasBody0"><pre>Matches a 'for', 'while', or 'do while' statement that has +a given body. + +Given + for (;;) {} +hasBody(compoundStmt()) + matches 'for (;;) {}' +with compoundStmt() + matching '{}' +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DoStmt.html">DoStmt</a>></td><td class="name" onclick="toggle('hasCondition3')"><a name="hasCondition3Anchor">hasCondition</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasCondition3"><pre>Matches the condition expression of an if statement, for loop, +or conditional operator. + +Example matches true (matcher = hasCondition(boolLiteral(equals(true)))) + if (true) {} +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>></td><td class="name" onclick="toggle('hasDestinationType0')"><a name="hasDestinationType0Anchor">hasDestinationType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDestinationType0"><pre>Matches casts whose destination type matches a given matcher. + +(Note: Clang's AST refers to other conversions as "casts" too, and calls +actual casts "explicit" casts.) +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('hasType3')"><a name="hasType3Anchor">hasType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasType3"><pre>Overloaded to match the declaration of the expression's or value +declaration's type. + +In case of a value declaration (for example a variable declaration), +this resolves one layer of indirection. For example, in the value +declaration "X x;", recordDecl(hasName("X")) matches the declaration of X, +while varDecl(hasType(recordDecl(hasName("X")))) matches the declaration +of x." + +Example matches x (matcher = expr(hasType(recordDecl(hasName("X"))))) + and z (matcher = varDecl(hasType(recordDecl(hasName("X"))))) + class X {}; + void y(X &x) { x; X z; } + +Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('ignoringImpCasts0')"><a name="ignoringImpCasts0Anchor">ignoringImpCasts</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="ignoringImpCasts0"><pre>Matches expressions that match InnerMatcher after any implicit casts +are stripped off. + +Parentheses and explicit casts are not discarded. +Given + int arr[5]; + int a = 0; + char b = 0; + const int c = a; + int *d = arr; + long e = (long) 0l; +The matchers + varDecl(hasInitializer(ignoringImpCasts(integerLiteral()))) + varDecl(hasInitializer(ignoringImpCasts(declRefExpr()))) +would match the declarations for a, b, c, and d, but not e. +While + varDecl(hasInitializer(integerLiteral())) + varDecl(hasInitializer(declRefExpr())) +only match the declarations for b, c, and d. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('ignoringParenCasts0')"><a name="ignoringParenCasts0Anchor">ignoringParenCasts</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="ignoringParenCasts0"><pre>Matches expressions that match InnerMatcher after parentheses and +casts are stripped off. + +Implicit and non-C Style casts are also discarded. +Given + int a = 0; + char b = (0); + void* c = reinterpret_cast<char*>(0); + char d = char(0); +The matcher + varDecl(hasInitializer(ignoringParenCasts(integerLiteral()))) +would match the declarations for a, b, c, and d. +while + varDecl(hasInitializer(integerLiteral())) +only match the declaration for a. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('ignoringParenImpCasts0')"><a name="ignoringParenImpCasts0Anchor">ignoringParenImpCasts</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="ignoringParenImpCasts0"><pre>Matches expressions that match InnerMatcher after implicit casts and +parentheses are stripped off. + +Explicit casts are not discarded. +Given + int arr[5]; + int a = 0; + char b = (0); + const int c = a; + int *d = (arr); + long e = ((long) 0l); +The matchers + varDecl(hasInitializer(ignoringParenImpCasts(integerLiteral()))) + varDecl(hasInitializer(ignoringParenImpCasts(declRefExpr()))) +would match the declarations for a, b, c, and d, but not e. +while + varDecl(hasInitializer(integerLiteral())) + varDecl(hasInitializer(declRefExpr())) +would only match the declaration for a. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ForStmt.html">ForStmt</a>></td><td class="name" onclick="toggle('hasBody1')"><a name="hasBody1Anchor">hasBody</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasBody1"><pre>Matches a 'for', 'while', or 'do while' statement that has +a given body. + +Given + for (;;) {} +hasBody(compoundStmt()) + matches 'for (;;) {}' +with compoundStmt() + matching '{}' +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ForStmt.html">ForStmt</a>></td><td class="name" onclick="toggle('hasCondition1')"><a name="hasCondition1Anchor">hasCondition</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasCondition1"><pre>Matches the condition expression of an if statement, for loop, +or conditional operator. + +Example matches true (matcher = hasCondition(boolLiteral(equals(true)))) + if (true) {} +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ForStmt.html">ForStmt</a>></td><td class="name" onclick="toggle('hasIncrement0')"><a name="hasIncrement0Anchor">hasIncrement</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasIncrement0"><pre>Matches the increment statement of a for loop. + +Example: + forStmt(hasIncrement(unaryOperator(hasOperatorName("++")))) +matches '++x' in + for (x; x < N; ++x) { } +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ForStmt.html">ForStmt</a>></td><td class="name" onclick="toggle('hasLoopInit0')"><a name="hasLoopInit0Anchor">hasLoopInit</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasLoopInit0"><pre>Matches the initialization statement of a for loop. + +Example: + forStmt(hasLoopInit(declStmt())) +matches 'int x = 0' in + for (int x = 0; x < N; ++x) { } +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('hasAnyParameter0')"><a name="hasAnyParameter0Anchor">hasAnyParameter</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ParmVarDecl.html">ParmVarDecl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasAnyParameter0"><pre>Matches any parameter of a function declaration. + +Does not match the 'this' parameter of a method. + +Given + class X { void f(int x, int y, int z) {} }; +methodDecl(hasAnyParameter(hasName("y"))) + matches f(int x, int y, int z) {} +with hasAnyParameter(...) + matching int y +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('hasParameter0')"><a name="hasParameter0Anchor">hasParameter</a></td><td>unsigned N, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ParmVarDecl.html">ParmVarDecl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasParameter0"><pre>Matches the n'th parameter of a function declaration. + +Given + class X { void f(int x) {} }; +methodDecl(hasParameter(0, hasType(varDecl()))) + matches f(int x) {} +with hasParameter(...) + matching int x +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('returns0')"><a name="returns0Anchor">returns</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="returns0"><pre>Matches the return type of a function declaration. + +Given: + class X { int f() { return 1; } }; +methodDecl(returns(asString("int"))) + matches int f() { return 1; } +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IfStmt.html">IfStmt</a>></td><td class="name" onclick="toggle('hasCondition0')"><a name="hasCondition0Anchor">hasCondition</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasCondition0"><pre>Matches the condition expression of an if statement, for loop, +or conditional operator. + +Example matches true (matcher = hasCondition(boolLiteral(equals(true)))) + if (true) {} +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1IfStmt.html">IfStmt</a>></td><td class="name" onclick="toggle('hasConditionVariableStatement0')"><a name="hasConditionVariableStatement0Anchor">hasConditionVariableStatement</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclStmt.html">DeclStmt</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasConditionVariableStatement0"><pre>Matches the condition variable statement in an if statement. + +Given + if (A* a = GetAPointer()) {} +hasConditionVariableStatment(...) + matches 'A* a = GetAPointer()'. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ImplicitCastExpr.html">ImplicitCastExpr</a>></td><td class="name" onclick="toggle('hasImplicitDestinationType0')"><a name="hasImplicitDestinationType0Anchor">hasImplicitDestinationType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasImplicitDestinationType0"><pre>Matches implicit casts whose destination type matches a given +matcher. + +FIXME: Unit test this matcher +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>></td><td class="name" onclick="toggle('hasObjectExpression0')"><a name="hasObjectExpression0Anchor">hasObjectExpression</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasObjectExpression0"><pre>Matches a member expression where the object expression is +matched by a given matcher. + +Given + struct X { int m; }; + void f(X x) { x.m; m; } +memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X"))))))) + matches "x.m" and "m" +with hasObjectExpression(...) + matching "x" and the implicit object expression of "m" which has type X*. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>></td><td class="name" onclick="toggle('member0')"><a name="member0Anchor">member</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="member0"><pre>Matches a member expression where the member is matched by a +given matcher. + +Given + struct { int first, second; } first, second; + int i(second.first); + int j(first.second); +memberExpr(member(hasName("first"))) + matches second.first + but not first.second (because the member name there is "second"). +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>></td><td class="name" onclick="toggle('hasDeclaration2')"><a name="hasDeclaration2Anchor">hasDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration2"><pre>Matches a type if the declaration of the type matches the given +matcher. + +Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>></td><td class="name" onclick="toggle('pointsTo1')"><a name="pointsTo1Anchor">pointsTo</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="pointsTo1"><pre>Overloaded to match the pointee type's declaration. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>></td><td class="name" onclick="toggle('references1')"><a name="references1Anchor">references</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="references1"><pre>Overloaded to match the referenced type's declaration. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('alignOfExpr0')"><a name="alignOfExpr0Anchor">alignOfExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html">UnaryExprOrTypeTraitExpr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="alignOfExpr0"><pre>Same as unaryExprOrTypeTraitExpr, but only matching +alignof. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('sizeOfExpr0')"><a name="sizeOfExpr0Anchor">sizeOfExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html">UnaryExprOrTypeTraitExpr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="sizeOfExpr0"><pre>Same as unaryExprOrTypeTraitExpr, but only matching +sizeof. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>></td><td class="name" onclick="toggle('refersToDeclaration0')"><a name="refersToDeclaration0Anchor">refersToDeclaration</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="refersToDeclaration0"><pre>Matches a TemplateArgument that refers to a certain declaration. + +Given + template<typename T> struct A {}; + struct B { B* next; }; + A<&B::next> a; +classTemplateSpecializationDecl(hasAnyTemplateArgument( + refersToDeclaration(fieldDecl(hasName("next")))) + matches the specialization A<&B::next> with fieldDecl(...) matching + B::next +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>></td><td class="name" onclick="toggle('refersToType0')"><a name="refersToType0Anchor">refersToType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="refersToType0"><pre>Matches a TemplateArgument that refers to a certain type. + +Given + struct X {}; + template<typename T> struct A {}; + A<X> a; +classTemplateSpecializationDecl(hasAnyTemplateArgument( + refersToType(class(hasName("X"))))) + matches the specialization A<X> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html">UnaryExprOrTypeTraitExpr</a>></td><td class="name" onclick="toggle('hasArgumentOfType0')"><a name="hasArgumentOfType0Anchor">hasArgumentOfType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasArgumentOfType0"><pre>Matches unary expressions that have a specific type of argument. + +Given + int a, c; float b; int s = sizeof(a) + sizeof(b) + alignof(c); +unaryExprOrTypeTraitExpr(hasArgumentOfType(asString("int")) + matches sizeof(a) and alignof(c) +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnaryOperator.html">UnaryOperator</a>></td><td class="name" onclick="toggle('hasUnaryOperand0')"><a name="hasUnaryOperand0Anchor">hasUnaryOperand</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasUnaryOperand0"><pre>Matches if the operand of a unary operator matches. + +Example matches true (matcher = hasOperand(boolLiteral(equals(true)))) + !true +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UsingDecl.html">UsingDecl</a>></td><td class="name" onclick="toggle('hasAnyUsingShadowDecl0')"><a name="hasAnyUsingShadowDecl0Anchor">hasAnyUsingShadowDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UsingShadowDecl.html">UsingShadowDecl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasAnyUsingShadowDecl0"><pre>Matches any using shadow declaration. + +Given + namespace X { void b(); } + using X::b; +usingDecl(hasAnyUsingShadowDecl(hasName("b")))) + matches using X::b </pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UsingShadowDecl.html">UsingShadowDecl</a>></td><td class="name" onclick="toggle('hasTargetDecl0')"><a name="hasTargetDecl0Anchor">hasTargetDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasTargetDecl0"><pre>Matches a using shadow declaration where the target declaration is +matched by the given matcher. + +Given + namespace X { int a; void b(); } + using X::a; + using X::b; +usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(functionDecl()))) + matches using X::b but not using X::a </pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>></td><td class="name" onclick="toggle('hasType2')"><a name="hasType2Anchor">hasType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasType2"><pre>Overloaded to match the declaration of the expression's or value +declaration's type. + +In case of a value declaration (for example a variable declaration), +this resolves one layer of indirection. For example, in the value +declaration "X x;", recordDecl(hasName("X")) matches the declaration of X, +while varDecl(hasType(recordDecl(hasName("X")))) matches the declaration +of x." + +Example matches x (matcher = expr(hasType(recordDecl(hasName("X"))))) + and z (matcher = varDecl(hasType(recordDecl(hasName("X"))))) + class X {}; + void y(X &x) { x; X z; } + +Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>> +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>></td><td class="name" onclick="toggle('hasInitializer0')"><a name="hasInitializer0Anchor">hasInitializer</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasInitializer0"><pre>Matches a variable declaration that has an initializer expression +that matches the given matcher. + +Example matches x (matcher = varDecl(hasInitializer(callExpr()))) + bool y() { return true; } + bool x = y(); +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1WhileStmt.html">WhileStmt</a>></td><td class="name" onclick="toggle('hasBody2')"><a name="hasBody2Anchor">hasBody</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasBody2"><pre>Matches a 'for', 'while', or 'do while' statement that has +a given body. + +Given + for (;;) {} +hasBody(compoundStmt()) + matches 'for (;;) {}' +with compoundStmt() + matching '{}' +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1WhileStmt.html">WhileStmt</a>></td><td class="name" onclick="toggle('hasCondition2')"><a name="hasCondition2Anchor">hasCondition</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasCondition2"><pre>Matches the condition expression of an if statement, for loop, +or conditional operator. + +Example matches true (matcher = hasCondition(boolLiteral(equals(true)))) + if (true) {} +</pre></td></tr> + +<!--END_TRAVERSAL_MATCHERS --> +</table> + +</div> +</body> +</html> + + diff --git a/docs/LibTooling.html b/docs/LibTooling.html index ed0ad45..163d24a 100644 --- a/docs/LibTooling.html +++ b/docs/LibTooling.html @@ -16,24 +16,27 @@ <p>LibTooling is a library to support writing standalone tools based on Clang. This document will provide a basic walkthrough of how to write a tool using LibTooling.</p> +<p>For the information on how to setup Clang Tooling for LLVM see +<a href="HowToSetupToolingForLLVM.html">HowToSetupToolingForLLVM.html</a></p> <!-- ======================================================================= --> <h2 id="intro">Introduction</h2> <!-- ======================================================================= --> -<p>Tools built with LibTooling, like Clang Plugins, run FrontendActions over -code. <!-- See FIXME for a tutorial on how to write FrontendActions. --> +<p>Tools built with LibTooling, like Clang Plugins, run +<code>FrontendActions</code> over code. +<!-- See FIXME for a tutorial on how to write FrontendActions. --> In this tutorial, we'll demonstrate the different ways of running clang's -SyntaxOnlyAction, which runs a quick syntax check, over a bunch of +<code>SyntaxOnlyAction</code>, which runs a quick syntax check, over a bunch of code.</p> <!-- ======================================================================= --> <h2 id="runoncode">Parsing a code snippet in memory.</h2> <!-- ======================================================================= --> -<p>If you ever wanted to run a FrontendAction over some sample code, for example -to unit test parts of the Clang AST, runToolOnCode is what you looked for. Let -me give you an example: +<p>If you ever wanted to run a <code>FrontendAction</code> over some sample +code, for example to unit test parts of the Clang AST, +<code>runToolOnCode</code> is what you looked for. Let me give you an example: <pre> #include "clang/Tooling/Tooling.h" @@ -48,53 +51,44 @@ me give you an example: <h2 id="standalonetool">Writing a standalone tool.</h2> <!-- ======================================================================= --> -<p>Once you unit tested your FrontendAction to the point where it cannot -possibly break, it's time to create a standalone tool. For a standalone tool -to run clang, it first needs to figure out what command line arguments to use -for a specified file. To that end we create a CompilationDatabase.</p> +<p>Once you unit tested your <code>FrontendAction</code> to the point where it +cannot possibly break, it's time to create a standalone tool. For a standalone +tool to run clang, it first needs to figure out what command line arguments to +use for a specified file. To that end we create a +<code>CompilationDatabase</code>. There are different ways to create a +compilation database, and we need to support all of them depending on +command-line options. There's the <code>CommonOptionsParser</code> class +that takes the responsibility to parse command-line parameters related to +compilation databases and inputs, so that all tools share the implementation. +</p> -<h3 id="compilationdb">Creating a compilation database.</h3> -<p>CompilationDatabase provides static factory functions to help with parsing -compile commands from a build directory or the command line. The following code -allows for both explicit specification of a compile command line, as well as -retrieving the compile commands lines from a database. +<h3 id="parsingcommonoptions">Parsing common tools options.</h3> +<p><code>CompilationDatabase</code> can be read from a build directory or the +command line. Using <code>CommonOptionsParser</code> allows for explicit +specification of a compile command line, specification of build path using the +<code>-p</code> command-line option, and automatic location of the compilation +database using source files paths. <pre> +#include "clang/Tooling/CommonOptionsParser.h" + +using namespace clang::tooling; + int main(int argc, const char **argv) { - // First, try to create a fixed compile command database from the command line - // arguments. - llvm::OwningPtr<CompilationDatabase> Compilations( - FixedCompilationDatabase::loadFromCommandLine(argc, argv)); - - // Next, use normal llvm command line parsing to get the tool specific - // parameters. - cl::ParseCommandLineOptions(argc, argv); - - if (!Compilations) { - // In case the user did not specify the compile command line via positional - // command line arguments after "--", try to load the compile commands from - // a database in the specified build directory or auto-detect it from a - // source file. - std::string ErrorMessage; - if (!BuildPath.empty()) { - Compilations.reset( - CompilationDatabase::autoDetectFromDirectory(BuildPath, ErrorMessage)); - } else { - Compilations.reset(CompilationDatabase::autoDetectFromSource( - SourcePaths[0], ErrorMessage)); - } - // If there is still no valid compile command database, we don't know how - // to run the tool. - if (!Compilations) - llvm::report_fatal_error(ErrorMessage); - } + // CommonOptionsParser constructor will parse arguments and create a + // CompilationDatabase. In case of error it will terminate the program. + CommonOptionsParser OptionsParser(argc, argv); + + // Use OptionsParser.GetCompilations() and OptionsParser.GetSourcePathList() + // to retrieve CompilationDatabase and the list of input file paths. } </pre> </p> <h3 id="tool">Creating and running a ClangTool.</h3> -<p>Once we have a CompilationDatabase, we can create a ClangTool and run our -FrontendAction over some code. For example, to run the SyntaxOnlyAction over -the files "a.cc" and "b.cc" one would write: +<p>Once we have a <code>CompilationDatabase</code>, we can create a +<code>ClangTool</code> and run our <code>FrontendAction</code> over some code. +For example, to run the <code>SyntaxOnlyAction</code> over the files "a.cc" and +"b.cc" one would write: <pre> // A clang tool can run over a number of sources in the same process... std::vector<std::string> Sources; @@ -103,7 +97,7 @@ the files "a.cc" and "b.cc" one would write: // We hand the CompilationDatabase we created and the sources to run over into // the tool constructor. - ClangTool Tool(*Compilations, Sources); + ClangTool Tool(OptionsParser.GetCompilations(), Sources); // The ClangTool needs a new FrontendAction for each translation unit we run // on. Thus, it takes a FrontendActionFactory as parameter. To create a @@ -117,40 +111,29 @@ the files "a.cc" and "b.cc" one would write: <p>Now we combine the two previous steps into our first real tool. This example tool is also checked into the clang tree at tools/clang-check/ClangCheck.cpp. <pre> -#include "llvm/Support/CommandLine.h" +// Declares clang::SyntaxOnlyAction. #include "clang/Frontend/FrontendActions.h" -#include "clang/Tooling/CompilationDatabase.h" +#include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/Tooling.h" +// Declares llvm::cl::extrahelp. +#include "llvm/Support/CommandLine.h" using namespace clang::tooling; using namespace llvm; -cl::opt<std::string> BuildPath( - "p", - cl::desc("<build-path>"), - cl::Optional); +// CommonOptionsParser declares HelpMessage with a description of the common +// command-line options related to the compilation database and input files. +// It's nice to have this help message in all tools. +static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); -cl::list<std::string> SourcePaths( - cl::Positional, - cl::desc("<source0> [... <sourceN>]"), - cl::OneOrMore); +// A help message for this specific tool can be added afterwards. +static cl::extrahelp MoreHelp("\nMore help text..."); int main(int argc, const char **argv) { - llvm::OwningPtr<CompilationDatabase> Compilations( - FixedCompilationDatabase::loadFromCommandLine(argc, argv)); - cl::ParseCommandLineOptions(argc, argv); - if (!Compilations) { - std::string ErrorMessage; - Compilations.reset( - !BuildPath.empty() ? - CompilationDatabase::autoDetectFromDirectory(BuildPath, ErrorMessage) : - CompilationDatabase::autoDetectFromSource(SourcePaths[0], ErrorMessage) - ); - if (!Compilations) - llvm::report_fatal_error(ErrorMessage); - } - ClangTool Tool(*Compilations, SourcePaths); - return Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>()); + CommonOptionsParser OptionsParser(argc, argv); + ClangTool Tool(OptionsParser.GetCompilations(), + OptionsParser.GetSourcePathList()); + return Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>()); } </pre> </p> diff --git a/docs/ObjectiveCLiterals.html b/docs/ObjectiveCLiterals.html index 11751a6..d5a8a9e 100644 --- a/docs/ObjectiveCLiterals.html +++ b/docs/ObjectiveCLiterals.html @@ -178,7 +178,7 @@ A C string literal prefixed by the <code>'@'</code> token denotes an <code>NSStr <pre> // Partition command line arguments into positional and option arguments. NSMutableArray *args = [NSMutableArray new]; -NSMutableDictionary *options = [NSMutableArray new]; +NSMutableDictionary *options = [NSMutableDictionary new]; while (--argc) { const char *arg = *++argv; if (strncmp(arg, "--", 2) == 0) { diff --git a/docs/PCHInternals.html b/docs/PCHInternals.html index 28ce1ce..7fed5ba 100644 --- a/docs/PCHInternals.html +++ b/docs/PCHInternals.html @@ -2,7 +2,7 @@ "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> - <title>Precompiled Headers (PCH)</title> + <title>Precompiled Header and Modules Internals</title> <link type="text/css" rel="stylesheet" href="../menu.css"> <link type="text/css" rel="stylesheet" href="../content.css"> <style type="text/css"> @@ -18,10 +18,10 @@ <div id="content"> -<h1>Precompiled Headers</h1> +<h1>Precompiled Header and Modules Internals</h1> <p>This document describes the design and implementation of Clang's - precompiled headers (PCH). If you are interested in the end-user + precompiled headers (PCH) and modules. If you are interested in the end-user view, please see the <a href="UsersManual.html#precompiledheaders">User's Manual</a>.</p> @@ -30,7 +30,7 @@ <li><a href="#usage">Using Precompiled Headers with <tt>clang</tt></a></li> <li><a href="#philosophy">Design Philosophy</a></li> - <li><a href="#contents">Precompiled Header Contents</a> + <li><a href="#contents">Serialized AST File Contents</a> <ul> <li><a href="#metadata">Metadata Block</a></li> <li><a href="#sourcemgr">Source Manager Block</a></li> @@ -42,8 +42,9 @@ <li><a href="#method-pool">Method Pool Block</a></li> </ul> </li> - <li><a href="#tendrils">Precompiled Header Integration - Points</a></li> + <li><a href="#tendrils">AST Reader Integration Points</a></li> + <li><a href="#chained">Chained precompiled headers</a></li> + <li><a href="#modules">Modules</a></li> </ul> <h2 id="usage">Using Precompiled Headers with <tt>clang</tt></h2> @@ -94,30 +95,39 @@ with the <b><tt>-include-pch</tt></b> option:</p> require the PCH file to be up-to-date.</li> </ul> -<p>Clang's precompiled headers are designed with a compact on-disk -representation, which minimizes both PCH creation time and the time -required to initially load the PCH file. The PCH file itself contains +<p>Modules, as implemented in Clang, use the same mechanisms as +precompiled headers to save a serialized AST file (one per module) and +use those AST modules. From an implementation standpoint, modules are +a generalization of precompiled headers, lifting a number of +restrictions placed on precompiled headers. In particular, there can +only be one precompiled header and it must be included at the +beginning of the translation unit. The extensions to the AST file +format required for modules are discussed in the section on <a href="#modules">modules</a>.</p> + +<p>Clang's AST files are designed with a compact on-disk +representation, which minimizes both creation time and the time +required to initially load the AST file. The AST file itself contains a serialized representation of Clang's abstract syntax trees and supporting data structures, stored using the same compressed bitstream as <a href="http://llvm.org/docs/BitCodeFormat.html">LLVM's bitcode file format</a>.</p> -<p>Clang's precompiled headers are loaded "lazily" from disk. When a -PCH file is initially loaded, Clang reads only a small amount of data -from the PCH file to establish where certain important data structures +<p>Clang's AST files are loaded "lazily" from disk. When an +AST file is initially loaded, Clang reads only a small amount of data +from the AST file to establish where certain important data structures are stored. The amount of data read in this initial load is -independent of the size of the PCH file, such that a larger PCH file -does not lead to longer PCH load times. The actual header data in the -PCH file--macros, functions, variables, types, etc.--is loaded only +independent of the size of the AST file, such that a larger AST file +does not lead to longer AST load times. The actual header data in the +AST file--macros, functions, variables, types, etc.--is loaded only when it is referenced from the user's code, at which point only that entity (and those entities it depends on) are deserialized from the -PCH file. With this approach, the cost of using a precompiled header +AST file. With this approach, the cost of using an AST file for a translation unit is proportional to the amount of code actually -used from the header, rather than being proportional to the size of -the header itself.</p> +used from the AST file, rather than being proportional to the size of +the AST file itself.</p> <p>When given the <code>-print-stats</code> option, Clang produces -statistics describing how much of the precompiled header was actually +statistics describing how much of the AST file was actually loaded from disk. For a simple "Hello, World!" program that includes the Apple <code>Cocoa.h</code> header (which is built as a precompiled header), this option illustrates how little of the actual precompiled @@ -143,7 +153,7 @@ header is required:</p> <p>For this small program, only a tiny fraction of the source locations, types, declarations, identifiers, and macros were actually deserialized from the precompiled header. These statistics can be -useful to determine whether the precompiled header implementation can +useful to determine whether the AST file implementation can be improved by making more of the implementation lazy.</p> <p>Precompiled headers can be chained. When you create a PCH while @@ -153,13 +163,15 @@ example, you could create a PCH out of all the headers that are very commonly used throughout your project, and then create a PCH for every single source file in the project that includes the code that is specific to that file, so that recompiling the file itself is very fast, -without duplicating the data from the common headers for every file.</p> +without duplicating the data from the common headers for every +file. The mechanisms behind chained precompiled headers are discussed +in a <a href="#chained">later section</a>. -<h2 id="contents">Precompiled Header Contents</h2> +<h2 id="contents">AST File Contents</h2> <img src="PCHLayout.png" style="float:right" alt="Precompiled header layout"> -<p>Clang's precompiled headers are organized into several different +<p>Clang's AST files are organized into several different blocks, each of which contains the serialized representation of a part of Clang's internal representation. Each of the blocks corresponds to either a block or a record within <a @@ -167,19 +179,19 @@ either a block or a record within <a format</a>. The contents of each of these logical blocks are described below.</p> -<p>For a given precompiled header, the <a +<p>For a given AST file, the <a href="http://llvm.org/cmds/llvm-bcanalyzer.html"><code>llvm-bcanalyzer</code></a> utility can be used to examine the actual structure of the bitstream -for the precompiled header. This information can be used both to help -understand the structure of the precompiled header and to isolate -areas where precompiled headers can still be optimized, e.g., through +for the AST file. This information can be used both to help +understand the structure of the AST file and to isolate +areas where AST files can still be optimized, e.g., through the introduction of abbreviations.</p> <h3 id="metadata">Metadata Block</h3> <p>The metadata block contains several records that provide -information about how the precompiled header was built. This metadata -is primarily used to validate the use of a precompiled header. For +information about how the AST file was built. This metadata +is primarily used to validate the use of an AST file. For example, a precompiled header built for a 32-bit x86 target cannot be used when compiling for a 64-bit x86 target. The metadata block contains information about:</p> @@ -187,17 +199,17 @@ information about:</p> <dl> <dt>Language options</dt> <dd>Describes the particular language dialect used to compile the -PCH file, including major options (e.g., Objective-C support) and more +AST file, including major options (e.g., Objective-C support) and more minor options (e.g., support for "//" comments). The contents of this record correspond to the <code>LangOptions</code> class.</dd> <dt>Target architecture</dt> <dd>The target triple that describes the architecture, platform, and -ABI for which the PCH file was generated, e.g., +ABI for which the AST file was generated, e.g., <code>i386-apple-darwin9</code>.</dd> - <dt>PCH version</dt> - <dd>The major and minor version numbers of the precompiled header + <dt>AST version</dt> + <dd>The major and minor version numbers of the AST file format. Changes in the minor version number should not affect backward compatibility, while changes in the major version number imply that a newer compiler cannot read an older precompiled header (and @@ -205,11 +217,11 @@ vice-versa).</dd> <dt>Original file name</dt> <dd>The full path of the header that was used to generate the -precompiled header.</dd> +AST file.</dd> <dt>Predefines buffer</dt> <dd>Although not explicitly stored as part of the metadata, the -predefines buffer is used in the validation of the precompiled header. +predefines buffer is used in the validation of the AST file. The predefines buffer itself contains code generated by the compiler to initialize the preprocessor state according to the current target, platform, and command-line options. For example, the predefines buffer @@ -220,26 +232,14 @@ contents are verified along with the rest of the metadata.</dd> </dl> -<p>A chained PCH file (that is, one that references another PCH) has -a slightly different metadata block, which contains the following -information:</p> +<p>A chained PCH file (that is, one that references another PCH) and a +module (which may import other modules) have additional metadata +containing the list of all AST files that this AST file depends +on. Each of those files will be loaded along with this AST file.</p> -<dl> - <dt>Referenced file</dt> - <dd>The name of the referenced PCH file. It is looked up like a file -specified using -include-pch.</dd> - - <dt>PCH version</dt> - <dd>This is the same as in normal PCH files.</dd> - - <dt>Original file name</dt> - <dd>The full path of the header that was used to generate this -precompiled header.</dd> - -</dl> - -<p>The language options, target architecture and predefines buffer data -is taken from the end of the chain, since they have to match anyway.</p> +<p>For chained precompiled headers, the language options, target +architecture and predefines buffer data is taken from the end of the +chain, since they have to match anyway.</p> <h3 id="sourcemgr">Source Manager Block</h3> @@ -248,10 +248,10 @@ Clang's <a href="InternalsManual.html#SourceLocation">SourceManager</a> class, which handles the mapping from source locations (as represented in Clang's abstract syntax tree) into actual column/line positions within -a source file or macro instantiation. The precompiled header's +a source file or macro instantiation. The AST file's representation of the source manager also includes information about all of the headers that were (transitively) included when building the -precompiled header.</p> +AST file.</p> <p>The bulk of the source manager block is dedicated to information about the various files, buffers, and macro instantiations into which @@ -259,18 +259,18 @@ a source location can refer. Each of these is referenced by a numeric "file ID", which is a unique number (allocated starting at 1) stored in the source location. Clang serializes the information for each kind of file ID, along with an index that maps file IDs to the position -within the PCH file where the information about that file ID is +within the AST file where the information about that file ID is stored. The data associated with a file ID is loaded only when required by the front end, e.g., to emit a diagnostic that includes a macro instantiation history inside the header itself.</p> <p>The source manager block also contains information about all of the -headers that were included when building the precompiled header. This +headers that were included when building the AST file. This includes information about the controlling macro for the header (e.g., when the preprocessor identified that the contents of the header dependent on a macro like <code>LLVM_CLANG_SOURCEMANAGER_H</code>) along with a cached version of the results of the <code>stat()</code> -system calls performed when building the precompiled header. The +system calls performed when building the AST file. The latter is particularly useful in reducing system time when searching for include files.</p> @@ -279,8 +279,8 @@ for include files.</p> <p>The preprocessor block contains the serialized representation of the preprocessor. Specifically, it contains all of the macros that have been defined by the end of the header used to build the -precompiled header, along with the token sequences that comprise each -macro. The macro definitions are only read from the PCH file when the +AST file, along with the token sequences that comprise each +macro. The macro definitions are only read from the AST file when the name of the macro first occurs in the program. This lazy loading of macro definitions is triggered by lookups into the <a href="#idtable">identifier table</a>.</p> @@ -290,8 +290,8 @@ macro definitions is triggered by lookups into the <a <p>The types block contains the serialized representation of all of the types referenced in the translation unit. Each Clang type node (<code>PointerType</code>, <code>FunctionProtoType</code>, etc.) has a -corresponding record type in the PCH file. When types are deserialized -from the precompiled header, the data within the record is used to +corresponding record type in the AST file. When types are deserialized +from the AST file, the data within the record is used to reconstruct the appropriate type node using the AST context.</p> <p>Each type has a unique type ID, which is an integer that uniquely @@ -300,10 +300,10 @@ less than <code>NUM_PREDEF_TYPE_IDS</code> represent predefined types (<code>void</code>, <code>float</code>, etc.), while other "user-defined" type IDs are assigned consecutively from <code>NUM_PREDEF_TYPE_IDS</code> upward as the types are encountered. -The PCH file has an associated mapping from the user-defined types +The AST file has an associated mapping from the user-defined types block to the location within the types block where the serialized representation of that type resides, enabling lazy deserialization of -types. When a type is referenced from within the PCH file, that +types. When a type is referenced from within the AST file, that reference is encoded using the type ID shifted left by 3 bits. The lower three bits are used to represent the <code>const</code>, <code>volatile</code>, and <code>restrict</code> qualifiers, as in @@ -316,19 +316,20 @@ class.</p> <p>The declarations block contains the serialized representation of all of the declarations referenced in the translation unit. Each Clang declaration node (<code>VarDecl</code>, <code>FunctionDecl</code>, -etc.) has a corresponding record type in the PCH file. When -declarations are deserialized from the precompiled header, the data +etc.) has a corresponding record type in the AST file. When +declarations are deserialized from the AST file, the data within the record is used to build and populate a new instance of the corresponding <code>Decl</code> node. As with types, each declaration node has a numeric ID that is used to refer to that declaration within -the PCH file. In addition, a lookup table provides a mapping from that +the AST file. In addition, a lookup table provides a mapping from that numeric ID to the offset within the precompiled header where that declaration is described.</p> <p>Declarations in Clang's abstract syntax trees are stored hierarchically. At the top of the hierarchy is the translation unit (<code>TranslationUnitDecl</code>), which contains all of the -declarations in the translation unit. These declarations (such as +declarations in the translation unit but is not actually written as a +specific declaration node. Its child declarations (such as functions or struct types) may also contain other declarations inside them, and so on. Within Clang, each declaration is stored within a <a href="http://clang.llvm.org/docs/InternalsManual.html#DeclContext">declaration @@ -339,7 +340,7 @@ in a structure) and iterate over the declarations stored within a context (e.g., iterate over all of the fields of a structure for structure layout).</p> -<p>In Clang's precompiled header format, deserializing a declaration +<p>In Clang's AST file format, deserializing a declaration that is a <code>DeclContext</code> is a separate operation from deserializing all of the declarations stored within that declaration context. Therefore, Clang will deserialize the translation unit @@ -354,14 +355,11 @@ the name-lookup and iteration behavior described above:</p> <code>x</code> within a given declaration context (for example, during semantic analysis of the expression <code>p->x</code>, where <code>p</code>'s type is defined in the precompiled header), - Clang deserializes a hash table mapping from the names within that - declaration context to the declaration IDs that represent each - visible declaration with that name. The entire hash table is - deserialized at this point (into the <code>llvm::DenseMap</code> - stored within each <code>DeclContext</code> object), but the actual - declarations are not yet deserialized. In a second step, those - declarations with the name <code>x</code> will be deserialized and - will be used as the result of name lookup.</li> + Clang refers to an on-disk hash table that maps from the names + within that declaration context to the declaration IDs that + represent each visible declaration with that name. The actual + declarations will then be deserialized to provide the results of + name lookup.</li> <li>When the front end performs iteration over all of the declarations within a declaration context, all of those declarations @@ -376,7 +374,7 @@ the name-lookup and iteration behavior described above:</p> <h3 id="stmt">Statements and Expressions</h3> -<p>Statements and expressions are stored in the precompiled header in +<p>Statements and expressions are stored in the AST file in both the <a href="#types">types</a> and the <a href="#decls">declarations</a> blocks, because every statement or expression will be associated with either a type or declaration. The @@ -389,10 +387,10 @@ function.</p> <p>As with types and declarations, each statement and expression kind in Clang's abstract syntax tree (<code>ForStmt</code>, <code>CallExpr</code>, etc.) has a corresponding record type in the -precompiled header, which contains the serialized representation of +AST file, which contains the serialized representation of that statement or expression. Each substatement or subexpression within an expression is stored as a separate record (which keeps most -records to a fixed size). Within the precompiled header, the +records to a fixed size). Within the AST file, the subexpressions of an expression are stored, in reverse order, prior to the expression that owns those expression, using a form of <a href="http://en.wikipedia.org/wiki/Reverse_Polish_notation">Reverse @@ -420,7 +418,7 @@ they are part of a different expression.</p> <h3 id="idtable">Identifier Table Block</h3> <p>The identifier table block contains an on-disk hash table that maps -each identifier mentioned within the precompiled header to the +each identifier mentioned within the AST file to the serialized representation of the identifier's information (e.g, the <code>IdentifierInfo</code> structure). The serialized representation contains:</p> @@ -438,17 +436,20 @@ contains:</p> declarations.</li> </ul> -<p>When a precompiled header is loaded, the precompiled header +<p>When an AST file is loaded, the AST file reader mechanism introduces itself into the identifier table as an external lookup source. Thus, when the user program refers to an identifier that has not yet been seen, Clang will perform a lookup into the identifier table. If an identifier is found, its contents (macro -definitions, flags, top-level declarations, etc.) will be deserialized, at which point the corresponding <code>IdentifierInfo</code> structure will have the same contents it would have after parsing the headers in the precompiled header.</p> +definitions, flags, top-level declarations, etc.) will be +deserialized, at which point the corresponding +<code>IdentifierInfo</code> structure will have the same contents it +would have after parsing the headers in the AST file.</p> -<p>Within the PCH file, the identifiers used to name declarations are represented with an integral value. A separate table provides a mapping from this integral value (the identifier ID) to the location within the on-disk +<p>Within the AST file, the identifiers used to name declarations are represented with an integral value. A separate table provides a mapping from this integral value (the identifier ID) to the location within the on-disk hash table where that identifier is stored. This mapping is used when deserializing the name of a declaration, the identifier of a token, or -any other construct in the PCH file that refers to a name.</p> +any other construct in the AST file that refers to a name.</p> <h3 id="method-pool">Method Pool Block</h3> @@ -457,7 +458,7 @@ serves two purposes: it provides a mapping from the names of Objective-C selectors to the set of Objective-C instance and class methods that have that particular selector (which is required for semantic analysis in Objective-C) and also stores all of the selectors -used by entities within the precompiled header. The design of the +used by entities within the AST file. The design of the method pool is similar to that of the <a href="#idtable">identifier table</a>: the first time a particular selector is formed during the compilation of the program, Clang will search in the on-disk hash @@ -468,25 +469,25 @@ structure (<code>Sema::InstanceMethodPool</code> and respectively).</p> <p>As with identifiers, selectors are represented by numeric values -within the PCH file. A separate index maps these numeric selector +within the AST file. A separate index maps these numeric selector values to the offset of the selector within the on-disk hash table, and will be used when de-serializing an Objective-C method declaration (or other Objective-C construct) that refers to the selector.</p> -<h2 id="tendrils">Precompiled Header Integration Points</h2> +<h2 id="tendrils">AST Reader Integration Points</h2> -<p>The "lazy" deserialization behavior of precompiled headers requires +<p>The "lazy" deserialization behavior of AST files requires their integration into several completely different submodules of Clang. For example, lazily deserializing the declarations during name lookup requires that the name-lookup routines be able to query the -precompiled header to find entities within the PCH file.</p> +AST file to find entities stored there.</p> <p>For each Clang data structure that requires direct interaction with -the precompiled header logic, there is an abstract class that provides -the interface between the two modules. The <code>PCHReader</code> -class, which handles the loading of a precompiled header, inherits +the AST reader logic, there is an abstract class that provides +the interface between the two modules. The <code>ASTReader</code> +class, which handles the loading of an AST file, inherits from all of these abstract classes to provide lazy deserialization of -Clang's data structures. <code>PCHReader</code> implements the +Clang's data structures. <code>ASTReader</code> implements the following abstract classes:</p> <dl> @@ -505,7 +506,7 @@ following abstract classes:</p> <dd>This abstract interface is associated with the <code>IdentifierTable</code> class, and is used whenever the program source refers to an identifier that has not yet been seen. - In this case, the precompiled header implementation searches for + In this case, the AST reader searches for this identifier within its <a href="#idtable">identifier table</a> to load any top-level declarations or macros associated with that identifier.</dd> @@ -513,7 +514,7 @@ following abstract classes:</p> <dt><code>ExternalASTSource</code></dt> <dd>This abstract interface is associated with the <code>ASTContext</code> class, and is used whenever the abstract - syntax tree nodes need to loaded from the precompiled header. It + syntax tree nodes need to loaded from the AST file. It provides the ability to de-serialize declarations and types identified by their numeric values, read the bodies of functions when required, and read the declarations stored within a @@ -526,6 +527,131 @@ following abstract classes:</p> pool</a>.</dd> </dl> +<h2 id="chained">Chained precompiled headers</h2> + +<p>Chained precompiled headers were initially intended to improve the +performance of IDE-centric operations such as syntax highlighting and +code completion while a particular source file is being edited by the +user. To minimize the amount of reparsing required after a change to +the file, a form of precompiled header--called a precompiled +<i>preamble</i>--is automatically generated by parsing all of the +headers in the source file, up to and including the last +#include. When only the source file changes (and none of the headers +it depends on), reparsing of that source file can use the precompiled +preamble and start parsing after the #includes, so parsing time is +proportional to the size of the source file (rather than all of its +includes). However, the compilation of that translation unit +may already use a precompiled header: in this case, Clang will create +the precompiled preamble as a chained precompiled header that refers +to the original precompiled header. This drastically reduces the time +needed to serialize the precompiled preamble for use in reparsing.</p> + +<p>Chained precompiled headers get their name because each precompiled header +can depend on one other precompiled header, forming a chain of +dependencies. A translation unit will then include the precompiled +header that starts the chain (i.e., nothing depends on it). This +linearity of dependencies is important for the semantic model of +chained precompiled headers, because the most-recent precompiled +header can provide information that overrides the information provided +by the precompiled headers it depends on, just like a header file +<code>B.h</code> that includes another header <code>A.h</code> can +modify the state produced by parsing <code>A.h</code>, e.g., by +<code>#undef</code>'ing a macro defined in <code>A.h</code>.</p> + +<p>There are several ways in which chained precompiled headers +generalize the AST file model:</p> + +<dl> + <dt>Numbering of IDs</dt> + <dd>Many different kinds of entities--identifiers, declarations, + types, etc.---have ID numbers that start at 1 or some other + predefined constant and grow upward. Each precompiled header records + the maximum ID number it has assigned in each category. Then, when a + new precompiled header is generated that depends on (chains to) + another precompiled header, it will start counting at the next + available ID number. This way, one can determine, given an ID + number, which AST file actually contains the entity.</dd> + + <dt>Name lookup</dt> + <dd>When writing a chained precompiled header, Clang attempts to + write only information that has changed from the precompiled header + on which it is based. This changes the lookup algorithm for the + various tables, such as the <a href="#idtable">identifier table</a>: + the search starts at the most-recent precompiled header. If no entry + is found, lookup then proceeds to the identifier table in the + precompiled header it depends on, and so one. Once a lookup + succeeds, that result is considered definitive, overriding any + results from earlier precompiled headers.</dd> + + <dt>Update records</dt> + <dd>There are various ways in which a later precompiled header can + modify the entities described in an earlier precompiled header. For + example, later precompiled headers can add entries into the various + name-lookup tables for the translation unit or namespaces, or add + new categories to an Objective-C class. Each of these updates is + captured in an "update record" that is stored in the chained + precompiled header file and will be loaded along with the original + entity.</dd> +</dl> + +<h2 id="modules">Modules</h2> + +<p>Modules generalize the chained precompiled header model yet +further, from a linear chain of precompiled headers to an arbitrary +directed acyclic graph (DAG) of AST files. All of the same techniques +used to make chained precompiled headers work---ID number, name +lookup, update records---are shared with modules. However, the DAG +nature of modules introduce a number of additional complications to +the model: + +<dl> + <dt>Numbering of IDs</dt> + <dd>The simple, linear numbering scheme used in chained precompiled + headers falls apart with the module DAG, because different modules + may end up with different numbering schemes for entities they + imported from common shared modules. To account for this, each + module file provides information about which modules it depends on + and which ID numbers it assigned to the entities in those modules, + as well as which ID numbers it took for its own new entities. The + AST reader then maps these "local" ID numbers into a "global" ID + number space for the current translation unit, providing a 1-1 + mapping between entities (in whatever AST file they inhabit) and + global ID numbers. If that translation unit is then serialized into + an AST file, this mapping will be stored for use when the AST file + is imported.</dd> + + <dt>Declaration merging</dt> + <dd>It is possible for a given entity (from the language's + perspective) to be declared multiple times in different places. For + example, two different headers can have the declaration of + <tt>printf</tt> or could forward-declare <tt>struct stat</tt>. If + each of those headers is included in a module, and some third party + imports both of those modules, there is a potentially serious + problem: name lookup for <tt>printf</tt> or <tt>struct stat</tt> will + find both declarations, but the AST nodes are unrelated. This would + result in a compilation error, due to an ambiguity in name + lookup. Therefore, the AST reader performs declaration merging + according to the appropriate language semantics, ensuring that the + two disjoint declarations are merged into a single redeclaration + chain (with a common canonical declaration), so that it is as if one + of the headers had been included before the other.</dd> + + <dt>Name Visibility</dt> + <dd>Modules allow certain names that occur during module creation to + be "hidden", so that they are not part of the public interface of + the module and are not visible to its clients. The AST reader + maintains a "visible" bit on various AST nodes (declarations, macros, + etc.) to indicate whether that particular AST node is currently + visible; the various name lookup mechanisms in Clang inspect the + visible bit to determine whether that entity, which is still in the + AST (because other, visible AST nodes may depend on it), can + actually be found by name lookup. When a new (sub)module is + imported, it may make existing, non-visible, already-deserialized + AST nodes visible; it is the responsibility of the AST reader to + find and update these AST nodes when it is notified of the import.</dd> + +</dl> + </div> </body> diff --git a/docs/ReleaseNotes.html b/docs/ReleaseNotes.html index 7a6a508..8a195f0 100644 --- a/docs/ReleaseNotes.html +++ b/docs/ReleaseNotes.html @@ -170,6 +170,16 @@ int f(vector<map<int, double>>); </li> + <li>Clang's <tt>-fcatch-undefined-behavior</tt> option has been renamed to + <tt>-fsanitize=undefined</tt> and has grown the ability to check for several + new types of undefined behavior. See the Users Manual for more information. + + <!-- Flesh this out prior to release. --> + + <!-- Document renaming of -faddress-sanitizer and -fthread-sanitizer. --> + + </li> + </ul> <h4 id="tlsmodel">Support for <code>tls_model</code> attribute</h4> diff --git a/docs/ThreadSanitizer.html b/docs/ThreadSanitizer.html index 7a1d075..aa251c1 100644 --- a/docs/ThreadSanitizer.html +++ b/docs/ThreadSanitizer.html @@ -37,9 +37,8 @@ Typical slowdown introduced by ThreadSanitizer is <b>5x-15x</b> (TODO: these num approximate so far). <h2 id="howtobuild">How to build</h2> -Follow the <a href="../get_started.html">clang build instructions</a>. <BR> -Note: CMake build does not work yet. -See <a href="http://llvm.org/bugs/show_bug.cgi?id=12272">bug 12272</a>. +Follow the <a href="../get_started.html">clang build instructions</a>. +CMake build is supported.<BR> <h2 id="platforms">Supported Platforms</h2> ThreadSanitizer is supported on Linux x86_64 (tested on Ubuntu 10.04). <BR> @@ -49,8 +48,8 @@ Support for 32-bit platforms is problematic and not yet planned. <h2 id="usage">Usage</h2> -Simply compile your program with <tt>-fthread-sanitizer -fPIE</tt> and link it -with <tt>-fthread-sanitizer -pie</tt>.<BR> +Simply compile your program with <tt>-fsanitize=thread -fPIE</tt> and link it +with <tt>-fsanitize=thread -pie</tt>.<BR> To get a reasonable performance add <tt>-O1</tt> or higher. <BR> Use <tt>-g</tt> to get file names and line numbers in the warning messages. <BR> @@ -73,7 +72,7 @@ int main() { </pre> <pre> -% clang -fthread-sanitizer -g -O1 tiny_race.c -fPIE -pie +% clang -fsanitize=thread -g -O1 tiny_race.c -fPIE -pie </pre> If a bug is detected, the program will print an error message to stderr. @@ -111,7 +110,9 @@ This means that tools like <tt>ulimit</tt> may not work as usually expected. ThreadSanitizer is in alpha stage. It is known to work on large C++ programs using pthreads, but we do not promise anything (yet). <BR> -C++11 threading is not yet supported. +C++11 threading is not yet supported. <BR> +The test suite is integrated into CMake build and can be run with +<tt>make check-tsan</tt> command. <BR> We are actively working on enhancing the tool -- stay tuned. Any help, especially in the form of minimized standalone tests is more than welcome. diff --git a/docs/UsersManual.html b/docs/UsersManual.html index 69f916c..35fc5dc 100644 --- a/docs/UsersManual.html +++ b/docs/UsersManual.html @@ -874,33 +874,77 @@ likely to affect PCH files that reference a large number of headers.</p> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <dl> -<dt id="opt_fcatch-undefined-behavior"><b>-fcatch-undefined-behavior</b>: Turn -on runtime code generation to check for undefined behavior.</dt> +<dt id="opt_fsanitize"><b>-fsanitize=check1,check2</b>: Turn on runtime checks +for various forms of undefined behavior.</dt> + +<dd>This option controls whether Clang adds runtime checks for various forms of +undefined behavior, and is disabled by default. If a check fails, a diagnostic +message is produced at runtime explaining the problem. The main checks are: -<dd>This option, which defaults to off, controls whether or not Clang -adds runtime checks for undefined runtime behavior. If a check fails, -<tt>__builtin_trap()</tt> is used to indicate failure. -The checks are: <ul> -<li>Subscripting where the static type of one operand is a variable - which is decayed from an array type and the other operand is - greater than the size of the array or less than zero.</li> -<li>Shift operators where the amount shifted is greater or equal to the - promoted bit-width of the left-hand-side or less than zero.</li> -<li>If control flow reaches __builtin_unreachable. -<li>When llvm implements more __builtin_object_size support, reads and - writes for objects that __builtin_object_size indicates we aren't - accessing valid memory. Bit-fields and vectors are not yet checked. +<li id="opt_fsanitize_address"><tt>-fsanitize=address</tt>: + <a href="AddressSanitizer.html">AddressSanitizer</a>, a memory error + detector.</li> +<li id="opt_fsanitize_thread"><tt>-fsanitize=thread</tt>: + <a href="ThreadSanitizer.html">ThreadSanitizer</a>, an <em>experimental</em> + data race detector. Not ready for widespread use.</li> +<li id="opt_fsanitize_undefined"><tt>-fsanitize=undefined</tt>: + Enables all the checks listed below.</li> </ul> + +The following more fine-grained checks are also available: + +<ul> +<li id="opt_fsanitize_alignment"><tt>-fsanitize=alignment</tt>: + Use of a misaligned pointer or creation of a misaligned reference.</li> +<li id="opt_fsanitize_divide-by-zero"><tt>-fsanitize=divide-by-zero</tt>: + Division by zero.</li> +<li id="opt_fsanitize_float-cast-overflow"><tt>-fsanitize=float-cast-overflow</tt>: + Conversion to, from, or between floating-point types which would overflow + the destination.</li> +<li id="opt_fsanitize_null"><tt>-fsanitize=null</tt>: + Use of a null pointer or creation of a null reference.</li> +<li id="opt_fsanitize_object-size"><tt>-fsanitize=object-size</tt>: + An attempt to use bytes which the optimizer can determine are not part of + the object being accessed. + The sizes of objects are determined using <tt>__builtin_object_size</tt>, and + consequently may be able to detect more problems at higher optimization + levels.</li> +<li id="opt_fsanitize_return"><tt>-fsanitize=return</tt>: + In C++, reaching the end of a value-returning function without returning a + value.</li> +<li id="opt_fsanitize_shift"><tt>-fsanitize=shift</tt>: + Shift operators where the amount shifted is greater or equal to the + promoted bit-width of the left hand side or less than zero, or where + the left hand side is negative. For a signed left shift, also checks + for signed overflow in C, and for unsigned overflow in C++.</li> +<li id="opt_fsanitize_signed-integer-overflow"><tt>-fsanitize=signed-integer-overflow</tt>: + Signed integer overflow, including all the checks added by <tt>-ftrapv</tt>, + and checking for overflow in signed division (<tt>INT_MIN / -1</tt>).</li> +<li id="opt_fsanitize_unreachable"><tt>-fsanitize=unreachable</tt>: + If control flow reaches __builtin_unreachable.</li> +<li id="opt_fsanitize_vla-bound"><tt>-fsanitize=vla-bound</tt>: + A variable-length array whose bound does not evaluate to a positive value.</li> +<li id="opt_fsanitize_vptr"><tt>-fsanitize=vptr</tt>: + Use of an object whose vptr indicates that it is of the wrong dynamic type, + or that its lifetime has not begun or has ended. Incompatible with + <tt>-fno-rtti</tt>.</li> +</ul> + +The <tt>-fsanitize=</tt> argument must also be provided when linking, in order +to link to the appropriate runtime library. It is not possible to combine the +<tt>-fsanitize=address</tt> and <tt>-fsanitize=thread</tt> checkers in the same +program. </dd> <dt id="opt_faddress-sanitizer"><b>-f[no-]address-sanitizer</b>: -Turn on <a href="AddressSanitizer.html">AddressSanitizer</a>, -a memory error detector. +Deprecated synonym for <a href="#opt_fsanitize_address"><tt>-f[no-]sanitize=address</tt></a>. <dt id="opt_fthread-sanitizer"><b>-f[no-]thread-sanitizer</b>: -Turn on ThreadSanitizer, an <em>experimental</em> data race detector. -Not ready for widespread use. +Deprecated synonym for <a href="#opt_fsanitize_address"><tt>-f[no-]sanitize=thread</tt></a>. + +<dt id="opt_fcatch-undefined-behavior"><b>-fcatch-undefined-behavior</b>: +Deprecated synonym for <a href="#opt_fsanitize_undefined"><tt>-fsanitize=undefined</tt></a>. <dt id="opt_fno-assume-sane-operator-new"><b>-fno-assume-sane-operator-new</b>: Don't assume that the C++'s new operator is sane.</dt> diff --git a/docs/analyzer/IPA.txt b/docs/analyzer/IPA.txt index 5691977..016cea9 100644 --- a/docs/analyzer/IPA.txt +++ b/docs/analyzer/IPA.txt @@ -1,96 +1,355 @@ Inlining ======== -Inlining Modes ------------------------ --analyzer-ipa=none - All inlining is disabled. --analyzer-ipa=inlining - Turns on inlining when we can confidently find the function/method body corresponding to the call. (C functions, static functions, devirtualized C++ methods, ObjC class methods, ObjC instance methods when we are confident about the dynamic type of the instance). --analyzer-ipa=dynamic - Inline instance methods for which the type is determined at runtime and we are not 100% sure that our type info is correct. For virtual calls, inline the most plausible definition. --analyzer-ipa=dynamic-bifurcate - Same as -analyzer-ipa=dynamic, but the path is split. We inline on one branch and do not inline on the other. This mode does not drop the coverage in cases when the parent class has code that is only exercised when some of its methods are overriden. +There are several options that control which calls the analyzer will consider for +inlining. The major one is -analyzer-ipa: + + -analyzer-ipa=none - All inlining is disabled. This is the only mode available + in LLVM 3.1 and earlier and in Xcode 4.3 and earlier. + + -analyzer-ipa=basic-inlining - Turns on inlining for C functions, C++ static + member functions, and blocks -- essentially, the calls that behave like + simple C function calls. This is essentially the mode used in Xcode 4.4. + + -analyzer-ipa=inlining - Turns on inlining when we can confidently find the + function/method body corresponding to the call. (C functions, static + functions, devirtualized C++ methods, Objective-C class methods, Objective-C + instance methods when ExprEngine is confident about the dynamic type of the + instance). + + -analyzer-ipa=dynamic - Inline instance methods for which the type is + determined at runtime and we are not 100% sure that our type info is + correct. For virtual calls, inline the most plausible definition. + + -analyzer-ipa=dynamic-bifurcate - Same as -analyzer-ipa=dynamic, but the path + is split. We inline on one branch and do not inline on the other. This mode + does not drop the coverage in cases when the parent class has code that is + only exercised when some of its methods are overridden. + +Currently, -analyzer-ipa=dynamic-bifurcate is the default mode. + +While -analyzer-ipa determines in general how aggressively the analyzer will try to +inline functions, several additional options control which types of functions can +inlined, in an all-or-nothing way. These options use the analyzer's configuration +table, so they are all specified as follows: + + -analyzer-config OPTION=VALUE + +### c++-inlining ### + +This option controls which C++ member functions may be inlined. + + -analyzer-config c++-inlining=[none | methods | constructors | destructors] + +Each of these modes implies that all the previous member function kinds will be +inlined as well; it doesn't make sense to inline destructors without inlining +constructors, for example. + +The default c++-inlining mode is 'methods', meaning only regular member +functions and overloaded operators will be inlined. Note that no C++ member +functions will be inlined under -analyzer-ipa=none or +-analyzer-ipa=basic-inlining. + +### c++-template-inlining ### + +This option controls whether C++ templated functions may be inlined. + + -analyzer-config c++-template-inlining=[true | false] + +Currently, template functions are considered for inlining by default. + +The motivation behind this option is that very generic code can be a source +of false positives, either by considering paths that the caller considers +impossible (by some unstated precondition), or by inlining some but not all +of a deep implementation of a function. + +### c++-stdlib-inlining ### + +This option controls whether functions from the C++ standard library, including +methods of the container classes in the Standard Template Library, should be +considered for inlining. + + -analyzer-config c++-template-inlining=[true | false] + +Currently, C++ standard library functions are NOT considered for inlining by default. + +The standard library functions and the STL in particular are used ubiquitously +enough that our tolerance for false positives is even lower here. A false +positive due to poor modeling of the STL leads to a poor user experience, since +most users would not be comfortable adding assertions to system headers in order +to silence analyzer warnings. -Currently, -analyzer-ipa=inlining is the default mode. Basics of Implementation ----------------------- -The low-level mechanism of inlining a function is handled in ExprEngine::inlineCall and ExprEngine::processCallExit. If the conditions are right for inlining, a CallEnter node is created and added to the analysis work list. The CallEnter node marks the change to a new LocationContext representing the called function, and its state includes the contents of the new stack frame. When the CallEnter node is actually processed, its single successor will be a edge to the first CFG block in the function. +The low-level mechanism of inlining a function is handled in +ExprEngine::inlineCall and ExprEngine::processCallExit. + +If the conditions are right for inlining, a CallEnter node is created and added +to the analysis work list. The CallEnter node marks the change to a new +LocationContext representing the called function, and its state includes the +contents of the new stack frame. When the CallEnter node is actually processed, +its single successor will be a edge to the first CFG block in the function. + +Exiting an inlined function is a bit more work, fortunately broken up into +reasonable steps: + +1. The CoreEngine realizes we're at the end of an inlined call and generates a + CallExitBegin node. -Exiting an inlined function is a bit more work, fortunately broken up into reasonable steps: -1. The CoreEngine realizes we're at the end of an inlined call and generates a CallExitBegin node. -2. ExprEngine takes over (in processCallExit) and finds the return value of the function, if it has one. This is bound to the expression that triggered the call. (In the case of calls without origin expressions, such as destructors, this step is skipped.) -3. Dead symbols and bindings are cleaned out from the state, including any local bindings. -4. A CallExitEnd node is generated, which marks the transition back to the caller's LocationContext. -5. Custom post-call checks are processed and the final nodes are pushed back onto the work list, so that evaluation of the caller can continue. +2. ExprEngine takes over (in processCallExit) and finds the return value of the + function, if it has one. This is bound to the expression that triggered the + call. (In the case of calls without origin expressions, such as destructors, + this step is skipped.) + +3. Dead symbols and bindings are cleaned out from the state, including any local + bindings. + +4. A CallExitEnd node is generated, which marks the transition back to the + caller's LocationContext. + +5. Custom post-call checks are processed and the final nodes are pushed back + onto the work list, so that evaluation of the caller can continue. Retry Without Inlining ------------------------ +---------------------- -In some cases, we would like to retry analyzes without inlining the particular call. Currently, we use this technique to recover the coverage in case we stop analyzing a path due to exceeding the maximum block count inside an inlined function. When this situation is detected, we walk up the path to find the first node before inlining was started and enqueue it on the WorkList with a special ReplayWithoutInlining bit added to it (ExprEngine::replayWithoutInlining). +In some cases, we would like to retry analysis without inlining a particular +call. -Deciding when to inline +Currently, we use this technique to recover coverage in case we stop +analyzing a path due to exceeding the maximum block count inside an inlined +function. + +When this situation is detected, we walk up the path to find the first node +before inlining was started and enqueue it on the WorkList with a special +ReplayWithoutInlining bit added to it (ExprEngine::replayWithoutInlining). The +path is then re-analyzed from that point without inlining that particular call. + +Deciding When to Inline ----------------------- -In general, we try to inline as much as possible, since it provides a better summary of what actually happens in the program. However, there are some cases where we choose not to inline: -- if there is no definition available (of course) -- if we can't create a CFG or compute variable liveness for the function -- if we reach a cutoff of maximum stack depth (to avoid infinite recursion) -- if the function is variadic -- in C++, we don't inline constructors unless we know the destructor will be inlined as well -- in C++, we don't inline allocators (custom operator new implementations), since we don't properly handle deallocators (at the time of this writing) -- "Dynamic" calls are handled specially; see below. -- Engine:FunctionSummaries map stores additional information about declarations, some of which is collected at runtime based on previous analyzes of the function. We do not inline functions which were not profitable to inline in a different context (for example, if the maximum block count was exceeded, see Retry Without Inlining). - - -Dynamic calls and devirtualization + +In general, the analyzer attempts to inline as much as possible, since it +provides a better summary of what actually happens in the program. There are +some cases, however, where the analyzer chooses not to inline: + +- If there is no definition available for the called function or method. In + this case, there is no opportunity to inline. + +- If the CFG cannot be constructed for a called function, or the liveness + cannot be computed. These are prerequisites for analyzing a function body, + with or without inlining. + +- If the LocationContext chain for a given ExplodedNode reaches a maximum cutoff + depth. This prevents unbounded analysis due to infinite recursion, but also + serves as a useful cutoff for performance reasons. + +- If the function is variadic. This is not a hard limitation, but an engineering + limitation. + + Tracked by: <rdar://problem/12147064> Support inlining of variadic functions + +- In C++, constructors are not inlined unless the destructor call will be + processed by the ExprEngine. Thus, if the CFG was built without nodes for + implicit destructors, or if the destructors for the given object are not + represented in the CFG, the constructor will not be inlined. (As an exception, + constructors for objects with trivial constructors can still be inlined.) + See "C++ Caveats" below. + +- In C++, ExprEngine does not inline custom implementations of operator 'new' + or operator 'delete', nor does it inline the constructors and destructors + associated with these. See "C++ Caveats" below. + +- Calls resulting in "dynamic dispatch" are specially handled. See more below. + +- The FunctionSummaries map stores additional information about declarations, + some of which is collected at runtime based on previous analyses. + We do not inline functions which were not profitable to inline in a different + context (for example, if the maximum block count was exceeded; see + "Retry Without Inlining"). + + +Dynamic Calls and Devirtualization ---------------------------------- -"Dynamic" calls are those that are resolved at runtime, such as C++ virtual method calls and Objective-C message sends. Due to the path-sensitive nature of the analyzer, we may be able to figure out the dynamic type of the object whose method is being called and thus "devirtualize" the call, i.e. find the actual method that will be called at runtime. (Obviously this is not always possible.) This is handled by CallEvent's getRuntimeDefinition method. -Type information is tracked as DynamicTypeInfo, stored within the program state. If no DynamicTypeInfo has been explicitly set for a region, it will be inferred from the region's type or associated symbol. Information from symbolic regions is weaker than from true typed regions; a C++ object declared "A obj" is known to have the class 'A', but a reference "A &ref" may dynamically be a subclass of 'A'. The DynamicTypePropagation checker gathers and propagates the type information. +"Dynamic" calls are those that are resolved at runtime, such as C++ virtual +method calls and Objective-C message sends. Due to the path-sensitive nature of +the analysis, the analyzer may be able to reason about the dynamic type of the +object whose method is being called and thus "devirtualize" the call. + +This path-sensitive devirtualization occurs when the analyzer can determine what +method would actually be called at runtime. This is possible when the type +information is constrained enough for a simulated C++/Objective-C object that +the analyzer can make such a decision. + + == DynamicTypeInfo == + +As the analyzer analyzes a path, it may accrue information to refine the +knowledge about the type of an object. This can then be used to make better +decisions about the target method of a call. + +Such type information is tracked as DynamicTypeInfo. This is path-sensitive +data that is stored in ProgramState, which defines a mapping from MemRegions to +an (optional) DynamicTypeInfo. + +If no DynamicTypeInfo has been explicitly set for a MemRegion, it will be lazily +inferred from the region's type or associated symbol. Information from symbolic +regions is weaker than from true typed regions. + + EXAMPLE: A C++ object declared "A obj" is known to have the class 'A', but a + reference "A &ref" may dynamically be a subclass of 'A'. + +The DynamicTypePropagation checker gathers and propagates DynamicTypeInfo, +updating it as information is observed along a path that can refine that type +information for a region. -(Warning: not all of the existing analyzer code has been retrofitted to use DynamicTypeInfo, nor is it universally appropriate. In particular, DynamicTypeInfo always applies to a region with all casts stripped off, but sometimes the information provided by casts can be useful.) + WARNING: Not all of the existing analyzer code has been retrofitted to use + DynamicTypeInfo, nor is it universally appropriate. In particular, + DynamicTypeInfo always applies to a region with all casts stripped + off, but sometimes the information provided by casts can be useful. -When asked to provide a definition, the CallEvents for dynamic calls will use the type info in their state to provide the best definition of the method to be called. In some cases this devirtualization can be perfect or near-perfect, and we can inline the definition as usual. In others we can make a guess, but report that our guess may not be the method actually called at runtime. -The -analyzer-ipa option has four different modes: none, inlining, dynamic, and dynamic-bifurcate. Under -analyzer-ipa=dynamic, all dynamic calls are inlined, whether we are certain or not that this will actually be the definition used at runtime. Under -analyzer-ipa=inlining, only "near-perfect" devirtualized calls are inlined*, and other dynamic calls are evaluated conservatively (as if no definition were available). + == RuntimeDefinition == -* Currently, no Objective-C messages are not inlined under -analyzer-ipa=inlining, even if we are reasonably confident of the type of the receiver. We plan to enable this once we have tested our heuristics more thoroughly. +The basis of devirtualization is CallEvent's getRuntimeDefinition() method, +which returns a RuntimeDefinition object. When asked to provide a definition, +the CallEvents for dynamic calls will use the DynamicTypeInfo in their +ProgramState to attempt to devirtualize the call. In the case of no dynamic +dispatch, or perfectly constrained devirtualization, the resulting +RuntimeDefinition contains a Decl corresponding to the definition of the called +function, and RuntimeDefinition::mayHaveOtherDefinitions will return FALSE. -The last option, -analyzer-ipa=dynamic-bifurcate, behaves similarly to "dynamic", but performs a conservative invalidation in the general virtual case in /addition/ to inlining. The details of this are discussed below. +In the case of dynamic dispatch where our information is not perfect, CallEvent +can make a guess, but RuntimeDefinition::mayHaveOtherDefinitions will return +TRUE. The RuntimeDefinition object will then also include a MemRegion +corresponding to the object being called (i.e., the "receiver" in Objective-C +parlance), which ExprEngine uses to decide whether or not the call should be +inlined. + + == Inlining Dynamic Calls == + +The -analyzer-ipa option has five different modes: none, basic-inlining, +inlining, dynamic, and dynamic-bifurcate. Under -analyzer-ipa=dynamic, all +dynamic calls are inlined, whether we are certain or not that this will actually +be the definition used at runtime. Under -analyzer-ipa=inlining, only +"near-perfect" devirtualized calls are inlined*, and other dynamic calls are +evaluated conservatively (as if no definition were available). + +* Currently, no Objective-C messages are not inlined under + -analyzer-ipa=inlining, even if we are reasonably confident of the type of the + receiver. We plan to enable this once we have tested our heuristics more + thoroughly. + +The last option, -analyzer-ipa=dynamic-bifurcate, behaves similarly to +"dynamic", but performs a conservative invalidation in the general virtual case +in *addition* to inlining. The details of this are discussed below. + +As stated above, -analyzer-ipa=basic-inlining does not inline any C++ member +functions or Objective-C method calls, even if they are non-virtual or can be +safely devirtualized. Bifurcation ----------- -ExprEngine::BifurcateCall implements the -analyzer-ipa=dynamic-bifurcate mode. When a call is made on a region with dynamic type information, we bifurcate the path and add the region's processing mode to the GDM. Currently, there are 2 modes: DynamicDispatchModeInlined and DynamicDispatchModeConservative. Going forward, we consult the state of the region to make decisions on whether the calls should be inlined or not, which ensures that we have at most one split per region. The modes model the cases when the dynamic type information is perfectly correct and when the info is not correct (i.e. where the region is a subclass of the type we store in DynamicTypeInfo). -Bifurcation mode allows for increased coverage in cases where the parent method contains code which is only executed when the class is subclassed. The disadvantages of this mode are a (considerable?) performance hit and the possibility of false positives on the path where the conservative mode is used. +ExprEngine::BifurcateCall implements the -analyzer-ipa=dynamic-bifurcate +mode. + +When a call is made on an object with imprecise dynamic type information +(RuntimeDefinition::mayHaveOtherDefinitions() evaluates to TRUE), ExprEngine +bifurcates the path and marks the object's region (retrieved from the +RuntimeDefinition object) with a path-sensitive "mode" in the ProgramState. + +Currently, there are 2 modes: + + DynamicDispatchModeInlined - Models the case where the dynamic type information + of the receiver (MemoryRegion) is assumed to be perfectly constrained so + that a given definition of a method is expected to be the code actually + called. When this mode is set, ExprEngine uses the Decl from + RuntimeDefinition to inline any dynamically dispatched call sent to this + receiver because the function definition is considered to be fully resolved. + + DynamicDispatchModeConservative - Models the case where the dynamic type + information is assumed to be incorrect, for example, implies that the method + definition is overriden in a subclass. In such cases, ExprEngine does not + inline the methods sent to the receiver (MemoryRegion), even if a candidate + definition is available. This mode is conservative about simulating the + effects of a call. +Going forward along the symbolic execution path, ExprEngine consults the mode +of the receiver's MemRegion to make decisions on whether the calls should be +inlined or not, which ensures that there is at most one split per region. + +At a high level, "bifurcation mode" allows for increased semantic coverage in +cases where the parent method contains code which is only executed when the +class is subclassed. The disadvantages of this mode are a (considerable?) +performance hit and the possibility of false positives on the path where the +conservative mode is used. Objective-C Message Heuristics ------------------------------ -We rely on a set of heuristics to partition the set of ObjC method calls into ones that require bifurcation and ones that do not (can or cannot be a subclass). Below are the cases when we consider that the dynamic type of the object is precise (cannot be a subclass): - - If the object was created with +alloc or +new and initialized with an -init method. - - If the calls are property accesses using dot syntax. This is based on the assumption that children rarely override properties, or do so in an essentially compatible way. - - If the class interface is declared inside the main source file. In this case it is unlikely that it will be subclassed. - - If the method is not declared outside of main source file, either by the receiver's class or by any superclasses. +ExprEngine relies on a set of heuristics to partition the set of Objective-C +method calls into those that require bifurcation and those that do not. Below +are the cases when the DynamicTypeInfo of the object is considered precise +(cannot be a subclass): + + - If the object was created with +alloc or +new and initialized with an -init + method. + + - If the calls are property accesses using dot syntax. This is based on the + assumption that children rarely override properties, or do so in an + essentially compatible way. + + - If the class interface is declared inside the main source file. In this case + it is unlikely that it will be subclassed. -C++ Inlining Caveats + - If the method is not declared outside of main source file, either by the + receiver's class or by any superclasses. + +C++ Caveats -------------------- -C++11 [class.cdtor]p4 describes how the vtable of an object is modified as it is being constructed or destructed; that is, the type of the object depends on which base constructors have been completed. This is tracked using dynamic type info in the DynamicTypePropagation checker. -Temporaries are poorly modelled right now because we're not confident in the placement +C++11 [class.cdtor]p4 describes how the vtable of an object is modified as it is +being constructed or destructed; that is, the type of the object depends on +which base constructors have been completed. This is tracked using +DynamicTypeInfo in the DynamicTypePropagation checker. + +There are several limitations in the current implementation: -'new' is poorly modelled due to some nasty CFG/design issues (elaborated in PR12014). 'delete' is essentially not modelled at all. +- Temporaries are poorly modeled right now because we're not confident in the + placement of their destructors in the CFG. We currently won't inline their + constructors unless the destructor is trivial, and don't process their + destructors at all, not even to invalidate the region. -Arrays of objects are modeled very poorly right now. We run only the first constructor and first destructor. Because of this, we don't inline any constructors or destructors for arrays. +- 'new' is poorly modeled due to some nasty CFG/design issues. This is tracked + in PR12014. 'delete' is not modeled at all. + +- Arrays of objects are modeled very poorly right now. ExprEngine currently + only simulates the first constructor and first destructor. Because of this, + ExprEngine does not inline any constructors or destructors for arrays. CallEvent ========= -A CallEvent represents a specific call to a function, method, or other body of code. It is path-sensitive, containing both the current state (ProgramStateRef) and stack space (LocationContext), and provides uniform access to the argument values and return type of a call, no matter how the call is written in the source or what sort of code body is being invoked. +A CallEvent represents a specific call to a function, method, or other body of +code. It is path-sensitive, containing both the current state (ProgramStateRef) +and stack space (LocationContext), and provides uniform access to the argument +values and return type of a call, no matter how the call is written in the +source or what sort of code body is being invoked. + + NOTE: For those familiar with Cocoa, CallEvent is roughly equivalent to + NSInvocation. -(For those familiar with Cocoa, CallEvent is roughly equivalent to NSInvocation.) +CallEvent should be used whenever there is logic dealing with function calls +that does not care how the call occurred. -CallEvent should be used whenever there is logic dealing with function calls that does not care how the call occurred. Examples include checking that arguments satisfy preconditions (such as __attribute__((nonnull))), and attempting to inline a call. +Examples include checking that arguments satisfy preconditions (such as +__attribute__((nonnull))), and attempting to inline a call. -CallEvents are reference-counted objects managed by a CallEventManager. While there is no inherent issue with persisting them (say, in the state's GDM), they are intended for short-lived use, and can be recreated from CFGElements or StackFrameContexts fairly easily. +CallEvents are reference-counted objects managed by a CallEventManager. While +there is no inherent issue with persisting them (say, in a ProgramState's GDM), +they are intended for short-lived use, and can be recreated from CFGElements or +non-top-level StackFrameContexts fairly easily. diff --git a/docs/analyzer/debug-checks.txt b/docs/analyzer/debug-checks.txt new file mode 100644 index 0000000..6ac451f --- /dev/null +++ b/docs/analyzer/debug-checks.txt @@ -0,0 +1,89 @@ +The analyzer contains a number of checkers which can aid in debugging. Enable them by using the "-analyzer-checker=" flag, followed by the name of the checker. + +General Analysis Dumpers +======================== +These checkers are used to dump the results of various infrastructural analyses to stderr. Some checkers also have "view" variants, which will display a graph using a 'dot' format viewer (such as Graphviz on OS X) instead. + +- debug.DumpCallGraph, debug.ViewCallGraph: Show the call graph generated for the current translation unit. This is used to determine the order in which to analyze functions when inlining is enabled. +- debug.DumpCFG, debug.ViewCFG: Show the CFG generated for each top-level function being analyzed. +- debug.DumpDominators: Shows the dominance tree for the CFG of each top-level function. +- debug.DumpLiveVars: Show the results of live variable analysis for each top-level function being analyzed. + + +Path Tracking +============= +These checkers print information about the path taken by the analyzer engine. + +- debug.DumpCalls: Prints out every function or method call encountered during a path traversal. This is indented to show the call stack, but does NOT do any special handling of branches, meaning different paths could end up interleaved. +- debug.DumpTraversal: Prints the name of each branch statement encountered during a path traversal ("IfStmt", "WhileStmt", etc). Currently used to check whether the analysis engine is doing BFS or DFS. + + +State Checking +============== +These checkers will print out information about the analyzer state in the form of analysis warnings. They are intended for use with the -verify functionality in regression tests. + +- debug.TaintTest: Prints out the word "tainted" for every expression that carries taint. At the time of this writing, taint was only introduced by the checks under experimental.security.taint.TaintPropagation; this checker may eventually move to the security.taint package. +- debug.ExprInspection: Responds to certain function calls, which are modeled after builtins. These function calls should affect the program state other than the evaluation of their arguments; to use them, you will need to declare them within your test file. The available functions are described below. + +(FIXME: debug.ExprInspection should probably be renamed, since it no longer only inspects expressions.) + + +ExprInspection checks +--------------------- + +- void clang_analyzer_eval(bool); + +Prints TRUE if the argument is known to have a non-zero value, + FALSE if the argument is known to have a zero or null value, and + UNKNOWN if the argument isn't sufficiently constrained on this path. +You can use this to test other values by using expressions like "x == 5". +Note that this functionality is currently DISABLED in inlined functions, +since different calls to the same inlined function could provide different +information, making it difficult to write proper -verify directives. + +In C, the argument can be typed as 'int' or as '_Bool'. + +Example usage: + clang_analyzer_eval(x); // expected-warning{{UNKNOWN}} + if (!x) return; + clang_analyzer_eval(x); // expected-warning{{TRUE}} + + +- void clang_analyzer_checkInlined(bool); + +If a call occurs within an inlined function, prints TRUE or FALSE according to +the value of its argument. If a call occurs outside an inlined function, +nothing is printed. + +The intended use of this checker is to assert that a function is inlined at +least once (by passing 'true' and expecting a warning), or to assert that a +function is never inlined (by passing 'false' and expecting no warning). The +argument is technically unnecessary but is intended to clarify intent. + +You might wonder why we can't print TRUE if a function is ever inlined and +FALSE if it is not. The problem is that any inlined function could conceivably +also be analyzed as a top-level function (in which case both TRUE and FALSE +would be printed), depending on the value of the -analyzer-inlining option. + +In C, the argument can be typed as 'int' or as '_Bool'. + +Example usage: + int inlined() { + clang_analyzer_checkInlined(true); // expected-warning{{TRUE}} + return 42; + } + + void topLevel() { + clang_analyzer_checkInlined(false); // no-warning (not inlined) + int value = inlined(); + // This assertion will not be valid if the previous call was not inlined. + clang_analyzer_eval(value == 42); // expected-warning{{TRUE}} + } + + + +Statistics +========== +The debug.Stats checker collects various information about the analysis of each function, such as how many blocks were reached and if the analyzer timed out. + +There is also an additional -analyzer-stats flag, which enables various statistics within the analyzer engine. Note the Stats checker (which produces at least one bug report per function) may actually change the values reported by -analyzer-stats. diff --git a/docs/tools/clang.pod b/docs/tools/clang.pod index 425a91e..9628d47 100644 --- a/docs/tools/clang.pod +++ b/docs/tools/clang.pod @@ -132,7 +132,7 @@ Treat subsequent input files as having type I<language>. Specify the language standard to compile for. -=item B<-stdlib>=I<language> +=item B<-stdlib>=I<library> Specify the C++ standard library to use; supported options are libstdc++ and libc++. diff --git a/docs/tools/dump_ast_matchers.py b/docs/tools/dump_ast_matchers.py new file mode 100644 index 0000000..bc5f1a6 --- /dev/null +++ b/docs/tools/dump_ast_matchers.py @@ -0,0 +1,264 @@ +#!/usr/bin/env python +# A tool to parse ASTMatchers.h and update the documentation in +# ../LibASTMatchersReference.html automatically. Run from the +# directory in which this file is located to update the docs. + +import collections +import re +import urllib2 + +MATCHERS_FILE = '../../include/clang/ASTMatchers/ASTMatchers.h' + +# Each matcher is documented in one row of the form: +# result | name | argA +# The subsequent row contains the documentation and is hidden by default, +# becoming visible via javascript when the user clicks the matcher name. +TD_TEMPLATE=""" +<tr><td>%(result)s</td><td class="name" onclick="toggle('%(id)s')"><a name="%(id)sAnchor">%(name)s</a></td><td>%(args)s</td></tr> +<tr><td colspan="4" class="doc" id="%(id)s"><pre>%(comment)s</pre></td></tr> +""" + +# We categorize the matchers into these three categories in the reference: +node_matchers = {} +narrowing_matchers = {} +traversal_matchers = {} + +# We output multiple rows per matcher if the matcher can be used on multiple +# node types. Thus, we need a new id per row to control the documentation +# pop-up. ids[name] keeps track of those ids. +ids = collections.defaultdict(int) + +# Cache for doxygen urls we have already verified. +doxygen_probes = {} + +def esc(text): + """Escape any html in the given text.""" + text = re.sub(r'&', '&', text) + text = re.sub(r'<', '<', text) + text = re.sub(r'>', '>', text) + def link_if_exists(m): + name = m.group(1) + url = 'http://clang.llvm.org/doxygen/classclang_1_1%s.html' % name + if url not in doxygen_probes: + try: + print 'Probing %s...' % url + urllib2.urlopen(url) + doxygen_probes[url] = True + except: + doxygen_probes[url] = False + if doxygen_probes[url]: + return r'Matcher<<a href="%s">%s</a>>' % (url, name) + else: + return m.group(0) + text = re.sub( + r'Matcher<([^\*&]+)>', link_if_exists, text) + return text + +def extract_result_types(comment): + """Extracts a list of result types from the given comment. + + We allow annotations in the comment of the matcher to specify what + nodes a matcher can match on. Those comments have the form: + Usable as: Any Matcher | (Matcher<T1>[, Matcher<t2>[, ...]]) + + Returns ['*'] in case of 'Any Matcher', or ['T1', 'T2', ...]. + Returns the empty list if no 'Usable as' specification could be + parsed. + """ + result_types = [] + m = re.search(r'Usable as: Any Matcher[\s\n]*$', comment, re.S) + if m: + return ['*'] + while True: + m = re.match(r'^(.*)Matcher<([^>]+)>\s*,?[\s\n]*$', comment, re.S) + if not m: + if re.search(r'Usable as:\s*$', comment): + return result_types + else: + return None + result_types += [m.group(2)] + comment = m.group(1) + +def strip_doxygen(comment): + """Returns the given comment without \-escaped words.""" + # If there is only a doxygen keyword in the line, delete the whole line. + comment = re.sub(r'^\\[^\s]+\n', r'', comment, flags=re.M) + # Delete the doxygen command and the following whitespace. + comment = re.sub(r'\\[^\s]+\s+', r'', comment) + return comment + +def unify_arguments(args): + """Gets rid of anything the user doesn't care about in the argument list.""" + args = re.sub(r'internal::', r'', args) + args = re.sub(r'const\s+', r'', args) + args = re.sub(r'&', r' ', args) + args = re.sub(r'(^|\s)M\d?(\s)', r'\1Matcher<*>\2', args) + return args + +def add_matcher(result_type, name, args, comment, is_dyncast=False): + """Adds a matcher to one of our categories.""" + if name == 'id': + # FIXME: Figure out whether we want to support the 'id' matcher. + return + matcher_id = '%s%d' % (name, ids[name]) + ids[name] += 1 + args = unify_arguments(args) + matcher_html = TD_TEMPLATE % { + 'result': esc('Matcher<%s>' % result_type), + 'name': name, + 'args': esc(args), + 'comment': esc(strip_doxygen(comment)), + 'id': matcher_id, + } + if is_dyncast: + node_matchers[result_type + name] = matcher_html + # Use a heuristic to figure out whether a matcher is a narrowing or + # traversal matcher. By default, matchers that take other matchers as + # arguments (and are not node matchers) do traversal. We specifically + # exclude known narrowing matchers that also take other matchers as + # arguments. + elif ('Matcher<' not in args or + name in ['allOf', 'anyOf', 'anything', 'unless']): + narrowing_matchers[result_type + name] = matcher_html + else: + traversal_matchers[result_type + name] = matcher_html + +def act_on_decl(declaration, comment, allowed_types): + """Parse the matcher out of the given declaration and comment. + + If 'allowed_types' is set, it contains a list of node types the matcher + can match on, as extracted from the static type asserts in the matcher + definition. + """ + if declaration.strip(): + # Node matchers are defined by writing: + # VariadicDynCastAllOfMatcher<ResultType, ArgumentType> name; + m = re.match(r""".*VariadicDynCastAllOfMatcher\s*< + \s*([^\s,]+)\s*, + \s*([^\s>]+)\s*> + \s*([^\s;]+)\s*;\s*$""", declaration, flags=re.X) + if m: + result, inner, name = m.groups() + add_matcher(result, name, 'Matcher<%s>...' % inner, + comment, is_dyncast=True) + return + + # Parse the various matcher definition macros. + m = re.match(r"""^\s*AST_(POLYMORPHIC_)?MATCHER(_P)?(.?)\( + (?:\s*([^\s,]+)\s*,)? + \s*([^\s,]+)\s* + (?:,\s*([^\s,]+)\s* + ,\s*([^\s,]+)\s*)? + (?:,\s*([^\s,]+)\s* + ,\s*([^\s,]+)\s*)? + \)\s*{\s*$""", declaration, flags=re.X) + if m: + p, n, result, name = m.groups()[1:5] + args = m.groups()[5:] + if not result: + if not allowed_types: + raise Exception('Did not find allowed result types for: %s' % name) + result_types = allowed_types + else: + result_types = [result] + if n not in ['', '2']: + raise Exception('Cannot parse "%s"' % declaration) + args = ', '.join('%s %s' % (args[i], args[i+1]) + for i in range(0, len(args), 2) if args[i]) + for result_type in result_types: + add_matcher(result_type, name, args, comment) + return + + # Parse free standing matcher functions, like: + # Matcher<ResultType> Name(Matcher<ArgumentType> InnerMatcher) { + m = re.match(r"""^\s*(.*)\s+ + ([^\s\(]+)\s*\( + (.*) + \)\s*{""", declaration, re.X) + if m: + result, name, args = m.groups() + args = ', '.join(p.strip() for p in args.split(',')) + m = re.match(r'.*\s+internal::Matcher<([^>]+)>$', result) + if m: + result_types = [m.group(1)] + else: + result_types = extract_result_types(comment) + if not result_types: + if not comment: + # Only overloads don't have their own doxygen comments; ignore those. + print 'Ignoring "%s"' % name + else: + print 'Cannot determine result type for "%s"' % name + else: + for result_type in result_types: + add_matcher(result_type, name, args, comment) + else: + print '*** Unparsable: "' + declaration + '" ***' + +def sort_table(matcher_type, matcher_map): + """Returns the sorted html table for the given row map.""" + table = '' + for key in sorted(matcher_map.keys()): + table += matcher_map[key] + '\n' + return ('<!-- START_%(type)s_MATCHERS -->\n' + + '%(table)s' + + '<!--END_%(type)s_MATCHERS -->') % { + 'type': matcher_type, + 'table': table, + } + +# Parse the ast matchers. +# We alternate between two modes: +# body = True: We parse the definition of a matcher. We need +# to parse the full definition before adding a matcher, as the +# definition might contain static asserts that specify the result +# type. +# body = False: We parse the comments and declaration of the matcher. +comment = '' +declaration = '' +allowed_types = [] +body = False +for line in open(MATCHERS_FILE).read().splitlines(): + if body: + if line.strip() and line[0] == '}': + if declaration: + act_on_decl(declaration, comment, allowed_types) + comment = '' + declaration = '' + allowed_types = [] + body = False + else: + m = re.search(r'is_base_of<([^,]+), NodeType>', line) + if m and m.group(1): + allowed_types += [m.group(1)] + continue + if line.strip() and line.lstrip()[0] == '/': + comment += re.sub(r'/+\s?', '', line) + '\n' + else: + declaration += ' ' + line + if ((not line.strip()) or + line.rstrip()[-1] == ';' or + line.rstrip()[-1] == '{'): + if line.strip() and line.rstrip()[-1] == '{': + body = True + else: + act_on_decl(declaration, comment, allowed_types) + comment = '' + declaration = '' + allowed_types = [] + +node_matcher_table = sort_table('DECL', node_matchers) +narrowing_matcher_table = sort_table('NARROWING', narrowing_matchers) +traversal_matcher_table = sort_table('TRAVERSAL', traversal_matchers) + +reference = open('../LibASTMatchersReference.html').read() +reference = re.sub(r'<!-- START_DECL_MATCHERS.*END_DECL_MATCHERS -->', + '%s', reference, flags=re.S) % node_matcher_table +reference = re.sub(r'<!-- START_NARROWING_MATCHERS.*END_NARROWING_MATCHERS -->', + '%s', reference, flags=re.S) % narrowing_matcher_table +reference = re.sub(r'<!-- START_TRAVERSAL_MATCHERS.*END_TRAVERSAL_MATCHERS -->', + '%s', reference, flags=re.S) % traversal_matcher_table + +with open('../LibASTMatchersReference.html', 'w') as output: + output.write(reference) + |