C/C++ Library Reference
Copyright © 2020 Synopsys, Inc. All rights reserved worldwide.
CodeXM is a domain-specific language that allows you to create customized code checkers for Coverity.
CodeXM checkers analyze source code for specific coding patterns, and report these issues with messages that you provide.
Like other Coverity checkers, the issues are displayed in Coverity Connect.
They can be archived with the cov-commit-defect
feature.
The CodeXM C/C++ library provides access to C and C++ coding constructs.
When you write your own patterns, you can employ library patterns to specify new conditions: either by narrowing down a general pattern to a more precise variation, or by combining simple patterns into a more complex composite.
This document provides information about the patterns and functions provided by the C/C++ library. To learn how to get started with CodeXM, please see Learning to Write CodeXM Checkers.
Describing CodeXM is a bit different from describing other languages. Most programming books talk about one language only. To describe CodeXM, we have to talk about CodeXM code itself, and the code of the language it is inspecting—the target language.
This reference shows all code in monospace
type.
CodeXM code appears in shades of green.
Target code (whatever the language) appears in shades of orange.
Reminder: By default, many browsers do not print out background colors.
The type of certain pattern properties is said to be nullable. This means that the property might return a value, or it might not. If it does not, its value matches the CodeXM keyword null. In the CodeXM documents, a nullable type is indicated by the name of the type the property might return, followed by a question mark; for example, int?.
In checker code, a nullable type requires some special handling in order to avoid the error of referencing the null. The Handling Null Values section of Learning to Write CodeXM Checkers describes how to do this.
In your CodeXM source, begin with an include declaration that names the library target language: include `C/C++`.
Specifying the target language makes the library’s special patterns and functions available within this CodeXM file. These patterns and functions are the subject of this reference.
The language specification also causes the checkers defined in your CodeXM file to be applied only to the target source code in your code base.
As of Coverity 2020.12, the C/C++ library provides support for that has been written for the CUDA® parallel computing platform. This support includes additional property fields for the functionSymbol, globalVariableSymbol, localVariableSymbol, and variableSymbol patterns. It also includes a new pattern, kernelCall, which matches calls to launch CUDA kernels.
To use kernelCall patterns in your CodeXM program, you need to replace the declaration that includes `C/C++` with an include of `CUDA`; for example: include `CUDA`.
If you don’t include the library named `CUDA`, your program can still use the CUDA-specific property fields, but it won’t recognize the kernelCall pattern.
Class definitions match class entities in the abstract representation of the target code, and provide properties that describe the classes that the library supports.
Every target-code object that Coverity inspects is a node in an abstract syntax tree. For a brief overview of how Coverity uses these syntax trees, see How Does Coverity Analysis Work? in the Syntax Reference.
Every astnode has the following properties:
Name | Type | Description |
---|---|---|
location | sourceloc | The location of this code construct in the source files |
children | list<astnode> | A list of child nodes that are sub-parts of this code construct |
parent | astnode? | This node’s parent node, if there is one; null if there is no parent |
macrosExpandedFrom | list<macroinfo> | If the code is produced by macro expansion, this list contains the macros that generated that expansion. Otherwise, this list is empty. |
implicit | bool | Indicates whether the node is the result of compiler intervention, as opposed to being explicitly stated in the source code. For example, if ( x ) in the source code is interpreted as if ( x != 0 ) by the compiler. The not-equals binary operator and the literal constant zero are implicit. |
The astnode elements are further classified as statement, expression, initializer and ctorinit (constructor initializer), and declaration elements (declaration elements declare symbols). Certain kinds of elements have their own set of properties in addition to the astnode properties shown here.
Describes a class (C++), struct, or union.
Note: If a type is never used in a project (a code base), its definition might be elided from analysis.
classDefinition produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
declaredType | classType | The associated classType record for this definition |
memberFunctionList | list<functionSymbol> | A list of member functions in this class |
staticFieldList | list<globalVariableSymbol> | A list of fields declared as static |
fieldList | list<fieldSymbol> | A list of fields that are not static |
staticMemberFunctionList | list<functionSymbol> | A list of the static member functions in this class |
parentList | list<classParent> | A list of parent classes |
location | sourceloc | The source-code location of the class definition |
byteSize | int | The byte size of a class instance |
instantiatedFrom | classType? | The class from which this class is instantiated; null if the class is not an instance |
specializationOf | classType? | The class of which this class is a specialization; null if the class is not a specialization |
isFinal | bool | true if the class is marked as final |
isPOD | bool | true if the class is marked as POD (Plain Old Data) |
isStandardLayout | bool | true if the class is a standard layout |
isTriviallyDefaultConstructible | bool | true if the class is trivially default-constructible |
isTriviallyDestructible | bool | true if the class is trivially destructible |
findBaseClass | function<testType> | A function that invokes a callback function, which can be used as a predicate to find a particular base class—in other words, to test whether the class is a parent of the current class. See the section, “The Base Class Properties”, below. |
findMatchingBaseClass | function<testType> | A function that invokes a pattern, which can be used as a predicate to find a particular base class—in other words, to test whether the class is a parent of the current class. See the section “The Base Class Properties”, below. |
Given the following source-code snippet:
... the pattern classDefinition matches the definition of struct T:
The function provided by the findBaseClass property has this form:
The function provided by the findMatchingBaseClass property has this form:
The findBaseClass call detects whether a base class is accepted by the callback function. If the callback returns a non-null value, then findBaseClass returns that value (which matches NonNull). If the callback does not return such a non-null value on any base class, findBaseClass returns null.
The findMatchingBaseClass call uses a pattern rather than a callback function, but it returns either a matching value or null, just as findBaseClass does.
Because both these function calls accomplish the same thing, for the most part which one you choose to use is up to you. The pattern form can be easier, and less lengthy, to code (see the examples that follow); on the other hand, a callback function can encode tests that a pattern cannot.
The following “Examples” section shows checkers that use these properties.
This first example uses findBaseClass. If findBaseClass can locate a class whose identifier (base.identifier) is "A", it returns the object for that class. Otherwise, the return value is null.
The second example uses findMatchingBaseClass:
Describes the parent of a given C++ class.
classParent produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
isVirtual | bool | true if this is a virtual parent |
parent | classDefinition | The definition for the parent class |
A class definition (that is, classDefinition) includes a list of its parent classes via the .parentList field.
Describes the definition of an enum.
enumDefinition produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
declaredType | enumType | The type name of this enum |
enumeratorList | list<enumerators> | A list of the literal values this type enumerates |
underlyingType | type | The underlying type of the enumerators |
hasExplicitEnumBase | bool | true if the underlying type is explicitly declared |
isScoped | bool | true if the enum has a class scope |
location | sourceloc | The source-code location of the enum definition |
For the following code snippet, enumDefinition matches the definition of enum E:
These are enumerations that are used by the language library, and that are available to your own CodeXM code.
Specifies whether an assignment is simple (assignment only) or compound (incorporating an additional operation such as plus, +, or minus, -).
The following values are defined:
Name | Description |
---|---|
`simple` | A simple assignment; for example, a = b |
`compound` | A compound assignment; for example, a += b |
assignmentOperator, assignmentOperatorCompound, assignmentOperatorSimple
Represents the various kinds of casts that C and C++ support.
The following values are defined:
Name | Description |
---|---|
`explicit` | An explicit cast; for example, (int) a |
`implicit` | An implicit cast |
`static` | A C++ static cast |
`dynamic` | A C++ dynamic cast |
`reinterpret` | A C++ reinterpret cast |
`const` | A C++ constant cast |
castOperator, castOperatorExplicit, castOperatorImplicit, castOperatorStaticCast, castOperatorDynamicCast, castOperatorReinterpretCast, castOperatorConstCast
Enumerates types that are deduced by the compiler (C++ only).
deducedTypeKind produces a record that contains the following properties:
Name | Description |
---|---|
`auto` | A type declared using the keyword auto. |
`decltype` | A type declared using the keyword decltype |
`gnu_auto` | A type declared using GNU auto. |
Represents the kinds of floating-point types known to C and C++.
The following values are defined:
Name | Description |
---|---|
`float` | A single-precision floating-point number |
`double` | A double-precision floating-point number |
`long double` | A long double-precision floating-point number |
Indicates the suffix used to specify the precision of a floating-point literal.
The following values are defined:
`f` | Indicates a suffix of f or F, which says to treat the literal value in calculations as a single-precision (float) floating-point value. |
`l` | Indicates a suffix of l or L, which says to treat the literal value in calculations as a long floating-point value. |
The precision of single or long floating-point values depends on the target implementation.
Represents either simple or range for loops.
A simple for loop is of the form:
A range for loop is of the form:
The following values are defined:
Name | Description |
---|---|
`range` | (C++) A for loop that uses the range expression introduced in C++11 |
`simple` | A simple C or C++ for loop |
forLoop, forLoopRange, forLoopSimple
Represents the integer types known to C and C++.
The following values are defined:
Name | Description |
---|---|
`bool` | A Boolean value |
`char` | A character |
`int` | A regular integer |
`long` | A long integer |
`long long` | A long long integer |
`short` | A short integer |
Specific bit lengths for integer values depend on the target implementation.
Enumerates the possible values for a literal null pointer value.
The following values are defined:
Name | Description |
---|---|
`0` | Zero |
`NULL` | The value NULL |
`nullptr` | The value nullptr (C++ only) |
Specifies one of the type qualifiers available to C or C++ code.
The following values are defined:
Name | Description |
---|---|
`_Atomic` | The type is qualified as _Atomic (C++ only, from C++11) |
`const` | The type is qualified as const (both C and C++) |
`restrict` | The type is qualified as restrict (C only, from C99) |
`volatile` | The type is qualified as volatile (both C and C++) |
Specifies whether the operand passed to sizeof() is an expression or a type.
Name | Description |
---|---|
`sizeofExpr` | The operand is an expression. |
`sizeofType` | The operand is a type. |
Describes which character encoding is used by a string literal.
The following values are defined:
Name | Description |
---|---|
`char` | Single-bite characters |
`wchar` | Wide character format |
`utf16` | Unicode UTF-16 format, variable length with either 2 or 4 bytes per character |
`utf32` | Unicode UTF-32 format, 4 bytes per character |
Describes how a variable has been declared.
The following values are defined:
Name | Description |
---|---|
`for` | The variable is declared within the condition of a for loop. |
`global` | The variable is declared globally. |
`if` | The variable is declared within the condition of an if statement. |
`simple` | The variable is declared locally. |
`switch` | The variable is declared within the condition of a switch statement. |
`while` | The variable is declared within the condition of a while loop. |
Represents the scope of a symbol.
The following values are defined:
Name | Description |
---|---|
`global` | The variable scope is global. |
`local` | The variable scope is local. |
variableReference, variableSymbol
The sets described in this section can help narrow the search of your checker. Typically they are used in for loop constructions such as the following:
Includes the definitions of all struct types, classes, and unions in the current code.
Includes the definition of all enum types in the current code.
Matches all the Abstract Syntax Tree (AST) nodes in all the functions and global variable initializers of the current C/C++ code.
Matches all function definitions and global variable definitions in the current code.
Matches all the Abstract Syntax Tree (AST) nodes in all the functions of the current C/C++ code.
Matches all function definitions in the current code.
Matches all definitions of global variables in the current code.
These patterns, organized by category, match the constructs that might be found in the target source code.
Patterns in this section belong to the statement class. They match executable statements in the target code.
Matches asm statements (C++ only) and their associated assembly source.
asmStatement produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
sourceString | expression | The assembly source code contained within the asm statement |
gccOperands | list<record>? |
Additional GNU Compiler Collection operands, such as infile and outfile .
If the compiler is not GCC-based, this property is null.
|
kind | enum (see below) | Specifies the development framework. |
The kind property can be one of the following:
Inherits properties from:
The asmStatement pattern matches an asm statement such as the following:
In this example, the .sourceString contains the entire assembly string "mov1 %1, %%eax; movl %%eax, %0" (which will have been string-glued by the compiler). Since this example illustrates a GCC-based asm statement, the .gccOperands list contains y and x, and .kind is set to `ADK_STANDARD`.
Matches a sequence of statements enclosed by curly braces.
This pattern only matches nodes of type statement.
blockStatement produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
containedStatements | list<statement> | An ordered list of the statements that the block contains |
Inherits properties from:
For the following blockStatement, .containedStatements contains only a simpleStatement—specifically, an assignmentOperator, x = 1;:
The following code shows a blockStatement whose .containedStatements contains only an empty list:
The following CodeXM pattern matches blocks that contain only an empty statement (for example, { ; }):
Matches break statements.
breakStatement produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
controlStatement | statement | The flow-of-control statement within which the break statement occurs, such as for, while, or switch |
Inherits properties from:
Consider this bit of C or C++ code:
A breakStatement pattern matches the break statement in the preceding code fragment. The pattern’s .controlStatement property references the while loop itself.
To identify break statements specifically within switch statements, use the following pattern:
Matches individual case statements within a switch. Does not match the statement in the default clause: See the defaultStatement pattern.
caseStatement produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
valueExpression | expression | The value associated with this case |
Inherits properties from:
Given the same example from switchStatement:
... we can use caseStatement to match the three case labels but exclude the default statement. The valueExpression is the associated value of the case label.
A custom pattern, matchCaseByValueExpression, that matches instances of case 1: looks like this:
Matches continue statements.
continueStatement produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
controlStatement | statement | The loop statement for which the continue statement occurs. |
Inherits properties from:
A continueStatement pattern matches the continue statement in the following example (.controlStatement is the outer for loop):
To detect all continue statements, you can use the following pattern:
Matches the default statement in a switch. See also caseStatement.
This pattern does not expose any new properties.
Inherits properties from:
Using the same source code as the switchStatement pattern, defaultStatement would match the default case.
The following pattern identifies switch statements that do have default cases:
Matches do ... while loops.
This pattern only matches nodes of type statement.
doWhileLoop produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
conditionExpression | expression | The condition that causes the loop to terminate |
bodyStatement | statement | The statement that the loop repeatedly executes. Frequently this is a blockStatement. |
Inherits properties from:
The following C/C++ fragment matches doWhileLoop:
The doWhileLoop pattern sets the following properties:
A special case of the do ... while loop is the non-looping do ... while. This can be used for the following reasons:
The following pattern code detects a do ... while loop whose condition is always false:
Matches empty statements.
An empty statement can be a line with no executable code that is terminated by a semicolon; non-executable code enclosed by curly braces; or an implied branch of an if statement.
See also blockStatement.
emptyStatement produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
isImplicit | bool | Indicates whether the empty statement is implicit or not. |
Inherits properties from:
Within a function, a semicolon without any code preceding it parses as an emptyStatement:
An emptyStatement can be inside a blockStatement, matched by blockStatement { .containedStatements == emptyStatement }:
Caveat: The following code does not match emptyStatement. Instead, this is a blockStatement where the list of .containedStatements is empty:
A for loop with an empty body can be matched by forLoop { .bodyStatement == emptyStatement }:
The following pattern matches any empty statement:
To match an empty statement located inside a for loop, use a pattern such as the following:
To match any implicit empty statement:
Matches both kinds of for loop recognized by C++. (C recognizes only the simple variant.) To match only specific kinds of for loop, or to gain access to such a loop’s properties, see forLoopSimple and forLoopRange.
forLoop produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
kind | enum forLoopKind | The kind of loop; this equals either `simple` or `range`; see forLoopKind |
Inherits properties from:
The following C code:
... matches the following pattern:
Similarly, the following C++ code:
... matches the following pattern:
Note: The more specific patterns forLoopSimple and forLoopRange are shorthand for the examples shown above. The more specific patterns have the added benefit of exposing properties specific to the kind of loop in question.
Here is another way to express the previous pattern:
... or its alternative:
Matches range-based for loops. (This kind of for loop was introduced in C++11.) Does not match any C-language code.
See also forLoopSimple, which matches the classic for loop construct in either C or C++.
forLoopRange produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
kind | enum forLoopKind | The kind of loop: always `range`; see forLoopKind |
loopVariable | variable? | The name of the loop control variable, if one was specified; null otherwise |
collectionExpression | expression | The collection of things being enumerated. This is either a variable or a literal. |
bodyStatement | statement | The statement that the loop repeatedly executes. Frequently this is a blockStatement. |
Inherits properties from:
The following code:
... is matched by a forLoopRange pattern. In this example, the properties of this pattern are returned as follows:
The following pattern detects any range-based for loop:
A common coding mistake is the “do-nothing” for loop—that is, where the developer mistakenly types a semicolon immediately after the for condition, as in this expression:
The following pattern can detect such a mistake:
As a matter of C++ best practices, it is safe and efficient to make the loop variable of a range-based for loop a const reference, as in the following example:
This protects you against unnecessary copying and accidental modification of the member that the loop variable refers to. The following pattern detects any range-based for loop in which the loop variable has not been declared with a const reference type:
Specifically matches only simple for loops.
forLoopSimple produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
kind | enum forLoopKind | The kind of loop: always `simple`; see forLoopKind |
initializationStatement | statement? | The initialization clause of the for loop; null if there is none |
conditionExpression | expression | The condition that causes the loop to terminate |
conditionDeclaration | declaration? | If a variable is declared within the condition (second clause) of the for loop, this property contains its name. (This is seldom done; this property is null if no such variable is declared.) |
updateStatement | statement? | The statement that updates the loop value; frequently something like i++. This record is null if there is no such statement |
bodyStatement | statement | The statement that the loop repeatedly executes. Frequently this is a blockStatement. |
Inherits properties from:
The following code:
... is matched by forLoopSimple, which sets the following properties:
The foreverLoop pattern below matches a loop with a constant true condition, such as for(;;) or while(1) or a similar construct.
Matches goto statements.
gotoStatement produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
labelStatement | statement | The labeled statement to which the goto jumps. |
Inherits properties from:
The pattern gotoStatement matches goto in source code. When matched, the pattern’s .labelStatement property indicates the target label.
Consider the following target code:
In this example, gotoStatement matches the goto flag; statement and the pattern’s .labelStatement is set to flag:.
Matches entire if statements, including their condition expressions and their true and false branches.
In C and C++, the consequences of the condition are each a single statement, but that single statement can be a block statement (that is, any number of statements enclosed by curly braces). This is reflected in the properties of the pattern.
ifStatement produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
conditionExpression | expression | The condition that determines whether the trueStatement or the falseStatement is executed |
trueStatement | statement | The “then” statement, which is only executed if conditionExpression evaluates to true |
falseStatement | statement? | The “else” statement, which is only executed if conditionExpression evaluates to false. If the if has no else statement, this property is null. |
conditionDeclaration | declaration? | If a variable is declared in the conditionExpression, this property contains its name; otherwise, this property is null. |
Inherits properties from:
The ifStatement pattern matches an instance such as this target source:
A match returns these values:
The following use of the ifStatement specifically finds if statements that have an else clause:
Matches statements that have a label.
labelStatement produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
nameString | string | The value of the label |
targetStatement | statement | The statement to which this label is assigned |
Inherits properties from:
Using the same source code as the gotoStatement pattern, the labelStatement pattern matches the flag: target, and .targetStatement contains the statement that follows; specifically, the assignment count = 2;:
Matches both simple, void return statements, and return <expression> returns.
returnStatement produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
isVoid | bool | Equal to true if the function is a void function that uses a simple return statement and does not return a value. |
returnedExpression | expression? | If the type of the function is not void, this property contains the expression that the function returns; otherwise, it is null. |
Inherits properties from:
Consider the following source:
The returnStatement pattern matches the return statement found within that function code. In this example, the pattern’s .isVoid property is false, and the .returnedExpression is i.
The following pattern matches instances of return where the expression being returned is an integer literal that appears directly in the source code (as opposed to one that was expanded from a preprocessor macro):
In other words, this matches return 42; but it does not match return ERROR_CODE;, where ERROR_CODE is defined to be an integer.
Matches individual executable statements.
In this context, the term simple means that such statements do not affect the flow of control. Simple statements include assignments and function calls. They do not include variable declarations: See variableDeclaration.
simpleStatement produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
expression | expression | The expression, such as a function call or an assignment, that makes up the statement |
Inherits properties from:
The target expression x = x + 5; matches the following pattern:
Similarly, a statement with the callFoo(); function call matches the following pattern:
To find all function calls in simple statements, you could use the following pattern:
Matches entire switch statements, including all the statements contained in their case and default clauses. See also caseStatement, defaultStatement, and breakStatement.
switchStatement produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
conditionExpression | expression | The expression that determines which case is to be taken |
caseList | list<statement>> | A list of the targets of this switch statement. A target is either a caseStatement or a defaultStatement. |
bodyStatement | statement | The body of the switch statement. In most cases this is a blockStatement. |
conditionDeclaration | declaration? | If a variable is declared in the conditionExpression, it is identified here. If no variable is declared, this property is null. |
Inherits properties from:
A switchStatement pattern matches a switch statement instance such as the following:
A match to the snippet above returns these values:
The following pattern identifies switch statements that do have default cases:
Matches try statements (C++ only), including any catch blocks associated with the try.
tryStatement produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
bodyStatement | statement | The statement in the body of the try statement |
catchBlockList | list<record> | The list of catch blocks |
Inherits properties from:
The tryStatement pattern matches source code such as this:
... where in this example, .bodyStatement refers to int i = 1; and .catchBlockList is a list that contains Exception1, Exception2, Exception3.
Matches only standard while loops (as opposed to do ... while loops or for loops). The match includes the body statement that the while loop contains.
This pattern only matches nodes of type statement.
whileLoop produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
conditionExpression | expression | The condition that causes the loop to terminate |
conditionDeclaration | declaration? | If a variable is declared within the condition of the while loop, this property contains its name. (This is seldom done; this property is null if no such variable is declared.) |
bodyStatement | statement | The statement that the loop repeatedly executes. Frequently this is a blockStatement. |
Inherits properties from:
The following C/C++ fragment matches a whileLoop, which sets the following properties:
Matching a Loop Whose Condition Is Always True
Patterns in this section belong to the declaration class. They match object declarations in the target code.
Matches function declarations within a function (as opposed to outside of a function, as is frequently done in headers).
This pattern does not match actual function calls. To find function calls, see functionCall.
See also: functionType.
localFunctionDeclaration produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
declaredFunction | functionType | Information for the declared function |
Inherits properties from:
Consider the following snippet of C code:
The functionDeclarationLocal pattern matches void bar(void); in the first line of foo(), since bar() is declared locally.
However, this pattern does not match the actual call to bar(). To match the function call itself, use the functionCall pattern.
Matches variable declarations, regardless of their location. For example, this pattern matches both the simple declarations found at the top of function code, and the scoped declarations that are found in various flow-of-control statements.
variableDeclaration produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
kind | enum variableDeclarationKind (see below) | Variables can be declared in a variety of locations. This property indicates the scope of the declaration. |
variable | symbol | The identifier of the variable being declared |
initializer | initializer? | The expression evaluated to determine the initial value; null if there is no such expression |
These are the possible values for the kind property (see also variableDeclarationKind):
Inherits properties from:
For example, a variable declared in the conditional expression of an if statement is in scope for the rest of the conditional, and also within the statement’s then and else clauses.
The variableDeclaration pattern matches source code such as the following:
In the first instance, .variable refers to num, and the property .initializer is null.
In the second instance, .variable refers to count, and .initializer is set to an expressionInitializer whose value is an intLiteral equal to 1.
The following pattern matches uninitialized variable declarations:
These patterns match various types of values in the target code.
Matches arrays.
arrayType produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
elementType | type | The type of the elements in the array |
elementCount | int? | The number of elements in the array; null if the array is uninitialized |
alignmentInBytes | int? | The alignment of the type, in bytes; null if the type is not aligned |
sizeInBytes | int | The number of bytes required to store a value of this type |
In the following source code, the pattern arrayType matches the type of a local variable x in the assignment statement, provided that .elementType is intType and .elementCount is 10:
The following pattern detects an expression that is an array type:
Matches the Boolean types, both bool and _Bool (C11 and later).
boolType produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
kind | enum | One of `bool` or `_Bool` |
alignmentInBytes | int? | The alignment of the type, in bytes; null if the type is not aligned |
sizeInBytes | int | The number of bytes required to store a value of this type |
sizeInBits | int | The number of bits required to store a value of this type |
In the following source code, the pattern boolType matches the type of a local variable x:
The following pattern matches all expressions with a Boolean type:
Matches character types such as char or the C++ wchar_t.
charType produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
kind | enum | One of `char`, `unsigned char`, `signed char`, or `wchar_t` |
isSigned | bool | true if the type is signed |
isExplicitlySigned | bool | true if the sign is explicitly stated (rather than being implied) |
alignmentInBytes | int? | The alignment of the type, in bytes; null if the type is not aligned |
sizeInBytes | int | The number of bytes required to store a value of this type |
sizeInBits | int | The number of bits required to store a value of this type |
In the following source code, the pattern charType matches the type of a local variable x:
The following example matches explicitly signed char types:
Matches class (C++), struct, and union types.
classType produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
kind | enum | One of `class`, `struct`, or `union` |
isAnonymous | bool | true if the object is anonymous |
identifier | string? | The string used as an unqualified name for this type; null if the object is unnamed |
mangledName | string? | The internal “mangled” name used for the class (the mangled name includes type and scope information, to disambiguate this instance of the identifier); null if the mangled name is not available |
isAlignmentAssigned | bool | true if the class is aligned |
alignmentInBytes | int? | The alignment of the type, in bytes; null if the type is not aligned |
isComplete | bool | true if the object definition is known at compile time |
location | sourceloc | The source-code location of the type definition |
scopeList | list<string> | The scopes within which the class is nested |
sizeInBytes | int | The number of bytes required to store a value of this type |
In the following source code, the pattern classType matches the type of a local variable x:
The following pattern matches all expressions with an anonymous class type:
Matches compiler-deduced types specified using the auto or decltype declarators.
Be careful: This pattern only applies to C++. With this pattern, the auto keyword refers to C++ usage, not to C usage. It indicates a variable that is declared in a function’s stack frame. Because the C-language use of auto is the default, auto in C code is not recorded by analysis, per se; see localVariableSymbol.
deducedType produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
kind | enum deducedTypeKind | One of `auto`, `decltype`, or `gnu_auto`; see deducedTypeKind |
inferredType | type | The type inferred by a compiler |
In the following source code, the type of a local variable a is declared using auto. This can be matched by a deducedType pattern that specifies .inferredType to be intType (that is, the compiler inferred the type of integer) and .kind to be `auto`.
The following example matches types that are inferred to be integers:
Matches enum types.
enumType produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
identifier | string | The string used as an unqualified name for the enum |
mangledName | string? | The internal “mangled” name used for the enum (the mangled name includes type and scope information, to disambiguate this instance of the identifier); null if the mangled name is not available |
location | sourceloc | The source-code location of the enum definition |
isAlignmentAssigned | bool | true if the enum is aligned |
alignmentInBytes | int? | The alignment of the type, in bytes; null if the type is not aligned |
scopeList | list<string> | The scopes within which the enum is nested |
sizeInBytes | int | The number of bytes required to store a value of this type |
In the following source, the code pattern enumType matches the type of a local variable x:
The following pattern matches all expressions with type enum FOO:
Matches primitive floating-point types such as float, double, or long double.
Please be aware: The precision of floating-point representations depends on the target system’s implementation.
floatType produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
kind | enum floatKind | One of `float`, `double`, or `long double`; see floatKind |
alignmentInBytes | int? | The alignment of the type, in bytes; null if the type is not aligned |
sizeInBytes | int | The number of bytes required to store a value of this type |
sizeInBits | int | The number of bits required to store a value of this type |
In the following source code, the pattern floatType matches the type of a local variable x:
The following example matches float types, but does not match double or long double:
Matches the types of functions; for example, the type of the function being called in a function call.
functionType produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
declaredThrownTypeList | list<type>? | The types of the exceptions that the function might directly or indirectly throw; null if there are none |
doesNotReturn | bool | true if the function does not return |
hasEllipsis | bool | true if the function’s parameter list uses ellipsis ( ... ) notation |
hasNoExcept | bool | true if the function is declared with the keyword noexcept (since C++11) |
isMemberFunction | bool | true if the function is a method in a class (C++ only) |
isPrototyped | bool | true if the function has a prototype |
paramTypeList | list<type> | The types of the function’s formal parameters |
returnType | type | The type of the value returned by the function |
The following pattern matches a member function call whose return type is voidType.
Matches integer types, including bool, char, short, int, long, and long long (C++).
intType produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
kind | enum intKind | One of `bool`, `char`, `short`, `int`, `long` or `long long`; see intKind |
isSigned | bool | true if the type is signed |
alignmentInBytes | int? | The alignment of the type, in bytes; null if the type is not aligned |
sizeInBytes | int | The number of bytes required to store a value of this type |
sizeInBits | int | The number of bits required to store a value of this type |
In the following source code, the pattern intType matches the type of a local variable x:
The following pattern matches all short types:
(C++) Matches members of classes.
memberType produces a record that has the following properties:
Name | Type | Description |
---|---|---|
classType | classType | The type of the class that owns the member |
memberType | type | The type of the member itself |
Consider the following source code:
The following CodeXM fragment would match both these members of Bird: the pointer pN and the pointer target &Bird::mN:
Matches null pointers, including the keyword nullptr introduced in C++11.
This pattern matches only nodes of type type. It does not expose any new properties.
Inherits properties from:
In the following source code fragment, nullPointerType matches the variable nullVar:
Matches pointer types such as int* or char*.
pointerType produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
pointerToType | type | The type of the referenced value |
alignmentInBytes | int? | The alignment of the type, in bytes; null if the type is not aligned |
sizeInBytes | int | The number of bytes required to store a value of this type |
In the following source code, the pattern pointerType matches the type of a local variable x, provided that the .pointerToType property is intType:
The following pattern matches all expressions that are pointers to integers:
Matches types that instantiate a template (C++).
This pattern only matches nodes of type type.
referencedTypesType produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
referencedTypes | list<type> | The types that the template instance references. |
targetType | type | The type of the template instance. |
Suppose you had a program with the following declarations:
... then referencedTypesType would match cls. Its .referencedTypes property would contain intType and boolType, and the value of .targetType would be "myClass".
Matches instances of the sizeof() operator applied to types; for example, sizeof( int ).
sizeofOperatorType produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
operandType | type | The type being evaluated |
vlaExpressions | list<expression>? | The expression being evaluated to find the size of a variable-length array; null if there is no expression |
The sizeofOperatorType pattern matches the use of sizeof() in the following source code:
In this case, the pattern has an .operandType indicating that it is an array, and .vlaExpressions refers to var.
The following pattern matches any sizeof() operator applied to a variable-length array:
Matches uses of a type defined using a typedef declarator.
typedefType produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
identifier | string | The string used as an unqualified name for the symbol |
mangledName | string | The internal “mangled” name used for the symbol (the mangled name includes type and scope information, to disambiguate this instance of the identifier) |
targetType | type | The original, underlying type |
scopeList | list<string> | The scopes within which the typedef is nested |
In the following source code, the type of variable pattern typedefType matches i, provided .targetType is a typeQualifier and .targetType specifies an integer type (intType):
The following pattern matches nodes whose type is defined as Cint:
Matches C-language type qualifiers, such as const, volatile, or restrict.
This pattern does not match the C++ qualifier _Atomic.
typeQualifier produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
qualifierList | list<enum qualifierEnum> | The qualifiers of the type: Items in the list can be `const`, `volatile`, or `restrict`; see qualifierEnum |
targetType | type | The type the qualifier is applied to |
Given the following code snippet:
... the following pattern:
... matches the variable i, because this variable’s declaration is qualified by const.
Matches types qualified by using the atomic qualifier.
typeQualifierAtomic produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
targetType | type | The type the qualifier is applied to |
Matches types qualified by using the const qualifier.
typeQualifierConst produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
targetType | type | The type the qualifier is applied to |
Matches types qualified by using the restrict qualifier.
typeQualifierRestrict produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
targetType | type | The type the qualifier is applied to |
Matches types qualified by using the volatile qualifier.
typeQualifierVolatile produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
targetType | type | The type the qualifier is applied to |
Matches the void type.
This pattern does not expose any new properties.
In the following code, the return type of the function test() is matched by voidType:
Patterns in this section belong to the expression class. They match expressions in the target code.
Many statements in C or C++ code contain expressions. The patterns in this section match specific kinds of expressions.
Please be aware: The patterns shown in the “Literals” and “Operators” sections are expressions, too.
For example, in the following snippet of target code:
... we see a pair of if statements. As described in the previous section, the ifStatement pattern detects either instance.
But each statement has a condition: namely, the part enclosed by the parentheses that follow the keyword if. Both conditions in this example are expressions. The first is simply a variable reference. The second is more complicated: It is made up of a binary operator (specifically, the equality operator) with operands (which are themselves expressions) appearing on either side. The left-hand operand is a function call, and the right-hand operand is a variable reference.
You could match the first of these conditions by using the expression pattern variableReference (which also matches the right-hand side of the second condition), and you could match the second of these conditions by using the expression pattern binaryOperator.
To inspect a complete condition expression, look at the .conditionExpression property of the ifStatement pattern.
In addition to the properties specific to each pattern, and the properties inherited from astnode, all expression patterns have the following properties:
Name | Type | Description |
---|---|---|
type | type | The C/C++ type of the expression |
isParenthesized | bool | Whether there are parenthesis around this expression |
Matches function call sites: places in the current code where a function is invoked.
This pattern only matches actual function call sites. It does not match simple references to the function’s identifier. For example, it would not match the function name’s appearance in code that assigned a function pointer to the function.
functionCall produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
calledFunction | functionSymbol? | Information about the function itself; null if this is not available |
argumentList | list<expression> | The parameters used in the call |
isVirtual | bool | true if the function is a virtual method call (C++ only) |
isNonstaticMethod | bool | true if the function call is into a class method that is not static (that is, it has a this pointer) |
isQualified | bool | true if the function’s return type has a qualifier |
Inherits properties from:
The functionCall pattern matches source code that invokes a call to another function; for example, sum( i, j+k ) in the initialization shown by the following code:
In this example, the .calledFunction refers to the metadata for the function sum(). The .argumentList contains two items: The first is a variableReference to i, and the second is the binaryOperator that represents the addition of the variables j and k.
Matches calls to launch a CUDA kernel.
These calls have the scheme launchNewKernel<<< Dg, Db, Ns >>>( parameters, ... ).
Reminder: To find kernelCall patterns, your program needs to include `CUDA` as the language library. See The CUDA Extension.
kernelCall produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
associatedStream | expression | The associated stream to launch |
blockDimension | expression | The dimension of each block |
callExpression | functionCall | The call itself, excluding its configuration arguments |
gridDimension | expression | The dimension of the grid |
sharedMemoryBytes | expression | The number of bytes per block in shared memory that is dynamically allocated for this call |
Inherits properties from:
Matches references to member fields of structures or classes (C++ only).
memberReference produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
objectExpression | expression | The structure or class object whose member is being accessed |
field | type | The member field |
Inherits properties from:
The pattern memberReference matches references to members of a struct or a class. Consider the following C++ code:
In this case, memberReference matches two instances, one on each line shown below:
On the first line, the .objectExpression is st, and the .field property refers to field i.
On the second, the pattern is almost the same, but the .field property refers to field f.
Matches pointer dereference (*p) expressions.
pointerDereference produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
pointerExpression | expression | The pointer being dereferenced |
Inherits properties from:
The pointerDereference pattern matches the dereference in the following code:
The .pointerExpression property is a variableReference to p_m.
Matches instances of the sizeof() operator applied to expression; for example, sizeof( y[0] ).
See also sizeofOperatorExpression and sizeofOperatorType.
sizeofOperatorExpression produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
operandExpression | expression | The expression being evaluated for size information |
Inherits properties from:
The sizeofOperatorExpression pattern matches code such as the following:
In this instance, .operandExpression refers to num.
The following pattern matches a sizeof() operator invoked using a variable reference expression:
Matches subscript references, such as p[i].
Caution: This pattern does not match the logical equivalent, *( p + i ), and it does not match C++ subscript operator overloads (which are method calls rather than actual operators).
See also arrayOf for a function that specifically looks for an array of the type you indicate.
subscriptReference produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
arrayExpression | expression | The array being referenced |
indexExpression | expression | The indexing expression |
Inherits properties from:
The subscriptReference pattern matches the two instances in the following source code:
In the both cases, .arrayExpression refers to a variableReference of arr, and in both cases the .indexExpression is an integer literal: The values will be 3 and 5, respectively.
Matches variable references within expressions.
variableReference produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
identifier | string | The name of the identifier (shorthand for .variable.identifier) |
mangledName | string | The internal “mangled” name used for the variable (the mangled name includes type and scope information, to disambiguate this instance of the identifier); null if the mangled name is not available |
variable | variableType | The variable being referenced |
scope | enum variableScopeEnum | The scope of the variable: either `local` or `global`. Static variables are classified as `global`; see variableScopeEnum |
isVolatile | bool | true if this variable is volatile |
isFunctionStatic | bool | true if this variable was declared within a function and modified by the keyword static |
isClassStatic | bool | true if this variable is a static member variable of a class (C++ only) |
Inherits properties from:
Imagine the following target code:
The variableReference pattern matches x in the function func() (specifically in respect to the assignment y = x).
The following pattern detects all references of global variables within expressions:
These patterns match literal values in the target code.
Matches the Boolean literals true and false.
This pattern only matches nodes of type expression.
booleanLiteral produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
isTrue | bool | Matches the value of the literal. |
Inherits properties from:
In the following C++ snippet, the pattern booleanLiteral matches false by setting the property .isTrue to false:
The following pattern matches any true Boolean literal.
Matches all floating-point literals, including both single and double precision (that is, the types float and double).
This pattern only matches nodes of type expression.
floatLiteral produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
valueString | string | The string representation of the literal |
suffix | enum floatSuffix? | `f` or `l` if a suffix is specified in the source (see floatSuffix); null if there is no suffix. |
isLowercaseSuffix | bool | true if the suffix is lower case in the source |
isLowercaseLSuffix | bool | true if the suffix is a lowercase l (ell) |
isHexFloat | bool | true if the literal is hexadecimal (preceded by 0x or 0X) |
Inherits properties from:
In the case of the folllowing code:
... a floatLiteral matches if .valueString is set to "2.5" and .suffix is set to `f`. The property .isLowercaseSuffix will be true.
Matches all integer literals, regardless of their sign or base.
This pattern only matches nodes of type expression.
intLiteral produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
value | int | The actual value represented by the literal |
base | enum | `binary`, `decimal`, `octal`, or `hexadecimal` |
kind | enum intKind | `bool`, `char`, `short`, `int`, `long`, or `long long` (C++ only); see intKind |
llsuffix | enum? | `l` or `ll` if the literal has one of these suffixes; null otherwise |
isLowercaseLSuffix | bool | true if the suffix is lower case |
hasUSuffix | bool | true if the suffix is U (for unsigned) |
isLowercaseSuffix | bool | true if all the suffixes are lower case |
Inherits properties from:
Consider the following literal initialization:
The value 8888l produces an integer literal, so an intLiteral pattern matches it. The .value property will be 8888, .kind will be `long`, .llSuffix will be `L`, and .isLowercaseLSuffix will be true.
Because the appearance of the lowercase letter L (l) is nearly indistinguishable from the digit one (1) in many typefaces and environments, many coding standards require that the suffix always be uppercase to avoid misinterpretation. The following pattern matches violations of this rule:
Matches null pointers.
The nullptr value (as opposed to NULL) was introduced in C++11.
This pattern only matches nodes of type expression.
nullPointerLiteral produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
kind | enumnullKind | The kind of literal used to encode the null: `0`, `NULL`, or `nullptr`; see nullKind |
Inherits properties from:
The nullPointerLiteral pattern matches NULL or nullptr or 0 in source code.
For example, the pattern nullPointerLiteral matches the following snippet with .kind set to `NULL`:
The pattern nullPointerLiteral matches the next snippet by setting .kind to `0`.
The following pattern matches the use of 0 as a null pointer:
Matches all character string literals.
This pattern only matches nodes of type expression.
stringLiteral produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
valueString | string | The actual string |
encodingType | enum stringLiteralEncoding | `char`, `wchar`, `utf16`, or `utf32`; see stringLiteralEncoding |
Inherits properties from:
Consider the following declaration:
In this case, the stringLiteral pattern matches "hello", with .valueString containing the string itself and .encodingType set to `char`.
The following pattern matches a stringLiteral whose encoding type is `char`, such as the one in the previous example:
These patterns match operators in the target code.
Matches instances of the & (“address of”) operator.
This pattern only matches nodes of type expression.
addressOf produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
operandExpression | expression | The operand of the & operator (the object whose address is being retrieved) |
Inherits properties from:
The addressOf pattern matches the &num in the following code:
The following pattern matches the addressOf of any global variable:
Matches all forms of the assignment operator in expressions, or the cases where a variable takes on a new value. This pattern does not match variable declarations, which are distinct and are matched by their own pattern, variableDeclaration.
This general pattern matches both simple assignments such as x = 10 and the compound forms such as x += 10. (The patterns assignmentOperatorSimple and assignmentOperatorCompound make the distinction by matching only one of these forms of assignment or the other.)
This pattern only matches nodes of type expression.
assignmentOperator produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
kind | enum assignKind | Either `simple` or `compound`, to indicate which form of assignment has matched; see assignKind |
targetExpression | expression | The target of the assignment; typically, a variable receiving a new value, such as what C/C++ refers to as an lvalue |
sourceExpression | expression | The expression which, when evaluated, is assigned to the target |
operator | enum | The assignment operator, either `=` or one of the many compound forms, such as `+=` or `*=` |
Inherits properties from:
The assignmentOperator pattern matches source such as the assignment shown here:
In this match, the .operator is described as `=` and its .kind is `simple`. Unsurprisingly, the .sourceExpression is an intLiteral; specifically, the literal 1.
What might be surprising is that there is a property named .targetExpression. You might expect this to be named “.targetVariable”, but consider that not every assignment is directly to a named variable. For example, an assignment can also be made to an address pointed to by a pointer, or to a member of an array.
In this particular example, however, .targetExpression is a variableReference, which is always the case when a variable is being assigned.
Consider the following pattern:
Statements and expressions in your code can be visualized as a tree structure. We saw this in the section named “Code Patterns”, and we draw upon that example here. Remember that the following source code:
... is expressed by the following syntax tree:
We see that the simpleStatement pattern matches the expression x = y*2 + 1, which is an assignment of y*2 + 1 to the variable x.
The pattern embeddedAssignment shown above matches any instance of an assignment operator that is not immediately under a simple statement. In other words, embeddedAssignment finds assignments that occur within a larger expression (because the parent would be another expression) or within an if, while, or other statement (because the parent would be another kind of statement).
Consequently, this pattern would detect the assignment of y in the following source code:
... as well as the assignment of x in the following source:
Matches only compound assignments such as x += y or z *= 3.14.
This pattern is shorthand for the pattern assignmentOperator { .kind == `compound` }.
This pattern only matches nodes of type expression.
assignmentOperatorCompound produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
kind | enum assignKind | Always `compound`; see assignKind |
targetExpression | expression | The target of the assignment; typically, a variable receiving a new value, such as what C/C++ refers to as an lvalue |
sourceExpression | expression | The expression which, when evaluated, is assigned to the target |
operator | enum | The assignment operator: one of the many compound forms, such as `+=` or `*=` |
Inherits properties from:
The assignmentOperatorCompound pattern can match source code that uses the += operator:
In this match, the property .kind is `compound` and .targetExpression refers to count. The .sourceExpression refers to the intLiteral with the value of 1, and .operator is `+`.
Combining these properties, we can construct the following pattern. It detects compound addition assignments to a variable named count. Pattern decomposition defines two constraints on the assignment operator’s properties—that is, both must be true for the overall pattern to match.
Matches only simple assignments.
Be careful: Even though variable declarations look similar to assignment operators, this pattern does not match variable declarations. See the pattern variableDeclaration.
This pattern is shorthand for the pattern assignmentOperator { .kind == `simple` }.
This pattern only matches nodes of type expression.
assignmentOperatorSimple produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
kind | enum assignKind | Always `simple`; see assignKind |
targetExpression | expression | The target of the assignment; typically, a variable receiving a new value, such as what C/C++ refers to as an lvalue |
sourceExpression | expression | The expression which, when evaluated, is assigned to the target |
operator | enum | Always `=` |
Inherits properties from:
The following code assigns a constant value 123 to the variable x. The pattern assignmentOperatorSimple matches this simple assignment:
As mentioned previously, assignment doesn’t happen only to variables. The following pattern matches an assignment to the target of a pointer:
Assuming the following definition:
... the assignmentToPointer pattern would not match the following code:
... because the target expression is a variable reference (chptr itself).
The pattern would match the following source:
... because here the target expression dereferences chptr.
When a variable is a pointer, the array-like notation is seen as a pointer dereference as well. That is, chptr[0] is equivalent to *chptr, so assignmentToPointer matches it. This does not hold true for variables defined as arrays: for char buf[], the array reference buf[0] does not match.
Matches the many binary operators—operators that take an operand on either side, such as +, *, ==, and so on.
This pattern only matches nodes of type expression.
binaryOperator produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
operator | enum | Can be one of: `==`, `!=`, `<`, `>`, `<=`, `>=`, `<=>`, `*`, `/`, `%`, `+`, `-`, `<<`, `>>`, `&`, `^`, `|`, `&&`, `||`, `,`, or `=` |
lhsExpression | expression | The operand on the left-hand side of the operator |
rhsExpression | expression | The operand on the right-hand side of the operator |
isImplicit | bool | true if the operator is implicit |
Inherits properties from:
When pattern matching, be aware that either or both operands of a binary operator can themselves be binary operators that represent operations to be completed before the matched operation is performed.
For example, a + b * c is understood as a + (b * c) due to operator precedence. This is matched as a binary addition that has a right-hand operand of b * c. The value of the subexpression must be computed before the addition is performed.
On the other hand, (a + b) * c is matched as a binary multiplication. The left-hand operand, a + b, must be computed before it is multiplied by c.
The following illustration shows these two situations:
In both these cases, a binaryOperator { .operand == `*` } pattern matches some part of the expression. In the left-hand case, it matches b * c. In the right-hand case, it matches the entire expression.
In the following snippet, an unconstrained binaryOperator matches all binary operations, including 2*a + 3 (the addition operation, where the left-hand side is a binary operation), 2*a (multiplication), and a & c (logical AND).
You can refine the binaryOperator pattern to match only specific operations. For example, the following pattern:
... matches only multiplication (the instance 2*a in the example above), and the following pattern:
... matches only addition.
Patterns can be compositions of separate sub-patterns, in order to match a more complicated expression; for example, to match the addition of a product of two terms with another term, you could use a pattern such as the following:
The previous pattern only detects when the multiplication happens on the left-hand side of the addition: 2*a + 3 matches, but 3 + 2*a does not. To generalize the pattern so it matches either variation, use the following code:
This uses the alternative ( | ) operator to say the pattern can match either multiplication on the left-hand side or the right-hand side.
However, this new pattern matches multiplication on one side, the other, or both; for example, it would also match this code:
... where multiplication occurs on both sides of the addition. If you want to match multiplication on one side only, revise the pattern to impose that constraint.
Matches all C and C++ type casts. These includes C-style casts (explicit), implicit type conversions, and the C++ operations static_cast, dynamic_cast, reinterpret_cast, and const_cast.
This pattern only matches nodes of type expression.
castOperator produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
operandExpression | expression | The expression being cast |
kind | enum castKind | `explicit`, `implicit`, `static`, `dynamic`, `reinterpret`, or `const`; see castKind |
The .type property, common to all expression nodes, indicates the type the operand is being cast to. The type of the expression being cast is determined by .operandExpression.type. In other words, this pattern represents a cast from .operandExpression.type to .type.
Inherits properties from:
Consider the following code:
The castOperator pattern matches the implicit cast on the second line, where the integer i needs to be converted to floating point so it can be assigned to f. In this example, the .kind property is `implicit`.
The following pattem shows how to match any implicit cast from an integer type to a floating-point type:
Matches only C++ constant casts (const_cast<A>( p )).
This pattern is equivalent to using castOperator with the .kind property set to `const`.
This pattern only matches nodes of type expression.
castOperatorConstCast produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
operandExpression | expression | The expression being cast |
kind | enum castKind | `const`; see castKind see castKind |
The .type property, common to all expression nodes, indicates the type the operand is being cast to. The type of the expression being cast is determined by .operandExpression.type. In other words, this pattern represents a cast from .operandExpression.type to .type.
Inherits properties from:
The castOperatorConstCast matches the following source code:
The following pattern matches constant casts from the integer type:
Matches only C++ dynamic casts (dynamic_cast<A>( p )).
This pattern is equivalent to using castOperator with the .kind property set to `dynamic`.
This pattern only matches nodes of type expression.
castOperatorDynamicCast produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
operandExpression | expression | The expression being cast |
kind | enum castKind | `dynamic`; see castKind |
The .type property, common to all expression nodes, indicates the type the operand is being cast to. The type of the expression being cast is determined by .operandExpression.type. In other words, this pattern represents a cast from .operandExpression.type to .type.
Inherits properties from:
The castOperatorDynamicCast pattern matches the cast present in following source code:
The following pattern matches dynamic casts from the class named A:
Matches only explicit C-style casts.
This pattern is equivalent to using castOperator with the .kind property set to `explicit`.
This pattern only matches nodes of type expression.
castOperatorExplicit produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
operandExpression | expression | The expression being cast |
kind | enum castKind | `explicit`; see castKind |
The .type property, common to all expression nodes, indicates the type the operand is being cast to. The type of the expression being cast is determined by .operandExpression.type. In other words, this pattern represents a cast from .operandExpression.type to .type.
Inherits properties from:
To match an explicit cast from the int type, you could use the following pattern:
Matches only implicit type conversions. That is, places where a type conversion occurs but is not explicitly specified in the source code.
This pattern is equivalent to using castOperator with the .kind property set to `implicit`.
This pattern only matches nodes of type expression.
castOperatorImplicit produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
operandExpression | expression | The expression being cast |
kind | enum castKind | `implicit`; see castKind |
The .type property, common to all expression nodes, indicates the type the operand is being cast to. The type of the expression being cast is determined by .operandExpression.type. In other words, this pattern represents a cast from .operandExpression.type to .type.
Inherits properties from:
To match an implicit cast from the int type, you could use the following pattern:
Matches only C++ reinterpret casts (reinterpret_cast<A>( p )).
This pattern is equivalent to using castOperator with the .kind property set to `reinterpret`.
This pattern only matches nodes of type expression.
castOperatorReinterpretCast produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
operandExpression | expression | The expression being cast |
kind | enum castKind | `reinterpret`; see castKind |
The .type property, common to all expression nodes, indicates the type the operand is being cast to. The type of the expression being cast is determined by .operandExpression.type. In other words, this pattern represents a cast from .operandExpression.type to .type.
Inherits properties from:
The castOperatorReinterpretCast matches the following source code:
The following pattern matches reinterpret casts from the class named A:
Matches only C++ static casts (static_cast<A>( p )).
This pattern is equivalent to using castOperator with the .kind property set to `static`.
This pattern only matches nodes of type expression.
castOperatorStaticCast produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
operandExpression | expression | The expression being cast |
kind | enum castKind | `static`; see castKind |
The .type property, common to all expression nodes, indicates the type the operand is being cast to. The type of the expression being cast is determined by .operandExpression.type. In other words, this pattern represents a cast from .operandExpression.type to .type.
Inherits properties from:
The castOperatorStaticCast matches the following source code:
To match static casts from integers, you could use the following pattern:
Matches the conditional operator (sometimes called the “ternary” operator) ?:.
This pattern only matches nodes of type expression.
conditionalOperator produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
conditionExpression | expression | The condition: the expression before the question mark |
trueExpression | expression | The expression to evaluate if the condition is true: the expression between the question mark and the colon |
falseExpression | expression | The expression to evaluate if the condition is false: the expression after the colon |
Inherits properties from:
The conditionalOperator matches the following source code:
In the preceding code, the property .conditionExpression is set to the condition x > 0. The x and -x outcomes correspond to the trueExpression and falseExpression, respectively.
The following pattern matches any operator that uses a binary operator as its condition:
Matches the decrement operators, detecting both prefix (as in --i) and postfix (i--) variants.
This pattern only matches nodes of type expression.
decrementOperator produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
operandExpression | expression | The expression being decremented |
kind | enum | `prefix` or `postfix` |
Inherits properties from:
The decrementOperator pattern matches the instance on both lines of the following source code:
In both instances, .operandExpression refers to the variable m. The .kind property is `postfix` in the first instance and `prefix` in the second.
The following pattern matches any postfix decrement operator:
Matches the C++ delete operator.
This pattern only matches nodes of type expression.
deleteOperator produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
isArray | bool | true if this instance represents the array delete[] rather than the scalar delete operator. |
operandExpression | expression | The expression (typically a variable) being deleted |
hasGlobalScopeModifier | bool | true if :: precedes delete (specifying global scope) |
operatorDeleteFunction | functionSymbol | The function operator delete |
Inherits properties from:
The deleteOperator matches the following source code:
In this instance, .isArray is false because the scalar version of delete was used. The .operandExpression refers to myPtr.
The following pattern matches any delete operator for an integer pointer:
Matches the increment operators, detecting both prefix (as in ++i) and postfix (i++) variants.
This pattern only matches nodes of type expression.
incrementOperator produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
operandExpression | expression | The expression being incremented |
kind | enum | `prefix` or `postfix` |
Inherits properties from:
The incrementOperator pattern matches both of the following two lines.
In both instances, .operandExpression refers to the variable m. The .kind property is `postfix` in the first instance and `prefix` in the second.
The following custom pattern detects when post-incrementation is used in the update statement of a for loop:
In particular, the forLoopPostIncrement pattern matches the following code,
... but it does not match the comparable pre-incrementation:
Matches the C++ new operator.
This pattern only matches nodes of type expression.
newOperator produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
operandType | type | The type being requested |
operatorDeleteFunction | functionSymbol? | The function operator delete (if there is a chance the constructor might throw); null if there is no such operator |
operatorNewFunction | functionSymbol | The function operator new |
placementArguments | list<expression>? | Argument to placement new; size is not included; null if there are no arguments |
arraySizeExpression | expression? | For array creation, the size of the array; null if the size is not specified |
hasGlobalScopeModifier | bool | true if :: precedes new (specifying global scope) |
initializer | initializer? | The expression evaluated to determine the initial value; null if the array is not initialized. For an array new, repeat this argument for each element. |
Inherits properties from:
The newOperator matches source code such as the following:
In this case, the .operandType is an int (which can be matched by the intType pattern) and the .hasGlobalScopeModifier is true.
The following pattern matches uses of the ::new operator (that is, with the global scope modifier ::):
Matches instances of the sizeof() operator, regardless of whether the operand is an expression or a type.
See also sizeofOperatorExpression and sizeofOperatorType.
This pattern only matches nodes of type expression.
sizeofOperator produces a record that contains the following property:
Name | Type | Description |
---|---|---|
kind | enum sizeofKind | `sizeofExpression` or `sizeofType`; see sizeofKind |
Inherits properties from:
Matches the C++ throw expression.
throwOperator produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
operandexpression | expression? | The expression to be thrown by this operator; null if an object is not specified |
Inherits properties from:
The throwOperator matches both of the following lines of code:
In the former case, .operandExpression refers to e; in the latter case, .operandExpression is null.
As part of memory ownership assignment, some development environments always require pointers to be thrown, while others never do. A checker that enforces either of these conventions might use the following pattern:
Conversely, to find instances where throw doesn’t use new, the following pattern would be useful:
Matches unary operators—those operators that have only one operand.
This pattern only matches nodes of type expression.
unaryOperator produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
operator | enum | Can be one of: `+`, `-`, `!`, or `~`. |
operandExpression | expression | The expression being operated on |
Inherits properties from:
The unaryOperator pattern matches source code such as this:
In the first instance, the .operator is `-` and in the second, the .operator is `!`.
Patterns in this section belong to the initializer class—or the ctorinit class, in the case of the constructor initializer. They match initializers in the target code.
In many cases, an initializer can look the same as an assigment statement. However, many languages treat initialization as its own, special case. The CodeXM language libraries treat initialization in this way, as well.
Matches expressions used to initialize aggregate types such as structs or arrays.
aggregateInitializer produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
hasExplicitBraces | bool | Whether the initializer is enclosed by braces ( {} ) in the source |
semanticIinitializerList | list<initializer> | The list of initializers used to initialize the subobjects of the aggregate type |
syntacticInitializerList | list<initializer> | The list of initializers used to initialize the subobjects of the aggregate type (at the syntactic level of a source program) |
tailInitializer | initializer? | A tail initializer used to initialize the remaining objects of an aggregate, if one exists; null if there is no tail initializer |
Inherits properties from:
The following code matches aggregateInitializer:
Both .semanticIinitializerList and .syntacticIinitializerList contain two elements, which are expressionInitializer { .expression == intLiteral }. (In most cases no semantic and syntactic initializers are similar.) The .tailInitializer is a zero initializer, indicating the initializer that the compiler provides to fill out the initialization.
A similar aggregate initializer of a struct:
This following pattern matches an aggregate initializer with exactly three elements:
Matches cases where a class constructor (C++ only) is used to initialize an object
constructorInitializer produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
constructorFunction | functionType | The constructor function called to initialize the object |
arguments | list<initializer> | A list of the arguments passed to the constructor |
Inherits properties from:
The constructorInitializer pattern matches the following code:
... such that the .arguments list holds a single argument (for example, 0) for the first instance and an empty list for the second.
Here is a pattern that matches a constructor that has no arguments:
Matches simple expressions used to initialize scalar objects.
expressionInitializer produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
expression | expression | The expression that evaluates to a value used to initialize the object |
Inherits properties from:
In the following code:
... expressionInitializer matches the right-hand-side of the initialization and captures it via the property .expression.
The unqualified pattern matches any initializer. To match a specific type of initializer—for example, the type of initializer represented by the binary operator (as in the example above)—you could use the following pattern:
Matches union field initializers.
unionFieldInitializer produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
field | fieldSymbol | The field in the union being initialized |
initializer | initializer | The initializer for this field |
Inherits properties from:
Given the following declaration:
... the unionFieldInitializer pattern matches the following code, such that the .field property refers to i, whereas the .initializer property is expressionInitializer:
The following pattern matches a union initialized using int only; that is, it matches the initializer { i: 0 } but does not match { f: 0.0 }:
Matches setting the initial value of an object to zero in the following cases:
This pattern does not expose any new properties.
Inherits properties from:
The following pattern:
... matches the right-hand-sides of the declarations shown in the following source code:
These patterns match symbols in the target code.
A symbol is an entity that can have an identifier; for example, a symbol might be a variable, a function, or a field in a record.
In Coverity Analysis, each symbol in a program is its own node in the abstract syntax tree, and is distinct from the identifier that represents it in the source.
In addition to the properties that are specific to each pattern, all symbol patterns have the following properties in common:
Name | Type | Description |
---|---|---|
identifier | string? | The string used as an unqualified name for the symbol; null if there is none |
mangledName | string? | The internal “mangled” name used for the symbol (the mangled name includes type and scope information, to disambiguate this instance of the identifier); null if the mangled name is not available |
location | sourceloc | The location where this symbol was declared |
type | type | The C/C++ type declared for this symbol |
access | enum AccessKeyword | The scoping keywords associated with the symbol, such as `public` or `private` |
is_file_or_readonly | bool | true if the symbol has a final specifier (applies only to C++ source) |
scopeList | list<string> | A list of the class names and namespaces that enclose the symbol |
Matches enumeration (enum) values.
This pattern only matches nodes of type symbol.
The .ownerEnumType property lists all possible values of the enumeration.
enumeratorSymbol produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
isExplicit | bool | true if the enumeration value is declared explicitly. |
ownerEnumType | record[type] | Enumerates the identifiers declared in the enum base type |
value | int | The value of this particular instance of a member of the enum |
Inherits properties from:
Given the following sample of source code:
... the following CodeXM fragment would match the non-explicit value represented by specMem:
Matches fields of a class (C++ only), struct, or union.
fieldSymbol produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
access | enum | The access kind of the field; can be `AK_NONE`, `fileprivate`, `internal`, `open`, `private`, `protected`, `protected internal`, `protected private`, or `public` |
isBitField | bool | true if the field is declared as a bit-field |
isSignedBitField | bool | true if the field is declared as a signed bit-field |
hasInitializer | bool | true if the field has an initializer in its declaration |
isAnonymous | bool | true if the bit-field was declared without a name |
bitWidth | int | The bit-width of the field |
offset | int | The offset from the start of the struct |
bitOffset | int | The bit-offset from the start of the struct |
isClassStatic | bool | true if the field is within a static class member |
isExplicitLambdaCapture | bool | true if the field is an explicit capture in a lambda expression |
isVolatile | bool | true if the field is within an object declared with the volatile specifier |
isAlignmentAssigned | bool | true if the variable is aligned |
alignmentInBytes | int? | The alignment of the type, in bytes; null if the type is not aligned |
Inherits properties from:
Given the following source-code declaration:
... the fieldSymbol pattern matches field m of the struct t in the following code snippet:
The following example shows one way to express the pattern:
Matches functions.
A function definition and a call to that function each have their own functionSymbol node. The node contains essential information about the function.
This pattern only matches nodes of type symbol.
functionSymbol produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
explicitParameterCount | int | The number of parameters explicitly declared for this function |
functionType | record[type] | The type of the function; see functionType |
hasThis | bool | (C++) true if the function is a class member method and it is a non-static and unfriended one |
isCUDAGlobal | bool | true if the function is declared as a CUDA __global__ function |
isCompilerGenerated | bool | true if the function is generated by the compiler |
isConstMethod | bool | (C++) true if the function is a const class member method that has been qualified with a const keyword at its end |
isConstexpr | bool | (C++ since C++11) true if the variable was declared as a constexpr |
isConstructor | bool | (C++) true if this function is a constructor of a class |
isDefaulted | bool | (C++) true if this is a special member function that is explicitly or implicitly defaulted |
isDeleted | bool | (C++) true if this is a special member function that is explicitly or implicitly deleted |
isDestructor | bool | (C++) true if this function is a destructor of a class |
isExplicitConstructor | bool | (C++) true if this function is a constructor declared with the keyword explicit |
isExplicitlyDefaulted | bool | (C++) true if this is a special member function that is explicitly defaulted using = default |
isExplicitlyDeleted | bool | (C++) true if this is a special member function that is explicitly deleted using = delete |
isInline | bool | true if this function is inline |
isNonstaticMethod | bool | (C++) true if this function is a non-static class member method |
isOverride | bool | true if this function overrides another function |
isPureVirtual | bool | true if this function is a pure virtual function |
isStaticMethod | bool | (C++) true if this function is a static class member method |
isStaticScope | bool | true if this function is a static function that is not a member |
isTemplate | bool | (C++) true if this function is a template function |
isTemplateOrInTemplateClass | bool | (C++) true if this function is a template function or it is a member method of a template class |
isTrailingReturnType | bool | (C++) true if this function uses a trailing return specifier |
isVirtual | bool | (C++) true if the function is virtual |
methodQualifierList | enum qualifierEnum | Enumerates the qualifiers with which this function was declared; can include `_Atomic`, `const`, `restrict`, and `volatile`; see qualifierEnum |
specialMethodKind | enum | (C++) Specifies the special member kind of this function; can be `None`, `DefaultConstructor`, `CopyConstructor`, `MoveConstructor`, `Constructor`, `CopyAssignment`, `MoveAssignment`, or `Destructor` |
Inherits properties from:
Given the following source-code snippet:
... the following pattern would match the call to foo():
Matches uses of global variables.
globalVariableSymbol produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
hasImplicitSize | bool | true if the variable is an array with an implicit size; for example, int a[] = {1, 2, 3} |
isFunctionStatic | bool | true if the variable is a static variable in a function |
isVolatile | bool | true if the variable was declared with the volatile specifier |
isClassStatic | bool | true if the variable is a static class member |
isConstexpr | bool | (C++) true if the variable was declared as a constexpr |
isCUDAConstant | bool | true if the variable is declared as a CUDA __constant__ |
isCUDAManaged | bool | true if the variable is declared as a CUDA __managed__ variable |
isCUDAShared | bool | true if the variable is declared as a CUDA __shared__ variable |
isAlignmentAssigned | bool | true if the variable is aligned |
alignmentInBytes | int? | The alignment of the type, in bytes; null if the type is not aligned |
Inherits properties from:
The globalVariableSymbol pattern matches variable a in the following code snippet, provided the property .identifier specifies "a":
The following expression matches a in the preceding source code:
The following code, relying on pattern decomposition, accomplishes the same thing:
Matches uses of local variables.
localVariableSymbol produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
hasImplicitSize | bool | true if the variable is an array with an implicit size; for example, int a[] = {1, 2, 3} |
isVolatile | bool | true if the variable was declared with the volatile specifier |
isRegister | bool | true if the variable was declared with the register specifier |
isCUDAConstant | bool | true if the variable is declared as a CUDA __constant__ |
isCUDAManaged | bool | true if the variable is declared as a CUDA __managed__ variable |
isCUDAShared | bool | true if the variable is declared as a CUDA __shared__ variable |
isAlignmentAssigned | bool | true if the variable is aligned |
alignmentInBytes | int? | The alignment of the type, in bytes; null if the type is not aligned |
Inherits properties from:
The localVariableSymbol pattern matches variable a in the following code snippet, provided the property .identifier specifies "a":
The following pattern limits the more general variableReference to match only local variables:
Matches uses of named parameters in function definitions.
parameterSymbol produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
position | int | The position in the parameter list |
isThis | bool | true if the symbol is the this pointer (applies only to C++ source) |
isArray | bool | true if this parameter was declared as an array with brackets and a minimum size |
arrayType | arrayType? | If the parameter was declared as an array, this property names the associated array type; null if the parameter is not an array |
isStaticSizeArray | bool | true if the keyword static was used when specifying the array size (does not apply if the parameter is not an array) |
declaredType | type | The parameter type as it appears in the function declaration, before dereferencing. In particular, this property can include array types. |
Inherits properties from:
The parameterSymbol pattern matches variable a in the following snippet, provided the .identifier property specifies "a":
The following pattern limits the more general variableReference to match only parameters:
Matches uses of variables, including both global and local variables.
This pattern only matches nodes of type symbol.
variableSymbol produces a record that contains the following properties:
Name | Type | Description |
---|---|---|
scope | enum variableScopeEnum | The scope of the variable: either `local` or `global`; see variableScopeEnum |
hasImplicitSize | bool | true if the variable is an array with an implicit size; for example, int a[] = {1, 2, 3} |
isFunctionStatic | bool | true if the variable is a static variable in a function |
isVolatile | bool | true if the variable was declared with the volatile specifier |
isClassStatic | bool | true if the variable is a static class member |
isConstexpr | bool | (C++ since C++11) true if the variable was declared as a constexpr |
isCUDAConstant | bool | true if the variable is declared as a CUDA __constant__ |
isCUDAManaged | bool | true if the variable is declared as a CUDA __managed__ variable |
isCUDAShared | bool | true if the variable is declared as a CUDA __shared__ variable |
isAlignmentAssigned | bool | true if the variable is aligned |
alignmentInBytes | int? | The alignment of the type, in bytes; null if the type is not aligned |
Inherits properties from:
globalVariableSymbol, lovalVariableSymbol
The C/C++ library provides a number of functions to help you handle, and analyze, the target source code.
See the Common Library Reference for descriptions of some general-purpose functions that are available to all language libraries.
Definition functions retrieve class and enum definitions.
Gets a classDefinition from the specified classType.
Name | Type | Description |
---|---|---|
classTypeResult | classType | The classType of a specific class |
return value | classDefinition? | The loaded definition of the specified class type; null if none exists |
Gets an enumDefinition from the specified enumType.
Name | Type | Description |
---|---|---|
enumTypeResult | enumType | The enumType of a specific enum |
return value | enumDefinition? | The loaded definition of the specified enum type; null if none exists |
Pattern functions return patterns that you can use in your CodeXM searches, just as you use patterns provided by the language library.
Returns a pattern that matches the type specified by typePattern. The pattern will also match declarations that eventually resolve to typePattern.
Name | Type | Description |
---|---|---|
typePattern | pattern | The type to match |
return value | pattern | Pattern to match type and its aliases |
Given the following code snippet:
... the pattern returned by aliasTypeOf(intType) will match x, because the type bar is an alias for int.
Here is a sample pattern to perform this match:
Returns a pattern that matches a type (specified by typePattern) provided the type is qualified by const, restrict (C++), or volatile. The pattern will also match qualified declarations that eventually resolve to typePattern.
Name | Type | Description |
---|---|---|
typePattern | pattern | The type to match |
return value | pattern | Pattern to match type when it is qualified |
Given the following code:
... the pattern that anyQualifiedTypeOf(intType) returns will match line (1), because this line declares an integer qualified by const. The pattern will not match line (2), because this line declares a pointer, not an integer.
Here is a sample pattern to perform this match:
Returns a pattern that matches an array of the type specified by typePattern. The pattern will also match arrays of types that eventually resolve to typePattern.
Name | Type | Description |
---|---|---|
typePattern | pattern | The type to match |
return value | pattern | Pattern to match an array of type |
Given the following code snippet:
... the pattern returned by arrayOf(intType) will match x, because x is an array of elements of type foo, and foo is in turn an alias for int.
Here is a sample pattern to perform this match:
Returns a pattern that matches a type (specified by typePattern), provided the type is declared to be const. The pattern will also match declarations that eventually resolve to typePattern.
Name | Type | Description |
---|---|---|
typePattern | pattern | The type to match |
return value | pattern | Pattern to match constants of type |
Given the following code snippet:
... the pattern returned by constOf(intType) will match x, because x is of type foo, and foo is an alias for const int.
Here is a sample pattern to perform this match:
Returns a pattern that matches a pointer to the type specified by typePattern. The pattern will also match pointers to types that eventually resolve to typePattern.
Name | Type | Description |
---|---|---|
typePattern | pattern | The type to match when it is pointed to |
return value | pattern | Pattern to match a pointer to type |
Given the following code snippet:
... the pattern returned by pointerTo(intType) will match x, because x points to the type foo, and foo is an alias for int.
Here is a sample pattern to perform this match:
Returns a pattern that matches a type (specified by typePattern), provided the type is declared to be volatile. The pattern will also match declarations that eventually resolve to typePattern.
Name | Type | Description |
---|---|---|
typePattern | pattern | The type to match |
return value | pattern | Pattern to match volatile instances of type |
Given the following code snippet
... the pattern returned by volatileOf(intType) will match x, because x is of type foo, and foo is an alias for volatile int.
Here is a sample pattern to perform this match:
Type functions handle elaborated types.
For pointerType, arrayType, typeQualifier, typedefType, or deducedType, returns the base type of these types; that is, the type a pointer points to, the type contained in an array, and so on.
This function is applied recursively, so that like the pattern functions, it can resolve declarations that resolve to typeName.
Name | Type | Description |
---|---|---|
typeName | type | The type to match |
return value | type | The base type without pointers, arrays, or qualifiers |
The following code defines the integer type sideLength, and then declares a pointer to the new type:
The following pattern uses hasBaseType() to check whether the type passed in (ty) resolves to an integer. It would match the sample above.
The hasBaseType() function can also check whether two types are the same, as in the following function declaration shows:
Decomposing functions deal explicitly with managing casts and qualifiers.
Returns a set that contains the qualifiers on a type.
Name | Type | Description |
---|---|---|
typeName | type | The type to match |
return value | set<qualifiers> | A set whose members represent the qualifiers applied to the type |
Given the following code snippet:
The following pattern would detect the volatile qualifier:
Returns a list of the qualifiers on a type.
The return type is list<qualifierEnum>.
This source code sample has declarations that are qualified:
You could use the following pattern to detect the `volatile` qualifier:
Strips an outermost cast, if present, to return the underlying expression.
If the expression consists of subexpressions that themselves are being cast, those casts are also stripped.
Name | Type | Description |
---|---|---|
expressionString | expression | The expression to strip casts from |
return value | expression | The expression without casts |
Given the following source code:
... the following pattern uses stripCasts() to match *a:
Returns the base type that is wrapped by typeQualifier, typedefType, or deducedType.
This is different from hasBaseType(), as it does not strip pointerType or arrayType.
Name | Type | Description |
---|---|---|
typeName | type | The type to match |
return value | type | The base type without qualifiers |
To strip qualifiers on a specific type, to any depth, you might define a pattern such as the following: