diff options
author | dim <dim@FreeBSD.org> | 2015-12-30 11:49:41 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-12-30 11:49:41 +0000 |
commit | 3176e97f130184ece0e1a21352c8124cc83ff24a (patch) | |
tree | 0a5b74c0b9ca73aded34df95c91fcaf3815230d8 /docs | |
parent | 1e9b8d38881c3213d1e67b0c47ab9b2c00721a5c (diff) | |
download | FreeBSD-src-3176e97f130184ece0e1a21352c8124cc83ff24a.zip FreeBSD-src-3176e97f130184ece0e1a21352c8124cc83ff24a.tar.gz |
Vendor import of clang trunk r256633:
https://llvm.org/svn/llvm-project/cfe/trunk@256633
Diffstat (limited to 'docs')
28 files changed, 2483 insertions, 2605 deletions
diff --git a/docs/AddressSanitizer.rst b/docs/AddressSanitizer.rst index 66ed344..93f6314 100644 --- a/docs/AddressSanitizer.rst +++ b/docs/AddressSanitizer.rst @@ -196,12 +196,11 @@ Disabling Instrumentation with ``__attribute__((no_sanitize("address")))`` -------------------------------------------------------------------------- Some code should not be instrumented by AddressSanitizer. One may use the -function attribute ``__attribute__((no_sanitize("address")))`` -(which has deprecated synonyms -:ref:`no_sanitize_address <langext-address_sanitizer>` and -`no_address_safety_analysis`) to disable instrumentation of a particular -function. This attribute may not be supported by other compilers, so we suggest -to use it together with ``__has_feature(address_sanitizer)``. +function attribute ``__attribute__((no_sanitize("address")))`` (which has +deprecated synonyms `no_sanitize_address` and `no_address_safety_analysis`) to +disable instrumentation of a particular function. This attribute may not be +supported by other compilers, so we suggest to use it together with +``__has_feature(address_sanitizer)``. Suppressing Errors in Recompiled Code (Blacklist) ------------------------------------------------- @@ -268,5 +267,4 @@ check-asan`` command. More Information ================ -`http://code.google.com/p/address-sanitizer <http://code.google.com/p/address-sanitizer/>`_ - +`<https://github.com/google/sanitizers/wiki/AddressSanitizer>`_ diff --git a/docs/AttributeReference.rst b/docs/AttributeReference.rst index e282824..a763dde 100644 --- a/docs/AttributeReference.rst +++ b/docs/AttributeReference.rst @@ -1,1760 +1,13 @@ .. ------------------------------------------------------------------- NOTE: This file is automatically generated by running clang-tblgen - -gen-attr-docs. Do not edit this file by hand!! + -gen-attr-docs. Do not edit this file by hand!! The contents for + this file are automatically generated by a server-side process. + + Please do not commit this file. The file exists for local testing + purposes only. ------------------------------------------------------------------- =================== Attributes in Clang -=================== -.. contents:: - :local: - -Introduction -============ - -This page lists the attributes currently supported by Clang. - -AMD GPU Register Attributes -=========================== -Clang supports attributes for controlling register usage on AMD GPU -targets. These attributes may be attached to a kernel function -definition and is an optimization hint to the backend for the maximum -number of registers to use. This is useful in cases where register -limited occupancy is known to be an important factor for the -performance for the kernel. - -The semantics are as follows: - -- The backend will attempt to limit the number of used registers to - the specified value, but the exact number used is not - guaranteed. The number used may be rounded up to satisfy the - allocation requirements or ABI constraints of the subtarget. For - example, on Southern Islands VGPRs may only be allocated in - increments of 4, so requesting a limit of 39 VGPRs will really - attempt to use up to 40. Requesting more registers than the - subtarget supports will truncate to the maximum allowed. The backend - may also use fewer registers than requested whenever possible. - -- 0 implies the default no limit on register usage. - -- Ignored on older VLIW subtargets which did not have separate scalar - and vector registers, R600 through Northern Islands. - -amdgpu_num_sgpr ---------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -Clang supports the -``__attribute__((amdgpu_num_sgpr(<num_registers>)))`` attribute on AMD -Southern Islands GPUs and later for controlling the number of scalar -registers. A typical value would be between 8 and 104 in increments of -8. - -Due to common instruction constraints, an additional 2-4 SGPRs are -typically required for internal use depending on features used. This -value is a hint for the total number of SGPRs to use, and not the -number of user SGPRs, so no special consideration needs to be given -for these. - - -amdgpu_num_vgpr ---------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -Clang supports the -``__attribute__((amdgpu_num_vgpr(<num_registers>)))`` attribute on AMD -Southern Islands GPUs and later for controlling the number of vector -registers. A typical value would be between 4 and 256 in increments -of 4. - - -Function Attributes -=================== - - -interrupt ---------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -Clang supports the GNU style ``__attribute__((interrupt("TYPE")))`` attribute on -ARM targets. This attribute may be attached to a function definition and -instructs the backend to generate appropriate function entry/exit code so that -it can be used directly as an interrupt service routine. - -The parameter passed to the interrupt attribute is optional, but if -provided it must be a string literal with one of the following values: "IRQ", -"FIQ", "SWI", "ABORT", "UNDEF". - -The semantics are as follows: - -- If the function is AAPCS, Clang instructs the backend to realign the stack to - 8 bytes on entry. This is a general requirement of the AAPCS at public - interfaces, but may not hold when an exception is taken. Doing this allows - other AAPCS functions to be called. -- If the CPU is M-class this is all that needs to be done since the architecture - itself is designed in such a way that functions obeying the normal AAPCS ABI - constraints are valid exception handlers. -- If the CPU is not M-class, the prologue and epilogue are modified to save all - non-banked registers that are used, so that upon return the user-mode state - will not be corrupted. Note that to avoid unnecessary overhead, only - general-purpose (integer) registers are saved in this way. If VFP operations - are needed, that state must be saved manually. - - Specifically, interrupt kinds other than "FIQ" will save all core registers - except "lr" and "sp". "FIQ" interrupts will save r0-r7. -- If the CPU is not M-class, the return instruction is changed to one of the - canonical sequences permitted by the architecture for exception return. Where - possible the function itself will make the necessary "lr" adjustments so that - the "preferred return address" is selected. - - Unfortunately the compiler is unable to make this guarantee for an "UNDEF" - handler, where the offset from "lr" to the preferred return address depends on - the execution state of the code which generated the exception. In this case - a sequence equivalent to "movs pc, lr" will be used. - - -acquire_capability (acquire_shared_capability, clang::acquire_capability, clang::acquire_shared_capability) ------------------------------------------------------------------------------------------------------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -Marks a function as acquiring a capability. - - -assert_capability (assert_shared_capability, clang::assert_capability, clang::assert_shared_capability) -------------------------------------------------------------------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -Marks a function that dynamically tests whether a capability is held, and halts -the program if it is not held. - - -assume_aligned (gnu::assume_aligned) ------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -Use ``__attribute__((assume_aligned(<alignment>[,<offset>]))`` on a function -declaration to specify that the return value of the function (which must be a -pointer type) has the specified offset, in bytes, from an address with the -specified alignment. The offset is taken to be zero if omitted. - -.. code-block:: c++ - - // The returned pointer value has 32-byte alignment. - void *a() __attribute__((assume_aligned (32))); - - // The returned pointer value is 4 bytes greater than an address having - // 32-byte alignment. - void *b() __attribute__((assume_aligned (32, 4))); - -Note that this attribute provides information to the compiler regarding a -condition that the code already ensures is true. It does not cause the compiler -to enforce the provided alignment assumption. - - -availability ------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -The ``availability`` attribute can be placed on declarations to describe the -lifecycle of that declaration relative to operating system versions. Consider -the function declaration for a hypothetical function ``f``: - -.. code-block:: c++ - - void f(void) __attribute__((availability(macosx,introduced=10.4,deprecated=10.6,obsoleted=10.7))); - -The availability attribute states that ``f`` was introduced in Mac OS X 10.4, -deprecated in Mac OS X 10.6, and obsoleted in Mac OS X 10.7. This information -is used by Clang to determine when it is safe to use ``f``: for example, if -Clang is instructed to compile code for Mac OS X 10.5, a call to ``f()`` -succeeds. If Clang is instructed to compile code for Mac OS X 10.6, the call -succeeds but Clang emits a warning specifying that the function is deprecated. -Finally, if Clang is instructed to compile code for Mac OS X 10.7, the call -fails because ``f()`` is no longer available. - -The availability attribute is a comma-separated list starting with the -platform name and then including clauses specifying important milestones in the -declaration's lifetime (in any order) along with additional information. Those -clauses can be: - -introduced=\ *version* - The first version in which this declaration was introduced. - -deprecated=\ *version* - The first version in which this declaration was deprecated, meaning that - users should migrate away from this API. - -obsoleted=\ *version* - The first version in which this declaration was obsoleted, meaning that it - was removed completely and can no longer be used. - -unavailable - This declaration is never available on this platform. - -message=\ *string-literal* - Additional message text that Clang will provide when emitting a warning or - error about use of a deprecated or obsoleted declaration. Useful to direct - users to replacement APIs. - -Multiple availability attributes can be placed on a declaration, which may -correspond to different platforms. Only the availability attribute with the -platform corresponding to the target platform will be used; any others will be -ignored. If no availability attribute specifies availability for the current -target platform, the availability attributes are ignored. Supported platforms -are: - -``ios`` - Apple's iOS operating system. The minimum deployment target is specified by - the ``-mios-version-min=*version*`` or ``-miphoneos-version-min=*version*`` - command-line arguments. - -``macosx`` - Apple's Mac OS X operating system. The minimum deployment target is - specified by the ``-mmacosx-version-min=*version*`` command-line argument. - -A declaration can be used even when deploying back to a platform version prior -to when the declaration was introduced. When this happens, the declaration is -`weakly linked -<https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html>`_, -as if the ``weak_import`` attribute were added to the declaration. A -weakly-linked declaration may or may not be present a run-time, and a program -can determine whether the declaration is present by checking whether the -address of that declaration is non-NULL. - -If there are multiple declarations of the same entity, the availability -attributes must either match on a per-platform basis or later -declarations must not have availability attributes for that -platform. For example: - -.. code-block:: c - - void g(void) __attribute__((availability(macosx,introduced=10.4))); - void g(void) __attribute__((availability(macosx,introduced=10.4))); // okay, matches - void g(void) __attribute__((availability(ios,introduced=4.0))); // okay, adds a new platform - void g(void); // okay, inherits both macosx and ios availability from above. - void g(void) __attribute__((availability(macosx,introduced=10.5))); // error: mismatch - -When one method overrides another, the overriding method can be more widely available than the overridden method, e.g.,: - -.. code-block:: objc - - @interface A - - (id)method __attribute__((availability(macosx,introduced=10.4))); - - (id)method2 __attribute__((availability(macosx,introduced=10.4))); - @end - - @interface B : A - - (id)method __attribute__((availability(macosx,introduced=10.3))); // okay: method moved into base class later - - (id)method __attribute__((availability(macosx,introduced=10.5))); // error: this method was available via the base class in 10.4 - @end - - -_Noreturn ---------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "","","","X", "" - -A function declared as ``_Noreturn`` shall not return to its caller. The -compiler will generate a diagnostic for a function declared as ``_Noreturn`` -that appears to be capable of returning to its caller. - - -noreturn --------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "","X","","", "" - -A function declared as ``[[noreturn]]`` shall not return to its caller. The -compiler will generate a diagnostic for a function declared as ``[[noreturn]]`` -that appears to be capable of returning to its caller. - - -carries_dependency ------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -The ``carries_dependency`` attribute specifies dependency propagation into and -out of functions. - -When specified on a function or Objective-C method, the ``carries_dependency`` -attribute means that the return value carries a dependency out of the function, -so that the implementation need not constrain ordering upon return from that -function. Implementations of the function and its caller may choose to preserve -dependencies instead of emitting memory ordering instructions such as fences. - -Note, this attribute does not change the meaning of the program, but may result -in generation of more efficient code. - - -enable_if ---------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -.. Note:: Some features of this attribute are experimental. The meaning of
- multiple enable_if attributes on a single declaration is subject to change in
- a future version of clang. Also, the ABI is not standardized and the name
- mangling may change in future versions. To avoid that, use asm labels. - -The ``enable_if`` attribute can be placed on function declarations to control -which overload is selected based on the values of the function's arguments. -When combined with the ``overloadable`` attribute, this feature is also -available in C. - -.. code-block:: c++ - - int isdigit(int c); - int isdigit(int c) __attribute__((enable_if(c <= -1 || c > 255, "chosen when 'c' is out of range"))) __attribute__((unavailable("'c' must have the value of an unsigned char or EOF"))); - - void foo(char c) { - isdigit(c); - isdigit(10); - isdigit(-10); // results in a compile-time error. - } - -The enable_if attribute takes two arguments, the first is an expression written -in terms of the function parameters, the second is a string explaining why this -overload candidate could not be selected to be displayed in diagnostics. The -expression is part of the function signature for the purposes of determining -whether it is a redeclaration (following the rules used when determining -whether a C++ template specialization is ODR-equivalent), but is not part of -the type. - -The enable_if expression is evaluated as if it were the body of a -bool-returning constexpr function declared with the arguments of the function -it is being applied to, then called with the parameters at the call site. If the -result is false or could not be determined through constant expression -evaluation, then this overload will not be chosen and the provided string may -be used in a diagnostic if the compile fails as a result. - -Because the enable_if expression is an unevaluated context, there are no global -state changes, nor the ability to pass information from the enable_if -expression to the function body. For example, suppose we want calls to -strnlen(strbuf, maxlen) to resolve to strnlen_chk(strbuf, maxlen, size of -strbuf) only if the size of strbuf can be determined: - -.. code-block:: c++ - - __attribute__((always_inline)) - static inline size_t strnlen(const char *s, size_t maxlen) - __attribute__((overloadable)) - __attribute__((enable_if(__builtin_object_size(s, 0) != -1))), - "chosen when the buffer size is known but 'maxlen' is not"))) - { - return strnlen_chk(s, maxlen, __builtin_object_size(s, 0)); - } - -Multiple enable_if attributes may be applied to a single declaration. In this -case, the enable_if expressions are evaluated from left to right in the -following manner. First, the candidates whose enable_if expressions evaluate to -false or cannot be evaluated are discarded. If the remaining candidates do not -share ODR-equivalent enable_if expressions, the overload resolution is -ambiguous. Otherwise, enable_if overload resolution continues with the next -enable_if attribute on the candidates that have not been discarded and have -remaining enable_if attributes. In this way, we pick the most specific -overload out of a number of viable overloads using enable_if. - -.. code-block:: c++ - - void f() __attribute__((enable_if(true, ""))); // #1 - void f() __attribute__((enable_if(true, ""))) __attribute__((enable_if(true, ""))); // #2 - - void g(int i, int j) __attribute__((enable_if(i, ""))); // #1 - void g(int i, int j) __attribute__((enable_if(j, ""))) __attribute__((enable_if(true))); // #2 - -In this example, a call to f() is always resolved to #2, as the first enable_if -expression is ODR-equivalent for both declarations, but #1 does not have another -enable_if expression to continue evaluating, so the next round of evaluation has -only a single candidate. In a call to g(1, 1), the call is ambiguous even though -#2 has more enable_if attributes, because the first enable_if expressions are -not ODR-equivalent. - -Query for this feature with ``__has_attribute(enable_if)``. - - -flatten (gnu::flatten) ----------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -The ``flatten`` attribute causes calls within the attributed function to -be inlined unless it is impossible to do so, for example if the body of the -callee is unavailable or if the callee has the ``noinline`` attribute. - - -format (gnu::format) --------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -Clang supports the ``format`` attribute, which indicates that the function -accepts a ``printf`` or ``scanf``-like format string and corresponding -arguments or a ``va_list`` that contains these arguments. - -Please see `GCC documentation about format attribute -<http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ to find details -about attribute syntax. - -Clang implements two kinds of checks with this attribute. - -#. Clang checks that the function with the ``format`` attribute is called with - a format string that uses format specifiers that are allowed, and that - arguments match the format string. This is the ``-Wformat`` warning, it is - on by default. - -#. Clang checks that the format string argument is a literal string. This is - the ``-Wformat-nonliteral`` warning, it is off by default. - - Clang implements this mostly the same way as GCC, but there is a difference - for functions that accept a ``va_list`` argument (for example, ``vprintf``). - GCC does not emit ``-Wformat-nonliteral`` warning for calls to such - functions. Clang does not warn if the format string comes from a function - parameter, where the function is annotated with a compatible attribute, - otherwise it warns. For example: - - .. code-block:: c - - __attribute__((__format__ (__scanf__, 1, 3))) - void foo(const char* s, char *buf, ...) { - va_list ap; - va_start(ap, buf); - - vprintf(s, ap); // warning: format string is not a string literal - } - - In this case we warn because ``s`` contains a format string for a - ``scanf``-like function, but it is passed to a ``printf``-like function. - - If the attribute is removed, clang still warns, because the format string is - not a string literal. - - Another example: - - .. code-block:: c - - __attribute__((__format__ (__printf__, 1, 3))) - void foo(const char* s, char *buf, ...) { - va_list ap; - va_start(ap, buf); - - vprintf(s, ap); // warning - } - - In this case Clang does not warn because the format string ``s`` and - the corresponding arguments are annotated. If the arguments are - incorrect, the caller of ``foo`` will receive a warning. - - -noduplicate (clang::noduplicate) --------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -The ``noduplicate`` attribute can be placed on function declarations to control -whether function calls to this function can be duplicated or not as a result of -optimizations. This is required for the implementation of functions with -certain special requirements, like the OpenCL "barrier" function, that might -need to be run concurrently by all the threads that are executing in lockstep -on the hardware. For example this attribute applied on the function -"nodupfunc" in the code below avoids that: - -.. code-block:: c - - void nodupfunc() __attribute__((noduplicate)); - // Setting it as a C++11 attribute is also valid - // void nodupfunc() [[clang::noduplicate]]; - void foo(); - void bar(); - - nodupfunc(); - if (a > n) { - foo(); - } else { - bar(); - } - -gets possibly modified by some optimizations into code similar to this: - -.. code-block:: c - - if (a > n) { - nodupfunc(); - foo(); - } else { - nodupfunc(); - bar(); - } - -where the call to "nodupfunc" is duplicated and sunk into the two branches -of the condition. - - -no_sanitize (clang::no_sanitize) --------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -Use the ``no_sanitize`` attribute on a function declaration to specify -that a particular instrumentation or set of instrumentations should not be -applied to that function. The attribute takes a list of string literals, -which have the same meaning as values accepted by the ``-fno-sanitize=`` -flag. For example, ``__attribute__((no_sanitize("address", "thread")))`` -specifies that AddressSanitizer and ThreadSanitizer should not be applied -to the function. - -See :ref:`Controlling Code Generation <controlling-code-generation>` for a -full list of supported sanitizer flags. - - -no_sanitize_address (no_address_safety_analysis, gnu::no_address_safety_analysis, gnu::no_sanitize_address) ------------------------------------------------------------------------------------------------------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -.. _langext-address_sanitizer: - -Use ``__attribute__((no_sanitize_address))`` on a function declaration to -specify that address safety instrumentation (e.g. AddressSanitizer) should -not be applied to that function. - - -no_sanitize_thread ------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -.. _langext-thread_sanitizer: - -Use ``__attribute__((no_sanitize_thread))`` on a function declaration to -specify that checks for data races on plain (non-atomic) memory accesses should -not be inserted by ThreadSanitizer. The function is still instrumented by the -tool to avoid false positives and provide meaningful stack traces. - - -no_sanitize_memory ------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -.. _langext-memory_sanitizer: - -Use ``__attribute__((no_sanitize_memory))`` on a function declaration to -specify that checks for uninitialized memory should not be inserted -(e.g. by MemorySanitizer). The function may still be instrumented by the tool -to avoid false positives in other places. - - -no_split_stack (gnu::no_split_stack) ------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -The ``no_split_stack`` attribute disables the emission of the split stack -preamble for a particular function. It has no effect if ``-fsplit-stack`` -is not specified. - - -objc_boxable ------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -Structs and unions marked with the ``objc_boxable`` attribute can be used -with the Objective-C boxed expression syntax, ``@(...)``. - -**Usage**: ``__attribute__((objc_boxable))``. This attribute -can only be placed on a declaration of a trivially-copyable struct or union: - -.. code-block:: objc - - struct __attribute__((objc_boxable)) some_struct { - int i; - }; - union __attribute__((objc_boxable)) some_union { - int i; - float f; - }; - typedef struct __attribute__((objc_boxable)) _some_struct some_struct; - - // ... - - some_struct ss; - NSValue *boxed = @(ss); - - -objc_method_family ------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -Many methods in Objective-C have conventional meanings determined by their -selectors. It is sometimes useful to be able to mark a method as having a -particular conventional meaning despite not having the right selector, or as -not having the conventional meaning that its selector would suggest. For these -use cases, we provide an attribute to specifically describe the "method family" -that a method belongs to. - -**Usage**: ``__attribute__((objc_method_family(X)))``, where ``X`` is one of -``none``, ``alloc``, ``copy``, ``init``, ``mutableCopy``, or ``new``. This -attribute can only be placed at the end of a method declaration: - -.. code-block:: objc - - - (NSString *)initMyStringValue __attribute__((objc_method_family(none))); - -Users who do not wish to change the conventional meaning of a method, and who -merely want to document its non-standard retain and release semantics, should -use the retaining behavior attributes (``ns_returns_retained``, -``ns_returns_not_retained``, etc). - -Query for this feature with ``__has_attribute(objc_method_family)``. - - -objc_requires_super -------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -Some Objective-C classes allow a subclass to override a particular method in a -parent class but expect that the overriding method also calls the overridden -method in the parent class. For these cases, we provide an attribute to -designate that a method requires a "call to ``super``" in the overriding -method in the subclass. - -**Usage**: ``__attribute__((objc_requires_super))``. This attribute can only -be placed at the end of a method declaration: - -.. code-block:: objc - - - (void)foo __attribute__((objc_requires_super)); - -This attribute can only be applied the method declarations within a class, and -not a protocol. Currently this attribute does not enforce any placement of -where the call occurs in the overriding method (such as in the case of -``-dealloc`` where the call must appear at the end). It checks only that it -exists. - -Note that on both OS X and iOS that the Foundation framework provides a -convenience macro ``NS_REQUIRES_SUPER`` that provides syntactic sugar for this -attribute: - -.. code-block:: objc - - - (void)foo NS_REQUIRES_SUPER; - -This macro is conditionally defined depending on the compiler's support for -this attribute. If the compiler does not support the attribute the macro -expands to nothing. - -Operationally, when a method has this annotation the compiler will warn if the -implementation of an override in a subclass does not call super. For example: - -.. code-block:: objc - - warning: method possibly missing a [super AnnotMeth] call - - (void) AnnotMeth{}; - ^ - - -objc_runtime_name ------------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -By default, the Objective-C interface or protocol identifier is used -in the metadata name for that object. The `objc_runtime_name` -attribute allows annotated interfaces or protocols to use the -specified string argument in the object's metadata name instead of the -default name. - -**Usage**: ``__attribute__((objc_runtime_name("MyLocalName")))``. This attribute -can only be placed before an @protocol or @interface declaration: - -.. code-block:: objc - - __attribute__((objc_runtime_name("MyLocalName"))) - @interface Message - @end - - -optnone (clang::optnone) ------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -The ``optnone`` attribute suppresses essentially all optimizations -on a function or method, regardless of the optimization level applied to -the compilation unit as a whole. This is particularly useful when you -need to debug a particular function, but it is infeasible to build the -entire application without optimization. Avoiding optimization on the -specified function can improve the quality of the debugging information -for that function. - -This attribute is incompatible with the ``always_inline`` and ``minsize`` -attributes. - - -overloadable ------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -Clang provides support for C++ function overloading in C. Function overloading -in C is introduced using the ``overloadable`` attribute. For example, one -might provide several overloaded versions of a ``tgsin`` function that invokes -the appropriate standard function computing the sine of a value with ``float``, -``double``, or ``long double`` precision: - -.. code-block:: c - - #include <math.h> - float __attribute__((overloadable)) tgsin(float x) { return sinf(x); } - double __attribute__((overloadable)) tgsin(double x) { return sin(x); } - long double __attribute__((overloadable)) tgsin(long double x) { return sinl(x); } - -Given these declarations, one can call ``tgsin`` with a ``float`` value to -receive a ``float`` result, with a ``double`` to receive a ``double`` result, -etc. Function overloading in C follows the rules of C++ function overloading -to pick the best overload given the call arguments, with a few C-specific -semantics: - -* Conversion from ``float`` or ``double`` to ``long double`` is ranked as a - floating-point promotion (per C99) rather than as a floating-point conversion - (as in C++). - -* A conversion from a pointer of type ``T*`` to a pointer of type ``U*`` is - considered a pointer conversion (with conversion rank) if ``T`` and ``U`` are - compatible types. - -* A conversion from type ``T`` to a value of type ``U`` is permitted if ``T`` - and ``U`` are compatible types. This conversion is given "conversion" rank. - -The declaration of ``overloadable`` functions is restricted to function -declarations and definitions. Most importantly, if any function with a given -name is given the ``overloadable`` attribute, then all function declarations -and definitions with that name (and in that scope) must have the -``overloadable`` attribute. This rule even applies to redeclarations of -functions whose original declaration had the ``overloadable`` attribute, e.g., - -.. code-block:: c - - int f(int) __attribute__((overloadable)); - float f(float); // error: declaration of "f" must have the "overloadable" attribute - - int g(int) __attribute__((overloadable)); - int g(int) { } // error: redeclaration of "g" must also have the "overloadable" attribute - -Functions marked ``overloadable`` must have prototypes. Therefore, the -following code is ill-formed: - -.. code-block:: c - - int h() __attribute__((overloadable)); // error: h does not have a prototype - -However, ``overloadable`` functions are allowed to use a ellipsis even if there -are no named parameters (as is permitted in C++). This feature is particularly -useful when combined with the ``unavailable`` attribute: - -.. code-block:: c++ - - void honeypot(...) __attribute__((overloadable, unavailable)); // calling me is an error - -Functions declared with the ``overloadable`` attribute have their names mangled -according to the same rules as C++ function names. For example, the three -``tgsin`` functions in our motivating example get the mangled names -``_Z5tgsinf``, ``_Z5tgsind``, and ``_Z5tgsine``, respectively. There are two -caveats to this use of name mangling: - -* Future versions of Clang may change the name mangling of functions overloaded - in C, so you should not depend on an specific mangling. To be completely - safe, we strongly urge the use of ``static inline`` with ``overloadable`` - functions. - -* The ``overloadable`` attribute has almost no meaning when used in C++, - because names will already be mangled and functions are already overloadable. - However, when an ``overloadable`` function occurs within an ``extern "C"`` - linkage specification, it's name *will* be mangled in the same way as it - would in C. - -Query for this feature with ``__has_extension(attribute_overloadable)``. - - -release_capability (release_shared_capability, clang::release_capability, clang::release_shared_capability) ------------------------------------------------------------------------------------------------------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -Marks a function as releasing a capability. - - -target (gnu::target) --------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -Clang supports the GNU style ``__attribute__((target("OPTIONS")))`` attribute. -This attribute may be attached to a function definition and instructs -the backend to use different code generation options than were passed on the -command line. - -The current set of options correspond to the existing "subtarget features" for -the target with or without a "-mno-" in front corresponding to the absence -of the feature, as well as ``arch="CPU"`` which will change the default "CPU" -for the function. - -Example "subtarget features" from the x86 backend include: "mmx", "sse", "sse4.2", -"avx", "xop" and largely correspond to the machine specific options handled by -the front end. - - -try_acquire_capability (try_acquire_shared_capability, clang::try_acquire_capability, clang::try_acquire_shared_capability) ---------------------------------------------------------------------------------------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -Marks a function that attempts to acquire a capability. This function may fail to -actually acquire the capability; they accept a Boolean value determining -whether acquiring the capability means success (true), or failing to acquire -the capability means success (false). - - -Variable Attributes -=================== - - -init_seg --------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "","","","", "X" - -The attribute applied by ``pragma init_seg()`` controls the section into -which global initialization function pointers are emitted. It is only -available with ``-fms-extensions``. Typically, this function pointer is -emitted into ``.CRT$XCU`` on Windows. The user can change the order of -initialization by using a different section name with the same -``.CRT$XC`` prefix and a suffix that sorts lexicographically before or -after the standard ``.CRT$XCU`` sections. See the init_seg_ -documentation on MSDN for more information. - -.. _init_seg: http://msdn.microsoft.com/en-us/library/7977wcck(v=vs.110).aspx - - -section (gnu::section, __declspec(allocate)) --------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","X","", "" - -The ``section`` attribute allows you to specify a specific section a -global variable or function should be in after translation. - - -tls_model (gnu::tls_model) --------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -The ``tls_model`` attribute allows you to specify which thread-local storage -model to use. It accepts the following strings: - -* global-dynamic -* local-dynamic -* initial-exec -* local-exec - -TLS models are mutually exclusive. - - -thread ------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "","","X","", "" - -The ``__declspec(thread)`` attribute declares a variable with thread local -storage. It is available under the ``-fms-extensions`` flag for MSVC -compatibility. See the documentation for `__declspec(thread)`_ on MSDN. - -.. _`__declspec(thread)`: http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx - -In Clang, ``__declspec(thread)`` is generally equivalent in functionality to the -GNU ``__thread`` keyword. The variable must not have a destructor and must have -a constant initializer, if any. The attribute only applies to variables -declared with static storage duration, such as globals, class static data -members, and static locals. - - -Type Attributes -=============== - - -align_value ------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -The align_value attribute can be added to the typedef of a pointer type or the -declaration of a variable of pointer or reference type. It specifies that the -pointer will point to, or the reference will bind to, only objects with at -least the provided alignment. This alignment value must be some positive power -of 2. - - .. code-block:: c - - typedef double * aligned_double_ptr __attribute__((align_value(64))); - void foo(double & x __attribute__((align_value(128)), - aligned_double_ptr y) { ... } - -If the pointer value does not have the specified alignment at runtime, the -behavior of the program is undefined. - - -flag_enum ---------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -This attribute can be added to an enumerator to signal to the compiler that it -is intended to be used as a flag type. This will cause the compiler to assume -that the range of the type includes all of the values that you can get by -manipulating bits of the enumerator when issuing warnings. - - -__single_inhertiance, __multiple_inheritance, __virtual_inheritance -------------------------------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "","","","X", "" - -This collection of keywords is enabled under ``-fms-extensions`` and controls -the pointer-to-member representation used on ``*-*-win32`` targets. - -The ``*-*-win32`` targets utilize a pointer-to-member representation which -varies in size and alignment depending on the definition of the underlying -class. - -However, this is problematic when a forward declaration is only available and -no definition has been made yet. In such cases, Clang is forced to utilize the -most general representation that is available to it. - -These keywords make it possible to use a pointer-to-member representation other -than the most general one regardless of whether or not the definition will ever -be present in the current translation unit. - -This family of keywords belong between the ``class-key`` and ``class-name``: - -.. code-block:: c++ - - struct __single_inheritance S; - int S::*i; - struct S {}; - -This keyword can be applied to class templates but only has an effect when used -on full specializations: - -.. code-block:: c++ - - template <typename T, typename U> struct __single_inheritance A; // warning: inheritance model ignored on primary template - template <typename T> struct __multiple_inheritance A<T, T>; // warning: inheritance model ignored on partial specialization - template <> struct __single_inheritance A<int, float>; - -Note that choosing an inheritance model less general than strictly necessary is -an error: - -.. code-block:: c++ - - struct __multiple_inheritance S; // error: inheritance model does not match definition - int S::*i; - struct S {}; - - -novtable --------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "","","X","", "" - -This attribute can be added to a class declaration or definition to signal to -the compiler that constructors and destructors will not reference the virtual -function table. - - -Statement Attributes -==================== - - -fallthrough (clang::fallthrough) --------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "","X","","", "" - -The ``clang::fallthrough`` attribute is used along with the -``-Wimplicit-fallthrough`` argument to annotate intentional fall-through -between switch labels. It can only be applied to a null statement placed at a -point of execution between any statement and the next switch label. It is -common to mark these places with a specific comment, but this attribute is -meant to replace comments with a more strict annotation, which can be checked -by the compiler. This attribute doesn't change semantics of the code and can -be used wherever an intended fall-through occurs. It is designed to mimic -control-flow statements like ``break;``, so it can be placed in most places -where ``break;`` can, but only if there are no statements on the execution path -between it and the next switch label. - -Here is an example: - -.. code-block:: c++ - - // compile with -Wimplicit-fallthrough - switch (n) { - case 22: - case 33: // no warning: no statements between case labels - f(); - case 44: // warning: unannotated fall-through - g(); - [[clang::fallthrough]]; - case 55: // no warning - if (x) { - h(); - break; - } - else { - i(); - [[clang::fallthrough]]; - } - case 66: // no warning - p(); - [[clang::fallthrough]]; // warning: fallthrough annotation does not - // directly precede case label - q(); - case 77: // warning: unannotated fall-through - r(); - } - - -#pragma clang loop ------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "","","","", "X" - -The ``#pragma clang loop`` directive allows loop optimization hints to be -specified for the subsequent loop. The directive allows vectorization, -interleaving, and unrolling to be enabled or disabled. Vector width as well -as interleave and unrolling count can be manually specified. See -`language extensions -<http://clang.llvm.org/docs/LanguageExtensions.html#extensions-for-loop-hint-optimizations>`_ -for details. - - -#pragma unroll, #pragma nounroll --------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "","","","", "X" - -Loop unrolling optimization hints can be specified with ``#pragma unroll`` and -``#pragma nounroll``. The pragma is placed immediately before a for, while, -do-while, or c++11 range-based for loop. - -Specifying ``#pragma unroll`` without a parameter directs the loop unroller to -attempt to fully unroll the loop if the trip count is known at compile time: - -.. code-block:: c++ - - #pragma unroll - for (...) { - ... - } - -Specifying the optional parameter, ``#pragma unroll _value_``, directs the -unroller to unroll the loop ``_value_`` times. The parameter may optionally be -enclosed in parentheses: - -.. code-block:: c++ - - #pragma unroll 16 - for (...) { - ... - } - - #pragma unroll(16) - for (...) { - ... - } - -Specifying ``#pragma nounroll`` indicates that the loop should not be unrolled: - -.. code-block:: c++ - - #pragma nounroll - for (...) { - ... - } - -``#pragma unroll`` and ``#pragma unroll _value_`` have identical semantics to -``#pragma clang loop unroll(full)`` and -``#pragma clang loop unroll_count(_value_)`` respectively. ``#pragma nounroll`` -is equivalent to ``#pragma clang loop unroll(disable)``. See -`language extensions -<http://clang.llvm.org/docs/LanguageExtensions.html#extensions-for-loop-hint-optimizations>`_ -for further details including limitations of the unroll hints. - - -Calling Conventions -=================== -Clang supports several different calling conventions, depending on the target -platform and architecture. The calling convention used for a function determines -how parameters are passed, how results are returned to the caller, and other -low-level details of calling a function. - -fastcall (gnu::fastcall, __fastcall, _fastcall) ------------------------------------------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","X", "" - -On 32-bit x86 targets, this attribute changes the calling convention of a -function to use ECX and EDX as register parameters and clear parameters off of -the stack on return. This convention does not support variadic calls or -unprototyped functions in C, and has no effect on x86_64 targets. This calling -convention is supported primarily for compatibility with existing code. Users -seeking register parameters should use the ``regparm`` attribute, which does -not require callee-cleanup. See the documentation for `__fastcall`_ on MSDN. - -.. _`__fastcall`: http://msdn.microsoft.com/en-us/library/6xa169sk.aspx - - -ms_abi (gnu::ms_abi) --------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -On non-Windows x86_64 targets, this attribute changes the calling convention of -a function to match the default convention used on Windows x86_64. This -attribute has no effect on Windows targets or non-x86_64 targets. - - -pcs (gnu::pcs) --------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -On ARM targets, this attribute can be used to select calling conventions -similar to ``stdcall`` on x86. Valid parameter values are "aapcs" and -"aapcs-vfp". - - -regparm (gnu::regparm) ----------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -On 32-bit x86 targets, the regparm attribute causes the compiler to pass -the first three integer parameters in EAX, EDX, and ECX instead of on the -stack. This attribute has no effect on variadic functions, and all parameters -are passed via the stack as normal. - - -stdcall (gnu::stdcall, __stdcall, _stdcall) -------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","X", "" - -On 32-bit x86 targets, this attribute changes the calling convention of a -function to clear parameters off of the stack on return. This convention does -not support variadic calls or unprototyped functions in C, and has no effect on -x86_64 targets. This calling convention is used widely by the Windows API and -COM applications. See the documentation for `__stdcall`_ on MSDN. - -.. _`__stdcall`: http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx - - -thiscall (gnu::thiscall, __thiscall, _thiscall) ------------------------------------------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","X", "" - -On 32-bit x86 targets, this attribute changes the calling convention of a -function to use ECX for the first parameter (typically the implicit ``this`` -parameter of C++ methods) and clear parameters off of the stack on return. This -convention does not support variadic calls or unprototyped functions in C, and -has no effect on x86_64 targets. See the documentation for `__thiscall`_ on -MSDN. - -.. _`__thiscall`: http://msdn.microsoft.com/en-us/library/ek8tkfbw.aspx - - -vectorcall (__vectorcall, _vectorcall) --------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","X", "" - -On 32-bit x86 *and* x86_64 targets, this attribute changes the calling -convention of a function to pass vector parameters in SSE registers. - -On 32-bit x86 targets, this calling convention is similar to ``__fastcall``. -The first two integer parameters are passed in ECX and EDX. Subsequent integer -parameters are passed in memory, and callee clears the stack. On x86_64 -targets, the callee does *not* clear the stack, and integer parameters are -passed in RCX, RDX, R8, and R9 as is done for the default Windows x64 calling -convention. - -On both 32-bit x86 and x86_64 targets, vector and floating point arguments are -passed in XMM0-XMM5. Homogenous vector aggregates of up to four elements are -passed in sequential SSE registers if enough are available. If AVX is enabled, -256 bit vectors are passed in YMM0-YMM5. Any vector or aggregate type that -cannot be passed in registers for any reason is passed by reference, which -allows the caller to align the parameter memory. - -See the documentation for `__vectorcall`_ on MSDN for more details. - -.. _`__vectorcall`: http://msdn.microsoft.com/en-us/library/dn375768.aspx - - -Consumed Annotation Checking -============================ -Clang supports additional attributes for checking basic resource management -properties, specifically for unique objects that have a single owning reference. -The following attributes are currently supported, although **the implementation -for these annotations is currently in development and are subject to change.** - -callable_when -------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -Use ``__attribute__((callable_when(...)))`` to indicate what states a method -may be called in. Valid states are unconsumed, consumed, or unknown. Each -argument to this attribute must be a quoted string. E.g.: - -``__attribute__((callable_when("unconsumed", "unknown")))`` - - -consumable ----------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -Each ``class`` that uses any of the typestate annotations must first be marked -using the ``consumable`` attribute. Failure to do so will result in a warning. - -This attribute accepts a single parameter that must be one of the following: -``unknown``, ``consumed``, or ``unconsumed``. - - -param_typestate ---------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -This attribute specifies expectations about function parameters. Calls to an -function with annotated parameters will issue a warning if the corresponding -argument isn't in the expected state. The attribute is also used to set the -initial state of the parameter when analyzing the function's body. - - -return_typestate ----------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -The ``return_typestate`` attribute can be applied to functions or parameters. -When applied to a function the attribute specifies the state of the returned -value. The function's body is checked to ensure that it always returns a value -in the specified state. On the caller side, values returned by the annotated -function are initialized to the given state. - -When applied to a function parameter it modifies the state of an argument after -a call to the function returns. The function's body is checked to ensure that -the parameter is in the expected state before returning. - - -set_typestate -------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -Annotate methods that transition an object into a new state with -``__attribute__((set_typestate(new_state)))``. The new state must be -unconsumed, consumed, or unknown. - - -test_typestate --------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -Use ``__attribute__((test_typestate(tested_state)))`` to indicate that a method -returns true if the object is in the specified state.. - - -Type Safety Checking -==================== -Clang supports additional attributes to enable checking type safety properties -that can't be enforced by the C type system. Use cases include: - -* MPI library implementations, where these attributes enable checking that - the buffer type matches the passed ``MPI_Datatype``; -* for HDF5 library there is a similar use case to MPI; -* checking types of variadic functions' arguments for functions like - ``fcntl()`` and ``ioctl()``. - -You can detect support for these attributes with ``__has_attribute()``. For -example: - -.. code-block:: c++ - - #if defined(__has_attribute) - # if __has_attribute(argument_with_type_tag) && \ - __has_attribute(pointer_with_type_tag) && \ - __has_attribute(type_tag_for_datatype) - # define ATTR_MPI_PWT(buffer_idx, type_idx) __attribute__((pointer_with_type_tag(mpi,buffer_idx,type_idx))) - /* ... other macros ... */ - # endif - #endif - - #if !defined(ATTR_MPI_PWT) - # define ATTR_MPI_PWT(buffer_idx, type_idx) - #endif - - int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */) - ATTR_MPI_PWT(1,3); - -argument_with_type_tag ----------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -Use ``__attribute__((argument_with_type_tag(arg_kind, arg_idx, -type_tag_idx)))`` on a function declaration to specify that the function -accepts a type tag that determines the type of some other argument. -``arg_kind`` is an identifier that should be used when annotating all -applicable type tags. - -This attribute is primarily useful for checking arguments of variadic functions -(``pointer_with_type_tag`` can be used in most non-variadic cases). - -For example: - -.. code-block:: c++ - - int fcntl(int fd, int cmd, ...) - __attribute__(( argument_with_type_tag(fcntl,3,2) )); - - -pointer_with_type_tag ---------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -Use ``__attribute__((pointer_with_type_tag(ptr_kind, ptr_idx, type_tag_idx)))`` -on a function declaration to specify that the function accepts a type tag that -determines the pointee type of some other pointer argument. - -For example: - -.. code-block:: c++ - - int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */) - __attribute__(( pointer_with_type_tag(mpi,1,3) )); - - -type_tag_for_datatype ---------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","","","", "" - -Clang supports annotating type tags of two forms. - -* **Type tag that is an expression containing a reference to some declared - identifier.** Use ``__attribute__((type_tag_for_datatype(kind, type)))`` on a - declaration with that identifier: - - .. code-block:: c++ - - extern struct mpi_datatype mpi_datatype_int - __attribute__(( type_tag_for_datatype(mpi,int) )); - #define MPI_INT ((MPI_Datatype) &mpi_datatype_int) - -* **Type tag that is an integral literal.** Introduce a ``static const`` - variable with a corresponding initializer value and attach - ``__attribute__((type_tag_for_datatype(kind, type)))`` on that declaration, - for example: - - .. code-block:: c++ - - #define MPI_INT ((MPI_Datatype) 42) - static const MPI_Datatype mpi_datatype_int - __attribute__(( type_tag_for_datatype(mpi,int) )) = 42 - -The attribute also accepts an optional third argument that determines how the -expression is compared to the type tag. There are two supported flags: - -* ``layout_compatible`` will cause types to be compared according to - layout-compatibility rules (C++11 [class.mem] p 17, 18). This is - implemented to support annotating types like ``MPI_DOUBLE_INT``. - - For example: - - .. code-block:: c++ - - /* In mpi.h */ - struct internal_mpi_double_int { double d; int i; }; - extern struct mpi_datatype mpi_datatype_double_int - __attribute__(( type_tag_for_datatype(mpi, struct internal_mpi_double_int, layout_compatible) )); - - #define MPI_DOUBLE_INT ((MPI_Datatype) &mpi_datatype_double_int) - - /* In user code */ - struct my_pair { double a; int b; }; - struct my_pair *buffer; - MPI_Send(buffer, 1, MPI_DOUBLE_INT /*, ... */); // no warning - - struct my_int_pair { int a; int b; } - struct my_int_pair *buffer2; - MPI_Send(buffer2, 1, MPI_DOUBLE_INT /*, ... */); // warning: actual buffer element - // type 'struct my_int_pair' - // doesn't match specified MPI_Datatype - -* ``must_be_null`` specifies that the expression should be a null pointer - constant, for example: - - .. code-block:: c++ - - /* In mpi.h */ - extern struct mpi_datatype mpi_datatype_null - __attribute__(( type_tag_for_datatype(mpi, void, must_be_null) )); - - #define MPI_DATATYPE_NULL ((MPI_Datatype) &mpi_datatype_null) - - /* In user code */ - MPI_Send(buffer, 1, MPI_DATATYPE_NULL /*, ... */); // warning: MPI_DATATYPE_NULL - // was specified but buffer - // is not a null pointer - - -OpenCL Address Spaces -===================== -The address space qualifier may be used to specify the region of memory that is -used to allocate the object. OpenCL supports the following address spaces: -__generic(generic), __global(global), __local(local), __private(private), -__constant(constant). - - .. code-block:: c - - __constant int c = ...; - - __generic int* foo(global int* g) { - __local int* l; - private int p; - ... - return l; - } - -More details can be found in the OpenCL C language Spec v2.0, Section 6.5. - -__constant(constant) --------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "","","","X", "" - -The constant address space attribute signals that an object is located in -a constant (non-modifiable) memory region. It is available to all work items. -Any type can be annotated with the constant address space attribute. Objects -with the constant address space qualifier can be declared in any scope and must -have an initializer. - - -__generic(generic) ------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "","","","X", "" - -The generic address space attribute is only available with OpenCL v2.0 and later. -It can be used with pointer types. Variables in global and local scope and -function parameters in non-kernel functions can have the generic address space -type attribute. It is intended to be a placeholder for any other address space -except for '__constant' in OpenCL code which can be used with multiple address -spaces. - - -__global(global) ----------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "","","","X", "" - -The global address space attribute specifies that an object is allocated in -global memory, which is accessible by all work items. The content stored in this -memory area persists between kernel executions. Pointer types to the global -address space are allowed as function parameters or local variables. Starting -with OpenCL v2.0, the global address space can be used with global (program -scope) variables and static local variable as well. - - -__local(local) --------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "","","","X", "" - -The local address space specifies that an object is allocated in the local (work -group) memory area, which is accessible to all work items in the same work -group. The content stored in this memory region is not accessible after -the kernel execution ends. In a kernel function scope, any variable can be in -the local address space. In other scopes, only pointer types to the local address -space are allowed. Local address space variables cannot have an initializer. - - -__private(private) ------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "","","","X", "" - -The private address space specifies that an object is allocated in the private -(work item) memory. Other work items cannot access the same memory area and its -content is destroyed after work item execution ends. Local variables can be -declared in the private address space. Function arguments are always in the -private address space. Kernel function arguments of a pointer or an array type -cannot point to the private address space. - - -Nullability Attributes -====================== -Whether a particular pointer may be "null" is an important concern when working with pointers in the C family of languages. The various nullability attributes indicate whether a particular pointer can be null or not, which makes APIs more expressive and can help static analysis tools identify bugs involving null pointers. Clang supports several kinds of nullability attributes: the ``nonnull`` and ``returns_nonnull`` attributes indicate which function or method parameters and result types can never be null, while nullability type qualifiers indicate which pointer types can be null (``_Nullable``) or cannot be null (``_Nonnull``). - -The nullability (type) qualifiers express whether a value of a given pointer type can be null (the ``_Nullable`` qualifier), doesn't have a defined meaning for null (the ``_Nonnull`` qualifier), or for which the purpose of null is unclear (the ``_Null_unspecified`` qualifier). Because nullability qualifiers are expressed within the type system, they are more general than the ``nonnull`` and ``returns_nonnull`` attributes, allowing one to express (for example) a nullable pointer to an array of nonnull pointers. Nullability qualifiers are written to the right of the pointer to which they apply. For example: - - .. code-block:: c - - // No meaningful result when 'ptr' is null (here, it happens to be undefined behavior). - int fetch(int * _Nonnull ptr) { return *ptr; } - - // 'ptr' may be null. - int fetch_or_zero(int * _Nullable ptr) { - return ptr ? *ptr : 0; - } - - // A nullable pointer to non-null pointers to const characters. - const char *join_strings(const char * _Nonnull * _Nullable strings, unsigned n); - -In Objective-C, there is an alternate spelling for the nullability qualifiers that can be used in Objective-C methods and properties using context-sensitive, non-underscored keywords. For example: - - .. code-block:: objective-c - - @interface NSView : NSResponder - - (nullable NSView *)ancestorSharedWithView:(nonnull NSView *)aView; - @property (assign, nullable) NSView *superview; - @property (readonly, nonnull) NSArray *subviews; - @end - -nonnull -------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -The ``nonnull`` attribute indicates that some function parameters must not be null, and can be used in several different ways. It's original usage (`from GCC <https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes>`_) is as a function (or Objective-C method) attribute that specifies which parameters of the function are nonnull in a comma-separated list. For example: - - .. code-block:: c - - extern void * my_memcpy (void *dest, const void *src, size_t len) - __attribute__((nonnull (1, 2))); - -Here, the ``nonnull`` attribute indicates that parameters 1 and 2 -cannot have a null value. Omitting the parenthesized list of parameter indices means that all parameters of pointer type cannot be null: - - .. code-block:: c - - extern void * my_memcpy (void *dest, const void *src, size_t len) - __attribute__((nonnull)); - -Clang also allows the ``nonnull`` attribute to be placed directly on a function (or Objective-C method) parameter, eliminating the need to specify the parameter index ahead of type. For example: - - .. code-block:: c - - extern void * my_memcpy (void *dest __attribute__((nonnull)), - const void *src __attribute__((nonnull)), size_t len); - -Note that the ``nonnull`` attribute indicates that passing null to a non-null parameter is undefined behavior, which the optimizer may take advantage of to, e.g., remove null checks. The ``_Nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner (because it is part of the type system) and does not imply undefined behavior, making it more widely applicable. - - -returns_nonnull ---------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "X","X","","", "" - -The ``returns_nonnull`` attribute indicates that a particular function (or Objective-C method) always returns a non-null pointer. For example, a particular system ``malloc`` might be defined to terminate a process when memory is not available rather than returning a null pointer: - - .. code-block:: c - - extern void * malloc (size_t size) __attribute__((returns_nonnull)); - -The ``returns_nonnull`` attribute implies that returning a null pointer is undefined behavior, which the optimizer may take advantage of. The ``_Nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner (because it is part of the type system) and does not imply undefined behavior, making it more widely applicable - - -_Nonnull --------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "","","","X", "" - -The ``_Nonnull`` nullability qualifier indicates that null is not a meaningful value for a value of the ``_Nonnull`` pointer type. For example, given a declaration such as: - - .. code-block:: c - - int fetch(int * _Nonnull ptr); - -a caller of ``fetch`` should not provide a null value, and the compiler will produce a warning if it sees a literal null value passed to ``fetch``. Note that, unlike the declaration attribute ``nonnull``, the presence of ``_Nonnull`` does not imply that passing null is undefined behavior: ``fetch`` is free to consider null undefined behavior or (perhaps for backward-compatibility reasons) defensively handle null. - - -_Null_unspecified ------------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "","","","X", "" - -The ``_Null_unspecified`` nullability qualifier indicates that neither the ``_Nonnull`` nor ``_Nullable`` qualifiers make sense for a particular pointer type. It is used primarily to indicate that the role of null with specific pointers in a nullability-annotated header is unclear, e.g., due to overly-complex implementations or historical factors with a long-lived API. - - -_Nullable ---------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma" - - "","","","X", "" - -The ``_Nullable`` nullability qualifier indicates that a value of the ``_Nullable`` pointer type can be null. For example, given: - - .. code-block:: c - - int fetch_or_zero(int * _Nullable ptr); - -a caller of ``fetch_or_zero`` can provide null. - - +===================
\ No newline at end of file diff --git a/docs/ClangFormat.rst b/docs/ClangFormat.rst index 45ea327..b4968ef 100644 --- a/docs/ClangFormat.rst +++ b/docs/ClangFormat.rst @@ -16,7 +16,7 @@ to format C/C++/Obj-C code. .. code-block:: console $ clang-format -help - OVERVIEW: A tool to format C/C++/Obj-C code. + OVERVIEW: A tool to format C/C++/Java/JavaScript/Objective-C/Protobuf code. If no arguments are specified, it formats the code from standard input and writes the result to the standard output. @@ -30,44 +30,53 @@ to format C/C++/Obj-C code. Clang-format options: - -cursor=<uint> - The position of the cursor when invoking - clang-format from an editor integration - -dump-config - Dump configuration options to stdout and exit. - Can be used with -style option. - -i - Inplace edit <file>s, if specified. - -length=<uint> - Format a range of this length (in bytes). - Multiple ranges can be formatted by specifying - several -offset and -length pairs. - When only a single -offset is specified without - -length, clang-format will format up to the end - of the file. - Can only be used with one input file. - -lines=<string> - <start line>:<end line> - format a range of - lines (both 1-based). - Multiple ranges can be formatted by specifying - several -lines arguments. - Can't be used with -offset and -length. - Can only be used with one input file. - -offset=<uint> - Format a range starting at this byte offset. - Multiple ranges can be formatted by specifying - several -offset and -length pairs. - Can only be used with one input file. - -output-replacements-xml - Output replacements as XML. - -style=<string> - Coding style, currently supports: - LLVM, Google, Chromium, Mozilla, WebKit. - Use -style=file to load style configuration from - .clang-format file located in one of the parent - directories of the source file (or current - directory for stdin). - Use -style="{key: value, ...}" to set specific - parameters, e.g.: - -style="{BasedOnStyle: llvm, IndentWidth: 8}" - - General options: - - -help - Display available options (-help-hidden for more) - -help-list - Display list of available options (-help-list-hidden for more) - -version - Display the version of this program + -assume-filename=<string> - When reading from stdin, clang-format assumes this + filename to look for a style config file (with + -style=file) and to determine the language. + -cursor=<uint> - The position of the cursor when invoking + clang-format from an editor integration + -dump-config - Dump configuration options to stdout and exit. + Can be used with -style option. + -fallback-style=<string> - The name of the predefined style used as a + fallback in case clang-format is invoked with + -style=file, but can not find the .clang-format + file to use. + Use -fallback-style=none to skip formatting. + -i - Inplace edit <file>s, if specified. + -length=<uint> - Format a range of this length (in bytes). + Multiple ranges can be formatted by specifying + several -offset and -length pairs. + When only a single -offset is specified without + -length, clang-format will format up to the end + of the file. + Can only be used with one input file. + -lines=<string> - <start line>:<end line> - format a range of + lines (both 1-based). + Multiple ranges can be formatted by specifying + several -lines arguments. + Can't be used with -offset and -length. + Can only be used with one input file. + -offset=<uint> - Format a range starting at this byte offset. + Multiple ranges can be formatted by specifying + several -offset and -length pairs. + Can only be used with one input file. + -output-replacements-xml - Output replacements as XML. + -sort-includes - Sort touched include lines + -style=<string> - Coding style, currently supports: + LLVM, Google, Chromium, Mozilla, WebKit. + Use -style=file to load style configuration from + .clang-format file located in one of the parent + directories of the source file (or current + directory for stdin). + Use -style="{key: value, ...}" to set specific + parameters, e.g.: + -style="{BasedOnStyle: llvm, IndentWidth: 8}" + + Generic Options: + + -help - Display available options (-help-hidden for more) + -help-list - Display list of available options (-help-list-hidden for more) + -version - Display the version of this program When the desired code formatting style is different from the available options, diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst index 031daee..bfabd59 100644 --- a/docs/ClangFormatStyleOptions.rst +++ b/docs/ClangFormatStyleOptions.rst @@ -150,26 +150,61 @@ the configuration (without a prefix: ``Auto``). **AccessModifierOffset** (``int``) The extra indent or outdent of access modifiers, e.g. ``public:``. -**AlignAfterOpenBracket** (``bool``) +**AlignAfterOpenBracket** (``BracketAlignmentStyle``) If ``true``, horizontally aligns arguments after an open bracket. This applies to round brackets (parentheses), angle brackets and square brackets. This will result in formattings like - \code - someLongFunction(argument1, - argument2); - \endcode + + Possible values: + + * ``BAS_Align`` (in configuration: ``Align``) + Align parameters on the open bracket, e.g.: + + .. code-block:: c++ + + someLongFunction(argument1, + argument2); + * ``BAS_DontAlign`` (in configuration: ``DontAlign``) + Don't align, instead use ``ContinuationIndentWidth``, e.g.: + + .. code-block:: c++ + + someLongFunction(argument1, + argument2); + * ``BAS_AlwaysBreak`` (in configuration: ``AlwaysBreak``) + Always break after an open bracket, if the parameters don't fit + on a single line, e.g.: + + .. code-block:: c++ + + someLongFunction( + argument1, argument2); + **AlignConsecutiveAssignments** (``bool``) If ``true``, aligns consecutive assignments. This will align the assignment operators of consecutive lines. This will result in formattings like - \code - int aaaa = 12; - int b = 23; - int ccc = 23; - \endcode + + .. code-block:: c++ + + int aaaa = 12; + int b = 23; + int ccc = 23; + +**AlignConsecutiveDeclarations** (``bool``) + If ``true``, aligns consecutive declarations. + + This will align the declaration names of consecutive lines. This + will result in formattings like + + .. code-block:: c++ + + int aaaa = 12; + float b = 23; + std::string ccc = 23; **AlignEscapedNewlinesLeft** (``bool``) If ``true``, aligns escaped newlines as far left as possible. @@ -219,7 +254,8 @@ the configuration (without a prefix: ``Auto``). single line. **AlwaysBreakAfterDefinitionReturnType** (``DefinitionReturnTypeBreakingStyle``) - The function definition return type breaking style to use. + The function definition return type breaking style to use. This + option is deprecated and is retained for backwards compatibility. Possible values: @@ -229,7 +265,25 @@ the configuration (without a prefix: ``Auto``). * ``DRTBS_All`` (in configuration: ``All``) Always break after the return type. * ``DRTBS_TopLevel`` (in configuration: ``TopLevel``) - Always break after the return types of top level functions. + Always break after the return types of top-level functions. + + +**AlwaysBreakAfterReturnType** (``ReturnTypeBreakingStyle``) + The function declaration return type breaking style to use. + + Possible values: + + * ``RTBS_None`` (in configuration: ``None``) + Break after return type automatically. + ``PenaltyReturnTypeOnItsOwnLine`` is taken into account. + * ``RTBS_All`` (in configuration: ``All``) + Always break after the return type. + * ``RTBS_TopLevel`` (in configuration: ``TopLevel``) + Always break after the return types of top-level functions. + * ``RTBS_AllDefinitions`` (in configuration: ``AllDefinitions``) + Always break after the return type of function definitions. + * ``RTBS_TopLevelDefinitions`` (in configuration: ``TopLevelDefinitions``) + Always break after the return type of top-level definitions. **AlwaysBreakBeforeMultilineStrings** (``bool``) @@ -252,6 +306,30 @@ the configuration (without a prefix: ``Auto``). If ``false``, a function declaration's or function definition's parameters will either all be on the same line or will have one line each. +**BraceWrapping** (``BraceWrappingFlags``) + Control of individual brace wrapping cases. + + If ``BreakBeforeBraces`` is set to ``custom``, use this to specify how each + individual brace case should be handled. Otherwise, this is ignored. + + Nested configuration flags: + + * ``bool AfterClass`` Wrap class definitions. + * ``bool AfterControlStatement`` Wrap control statements (if/for/while/switch/..). + * ``bool AfterEnum`` Wrap enum definitions. + * ``bool AfterFunction`` Wrap function definitions. + * ``bool AfterNamespace`` Wrap namespace definitions. + * ``bool AfterObjCDeclaration`` Wrap ObjC definitions (@autoreleasepool, interfaces, ..). + * ``bool AfterStruct`` Wrap struct definitions. + * ``bool AfterUnion`` Wrap union definitions. + * ``bool BeforeCatch`` Wrap before ``catch``. + * ``bool BeforeElse`` Wrap before ``else``. + * ``bool IndentBraces`` Indent the wrapped braces themselves. + + +**BreakAfterJavaFieldAnnotations** (``bool``) + Break after each annotation on a field in Java files. + **BreakBeforeBinaryOperators** (``BinaryOperatorStyle``) The way to wrap binary operators. @@ -279,13 +357,17 @@ the configuration (without a prefix: ``Auto``). Like ``Attach``, but break before braces on enum, function, and record definitions. * ``BS_Stroustrup`` (in configuration: ``Stroustrup``) - Like ``Attach``, but break before function definitions, and 'else'. + Like ``Attach``, but break before function definitions, 'catch', and 'else'. * ``BS_Allman`` (in configuration: ``Allman``) Always break before braces. * ``BS_GNU`` (in configuration: ``GNU``) Always break before braces and add an extra level of indentation to braces of control statements, not to those of class, function or other definitions. + * ``BS_WebKit`` (in configuration: ``WebKit``) + Like ``Attach``, but break before functions. + * ``BS_Custom`` (in configuration: ``Custom``) + Configure each individual brace in ``BraceWrapping``. **BreakBeforeTernaryOperators** (``bool``) @@ -356,13 +438,47 @@ the configuration (without a prefix: ``Auto``). instead of as function calls. These are expected to be macros of the form: - \code - FOREACH(<variable-declaration>, ...) - <loop-body> - \endcode + + .. code-block:: c++ + + FOREACH(<variable-declaration>, ...) + <loop-body> + + In the .clang-format configuration file, this can be configured like: + + .. code-block:: c++ + + ForEachMacros: ['RANGES_FOR', 'FOREACH'] For example: BOOST_FOREACH. +**IncludeCategories** (``std::vector<IncludeCategory>``) + Regular expressions denoting the different #include categories used + for ordering #includes. + + These regular expressions are matched against the filename of an include + (including the <> or "") in order. The value belonging to the first + matching regular expression is assigned and #includes are sorted first + according to increasing category number and then alphabetically within + each category. + + If none of the regular expressions match, UINT_MAX is assigned as + category. The main header for a source file automatically gets category 0, + so that it is kept at the beginning of the #includes + (http://llvm.org/docs/CodingStandards.html#include-style). + + To configure this in the .clang-format file, use: + + .. code-block:: c++ + + IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + - Regex: '^(<|"(gtest|isl|json)/)' + Priority: 3 + - Regex: '.\*' + Priority: 1 + **IndentCaseLabels** (``bool``) Indent case labels one level from the switch statement. @@ -546,6 +662,26 @@ the configuration (without a prefix: ``Auto``). .. END_FORMAT_STYLE_OPTIONS +Adding additional style options +=============================== + +Each additional style option adds costs to the clang-format project. Some of +these costs affect the clang-format developement itself, as we need to make +sure that any given combination of options work and that new features don't +break any of the existing options in any way. There are also costs for end users +as options become less discoverable and people have to think about and make a +decision on options they don't really care about. + +The goal of the clang-format project is more on the side of supporting a +limited set of styles really well as opposed to supporting every single style +used by a codebase somewhere in the wild. Of course, we do want to support all +major projects and thus have established the following bar for adding style +options. Each new style option must .. + + * be used in a project of significant size (have dozens of contributors) + * have a publicly accessible style guide + * have a person willing to contribute and maintain patches + Examples ======== diff --git a/docs/ClangTools.rst b/docs/ClangTools.rst index 8957541..e371596 100644 --- a/docs/ClangTools.rst +++ b/docs/ClangTools.rst @@ -82,7 +82,7 @@ fixit-hints offered by clang. See :doc:`HowToSetupToolingForLLVM` for instructions on how to setup and used `clang-check`. ``clang-format`` -~~~~~~~~~~~~~~~~ +---------------- Clang-format is both a :doc:`library <LibFormat>` and a :doc:`stand-alone tool <ClangFormat>` with the goal of automatically reformatting C++ sources files @@ -93,18 +93,6 @@ as a user tool (ideally with powerful IDE integrations) and as part of other refactoring tools, e.g. to do a reformatting of all the lines changed during a renaming. -``clang-modernize`` -~~~~~~~~~~~~~~~~~~~ -``clang-modernize`` migrates C++ code to use C++11 features where appropriate. -Currently it can: - -* convert loops to range-based for loops; - -* convert null pointer constants (like ``NULL`` or ``0``) to C++11 ``nullptr``; - -* replace the type specifier in variable declarations with the ``auto`` type specifier; - -* add the ``override`` specifier to applicable member functions. Extra Clang Tools ================= @@ -114,6 +102,15 @@ they'll be tracked here. The focus of this documentation is on the scope and features of the tools for other tool developers; each tool should provide its own user-focused documentation. +``clang-tidy`` +-------------- + +`clang-tidy <http://clang.llvm.org/extra/clang-tidy/>`_ is a clang-based C++ +linter tool. It provides an extensible framework for building compiler-based +static analyses detecting and fixing bug-prone patterns, performance, +portability and maintainability issues. + + Ideas for new Tools =================== @@ -124,27 +121,6 @@ Ideas for new Tools ``foo.begin()`` into ``begin(foo)`` and similarly for ``end()``, where ``foo`` is a standard container. We could also detect similar patterns for arrays. -* ``make_shared`` / ``make_unique`` conversion. Part of this transformation - can be incorporated into the ``auto`` transformation. Will convert - - .. code-block:: c++ - - std::shared_ptr<Foo> sp(new Foo); - std::unique_ptr<Foo> up(new Foo); - - func(std::shared_ptr<Foo>(new Foo), bar()); - - into: - - .. code-block:: c++ - - auto sp = std::make_shared<Foo>(); - auto up = std::make_unique<Foo>(); // In C++14 mode. - - // This also affects correctness. For the cases where bar() throws, - // make_shared() is safe and the original code may leak. - func(std::make_shared<Foo>(), bar()); - * ``tr1`` removal tool. Will migrate source code from using TR1 library features to C++11 library. For example: diff --git a/docs/CommandGuide/clang.rst b/docs/CommandGuide/clang.rst index 39dbe02..2b45695 100644 --- a/docs/CommandGuide/clang.rst +++ b/docs/CommandGuide/clang.rst @@ -257,6 +257,18 @@ Code Generation Options Generate debug information. Note that Clang debug information works best at -O0. +.. option:: -gmodules + + Generate debug information that contains external references to + types defined in clang modules or precompiled headers instead of + emitting redundant debug type information into every object file. + This option implies :option:`-fmodule-format=obj`. + + This option should not be used when building static libraries for + distribution to other machines because the debug info will contain + references to the module cache on the machine the object files in + the library were built on. + .. option:: -fstandalone-debug -fno-standalone-debug Clang supports a number of optimizations to reduce the size of debug diff --git a/docs/ControlFlowIntegrity.rst b/docs/ControlFlowIntegrity.rst index ce1c37b..780ff88 100644 --- a/docs/ControlFlowIntegrity.rst +++ b/docs/ControlFlowIntegrity.rst @@ -20,20 +20,72 @@ program's control flow. These schemes have been optimized for performance, allowing developers to enable them in release builds. To enable Clang's available CFI schemes, use the flag ``-fsanitize=cfi``. -As currently implemented, CFI relies on link-time optimization (LTO); so it is -required to specify ``-flto``, and the linker used must support LTO, for example -via the `gold plugin`_. To allow the checks to be implemented efficiently, -the program must be structured such that certain object files are compiled -with CFI enabled, and are statically linked into the program. This may -preclude the use of shared libraries in some cases. - -Clang currently implements forward-edge CFI for member function calls and -bad cast checking. More schemes are under development. +You can also enable a subset of available :ref:`schemes <cfi-schemes>`. +As currently implemented, all schemes rely on link-time optimization (LTO); +so it is required to specify ``-flto``, and the linker used must support LTO, +for example via the `gold plugin`_. + +To allow the checks to be implemented efficiently, the program must be +structured such that certain object files are compiled with CFI +enabled, and are statically linked into the program. This may preclude +the use of shared libraries in some cases. Experimental support for +:ref:`cross-DSO control flow integrity <cfi-cross-dso>` exists that +does not have these requirements. This cross-DSO support has unstable +ABI at this time. .. _gold plugin: http://llvm.org/docs/GoldPlugin.html +.. _cfi-schemes: + +Available schemes +================= + +Available schemes are: + + - ``-fsanitize=cfi-cast-strict``: Enables :ref:`strict cast checks + <cfi-strictness>`. + - ``-fsanitize=cfi-derived-cast``: Base-to-derived cast to the wrong + dynamic type. + - ``-fsanitize=cfi-unrelated-cast``: Cast from ``void*`` or another + unrelated type to the wrong dynamic type. + - ``-fsanitize=cfi-nvcall``: Non-virtual call via an object whose vptr is of + the wrong dynamic type. + - ``-fsanitize=cfi-vcall``: Virtual call via an object whose vptr is of the + wrong dynamic type. + - ``-fsanitize=cfi-icall``: Indirect call of a function with wrong dynamic + type. + +You can use ``-fsanitize=cfi`` to enable all the schemes and use +``-fno-sanitize`` flag to narrow down the set of schemes as desired. +For example, you can build your program with +``-fsanitize=cfi -fno-sanitize=cfi-nvcall,cfi-icall`` +to use all schemes except for non-virtual member function call and indirect call +checking. + +Remember that you have to provide ``-flto`` if at least one CFI scheme is +enabled. + +Trapping and Diagnostics +======================== + +By default, CFI will abort the program immediately upon detecting a control +flow integrity violation. You can use the :ref:`-fno-sanitize-trap= +<controlling-code-generation>` flag to cause CFI to print a diagnostic +similar to the one below before the program aborts. + +.. code-block:: console + + bad-cast.cpp:109:7: runtime error: control flow integrity check for type 'B' failed during base-to-derived cast (vtable address 0x000000425a50) + 0x000000425a50: note: vtable is of type 'A' + 00 00 00 00 f0 f1 41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 5a 42 00 + ^ + +If diagnostics are enabled, you can also configure CFI to continue program +execution instead of aborting by using the :ref:`-fsanitize-recover= +<controlling-code-generation>` flag. + Forward-Edge CFI for Virtual Calls ----------------------------------- +================================== This scheme checks that virtual calls take place using a vptr of the correct dynamic type; that is, the dynamic type of the called object must be a @@ -41,14 +93,12 @@ derived class of the static type of the object used to make the call. This CFI scheme can be enabled on its own using ``-fsanitize=cfi-vcall``. For this scheme to work, all translation units containing the definition -of a virtual member function (whether inline or not) must be compiled -with ``-fsanitize=cfi-vcall`` enabled and be statically linked into the -program. Classes in the C++ standard library (under namespace ``std``) are -exempted from checking, and therefore programs may be linked against a -pre-built standard library, but this may change in the future. +of a virtual member function (whether inline or not), other than members +of :ref:`blacklisted <cfi-blacklist>` types, must be compiled with +``-fsanitize=cfi-vcall`` enabled and be statically linked into the program. Performance -~~~~~~~~~~~ +----------- A performance overhead of less than 1% has been measured by running the Dromaeo benchmark suite against an instrumented version of the Chromium @@ -59,7 +109,7 @@ Note that this scheme has not yet been optimized for binary size; an increase of up to 15% has been observed for Chromium. Bad Cast Checking ------------------ +================= This scheme checks that pointer casts are made to an object of the correct dynamic type; that is, the dynamic type of the object must be a derived class @@ -85,18 +135,16 @@ If a program as a matter of policy forbids the second type of cast, that restriction can normally be enforced. However it may in some cases be necessary for a function to perform a forbidden cast to conform with an external API (e.g. the ``allocate`` member function of a standard library allocator). Such -functions may be blacklisted using a :doc:`SanitizerSpecialCaseList`. +functions may be :ref:`blacklisted <cfi-blacklist>`. For this scheme to work, all translation units containing the definition -of a virtual member function (whether inline or not) must be compiled with +of a virtual member function (whether inline or not), other than members +of :ref:`blacklisted <cfi-blacklist>` types, must be compiled with ``-fsanitize=cfi-derived-cast`` or ``-fsanitize=cfi-unrelated-cast`` enabled -and be statically linked into the program. Classes in the C++ standard library -(under namespace ``std``) are exempted from checking, and therefore programs -may be linked against a pre-built standard library, but this may change in -the future. +and be statically linked into the program. Non-Virtual Member Function Call Checking ------------------------------------------ +========================================= This scheme checks that non-virtual calls take place using an object of the correct dynamic type; that is, the dynamic type of the called object @@ -106,16 +154,14 @@ polymorphic class type. This CFI scheme can be enabled on its own using ``-fsanitize=cfi-nvcall``. For this scheme to work, all translation units containing the definition -of a virtual member function (whether inline or not) must be compiled -with ``-fsanitize=cfi-nvcall`` enabled and be statically linked into the -program. Classes in the C++ standard library (under namespace ``std``) are -exempted from checking, and therefore programs may be linked against a -pre-built standard library, but this may change in the future. +of a virtual member function (whether inline or not), other than members +of :ref:`blacklisted <cfi-blacklist>` types, must be compiled with +``-fsanitize=cfi-nvcall`` enabled and be statically linked into the program. .. _cfi-strictness: Strictness -~~~~~~~~~~ +---------- If a class has a single non-virtual base and does not introduce or override virtual member functions or fields other than an implicitly defined virtual @@ -129,13 +175,97 @@ member functions on class instances with specific properties that works under most compilers and should not have security implications, so we allow it by default. It can be disabled with ``-fsanitize=cfi-cast-strict``. +Indirect Function Call Checking +=============================== + +This scheme checks that function calls take place using a function of the +correct dynamic type; that is, the dynamic type of the function must match +the static type used at the call. This CFI scheme can be enabled on its own +using ``-fsanitize=cfi-icall``. + +For this scheme to work, each indirect function call in the program, other +than calls in :ref:`blacklisted <cfi-blacklist>` functions, must call a +function which was either compiled with ``-fsanitize=cfi-icall`` enabled, +or whose address was taken by a function in a translation unit compiled with +``-fsanitize=cfi-icall``. + +If a function in a translation unit compiled with ``-fsanitize=cfi-icall`` +takes the address of a function not compiled with ``-fsanitize=cfi-icall``, +that address may differ from the address taken by a function in a translation +unit not compiled with ``-fsanitize=cfi-icall``. This is technically a +violation of the C and C++ standards, but it should not affect most programs. + +Each translation unit compiled with ``-fsanitize=cfi-icall`` must be +statically linked into the program or shared library, and calls across +shared library boundaries are handled as if the callee was not compiled with +``-fsanitize=cfi-icall``. + +This scheme is currently only supported on the x86 and x86_64 architectures. + +``-fsanitize=cfi-icall`` and ``-fsanitize=function`` +---------------------------------------------------- + +This tool is similar to ``-fsanitize=function`` in that both tools check +the types of function calls. However, the two tools occupy different points +on the design space; ``-fsanitize=function`` is a developer tool designed +to find bugs in local development builds, whereas ``-fsanitize=cfi-icall`` +is a security hardening mechanism designed to be deployed in release builds. + +``-fsanitize=function`` has a higher space and time overhead due to a more +complex type check at indirect call sites, as well as a need for run-time +type information (RTTI), which may make it unsuitable for deployment. Because +of the need for RTTI, ``-fsanitize=function`` can only be used with C++ +programs, whereas ``-fsanitize=cfi-icall`` can protect both C and C++ programs. + +On the other hand, ``-fsanitize=function`` conforms more closely with the C++ +standard and user expectations around interaction with shared libraries; +the identity of function pointers is maintained, and calls across shared +library boundaries are no different from calls within a single program or +shared library. + +.. _cfi-blacklist: + +Blacklist +========= + +A :doc:`SanitizerSpecialCaseList` can be used to relax CFI checks for certain +source files, functions and types using the ``src``, ``fun`` and ``type`` +entity types. + +In addition, if a type has a ``uuid`` attribute and the blacklist contains +the type entry ``attr:uuid``, CFI checks are suppressed for that type. This +allows all COM types to be easily blacklisted, which is useful as COM types +are typically defined outside of the linked program. + +.. code-block:: bash + + # Suppress checking for code in a file. + src:bad_file.cpp + src:bad_header.h + # Ignore all functions with names containing MyFooBar. + fun:*MyFooBar* + # Ignore all types in the standard library. + type:std::* + # Ignore all types with a uuid attribute. + type:attr:uuid + +.. _cfi-cross-dso: + +Shared library support +====================== + +Use **-f[no-]sanitize-cfi-cross-dso** to enable the cross-DSO control +flow integrity mode, which allows all CFI schemes listed above to +apply across DSO boundaries. As in the regular CFI, each DSO must be +built with ``-flto``. + Design ------- +====== Please refer to the :doc:`design document<ControlFlowIntegrityDesign>`. Publications ------------- +============ `Control-Flow Integrity: Principles, Implementations, and Applications <http://research.microsoft.com/pubs/64250/ccs05.pdf>`_. Martin Abadi, Mihai Budiu, Ćlfar Erlingsson, Jay Ligatti. diff --git a/docs/ControlFlowIntegrityDesign.rst b/docs/ControlFlowIntegrityDesign.rst index 89aa038..b4aacd3 100644 --- a/docs/ControlFlowIntegrityDesign.rst +++ b/docs/ControlFlowIntegrityDesign.rst @@ -273,3 +273,227 @@ Eliminating Bit Vector Checks for All-Ones Bit Vectors If the bit vector is all ones, the bit vector check is redundant; we simply need to check that the address is in range and well aligned. This is more likely to occur if the virtual tables are padded. + +Forward-Edge CFI for Indirect Function Calls +============================================ + +Under forward-edge CFI for indirect function calls, each unique function +type has its own bit vector, and at each call site we need to check that the +function pointer is a member of the function type's bit vector. This scheme +works in a similar way to forward-edge CFI for virtual calls, the distinction +being that we need to build bit vectors of function entry points rather than +of virtual tables. + +Unlike when re-arranging global variables, we cannot re-arrange functions +in a particular order and base our calculations on the layout of the +functions' entry points, as we have no idea how large a particular function +will end up being (the function sizes could even depend on how we arrange +the functions). Instead, we build a jump table, which is a block of code +consisting of one branch instruction for each of the functions in the bit +set that branches to the target function, and redirect any taken function +addresses to the corresponding jump table entry. In this way, the distance +between function entry points is predictable and controllable. In the object +file's symbol table, the symbols for the target functions also refer to the +jump table entries, so that addresses taken outside the module will pass +any verification done inside the module. + +In more concrete terms, suppose we have three functions ``f``, ``g``, ``h`` +which are members of a single bitset, and a function foo that returns their +addresses: + +.. code-block:: none + + f: + mov 0, %eax + ret + + g: + mov 1, %eax + ret + + h: + mov 2, %eax + ret + + foo: + mov f, %eax + mov g, %edx + mov h, %ecx + ret + +Our jump table will (conceptually) look like this: + +.. code-block:: none + + f: + jmp .Ltmp0 ; 5 bytes + int3 ; 1 byte + int3 ; 1 byte + int3 ; 1 byte + + g: + jmp .Ltmp1 ; 5 bytes + int3 ; 1 byte + int3 ; 1 byte + int3 ; 1 byte + + h: + jmp .Ltmp2 ; 5 bytes + int3 ; 1 byte + int3 ; 1 byte + int3 ; 1 byte + + .Ltmp0: + mov 0, %eax + ret + + .Ltmp1: + mov 1, %eax + ret + + .Ltmp2: + mov 2, %eax + ret + + foo: + mov f, %eax + mov g, %edx + mov h, %ecx + ret + +Because the addresses of ``f``, ``g``, ``h`` are evenly spaced at a power of +2, and function types do not overlap (unlike class types with base classes), +we can normally apply the `Alignment`_ and `Eliminating Bit Vector Checks +for All-Ones Bit Vectors`_ optimizations thus simplifying the check at each +call site to a range and alignment check. + +Shared library support +====================== + +**EXPERIMENTAL** + +The basic CFI mode described above assumes that the application is a +monolithic binary; at least that all possible virtual/indirect call +targets and the entire class hierarchy are known at link time. The +cross-DSO mode, enabled with **-f[no-]sanitize-cfi-cross-dso** relaxes +this requirement by allowing virtual and indirect calls to cross the +DSO boundary. + +Assuming the following setup: the binary consists of several +instrumented and several uninstrumented DSOs. Some of them may be +dlopen-ed/dlclose-d periodically, even frequently. + + - Calls made from uninstrumented DSOs are not checked and just work. + - Calls inside any instrumented DSO are fully protected. + - Calls between different instrumented DSOs are also protected, with + a performance penalty (in addition to the monolithic CFI + overhead). + - Calls from an instrumented DSO to an uninstrumented one are + unchecked and just work, with performance penalty. + - Calls from an instrumented DSO outside of any known DSO are + detected as CFI violations. + +In the monolithic scheme a call site is instrumented as + +.. code-block:: none + + if (!InlinedFastCheck(f)) + abort(); + call *f + +In the cross-DSO scheme it becomes + +.. code-block:: none + + if (!InlinedFastCheck(f)) + __cfi_slowpath(CallSiteTypeId, f); + call *f + +CallSiteTypeId +-------------- + +``CallSiteTypeId`` is a stable process-wide identifier of the +call-site type. For a virtual call site, the type in question is the class +type; for an indirect function call it is the function signature. The +mapping from a type to an identifier is an ABI detail. In the current, +experimental, implementation the identifier of type T is calculated as +follows: + + - Obtain the mangled name for "typeinfo name for T". + - Calculate MD5 hash of the name as a string. + - Reinterpret the first 8 bytes of the hash as a little-endian + 64-bit integer. + +It is possible, but unlikely, that collisions in the +``CallSiteTypeId`` hashing will result in weaker CFI checks that would +still be conservatively correct. + +CFI_Check +--------- + +In the general case, only the target DSO knows whether the call to +function ``f`` with type ``CallSiteTypeId`` is valid or not. To +export this information, every DSO implements + +.. code-block:: none + + void __cfi_check(uint64 CallSiteTypeId, void *TargetAddr) + +This function provides external modules with access to CFI checks for +the targets inside this DSO. For each known ``CallSiteTypeId``, this +functions performs an ``llvm.bitset.test`` with the corresponding bit +set. It aborts if the type is unknown, or if the check fails. + +The basic implementation is a large switch statement over all values +of CallSiteTypeId supported by this DSO, and each case is similar to +the InlinedFastCheck() in the basic CFI mode. + +CFI Shadow +---------- + +To route CFI checks to the target DSO's __cfi_check function, a +mapping from possible virtual / indirect call targets to +the corresponding __cfi_check functions is maintained. This mapping is +implemented as a sparse array of 2 bytes for every possible page (4096 +bytes) of memory. The table is kept readonly (FIXME: not yet) most of +the time. + +There are 3 types of shadow values: + + - Address in a CFI-instrumented DSO. + - Unchecked address (a ātrustedā non-instrumented DSO). Encoded as + value 0xFFFF. + - Invalid address (everything else). Encoded as value 0. + +For a CFI-instrumented DSO, a shadow value encodes the address of the +__cfi_check function for all call targets in the corresponding memory +page. If Addr is the target address, and V is the shadow value, then +the address of __cfi_check is calculated as + +.. code-block:: none + + __cfi_check = AlignUpTo(Addr, 4096) - (V + 1) * 4096 + +This works as long as __cfi_check is aligned by 4096 bytes and located +below any call targets in its DSO, but not more than 256MB apart from +them. + +CFI_SlowPath +------------ + +The slow path check is implemented in compiler-rt library as + +.. code-block:: none + + void __cfi_slowpath(uint64 CallSiteTypeId, void *TargetAddr) + +This functions loads a shadow value for ``TargetAddr``, finds the +address of __cfi_check as described above and calls that. + +Position-independent executable requirement +------------------------------------------- + +Cross-DSO CFI mode requires that the main executable is built as PIE. +In non-PIE executables the address of an external function (taken from +the main executable) is the address of that functionās PLT record in +the main executable. This would break the CFI checks. diff --git a/docs/InternalsManual.rst b/docs/InternalsManual.rst index 7959179..c4af5b1 100644 --- a/docs/InternalsManual.rst +++ b/docs/InternalsManual.rst @@ -1995,7 +1995,7 @@ are similar. * Make sure that ``children()`` visits all of the subexpressions. This is important for a number of features (e.g., IDE support, C++ variadic templates). If you have sub-types, you'll also need to visit those - sub-types in ``RecursiveASTVisitor`` and ``DataRecursiveASTVisitor``. + sub-types in ``RecursiveASTVisitor``. * Add printing support (``StmtPrinter.cpp``) for your expression. * Add profiling support (``StmtProfile.cpp``) for your AST node, noting the distinguishing (non-source location) characteristics of an instance of diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst index 6a4dd5c..333dee6 100644 --- a/docs/LanguageExtensions.rst +++ b/docs/LanguageExtensions.rst @@ -415,7 +415,7 @@ dash indicates that an operation is not accepted according to a corresponding specification. ============================== ======= ======= ======= ======= - Opeator OpenCL AltiVec GCC NEON + Operator OpenCL AltiVec GCC NEON ============================== ======= ======= ======= ======= [] yes yes yes -- unary operators +, -- yes yes yes -- @@ -1017,8 +1017,8 @@ The following type trait primitives are supported by Clang: ``argtypes...`` such that no non-trivial functions are called as part of that initialization. This trait is required to implement the C++11 standard library. -* ``__is_destructible`` (MSVC 2013): partially implemented -* ``__is_nothrow_destructible`` (MSVC 2013): partially implemented +* ``__is_destructible`` (MSVC 2013) +* ``__is_nothrow_destructible`` (MSVC 2013) * ``__is_nothrow_assignable`` (MSVC 2013, clang) * ``__is_constructible`` (MSVC 2013, clang) * ``__is_nothrow_constructible`` (MSVC 2013, clang) @@ -1540,6 +1540,33 @@ takes no arguments and produces a void result. Query for this feature with ``__has_builtin(__builtin_unreachable)``. +``__builtin_unpredictable`` +--------------------------- + +``__builtin_unpredictable`` is used to indicate that a branch condition is +unpredictable by hardware mechanisms such as branch prediction logic. + +**Syntax**: + +.. code-block:: c++ + + __builtin_unpredictable(long long) + +**Example of use**: + +.. code-block:: c++ + + if (__builtin_unpredictable(x > 0)) { + foo(); + } + +**Description**: + +The ``__builtin_unpredictable()`` builtin is expected to be used with control +flow conditions such as in ``if`` and ``switch`` statements. + +Query for this feature with ``__has_builtin(__builtin_unpredictable)``. + ``__sync_swap`` --------------- @@ -1652,17 +1679,20 @@ an example of their usage: errorcode_t security_critical_application(...) { unsigned x, y, result; ... - if (__builtin_umul_overflow(x, y, &result)) + if (__builtin_mul_overflow(x, y, &result)) return kErrorCodeHackers; ... use_multiply(result); ... } -A complete enumeration of the builtins are: +Clang provides the following checked arithmetic builtins: .. code-block:: c + bool __builtin_add_overflow (type1 x, type2 y, type3 *sum); + bool __builtin_sub_overflow (type1 x, type2 y, type3 *diff); + bool __builtin_mul_overflow (type1 x, type2 y, type3 *prod); bool __builtin_uadd_overflow (unsigned x, unsigned y, unsigned *sum); bool __builtin_uaddl_overflow (unsigned long x, unsigned long y, unsigned long *sum); bool __builtin_uaddll_overflow(unsigned long long x, unsigned long long y, unsigned long long *sum); @@ -1682,6 +1712,21 @@ A complete enumeration of the builtins are: bool __builtin_smull_overflow (long x, long y, long *prod); bool __builtin_smulll_overflow(long long x, long long y, long long *prod); +Each builtin performs the specified mathematical operation on the +first two arguments and stores the result in the third argument. If +possible, the result will be equal to mathematically-correct result +and the builtin will return 0. Otherwise, the builtin will return +1 and the result will be equal to the unique value that is equivalent +to the mathematically-correct result modulo two raised to the *k* +power, where *k* is the number of bits in the result type. The +behavior of these builtins is well-defined for all argument values. + +The first three builtins work generically for operands of any integer type, +including boolean types. The operands need not have the same type as each +other, or as the result. The other builtins may implicitly promote or +convert their operands before performing the operation. + +Query for this feature with ``__has_builtin(__builtin_add_overflow)``, etc. .. _langext-__c11_atomic: @@ -1715,6 +1760,9 @@ The macros ``__ATOMIC_RELAXED``, ``__ATOMIC_CONSUME``, ``__ATOMIC_ACQUIRE``, provided, with values corresponding to the enumerators of C11's ``memory_order`` enumeration. +(Note that Clang additionally provides GCC-compatible ``__atomic_*`` +builtins) + Low-level ARM exclusive memory builtins --------------------------------------- @@ -1730,6 +1778,7 @@ instructions for implementing atomic operations. void __builtin_arm_clrex(void); The types ``T`` currently supported are: + * Integer types with width at most 64 bits (or 128 bits on AArch64). * Floating-point types * Pointer types. @@ -1748,6 +1797,26 @@ care should be exercised. For these reasons the higher level atomic primitives should be preferred where possible. +Non-temporal load/store builtins +-------------------------------- + +Clang provides overloaded builtins allowing generation of non-temporal memory +accesses. + +.. code-block:: c + + T __builtin_nontemporal_load(T *addr); + void __builtin_nontemporal_store(T value, T *addr); + +The types ``T`` currently supported are: + +* Integer types. +* Floating-point types. +* Vector types. + +Note that the compiler does not guarantee that non-temporal loads or stores +will be used. + Non-standard C++11 Attributes ============================= @@ -1990,11 +2059,23 @@ iterations. Full unrolling is only possible if the loop trip count is known at compile time. Partial unrolling replicates the loop body within the loop and reduces the trip count. -If ``unroll(full)`` is specified the unroller will attempt to fully unroll the +If ``unroll(enable)`` is specified the unroller will attempt to fully unroll the loop if the trip count is known at compile time. If the fully unrolled code size is greater than an internal limit the loop will be partially unrolled up to this -limit. If the loop count is not known at compile time the loop will not be -unrolled. +limit. If the trip count is not known at compile time the loop will be partially +unrolled with a heuristically chosen unroll factor. + +.. code-block:: c++ + + #pragma clang loop unroll(enable) + for(...) { + ... + } + +If ``unroll(full)`` is specified the unroller will attempt to fully unroll the +loop if the trip count is known at compile time identically to +``unroll(enable)``. However, with ``unroll(full)`` the loop will not be unrolled +if the loop count is not known at compile time. .. code-block:: c++ @@ -2006,7 +2087,7 @@ unrolled. The unroll count can be specified explicitly with ``unroll_count(_value_)`` where _value_ is a positive integer. If this value is greater than the trip count the loop will be fully unrolled. Otherwise the loop is partially unrolled subject -to the same code size limit as with ``unroll(full)``. +to the same code size limit as with ``unroll(enable)``. .. code-block:: c++ diff --git a/docs/LeakSanitizer.rst b/docs/LeakSanitizer.rst index d4b4fa0..8591808 100644 --- a/docs/LeakSanitizer.rst +++ b/docs/LeakSanitizer.rst @@ -28,6 +28,4 @@ There are plans to support LeakSanitizer in :doc:`MemorySanitizer` builds. More Information ================ -`https://code.google.com/p/address-sanitizer/wiki/LeakSanitizer -<https://code.google.com/p/address-sanitizer/wiki/LeakSanitizer>`_ - +`<https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer>`_ diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index a555bb3..48f061c 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -100,8 +100,8 @@ recordDecl(decl().bind("id"), hasName("::MyClass")) <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_1CXXCtorInitializer.html">CXXCtorInitializer</a>></td><td class="name" onclick="toggle('ctorInitializer0')"><a name="ctorInitializer0Anchor">ctorInitializer</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>>...</td></tr> -<tr><td colspan="4" class="doc" id="ctorInitializer0"><pre>Matches constructor initializers. +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>></td><td class="name" onclick="toggle('cxxCtorInitializer0')"><a name="cxxCtorInitializer0Anchor">cxxCtorInitializer</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="cxxCtorInitializer0"><pre>Matches constructor initializers. Examples matches i(42). class C { @@ -144,8 +144,8 @@ classTemplateSpecializationDecl() </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. +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('cxxConstructorDecl0')"><a name="cxxConstructorDecl0Anchor">cxxConstructorDecl</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="cxxConstructorDecl0"><pre>Matches C++ constructor declarations. Example matches Foo::Foo() and Foo::Foo(int) class Foo { @@ -157,6 +157,42 @@ Example matches Foo::Foo() and Foo::Foo(int) </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('cxxConversionDecl0')"><a name="cxxConversionDecl0Anchor">cxxConversionDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConversionDecl.html">CXXConversionDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="cxxConversionDecl0"><pre>Matches conversion operator declarations. + +Example matches the operator. + class X { operator int() const; }; +</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('cxxDestructorDecl0')"><a name="cxxDestructorDecl0Anchor">cxxDestructorDecl</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="cxxDestructorDecl0"><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('cxxMethodDecl0')"><a name="cxxMethodDecl0Anchor">cxxMethodDecl</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="cxxMethodDecl0"><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('cxxRecordDecl0')"><a name="cxxRecordDecl0Anchor">cxxRecordDecl</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="cxxRecordDecl0"><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('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. @@ -179,17 +215,6 @@ declaratorDecl() </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. @@ -256,14 +281,6 @@ linkageSpecDecl() </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. @@ -277,6 +294,17 @@ Example matches X, S, the anonymous union type, i, and 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('namespaceAliasDecl0')"><a name="namespaceAliasDecl0Anchor">namespaceAliasDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1NamespaceAliasDecl.html">NamespaceAliasDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="namespaceAliasDecl0"><pre>Matches a declaration of a namespace alias. + +Given + namespace test {} + namespace alias = ::test; +namespaceAliasDecl() + matches "namespace alias" but not "namespace test" +</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('namespaceDecl0')"><a name="namespaceDecl0Anchor">namespaceDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1NamespaceDecl.html">NamespaceDecl</a>>...</td></tr> <tr><td colspan="4" class="doc" id="namespaceDecl0"><pre>Matches a declaration of a namespace. @@ -288,6 +316,25 @@ namespaceDecl() </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('nonTypeTemplateParmDecl0')"><a name="nonTypeTemplateParmDecl0Anchor">nonTypeTemplateParmDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1NonTypeTemplateParmDecl.html">NonTypeTemplateParmDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="nonTypeTemplateParmDecl0"><pre>Matches non-type template parameter declarations. + +Given + template <typename T, int N> struct C {}; +nonTypeTemplateParmDecl() + matches 'N', but not '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('objcInterfaceDecl0')"><a name="objcInterfaceDecl0Anchor">objcInterfaceDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCInterfaceDecl.html">ObjCInterfaceDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="objcInterfaceDecl0"><pre>Matches Objective-C interface declarations. + +Example matches Foo + @interface Foo + @end +</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('parmVarDecl0')"><a name="parmVarDecl0Anchor">parmVarDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ParmVarDecl.html">ParmVarDecl</a>>...</td></tr> <tr><td colspan="4" class="doc" id="parmVarDecl0"><pre>Matches parameter variable declarations. @@ -298,12 +345,39 @@ parmVarDecl() </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. +<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_1RecordDecl.html">RecordDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="recordDecl0"><pre>Matches class, struct, and union declarations. -Example matches X, Z +Example matches X, Z, U, and S class X; template<class T> class Z {}; + struct S {}; + union 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('staticAssertDecl0')"><a name="staticAssertDecl0Anchor">staticAssertDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1StaticAssertDecl.html">StaticAssertDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="staticAssertDecl0"><pre>Matches a C++ static_assert declaration. + +Example: + staticAssertExpr() +matches + static_assert(sizeof(S) == sizeof(int)) +in + struct S { + int x; + }; + static_assert(sizeof(S) == sizeof(int)); +</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('templateTypeParmDecl0')"><a name="templateTypeParmDecl0Anchor">templateTypeParmDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmDecl.html">TemplateTypeParmDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="templateTypeParmDecl0"><pre>Matches template type parameter declarations. + +Given + template <typename T, int N> struct C {}; +templateTypeParmDecl() + matches 'T', but not 'N'. </pre></td></tr> @@ -330,6 +404,22 @@ typedefDecl() </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('unresolvedUsingTypenameDecl0')"><a name="unresolvedUsingTypenameDecl0Anchor">unresolvedUsingTypenameDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingTypenameDecl.html">UnresolvedUsingTypenameDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="unresolvedUsingTypenameDecl0"><pre>Matches unresolved using value declarations that involve the +typename. + +Given + template <typename T> + struct Base { typedef T Foo; }; + + template<typename T> + struct S : private Base<T> { + using typename Base<T>::Foo; + }; +unresolvedUsingTypenameDecl() + matches using Base<T>::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('unresolvedUsingValueDecl0')"><a name="unresolvedUsingValueDecl0Anchor">unresolvedUsingValueDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingValueDecl.html">UnresolvedUsingValueDecl</a>>...</td></tr> <tr><td colspan="4" class="doc" id="unresolvedUsingValueDecl0"><pre>Matches unresolved using value declarations. @@ -407,14 +497,6 @@ nestedNameSpecifier() </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('CUDAKernelCallExpr0')"><a name="CUDAKernelCallExpr0Anchor">CUDAKernelCallExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CUDAKernelCallExpr.html">CUDAKernelCallExpr</a>>...</td></tr> -<tr><td colspan="4" class="doc" id="CUDAKernelCallExpr0"><pre>Matches CUDA kernel call expression. - -Example matches, - kernel<<<i,j>>>(); -</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. @@ -443,24 +525,6 @@ Example matches 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('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_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('breakStmt0')"><a name="breakStmt0Anchor">breakStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1BreakStmt.html">BreakStmt</a>>...</td></tr> <tr><td colspan="4" class="doc" id="breakStmt0"><pre>Matches break statements. @@ -512,15 +576,6 @@ but does not match </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('catchStmt0')"><a name="catchStmt0Anchor">catchStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCatchStmt.html">CXXCatchStmt</a>>...</td></tr> -<tr><td colspan="4" class="doc" id="catchStmt0"><pre>Matches catch statements. - - try {} catch(int i) {} -catchStmt() - matches 'catch(int i)' -</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('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). @@ -556,8 +611,53 @@ Example matches a ? 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('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. +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('continueStmt0')"><a name="continueStmt0Anchor">continueStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ContinueStmt.html">ContinueStmt</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="continueStmt0"><pre>Matches continue statements. + +Given + while (true) { continue; } +continueStmt() + matches 'continue' +</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('cudaKernelCallExpr0')"><a name="cudaKernelCallExpr0Anchor">cudaKernelCallExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CUDAKernelCallExpr.html">CUDAKernelCallExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="cudaKernelCallExpr0"><pre>Matches CUDA kernel call expression. + +Example matches, + kernel<<<i,j>>>(); +</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('cxxBindTemporaryExpr0')"><a name="cxxBindTemporaryExpr0Anchor">cxxBindTemporaryExpr</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="cxxBindTemporaryExpr0"><pre>Matches nodes where temporaries are created. + +Example matches FunctionTakesString(GetStringByValue()) + (matcher = cxxBindTemporaryExpr()) + 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('cxxBoolLiteral0')"><a name="cxxBoolLiteral0Anchor">cxxBoolLiteral</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="cxxBoolLiteral0"><pre>Matches bool literals. + +Example matches true + 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('cxxCatchStmt0')"><a name="cxxCatchStmt0Anchor">cxxCatchStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCatchStmt.html">CXXCatchStmt</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="cxxCatchStmt0"><pre>Matches catch statements. + + try {} catch(int i) {} +cxxCatchStmt() + matches 'catch(int i)' +</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('cxxConstCastExpr0')"><a name="cxxConstCastExpr0Anchor">cxxConstCastExpr</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="cxxConstCastExpr0"><pre>Matches a const_cast expression. Example: Matches const_cast<int*>(&r) in int n = 42; @@ -566,11 +666,11 @@ Example: Matches const_cast<int*>(&r) in </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). +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('cxxConstructExpr0')"><a name="cxxConstructExpr0Anchor">cxxConstructExpr</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="cxxConstructExpr0"><pre>Matches constructor call expressions (including implicit ones). Example matches string(ptr, n) and ptr within arguments of f - (matcher = constructExpr()) + (matcher = cxxConstructExpr()) void f(const string &a, const string &b); char *ptr; int n; @@ -578,13 +678,172 @@ Example matches string(ptr, n) and ptr within arguments of f </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('continueStmt0')"><a name="continueStmt0Anchor">continueStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ContinueStmt.html">ContinueStmt</a>>...</td></tr> -<tr><td colspan="4" class="doc" id="continueStmt0"><pre>Matches continue statements. +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('cxxDefaultArgExpr0')"><a name="cxxDefaultArgExpr0Anchor">cxxDefaultArgExpr</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="cxxDefaultArgExpr0"><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 = cxxDefaultArgExpr()) + 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('cxxDeleteExpr0')"><a name="cxxDeleteExpr0Anchor">cxxDeleteExpr</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="cxxDeleteExpr0"><pre>Matches delete expressions. Given - while (true) { continue; } -continueStmt() - matches 'continue' + delete X; +cxxDeleteExpr() + 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('cxxDynamicCastExpr0')"><a name="cxxDynamicCastExpr0Anchor">cxxDynamicCastExpr</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="cxxDynamicCastExpr0"><pre>Matches a dynamic_cast expression. + +Example: + cxxDynamicCastExpr() +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_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('cxxForRangeStmt0')"><a name="cxxForRangeStmt0Anchor">cxxForRangeStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXForRangeStmt.html">CXXForRangeStmt</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="cxxForRangeStmt0"><pre>Matches range-based for statements. + +cxxForRangeStmt() matches 'for (auto a : i)' + int i[] = {1, 2, 3}; for (auto a : i); + for(int j = 0; j < 5; ++j); +</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('cxxFunctionalCastExpr0')"><a name="cxxFunctionalCastExpr0Anchor">cxxFunctionalCastExpr</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="cxxFunctionalCastExpr0"><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_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('cxxMemberCallExpr0')"><a name="cxxMemberCallExpr0Anchor">cxxMemberCallExpr</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="cxxMemberCallExpr0"><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('cxxNewExpr0')"><a name="cxxNewExpr0Anchor">cxxNewExpr</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="cxxNewExpr0"><pre>Matches new expressions. + +Given + new X; +cxxNewExpr() + 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('cxxNullPtrLiteralExpr0')"><a name="cxxNullPtrLiteralExpr0Anchor">cxxNullPtrLiteralExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXNullPtrLiteralExpr.html">CXXNullPtrLiteralExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="cxxNullPtrLiteralExpr0"><pre>Matches nullptr literal. +</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('cxxOperatorCallExpr0')"><a name="cxxOperatorCallExpr0Anchor">cxxOperatorCallExpr</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="cxxOperatorCallExpr0"><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 = cxxOperatorCallExpr()) + 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('cxxReinterpretCastExpr0')"><a name="cxxReinterpretCastExpr0Anchor">cxxReinterpretCastExpr</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="cxxReinterpretCastExpr0"><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_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('cxxStaticCastExpr0')"><a name="cxxStaticCastExpr0Anchor">cxxStaticCastExpr</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="cxxStaticCastExpr0"><pre>Matches a C++ static_cast expression. + +hasDestinationType +reinterpretCast + +Example: + cxxStaticCastExpr() +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_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('cxxTemporaryObjectExpr0')"><a name="cxxTemporaryObjectExpr0Anchor">cxxTemporaryObjectExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="cxxTemporaryObjectExpr0"><pre>Matches functional cast expressions having N != 1 arguments + +Example: Matches Foo(bar, bar) + Foo h = Foo(bar, bar); +</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('cxxThisExpr0')"><a name="cxxThisExpr0Anchor">cxxThisExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXThisExpr.html">CXXThisExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="cxxThisExpr0"><pre>Matches implicit and explicit this expressions. + +Example matches the implicit this expression in "return i". + (matcher = cxxThisExpr()) +struct foo { + int i; + int f() { return i; } +}; +</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('cxxThrowExpr0')"><a name="cxxThrowExpr0Anchor">cxxThrowExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXThrowExpr.html">CXXThrowExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="cxxThrowExpr0"><pre>Matches throw expressions. + + try { throw 5; } catch(int i) {} +cxxThrowExpr() + matches 'throw 5' +</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('cxxTryStmt0')"><a name="cxxTryStmt0Anchor">cxxTryStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXTryStmt.html">CXXTryStmt</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="cxxTryStmt0"><pre>Matches try statements. + + try {} catch(int i) {} +cxxTryStmt() + matches 'try {}' +</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('cxxUnresolvedConstructExpr0')"><a name="cxxUnresolvedConstructExpr0Anchor">cxxUnresolvedConstructExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html">CXXUnresolvedConstructExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="cxxUnresolvedConstructExpr0"><pre>Matches unresolved constructor call expressions. + +Example matches T(t) in return statement of f + (matcher = cxxUnresolvedConstructExpr()) + template <typename T> + void f(const T& t) { return T(t); } </pre></td></tr> @@ -607,17 +866,6 @@ declStmt() </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('defaultStmt0')"><a name="defaultStmt0Anchor">defaultStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DefaultStmt.html">DefaultStmt</a>>...</td></tr> <tr><td colspan="4" class="doc" id="defaultStmt0"><pre>Matches default statements inside switch statements. @@ -628,16 +876,6 @@ defaultStmt() </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. @@ -648,20 +886,6 @@ doStmt() </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('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_1Stmt.html">Stmt</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. @@ -709,15 +933,6 @@ Does not match implicit conversions such as </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('forRangeStmt0')"><a name="forRangeStmt0Anchor">forRangeStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXForRangeStmt.html">CXXForRangeStmt</a>>...</td></tr> -<tr><td colspan="4" class="doc" id="forRangeStmt0"><pre>Matches range-based for statements. - -forRangeStmt() matches 'for (auto a : i)' - int i[] = {1, 2, 3}; for (auto a : i); - for(int j = 0; j < 5; ++j); -</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. @@ -727,13 +942,8 @@ Example matches '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('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); +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('gnuNullExpr0')"><a name="gnuNullExpr0Anchor">gnuNullExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1GNUNullExpr.html">GNUNullExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="gnuNullExpr0"><pre>Matches GNU __null expression. </pre></td></tr> @@ -819,15 +1029,6 @@ but does not match </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. @@ -841,21 +1042,6 @@ memberExpr() </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('nullPtrLiteralExpr0')"><a name="nullPtrLiteralExpr0Anchor">nullPtrLiteralExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXNullPtrLiteralExpr.html">CXXNullPtrLiteralExpr</a>>...</td></tr> -<tr><td colspan="4" class="doc" id="nullPtrLiteralExpr0"><pre>Matches nullptr literal. -</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('nullStmt0')"><a name="nullStmt0Anchor">nullStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1NullStmt.html">NullStmt</a>>...</td></tr> <tr><td colspan="4" class="doc" id="nullStmt0"><pre>Matches null statements. @@ -865,31 +1051,14 @@ nullStmt() </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? +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('objcMessageExpr0')"><a name="objcMessageExpr0Anchor">objcMessageExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="objcMessageExpr0"><pre>Matches ObjectiveC Message invocation expressions. -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('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); +The innermost message send invokes the "alloc" class method on the +NSString class, while the outermost message send invokes the +"initWithString" instance method on the object returned from +NSString's "alloc". This matcher should match both message sends. + [[NSString alloc] initWithString:@"Hello"] </pre></td></tr> @@ -903,21 +1072,6 @@ returnStmt() </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('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_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. @@ -968,44 +1122,6 @@ switchStmt() </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('temporaryObjectExpr0')"><a name="temporaryObjectExpr0Anchor">temporaryObjectExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>>...</td></tr> -<tr><td colspan="4" class="doc" id="temporaryObjectExpr0"><pre>Matches functional cast expressions having N != 1 arguments - -Example: Matches Foo(bar, bar) - Foo h = Foo(bar, bar); -</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('thisExpr0')"><a name="thisExpr0Anchor">thisExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXThisExpr.html">CXXThisExpr</a>>...</td></tr> -<tr><td colspan="4" class="doc" id="thisExpr0"><pre>Matches implicit and explicit this expressions. - -Example matches the implicit this expression in "return i". - (matcher = thisExpr()) -struct foo { - int i; - int f() { return i; } -}; -</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('throwExpr0')"><a name="throwExpr0Anchor">throwExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXThrowExpr.html">CXXThrowExpr</a>>...</td></tr> -<tr><td colspan="4" class="doc" id="throwExpr0"><pre>Matches throw expressions. - - try { throw 5; } catch(int i) {} -throwExpr() - matches 'throw 5' -</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('tryStmt0')"><a name="tryStmt0Anchor">tryStmt</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXTryStmt.html">CXXTryStmt</a>>...</td></tr> -<tr><td colspan="4" class="doc" id="tryStmt0"><pre>Matches try statements. - - try {} catch(int i) {} -tryStmt() - matches 'try {}' -</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) @@ -1025,16 +1141,6 @@ Example matches !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('unresolvedConstructExpr0')"><a name="unresolvedConstructExpr0Anchor">unresolvedConstructExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html">CXXUnresolvedConstructExpr</a>>...</td></tr> -<tr><td colspan="4" class="doc" id="unresolvedConstructExpr0"><pre>Matches unresolved constructor call expressions. - -Example matches T(t) in return statement of f - (matcher = unresolvedConstructExpr()) - template <typename T> - void f(const T& t) { return T(t); } -</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('userDefinedLiteral0')"><a name="userDefinedLiteral0Anchor">userDefinedLiteral</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UserDefinedLiteral.html">UserDefinedLiteral</a>>...</td></tr> <tr><td colspan="4" class="doc" id="userDefinedLiteral0"><pre>Matches user defined literal operator call. @@ -1148,6 +1254,18 @@ constantArrayType() </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('decayedType0')"><a name="decayedType0Anchor">decayedType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DecayedType.html">DecayedType</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="decayedType0"><pre>Matches decayed type +Example matches i[] in declaration of f. + (matcher = valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))) +Example matches i[1]. + (matcher = expr(hasType(decayedType(hasDecayedType(pointerType()))))) + void f(int i[]) { + i[1] = 0; + } +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('dependentSizedArrayType0')"><a name="dependentSizedArrayType0Anchor">dependentSizedArrayType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DependentSizedArrayType.html">DependentSizedArrayType</a>>...</td></tr> <tr><td colspan="4" class="doc" id="dependentSizedArrayType0"><pre>Matches C++ arrays whose size is a value-dependent expression. @@ -1204,6 +1322,18 @@ incompleteArrayType() </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('injectedClassNameType0')"><a name="injectedClassNameType0Anchor">injectedClassNameType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="injectedClassNameType0"><pre>Matches injected class name types. + +Example matches S s, but not S<T> s. + (matcher = parmVarDecl(hasType(injectedClassNameType()))) + template <typename T> struct S { + void f(S s); + void g(S<T> s); + }; +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('lValueReferenceType0')"><a name="lValueReferenceType0Anchor">lValueReferenceType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1LValueReferenceType.html">LValueReferenceType</a>>...</td></tr> <tr><td colspan="4" class="doc" id="lValueReferenceType0"><pre>Matches lvalue reference types. @@ -1231,6 +1361,21 @@ memberPointerType() </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('objcObjectPointerType0')"><a name="objcObjectPointerType0Anchor">objcObjectPointerType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCObjectPointerType.html">ObjCObjectPointerType</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="objcObjectPointerType0"><pre>Matches an Objective-C object pointer type, which is different from +a pointer type, despite being syntactically similar. + +Given + int *a; + + @interface Foo + @end + Foo *f; +pointerType() + matches "Foo *f", but does not match "int *a". +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('parenType0')"><a name="parenType0Anchor">parenType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ParenType.html">ParenType</a>>...</td></tr> <tr><td colspan="4" class="doc" id="parenType0"><pre>Matches ParenType nodes. @@ -1244,14 +1389,19 @@ array_of_ptrs. <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('pointerType0')"><a name="pointerType0Anchor">pointerType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1PointerType.html">PointerType</a>>...</td></tr> -<tr><td colspan="4" class="doc" id="pointerType0"><pre>Matches pointer types. +<tr><td colspan="4" class="doc" id="pointerType0"><pre>Matches pointer types, but does not match Objective-C object pointer +types. Given int *a; int &b = *a; int c = 5; + + @interface Foo + @end + Foo *f; pointerType() - matches "int *a" + matches "int *a", but does not match "Foo *f". </pre></td></tr> @@ -1303,6 +1453,20 @@ referenceType() matches the types of b, c, d, e, and f. </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('substTemplateTypeParmType0')"><a name="substTemplateTypeParmType0Anchor">substTemplateTypeParmType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1SubstTemplateTypeParmType.html">SubstTemplateTypeParmType</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="substTemplateTypeParmType0"><pre>Matches types that represent the result of substituting a type for a +template type parameter. + +Given + template <typename T> + void F(T t) { + int i = 1 + t; + } + +substTemplateTypeParmType() matches the type of 't' but not '1' +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('templateSpecializationType0')"><a name="templateSpecializationType0Anchor">templateSpecializationType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>...</td></tr> <tr><td colspan="4" class="doc" id="templateSpecializationType0"><pre>Matches template specialization types. @@ -1318,6 +1482,15 @@ instantiation in A and the type of the variable declaration in B. </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('templateTypeParmType0')"><a name="templateTypeParmType0Anchor">templateTypeParmType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="templateTypeParmType0"><pre>Matches template type parameter types. + +Example matches T, but not int. + (matcher = templateTypeParmType()) + template <typename T> void f(int i); +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('type0')"><a name="type0Anchor">type</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>>...</td></tr> <tr><td colspan="4" class="doc" id="type0"><pre>Matches Types in the clang AST. </pre></td></tr> @@ -1407,7 +1580,7 @@ Usable as: Any Matcher <tr><td>Matcher<*></td><td class="name" onclick="toggle('unless0')"><a name="unless0Anchor">unless</a></td><td>Matcher<*></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")))) +Example matches Y (matcher = cxxRecordDecl(unless(hasName("X")))) class X {}; class Y {}; @@ -1427,21 +1600,27 @@ Example matches a || b (matcher = binaryOperator(hasOperatorName("||"))) <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))) +Example matches true (matcher = cxxBoolLiteral(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_1CXXCatchStmt.html">CXXCatchStmt</a>></td><td class="name" onclick="toggle('isCatchAll1')"><a name="isCatchAll1Anchor">isCatchAll</a></td><td></td></tr> -<tr><td colspan="4" class="doc" id="isCatchAll1"><pre>Matches a C++ catch statement that has a handler that catches any exception type. -Example matches catch(...) (matcher = catchStmt(isCatchAll())) +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCatchStmt.html">CXXCatchStmt</a>></td><td class="name" onclick="toggle('isCatchAll0')"><a name="isCatchAll0Anchor">isCatchAll</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isCatchAll0"><pre>Matches a C++ catch statement that has a catch-all handler. + +Given try { - // ... - } catch(...) { + ... + } catch (int) { + ... + } catch (...) { + ... } +endcode +cxxCatchStmt(isCatchAll()) matches catch(...) but not catch(int). </pre></td></tr> @@ -1460,6 +1639,113 @@ Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2))) </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('isCopyConstructor0')"><a name="isCopyConstructor0Anchor">isCopyConstructor</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isCopyConstructor0"><pre>Matches constructor declarations that are copy constructors. + +Given + struct S { + S(); #1 + S(const S &); #2 + S(S &&); #3 + }; +cxxConstructorDecl(isCopyConstructor()) will match #2, but not #1 or #3. +</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('isDefaultConstructor0')"><a name="isDefaultConstructor0Anchor">isDefaultConstructor</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isDefaultConstructor0"><pre>Matches constructor declarations that are default constructors. + +Given + struct S { + S(); #1 + S(const S &); #2 + S(S &&); #3 + }; +cxxConstructorDecl(isDefaultConstructor()) will match #1, but not #2 or #3. +</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('isExplicit0')"><a name="isExplicit0Anchor">isExplicit</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isExplicit0"><pre>Matches constructor and conversion declarations that are marked with +the explicit keyword. + +Given + struct S { + S(int); #1 + explicit S(double); #2 + operator int(); #3 + explicit operator bool(); #4 + }; +cxxConstructorDecl(isExplicit()) will match #2, but not #1. +cxxConversionDecl(isExplicit()) will match #4, but not #3. +</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('isMoveConstructor0')"><a name="isMoveConstructor0Anchor">isMoveConstructor</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isMoveConstructor0"><pre>Matches constructor declarations that are move constructors. + +Given + struct S { + S(); #1 + S(const S &); #2 + S(S &&); #3 + }; +cxxConstructorDecl(isMoveConstructor()) will match #3, but not #1 or #2. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConversionDecl.html">CXXConversionDecl</a>></td><td class="name" onclick="toggle('isExplicit1')"><a name="isExplicit1Anchor">isExplicit</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isExplicit1"><pre>Matches constructor and conversion declarations that are marked with +the explicit keyword. + +Given + struct S { + S(int); #1 + explicit S(double); #2 + operator int(); #3 + explicit operator bool(); #4 + }; +cxxConstructorDecl(isExplicit()) will match #2, but not #1. +cxxConversionDecl(isExplicit()) will match #4, but not #3. +</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('isBaseInitializer0')"><a name="isBaseInitializer0Anchor">isBaseInitializer</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isBaseInitializer0"><pre>Matches a constructor initializer if it is initializing a base, as +opposed to a member. + +Given + struct B {}; + struct D : B { + int I; + D(int i) : I(i) {} + }; + struct E : B { + E() : B() {} + }; +cxxConstructorDecl(hasAnyConstructorInitializer(isBaseInitializer())) + will match E(), but not match D(int). +</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('isMemberInitializer0')"><a name="isMemberInitializer0Anchor">isMemberInitializer</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isMemberInitializer0"><pre>Matches a constructor initializer if it is initializing a member, as +opposed to a base. + +Given + struct B {}; + struct D : B { + int I; + D(int i) : I(i) {} + }; + struct E : B { + E() : B() {} + }; +cxxConstructorDecl(hasAnyConstructorInitializer(isMemberInitializer())) + will match D(int), but not match E(). +</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 constructor initializer if it is explicitly written in code (as opposed to implicitly added by the compiler). @@ -1470,7 +1756,7 @@ Given Foo(int) : foo_("A") { } string foo_; }; -constructorDecl(hasAnyConstructorInitializer(isWritten())) +cxxConstructorDecl(hasAnyConstructorInitializer(isWritten())) will match Foo(int), but not Foo() </pre></td></tr> @@ -1484,7 +1770,39 @@ struct A { void bar(); }; -methodDecl(isConst()) matches A::foo() but not A::bar() +cxxMethodDecl(isConst()) matches A::foo() but not A::bar() +</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('isCopyAssignmentOperator0')"><a name="isCopyAssignmentOperator0Anchor">isCopyAssignmentOperator</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isCopyAssignmentOperator0"><pre>Matches if the given method declaration declares a copy assignment +operator. + +Given +struct A { + A &operator=(const A &); + A &operator=(A &&); +}; + +cxxMethodDecl(isCopyAssignmentOperator()) matches the first method but not +the second one. +</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('isFinal1')"><a name="isFinal1Anchor">isFinal</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isFinal1"><pre>Matches if the given method or class declaration is final. + +Given: + class A final {}; + + struct B { + virtual void f(); + }; + + struct C : B { + void f() final; + }; +matches A and C::f, but not B, C, or B::f </pre></td></tr> @@ -1540,9 +1858,10 @@ Given: A a; a << a; <-- This matches -operatorCallExpr(hasOverloadedOperatorName("<<"))) matches the specified -line and recordDecl(hasMethod(hasOverloadedOperatorName("*"))) matches -the declaration of A. +cxxOperatorCallExpr(hasOverloadedOperatorName("<<"))) matches the +specified line and +cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*"))) +matches the declaration of A. Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html">CXXOperatorCallExpr</a>>, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>> </pre></td></tr> @@ -1567,6 +1886,23 @@ Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Functi </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('isFinal0')"><a name="isFinal0Anchor">isFinal</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isFinal0"><pre>Matches if the given method or class declaration is final. + +Given: + class A final {}; + + struct B { + virtual void f(); + }; + + struct C : B { + void f() final; + }; +matches A and C::f, but not B, C, or B::f +</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('isSameOrDerivedFrom1')"><a name="isSameOrDerivedFrom1Anchor">isSameOrDerivedFrom</a></td><td>std::string BaseName</td></tr> <tr><td colspan="4" class="doc" id="isSameOrDerivedFrom1"><pre>Overloaded method as shortcut for isSameOrDerivedFrom(hasName(...)). @@ -1581,13 +1917,13 @@ 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()) +cxxRecordDecl(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()) +cxxRecordDecl(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>> @@ -1607,7 +1943,7 @@ Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2))) <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))) +Example matches true (matcher = cxxBoolLiteral(equals(true))) true Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<CXXBoolLiteral>, @@ -1670,7 +2006,7 @@ Matches a node if it equals the node previously bound to ID. Given class X { int a; int b; }; -recordDecl( +cxxRecordDecl( has(fieldDecl(hasName("a"), hasType(type().bind("t")))), has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t")))))) matches the class X, as a and b have the same type. @@ -1692,7 +2028,8 @@ and reference to that variable declaration within a compound statement. Given __attribute__((device)) void f() { ... } decl(hasAttr(clang::attr::CUDADevice)) matches the function declaration of -f. +f. If the matcher is use from clang-query, attr::Kind parameter should be +passed as a quoted string. e.g., hasAttr("attr::CUDADevice"). </pre></td></tr> @@ -1701,7 +2038,7 @@ f. partially matching a given regex. Example matches Y but not X - (matcher = recordDecl(isExpansionInFileMatching("AST.*")) + (matcher = cxxRecordDecl(isExpansionInFileMatching("AST.*")) #include "ASTMatcher.h" class X {}; ASTMatcher.h: @@ -1714,7 +2051,8 @@ Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.h <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('isExpansionInMainFile0')"><a name="isExpansionInMainFile0Anchor">isExpansionInMainFile</a></td><td></td></tr> <tr><td colspan="4" class="doc" id="isExpansionInMainFile0"><pre>Matches AST nodes that were expanded within the main-file. -Example matches X but not Y (matcher = recordDecl(isExpansionInMainFile()) +Example matches X but not Y + (matcher = cxxRecordDecl(isExpansionInMainFile()) #include <Y.h> class X {}; Y.h: @@ -1728,7 +2066,7 @@ Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.h <tr><td colspan="4" class="doc" id="isExpansionInSystemHeader0"><pre>Matches AST nodes that were expanded within system-header-files. Example matches Y but not X - (matcher = recordDecl(isExpansionInSystemHeader()) + (matcher = cxxRecordDecl(isExpansionInSystemHeader()) #include <SystemHeader.h> class X {}; SystemHeader.h: @@ -1789,7 +2127,7 @@ fieldDecl(isPublic()) <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))) +Example matches true (matcher = cxxBoolLiteral(equals(true))) true Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<CXXBoolLiteral>, @@ -1809,14 +2147,28 @@ Given: A a; a << a; <-- This matches -operatorCallExpr(hasOverloadedOperatorName("<<"))) matches the specified -line and recordDecl(hasMethod(hasOverloadedOperatorName("*"))) matches -the declaration of A. +cxxOperatorCallExpr(hasOverloadedOperatorName("<<"))) matches the +specified line and +cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*"))) +matches the declaration of A. Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html">CXXOperatorCallExpr</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('isConstexpr1')"><a name="isConstexpr1Anchor">isConstexpr</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isConstexpr1"><pre>Matches constexpr variable and function declarations. + +Given: + constexpr int foo = 42; + constexpr int bar(); +varDecl(isConstexpr()) + matches the declaration of foo. +functionDecl(isConstexpr()) + matches the declaration of bar. +</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('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. @@ -1869,6 +2221,35 @@ functionDecl(isExternC()) </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('isInline1')"><a name="isInline1Anchor">isInline</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isInline1"><pre>Matches function and namespace declarations that are marked with +the inline keyword. + +Given + inline void f(); + void g(); + namespace n { + inline namespace m {} + } +functionDecl(isInline()) will match ::f(). +namespaceDecl(isInline()) will match n::m. +</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('isNoThrow0')"><a name="isNoThrow0Anchor">isNoThrow</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isNoThrow0"><pre>Matches functions that have a non-throwing exception specification. + +Given: + void f(); + void g() noexcept; + void h() throw(); + void i() throw(int); + void j() noexcept(false); +functionDecl(isNoThrow()) + matches the declarations of g, and h, but not f, i or j. +</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('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. @@ -1877,19 +2258,31 @@ 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()) +cxxRecordDecl(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()) +cxxRecordDecl(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_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('isVariadic0')"><a name="isVariadic0Anchor">isVariadic</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isVariadic0"><pre>Matches if a function declaration is variadic. + +Example matches f, but not g or h. The function i will not match, even when +compiled in C mode. + void f(...); + void g(int); + template <typename... Ts> void h(Ts...); + void i(); +</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('parameterCountIs0')"><a name="parameterCountIs0Anchor">parameterCountIs</a></td><td>unsigned N</td></tr> <tr><td colspan="4" class="doc" id="parameterCountIs0"><pre>Matches FunctionDecls that have a specific parameter count. @@ -1904,7 +2297,7 @@ functionDecl(parameterCountIs(2)) <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))) +Example matches true (matcher = cxxBoolLiteral(equals(true))) true Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>>, Matcher<CXXBoolLiteral>, @@ -1960,13 +2353,113 @@ Example matches X (regexp is one of "::X", "^foo::.*X", among others) </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1NamespaceDecl.html">NamespaceDecl</a>></td><td class="name" onclick="toggle('isAnonymous0')"><a name="isAnonymous0Anchor">isAnonymous</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isAnonymous0"><pre>Matches anonymous namespace declarations. + +Given + namespace n { + namespace {} #1 + } +namespaceDecl(isAnonymous()) will match #1 but not ::n. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1NamespaceDecl.html">NamespaceDecl</a>></td><td class="name" onclick="toggle('isInline0')"><a name="isInline0Anchor">isInline</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isInline0"><pre>Matches function and namespace declarations that are marked with +the inline keyword. + +Given + inline void f(); + void g(); + namespace n { + inline namespace m {} + } +functionDecl(isInline()) will match ::f(). +namespaceDecl(isInline()) will match n::m. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('argumentCountIs2')"><a name="argumentCountIs2Anchor">argumentCountIs</a></td><td>unsigned N</td></tr> +<tr><td colspan="4" class="doc" id="argumentCountIs2"><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_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('hasKeywordSelector0')"><a name="hasKeywordSelector0Anchor">hasKeywordSelector</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="hasKeywordSelector0"><pre>Matches when the selector is a keyword selector + +objCMessageExpr(hasKeywordSelector()) matches the generated setFrame +message expression in + + UIWebView *webView = ...; + CGRect bodyFrame = webView.frame; + bodyFrame.size.height = self.bodyContentHeight; + webView.frame = bodyFrame; + ^---- matches here +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('hasNullSelector0')"><a name="hasNullSelector0Anchor">hasNullSelector</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="hasNullSelector0"><pre>Matches when the selector is the empty selector + +Matches only when the selector of the objCMessageExpr is NULL. This may +represent an error condition in the tree! +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('hasSelector0')"><a name="hasSelector0Anchor">hasSelector</a></td><td>std::string BaseName</td></tr> +<tr><td colspan="4" class="doc" id="hasSelector0"><pre>Matches when BaseName == Selector.getAsString() + + matcher = objCMessageExpr(hasSelector("loadHTMLString:baseURL:")); + matches the outer message expr in the code below, but NOT the message + invocation for self.bodyView. + [self.bodyView loadHTMLString:html baseURL:NULL]; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('hasUnarySelector0')"><a name="hasUnarySelector0Anchor">hasUnarySelector</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="hasUnarySelector0"><pre>Matches when the selector is a Unary Selector + + matcher = objCMessageExpr(matchesSelector(hasUnarySelector()); + matches self.bodyView in the code below, but NOT the outer message + invocation of "loadHTMLString:baseURL:". + [self.bodyView loadHTMLString:html baseURL:NULL]; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('matchesSelector0')"><a name="matchesSelector0Anchor">matchesSelector</a></td><td>std::string RegExp</td></tr> +<tr><td colspan="4" class="doc" id="matchesSelector0"><pre>Matches ObjC selectors whose name contains +a substring matched by the given RegExp. + matcher = objCMessageExpr(matchesSelector("loadHTMLStringmatches the outer message expr in the code below, but NOT the message + invocation for self.bodyView. + [self.bodyView loadHTMLString:html baseURL:NULL]; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('numSelectorArgs0')"><a name="numSelectorArgs0Anchor">numSelectorArgs</a></td><td>unsigned N</td></tr> +<tr><td colspan="4" class="doc" id="numSelectorArgs0"><pre>Matches when the selector has the specified number of arguments + + matcher = objCMessageExpr(numSelectorArgs(0)); + matches self.bodyView in the code below + + matcher = objCMessageExpr(numSelectorArgs(2)); + matches the invocation of "loadHTMLString:baseURL:" but not that + of self.bodyView + [self.bodyView loadHTMLString:html baseURL:NULL]; +</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 *")))) +cxxMemberCallExpr(on(hasType(asString("class Y *")))) matches y->x() </pre></td></tr> @@ -1978,7 +2471,7 @@ Matches a node if it equals the node previously bound to ID. Given class X { int a; int b; }; -recordDecl( +cxxRecordDecl( has(fieldDecl(hasName("a"), hasType(type().bind("t")))), has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t")))))) matches the class X, as a and b have the same type. @@ -2009,6 +2502,18 @@ i is const-qualified but the qualifier is not local. </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('isAnyCharacter0')"><a name="isAnyCharacter0Anchor">isAnyCharacter</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isAnyCharacter0"><pre>Matches QualType nodes that are of character type. + +Given + void a(char); + void b(wchar_t); + void c(double); +functionDecl(hasAnyParameter(hasType(isAnyCharacter()))) +matches "a(char)", "b(wchar_t)", but not "c(double)". +</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. @@ -2038,6 +2543,53 @@ matches "a(int)", "b(long)", but not "c(double)". </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('isVolatileQualified0')"><a name="isVolatileQualified0Anchor">isVolatileQualified</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isVolatileQualified0"><pre>Matches QualType nodes that are volatile-qualified, i.e., that +include "top-level" volatile. + +Given + void a(int); + void b(int volatile); + void c(volatile int); + void d(volatile int*); + void e(int volatile) {}; +functionDecl(hasAnyParameter(hasType(isVolatileQualified()))) + matches "void b(int volatile)", "void c(volatile int)" and + "void e(int volatile) {}". It does not match d as there + is no top-level volatile on the parameter type "volatile int *". +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordDecl.html">RecordDecl</a>></td><td class="name" onclick="toggle('isClass0')"><a name="isClass0Anchor">isClass</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isClass0"><pre>Matches RecordDecl object that are spelled with "class." + +Example matches C, but not S or U. + struct S {}; + class C {}; + union U {}; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordDecl.html">RecordDecl</a>></td><td class="name" onclick="toggle('isStruct0')"><a name="isStruct0Anchor">isStruct</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isStruct0"><pre>Matches RecordDecl object that are spelled with "struct." + +Example matches S, but not C or U. + struct S {}; + class C {}; + union U {}; +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordDecl.html">RecordDecl</a>></td><td class="name" onclick="toggle('isUnion0')"><a name="isUnion0Anchor">isUnion</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isUnion0"><pre>Matches RecordDecl object that are spelled with "union." + +Example matches U, but not C or S. + struct S {}; + class C {}; + union U {}; +</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('equalsBoundNode0')"><a name="equalsBoundNode0Anchor">equalsBoundNode</a></td><td>std::string ID</td></tr> <tr><td colspan="4" class="doc" id="equalsBoundNode0"><pre>Matches if a node equals a previously bound node. @@ -2045,7 +2597,7 @@ Matches a node if it equals the node previously bound to ID. Given class X { int a; int b; }; -recordDecl( +cxxRecordDecl( has(fieldDecl(hasName("a"), hasType(type().bind("t")))), has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t")))))) matches the class X, as a and b have the same type. @@ -2066,7 +2618,7 @@ and reference to that variable declaration within a compound statement. partially matching a given regex. Example matches Y but not X - (matcher = recordDecl(isExpansionInFileMatching("AST.*")) + (matcher = cxxRecordDecl(isExpansionInFileMatching("AST.*")) #include "ASTMatcher.h" class X {}; ASTMatcher.h: @@ -2079,7 +2631,8 @@ Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.h <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('isExpansionInMainFile1')"><a name="isExpansionInMainFile1Anchor">isExpansionInMainFile</a></td><td></td></tr> <tr><td colspan="4" class="doc" id="isExpansionInMainFile1"><pre>Matches AST nodes that were expanded within the main-file. -Example matches X but not Y (matcher = recordDecl(isExpansionInMainFile()) +Example matches X but not Y + (matcher = cxxRecordDecl(isExpansionInMainFile()) #include <Y.h> class X {}; Y.h: @@ -2093,7 +2646,7 @@ Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.h <tr><td colspan="4" class="doc" id="isExpansionInSystemHeader1"><pre>Matches AST nodes that were expanded within system-header-files. Example matches Y but not X - (matcher = recordDecl(isExpansionInSystemHeader()) + (matcher = cxxRecordDecl(isExpansionInSystemHeader()) #include <SystemHeader.h> class X {}; SystemHeader.h: @@ -2163,7 +2716,7 @@ classTemplateSpecializationDecl(templateArgumentCountIs(1)) partially matching a given regex. Example matches Y but not X - (matcher = recordDecl(isExpansionInFileMatching("AST.*")) + (matcher = cxxRecordDecl(isExpansionInFileMatching("AST.*")) #include "ASTMatcher.h" class X {}; ASTMatcher.h: @@ -2176,7 +2729,8 @@ Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.h <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('isExpansionInMainFile2')"><a name="isExpansionInMainFile2Anchor">isExpansionInMainFile</a></td><td></td></tr> <tr><td colspan="4" class="doc" id="isExpansionInMainFile2"><pre>Matches AST nodes that were expanded within the main-file. -Example matches X but not Y (matcher = recordDecl(isExpansionInMainFile()) +Example matches X but not Y + (matcher = cxxRecordDecl(isExpansionInMainFile()) #include <Y.h> class X {}; Y.h: @@ -2190,7 +2744,7 @@ Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.h <tr><td colspan="4" class="doc" id="isExpansionInSystemHeader2"><pre>Matches AST nodes that were expanded within system-header-files. Example matches Y but not X - (matcher = recordDecl(isExpansionInSystemHeader()) + (matcher = cxxRecordDecl(isExpansionInSystemHeader()) #include <SystemHeader.h> class X {}; SystemHeader.h: @@ -2200,6 +2754,16 @@ Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.h </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('booleanType0')"><a name="booleanType0Anchor">booleanType</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="booleanType0"><pre>Matches type bool. + +Given + struct S { bool func(); }; +functionDecl(returns(booleanType())) + matches "bool func();" +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('equalsBoundNode2')"><a name="equalsBoundNode2Anchor">equalsBoundNode</a></td><td>std::string ID</td></tr> <tr><td colspan="4" class="doc" id="equalsBoundNode2"><pre>Matches if a node equals a previously bound node. @@ -2207,7 +2771,7 @@ Matches a node if it equals the node previously bound to ID. Given class X { int a; int b; }; -recordDecl( +cxxRecordDecl( has(fieldDecl(hasName("a"), hasType(type().bind("t")))), has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t")))))) matches the class X, as a and b have the same type. @@ -2253,6 +2817,20 @@ Example matches a || b (matcher = binaryOperator(hasOperatorName("||"))) </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('hasAutomaticStorageDuration0')"><a name="hasAutomaticStorageDuration0Anchor">hasAutomaticStorageDuration</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="hasAutomaticStorageDuration0"><pre>Matches a variable declaration that has automatic storage duration. + +Example matches x, but not y, z, or a. +(matcher = varDecl(hasAutomaticStorageDuration()) +void f() { + int x; + static int y; + thread_local int z; +} +int 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('hasGlobalStorage0')"><a name="hasGlobalStorage0Anchor">hasGlobalStorage</a></td><td></td></tr> <tr><td colspan="4" class="doc" id="hasGlobalStorage0"><pre>Matches a variable declaration that does not have local storage. @@ -2278,6 +2856,47 @@ int z; </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('hasStaticStorageDuration0')"><a name="hasStaticStorageDuration0Anchor">hasStaticStorageDuration</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="hasStaticStorageDuration0"><pre>Matches a variable declaration that has static storage duration. + +Example matches y and a, but not x or z. +(matcher = varDecl(hasStaticStorageDuration()) +void f() { + int x; + static int y; + thread_local int z; +} +int 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('hasThreadStorageDuration0')"><a name="hasThreadStorageDuration0Anchor">hasThreadStorageDuration</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="hasThreadStorageDuration0"><pre>Matches a variable declaration that has thread storage duration. + +Example matches z, but not x, z, or a. +(matcher = varDecl(hasThreadStorageDuration()) +void f() { + int x; + static int y; + thread_local int z; +} +int 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('isConstexpr0')"><a name="isConstexpr0Anchor">isConstexpr</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isConstexpr0"><pre>Matches constexpr variable and function declarations. + +Given: + constexpr int foo = 42; + constexpr int bar(); +varDecl(isConstexpr()) + matches the declaration of foo. +functionDecl(isConstexpr()) + matches the declaration of bar. +</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. @@ -2293,6 +2912,19 @@ Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagDec </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('isExceptionVariable0')"><a name="isExceptionVariable0Anchor">isExceptionVariable</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isExceptionVariable0"><pre>Matches a variable declaration that is an exception variable from +a C++ catch block, or an Objective-C statement. + +Example matches x (matcher = varDecl(isExceptionVariable()) +void f(int y) { + try { + } catch (int x) { + } +} +</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. @@ -2315,13 +2947,13 @@ 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()) +cxxRecordDecl(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()) +cxxRecordDecl(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>> @@ -2383,8 +3015,8 @@ matching submatcher. For example, in: class A { int a; int b; }; The matcher: - recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), - has(fieldDecl(hasName("b")).bind("v")))) + cxxRecordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), + has(fieldDecl(hasName("b")).bind("v")))) will generate two results binding "v", the first of which binds the field declaration of a, the second the field declaration of b. @@ -2398,7 +3030,7 @@ Usable as: Any Matcher provided matcher. Example matches X, A, B, C - (matcher = recordDecl(forEachDescendant(recordDecl(hasName("X"))))) + (matcher = cxxRecordDecl(forEachDescendant(cxxRecordDecl(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 {}; }; }; @@ -2409,7 +3041,9 @@ 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())))) + cxxRecordDecl(forEachDescendant(cxxRecordDecl( + forEachDescendant(cxxRecordDecl()) + ))) will match 10 times (plus injected class name matches) on: class A { class B { class C { class D { class E {}; }; }; }; }; @@ -2421,7 +3055,8 @@ Usable as: Any Matcher <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"))) +Example matches X, Y + (matcher = cxxRecordDecl(forEach(cxxRecordDecl(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. @@ -2453,7 +3088,7 @@ Usable as: Any Matcher provided matcher. Example matches X, Y, Z - (matcher = recordDecl(hasDescendant(recordDecl(hasName("X"))))) + (matcher = cxxRecordDecl(hasDescendant(cxxRecordDecl(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 {}; }; }; @@ -2468,7 +3103,8 @@ Usable as: Any Matcher <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"))) +Example matches X, Y + (matcher = cxxRecordDecl(has(cxxRecordDecl(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. @@ -2514,6 +3150,22 @@ arraySubscriptExpression(hasIndex(integerLiteral())) </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('hasLHS1')"><a name="hasLHS1Anchor">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="hasLHS1"><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_1ArraySubscriptExpr.html">ArraySubscriptExpr</a>></td><td class="name" onclick="toggle('hasRHS1')"><a name="hasRHS1Anchor">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="hasRHS1"><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_1ArrayTypeLoc.html">ArrayTypeLoc</a>></td><td class="name" onclick="toggle('hasElementTypeLoc0')"><a name="hasElementTypeLoc0Anchor">hasElementTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td></tr> <tr><td colspan="4" class="doc" id="hasElementTypeLoc0"><pre>Matches arrays and C99 complex types that have a specific element type. @@ -2695,7 +3347,9 @@ Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallEx Given class A { A() : i(42), j(42) {} int i; int j; }; -constructorDecl(forEachConstructorInitializer(forField(decl().bind("x")))) +cxxConstructorDecl(forEachConstructorInitializer( + forField(decl().bind("x")) +)) will trigger two matches, binding for 'i' and 'j' respectively. </pre></td></tr> @@ -2708,7 +3362,9 @@ Given Foo() : foo_(1) { } int foo_; }; -recordDecl(has(constructorDecl(hasAnyConstructorInitializer(anything())))) +cxxRecordDecl(has(cxxConstructorDecl( + hasAnyConstructorInitializer(anything()) +))) record matches Foo, hasAnyConstructorInitializer matches foo_(1) </pre></td></tr> @@ -2721,7 +3377,7 @@ Given Foo() : foo_(1) { } int foo_; }; -recordDecl(has(constructorDecl(hasAnyConstructorInitializer( +cxxRecordDecl(has(cxxConstructorDecl(hasAnyConstructorInitializer( forField(hasName("foo_")))))) matches Foo with forField matching foo_ @@ -2736,7 +3392,7 @@ Given Foo() : foo_(1) { } int foo_; }; -recordDecl(has(constructorDecl(hasAnyConstructorInitializer( +cxxRecordDecl(has(cxxConstructorDecl(hasAnyConstructorInitializer( withInitializer(integerLiteral(equals(1))))))) matches Foo with withInitializer matching (1) @@ -2783,7 +3439,8 @@ matches 'a' in <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")))))) +Example matches y.x() + (matcher = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y")))))) class Y { public: void x(); }; void z() { Y y; y.x(); }", @@ -2811,7 +3468,7 @@ FIXME: What other kind of declarations would we need to generalize this to? Example matches A() in the last line - (matcher = constructExpr(hasDeclaration(methodDecl( + (matcher = cxxConstructExpr(hasDeclaration(cxxMethodDecl( ofClass(hasName("A")))))) class A { public: @@ -2828,8 +3485,8 @@ Given: class A { void func(); }; class B { void member(); }; -recordDecl(hasMethod(hasName("func"))) matches the declaration of A -but not B. +cxxRecordDecl(hasMethod(hasName("func"))) matches the declaration of +A but not B. </pre></td></tr> @@ -2864,7 +3521,8 @@ match Base. <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"))))) +Example matches y.x() (matcher = callExpr(callee( + cxxMethodDecl(hasName("x"))))) class Y { public: void x(); }; void z() { Y y; y.x(); } </pre></td></tr> @@ -2953,7 +3611,7 @@ caseStmt(hasCaseConstant(integerLiteral())) <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())) + hasSourceExpression(cxxConstructExpr())) class URL { URL(string); }; URL url = "a string"; </pre></td></tr> @@ -3034,7 +3692,7 @@ with compoundStmt() <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)))) +Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) if (true) {} </pre></td></tr> @@ -3055,6 +3713,11 @@ Example matches a </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1DecayedType.html">DecayedType</a>></td><td class="name" onclick="toggle('hasDecayedType0')"><a name="hasDecayedType0Anchor">hasDecayedType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>> InnerType</td></tr> +<tr><td colspan="4" class="doc" id="hasDecayedType0"><pre>Matches the decayed type, whos decayed type matches InnerMatcher +</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('hasDeclaration11')"><a name="hasDeclaration11Anchor">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="hasDeclaration11"><pre>Matches a node if the declaration associated with that node matches the given matcher. @@ -3081,8 +3744,6 @@ Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallEx <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; @@ -3090,7 +3751,7 @@ Given f(); Matches this .. a::f(); .. but not this. } -declRefExpr(throughUsingDeclaration(anything())) +declRefExpr(throughUsingDecl(anything())) matches f() </pre></td></tr> @@ -3158,7 +3819,7 @@ Given } } -recordDecl(hasDeclContext(namedDecl(hasName("M")))) matches the +cxxRcordDecl(hasDeclContext(namedDecl(hasName("M")))) matches the declaration of class D. </pre></td></tr> @@ -3180,7 +3841,7 @@ with compoundStmt() <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)))) +Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) if (true) {} </pre></td></tr> @@ -3255,12 +3916,12 @@ 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." +declaration "X x;", cxxRecordDecl(hasName("X")) matches the declaration of +X, while varDecl(hasType(cxxRecordDecl(hasName("X")))) matches the +declaration of x. -Example matches x (matcher = expr(hasType(recordDecl(hasName("X"))))) - and z (matcher = varDecl(hasType(recordDecl(hasName("X"))))) +Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X"))))) + and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X"))))) class X {}; void y(X &x) { x; X z; } @@ -3272,8 +3933,8 @@ Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.h <tr><td colspan="4" class="doc" id="hasType0"><pre>Matches if the expression's or declaration's type matches a type matcher. -Example matches x (matcher = expr(hasType(recordDecl(hasName("X"))))) - and z (matcher = varDecl(hasType(recordDecl(hasName("X"))))) +Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X"))))) + and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X"))))) class X {}; void y(X &x) { x; X z; } </pre></td></tr> @@ -3361,7 +4022,7 @@ with compoundStmt() <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)))) +Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) if (true) {} </pre></td></tr> @@ -3393,7 +4054,7 @@ Does not match the 'this' parameter of a method. Given class X { void f(int x, int y, int z) {} }; -methodDecl(hasAnyParameter(hasName("y"))) +cxxMethodDecl(hasAnyParameter(hasName("y"))) matches f(int x, int y, int z) {} with hasAnyParameter(...) matching int y @@ -3405,7 +4066,7 @@ with hasAnyParameter(...) Given class X { void f(int x) {} }; -methodDecl(hasParameter(0, hasType(varDecl()))) +cxxMethodDecl(hasParameter(0, hasType(varDecl()))) matches f(int x) {} with hasParameter(...) matching int x @@ -3417,7 +4078,7 @@ with hasParameter(...) Given: class X { int f() { return 1; } }; -methodDecl(returns(asString("int"))) +cxxMethodDecl(returns(asString("int"))) matches int f() { return 1; } </pre></td></tr> @@ -3426,7 +4087,7 @@ methodDecl(returns(asString("int"))) <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)))) +Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) if (true) {} </pre></td></tr> @@ -3445,7 +4106,7 @@ hasConditionVariableStatement(...) <tr><td colspan="4" class="doc" id="hasElse0"><pre>Matches the else-statement of an if statement. Examples matches the if statement - (matcher = ifStmt(hasElse(boolLiteral(equals(true))))) + (matcher = ifStmt(hasElse(cxxBoolLiteral(equals(true))))) if (false) false; else true; </pre></td></tr> @@ -3454,7 +4115,7 @@ Examples matches the if statement <tr><td colspan="4" class="doc" id="hasThen0"><pre>Matches the then-statement of an if statement. Examples matches the if statement - (matcher = ifStmt(hasThen(boolLiteral(equals(true))))) + (matcher = ifStmt(hasThen(cxxBoolLiteral(equals(true))))) if (false) true; else false; </pre></td></tr> @@ -3540,7 +4201,7 @@ matched by a given matcher. Given struct X { int m; }; void f(X x) { x.m; m; } -memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X"))))))) +memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X"))))))) matches "x.m" and "m" with hasObjectExpression(...) matching "x" and the implicit object expression of "m" which has type X*. @@ -3612,7 +4273,7 @@ Given struct A { struct B { struct C {}; }; }; A::B::C c; nestedNameSpecifierLoc(specifiesTypeLoc(loc(type( - hasDeclaration(recordDecl(hasName("A"))))))) + hasDeclaration(cxxRecordDecl(hasName("A"))))))) matches "A::" </pre></td></tr> @@ -3647,11 +4308,35 @@ given QualType matcher without qualifiers. Given struct A { struct B { struct C {}; }; }; A::B::C c; -nestedNameSpecifier(specifiesType(hasDeclaration(recordDecl(hasName("A"))))) +nestedNameSpecifier(specifiesType( + hasDeclaration(cxxRecordDecl(hasName("A"))) +)) matches "A::" </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('hasArgument2')"><a name="hasArgument2Anchor">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="hasArgument2"><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_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('hasReceiverType0')"><a name="hasReceiverType0Anchor">hasReceiverType</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="hasReceiverType0"><pre>Matches on the receiver of an ObjectiveC Message expression. + +Example +matcher = objCMessageExpr(hasRecieverType(asString("UIWebView *"))); +matches the [webView ...] message invocation. + NSString *webViewJavaScript = ... + UIWebView *webView = ... + [webView stringByEvaluatingJavaScriptFromString:webViewJavascript]; +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ParenType.html">ParenType</a>></td><td class="name" onclick="toggle('innerType0')"><a name="innerType0Anchor">innerType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr> <tr><td colspan="4" class="doc" id="innerType0"><pre>Matches ParenType nodes where the inner type is a specific type. @@ -3743,7 +4428,8 @@ Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallEx matches the specified matcher. Example matches y->x() - (matcher = callExpr(on(hasType(pointsTo(recordDecl(hasName("Y"))))))) + (matcher = cxxMemberCallExpr(on(hasType(pointsTo + cxxRecordDecl(hasName("Y"))))))) class Y { public: void x(); }; void z() { Y *y; y->x(); } </pre></td></tr> @@ -3759,7 +4445,7 @@ Example matches y->x() type matches the specified matcher. Example matches X &x and const X &y - (matcher = varDecl(hasType(references(recordDecl(hasName("X")))))) + (matcher = varDecl(hasType(references(cxxRecordDecl(hasName("X")))))) class X { void a(X b) { X &x = b; @@ -4004,7 +4690,8 @@ Generates results for each match. For example, in: class A { class B {}; class C {}; }; The matcher: - recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("m"))) + cxxRecordDecl(hasName("::A"), + findAll(cxxRecordDecl(isDefinition()).bind("m"))) will generate results for A, B and C. Usable as: Any Matcher @@ -4046,7 +4733,8 @@ unaryExprOrTypeTraitExpr(hasArgumentOfType(asString("int")) <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 = hasUnaryOperand(boolLiteral(equals(true)))) +Example matches true (matcher = hasUnaryOperand( + cxxBoolLiteral(equals(true)))) !true </pre></td></tr> @@ -4101,12 +4789,12 @@ 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." +declaration "X x;", cxxRecordDecl(hasName("X")) matches the declaration of +X, while varDecl(hasType(cxxRecordDecl(hasName("X")))) matches the +declaration of x. -Example matches x (matcher = expr(hasType(recordDecl(hasName("X"))))) - and z (matcher = varDecl(hasType(recordDecl(hasName("X"))))) +Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X"))))) + and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X"))))) class X {}; void y(X &x) { x; X z; } @@ -4118,8 +4806,8 @@ Usable as: Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.h <tr><td colspan="4" class="doc" id="hasType1"><pre>Matches if the expression's or declaration's type matches a type matcher. -Example matches x (matcher = expr(hasType(recordDecl(hasName("X"))))) - and z (matcher = varDecl(hasType(recordDecl(hasName("X"))))) +Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X"))))) + and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X"))))) class X {}; void y(X &x) { x; X z; } </pre></td></tr> @@ -4166,7 +4854,7 @@ with compoundStmt() <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)))) +Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) if (true) {} </pre></td></tr> diff --git a/docs/LibASTMatchersTutorial.rst b/docs/LibASTMatchersTutorial.rst index fe36511..603b2fa 100644 --- a/docs/LibASTMatchersTutorial.rst +++ b/docs/LibASTMatchersTutorial.rst @@ -108,7 +108,6 @@ CMakeLists.txt should have the following contents: :: set(LLVM_LINK_COMPONENTS support) - set(LLVM_USED_LIBS clangTooling clangBasic clangAST) add_clang_executable(loop-convert LoopConvert.cpp diff --git a/docs/MemorySanitizer.rst b/docs/MemorySanitizer.rst index 007e086..62cacce 100644 --- a/docs/MemorySanitizer.rst +++ b/docs/MemorySanitizer.rst @@ -48,10 +48,7 @@ to disable inlining (just use ``-O1``) and tail call elimination % clang -fsanitize=memory -fno-omit-frame-pointer -g -O2 umr.cc If a bug is detected, the program will print an error message to -stderr and exit with a non-zero exit code. Currently, MemorySanitizer -does not symbolize its output by default, so you may need to use a -separate script to symbolize the result offline (this will be fixed in -future). +stderr and exit with a non-zero exit code. .. code-block:: console @@ -60,7 +57,9 @@ future). #0 0x7f45944b418a in main umr.cc:6 #1 0x7f45938b676c in __libc_start_main libc-start.c:226 -By default, MemorySanitizer exits on the first detected error. +By default, MemorySanitizer exits on the first detected error. If you +find the error report hard to understand, try enabling +:ref:`origin tracking <msan-origins>`. ``__has_feature(memory_sanitizer)`` ------------------------------------ @@ -80,14 +79,11 @@ whether MemorySanitizer is enabled. :ref:`\_\_has\_feature ``__attribute__((no_sanitize_memory))`` ----------------------------------------------- -Some code should not be checked by MemorySanitizer. -One may use the function attribute -:ref:`no_sanitize_memory <langext-memory_sanitizer>` -to disable uninitialized checks in a particular function. -MemorySanitizer may still instrument such functions to avoid false positives. -This attribute may not be -supported by other compilers, so we suggest to use it together with -``__has_feature(memory_sanitizer)``. +Some code should not be checked by MemorySanitizer. One may use the function +attribute `no_sanitize_memory` to disable uninitialized checks in a particular +function. MemorySanitizer may still instrument such functions to avoid false +positives. This attribute may not be supported by other compilers, so we +suggest to use it together with ``__has_feature(memory_sanitizer)``. Blacklist --------- @@ -105,10 +101,12 @@ MemorySanitizer uses an external symbolizer to print files and line numbers in reports. Make sure that ``llvm-symbolizer`` binary is in ``PATH``, or set environment variable ``MSAN_SYMBOLIZER_PATH`` to point to it. +.. _msan-origins: + Origin Tracking =============== -MemorySanitizer can track origins of unitialized values, similar to +MemorySanitizer can track origins of uninitialized values, similar to Valgrind's --track-origins option. This feature is enabled by ``-fsanitize-memory-track-origins=2`` (or simply ``-fsanitize-memory-track-origins``) Clang option. With the code from @@ -146,14 +144,29 @@ By default, MemorySanitizer collects both allocation points and all intermediate stores the uninitialized value went through. Origin tracking has proved to be very useful for debugging MemorySanitizer reports. It slows down program execution by a factor of 1.5x-2x on top -of the usual MemorySanitizer slowdown. +of the usual MemorySanitizer slowdown and increases memory overhead. -Clang option ``-fsanitize-memory-track-origins=1`` enabled a slightly +Clang option ``-fsanitize-memory-track-origins=1`` enables a slightly faster mode when MemorySanitizer collects only allocation points but not intermediate stores. +Use-after-destruction detection +=============================== + +You can enable experimental use-after-destruction detection in MemorySanitizer. +After invocation of the destructor, the object will be considered no longer +readable, and using underlying memory will lead to error reports in runtime. + +This feature is still experimental, in order to enable it at runtime you need +to: + +#. Pass addition Clang option ``-fsanitize-memory-use-after-dtor`` during + compilation. +#. Set environment variable `MSAN_OPTIONS=poison_in_dtor=1` before running + the program. + Handling external code -============================ +====================== MemorySanitizer requires that all program code is instrumented. This also includes any libraries that the program depends on, even libc. @@ -170,9 +183,7 @@ self-built instrumented libc++ (as a replacement for libstdc++). Supported Platforms =================== -MemorySanitizer is supported on - -* Linux x86\_64 (tested on Ubuntu 12.04); +MemorySanitizer is supported on Linux x86\_64/MIPS64/AArch64. Limitations =========== @@ -183,22 +194,19 @@ Limitations address space. This means that tools like ``ulimit`` may not work as usually expected. * Static linking is not supported. -* Non-position-independent executables are not supported. Therefore, the - ``fsanitize=memory`` flag will cause Clang to act as though the ``-fPIE`` - flag had been supplied if compiling without ``-fPIC``, and as though the - ``-pie`` flag had been supplied if linking an executable. -* Depending on the version of Linux kernel, running without ASLR may - be not supported. Note that GDB disables ASLR by default. To debug - instrumented programs, use "set disable-randomization off". +* Older versions of MSan (LLVM 3.7 and older) didn't work with + non-position-independent executables, and could fail on some Linux + kernel versions with disabled ASLR. Refer to documentation for older versions + for more details. Current Status ============== -MemorySanitizer is an experimental tool. It is known to work on large -real-world programs, like Clang/LLVM itself. +MemorySanitizer is known to work on large real-world programs +(like Clang/LLVM itself) that can be recompiled from source, including all +dependent libraries. More Information ================ -`http://code.google.com/p/memory-sanitizer <http://code.google.com/p/memory-sanitizer/>`_ - +`<https://github.com/google/sanitizers/wiki/MemorySanitizer>`_ diff --git a/docs/Modules.rst b/docs/Modules.rst index 1f3d898..0ea3b5b 100644 --- a/docs/Modules.rst +++ b/docs/Modules.rst @@ -222,7 +222,7 @@ Modules are modeled as if each submodule were a separate translation unit, and a This behavior is currently only approximated when building a module with submodules. Entities within a submodule that has already been built are visible when building later submodules in that module. This can lead to fragile modules that depend on the build order used for the submodules of the module, and should not be relied upon. This behavior is subject to change. -As an example, in C, this implies that if two structs are defined in different submodules with the same name, those two types are distinct types (but may be *compatible* types if their definitions match. In C++, two structs defined with the same name in different submodules are the *same* type, and must be equivalent under C++'s One Definition Rule. +As an example, in C, this implies that if two structs are defined in different submodules with the same name, those two types are distinct types (but may be *compatible* types if their definitions match). In C++, two structs defined with the same name in different submodules are the *same* type, and must be equivalent under C++'s One Definition Rule. .. note:: diff --git a/docs/RAVFrontendAction.rst b/docs/RAVFrontendAction.rst index ec5d5d5..c37d3c0 100644 --- a/docs/RAVFrontendAction.rst +++ b/docs/RAVFrontendAction.rst @@ -205,10 +205,10 @@ following CMakeLists.txt to link it: :: - set(LLVM_USED_LIBS clangTooling) - add_clang_executable(find-class-decls FindClassDecls.cpp) + target_link_libraries(find-class-decls clangTooling) + When running this tool over a small code snippet it will output all declarations of a class n::m::C it found: diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index 2941afd..779d45c 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -1,6 +1,6 @@ -======================= -Clang 3.7 Release Notes -======================= +===================================== +Clang 3.8 (In-Progress) Release Notes +===================================== .. contents:: :local: @@ -8,12 +8,17 @@ Clang 3.7 Release Notes Written by the `LLVM Team <http://llvm.org/>`_ +.. warning:: + + These are in-progress notes for the upcoming Clang 3.8 release. You may + prefer the `Clang 3.7 Release Notes + <http://llvm.org/releases/3.7.0/tools/clang/docs/ReleaseNotes.html>`_. Introduction ============ This document contains the release notes for the Clang C/C++/Objective-C -frontend, part of the LLVM Compiler Infrastructure, release 3.7. Here we +frontend, part of the LLVM Compiler Infrastructure, release 3.8. Here we describe the status of Clang in some detail, including major improvements from the previous release and new feature work. For the general LLVM release notes, see `the LLVM @@ -26,7 +31,12 @@ the latest release, please check out the main please see the `Clang Web Site <http://clang.llvm.org>`_ or the `LLVM Web Site <http://llvm.org>`_. -What's New in Clang 3.7? +Note that if you are reading this file from a Subversion checkout or the +main Clang web page, this document applies to the *next* release, not +the current one. To see the release notes for a specific release, please +see the `releases page <http://llvm.org/releases/>`_. + +What's New in Clang 3.8? ======================== Some of the major new features and improvements to Clang are listed @@ -37,223 +47,147 @@ sections with improvements to Clang's support for those languages. Major New Features ------------------ -- Use of the ``__declspec`` language extension for declaration attributes now - requires passing the -fms-extensions or -fborland compiler flag. This language - extension is also enabled when compiling CUDA code, but its use should be - viewed as an implementation detail that is subject to change. - -- On Windows targets, some uses of the ``__try``, ``__except``, and - ``__finally`` language constructs are supported in Clang 3.7. MSVC-compatible - C++ exceptions are not yet supported, however. - -- Clang 3.7 fully supports OpenMP 3.1 and reported to work on many platforms, - including x86, x86-64 and Power. Also, pragma ``omp simd`` from OpenMP 4.0 is - supported as well. See below for details. - -- Clang 3.7 includes an implementation of :doc:`control flow integrity - <ControlFlowIntegrity>`, a security hardening mechanism. - +- Feature1... Improvements to Clang's diagnostics ------------------------------------ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Clang's diagnostics are constantly being improved to catch more issues, explain them more clearly, and provide more accurate source information -about them. The improvements since the 3.6 release include: - -- -Wrange-loop-analysis analyzes the loop variable type and the container type - to determine whether copies are made of the container elements. If possible, - suggest a const reference type to prevent copies, or a non-reference type - to indicate a copy is made. - -- -Wredundant-move warns when a parameter variable is moved on return and the - return type is the same as the variable. Returning the variable directly - will already make a move, so the call is not needed. - -- -Wpessimizing-move warns when a local variable is moved on return and the - return type is the same as the variable. Copy elision cannot take place with - a move, but can take place if the variable is returned directly. - -- -Wmove is a new warning group which has the previous two warnings, - -Wredundant-move and -Wpessimizing-move, as well as previous warning - -Wself-move. In addition, this group is part of -Wmost and -Wall now. +about them. The improvements since the 3.7 release include: -- -Winfinite-recursion, a warning for functions that only call themselves, - is now part of -Wmost and -Wall. - -- -Wobjc-circular-container prevents creation of circular containers, - it covers ``NSMutableArray``, ``NSMutableSet``, ``NSMutableDictionary``, - ``NSMutableOrderedSet`` and all their subclasses. +- ... New Compiler Flags ------------------ -The sized deallocation feature of C++14 is now controlled by the -``-fsized-deallocation`` flag. This feature relies on library support that -isn't yet widely deployed, so the user must supply an extra flag to get the -extra functionality. - - -Objective-C Language Changes in Clang -------------------------------------- - -- ``objc_boxable`` attribute was added. Structs and unions marked with this attribute can be - used with boxed expressions (``@(...)``) to create ``NSValue``. - -Profile Guided Optimization ---------------------------- - -Clang now accepts GCC-compatible flags for profile guided optimization (PGO). -You can now use ``-fprofile-generate=<dir>``, ``-fprofile-use=<dir>``, -``-fno-profile-generate`` and ``-fno-profile-use``. These flags have the -same semantics as their GCC counterparts. However, the generated profile -is still LLVM-specific. PGO profiles generated with Clang cannot be used -by GCC and vice-versa. - -Clang now emits function entry counts in profile-instrumented binaries. -This has improved the computation of weights and frequencies in -profile analysis. - -OpenMP Support --------------- -OpenMP 3.1 is fully supported, but disabled by default. To enable it, please use -the ``-fopenmp=libomp`` command line option. Your feedback (positive or negative) on -using OpenMP-enabled clang would be much appreciated; please share it either on -`cfe-dev <http://lists.llvm.org/mailman/listinfo/cfe-dev>`_ or `openmp-dev -<http://lists.llvm.org/mailman/listinfo/openmp-dev>`_ mailing lists. - -In addition to OpenMP 3.1, several important elements of the 4.0 version of the -standard are supported as well: - -- ``omp simd``, ``omp for simd`` and ``omp parallel for simd`` pragmas -- atomic constructs -- ``proc_bind`` clause of ``omp parallel`` pragma -- ``depend`` clause of ``omp task`` pragma (except for array sections) -- ``omp cancel`` and ``omp cancellation point`` pragmas -- ``omp taskgroup`` pragma +The option .... -Internal API Changes --------------------- - -These are major API changes that have happened since the 3.6 release of -Clang. If upgrading an external codebase that uses Clang as a library, -this section should help get you past the largest hurdles of upgrading. -- Some of the ``PPCallbacks`` interface now deals in ``MacroDefinition`` - objects instead of ``MacroDirective`` objects. This allows preserving - full information on macros imported from modules. +New Pragmas in Clang +----------------------- -- ``clang-c/Index.h`` no longer ``#include``\s ``clang-c/Documentation.h``. - You now need to explicitly ``#include "clang-c/Documentation.h"`` if - you use the libclang documentation API. +Clang now supports the ... -Static Analyzer +Windows Support --------------- -* The generated plists now contain the name of the check that generated it. - -* Configuration options can now be passed to the checkers (not just the static - analyzer core). - -* New check for dereferencing object that the result of a zero-length - allocation. - -* Also check functions in precompiled headers. - -* Properly handle alloca() in some checkers. +Clang's support for building native Windows programs ... -* Various improvements to the retain count checker. +C Language Changes in Clang +--------------------------- -clang-tidy ----------- -Added new checks: +... -* google-global-names-in-headers: flag global namespace pollution in header - files. +C11 Feature Support +^^^^^^^^^^^^^^^^^^^ -* misc-assert-side-effect: detects ``assert()`` conditions with side effects - which can cause different behavior in debug / release builds. +... -* misc-assign-operator-signature: finds declarations of assign operators with - the wrong return and/or argument types. +C++ Language Changes in Clang +----------------------------- -* misc-inaccurate-erase: warns when some elements of a container are not - removed due to using the ``erase()`` algorithm incorrectly. +- ... -* misc-inefficient-algorithm: warns on inefficient use of STL algorithms on - associative containers. +C++11 Feature Support +^^^^^^^^^^^^^^^^^^^^^ -* misc-macro-parentheses: finds macros that can have unexpected behavior due - to missing parentheses. +... -* misc-macro-repeated-side-effects: checks for repeated argument with side - effects in macros. +Objective-C Language Changes in Clang +------------------------------------- -* misc-noexcept-move-constructor: flags user-defined move constructors and - assignment operators not marked with ``noexcept`` or marked with - ``noexcept(expr)`` where ``expr`` evaluates to ``false`` (but is not a - ``false`` literal itself). +... -* misc-static-assert: replaces ``assert()`` with ``static_assert()`` if the - condition is evaluable at compile time. +OpenCL C Language Changes in Clang +---------------------------------- -* readability-container-size-empty: checks whether a call to the ``size()`` - method can be replaced with a call to ``empty()``. +... -* readability-else-after-return: flags conditional statements having the - ``else`` branch, when the ``true`` branch has a ``return`` as the last statement. +Internal API Changes +-------------------- -* readability-redundant-string-cstr: finds unnecessary calls to - ``std::string::c_str()``. +These are major API changes that have happened since the 3.7 release of +Clang. If upgrading an external codebase that uses Clang as a library, +this section should help get you past the largest hurdles of upgrading. -* readability-shrink-to-fit: replaces copy and swap tricks on shrinkable - containers with the ``shrink_to_fit()`` method call. +- ... + +AST Matchers +------------ +The AST matcher functions were renamed to reflect the exact AST node names, +which is a breaking change to AST matching code. The following matchers were +affected: + +======================= ============================ +Previous Matcher Name New Matcher Name +======================= ============================ +recordDecl recordDecl and cxxRecordDecl +ctorInitializer cxxCtorInitializer +constructorDecl cxxConstructorDecl +destructorDecl cxxDestructorDecl +methodDecl cxxMethodDecl +conversionDecl cxxConversionDecl +memberCallExpr cxxMemberCallExpr +constructExpr cxxConstructExpr +unresolvedConstructExpr cxxUnresolvedConstructExpr +thisExpr cxxThisExpr +bindTemporaryExpr cxxBindTemporaryExpr +newExpr cxxNewExpr +deleteExpr cxxDeleteExpr +defaultArgExpr cxxDefaultArgExpr +operatorCallExpr cxxOperatorCallExpr +forRangeStmt cxxForRangeStmt +catchStmt cxxCatchStmt +tryStmt cxxTryStmt +throwExpr cxxThrowExpr +boolLiteral cxxBoolLiteral +nullPtrLiteralExpr cxxNullPtrLiteralExpr +reinterpretCastExpr cxxReinterpretCastExpr +staticCastExpr cxxStaticCastExpr +dynamicCastExpr cxxDynamicCastExpr +constCastExpr cxxConstCastExpr +functionalCastExpr cxxFunctionalCastExpr +temporaryObjectExpr cxxTemporaryObjectExpr +CUDAKernalCallExpr cudaKernelCallExpr +======================= ============================ + +recordDecl() previously matched AST nodes of type CXXRecordDecl, but now +matches AST nodes of type RecordDecl. If a CXXRecordDecl is required, use the +cxxRecordDecl() matcher instead. + +... + +libclang +-------- + +... -* readability-simplify-boolean-expr: looks for boolean expressions involving - boolean constants and simplifies them to use the appropriate boolean - expression directly (``if (x == true) ... -> if (x)``, etc.) +Static Analyzer +--------------- -SystemZ -------- +... -* Clang will now always default to the z10 processor when compiling - without any ``-march=`` option. Previous releases used to automatically - detect the current host CPU when compiling natively. If you wish to - still have clang detect the current host CPU, you now need to use the - ``-march=native`` option. +Core Analysis Improvements +========================== -* Clang now provides the ``<s390intrin.h>`` header file. +- ... -* Clang now supports the transactional-execution facility and - provides associated builtins and the ``<htmintrin.h>`` and - ``<htmxlintrin.h>`` header files. Support is enabled by default - on zEC12 and above, and can additionally be enabled or disabled - via the ``-mhtm`` / ``-mno-htm`` command line options. +New Issues Found +================ -* Clang now supports the vector facility. This includes a - change in the ABI to pass arguments and return values of - vector types in vector registers, as well as a change in - the default alignment of vector types. Support is enabled - by default on z13 and above, and can additionally be enabled - or disabled via the ``-mvx`` / ``-mno-vx`` command line options. +- ... -* Clang now supports the System z vector language extension, - providing a "vector" keyword to define vector types, and a - set of builtins defined in the ``<vecintrin.h>`` header file. - This can be enabled via the ``-fzvector`` command line option. - For compatibility with GCC, Clang also supports the - ``-mzvector`` option as an alias. - -* Several cases of ABI incompatibility with GCC have been fixed. +Python Binding Changes +---------------------- +The following methods have been added: -Last release which will run on Windows XP and Windows Vista ------------------------------------------------------------ +- ... -This is expected to the be the last major release of Clang that will support -running on Windows XP and Windows Vista. For the next major release the -minimum Windows version requirement will be Windows 7. +Significant Known Problems +========================== Additional Information ====================== diff --git a/docs/SanitizerCoverage.rst b/docs/SanitizerCoverage.rst index 65af6ff..e759b35 100644 --- a/docs/SanitizerCoverage.rst +++ b/docs/SanitizerCoverage.rst @@ -249,6 +249,41 @@ These counters may also be used for in-process coverage-guided fuzzers. See uintptr_t __sanitizer_update_counter_bitset_and_clear_counters(uint8_t *bitset); +Tracing basic blocks +==================== +An *experimental* feature to support basic block (or edge) tracing. +With ``-fsanitize-coverage=trace-bb`` the compiler will insert +``__sanitizer_cov_trace_basic_block(s32 *id)`` before every function, basic block, or edge +(depending on the value of ``-fsanitize-coverage=[func,bb,edge]``). + +Tracing data flow +================= + +An *experimental* feature to support data-flow-guided fuzzing. +With ``-fsanitize-coverage=trace-cmp`` the compiler will insert extra instrumentation +around comparison instructions and switch statements. +The fuzzer will need to define the following functions, +they will be called by the instrumented code. + +.. code-block:: c++ + + // Called before a comparison instruction. + // SizeAndType is a packed value containing + // - [63:32] the Size of the operands of comparison in bits + // - [31:0] the Type of comparison (one of ICMP_EQ, ... ICMP_SLE) + // Arg1 and Arg2 are arguments of the comparison. + void __sanitizer_cov_trace_cmp(uint64_t SizeAndType, uint64_t Arg1, uint64_t Arg2); + + // Called before a switch statement. + // Val is the switch operand. + // Cases[0] is the number of case constants. + // Cases[1] is the size of Val in bits. + // Cases[2:] are the case constants. + void __sanitizer_cov_trace_switch(uint64_t Val, uint64_t *Cases); + +This interface is a subject to change. +The current implementation is not thread-safe and thus can be safely used only for single-threaded targets. + Output directory ================ diff --git a/docs/ThreadSanitizer.rst b/docs/ThreadSanitizer.rst index d1aeaa8..0b9b163 100644 --- a/docs/ThreadSanitizer.rst +++ b/docs/ThreadSanitizer.rst @@ -86,25 +86,22 @@ this purpose. ``__attribute__((no_sanitize_thread))`` ----------------------------------------------- -Some code should not be instrumented by ThreadSanitizer. -One may use the function attribute -:ref:`no_sanitize_thread <langext-thread_sanitizer>` -to disable instrumentation of plain (non-atomic) loads/stores in a particular function. -ThreadSanitizer still instruments such functions to avoid false positives and -provide meaningful stack traces. -This attribute may not be -supported by other compilers, so we suggest to use it together with -``__has_feature(thread_sanitizer)``. +Some code should not be instrumented by ThreadSanitizer. One may use the +function attribute `no_sanitize_thread` to disable instrumentation of plain +(non-atomic) loads/stores in a particular function. ThreadSanitizer still +instruments such functions to avoid false positives and provide meaningful stack +traces. This attribute may not be supported by other compilers, so we suggest +to use it together with ``__has_feature(thread_sanitizer)``. Blacklist --------- ThreadSanitizer supports ``src`` and ``fun`` entity types in -:doc:`SanitizerSpecialCaseList`, that can be used to suppress data race reports in -the specified source files or functions. Unlike functions marked with -:ref:`no_sanitize_thread <langext-thread_sanitizer>` attribute, -blacklisted functions are not instrumented at all. This can lead to false positives -due to missed synchronization via atomic operations and missed stack frames in reports. +:doc:`SanitizerSpecialCaseList`, that can be used to suppress data race reports +in the specified source files or functions. Unlike functions marked with +`no_sanitize_thread` attribute, blacklisted functions are not instrumented at +all. This can lead to false positives due to missed synchronization via atomic +operations and missed stack frames in reports. Limitations ----------- @@ -134,5 +131,4 @@ especially in the form of minimized standalone tests is more than welcome. More Information ---------------- -`http://code.google.com/p/thread-sanitizer <http://code.google.com/p/thread-sanitizer/>`_. - +`<https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual>`_ diff --git a/docs/UndefinedBehaviorSanitizer.rst b/docs/UndefinedBehaviorSanitizer.rst new file mode 100644 index 0000000..37ff16d --- /dev/null +++ b/docs/UndefinedBehaviorSanitizer.rst @@ -0,0 +1,204 @@ +========================== +UndefinedBehaviorSanitizer +========================== + +.. contents:: + :local: + +Introduction +============ + +UndefinedBehaviorSanitizer (UBSan) is a fast undefined behavior detector. +UBSan modifies the program at compile-time to catch various kinds of undefined +behavior during program execution, for example: + +* Using misaligned or null pointer +* Signed integer overflow +* Conversion to, from, or between floating-point types which would + overflow the destination + +See the full list of available :ref:`checks <ubsan-checks>` below. + +UBSan has an optional run-time library which provides better error reporting. +The checks have small runtime cost and no impact on address space layout or ABI. + +How to build +============ + +Build LLVM/Clang with `CMake <http://llvm.org/docs/CMake.html>`_. + +Usage +===== + +Use ``clang++`` to compile and link your program with ``-fsanitize=undefined`` +flag. Make sure to use ``clang++`` (not ``ld``) as a linker, so that your +executable is linked with proper UBSan runtime libraries. You can use ``clang`` +instead of ``clang++`` if you're compiling/linking C code. + +.. code-block:: console + + % cat test.cc + int main(int argc, char **argv) { + int k = 0x7fffffff; + k += argc; + return 0; + } + % clang++ -fsanitize=undefined test.cc + % ./a.out + test.cc:3:5: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int' + +You can enable only a subset of :ref:`checks <ubsan-checks>` offered by UBSan, +and define the desired behavior for each kind of check: + +* print a verbose error report and continue execution (default); +* print a verbose error report and exit the program; +* execute a trap instruction (doesn't require UBSan run-time support). + +For example if you compile/link your program as: + +.. code-block:: console + + % clang++ -fsanitize=signed-integer-overflow,null,alignment -fno-sanitize-recover=null -fsanitize-trap=alignment + +the program will continue execution after signed integer overflows, exit after +the first invalid use of a null pointer, and trap after the first use of misaligned +pointer. + +.. _ubsan-checks: + +Availablle checks +================= + +Available checks are: + + - ``-fsanitize=alignment``: Use of a misaligned pointer or creation + of a misaligned reference. + - ``-fsanitize=bool``: Load of a ``bool`` value which is neither + ``true`` nor ``false``. + - ``-fsanitize=bounds``: Out of bounds array indexing, in cases + where the array bound can be statically determined. + - ``-fsanitize=enum``: Load of a value of an enumerated type which + is not in the range of representable values for that enumerated + type. + - ``-fsanitize=float-cast-overflow``: Conversion to, from, or + between floating-point types which would overflow the + destination. + - ``-fsanitize=float-divide-by-zero``: Floating point division by + zero. + - ``-fsanitize=function``: Indirect call of a function through a + function pointer of the wrong type (Linux, C++ and x86/x86_64 only). + - ``-fsanitize=integer-divide-by-zero``: Integer division by zero. + - ``-fsanitize=nonnull-attribute``: Passing null pointer as a function + parameter which is declared to never be null. + - ``-fsanitize=null``: Use of a null pointer or creation of a null + reference. + - ``-fsanitize=object-size``: 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 + ``__builtin_object_size``, and consequently may be able to detect + more problems at higher optimization levels. + - ``-fsanitize=return``: In C++, reaching the end of a + value-returning function without returning a value. + - ``-fsanitize=returns-nonnull-attribute``: Returning null pointer + from a function which is declared to never return null. + - ``-fsanitize=shift``: 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++. You can use ``-fsanitize=shift-base`` or + ``-fsanitize=shift-exponent`` to check only left-hand side or + right-hand side of shift operation, respectively. + - ``-fsanitize=signed-integer-overflow``: Signed integer overflow, + including all the checks added by ``-ftrapv``, and checking for + overflow in signed division (``INT_MIN / -1``). + - ``-fsanitize=unreachable``: If control flow reaches + ``__builtin_unreachable``. + - ``-fsanitize=unsigned-integer-overflow``: Unsigned integer + overflows. + - ``-fsanitize=vla-bound``: A variable-length array whose bound + does not evaluate to a positive value. + - ``-fsanitize=vptr``: 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 ``-fno-rtti``. Link must + be performed by ``clang++``, not ``clang``, to make sure C++-specific + parts of the runtime library and C++ standard libraries are present. + +You can also use the following check groups: + - ``-fsanitize=undefined``: All of the checks listed above other than + ``unsigned-integer-overflow``. + - ``-fsanitize=undefined-trap``: Deprecated alias of + ``-fsanitize=undefined``. + - ``-fsanitize=integer``: Checks for undefined or suspicious integer + behavior (e.g. unsigned integer overflow). + +Stack traces and report symbolization +===================================== +If you want UBSan to print symbolized stack trace for each error report, you +will need to: + +#. Compile with ``-g`` and ``-fno-omit-frame-pointer`` to get proper debug + information in your binary. +#. Run your program with environment variable + ``UBSAN_OPTIONS=print_stacktrace=1``. +#. Make sure ``llvm-symbolizer`` binary is in ``PATH``. + +Issue Suppression +================= + +UndefinedBehaviorSanitizer is not expected to produce false positives. +If you see one, look again; most likely it is a true positive! + +Disabling Instrumentation with ``__attribute__((no_sanitize("undefined")))`` +---------------------------------------------------------------------------- + +You disable UBSan checks for particular functions with +``__attribute__((no_sanitize("undefined")))``. You can use all values of +``-fsanitize=`` flag in this attribute, e.g. if your function deliberately +contains possible signed integer overflow, you can use +``__attribute__((no_sanitize("signed-integer-overflow")))``. + +This attribute may not be +supported by other compilers, so consider using it together with +``#if defined(__clang__)``. + +Suppressing Errors in Recompiled Code (Blacklist) +------------------------------------------------- + +UndefinedBehaviorSanitizer supports ``src`` and ``fun`` entity types in +:doc:`SanitizerSpecialCaseList`, that can be used to suppress error reports +in the specified source files or functions. + +Supported Platforms +=================== + +UndefinedBehaviorSanitizer is supported on the following OS: + +* Android +* Linux +* FreeBSD +* OS X 10.6 onwards + +and for the following architectures: + +* i386/x86\_64 +* ARM +* AArch64 +* PowerPC64 +* MIPS/MIPS64 + +Current Status +============== + +UndefinedBehaviorSanitizer is available on selected platforms starting from LLVM +3.3. The test suite is integrated into the CMake build and can be run with +``check-ubsan`` command. + +More Information +================ + +* From LLVM project blog: + `What Every C Programmer Should Know About Undefined Behavior + <http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html>`_ +* From John Regehr's *Embedded in Academia* blog: + `A Guide to Undefined Behavior in C and C++ + <http://blog.regehr.org/archives/213>`_ diff --git a/docs/UsersManual.rst b/docs/UsersManual.rst index 78d8dcc..5fe1e37 100644 --- a/docs/UsersManual.rst +++ b/docs/UsersManual.rst @@ -148,8 +148,8 @@ Formatting of Diagnostics Clang aims to produce beautiful diagnostics by default, particularly for new users that first come to Clang. However, different people have -different preferences, and sometimes Clang is driven by another program -that wants to parse simple and consistent output, not a person. For +different preferences, and sometimes Clang is driven not by a human, +but by a program that wants consistent and easily parsable output. For these cases, Clang provides a wide range of options to control the exact output format of the diagnostics that it generates. @@ -952,26 +952,18 @@ are listed below. ``-fsanitize=address``: :doc:`AddressSanitizer`, a memory error detector. - - ``-fsanitize=integer``: Enables checks for undefined or - suspicious integer behavior. - .. _opt_fsanitize_thread: ``-fsanitize=thread``: :doc:`ThreadSanitizer`, a data race detector. - .. _opt_fsanitize_memory: ``-fsanitize=memory``: :doc:`MemorySanitizer`, - an *experimental* detector of uninitialized reads. Not ready for - widespread use. + a detector of uninitialized reads. Requires instrumentation of all + program code. - .. _opt_fsanitize_undefined: - ``-fsanitize=undefined``: Fast and compatible undefined behavior - checker. Enables the undefined behavior checks that have small - runtime cost and no impact on address space layout or ABI. This - includes all of the checks listed below other than - ``unsigned-integer-overflow``. - - - ``-fsanitize=undefined-trap``: This is a deprecated alias for - ``-fsanitize=undefined``. + ``-fsanitize=undefined``: :doc:`UndefinedBehaviorSanitizer`, + a fast and compatible undefined behavior checker. - ``-fsanitize=dataflow``: :doc:`DataFlowSanitizer`, a general data flow analysis. @@ -980,103 +972,17 @@ are listed below. - ``-fsanitize=safe-stack``: :doc:`safe stack <SafeStack>` protection against stack-based memory corruption errors. - The following more fine-grained checks are also available: - - - ``-fsanitize=alignment``: Use of a misaligned pointer or creation - of a misaligned reference. - - ``-fsanitize=bool``: Load of a ``bool`` value which is neither - ``true`` nor ``false``. - - ``-fsanitize=bounds``: Out of bounds array indexing, in cases - where the array bound can be statically determined. - - ``-fsanitize=cfi-cast-strict``: Enables :ref:`strict cast checks - <cfi-strictness>`. - - ``-fsanitize=cfi-derived-cast``: Base-to-derived cast to the wrong - dynamic type. Requires ``-flto``. - - ``-fsanitize=cfi-unrelated-cast``: Cast from ``void*`` or another - unrelated type to the wrong dynamic type. Requires ``-flto``. - - ``-fsanitize=cfi-nvcall``: Non-virtual call via an object whose vptr is of - the wrong dynamic type. Requires ``-flto``. - - ``-fsanitize=cfi-vcall``: Virtual call via an object whose vptr is of the - wrong dynamic type. Requires ``-flto``. - - ``-fsanitize=enum``: Load of a value of an enumerated type which - is not in the range of representable values for that enumerated - type. - - ``-fsanitize=float-cast-overflow``: Conversion to, from, or - between floating-point types which would overflow the - destination. - - ``-fsanitize=float-divide-by-zero``: Floating point division by - zero. - - ``-fsanitize=function``: Indirect call of a function through a - function pointer of the wrong type (Linux, C++ and x86/x86_64 only). - - ``-fsanitize=integer-divide-by-zero``: Integer division by zero. - - ``-fsanitize=nonnull-attribute``: Passing null pointer as a function - parameter which is declared to never be null. - - ``-fsanitize=null``: Use of a null pointer or creation of a null - reference. - - ``-fsanitize=object-size``: 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 - ``__builtin_object_size``, and consequently may be able to detect - more problems at higher optimization levels. - - ``-fsanitize=return``: In C++, reaching the end of a - value-returning function without returning a value. - - ``-fsanitize=returns-nonnull-attribute``: Returning null pointer - from a function which is declared to never return null. - - ``-fsanitize=shift``: 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++. You can use ``-fsanitize=shift-base`` or - ``-fsanitize=shift-exponent`` to check only left-hand side or - right-hand side of shift operation, respectively. - - ``-fsanitize=signed-integer-overflow``: Signed integer overflow, - including all the checks added by ``-ftrapv``, and checking for - overflow in signed division (``INT_MIN / -1``). - - ``-fsanitize=unreachable``: If control flow reaches - ``__builtin_unreachable``. - - ``-fsanitize=unsigned-integer-overflow``: Unsigned integer - overflows. - - ``-fsanitize=vla-bound``: A variable-length array whose bound - does not evaluate to a positive value. - - ``-fsanitize=vptr``: 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 ``-fno-rtti``. - - You can turn off or modify checks for certain source files, functions - or even variables by providing a special file: - - - ``-fsanitize-blacklist=/path/to/blacklist/file``: disable or modify - sanitizer checks for objects listed in the file. See - :doc:`SanitizerSpecialCaseList` for file format description. - - ``-fno-sanitize-blacklist``: don't use blacklist file, if it was - specified earlier in the command line. - - Extra features of MemorySanitizer (require explicit - ``-fsanitize=memory``): - - - ``-fsanitize-memory-track-origins[=level]``: Enables origin tracking in - MemorySanitizer. Adds a second section to MemorySanitizer - reports pointing to the heap or stack allocation the - uninitialized bits came from. Slows down execution by additional - 1.5x-2x. - - Possible values for level are 0 (off), 1, 2 (default). Level 2 - adds more sections to MemorySanitizer reports describing the - order of memory stores the uninitialized value went - through. This mode may use extra memory in programs that copy - uninitialized memory a lot. + There are more fine-grained checks available: see + the :ref:`list <ubsan-checks>` of specific kinds of + undefined behavior that can be detected and the :ref:`list <cfi-schemes>` + of control flow integrity schemes. The ``-fsanitize=`` argument must also be provided when linking, in - order to link to the appropriate runtime library. When using - ``-fsanitize=vptr`` (or a group that includes it, such as - ``-fsanitize=undefined``) with a C++ program, the link must be - performed by ``clang++``, not ``clang``, in order to link against the - C++-specific parts of the runtime library. + order to link to the appropriate runtime library. It is not possible to combine more than one of the ``-fsanitize=address``, ``-fsanitize=thread``, and ``-fsanitize=memory`` checkers in the same - program. The ``-fsanitize=undefined`` checks can only be combined with - ``-fsanitize=address``. + program. **-f[no-]sanitize-recover=check1,check2,...** @@ -1084,10 +990,12 @@ are listed below. If the check is fatal, program will halt after the first error of this kind is detected and error report is printed. - By default, non-fatal checks are those enabled by UndefinedBehaviorSanitizer, + By default, non-fatal checks are those enabled by + :doc:`UndefinedBehaviorSanitizer`, except for ``-fsanitize=return`` and ``-fsanitize=unreachable``. Some - sanitizers (e.g. :doc:`AddressSanitizer`) may not support recovery, - and always crash the program after the issue is detected. + sanitizers may not support recovery (or not support it by default + e.g. :doc:`AddressSanitizer`), and always crash the program after the issue + is detected. Note that the ``-fsanitize-trap`` flag has precedence over this flag. This means that if a check has been configured to trap elsewhere on the @@ -1107,14 +1015,24 @@ are listed below. be used (for instance, when building libc or a kernel module), or where the binary size increase caused by the sanitizer runtime is a concern. - This flag is only compatible with ``local-bounds``, - ``unsigned-integer-overflow``, sanitizers in the ``cfi`` group and - sanitizers in the ``undefined`` group other than ``vptr``. If this flag + This flag is only compatible with :doc:`control flow integrity + <ControlFlowIntegrity>` schemes and :doc:`UndefinedBehaviorSanitizer` + checks other than ``vptr``. If this flag is supplied together with ``-fsanitize=undefined``, the ``vptr`` sanitizer will be implicitly disabled. This flag is enabled by default for sanitizers in the ``cfi`` group. +.. option:: -fsanitize-blacklist=/path/to/blacklist/file + + Disable or modify sanitizer checks for objects (source files, functions, + variables, types) listed in the file. See + :doc:`SanitizerSpecialCaseList` for file format description. + +.. option:: -fno-sanitize-blacklist + + Don't use blacklist file, if it was specified earlier in the command line. + **-f[no-]sanitize-coverage=[type,features,...]** Enable simple code coverage in addition to certain sanitizers. @@ -1124,6 +1042,12 @@ are listed below. Deprecated alias for ``-fsanitize-trap=undefined``. +.. option:: -fsanitize-cfi-cross-dso + + Enable cross-DSO control flow integrity checks. This flag modifies + the behavior of sanitizers in the ``cfi`` group to allow checking + of cross-DSO virtual and indirect calls. + .. option:: -fno-assume-sane-operator-new Don't assume that the C++'s new operator is sane. @@ -1157,6 +1081,13 @@ are listed below. efficient model can be used. The TLS model can be overridden per variable using the ``tls_model`` attribute. +.. option:: -femulated-tls + + Select emulated TLS model, which overrides all -ftls-model choices. + + In emulated TLS mode, all access to TLS variables are converted to + calls to __emutls_get_address in the runtime library. + .. option:: -mhwdiv=[values] Select the ARM modes (arm or thumb) that support hardware division @@ -1183,7 +1114,7 @@ are listed below. This option restricts the generated code to use general registers only. This only applies to the AArch64 architecture. -**-f[no-]max-unknown-pointer-align=[number]** +**-f[no-]max-type-align=[number]** Instruct the code generator to not enforce a higher alignment than the given number (of bytes) when accessing memory via an opaque pointer or reference. This cap is ignored when directly accessing a variable or when the pointee @@ -1211,7 +1142,7 @@ are listed below. void initialize_vector(__aligned_v16si *v) { // The compiler may assume that āvā is 64-byte aligned, regardless of the - // value of -fmax-unknown-pointer-align. + // value of -fmax-type-align. } @@ -1338,15 +1269,18 @@ read by the backend. LLVM supports three different sample profile formats: 1. ASCII text. This is the easiest one to generate. The file is divided into sections, which correspond to each of the functions with profile - information. The format is described below. + information. The format is described below. It can also be generated from + the binary or gcov formats using the ``llvm-profdata`` tool. 2. Binary encoding. This uses a more efficient encoding that yields smaller - profile files, which may be useful when generating large profiles. It can be - generated from the text format using the ``llvm-profdata`` tool. + profile files. This is the format generated by the ``create_llvm_prof`` tool + in http://github.com/google/autofdo. 3. GCC encoding. This is based on the gcov format, which is accepted by GCC. It - is only interesting in environments where GCC and Clang co-exist. Similarly - to the binary encoding, it can be generated using the ``llvm-profdata`` tool. + is only interesting in environments where GCC and Clang co-exist. This + encoding is only generated by the ``create_gcov`` tool in + http://github.com/google/autofdo. It can be read by LLVM and + ``llvm-profdata``, but it cannot be generated by either. If you are using Linux Perf to generate sampling profiles, you can use the conversion tool ``create_llvm_prof`` described in the previous section. @@ -1360,19 +1294,32 @@ Sample Profile Text Format This section describes the ASCII text format for sampling profiles. It is, arguably, the easiest one to generate. If you are interested in generating any of the other two, consult the ``ProfileData`` library in in LLVM's source tree -(specifically, ``llvm/lib/ProfileData/SampleProfWriter.cpp``). +(specifically, ``include/llvm/ProfileData/SampleProfReader.h``). .. code-block:: console function1:total_samples:total_head_samples - offset1[.discriminator]: number_of_samples [fn1:num fn2:num ... ] - offset2[.discriminator]: number_of_samples [fn3:num fn4:num ... ] - ... - offsetN[.discriminator]: number_of_samples [fn5:num fn6:num ... ] + offset1[.discriminator]: number_of_samples [fn1:num fn2:num ... ] + offset2[.discriminator]: number_of_samples [fn3:num fn4:num ... ] + ... + offsetN[.discriminator]: number_of_samples [fn5:num fn6:num ... ] + offsetA[.discriminator]: fnA:num_of_total_samples + offsetA1[.discriminator]: number_of_samples [fn7:num fn8:num ... ] + offsetA1[.discriminator]: number_of_samples [fn9:num fn10:num ... ] + offsetB[.discriminator]: fnB:num_of_total_samples + offsetB1[.discriminator]: number_of_samples [fn11:num fn12:num ... ] + +This is a nested tree in which the identation represents the nesting level +of the inline stack. There are no blank lines in the file. And the spacing +within a single line is fixed. Additional spaces will result in an error +while reading the file. + +Any line starting with the '#' character is completely ignored. -The file may contain blank lines between sections and within a -section. However, the spacing within a single line is fixed. Additional -spaces will result in an error while reading the file. +Inlined calls are represented with indentation. The Inline stack is a +stack of source locations in which the top of the stack represents the +leaf function, and the bottom of the stack represents the actual +symbol to which the instruction belongs. Function names must be mangled in order for the profile loader to match them in the current translation unit. The two numbers in the @@ -1381,6 +1328,14 @@ function (first number), and the total number of samples accumulated in the prologue of the function (second number). This head sample count provides an indicator of how frequently the function is invoked. +There are two types of lines in the function body. + +- Sampled line represents the profile information of a source location. + ``offsetN[.discriminator]: number_of_samples [fn5:num fn6:num ... ]`` + +- Callsite line represents the profile information of an inlined callsite. + ``offsetA[.discriminator]: fnA:num_of_total_samples`` + Each sampled line may contain several items. Some are optional (marked below): @@ -1434,6 +1389,24 @@ d. [OPTIONAL] Potential call targets and samples. If present, this instruction that calls one of ``foo()``, ``bar()`` and ``baz()``, with ``baz()`` being the relatively more frequently called target. +As an example, consider a program with the call chain ``main -> foo -> bar``. +When built with optimizations enabled, the compiler may inline the +calls to ``bar`` and ``foo`` inside ``main``. The generated profile +could then be something like this: + +.. code-block:: console + + main:35504:0 + 1: _Z3foov:35504 + 2: _Z32bari:31977 + 1.1: 31977 + 2: 0 + +This profile indicates that there were a total of 35,504 samples +collected in main. All of those were at line 1 (the call to ``foo``). +Of those, 31,977 were spent inside the body of ``bar``. The last line +of the profile (``2: 0``) corresponds to line 2 inside ``main``. No +samples were collected there. Profiling with Instrumentation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1527,9 +1500,25 @@ with respect to profile creation and use. profile file, it reads from that file. If ``pathname`` is a directory name, it reads from ``pathname/default.profdata``. +Disabling Instrumentation +^^^^^^^^^^^^^^^^^^^^^^^^^ + +In certain situations, it may be useful to disable profile generation or use +for specific files in a build, without affecting the main compilation flags +used for the other files in the project. + +In these cases, you can use the flag ``-fno-profile-instr-generate`` (or +``-fno-profile-generate``) to disable profile generation, and +``-fno-profile-instr-use`` (or ``-fno-profile-use``) to disable profile use. + +Note that these flags should appear after the corresponding profile +flags to have an effect. + +Controlling Debug Information +----------------------------- Controlling Size of Debug Information -------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Debug info kind generated by Clang can be set by one of the flags listed below. If multiple flags are present, the last one is used. @@ -1573,6 +1562,21 @@ below. If multiple flags are present, the last one is used. Generate complete debug info. +Controlling Debugger "Tuning" +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +While Clang generally emits standard DWARF debug info (http://dwarfstd.org), +different debuggers may know how to take advantage of different specific DWARF +features. You can "tune" the debug info for one of several different debuggers. + +.. option:: -ggdb, -glldb, -gsce + + Tune the debug info for the ``gdb``, ``lldb``, or Sony Computer Entertainment + debugger, respectively. Each of these options implies **-g**. (Therefore, if + you want both **-gline-tables-only** and debugger tuning, the tuning option + must come first.) + + Comment Parsing Options ----------------------- @@ -1832,6 +1836,32 @@ Objective-C Language Features Objective-C++ Language Features =============================== +.. _openmp: + +OpenMP Features +=============== + +Clang supports all OpenMP 3.1 directives and clauses. In addition, some +features of OpenMP 4.0 are supported. For example, ``#pragma omp simd``, +``#pragma omp for simd``, ``#pragma omp parallel for simd`` directives, extended +set of atomic constructs, ``proc_bind`` clause for all parallel-based +directives, ``depend`` clause for ``#pragma omp task`` directive (except for +array sections), ``#pragma omp cancel`` and ``#pragma omp cancellation point`` +directives, and ``#pragma omp taskgroup`` directive. + +Use :option:`-fopenmp` to enable OpenMP. Support for OpenMP can be disabled with +:option:`-fno-openmp`. + +Controlling implementation limits +--------------------------------- + +.. option:: -fopenmp-use-tls + + Controls code generation for OpenMP threadprivate variables. In presence of + this option all threadprivate variables are generated the same way as thread + local variables, using TLS support. If :option:`-fno-openmp-use-tls` + is provided or target does not support TLS, code generation for threadprivate + variables relies on OpenMP runtime library. .. _target_features: @@ -2019,11 +2049,11 @@ Execute ``clang-cl /?`` to see a list of supported options: /FI <value> Include file before parsing /Fi<file> Set preprocess output file name (with /P) /Fo<file or directory> Set output object file, or directory (ends in / or \) (with /c) - /fp:except- - /fp:except - /fp:fast - /fp:precise - /fp:strict + /fp:except- + /fp:except + /fp:fast + /fp:precise + /fp:strict /GA Assume thread-local variables are defined in the executable /GF- Disable string pooling /GR- Disable emission of RTTI data @@ -2049,10 +2079,9 @@ Execute ``clang-cl /?`` to see a list of supported options: /Oi Enable use of builtin functions /Os Optimize for size /Ot Optimize for speed - /Ox Maximum optimization /Oy- Disable frame pointer omission /Oy Enable frame pointer omission - /O<n> Optimization level + /O<value> Optimization level /o <file or directory> Set output file or directory (ends in / or \) /P Preprocess to file /Qvec- Disable the loop vectorization passes @@ -2075,11 +2104,12 @@ Execute ``clang-cl /?`` to see a list of supported options: /W1 Enable -Wall /W2 Enable -Wall /W3 Enable -Wall - /W4 Enable -Wall + /W4 Enable -Wall and -Wextra /Wall Enable -Wall /WX- Do not treat warnings as errors /WX Treat warnings as errors /w Disable all warnings + /Z7 Enable CodeView debug information in object files /Zc:sizedDealloc- Disable C++14 sized global deallocation functions /Zc:sizedDealloc Enable C++14 sized global deallocation functions /Zc:strictStrings Treat string literals as const @@ -2087,7 +2117,8 @@ Execute ``clang-cl /?`` to see a list of supported options: /Zc:threadSafeInit Enable thread-safe initialization of static variables /Zc:trigraphs- Disable trigraphs (default) /Zc:trigraphs Enable trigraphs - /Zi Enable debug information + /Zi Alias for /Z7. Does not produce PDBs. + /Zl Don't mention any default libraries in the object file /Zp Set the default maximum struct packing alignment to 1 /Zp<value> Specify the default maximum struct packing alignment /Zs Syntax-check only @@ -2119,6 +2150,7 @@ Execute ``clang-cl /?`` to see a list of supported options: -fsanitize-trap=<value> Enable trapping for specified sanitizers -fsanitize=<check> Turn on runtime checks for various forms of undefined or suspicious behavior. See user manual for available checks + -gcodeview Generate CodeView debug information -mllvm <value> Additional arguments to forward to LLVM's option processing -Qunused-arguments Don't emit warning for unused driver arguments -R<remark> Enable the specified remark diff --git a/docs/analyzer/DebugChecks.rst b/docs/analyzer/DebugChecks.rst index 14d6ae4..771e39f 100644 --- a/docs/analyzer/DebugChecks.rst +++ b/docs/analyzer/DebugChecks.rst @@ -138,6 +138,29 @@ ExprInspection checks clang_analyzer_warnIfReached(); // no-warning } +- void clang_analyzer_warnOnDeadSymbol(int); + + Subscribe for a delayed warning when the symbol that represents the value of + the argument is garbage-collected by the analyzer. + + When calling 'clang_analyzer_warnOnDeadSymbol(x)', if value of 'x' is a + symbol, then this symbol is marked by the ExprInspection checker. Then, + during each garbage collection run, the checker sees if the marked symbol is + being collected and issues the 'SYMBOL DEAD' warning if it does. + This way you know where exactly, up to the line of code, the symbol dies. + + It is unlikely that you call this function after the symbol is already dead, + because the very reference to it as the function argument prevents it from + dying. However, if the argument is not a symbol but a concrete value, + no warning would be issued. + + Example usage:: + + do { + int x = generate_some_integer(); + clang_analyzer_warnOnDeadSymbol(x); + } while(0); // expected-warning{{SYMBOL DEAD}} + Statistics ========== diff --git a/docs/analyzer/nullability.rst b/docs/analyzer/nullability.rst new file mode 100644 index 0000000..93909d0 --- /dev/null +++ b/docs/analyzer/nullability.rst @@ -0,0 +1,92 @@ +============ +Nullability Checks +============ + +This document is a high level description of the nullablility checks. +These checks intended to use the annotations that is described in this +RFC: http://lists.cs.uiuc.edu/pipermail/cfe-dev/2015-March/041798.html. + +Let's consider the following 2 categories: + +1) nullable +============ + +If a pointer 'p' has a nullable annotation and no explicit null check or assert, we should warn in the following cases: +- 'p' gets implicitly converted into nonnull pointer, for example, we are passing it to a function that takes a nonnull parameter. +- 'p' gets dereferenced + +Taking a branch on nullable pointers are the same like taking branch on null unspecified pointers. + +Explicit cast from nullable to nonnul:: + + __nullable id foo; + id bar = foo; + takesNonNull((_nonnull) bar); <ā should not warn here (backward compatibility hack) + anotherTakesNonNull(bar); <ā would be great to warn here, but not necessary(*) + +Because bar corresponds to the same symbol all the time it is not easy to implement the checker that way the cast only suppress the first call but not the second. For this reason in the first implementation after a contradictory cast happens, I will treat bar as nullable unspecified, this way all of the warnings will be suppressed. Treating the symbol as nullable unspecified also has an advantage that in case the takesNonNull function body is being inlined, the will be no warning, when the symbol is dereferenced. In case I have time after the initial version I might spend additional time to try to find a more sophisticated solution, in which we would produce the second warning (*). + +2) nonnull +============ + +- Dereferencing a nonnull, or sending message to it is ok. +- Converting nonnull to nullable is Ok. +- When there is an explicit cast from nonnull to nullable I will trust the cast (it is probable there for a reason, because this cast does not suppress any warnings or errors). +- But what should we do about null checks?:: + + __nonnull id takesNonnull(__nonnull id x) { + if (x == nil) { + // Defensive backward compatible code: + .... + return nil; <- Should the analyzer cover this piece of code? Should we require the cast (__nonnull)nil? + } + .... + } + +There are these directions: +- We can either take the branch; this way the branch is analyzed + - Should we not warn about any nullability issues in that branch? Probably not, it is ok to break the nullability postconditions when the nullability preconditions are violated. +- We can assume that these pointers are not null and we lose coverage with the analyzer. (This can be implemented either in constraint solver or in the checker itself.) + +Other Issues to keep in mind/take care of: +Messaging: +- Sending a message to a nullable pointer + - Even though the method might return a nonnull pointer, when it was sent to a nullable pointer the return type will be nullable. + - The result is nullable unless the receiver is known to be non null. +- Sending a message to a unspecified or nonnull pointer + - If the pointer is not assumed to be nil, we should be optimistic and use the nullability implied by the method. + - This will not happen automatically, since the AST will have null unspecified in this case. + +Inlining +============ + +A symbol may need to be treated differently inside an inlined body. For example, consider these conversions from nonnull to nullable in presence of inlining:: + + id obj = getNonnull(); + takesNullable(obj); + takesNonnull(obj); + + void takesNullable(nullable id obj) { + obj->ivar // we should assume obj is nullable and warn here + } + +With no special treatment, when the takesNullable is inlined the analyzer will not warn when the obj symbol is dereferenced. One solution for this is to reanalyze takesNullable as a top level function to get possible violations. The alternative method, deducing nullability information from the arguments after inlining is not robust enough (for example there might be more parameters with different nullability, but in the given path the two parameters might end up being the same symbol or there can be nested functions that take different view of the nullability of the same symbol). So the symbol will remain nonnull to avoid false positives but the functions that takes nullable parameters will be analyzed separately as well without inlining. + +Annotations on multi level pointers +============ + +Tracking multiple levels of annotations for pointers pointing to pointers would make the checker more complicated, because this way a vector of nullability qualifiers would be needed to be tracked for each symbol. This is not a big caveat, since once the top level pointer is dereferenced, the symvol for the inner pointer will have the nullability information. The lack of multi level annotation tracking only observable, when multiple levels of pointers are passed to a function which has a parameter with multiple levels of annotations. So for now the checker support the top level nullability qualifiers only.:: + + int * __nonnull * __nullable p; + int ** q = p; + takesStarNullableStarNullable(q); + +Implementation notes +============ + +What to track? +- The checker would track memory regions, and to each relevant region a qualifier information would be attached which is either nullable, nonnull or null unspecified (or contradicted to suppress warnings for a specific region). +- On a branch, where a nullable pointer is known to be non null, the checker treat it as a same way as a pointer annotated as nonnull. +- When there is an explicit cast from a null unspecified to either nonnull or nullable I will trust the cast. +- Unannotated pointers are treated the same way as pointers annotated with nullability unspecified qualifier, unless the region is wrapped in ASSUME_NONNULL macros. +- We might want to implement a callback for entry points to top level functions, where the pointer nullability assumptions would be made. diff --git a/docs/conf.py b/docs/conf.py index b7ed23a..6d53d94 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -12,6 +12,7 @@ # serve to show the default. import sys, os +from datetime import date # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -41,16 +42,16 @@ master_doc = 'index' # General information about the project. project = u'Clang' -copyright = u'2007-2015, The Clang Team' +copyright = u'2007-%d, The Clang Team' % date.today().year # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '3.7' +version = '3.8' # The full version, including alpha/beta/rc tags. -release = '3.7' +release = '3.8' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/doxygen.cfg.in b/docs/doxygen.cfg.in index b4cfbbd..f6c7cba 100644 --- a/docs/doxygen.cfg.in +++ b/docs/doxygen.cfg.in @@ -169,7 +169,7 @@ SHORT_NAMES = NO # description.) # The default value is: NO. -JAVADOC_AUTOBRIEF = NO +JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If @@ -177,7 +177,7 @@ JAVADOC_AUTOBRIEF = NO # requiring an explicit \brief command for a brief description.) # The default value is: NO. -QT_AUTOBRIEF = NO +QT_AUTOBRIEF = YES # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as diff --git a/docs/index.rst b/docs/index.rst index d50667d..a0a70c0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -24,6 +24,7 @@ Using Clang as a Compiler AddressSanitizer ThreadSanitizer MemorySanitizer + UndefinedBehaviorSanitizer DataFlowSanitizer LeakSanitizer SanitizerCoverage diff --git a/docs/tools/dump_ast_matchers.py b/docs/tools/dump_ast_matchers.py index 1e1fd3c9..9ecff04 100644 --- a/docs/tools/dump_ast_matchers.py +++ b/docs/tools/dump_ast_matchers.py @@ -166,7 +166,7 @@ def act_on_decl(declaration, comment, allowed_types): \s*AST_POLYMORPHIC_SUPPORTED_TYPES\(([^)]*)\) \)\s*;\s*$""", declaration, flags=re.X) if m: - loc, name, n_results, results = m.groups()[0:4] + loc, name, results = m.groups()[0:3] result_types = [r.strip() for r in results.split(',')] comment_result_types = extract_result_types(comment) @@ -191,8 +191,8 @@ def act_on_decl(declaration, comment, allowed_types): \)\s*{\s*$""", declaration, flags=re.X) if m: - p, n, name, n_results, results = m.groups()[0:5] - args = m.groups()[5:] + p, n, name, results = m.groups()[0:4] + args = m.groups()[4:] result_types = [r.strip() for r in results.split(',')] if allowed_types and allowed_types != result_types: raise Exception('Inconsistent documentation for: %s' % name) @@ -364,6 +364,6 @@ reference = re.sub(r'<!-- START_NARROWING_MATCHERS.*END_NARROWING_MATCHERS -->', 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: +with open('../LibASTMatchersReference.html', 'wb') as output: output.write(reference) diff --git a/docs/tools/dump_format_style.py b/docs/tools/dump_format_style.py index fdf03c6..b61d201 100644 --- a/docs/tools/dump_format_style.py +++ b/docs/tools/dump_format_style.py @@ -36,14 +36,35 @@ class Option: self.type = type self.comment = comment.strip() self.enum = None + self.nested_struct = None def __str__(self): s = '**%s** (``%s``)\n%s' % (self.name, self.type, doxygen2rst(indent(self.comment, 2))) if self.enum: s += indent('\n\nPossible values:\n\n%s\n' % self.enum, 2) + if self.nested_struct: + s += indent('\n\nNested configuration flags:\n\n%s\n' %self.nested_struct, + 2) return s +class NestedStruct: + def __init__(self, name, comment): + self.name = name + self.comment = comment.strip() + self.values = [] + + def __str__(self): + return '\n'.join(map(str, self.values)) + +class NestedField: + def __init__(self, name, comment): + self.name = name + self.comment = comment.strip() + + def __str__(self): + return '* ``%s`` %s' % (self.name, doxygen2rst(self.comment)) + class Enum: def __init__(self, name, comment): self.name = name @@ -65,18 +86,24 @@ class EnumValue: doxygen2rst(indent(self.comment, 2))) def clean_comment_line(line): - return line[3:].strip() + '\n' + if line == '/// \\code': + return '\n.. code-block:: c++\n\n' + if line == '/// \\endcode': + return '' + return line[4:] + '\n' def read_options(header): class State: - BeforeStruct, Finished, InStruct, InFieldComment, InEnum, \ - InEnumMemberComment = range(6) + BeforeStruct, Finished, InStruct, InNestedStruct, InNestedFieldComent, \ + InFieldComment, InEnum, InEnumMemberComment = range(8) state = State.BeforeStruct options = [] enums = {} + nested_structs = {} comment = '' enum = None + nested_struct = None for line in header: line = line.strip() @@ -97,13 +124,31 @@ def read_options(header): state = State.InEnum name = re.sub(r'enum\s+(\w+)\s*\{', '\\1', line) enum = Enum(name, comment) + elif line.startswith('struct'): + state = State.InNestedStruct + name = re.sub(r'struct\s+(\w+)\s*\{', '\\1', line) + nested_struct = NestedStruct(name, comment) elif line.endswith(';'): state = State.InStruct - field_type, field_name = re.match(r'([<>:\w]+)\s+(\w+);', line).groups() + field_type, field_name = re.match(r'([<>:\w(,\s)]+)\s+(\w+);', + line).groups() option = Option(str(field_name), str(field_type), comment) options.append(option) else: raise Exception('Invalid format, expected comment, field or enum') + elif state == State.InNestedStruct: + if line.startswith('///'): + state = State.InNestedFieldComent + comment = clean_comment_line(line) + elif line == '};': + state = State.InStruct + nested_structs[nested_struct.name] = nested_struct + elif state == State.InNestedFieldComent: + if line.startswith('///'): + comment += clean_comment_line(line) + else: + state = State.InNestedStruct + nested_struct.values.append(NestedField(line.replace(';', ''), comment)) elif state == State.InEnum: if line.startswith('///'): state = State.InEnumMemberComment @@ -124,9 +169,12 @@ def read_options(header): for option in options: if not option.type in ['bool', 'unsigned', 'int', 'std::string', - 'std::vector<std::string>']: + 'std::vector<std::string>', + 'std::vector<IncludeCategory>']: if enums.has_key(option.type): option.enum = enums[option.type] + elif nested_structs.has_key(option.type): + option.nested_struct = nested_structs[option.type]; else: raise Exception('Unknown type: %s' % option.type) return options @@ -140,6 +188,6 @@ contents = open(DOC_FILE).read() contents = substitute(contents, 'FORMAT_STYLE_OPTIONS', options_text) -with open(DOC_FILE, 'w') as output: +with open(DOC_FILE, 'wb') as output: output.write(contents) |