DragonFly On-Line Manual Pages
EXTRACLANGTOOLS(1) Extra Clang Tools EXTRACLANGTOOLS(1)
NAME
extraclangtools - Extra Clang Tools Documentation
Welcome to the clang-tools-extra project which contains extra tools
built using Clangas tooling APIas.
EXTRA CLANG TOOLS 4.0.0 RELEASE NOTES
o Introduction
o What^<i>as New in Extra Clang Tools 4.0.0?
o Improvements to clang-tidy
o Improvements to include-fixer
Written by the LLVM Team
Introduction
This document contains the release notes for the Extra Clang Tools,
part of the Clang release 4.0.0. Here we describe the status of the
Extra Clang Tools in some detail, including major improvements from the
previous release and new feature work. All LLVM releases may be down-
loaded from the LLVM releases web site.
For more information about Clang or LLVM, including information about
the latest release, please see the Clang Web Site or the LLVM Web Site.
What^s New in Extra Clang Tools 4.0.0?
Some of the major new features and improvements to Extra Clang Tools
are listed here.
Improvements to clang-tidy
o New cppcoreguidelines-slicing check
Flags slicing of member variables or vtable.
o New cppcoreguidelines-special-member-functions check
Flags classes where some, but not all, special member functions are
user-defined.
o The UseCERTSemantics option for the misc-move-constructor-init check
has been removed as it duplicated the modernize-pass-by-value check.
o New misc-move-forwarding-reference check
Warns when std::move is applied to a forwarding reference instead of
std::forward.
o misc-pointer-and-integral-operation check was removed.
o New misc-string-compare check
Warns about using compare to test for string equality or inequality.
o New misc-use-after-move check
Warns if an object is used after it has been moved, without an inter-
vening reinitialization.
o New cppcoreguidelines-no-malloc check warns if C-style memory manage-
ment is used and suggests the use of RAII.
o modernize-make-unique and modernize-make-shared now handle calls to
the smart pointeras reset() method.
o The modernize-pass-by-value check now has a ValuesOnly option to only
warn about parameters that are passed by value but not moved.
o The modernize-use-auto check now warns about variable declarations
that are initialized with a cast, or by calling a templated function
that behaves as a cast.
o The modernize-use-default check has been renamed to
modernize-use-equals-default.
o New modernize-use-default-member-init check
Converts a default constructoras member initializers into default
member initializers. Removes member initializers that are the same
as a default member initializer.
o New modernize-use-equals-delete check
Adds = delete to unimplemented private special member functions.
o New modernize-use-transparent-functors check
Replaces uses of non-transparent functors with transparent ones where
applicable.
o New mpi-buffer-deref check
Flags buffers which are insufficiently dereferenced when passed to an
MPI function call.
o New mpi-type-mismatch check
Flags MPI function calls with a buffer type and MPI data type mis-
match.
o New performance-inefficient-string-concatenation check
Warns about the performance overhead arising from concatenating
strings using the operator+, instead of operator+=.
o New performance-type-promotion-in-math-fn check
Replaces uses of C-style standard math functions with double parame-
ters and float arguments with an equivalent function that takes a
float parameter.
o readability-container-size-empty check supports arbitrary containers
with with suitable empty() and size() methods.
o New readability-misplaced-array-index check
Warns when there is array index before the [] instead of inside it.
o New readability-non-const-parameter check
Flags function parameters of a pointer type that could be changed to
point to a constant type instead.
o New readability-redundant-declaration check
Finds redundant variable and function declarations.
o New readability-redundant-function-ptr-dereference check
Finds redundant function pointer dereferences.
o New readability-redundant-member-init check
Flags member initializations that are unnecessary because the same
default constructor would be called if they were not present.
o The readability-redundant-string-cstr check now warns about redundant
calls to data() too.
o The google-explicit-constructor check now warns about conversion
operators not marked explicit.
Fixed bugs:
o modernize-make-unique and modernize-make-shared Calling
make_{unique|shared} from within a member function of a type with a
private or protected constructor would be ill-formed.
Improvements to include-fixer
o Emacs integration was added.
CLANG-TIDY
Contents
o Clang-Tidy
o Using clang-tidy
o Getting Involved
o Choosing the Right Place for your Check
o Preparing your Workspace
o The Directory Structure
o Writing a clang-tidy Check
o Registering your Check
o Configuring Checks
o Testing Checks
o Running clang-tidy on LLVM
See also:
Clang-Tidy Checks
boost-use-to-string
This check finds conversion from integer type like int to std::string
or std::wstring using boost::lexical_cast, and replace it with calls to
std::to_string and std::to_wstring.
It doesnat replace conversion from floating points despite the
to_string overloads, because it would change the behaviour.
auto str = boost::lexical_cast<std::string>(42);
auto wstr = boost::lexical_cast<std::wstring>(2137LL);
// Will be changed to
auto str = std::to_string(42);
auto wstr = std::to_wstring(2137LL);
cert-dcl03-c
The cert-dcl03-c check is an alias, please see misc-static-assert for
more information.
cert-dcl50-cpp
This check flags all function definitions (but not declarations) of
C-style variadic functions.
This check corresponds to the CERT C++ Coding Standard rule DCL50-CPP.
Do not define a C-style variadic function.
cert-dcl54-cpp
The cert-dcl54-cpp check is an alias, please see
misc-new-delete-overloads for more information.
cert-dcl59-cpp
The cert-dcl59-cpp check is an alias, please see
google-build-namespaces for more information.
cert-env33-c
This check flags calls to system(), popen(), and _popen(), which exe-
cute a command processor. It does not flag calls to system() with a
null pointer argument, as such a call checks for the presence of a com-
mand processor but does not actually attempt to execute a command.
This check corresponds to the CERT C Coding Standard rule ENV33-C. Do
not call system().
cert-err09-cpp
The cert-err09-cpp check is an alias, please see
misc-throw-by-value-catch-by-reference for more information.
cert-err34-c
This check flags calls to string-to-number conversion functions that do
not verify the validity of the conversion, such as atoi() or scanf().
It does not flag calls to strtol(), or other, related conversion func-
tions that do perform better error checking.
#include <stdlib.h>
void func(const char *buff) {
int si;
if (buff) {
si = atoi(buff); /* 'atoi' used to convert a string to an integer, but function will
not report conversion errors; consider using 'strtol' instead. */
} else {
/* Handle error */
}
}
This check corresponds to the CERT C Coding Standard rule ERR34-C.
Detect errors when converting a string to a number.
cert-err52-cpp
This check flags all call expressions involving setjmp() and longjmp().
This check corresponds to the CERT C++ Coding Standard rule ERR52-CPP.
Do not use setjmp() or longjmp().
cert-err58-cpp
This check flags all static or thread_local variable declarations where
the initializer for the object may throw an exception.
This check corresponds to the CERT C++ Coding Standard rule ERR58-CPP.
Handle all exceptions thrown before main() begins executing.
cert-err60-cpp
This check flags all throw expressions where the exception object is
not nothrow copy constructible.
This check corresponds to the CERT C++ Coding Standard rule ERR60-CPP.
Exception objects must be nothrow copy constructible.
cert-err61-cpp
The cert-err61-cpp check is an alias, please see
misc-throw-by-value-catch-by-reference for more information.
cert-fio38-c
The cert-fio38-c check is an alias, please see
misc-non-copyable-objects for more information.
cert-flp30-c
This check flags for loops where the induction expression has a float-
ing-point type.
This check corresponds to the CERT C Coding Standard rule FLP30-C. Do
not use floating-point variables as loop counters.
cert-msc30-c
The cert-msc30-c check is an alias, please see cert-msc50-cpp for more
information.
cert-msc50-cpp
Pseudorandom number generators use mathematical algorithms to produce a
sequence of numbers with good statistical properties, but the numbers
produced are not genuinely random. The std::rand() function takes a
seed (number), runs a mathematical operation on it and returns the
result. By manipulating the seed the result can be predictable. This
check warns for the usage of std::rand().
cert-oop11-cpp
The cert-oop11-cpp check is an alias, please see
misc-move-constructor-init for more information.
cppcoreguidelines-interfaces-global-init
This check flags initializers of globals that access extern objects,
and therefore can lead to order-of-initialization problems.
This rule is part of the aInterfacesa profile of the C++ Core Guide-
lines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Ri-global-init
Note that currently this does not flag calls to non-constexpr func-
tions, and therefore globals could still be accessed from functions
themselves.
cppcoreguidelines-no-malloc
This check handles C-Style memory management using malloc(), realloc(),
calloc() and free(). It warns about its use and tries to suggest the
use of an appropriate RAII object. See C++ Core Guidelines
<https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuide-
lines.md#Rr-mallocfree>.
There is no attempt made to provide fixit hints, since manual resource
management isnat easily transformed automatically into RAII.
// Warns each of the following lines.
// Containers like std::vector or std::string should be used.
char* some_string = (char*) malloc(sizeof(char) * 20);
char* some_string = (char*) realloc(sizeof(char) * 30);
free(some_string);
int* int_array = (int*) calloc(30, sizeof(int));
// Rather use a smartpointer or stack variable.
struct some_struct* s = (struct some_struct*) malloc(sizeof(struct some_struct));
cppcoreguidelines-pro-bounds-array-to-pointer-decay
This check flags all array to pointer decays.
Pointers should not be used as arrays. span<T> is a bounds-checked,
safe alternative to using pointers to access arrays.
This rule is part of the aBounds safetya profile of the C++ Core Guide-
lines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Pro-bounds-decay.
cppcoreguidelines-pro-bounds-constant-array-index
This check flags all array subscript expressions on static arrays and
std::arrays that either do not have a constant integer expression index
or are out of bounds (for std::array). For out-of-bounds checking of
static arrays, see the -Warray-bounds Clang diagnostic.
This rule is part of the aBounds safetya profile of the C++ Core Guide-
lines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Pro-bounds-arrayindex.
Options
GslHeader
The check can generate fixes after this option has been set to
the name of the include file that contains gsl::at(), e.g.
^<i>agsl/gsl.h^<i>a.
IncludeStyle
A string specifying which include-style is used, llvm or google.
Default is llvm.
cppcoreguidelines-pro-bounds-pointer-arithmetic
This check flags all usage of pointer arithmetic, because it could lead
to an invalid pointer. Subtraction of two pointers is not flagged by
this check.
Pointers should only refer to single objects, and pointer arithmetic is
fragile and easy to get wrong. span<T> is a bounds-checked, safe type
for accessing arrays of data.
This rule is part of the aBounds safetya profile of the C++ Core Guide-
lines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Pro-bounds-arithmetic.
cppcoreguidelines-pro-type-const-cast
This check flags all uses of const_cast in C++ code.
Modifying a variable that was declared const is undefined behavior,
even with const_cast.
This rule is part of the aType safetya profile of the C++ Core Guide-
lines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Pro-type-constcast.
cppcoreguidelines-pro-type-cstyle-cast
This check flags all use of C-style casts that perform a static_cast
downcast, const_cast, or reinterpret_cast.
Use of these casts can violate type safety and cause the program to
access a variable that is actually of type X to be accessed as if it
were of an unrelated type Z. Note that a C-style (T)expression cast
means to perform the first of the following that is possible: a
const_cast, a static_cast, a static_cast followed by a const_cast, a
reinterpret_cast, or a reinterpret_cast followed by a const_cast. This
rule bans (T)expression only when used to perform an unsafe cast.
This rule is part of the aType safetya profile of the C++ Core Guide-
lines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Pro-type-cstylecast.
cppcoreguidelines-pro-type-member-init
The check flags user-defined constructor definitions that do not ini-
tialize all fields that would be left in an undefined state by default
construction, e.g. builtins, pointers and record types without
user-provided default constructors containing at least one such type.
If these fields arenat initialized, the constructor will leave some of
the memory in an undefined state.
For C++11 it suggests fixes to add in-class field initializers. For
older versions it inserts the field initializers into the constructor
initializer list. It will also initialize any direct base classes that
need to be zeroed in the constructor initializer list.
The check takes assignment of fields in the constructor body into
account but generates false positives for fields initialized in methods
invoked in the constructor body.
The check also flags variables with automatic storage duration that
have record types without a user-provided constructor and are not ini-
tialized. The suggested fix is to zero initialize the variable via {}
for C++11 and beyond or = {} for older language versions.
Options
IgnoreArrays
If set to non-zero, the check will not warn about array members
that are not zero-initialized during construction. For perfor-
mance critical code, it may be important to not initialize
fixed-size array members. Default is 0.
This rule is part of the aType safetya profile of the C++ Core Guide-
lines, corresponding to rule Type.6. See
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Pro-type-memberinit.
cppcoreguidelines-pro-type-reinterpret-cast
This check flags all uses of reinterpret_cast in C++ code.
Use of these casts can violate type safety and cause the program to
access a variable that is actually of type X to be accessed as if it
were of an unrelated type Z.
This rule is part of the aType safetya profile of the C++ Core Guide-
lines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Pro-type-reinterpretcast.
cppcoreguidelines-pro-type-static-cast-downcast
This check flags all usages of static_cast, where a base class is
casted to a derived class. In those cases, a fixit is provided to con-
vert the cast to a dynamic_cast.
Use of these casts can violate type safety and cause the program to
access a variable that is actually of type X to be accessed as if it
were of an unrelated type Z.
This rule is part of the aType safetya profile of the C++ Core Guide-
lines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Pro-type-downcast.
cppcoreguidelines-pro-type-union-access
This check flags all access to members of unions. Passing unions as a
whole is not flagged.
Reading from a union member assumes that member was the last one writ-
ten, and writing to a union member assumes another member with a non-
trivial destructor had its destructor called. This is fragile because
it cannot generally be enforced to be safe in the language and so
relies on programmer discipline to get it right.
This rule is part of the aType safetya profile of the C++ Core Guide-
lines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Pro-type-unions.
cppcoreguidelines-pro-type-vararg
This check flags all calls to c-style vararg functions and all use of
va_arg.
To allow for SFINAE use of vararg functions, a call is not flagged if a
literal 0 is passed as the only vararg argument.
Passing to varargs assumes the correct type will be read. This is frag-
ile because it cannot generally be enforced to be safe in the language
and so relies on programmer discipline to get it right.
This rule is part of the aType safetya profile of the C++ Core Guide-
lines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Pro-type-varargs.
cppcoreguidelines-slicing
Flags slicing of member variables or vtable. Slicing happens when copy-
ing a derived object into a base object: the members of the derived
object (both member variables and virtual member functions) will be
discarded. This can be misleading especially for member function slic-
ing, for example:
struct B { int a; virtual int f(); };
struct D : B { int b; int f() override; };
void use(B b) { // Missing reference, intended?
b.f(); // Calls B::f.
}
D d;
use(d); // Slice.
See the relevant C++ Core Guidelines sections for details:
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es63-dont-slice
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c145-access-polymorphic-objects-through-pointers-and-references
cppcoreguidelines-special-member-functions
The check finds classes where some but not all of the special member
functions are defined.
By default the compiler defines a copy constructor, copy assignment
operator, move constructor, move assignment operator and destructor.
The default can be suppressed by explicit user-definitions. The rela-
tionship between which functions will be suppressed by definitions of
other functions is complicated and it is advised that all five are
defaulted or explicitly defined.
Note that defining a function with = delete is considered to be a defi-
nition.
This rule is part of the aConstructors, assignments, and destructorsa
profile of the C++ Core Guidelines, corresponding to rule C.21. See
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c21-if-you-define-or-delete-any-default-operation-define-or-delete-them-all.
google-build-explicit-make-pair
Check that make_pairas template arguments are deduced.
G++ 4.6 in C++11 mode fails badly if make_pairas template arguments are
specified explicitly, and such use isnat intended in any case.
Corresponding cpplint.py check name: build/explicit_make_pair.
google-build-namespaces
cert-dcl59-cpp redirects here as an alias for this check.
Finds anonymous namespaces in headers.
https://google.github.io/styleguide/cppguide.html#Namespaces
Corresponding cpplint.py check name: build/namespaces.
Options
HeaderFileExtensions
A comma-separated list of filename extensions of header files
(the filename extensions should not include a.a prefix). Default
is ah,hh,hpp,hxxa. For header files without an extension, use
an empty string (if there are no other desired extensions) or
leave an empty element in the list. e.g., ah,hh,hpp,hxx,a (note
the trailing comma).
google-build-using-namespace
Finds using namespace directives.
The check implements the following rule of the Google C++ Style Guide:
You may not use a using-directive to make all names from a namespace
available.
// Forbidden -- This pollutes the namespace.
using namespace foo;
Corresponding cpplint.py check name: build/namespaces.
google-default-arguments
Checks that default arguments are not given for virtual methods.
See https://google.github.io/styleguide/cppguide.html#Default_Arguments
google-explicit-constructor
Checks that constructors callable with a single argument and conversion
operators are marked explicit to avoid the risk of unintentional
implicit conversions.
Consider this example:
struct S {
int x;
operator bool() const { return true; }
};
bool f() {
S a{1};
S b{2};
return a == b;
}
The function will return true, since the objects are implicitly con-
verted to bool before comparison, which is unlikely to be the intent.
The check will suggest inserting explicit before the constructor or
conversion operator declaration. However, copy and move constructors
should not be explicit, as well as constructors taking a single ini-
tializer_list argument.
This code:
struct S {
S(int a);
explicit S(const S&);
operator bool() const;
...
will become
struct S {
explicit S(int a);
S(const S&);
explicit operator bool() const;
...
See
https://google.github.io/styleguide/cppguide.html#Explicit_Constructors
google-global-names-in-headers
Flag global namespace pollution in header files. Right now it only
triggers on using declarations and directives.
The relevant style guide section is
https://google.github.io/styleguide/cppguide.html#Namespaces.
Options
HeaderFileExtensions
A comma-separated list of filename extensions of header files
(the filename extensions should not contain a.a prefix). Default
is aha. For header files without an extension, use an empty
string (if there are no other desired extensions) or leave an
empty element in the list. e.g., ah,hh,hpp,hxx,a (note the
trailing comma).
google-readability-braces-around-statements
The google-readability-braces-around-statements check is an alias,
please see readability-braces-around-statements for more information.
google-readability-casting
Finds usages of C-style casts.
https://google.github.io/styleguide/cppguide.html#Casting
Corresponding cpplint.py check name: readability/casting.
This check is similar to -Wold-style-cast, but it suggests automated
fixes in some cases. The reported locations should not be different
from the ones generated by -Wold-style-cast.
google-readability-function-size
The google-readability-function-size check is an alias, please see
readability-function-size for more information.
google-readability-namespace-comments
The google-readability-namespace-comments check is an alias, please see
llvm-namespace-comment for more information.
google-readability-redundant-smartptr-get
The google-readability-redundant-smartptr-get check is an alias, please
see readability-redundant-smartptr-get for more information.
google-readability-todo
Finds TODO comments without a username or bug number.
The relevant style guide section is
https://google.github.io/styleguide/cppguide.html#TODO_Comments.
Corresponding cpplint.py check: readability/todo
google-runtime-int
Finds uses of short, long and long long and suggest replacing them with
u?intXX(_t)?.
The corresponding style guide rule:
https://google.github.io/styleguide/cppguide.html#Integer_Types.
Correspondig cpplint.py check: runtime/int.
Options
UnsignedTypePrefix
A string specifying the unsigned type prefix. Default is uint.
SignedTypePrefix
A string specifying the signed type prefix. Default is int.
TypeSuffix
A string specifying the type suffix. Default is an empty string.
google-runtime-member-string-references
Finds members of type const string&.
const string reference members are generally considered unsafe as they
can be created from a temporary quite easily.
struct S {
S(const string &Str) : Str(Str) {}
const string &Str;
};
S instance("string");
In the constructor call a string temporary is created from const char *
and destroyed immediately after the call. This leaves around a dangling
reference.
This check emit warnings for both std::string and ::string const refer-
ence members.
Corresponding cpplint.py check name: runtime/member_string_reference.
google-runtime-memset
Finds calls to memset with a literal zero in the length argument.
This is most likely unintended and the length and value arguments are
swapped.
Corresponding cpplint.py check name: runtime/memset.
google-runtime-operator
Finds overloads of unary operator &.
https://google.github.io/styleguide/cppguide.html#Operator_Overloading
Corresponding cpplint.py check name: runtime/operator.
google-runtime-references
Checks the usage of non-constant references in function parameters.
The corresponding style guide rule:
https://google.github.io/styleguide/cppguide.html#Reference_Arguments
Options
WhiteListTypes
A semicolon-separated list of names of whitelist types. Default
is empty.
llvm-header-guard
Finds and fixes header guards that do not adhere to LLVM style.
Options
HeaderFileExtensions
A comma-separated list of filename extensions of header files
(the filename extensions should not include a.a prefix). Default
is ah,hh,hpp,hxxa. For header files without an extension, use
an empty string (if there are no other desired extensions) or
leave an empty element in the list. e.g., ah,hh,hpp,hxx,a (note
the trailing comma).
llvm-include-order
Checks the correct order of #includes.
See http://llvm.org/docs/CodingStandards.html#include-style
llvm-namespace-comment
google-readability-namespace-comments redirects here as an alias for
this check.
Checks that long namespaces have a closing comment.
http://llvm.org/docs/CodingStandards.html#namespace-indentation
https://google.github.io/styleguide/cppguide.html#Namespaces
Options
ShortNamespaceLines
Requires the closing brace of the namespace definition to be
followed by a closing comment if the body of the namespace has
more than ShortNamespaceLines lines of code. The value is an
unsigned integer that defaults to 1U.
SpacesBeforeComments
An unsigned integer specifying the number of spaces before the
comment closing a namespace definition. Default is 1U.
llvm-twine-local
Looks for local Twine variables which are prone to use after frees and
should be generally avoided.
misc-argument-comment
Checks that argument comments match parameter names.
The check understands argument comments in the form /*parameter_name=*/
that are placed right before the argument.
void f(bool foo);
...
f(/*bar=*/true);
// warning: argument name 'bar' in comment does not match parameter name 'foo'
The check tries to detect typos and suggest automated fixes for them.
Options
StrictMode
When non-zero, the check will ignore leading and trailing under-
scores and case when comparing parameter names.
misc-assert-side-effect
Finds assert() with side effect.
The condition of assert() is evaluated only in debug builds so a condi-
tion with side effect can cause different behavior in debug / release
builds.
Options
AssertMacros
A comma-separated list of the names of assert macros to be
checked.
CheckFunctionCalls
Whether to treat non-const member and non-member functions as
they produce side effects. Disabled by default because it can
increase the number of false positive warnings.
misc-bool-pointer-implicit-conversion
Checks for conditions based on implicit conversion from a bool pointer
to bool.
Example:
bool *p;
if (p) {
// Never used in a pointer-specific way.
}
misc-dangling-handle
Detect dangling references in value handles like std::experimen-
tal::string_view. These dangling references can be a result of con-
structing handles from temporary values, where the temporary is
destroyed soon after the handle is created.
Examples:
string_view View = string(); // View will dangle.
string A;
View = A + "A"; // still dangle.
vector<string_view> V;
V.push_back(string()); // V[0] is dangling.
V.resize(3, string()); // V[1] and V[2] will also dangle.
string_view f() {
// All these return values will dangle.
return string();
string S;
return S;
char Array[10]{};
return Array;
}
Options
HandleClasses
A semicolon-separated list of class names that should be treated
as handles. By default only std::experimen-
tal::basic_string_view is considered.
misc-definitions-in-headers
Finds non-extern non-inline function and variable definitions in header
files, which can lead to potential ODR violations in case these headers
are included from multiple translation units.
// Foo.h
int a = 1; // Warning: variable definition.
extern int d; // OK: extern variable.
namespace N {
int e = 2; // Warning: variable definition.
}
// Warning: variable definition.
const char* str = "foo";
// OK: internal linkage variable definitions are ignored for now.
// Although these might also cause ODR violations, we can be less certain and
// should try to keep the false-positive rate down.
static int b = 1;
const int c = 1;
const char* const str2 = "foo";
// Warning: function definition.
int g() {
return 1;
}
// OK: inline function definition is allowed to be defined multiple times.
inline int e() {
return 1;
}
class A {
public:
int f1() { return 1; } // OK: implicitly inline member function definition is allowed.
int f2();
static int d;
};
// Warning: not an inline member function definition.
int A::f2() { return 1; }
// OK: class static data member declaration is allowed.
int A::d = 1;
// OK: function template is allowed.
template<typename T>
T f3() {
T a = 1;
return a;
}
// Warning: full specialization of a function template is not allowed.
template <>
int f3() {
int a = 1;
return a;
}
template <typename T>
struct B {
void f1();
};
// OK: member function definition of a class template is allowed.
template <typename T>
void B<T>::f1() {}
Options
HeaderFileExtensions
A comma-separated list of filename extensions of header files
(the filename extensions should not include a.a prefix). Default
is ah,hh,hpp,hxxa. For header files without an extension, use
an empty string (if there are no other desired extensions) or
leave an empty element in the list. e.g., ah,hh,hpp,hxx,a (note
the trailing comma).
UseHeaderFileExtension
When non-zero, the check will use the file extension to distin-
guish header files. Default is 1.
misc-fold-init-type
The check flags type mismatches in folds like std::accumulate that
might result in loss of precision. std::accumulate folds an input
range into an initial value using the type of the latter, with opera-
tor+ by default. This can cause loss of precision through:
o Truncation: The following code uses a floating point range and an int
initial value, so trucation wil happen at every application of opera-
tor+ and the result will be 0, which might not be what the user
expected.
auto a = {0.5f, 0.5f, 0.5f, 0.5f};
return std::accumulate(std::begin(a), std::end(a), 0);
o Overflow: The following code also returns 0.
auto a = {65536LL * 65536 * 65536};
return std::accumulate(std::begin(a), std::end(a), 0);
misc-forward-declaration-namespace
Checks if an unused forward declaration is in a wrong namespace.
The check inspects all unused forward declarations and checks if there
is any declaration/definition with the same name existing, which could
indicate that the forward declaration is in a potentially wrong names-
pace.
namespace na { struct A; }
namespace nb { struct A {}; }
nb::A a;
// warning : no definition found for 'A', but a definition with the same name
// 'A' found in another namespace 'nb::'
This check can only generate warnings, but it canat suggest a fix at
this point.
misc-inaccurate-erase
Checks for inaccurate use of the erase() method.
Algorithms like remove() do not actually remove any element from the
container but return an iterator to the first redundant element at the
end of the container. These redundant elements must be removed using
the erase() method. This check warns when not all of the elements will
be removed due to using an inappropriate overload.
misc-incorrect-roundings
Checks the usage of patterns known to produce incorrect rounding. Pro-
grammers often use:
(int)(double_expression + 0.5)
to round the double expression to an integer. The problem with this:
1. It is unnecessarily slow.
2. It is incorrect. The number 0.499999975 (smallest representable
float number below 0.5) rounds to 1.0. Even worse behavior for nega-
tive numbers where both -0.5f and -1.4f both round to 0.0.
misc-inefficient-algorithm
Warns on inefficient use of STL algorithms on associative containers.
Associative containers implements some of the algorithms as methods
which should be preferred to the algorithms in the algorithm header.
The methods can take advanatage of the order of the elements.
misc-macro-parentheses
Finds macros that can have unexpected behaviour due to missing paren-
theses.
Macros are expanded by the preprocessor as-is. As a result, there can
be unexpected behaviour; operators may be evaluated in unexpected order
and unary operators may become binary operators, etc.
When the replacement list has an expression, it is recommended to sur-
round it with parentheses. This ensures that the macro result is evalu-
ated completely before it is used.
It is also recommended to surround macro arguments in the replacement
list with parentheses. This ensures that the argument value is calcu-
lated properly.
misc-macro-repeated-side-effects
Checks for repeated argument with side effects in macros.
misc-misplaced-const
This check diagnoses when a const qualifier is applied to a typedef to
a pointer type rather than to the pointee, because such constructs are
often misleading to developers because the const applies to the pointer
rather than the pointee.
For instance, in the following code, the resulting type is int * const
rather than const int *:
typedef int *int_ptr;
void f(const int_ptr ptr);
The check does not diagnose when the underlying typedef type is a
pointer to a const type or a function pointer type. This is because the
const qualifier is less likely to be mistaken because it would be
redundant (or disallowed) on the underlying pointee type.
misc-misplaced-widening-cast
This check will warn when there is a cast of a calculation result to a
bigger type. If the intention of the cast is to avoid loss of precision
then the cast is misplaced, and there can be loss of precision. Other-
wise the cast is ineffective.
Example code:
long f(int x) {
return (long)(x * 1000);
}
The result x * 1000 is first calculated using int precision. If the
result exceeds int precision there is loss of precision. Then the
result is casted to long.
If there is no loss of precision then the cast can be removed or you
can explicitly cast to int instead.
If you want to avoid loss of precision then put the cast in a proper
location, for instance:
long f(int x) {
return (long)x * 1000;
}
Implicit casts
Forgetting to place the cast at all is at least as dangerous and at
least as common as misplacing it. If CheckImplicitCasts is enabled the
check also detects these cases, for instance:
long f(int x) {
return x * 1000;
}
Floating point
Currently warnings are only written for integer conversion. No warning
is written for this code:
double f(float x) {
return (double)(x * 10.0f);
}
Options
CheckImplicitCasts
If non-zero, enables detection of implicit casts. Default is
non-zero.
misc-move-const-arg
The check warns
o if std::move() is called with a constant argument,
o if std::move() is called with an argument of a trivially-copyable
type,
o if the result of std::move() is passed as a const reference argument.
In all three cases, the check will suggest a fix that removes the
std::move().
Here are examples of each of the three cases:
const string s;
return std::move(s); // Warning: std::move of the const variable has no effect
int x;
return std::move(x); // Warning: std::move of the variable of a trivially-copyable type has no effect
void f(const string &s);
string s;
f(std::move(s)); // Warning: passing result of std::move as a const reference argument; no move will actually happen
misc-move-constructor-init
acert-oop11-cppa redirects here as an alias for this check.
The check flags user-defined move constructors that have a ctor-ini-
tializer initializing a member or base class through a copy constructor
instead of a move constructor.
Options
IncludeStyle
A string specifying which include-style is used, llvm or google.
Default is llvm.
misc-move-forwarding-reference
Warns if std::move is called on a forwarding reference, for example:
template <typename T>
void foo(T&& t) {
bar(std::move(t));
}
Forwarding references should typically be passed to std::forward
instead of std::move, and this is the fix that will be suggested.
(A forwarding reference is an rvalue reference of a type that is a
deduced function template argument.)
In this example, the suggested fix would be
bar(std::forward<T>(t));
Background
Code like the example above is sometimes written with the expectation
that T&& will always end up being an rvalue reference, no matter what
type is deduced for T, and that it is therefore not possible to pass an
lvalue to foo(). However, this is not true. Consider this example:
std::string s = "Hello, world";
foo(s);
This code compiles and, after the call to foo(), s is left in an inde-
terminate state because it has been moved from. This may be surprising
to the caller of foo() because no std::move was used when calling
foo().
The reason for this behavior lies in the special rule for template
argument deduction on function templates like foo() a i.e. on function
templates that take an rvalue reference argument of a type that is a
deduced function template argument. (See section [temp.deduct.call]/3
in the C++11 standard.)
If foo() is called on an lvalue (as in the example above), then T is
deduced to be an lvalue reference. In the example, T is deduced to be
std::string &. The type of the argument t therefore becomes
std::string& &&; by the reference collapsing rules, this collapses to
std::string&.
This means that the foo(s) call passes s as an lvalue reference, and
foo() ends up moving s and thereby placing it into an indeterminate
state.
misc-multiple-statement-macro
Detect multiple statement macros that are used in unbraced condition-
als. Only the first statement of the macro will be inside the condi-
tional and the other ones will be executed unconditionally.
Example:
#define INCREMENT_TWO(x, y) (x)++; (y)++
if (do_increment)
INCREMENT_TWO(a, b); // (b)++ will be executed unconditionally.
misc-new-delete-overloads
cert-dcl54-cpp redirects here as an alias for this check.
The check flags overloaded operator new() and operator delete() func-
tions that do not have a corresponding free store function defined
within the same scope. For instance, the check will flag a class
implementation of a non-placement operator new() when the class does
not also define a non-placement operator delete() function as well.
The check does not flag implicitly-defined operators, deleted or pri-
vate operators, or placement operators.
This check corresponds to CERT C++ Coding Standard rule DCL54-CPP.
Overload allocation and deallocation functions as a pair in the same
scope.
misc-noexcept-move-constructor
The check flags user-defined move constructors and assignment operators
not marked with noexcept or marked with noexcept(expr) where expr eval-
uates to false (but is not a false literal itself).
Move constructors of all the types used with STL containers, for exam-
ple, need to be declared noexcept. Otherwise STL will choose copy con-
structors instead. The same is valid for move assignment operations.
misc-non-copyable-objects
cert-fio38-c redirects here as an alias for this check.
The check flags dereferences and non-pointer declarations of objects
that are not meant to be passed by value, such as C FILE objects or
POSIX pthread_mutex_t objects.
This check corresponds to CERT C++ Coding Standard rule FIO38-C. Do not
copy a FILE object.
misc-redundant-expression
Detect redundant expressions which are typically errors due to
copy-paste.
Depending on the operator expressions may be
o redundant,
o always be true,
o always be false,
o always be a constant (zero or one).
Example:
((x+1) | (x+1)) // (x+1) is redundant
(p->x == p->x) // always true
(p->x < p->x) // always false
(speed - speed + 1 == 12) // speed - speed is always zero
misc-sizeof-container
The check finds usages of sizeof on expressions of STL container types.
Most likely the user wanted to use .size() instead.
All class/struct types declared in namespace std:: having a const
size() method are considered containers, with the exception of
std::bitset and std::array.
Examples:
std::string s;
int a = 47 + sizeof(s); // warning: sizeof() doesn't return the size of the container. Did you mean .size()?
int b = sizeof(std::string); // no warning, probably intended.
std::string array_of_strings[10];
int c = sizeof(array_of_strings) / sizeof(array_of_strings[0]); // no warning, definitely intended.
std::array<int, 3> std_array;
int d = sizeof(std_array); // no warning, probably intended.
misc-sizeof-expression
The check finds usages of sizeof expressions which are most likely
errors.
The sizeof operator yields the size (in bytes) of its operand, which
may be an expression or the parenthesized name of a type. Misuse of
this operator may be leading to errors and possible software vulnera-
bilities.
Suspicious usage of ^sizeof(K)^
A common mistake is to query the sizeof of an integer literal. This is
equivalent to query the size of its type (probably int). The intent of
the programmer was probably to simply get the integer and not its size.
#define BUFLEN 42
char buf[BUFLEN];
memset(buf, 0, sizeof(BUFLEN)); // sizeof(42) ==> sizeof(int)
Suspicious usage of ^sizeof(this)^
The this keyword is evaluated to a pointer to an object of a given
type. The expression sizeof(this) is returning the size of a pointer.
The programmer most likely wanted the size of the object and not the
size of the pointer.
class Point {
[...]
size_t size() { return sizeof(this); } // should probably be sizeof(*this)
[...]
};
Suspicious usage of ^sizeof(char*)^
There is a subtle difference between declaring a string literal with
char* A = "" and char A[] = "". The first case has the type char*
instead of the aggregate type char[]. Using sizeof on an object
declared with char* type is returning the size of a pointer instead of
the number of characters (bytes) in the string literal.
const char* kMessage = "Hello World!"; // const char kMessage[] = "...";
void getMessage(char* buf) {
memcpy(buf, kMessage, sizeof(kMessage)); // sizeof(char*)
}
Suspicious usage of ^sizeof(A*)^
A common mistake is to compute the size of a pointer instead of its
pointee. These cases may occur because of explicit cast or implicit
conversion.
int A[10];
memset(A, 0, sizeof(A + 0));
struct Point point;
memset(point, 0, sizeof(&point));
Suspicious usage of ^sizeof(^|)/sizeof(^|)^
Dividing sizeof expressions is typically used to retrieve the number of
elements of an aggregate. This check warns on incompatible or suspi-
cious cases.
In the following example, the entity has 10-bytes and is incompatible
with the type int which has 4 bytes.
char buf[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // sizeof(buf) => 10
void getMessage(char* dst) {
memcpy(dst, buf, sizeof(buf) / sizeof(int)); // sizeof(int) => 4 [incompatible sizes]
}
In the following example, the expression sizeof(Values) is returning
the size of char*. One can easily be fooled by its declaration, but in
parameter declaration the size a10a is ignored and the function is
receiving a char*.
char OrderedValues[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
return CompareArray(char Values[10]) {
return memcmp(OrderedValues, Values, sizeof(Values)) == 0; // sizeof(Values) ==> sizeof(char*) [implicit cast to char*]
}
Suspicious ^sizeof^ by ^sizeof^ expression
Multiplying sizeof expressions typically makes no sense and is probably
a logic error. In the following example, the programmer used * instead
of /.
const char kMessage[] = "Hello World!";
void getMessage(char* buf) {
memcpy(buf, kMessage, sizeof(kMessage) * sizeof(char)); // sizeof(kMessage) / sizeof(char)
}
This check may trigger on code using the arraysize macro. The following
code is working correctly but should be simplified by using only the
sizeof operator.
extern Object objects[100];
void InitializeObjects() {
memset(objects, 0, arraysize(objects) * sizeof(Object)); // sizeof(objects)
}
Suspicious usage of ^sizeof(sizeof(^|))^
Getting the sizeof of a sizeof makes no sense and is typically an error
hidden through macros.
#define INT_SZ sizeof(int)
int buf[] = { 42 };
void getInt(int* dst) {
memcpy(dst, buf, sizeof(INT_SZ)); // sizeof(sizeof(int)) is suspicious.
}
Options
WarnOnSizeOfConstant
When non-zero, the check will warn on an expression like
sizeof(CONSTANT). Default is 1.
WarnOnSizeOfThis
When non-zero, the check will warn on an expression like
sizeof(this). Default is 1.
WarnOnSizeOfCompareToConstant
When non-zero, the check will warn on an expression like
sizeof(epxr) <= k for a suspicious constant k while k is 0 or
greater than 0x8000. Default is 1.
misc-static-assert
cert-dcl03-c redirects here as an alias for this check.
Replaces assert() with static_assert() if the condition is evaluatable
at compile time.
The condition of static_assert() is evaluated at compile time which is
safer and more efficient.
misc-string-compare
Finds string comparisons using the compare method.
A common mistake is to use the stringas compare method instead of using
the equality or inequality operators. The compare method is intended
for sorting functions and thus returns a negative number, a positive
number or zero depending on the lexicographical relationship between
the strings compared. If an equality or inequality check can suffice,
that is recommended. This is recommended to avoid the risk of incorrect
interpretation of the return value and to simplify the code. The string
equality and inequality operators can also be faster than the compare
method due to early termination.
Examples:
std::string str1{"a"};
std::string str2{"b"};
// use str1 != str2 instead.
if (str1.compare(str2)) {
}
// use str1 == str2 instead.
if (!str1.compare(str2)) {
}
// use str1 == str2 instead.
if (str1.compare(str2) == 0) {
}
// use str1 != str2 instead.
if (str1.compare(str2) != 0) {
}
// use str1 == str2 instead.
if (0 == str1.compare(str2)) {
}
// use str1 != str2 instead.
if (0 != str1.compare(str2)) {
}
// Use str1 == "foo" instead.
if (str1.compare("foo") == 0) {
}
The above code examples shows the list of if-statements that this check
will give a warning for. All of them uses compare to check if equality
or inequality of two strings instead of using the correct operators.
misc-string-constructor
Finds string constructors that are suspicious and probably errors.
A common mistake is to swap parameters to the afilla string-construc-
tor.
Examples:
std::string('x', 50) str; // should be std::string(50, 'x')
Calling the string-literal constructor with a length bigger than the
literal is suspicious and adds extra random characters to the string.
Examples:
std::string("test", 200); // Will include random characters after "test".
Creating an empty string from constructors with parameters is consid-
ered suspicious. The programmer should use the empty constructor
instead.
Examples:
std::string("test", 0); // Creation of an empty string.
Options
WarnOnLargeLength
When non-zero, the check will warn on a string with a length
greater than LargeLengthThreshold. Default is 1.
LargeLengthThreshold
An integer specifying the large length threshold. Default is
0x800000.
misc-string-integer-assignment
The check finds assignments of an integer to std::basic_string<CharT>
(std::string, std::wstring, etc.). The source of the problem is the
following assignment operator of std::basic_string<CharT>:
basic_string& operator=( CharT ch );
Numeric types can be implicitly casted to character types.
std::string s;
int x = 5965;
s = 6;
s = x;
Use the appropriate conversion functions or character literals.
std::string s;
int x = 5965;
s = '6';
s = std::to_string(x);
In order to suppress false positives, use an explicit cast.
std::string s;
s = static_cast<char>(6);
misc-string-literal-with-embedded-nul
Finds occurrences of string literal with embedded NUL character and
validates their usage.
Invalid escaping
Special characters can be escaped within a string literal by using
their hexadecimal encoding like \x42. A common mistake is to escape
them like this \0x42 where the \0 stands for the NUL character.
const char* Example[] = "Invalid character: \0x12 should be \x12";
const char* Bytes[] = "\x03\0x02\0x01\0x00\0xFF\0xFF\0xFF";
Truncated literal
String-like classes can manipulate strings with embedded NUL as they
are keeping track of the bytes and the length. This is not the case for
a char* (NUL-terminated) string.
A common mistake is to pass a string-literal with embedded NUL to a
string constructor expecting a NUL-terminated string. The bytes after
the first NUL character are truncated.
std::string str("abc\0def"); // "def" is truncated
str += "\0"; // This statement is doing nothing
if (str == "\0abc") return; // This expression is always true
misc-suspicious-enum-usage
The checker detects various cases when an enum is probably misused (as
a bitmask ).
1. When aADDa or abitwise ORa is used between two enum which come from
different types and these types value ranges are not disjoint.
The following cases will be investigated only using StrictMode. We
regard the enum as a (suspicious) bitmask if the three conditions below
are true at the same time:
o at most half of the elements of the enum are non pow-of-2 numbers
(because of short enumerations)
o there is another non pow-of-2 number than the enum constant repre-
senting all choices (the result abitwise ORa operation of all enum
elements)
o enum type variable/enumconstant is used as an argument of a + or
abitwise OR a operator
So whenever the non pow-of-2 element is used as a bitmask element we
diagnose a misuse and give a warning.
2. Investigating the right hand side of += and |= operator.
3. Check only the enum value side of a | and + operator if one of them
is not enum val.
4. Check both side of | or + operator where the enum values are from
the same enum type.
Examples:
enum { A, B, C };
enum { D, E, F = 5 };
enum { G = 10, H = 11, I = 12 };
unsigned flag;
flag =
A |
H; // OK, disjoint value intervalls in the enum types ->probably good use.
flag = B | F; // Warning, have common values so they are probably misused.
// Case 2:
enum Bitmask {
A = 0,
B = 1,
C = 2,
D = 4,
E = 8,
F = 16,
G = 31 // OK, real bitmask.
};
enum Almostbitmask {
AA = 0,
BB = 1,
CC = 2,
DD = 4,
EE = 8,
FF = 16,
GG // Problem, forgot to initialize.
};
unsigned flag = 0;
flag |= E; // OK.
flag |=
EE; // Warning at the decl, and note that it was used here as a bitmask.
Options
StrictMode
Default value: 0. When non-null the suspicious bitmask usage
will be investigated additionally to the different enum usage
check.
misc-suspicious-missing-comma
String literals placed side-by-side are concatenated at translation
phase 6 (after the preprocessor). This feature is used to represent
long string literal on multiple lines.
For instance, the following declarations are equivalent:
const char* A[] = "This is a test";
const char* B[] = "This" " is a " "test";
A common mistake done by programmers is to forget a comma between two
string literals in an array initializer list.
const char* Test[] = {
"line 1",
"line 2" // Missing comma!
"line 3",
"line 4",
"line 5"
};
The array contains the string aline 2line3a at offset 1 (i.e. Test[1]).
Clang wonat generate warnings at compile time.
This check may warn incorrectly on cases like:
const char* SupportedFormat[] = {
"Error %s",
"Code " PRIu64, // May warn here.
"Warning %s",
};
Options
SizeThreshold
An unsigned integer specifying the minimum size of a string lit-
eral to be considered by the check. Default is 5U.
RatioThreshold
A string specifying the maximum threshold ratio [0, 1.0] of sus-
picious string literals to be considered. Default is ^<i>a.2^<i>a.
MaxConcatenatedTokens
An unsigned integer specifying the maximum number of concate-
nated tokens. Default is 5U.
misc-suspicious-semicolon
Finds most instances of stray semicolons that unexpectedly alter the
meaning of the code. More specifically, it looks for if, while, for and
for-range statements whose body is a single semicolon, and then ana-
lyzes the context of the code (e.g. indentation) in an attempt to
determine whether that is intentional.
if (x < y);
{
x++;
}
Here the body of the if statement consists of only the semicolon at the
end of the first line, and x will be incremented regardless of the con-
dition.
while ((line = readLine(file)) != NULL);
processLine(line);
As a result of this code, processLine() will only be called once, when
the while loop with the empty body exits with line == NULL. The inden-
tation of the code indicates the intention of the programmer.
if (x >= y);
x -= y;
While the indentation does not imply any nesting, there is simply no
valid reason to have an if statement with an empty body (but it can
make sense for a loop). So this check issues a warning for the code
above.
To solve the issue remove the stray semicolon or in case the empty body
is intentional, reflect this using code indentation or put the semi-
colon in a new line. For example:
while (readWhitespace());
Token t = readNextToken();
Here the second line is indented in a way that suggests that it is
meant to be the body of the while loop - whose body is in fact empty,
because of the semicolon at the end of the first line.
Either remove the indentation from the second line:
while (readWhitespace());
Token t = readNextToken();
a| or move the semicolon from the end of the first line to a new line:
while (readWhitespace())
;
Token t = readNextToken();
In this case the check will assume that you know what you are doing,
and will not raise a warning.
misc-suspicious-string-compare
Find suspicious usage of runtime string comparison functions. This
check is valid in C and C++.
Checks for calls with implicit comparator and proposed to explicitly
add it.
if (strcmp(...)) // Implicitly compare to zero
if (!strcmp(...)) // Won't warn
if (strcmp(...) != 0) // Won't warn
Checks that compare function results (i,e, strcmp) are compared to
valid constant. The resulting value is
< 0 when lower than,
> 0 when greater than,
== 0 when equals.
A common mistake is to compare the result to 1 or -1.
if (strcmp(...) == -1) // Incorrect usage of the returned value.
Additionally, the check warns if the results value is implicitly cast
to a suspicious non-integer type. Itas happening when the returned
value is used in a wrong context.
if (strcmp(...) < 0.) // Incorrect usage of the returned value.
Options
WarnOnImplicitComparison
When non-zero, the check will warn on implicit comparison. 1 by
default.
WarnOnLogicalNotComparison
When non-zero, the check will warn on logical not comparison. 0
by default.
StringCompareLikeFunctions
A string specifying the comma-separated names of the extra
string comparison functions. Default is an empty string. The
check will detect the following string comparison functions:
__builtin_memcmp, __builtin_strcasecmp, __builtin_strcmp,
__builtin_strncasecmp, __builtin_strncmp, _mbscmp, _mbscmp_l,
_mbsicmp, _mbsicmp_l, _mbsnbcmp, _mbsnbcmp_l, _mbsnbicmp,
_mbsnbicmp_l, _mbsncmp, _mbsncmp_l, _mbsnicmp, _mbsnicmp_l,
_memicmp, _memicmp_l, _stricmp, _stricmp_l, _strnicmp, _str-
nicmp_l, _wcsicmp, _wcsicmp_l, _wcsnicmp, _wcsnicmp_l, lstrcmp,
lstrcmpi, memcmp, memicmp, strcasecmp, strcmp, strcmpi, stricmp,
strncasecmp, strncmp, strnicmp, wcscasecmp, wcscmp, wcsicmp,
wcsncmp, wcsnicmp, wmemcmp.
misc-swapped-arguments
Finds potentially swapped arguments by looking at implicit conversions.
misc-throw-by-value-catch-by-reference
acert-err09-cppa redirects here as an alias for this check.
acert-err61-cppa redirects here as an alias for this check.
Finds violations of the rule aThrow by value, catch by referencea pre-
sented for example in aC++ Coding Standardsa by H. Sutter and A.
Alexandrescu.
Exceptions:
o Throwing string literals will not be flagged despite being a
pointer. They are not susceptible to slicing and the usage of
string literals is idomatic.
o Catching character pointers (char, wchar_t, unicode character
types) will not be flagged to allow catching sting literals.
o Moved named values will not be flagged as not throwing an
anonymous temporary. In this case we can be sure that the user
knows that the object canat be accessed outside catch blocks
handling the error.
o Throwing function parameters will not be flagged as not throw-
ing an anonymous temporary. This allows helper functions for
throwing.
o Re-throwing caught exception variables will not be flragged as
not throwing an anonymous temporary. Although this can usually
be done by just writing throw; it happens often enough in real
code.
Options
CheckThrowTemporaries
Triggers detection of violations of the rule Throw anonymous
temporaries. Default is 1.
misc-unconventional-assign-operator
Finds declarations of assign operators with the wrong return and/or
argument types and definitions with good return type but wrong return
statements.
o The return type must be Class&.
o Works with move-assign and assign by value.
o Private and deleted operators are ignored.
o The operator must always return *this.
misc-undelegated-constructor
Finds creation of temporary objects in constructors that look like a
function call to another constructor of the same class.
The user most likely meant to use a delegating constructor or base
class initializer.
misc-uniqueptr-reset-release
Find and replace unique_ptr::reset(release()) with std::move().
Example:
std::unique_ptr<Foo> x, y;
x.reset(y.release()); -> x = std::move(y);
If y is already rvalue, std::move() is not added. x and y can also be
std::unique_ptr<Foo>*.
misc-unused-alias-decls
Finds unused namespace alias declarations.
misc-unused-parameters
Finds unused parameters and fixes them, so that -Wunused-parameter can
be turned on.
misc-unused-raii
Finds temporaries that look like RAII objects.
The canonical example for this is a scoped lock.
{
scoped_lock(&global_mutex);
critical_section();
}
The destructor of the scoped_lock is called before the critical_section
is entered, leaving it unprotected.
We apply a number of heuristics to reduce the false positive count of
this check:
o Ignore code expanded from macros. Testing frameworks make heavy use
of this.
o Ignore types with trivial destructors. They are very unlikely to be
RAII objects and thereas no difference when they are deleted.
o Ignore objects at the end of a compound statement (doesnat change
behavior).
o Ignore objects returned from a call.
misc-unused-using-decls
Finds unused using declarations.
Example:
namespace n { class C; }
using n::C; // Never actually used.
misc-use-after-move
Warns if an object is used after it has been moved, for example:
std::string str = "Hello, world!\n";
std::vector<std::string> messages;
messages.emplace_back(std::move(str));
std::cout << str;
The last line will trigger a warning that str is used after it has been
moved.
The check does not trigger a warning if the object is reinitialized
after the move and before the use. For example, no warning will be out-
put for this code:
messages.emplace_back(std::move(str));
str = "Greetings, stranger!\n";
std::cout << str;
The check takes control flow into account. A warning is only emitted if
the use can be reached from the move. This means that the following
code does not produce a warning:
if (condition) {
messages.emplace_back(std::move(str));
} else {
std::cout << str;
}
On the other hand, the following code does produce a warning:
for (int i = 0; i < 10; ++i) {
std::cout << str;
messages.emplace_back(std::move(str));
}
(The use-after-move happens on the second iteration of the loop.)
In some cases, the check may not be able to detect that two branches
are mutually exclusive. For example (assuming that i is an int):
if (i == 1) {
messages.emplace_back(std::move(str));
}
if (i == 2) {
std::cout << str;
}
In this case, the check will erroneously produce a warning, even though
it is not possible for both the move and the use to be executed.
An erroneous warning can be silenced by reinitializing the object after
the move:
if (i == 1) {
messages.emplace_back(std::move(str));
str = "";
}
if (i == 2) {
std::cout << str;
}
Subsections below explain more precisely what exactly the check consid-
ers to be a move, use, and reinitialization.
Unsequenced moves, uses, and reinitializations
In many cases, C++ does not make any guarantees about the order in
which sub-expressions of a statement are evaluated. This means that in
code like the following, it is not guaranteed whether the use will hap-
pen before or after the move:
void f(int i, std::vector<int> v);
std::vector<int> v = { 1, 2, 3 };
f(v[1], std::move(v));
In this kind of situation, the check will note that the use and move
are unsequenced.
The check will also take sequencing rules into account when reinitial-
izations occur in the same statement as moves or uses. A reinitializa-
tion is only considered to reinitialize a variable if it is guaranteed
to be evaluated after the move and before the use.
Move
The check currently only considers calls of std::move on local vari-
ables or function parameters. It does not check moves of member vari-
ables or global variables.
Any call of std::move on a variable is considered to cause a move of
that variable, even if the result of std::move is not passed to an
rvalue reference parameter.
This means that the check will flag a use-after-move even on a type
that does not define a move constructor or move assignment operator.
This is intentional. Developers may use std::move on such a type in
the expectation that the type will add move semantics in the future. If
such a std::move has the potential to cause a use-after-move, we want
to warn about it even if the type does not implement move semantics
yet.
Furthermore, if the result of std::move is passed to an rvalue refer-
ence parameter, this will always be considered to cause a move, even if
the function that consumes this parameter does not move from it, or if
it does so only conditionally. For example, in the following situation,
the check will assume that a move always takes place:
std::vector<std::string> messages;
void f(std::string &&str) {
// Only remember the message if it isn't empty.
if (!str.empty()) {
messages.emplace_back(std::move(str));
}
}
std::string str = "";
f(std::move(str));
The check will assume that the last line causes a move, even though, in
this particular case, it does not. Again, this is intentional.
When analyzing the order in which moves, uses and reinitializations
happen (see section Unsequenced moves, uses, and reinitializations),
the move is assumed to occur in whichever function the result of the
std::move is passed to.
Use
Any occurrence of the moved variable that is not a reinitialization
(see below) is considered to be a use.
An exception to this are objects of type std::unique_ptr,
std::shared_ptr and std::weak_ptr, which have defined move behavior
(objects of these classes are guaranteed to be empty after they have
been moved from). Therefore, an object of these classes will only be
considered to be used if it is dereferenced, i.e. if operator*, opera-
tor-> or operator[] (in the case of std::unique_ptr<T []>) is called on
it.
If multiple uses occur after a move, only the first of these is
flagged.
Reinitialization
The check considers a variable to be reinitialized in the following
cases:
o The variable occurs on the left-hand side of an assignment.
o The variable is passed to a function as a non-const pointer or
non-const lvalue reference. (It is assumed that the variable may
be an out-parameter for the function.)
o clear() or assign() is called on the variable and the variable is
of one of the standard container types basic_string, vector,
deque, forward_list, list, set, map, multiset, multimap,
unordered_set, unordered_map, unordered_multiset, unordered_mul-
timap.
o reset() is called on the variable and the variable is of type
std::unique_ptr, std::shared_ptr or std::weak_ptr.
If the variable in question is a struct and an individual member vari-
able of that struct is written to, the check does not consider this to
be a reinitialization a even if, eventually, all member variables of
the struct are written to. For example:
struct S {
std::string str;
int i;
};
S s = { "Hello, world!\n", 42 };
S s_other = std::move(s);
s.str = "Lorem ipsum";
s.i = 99;
The check will not consider s to be reinitialized after the last line;
instead, the line that assigns to s.str will be flagged as a
use-after-move. This is intentional as this pattern of reinitializing
a struct is error-prone. For example, if an additional member variable
is added to S, it is easy to forget to add the reinitialization for
this additional member. Instead, it is safer to assign to the entire
struct in one go, and this will also avoid the use-after-move warning.
misc-virtual-near-miss
Warn if a function is a near miss (ie. the name is very similar and the
function signiture is the same) to a virtual function from a base
class.
Example:
struct Base {
virtual void func();
};
struct Derived : Base {
virtual funk();
// warning: 'Derived::funk' has a similar name and the same signature as virtual method 'Base::func'; did you mean to override it?
};
modernize-avoid-bind
The check finds uses of std::bind and replaces simple uses with lamb-
das. Lambdas will use value-capture where required.
Right now it only handles free functions, not member functions.
Given:
int add(int x, int y) { return x + y; }
Then:
void f() {
int x = 2;
auto clj = std::bind(add, x, _1);
}
is replaced by:
void f() {
int x = 2;
auto clj = [=](auto && arg1) { return add(x, arg1); };
}
std::bind can be hard to read and can result in larger object files and
binaries due to type information that will not be produced by equiva-
lent lambdas.
modernize-deprecated-headers
Some headers from C library were deprecated in C++ and are no longer
welcome in C++ codebases. Some have no effect in C++. For more details
refer to the C++ 14 Standard [depr.c.headers] section.
This check replaces C standard library headers with their C++ alterna-
tives and removes redundant ones.
Improtant note: the Standard doesnat guarantee that the C++ headers
declare all the same functions in the global namespace. The check in
its current form can break the code that uses library symbols from the
global namespace.
o <assert.h>
o <complex.h>
o <ctype.h>
o <errno.h>
o <fenv.h> // deprecated since C++11
o <float.h>
o <inttypes.h>
o <limits.h>
o <locale.h>
o <math.h>
o <setjmp.h>
o <signal.h>
o <stdarg.h>
o <stddef.h>
o <stdint.h>
o <stdio.h>
o <stdlib.h>
o <string.h>
o <tgmath.h> // deprecated since C++11
o <time.h>
o <uchar.h> // deprecated since C++11
o <wchar.h>
o <wctype.h>
If the specified standard is older than C++11 the check will only
replace headers deprecated before C++11, otherwise a every header that
appeared in the previous list.
These headers donat have effect in C++:
o <iso646.h>
o <stdalign.h>
o <stdbool.h>
modernize-loop-convert
This check converts for(...; ...; ...) loops to use the new range-based
loops in C++11.
Three kinds of loops can be converted:
o Loops over statically allocated arrays.
o Loops over containers, using iterators.
o Loops over array-like containers, using operator[] and at().
MinConfidence option
risky
In loops where the container expression is more complex than just a
reference to a declared expression (a variable, function, enum, etc.),
and some part of it appears elsewhere in the loop, we lower our confi-
dence in the transformation due to the increased risk of changing
semantics. Transformations for these loops are marked as risky, and
thus will only be converted if the minimum required confidence level is
set to risky.
int arr[10][20];
int l = 5;
for (int j = 0; j < 20; ++j)
int k = arr[l][j] + l; // using l outside arr[l] is considered risky
for (int i = 0; i < obj.getVector().size(); ++i)
obj.foo(10); // using 'obj' is considered risky
See Range-based loops evaluate end() only once for an example of an
incorrect transformation when the minimum required confidence level is
set to risky.
reasonable (Default)
If a loop calls .end() or .size() after each iteration, the transforma-
tion for that loop is marked as reasonable, and thus will be converted
if the required confidence level is set to reasonable (default) or
lower.
// using size() is considered reasonable
for (int i = 0; i < container.size(); ++i)
cout << container[i];
safe
Any other loops that do not match the above criteria to be marked as
risky or reasonable are marked safe, and thus will be converted if the
required confidence level is set to safe or lower.
int arr[] = {1,2,3};
for (int i = 0; i < 3; ++i)
cout << arr[i];
Example
Original:
const int N = 5;
int arr[] = {1,2,3,4,5};
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
// safe conversion
for (int i = 0; i < N; ++i)
cout << arr[i];
// reasonable conversion
for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
cout << *it;
// reasonable conversion
for (int i = 0; i < v.size(); ++i)
cout << v[i];
After applying the check with minimum confidence level set to reason-
able (default):
const int N = 5;
int arr[] = {1,2,3,4,5};
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
// safe conversion
for (auto & elem : arr)
cout << elem;
// reasonable conversion
for (auto & elem : v)
cout << elem;
// reasonable conversion
for (auto & elem : v)
cout << elem;
Limitations
There are certain situations where the tool may erroneously perform
transformations that remove information and change semantics. Users of
the tool should be aware of the behaviour and limitations of the check
outlined by the cases below.
Comments inside loop headers
Comments inside the original loop header are ignored and deleted when
transformed.
for (int i = 0; i < N; /* This will be deleted */ ++i) { }
Range-based loops evaluate end() only once
The C++11 range-based for loop calls .end() only once during the ini-
tialization of the loop. If in the original loop .end() is called after
each iteration the semantics of the transformed loop may differ.
// The following is semantically equivalent to the C++11 range-based for loop,
// therefore the semantics of the header will not change.
for (iterator it = container.begin(), e = container.end(); it != e; ++it) { }
// Instead of calling .end() after each iteration, this loop will be
// transformed to call .end() only once during the initialization of the loop,
// which may affect semantics.
for (iterator it = container.begin(); it != container.end(); ++it) { }
As explained above, calling member functions of the container in the
body of the loop is considered risky. If the called member function
modifies the container the semantics of the converted loop will differ
due to .end() being called only once.
bool flag = false;
for (vector<T>::iterator it = vec.begin(); it != vec.end(); ++it) {
// Add a copy of the first element to the end of the vector.
if (!flag) {
// This line makes this transformation 'risky'.
vec.push_back(*it);
flag = true;
}
cout << *it;
}
The original code above prints out the contents of the container
including the newly added element while the converted loop, shown
below, will only print the original contents and not the newly added
element.
bool flag = false;
for (auto & elem : vec) {
// Add a copy of the first element to the end of the vector.
if (!flag) {
// This line makes this transformation 'risky'
vec.push_back(elem);
flag = true;
}
cout << elem;
}
Semantics will also be affected if .end() has side effects. For exam-
ple, in the case where calls to .end() are logged the semantics will
change in the transformed loop if .end() was originally called after
each iteration.
iterator end() {
num_of_end_calls++;
return container.end();
}
Overloaded operator->() with side effects
Similarly, if operator->() was overloaded to have side effects, such as
logging, the semantics will change. If the iteratoras operator->() was
used in the original loop it will be replaced with <container ele-
ment>.<member> instead due to the implicit dereference as part of the
range-based for loop. Therefore any side effect of the overloaded
operator->() will no longer be performed.
for (iterator it = c.begin(); it != c.end(); ++it) {
it->func(); // Using operator->()
}
// Will be transformed to:
for (auto & elem : c) {
elem.func(); // No longer using operator->()
}
Pointers and references to containers
While most of the checkas risk analysis is dedicated to determining
whether the iterator or container was modified within the loop, it is
possible to circumvent the analysis by accessing and modifying the con-
tainer through a pointer or reference.
If the container were directly used instead of using the pointer or
reference the following transformation would have only been applied at
the risky level since calling a member function of the container is
considered risky. The check cannot identify expressions associated
with the container that are different than the one used in the loop
header, therefore the transformation below ends up being performed at
the safe level.
vector<int> vec;
vector<int> *ptr = &vec;
vector<int> &ref = vec;
for (vector<int>::iterator it = vec.begin(), e = vec.end(); it != e; ++it) {
if (!flag) {
// Accessing and modifying the container is considered risky, but the risk
// level is not raised here.
ptr->push_back(*it);
ref.push_back(*it);
flag = true;
}
}
modernize-make-shared
This check finds the creation of std::shared_ptr objects by explicitly
calling the constructor and a new expression, and replaces it with a
call to std::make_shared.
auto my_ptr = std::shared_ptr<MyPair>(new MyPair(1, 2));
// becomes
auto my_ptr = std::make_shared<MyPair>(1, 2);
This check also finds calls to std::shared_ptr::reset() with a new
expression, and replaces it with a call to std::make_shared.
my_ptr.reset(new MyPair(1, 2));
// becomes
my_ptr = std::make_shared<MyPair>(1, 2);
modernize-make-unique
This check finds the creation of std::unique_ptr objects by explicitly
calling the constructor and a new expression, and replaces it with a
call to std::make_unique, introduced in C++14.
auto my_ptr = std::unique_ptr<MyPair>(new MyPair(1, 2));
// becomes
auto my_ptr = std::make_unique<MyPair>(1, 2);
This check also finds calls to std::unique_ptr::reset() with a new
expression, and replaces it with a call to std::make_unique.
my_ptr.reset(new MyPair(1, 2));
// becomes
my_ptr = std::make_unique<MyPair>(1, 2);
modernize-pass-by-value
With move semantics added to the language and the standard library
updated with move constructors added for many types it is now interest-
ing to take an argument directly by value, instead of by const-refer-
ence, and then copy. This check allows the compiler to take care of
choosing the best way to construct the copy.
The transformation is usually beneficial when the calling code passes
an rvalue and assumes the move construction is a cheap operation. This
short example illustrates how the construction of the value happens:
void foo(std::string s);
std::string get_str();
void f(const std::string &str) {
foo(str); // lvalue -> copy construction
foo(get_str()); // prvalue -> move construction
}
NOTE:
Currently, only constructors are transformed to make use of
pass-by-value. Contributions that handle other situations are wel-
come!
Pass-by-value in constructors
Replaces the uses of const-references constructor parameters that are
copied into class fields. The parameter is then moved with std::move().
Since std::move() is a library function declared in <utility> it may be
necessary to add this include. The check will add the include directive
when necessary.
#include <string>
class Foo {
public:
- Foo(const std::string &Copied, const std::string &ReadOnly)
- : Copied(Copied), ReadOnly(ReadOnly)
+ Foo(std::string Copied, const std::string &ReadOnly)
+ : Copied(std::move(Copied)), ReadOnly(ReadOnly)
{}
private:
std::string Copied;
const std::string &ReadOnly;
};
std::string get_cwd();
void f(const std::string &Path) {
// The parameter corresponding to 'get_cwd()' is move-constructed. By
// using pass-by-value in the Foo constructor we managed to avoid a
// copy-construction.
Foo foo(get_cwd(), Path);
}
If the parameter is used more than once no transformation is performed
since moved objects have an undefined state. It means the following
code will be left untouched:
#include <string>
void pass(const std::string &S);
struct Foo {
Foo(const std::string &S) : Str(S) {
pass(S);
}
std::string Str;
};
Known limitations
A situation where the generated code can be wrong is when the object
referenced is modified before the assignment in the init-list through a
ahiddena reference.
Example:
std::string s("foo");
struct Base {
Base() {
s = "bar";
}
};
struct Derived : Base {
- Derived(const std::string &S) : Field(S)
+ Derived(std::string S) : Field(std::move(S))
{ }
std::string Field;
};
void f() {
- Derived d(s); // d.Field holds "bar"
+ Derived d(s); // d.Field holds "foo"
}
Note about delayed template parsing
When delayed template parsing is enabled, constructors part of tem-
plated contexts; templated constructors, constructors in class tem-
plates, constructors of inner classes of template classes, etc., are
not transformed. Delayed template parsing is enabled by default on Win-
dows as a Microsoft extension: Clang Compiler User^<i>as Manual - Microsoft
extensions.
Delayed template parsing can be enabled using the -fdelayed-tem-
plate-parsing flag and disabled using -fno-delayed-template-parsing.
Example:
template <typename T> class C {
std::string S;
public:
= // using -fdelayed-template-parsing (default on Windows)
= C(const std::string &S) : S(S) {}
+ // using -fno-delayed-template-parsing (default on non-Windows systems)
+ C(std::string S) : S(std::move(S)) {}
};
SEE ALSO:
For more information about the pass-by-value idiom, read: Want
Speed? Pass by Value.
Options
IncludeStyle
A string specifying which include-style is used, llvm or google.
Default is llvm.
ValuesOnly
When non-zero, the check only warns about copied parameters that
are already passed by value. Default is 0.
modernize-raw-string-literal
This check selectively replaces string literals containing escaped
characters with raw string literals.
Example:
const char *const Quotes{"embedded \"quotes\""};
const char *const Paragraph{"Line one.\nLine two.\nLine three.\n"};
const char *const SingleLine{"Single line.\n"};
const char *const TrailingSpace{"Look here -> \n"};
const char *const Tab{"One\tTwo\n"};
const char *const Bell{"Hello!\a And welcome!"};
const char *const Path{"C:\\Program Files\\Vendor\\Application.exe"};
const char *const RegEx{"\\w\\([a-z]\\)"};
becomes
const char *const Quotes{R"(embedded "quotes")"};
const char *const Paragraph{"Line one.\nLine two.\nLine three.\n"};
const char *const SingleLine{"Single line.\n"};
const char *const TrailingSpace{"Look here -> \n"};
const char *const Tab{"One\tTwo\n"};
const char *const Bell{"Hello!\a And welcome!"};
const char *const Path{R"(C:\Program Files\Vendor\Application.exe)"};
const char *const RegEx{R"(\w\([a-z]\))"};
The presence of any of the following escapes can cause the string to be
converted to a raw string literal: \\, \', \", \?, and octal or hexa-
decimal escapes for printable ASCII characters.
A string literal containing only escaped newlines is a common way of
writing lines of text output. Introducing physical newlines with raw
string literals in this case is likely to impede readability. These
string literals are left unchanged.
An escaped horizontal tab, form feed, or vertical tab prevents the
string literal from being converted. The presence of a horizontal tab,
form feed or vertical tab in source code is not visually obvious.
modernize-redundant-void-arg
Find and remove redundant void argument lists.
Examples:
+---------------------------+-------------------------+
|Initial code | Code with applied fixes |
+---------------------------+-------------------------+
|int f(void); | int f(); |
+---------------------------+-------------------------+
|int (*f(void))(void); | int (*f())(); |
+---------------------------+-------------------------+
|typedef int | typedef int (*f_t())(); |
|(*f_t(void))(void); | |
+---------------------------+-------------------------+
|void (C::*p)(void); | void (C::*p)(); |
+---------------------------+-------------------------+
|C::C(void) {} | C::C() {} |
+---------------------------+-------------------------+
|C::~C(void) {} | C::~C() {} |
+---------------------------+-------------------------+
modernize-replace-auto-ptr
This check replaces the uses of the deprecated class std::auto_ptr by
std::unique_ptr (introduced in C++11). The transfer of ownership, done
by the copy-constructor and the assignment operator, is changed to
match std::unique_ptr usage by using explicit calls to std::move().
Migration example:
-void take_ownership_fn(std::auto_ptr<int> int_ptr);
+void take_ownership_fn(std::unique_ptr<int> int_ptr);
void f(int x) {
- std::auto_ptr<int> a(new int(x));
- std::auto_ptr<int> b;
+ std::unique_ptr<int> a(new int(x));
+ std::unique_ptr<int> b;
- b = a;
- take_ownership_fn(b);
+ b = std::move(a);
+ take_ownership_fn(std::move(b));
}
Since std::move() is a library function declared in <utility> it may be
necessary to add this include. The check will add the include directive
when necessary.
Known Limitations
o If headers modification is not activated or if a header is not
allowed to be changed this check will produce broken code (compila-
tion error), where the headersa code will stay unchanged while the
code using them will be changed.
o Client code that declares a reference to an std::auto_ptr coming from
code that canat be migrated (such as a header coming from a 3rd party
library) will produce a compilation error after migration. This is
because the type of the reference will be changed to std::unique_ptr
but the type returned by the library wonat change, binding a refer-
ence to std::unique_ptr from an std::auto_ptr. This pattern doesnat
make much sense and usually std::auto_ptr are stored by value (other-
wise what is the point in using them instead of a reference or a
pointer?).
// <3rd-party header...>
std::auto_ptr<int> get_value();
const std::auto_ptr<int> & get_ref();
// <calling code (with migration)...>
-std::auto_ptr<int> a(get_value());
+std::unique_ptr<int> a(get_value()); // ok, unique_ptr constructed from auto_ptr
-const std::auto_ptr<int> & p = get_ptr();
+const std::unique_ptr<int> & p = get_ptr(); // won't compile
o Non-instantiated templates arenat modified.
template <typename X>
void f() {
std::auto_ptr<X> p;
}
// only 'f<int>()' (or similar) will trigger the replacement.
Options
IncludeStyle
A string specifying which include-style is used, llvm or google.
Default is llvm.
modernize-shrink-to-fit
Replace copy and swap tricks on shrinkable containers with the
shrink_to_fit() method call.
The shrink_to_fit() method is more readable and more effective than the
copy and swap trick to reduce the capacity of a shrinkable container.
Note that, the shrink_to_fit() method is only available in C++11 and
up.
modernize-use-auto
This check is responsible for using the auto type specifier for vari-
able declarations to improve code readability and maintainability. For
example:
std::vector<int>::iterator I = my_container.begin();
// transforms to:
auto I = my_container.begin();
The auto type specifier will only be introduced in situations where the
variable type matches the type of the initializer expression. In other
words auto should deduce the same type that was originally spelled in
the source. However, not every situation should be transformed:
int val = 42;
InfoStruct &I = SomeObject.getInfo();
// Should not become:
auto val = 42;
auto &I = SomeObject.getInfo();
In this example using auto for builtins doesnat improve readability. In
other situations it makes the code less self-documenting impairing
readability and maintainability. As a result, auto is used only intro-
duced in specific situations described below.
Iterators
Iterator type specifiers tend to be long and used frequently, espe-
cially in loop constructs. Since the functions generating iterators
have a common format, the type specifier can be replaced without
obscuring the meaning of code while improving readability and maintain-
ability.
for (std::vector<int>::iterator I = my_container.begin(),
E = my_container.end();
I != E; ++I) {
}
// becomes
for (auto I = my_container.begin(), E = my_container.end(); I != E; ++I) {
}
The check will only replace iterator type-specifiers when all of the
following conditions are satisfied:
o The iterator is for one of the standard container in std namespace:
o array
o deque
o forward_list
o list
o vector
o map
o multimap
o set
o multiset
o unordered_map
o unordered_multimap
o unordered_set
o unordered_multiset
o queue
o priority_queue
o stack
o The iterator is one of the possible iterator types for standard con-
tainers:
o iterator
o reverse_iterator
o const_iterator
o const_reverse_iterator
o In addition to using iterator types directly, typedefs or other ways
of referring to those types are also allowed. However, implementa-
tion-specific types for which a type like std::vector<int>::iterator
is itself a typedef will not be transformed. Consider the following
examples:
// The following direct uses of iterator types will be transformed.
std::vector<int>::iterator I = MyVec.begin();
{
using namespace std;
list<int>::iterator I = MyList.begin();
}
// The type specifier for J would transform to auto since it's a typedef
// to a standard iterator type.
typedef std::map<int, std::string>::const_iterator map_iterator;
map_iterator J = MyMap.begin();
// The following implementation-specific iterator type for which
// std::vector<int>::iterator could be a typedef would not be transformed.
__gnu_cxx::__normal_iterator<int*, std::vector> K = MyVec.begin();
o The initializer for the variable being declared is not a braced ini-
tializer list. Otherwise, use of auto would cause the type of the
variable to be deduced as std::initializer_list.
New expressions
Frequently, when a pointer is declared and initialized with new, the
pointee type is written twice: in the declaration type and in the new
expression. In this cases, the declaration type can be replaced with
auto improving readability and maintainability.
TypeName *my_pointer = new TypeName(my_param);
// becomes
auto *my_pointer = new TypeName(my_param);
The check will also replace the declaration type in multiple declara-
tions, if the following conditions are satisfied:
o All declared variables have the same type (i.e. all of them are
pointers to the same type).
o All declared variables are initialized with a new expression.
o The types of all the new expressions are the same than the pointee of
the declaration type.
TypeName *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;
// becomes
auto *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;
Cast expressions
Frequently, when a variable is declared and initialized with a cast,
the variable type is written twice: in the declaration type and in the
cast expression. In this cases, the declaration type can be replaced
with auto improving readability and maintainability.
TypeName *my_pointer = static_cast<TypeName>(my_param);
// becomes
auto *my_pointer = static_cast<TypeName>(my_param);
The check handles static_cast, dynamic_cast, const_cast, reinter-
pret_cast, functional casts, C-style casts and function templates that
behave as casts, such as llvm::dyn_cast, boost::lexical_cast and
gsl::narrow_cast. Calls to function templates are considered to behave
as casts if the first template argument is explicit and is a type, and
the function returns that type, or a pointer or reference to it.
Known Limitations
o If the initializer is an explicit conversion constructor, the check
will not replace the type specifier even though it would be safe to
do so.
o User-defined iterators are not handled at this time.
Options
RemoveStars
If the option is set to non-zero (default is 0), the check will
remove stars from the non-typedef pointer types when replacing
type names with auto. Otherwise, the check will leave stars. For
example:
TypeName *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;
// RemoveStars = 0
auto *my_first_pointer = new TypeName, *my_second_pointer = new TypeName;
// RemoveStars = 1
auto my_first_pointer = new TypeName, my_second_pointer = new TypeName;
modernize-use-bool-literals
Finds integer literals which are cast to bool.
bool p = 1;
bool f = static_cast<bool>(1);
std::ios_base::sync_with_stdio(0);
bool x = p ? 1 : 0;
// transforms to
bool p = true;
bool f = true;
std::ios_base::sync_with_stdio(false);
bool x = p ? true : false;
modernize-use-default-member-init
This check converts a default constructoras member initializers into
the new default member initializers in C++11. Other member initializers
that match the default member initializer are removed. This can reduce
repeated code or allow use of a= defaulta.
struct A {
A() : i(5), j(10.0) {}
A(int i) : i(i), j(10.0) {}
int i;
double j;
};
// becomes
struct A {
A() {}
A(int i) : i(i) {}
int i{5};
double j{10.0};
};
NOTE:
Only converts member initializers for built-in types, enums, and
pointers. The readability-redundant-member-init check will remove
redundant member initializers for classes.
Options
UseAssignment
If this option is set to non-zero (default is 0), the check will
initialise members with an assignment. For example:
struct A {
A() {}
A(int i) : i(i) {}
int i = 5;
double j = 10.0;
};
modernize-use-emplace
The check flags insertions to an STL-style container done by calling
the push_back method with an explicitly-constructed temporary of the
container element type. In this case, the corresponding emplace_back
method results in less verbose and potentially more efficient code.
Right now the check doesnat support push_front and insert. It also
doesnat support insert functions for associative containers because
replacing insert with emplace may result in speed regression, but it
might get support with some addition flag in the future.
By default only std::vector, std::deque, std::list are considered.
This list can be modified using the ContainersWithPushBack option.
Before:
std::vector<MyClass> v;
v.push_back(MyClass(21, 37));
std::vector<std::pair<int, int>> w;
w.push_back(std::pair<int, int>(21, 37));
w.push_back(std::make_pair(21L, 37L));
After:
std::vector<MyClass> v;
v.emplace_back(21, 37);
std::vector<std::pair<int, int>> w;
w.emplace_back(21, 37);
// This will be fixed to w.push_back(21, 37); in next version
w.emplace_back(std::make_pair(21L, 37L);
The other situation is when we pass arguments that will be converted to
a type inside a container.
Before:
std::vector<boost::optional<std::string> > v;
v.push_back("abc");
After:
std::vector<boost::optional<std::string> > v;
v.emplace_back("abc");
In some cases the transformation would be valid, but the code wouldnat
be exception safe. In this case the calls of push_back wonat be
replaced.
std::vector<std::unique_ptr<int>> v;
v.push_back(std::unique_ptr<int>(new int(0)));
auto *ptr = new int(1);
v.push_back(std::unique_ptr<int>(ptr));
This is because replacing it with emplace_back could cause a leak of
this pointer if emplace_back would throw exception before emplacement
(e.g. not enough memory to add new element).
For more info read item 42 - aConsider emplacement instead of inser-
tion.a of Scott Meyers aEffective Modern C++a.
The default smart pointers that are considered are std::unique_ptr,
std::shared_ptr, std::auto_ptr. To specify other smart pointers or
other classes use the SmartPointers option.
Check also fires if any argument of constructor call would be:
o bitfield (bitfields canat bind to rvalue/universal reference)
o new expression (to avoid leak) or if the argument would be con-
verted via derived-to-base cast.
This check requires C++11 of higher to run.
Options
ContainersWithPushBack
Semicolon-separated list of class names of custom containers
that support push_back.
SmartPointers
Semicolon-separated list of class names of custom smart point-
ers.
modernize-use-equals-default
This check replaces default bodies of special member functions with =
default;. The explicitly defaulted function declarations enable more
opportunities in optimization, because the compiler might treat explic-
itly defaulted functions as trivial.
struct A {
A() {}
~A();
};
A::~A() {}
// becomes
struct A {
A() = default;
~A();
};
A::~A() = default;
NOTE:
Move-constructor and move-assignment operator are not supported yet.
modernize-use-equals-delete
This check marks unimplemented private special member functions with =
delete. To avoid false-positives, this check only applies in a trans-
lation unit that has all other member functions implemented.
struct A {
private:
A(const A&);
A& operator=(const A&);
};
// becomes
struct A {
private:
A(const A&) = delete;
A& operator=(const A&) = delete;
};
modernize-use-nullptr
The check converts the usage of null pointer constants (eg. NULL, 0) to
use the new C++11 nullptr keyword.
Example
void assignment() {
char *a = NULL;
char *b = 0;
char c = 0;
}
int *ret_ptr() {
return 0;
}
transforms to:
void assignment() {
char *a = nullptr;
char *b = nullptr;
char c = 0;
}
int *ret_ptr() {
return nullptr;
}
Options
UserNullMacros
Comma-separated list of macro names that will be transformed
along with NULL. By default this check will only replace the
NULL macro and will skip any similar user-defined macros.
Example
#define MY_NULL (void*)0
void assignment() {
void *p = MY_NULL;
}
transforms to:
#define MY_NULL NULL
void assignment() {
int *p = nullptr;
}
if the UserNullMacros option is set to MY_NULL.
modernize-use-override
Use C++11as override and remove virtual where applicable.
modernize-use-transparent-functors
Prefer transparent functors to non-transparent ones. When using trans-
parent functors, the type does not need to be repeated. The code is
easier to read, maintain and less prone to errors. It is not possible
to introduce unwanted conversions.
// Non-transparent functor
std::map<int, std::string, std::greater<int>> s;
// Transparent functor.
std::map<int, std::string, std::greater<>> s;
// Non-transparent functor
using MyFunctor = std::less<MyType>;
It is not always a safe transformation though. The following case will
be untouched to preserve the semantics.
// Non-transparent functor
std::map<const char *, std::string, std::greater<std::string>> s;
Options
SafeMode
If the option is set to non-zero, the check will not diagnose
cases where using a transparent functor cannot be guaranteed to
produce identical results as the original code. The default
value for this option is 0.
This check requires using C++14 or higher to run.
modernize-use-using
The check converts the usage of typedef with using keyword.
Before:
typedef int variable;
class Class{};
typedef void (Class::* MyPtrType)() const;
After:
using variable = int;
class Class{};
using MyPtrType = void (Class::*)() const;
This check requires using C++11 or higher to run.
mpi-buffer-deref
This check verifies if a buffer passed to an MPI (Message Passing
Interface) function is sufficiently dereferenced. Buffers should be
passed as a single pointer or array. As MPI function signatures specify
void * for their buffer types, insufficiently dereferenced buffers can
be passed, like for example as double pointers or multidimensional
arrays, without a compiler warning emitted.
Examples:
// A double pointer is passed to the MPI function.
char *buf;
MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
// A multidimensional array is passed to the MPI function.
short buf[1][1];
MPI_Send(buf, 1, MPI_SHORT, 0, 0, MPI_COMM_WORLD);
// A pointer to an array is passed to the MPI function.
short *buf[1];
MPI_Send(buf, 1, MPI_SHORT, 0, 0, MPI_COMM_WORLD);
mpi-type-mismatch
This check verifies if buffer type and MPI (Message Passing Interface)
datatype pairs match for used MPI functions. All MPI datatypes defined
by the MPI standard (3.1) are verified by this check. User defined
typedefs, custom MPI datatypes and null pointer constants are skipped,
in the course of verification.
Example:
// In this case, the buffer type matches MPI datatype.
char buf;
MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
// In the following case, the buffer type does not match MPI datatype.
int buf;
MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
performance-faster-string-find
Optimize calls to std::string::find() and friends when the needle
passed is a single character string literal. The character literal
overload is more efficient.
Examples:
str.find("A");
// becomes
str.find('A');
Options
StringLikeClasses
Semicolon-separated list of names of string-like classes. By
default only std::basic_string is considered. The list of meth-
ods to consired is fixed.
performance-for-range-copy
Finds C++11 for ranges where the loop variable is copied in each itera-
tion but it would suffice to obtain it by const reference.
The check is only applied to loop variables of types that are expensive
to copy which means they are not trivially copyable or have a non-triv-
ial copy constructor or destructor.
To ensure that it is safe to replace the copy with a const reference
the following heuristic is employed:
1. The loop variable is const qualified.
2. The loop variable is not const, but only const methods or operators
are invoked on it, or it is used as const reference or value argu-
ment in constructors or function calls.
Options
WarnOnAllAutoCopies
When non-zero, warns on any use of auto as the type of the
range-based for loop variable. Default is 0.
performance-implicit-cast-in-loop
This warning appears in a range-based loop with a loop variable of
const ref type where the type of the variable does not match the one
returned by the iterator. This means that an implicit cast has been
added, which can for example result in expensive deep copies.
Example:
map<int, vector<string>> my_map;
for (const pair<int, vector<string>>& p : my_map) {}
// The iterator type is in fact pair<const int, vector<string>>, which means
// that the compiler added a cast, resulting in a copy of the vectors.
The easiest solution is usually to use const auto& instead of writing
the type manually.
performance-inefficient-string-concatenation
This check warns about the performance overhead arising from concate-
nating strings using the operator+, for instance:
std::string a("Foo"), b("Bar");
a = a + b;
Instead of this structure you should use operator+= or std::stringas
(std::basic_string) class member function append(). For instance:
std::string a("Foo"), b("Baz");
for (int i = 0; i < 20000; ++i) {
a = a + "Bar" + b;
}
Could be rewritten in a greatly more efficient way like:
std::string a("Foo"), b("Baz");
for (int i = 0; i < 20000; ++i) {
a.append("Bar").append(b);
}
And this can be rewritten too:
void f(const std::string&) {}
std::string a("Foo"), b("Baz");
void g() {
f(a + "Bar" + b);
}
In a slightly more efficient way like:
void f(const std::string&) {}
std::string a("Foo"), b("Baz");
void g() {
f(std::string(a).append("Bar").append(b));
}
Options
StrictMode
When zero, the check will only check the string usage in while,
for and for-range statements. Default is 0.
performance-type-promotion-in-math-fn
Finds calls to C math library functions (from math.h or, in C++, cmath)
with implicit float to double promotions.
For example, warns on ::sin(0.f), because this funcitonas parameter is
a double. You probably meant to call std::sin(0.f) (in C++), or
sinf(0.f) (in C).
performance-unnecessary-copy-initialization
Finds local variable declarations that are initialized using the copy
constructor of a non-trivially-copyable type but it would suffice to
obtain a const reference.
The check is only applied if it is safe to replace the copy by a const
reference. This is the case when the variable is const qualified or
when it is only used as a const, i.e. only const methods or operators
are invoked on it, or it is used as const reference or value argument
in constructors or function calls.
Example:
const string& constReference();
void Function() {
// The warning will suggest making this a const reference.
const string UnnecessaryCopy = constReference();
}
struct Foo {
const string& name() const;
};
void Function(const Foo& foo) {
// The warning will suggest making this a const reference.
string UnnecessaryCopy1 = foo.name();
UnnecessaryCopy1.find("bar");
// The warning will suggest making this a const reference.
string UnnecessaryCopy2 = UnnecessaryCopy1;
UnnecessaryCopy2.find("bar");
}
performance-unnecessary-value-param
Flags value parameter declarations of expensive to copy types that are
copied for each invocation but it would suffice to pass them by const
reference.
The check is only applied to parameters of types that are expensive to
copy which means they are not trivially copyable or have a non-trivial
copy constructor or destructor.
To ensure that it is safe to replace the value parameter with a const
reference the following heuristic is employed:
1. the parameter is const qualified;
2. the parameter is not const, but only const methods or operators are
invoked on it, or it is used as const reference or value argument in
constructors or function calls.
Example:
void f(const string Value) {
// The warning will suggest making Value a reference.
}
void g(ExpensiveToCopy Value) {
// The warning will suggest making Value a const reference.
Value.ConstMethd();
ExpensiveToCopy Copy(Value);
}
If the parameter is not const, only copied or assigned once and has a
non-trivial move-constructor or move-assignment operator respectively
the check will suggest to move it.
Example:
void setValue(string Value) {
Field = Value;
}
Will become:
#include <utility>
void setValue(string Value) {
Field = std::move(Value);
}
Options
IncludeStyle
A string specifying which include-style is used, llvm or google.
Default is llvm.
readability-avoid-const-params-in-decls
Checks whether a function declaration has parameters that are top level
const.
const values in declarations do not affect the signature of a function,
so they should not be put there.
Examples:
void f(const string); // Bad: const is top level.
void f(const string&); // Good: const is not top level.
readability-braces-around-statements
google-readability-braces-around-statements redirects here as an alias
for this check.
Checks that bodies of if statements and loops (for, do while, and
while) are inside braces.
Before:
if (condition)
statement;
After:
if (condition) {
statement;
}
Options
ShortStatementLines
Defines the minimal number of lines that the statement should
have in order to trigger this check.
The number of lines is counted from the end of condition or ini-
tial keyword (do/else) until the last line of the inner state-
ment. Default value 0 means that braces will be added to all
statements (not having them already).
readability-container-size-empty
Checks whether a call to the size() method can be replaced with a call
to empty().
The emptiness of a container should be checked using the empty() method
instead of the size() method. It is not guaranteed that size() is a
constant-time function, and it is generally more efficient and also
shows clearer intent to use empty(). Furthermore some containers may
implement the empty() method but not implement the size() method. Using
empty() whenever possible makes it easier to switch to another con-
tainer in the future.
The check issues warning if a container has size() and empty() methods
matching following signatures:
code-block:: c++
size_type size() const; bool empty() const;
size_type can be any kind of integer type.
readability-delete-null-pointer
Checks the if statements where a pointeras existence is checked and
then deletes the pointer. The check is unnecessary as deleting a null
pointer has no effect.
int *p;
if (p)
delete p;
readability-deleted-default
Checks that constructors and assignment operators marked as = default
are not actually deleted by the compiler.
class Example {
public:
// This constructor is deleted because I is missing a default value.
Example() = default;
// This is fine.
Example(const Example& Other) = default;
// This operator is deleted because I cannot be assigned (it is const).
Example& operator=(const Example& Other) = default;
private:
const int I;
};
readability-else-after-return
LLVM Coding Standards advises to reduce indentation where possible and
where it makes understanding code easier. Early exit is one of the
suggested enforcements of that. Please do not use else or else if after
something that interrupts control flow - like return, break, continue,
throw.
The following piece of code illustrates how the check works. This piece
of code:
void foo(int Value) {
int Local = 0;
for (int i = 0; i < 42; i++) {
if (Value == 1) {
return;
} else {
Local++;
}
if (Value == 2)
continue;
else
Local++;
if (Value == 3) {
throw 42;
} else {
Local++;
}
}
}
Would be transformed into:
void foo(int Value) {
int Local = 0;
for (int i = 0; i < 42; i++) {
if (Value == 1) {
return;
}
Local++;
if (Value == 2)
continue;
Local++;
if (Value == 3) {
throw 42;
}
Local++;
}
}
This check helps to enforce this LLVM Coding Standards recommendation.
readability-function-size
google-readability-function-size redirects here as an alias for this
check.
Checks for large functions based on various metrics.
Options
LineThreshold
Flag functions exceeding this number of lines. The default is -1
(ignore the number of lines).
StatementThreshold
Flag functions exceeding this number of statements. This may
differ significantly from the number of lines for macro-heavy
code. The default is 800.
BranchThreshold
Flag functions exceeding this number of control statements. The
default is -1 (ignore the number of branches).
readability-identifier-naming
Checks for identifiers naming style mismatch.
This check will try to enforce coding guidelines on the identifiers
naming. It supports lower_case, UPPER_CASE, camelBack and CamelCase
casing and tries to convert from one to another if a mismatch is
detected.
It also supports a fixed prefix and suffix that will be prepended or
appended to the identifiers, regardless of the casing.
Many configuration options are available, in order to be able to create
different rules for different kind of identifier. In general, the rules
are falling back to a more generic rule if the specific case is not
configured.
readability-implicit-bool-cast
This check can be used to find implicit conversions between built-in
types and booleans. Depending on use case, it may simply help with
readability of the code, or in some cases, point to potential bugs
which remain unnoticed due to implicit conversions.
The following is a real-world example of bug which was hiding behind
implicit bool cast:
class Foo {
int m_foo;
public:
void setFoo(bool foo) { m_foo = foo; } // warning: implicit cast bool -> int
int getFoo() { return m_foo; }
};
void use(Foo& foo) {
bool value = foo.getFoo(); // warning: implicit cast int -> bool
}
This code is the result of unsuccessful refactoring, where type of
m_foo changed from bool to int. The programmer forgot to change all
occurrences of bool, and the remaining code is no longer correct, yet
it still compiles without any visible warnings.
In addition to issuing warnings, fix-it hints are provided to help
solve the reported issues. This can be used for improving readability
of code, for example:
void conversionsToBool() {
float floating;
bool boolean = floating;
// ^ propose replacement: bool boolean = floating != 0.0f;
int integer;
if (integer) {}
// ^ propose replacement: if (integer != 0) {}
int* pointer;
if (!pointer) {}
// ^ propose replacement: if (pointer == nullptr) {}
while (1) {}
// ^ propose replacement: while (true) {}
}
void functionTakingInt(int param);
void conversionsFromBool() {
bool boolean;
functionTakingInt(boolean);
// ^ propose replacement: functionTakingInt(static_cast<int>(boolean));
functionTakingInt(true);
// ^ propose replacement: functionTakingInt(1);
}
In general, the following cast types are checked:
o integer expression/literal to boolean,
o floating expression/literal to boolean,
o pointer/pointer to member/nullptr/NULL to boolean,
o boolean expression/literal to integer,
o boolean expression/literal to floating.
The rules for generating fix-it hints are:
o in case of casts from other built-in type to bool, an explicit com-
parison is proposed to make it clear what exaclty is being compared:
o bool boolean = floating; is changed to bool boolean = floating ==
0.0f;,
o for other types, appropriate literals are used (0, 0u, 0.0f, 0.0,
nullptr),
o in case of negated expressions cast to bool, the proposed replacement
with comparison is simplified:
o if (!pointer) is changed to if (pointer == nullptr),
o in case of casts from bool to other built-in types, an explicit
static_cast is proposed to make it clear that a cast is taking place:
o int integer = boolean; is changed to int integer =
static_cast<int>(boolean);,
o if the cast is performed on type literals, an equivalent literal is
proposed, according to what type is actually expected, for example:
o functionTakingBool(0); is changed to functionTakingBool(false);,
o functionTakingInt(true); is changed to functionTakingInt(1);,
o for other types, appropriate literals are used (false, true, 0, 1,
0u, 1u, 0.0f, 1.0f, 0.0, 1.0f).
Some additional accommodations are made for pre-C++11 dialects:
o false literal cast to pointer is detected,
o instead of nullptr literal, 0 is proposed as replacement.
Occurrences of implicit casts inside macros and template instantiations
are deliberately ignored, as it is not clear how to deal with such
cases.
Options
AllowConditionalIntegerCasts
When non-zero, the check will allow conditional integer casts.
Default is 0.
AllowConditionalPointerCasts
When non-zero, the check will allow conditional pointer casts.
Default is 0.
readability-inconsistent-declaration-parameter-name
Find function declarations which differ in parameter names.
Example:
// in foo.hpp:
void foo(int a, int b, int c);
// in foo.cpp:
void foo(int d, int e, int f); // warning
This check should help to enforce consistency in large projects, where
it often happens that a definition of function is refactored, changing
the parameter names, but its declaration in header file is not updated.
With this check, we can easily find and correct such inconsistencies,
keeping declaration and definition always in sync.
Unnamed parameters are allowed and are not taken into account when com-
paring function declarations, for example:
void foo(int a);
void foo(int); // no warning
To help with refactoring, in some cases fix-it hints are generated to
align parameter names to a single naming convention. This works with
the assumption that the function definition is the most up-to-date ver-
sion, as it directly references parameter names in its body. Example:
void foo(int a); // warning and fix-it hint (replace "a" to "b")
int foo(int b) { return b + 2; } // definition with use of "b"
In the case of multiple redeclarations or function template specializa-
tions, a warning is issued for every redeclaration or specialization
inconsistent with the definition or the first declaration seen in a
translation unit.
readability-misplaced-array-index
This check warns for unusual array index syntax.
The following code has unusual array index syntax:
void f(int *X, int Y) {
Y[X] = 0;
}
becomes
void f(int *X, int Y) {
X[Y] = 0;
}
The check warns about such unusual syntax for readability reasons:
o There are programmers that are not familiar with this unusual
syntax.
o It is possible that variables are mixed up.
readability-named-parameter
Find functions with unnamed arguments.
The check implements the following rule originating in the Google C++
Style Guide:
https://google.github.io/styleguide/cppguide.html#Function_Declarations_and_Definitions
All parameters should be named, with identical names in the declaration
and implementation.
Corresponding cpplint.py check name: readability/function.
readability-non-const-parameter
The check finds function parameters of a pointer type that could be
changed to point to a constant type instead.
When const is used properly, many mistakes can be avoided. Advantages
when using const properly:
o prevent unintentional modification of data;
o get additional warnings such as using uninitialized data;
o make it easier for developers to see possible side effects.
This check is not strict about constness, it only warns when the const-
ness will make the function interface safer.
// warning here; the declaration "const char *p" would make the function
// interface safer.
char f1(char *p) {
return *p;
}
// no warning; the declaration could be more const "const int * const p" but
// that does not make the function interface safer.
int f2(const int *p) {
return *p;
}
// no warning; making x const does not make the function interface safer
int f3(int x) {
return x;
}
// no warning; Technically, *p can be const ("const struct S *p"). But making
// *p const could be misleading. People might think that it's safe to pass
// const data to this function.
struct S { int *a; int *b; };
int f3(struct S *p) {
*(p->a) = 0;
}
readability-redundant-control-flow
This check looks for procedures (functions returning no value) with
return statements at the end of the function. Such return statements
are redundant.
Loop statements (for, while, do while) are checked for redundant con-
tinue statements at the end of the loop body.
Examples:
The following function f contains a redundant return statement:
extern void g();
void f() {
g();
return;
}
becomes
extern void g();
void f() {
g();
}
The following function k contains a redundant continue statement:
void k() {
for (int i = 0; i < 10; ++i) {
continue;
}
}
becomes
void k() {
for (int i = 0; i < 10; ++i) {
}
}
readability-redundant-declaration
Finds redundant variable and function declarations.
extern int X;
extern int X;
becomes
extern int X;
Such redundant declarations can be removed without changing program be-
haviour. They can for instance be unintentional left overs from previ-
ous refactorings when code has been moved around. Having redundant dec-
larations could in worst case mean that there are typos in the code
that cause bugs.
Normally the code can be automatically fixed, clang-tidy can remove the
second declaration. However there are 2 cases when you need to fix the
code manually:
o When the declarations are in different header files;
o When multiple variables are declared together.
readability-redundant-function-ptr-dereference
Finds redundant dereferences of a function pointer.
Before:
int f(int,int);
int (*p)(int, int) = &f;
int i = (**p)(10, 50);
After:
int f(int,int);
int (*p)(int, int) = &f;
int i = (*p)(10, 50);
readability-redundant-member-init
Finds member initializations that are unnecessary because the same
default constructor would be called if they were not present.
Example:
// Explicitly initializing the member s is unnecessary.
class Foo {
public:
Foo() : s() {}
private:
std::string s;
};
readability-redundant-smartptr-get
google-readability-redundant-smartptr-get redirects here as an alias
for this check.
Find and remove redundant calls to smart pointeras .get() method.
Examples:
ptr.get()->Foo() ==> ptr->Foo()
*ptr.get() ==> *ptr
*ptr->get() ==> **ptr
readability-redundant-string-cstr
Finds unnecessary calls to std::string::c_str() and
std::string::data().
readability-redundant-string-init
Finds unnecessary string initializations.
Examples:
// Initializing string with empty string literal is unnecessary.
std::string a = "";
std::string b("");
readability-simplify-boolean-expr
Looks for boolean expressions involving boolean constants and simpli-
fies them to use the appropriate boolean expression directly.
Examples:
+---------------------------+------------+
|Initial expression | Result |
+---------------------------+------------+
|if (b == true) | if (b) |
+---------------------------+------------+
|if (b == false) | if (!b) |
+---------------------------+------------+
|if (b && true) | if (b) |
+---------------------------+------------+
|if (b && false) | if (false) |
+---------------------------+------------+
|if (b || true) | if (true) |
+---------------------------+------------+
|if (b || false) | if (b) |
+---------------------------+------------+
|e ? true : false | e |
+---------------------------+------------+
|e ? false : true | !e |
+---------------------------+------------+
|if (true) t(); else f(); | t(); |
+---------------------------+------------+
|if (false) t(); else f(); | f(); |
+---------------------------+------------+
|if (e) return true; else | return e; |
|return false; | |
+---------------------------+------------+
|if (e) return false; else | return !e; |
|return true; | |
+---------------------------+------------+
|if (e) b = true; else b = | b = e; |
|false; | |
+---------------------------+------------+
|if (e) b = false; else b = | b = !e; |
|true; | |
+---------------------------+------------+
|if (e) return true; return | return e; |
|false; | |
+---------------------------+------------+
|if (e) return false; | return !e; |
|return true; | |
+---------------------------+------------+
The resulting expression e is modified as follows:
1. Unnecessary parentheses around the expression are removed.
2. Negated applications of ! are eliminated.
3. Negated applications of comparison operators are changed to
use the opposite condition.
4. Implicit conversions of pointers, including pointers to mem-
bers, to bool are replaced with explicit comparisons to
nullptr in C++11 or NULL in C++98/03.
5. Implicit casts to bool are replaced with explicit casts to
bool.
6. Object expressions with explicit operator bool conversion
operators are replaced with explicit casts to bool.
7. Implicit conversions of integral types to bool are replaced
with explicit comparisons to 0.
Examples:
1. The ternary assignment bool b = (i < 0) ? true : false; has
redundant parentheses and becomes bool b = i < 0;.
2. The conditional return if (!b) return false; return true; has
an implied double negation and becomes return b;.
3. The conditional return if (i < 0) return false; return true;
becomes return i >= 0;.
The conditional return if (i != 0) return false; return true;
becomes return i == 0;.
4. The conditional return if (p) return true; return false; has
an implicit conversion of a pointer to bool and becomes
return p != nullptr;.
The ternary assignment bool b = (i & 1) ? true : false; has
an implicit conversion of i & 1 to bool and becomes bool b =
(i & 1) != 0;.
5. The conditional return if (i & 1) return true; else return
false; has an implicit conversion of an integer quantity i &
1 to bool and becomes return (i & 1) != 0;
6. Given struct X { explicit operator bool(); };, and an
instance x of struct X, the conditional return if (x) return
true; return false; becomes return static_cast<bool>(x);
Options
ChainedConditionalReturn
If non-zero, conditional boolean return statements at the end of
an if/else if chain will be transformed. Default is 0.
ChainedConditionalAssignment
If non-zero, conditional boolean assignments at the end of an
if/else if chain will be transformed. Default is 0.
readability-static-definition-in-anonymous-namespace
Finds static function and variable definitions in anonymous namespace.
In this case, static is redundant, because anonymous namespace limits
the visibility of definitions to a single translation unit.
namespace {
static int a = 1; // Warning.
static const b = 1; // Warning.
}
The check will apply a fix by removing the redundant static qualifier.
readability-uniqueptr-delete-release
Replace delete <unique_ptr>.release() with <unique_ptr> = nullptr. The
latter is shorter, simpler and does not require use of raw pointer
APIs.
clang-tidy is a clang-based C++ alintera tool. Its purpose is to pro-
vide an extensible framework for diagnosing and fixing typical program-
ming errors, like style violations, interface misuse, or bugs that can
be deduced via static analysis. clang-tidy is modular and provides a
convenient interface for writing new checks.
Using clang-tidy
clang-tidy is a LibTooling-based tool, and itas easier to work with if
you set up a compile command database for your project (for an example
of how to do this see How To Setup Tooling For LLVM). You can also
specify compilation options on the command line after --:
$ clang-tidy test.cpp -- -Imy_project/include -DMY_DEFINES ...
clang-tidy has its own checks and can also run Clang static analyzer
checks. Each check has a name and the checks to run can be chosen using
the -checks= option, which specifies a comma-separated list of positive
and negative (prefixed with -) globs. Positive globs add subsets of
checks, negative globs remove them. For example,
$ clang-tidy test.cpp -checks=-*,clang-analyzer-*,-clang-analyzer-cplusplus*
will disable all default checks (-*) and enable all clang-analyzer-*
checks except for clang-analyzer-cplusplus* ones.
The -list-checks option lists all the enabled checks. When used without
-checks=, it shows checks enabled by default. Use -checks=* to see all
available checks or with any other value of -checks= to see which
checks are enabled by this value.
There are currently the following groups of checks:
+-------------------+----------------------------+
|Name prefix | Description |
+-------------------+----------------------------+
|boost- | Checks related to Boost |
| | library. |
+-------------------+----------------------------+
|cert- | Checks related to CERT |
| | Secure Coding Guidelines. |
+-------------------+----------------------------+
|cppcoreguidelines- | Checks related to C++ Core |
| | Guidelines. |
+-------------------+----------------------------+
|clang-analyzer- | Clang Static Analyzer |
| | checks. |
+-------------------+----------------------------+
|google- | Checks related to the |
| | Google coding conventions. |
+-------------------+----------------------------+
|llvm- | Checks related to the LLVM |
| | coding conventions. |
+-------------------+----------------------------+
|misc- | Checks that we didnat have |
| | a better category for. |
+-------------------+----------------------------+
|modernize- | Checks that advocate usage |
| | of modern (currently amod- |
| | erna means aC++11a) lan- |
| | guage constructs. |
+-------------------+----------------------------+
|mpi- | Checks related to MPI |
| | (Message Passing Inter- |
| | face). |
+-------------------+----------------------------+
|performance- | Checks that target perfor- |
| | mance-related issues. |
+-------------------+----------------------------+
|readability- | Checks that target read- |
| | ability-related issues |
| | that donat relate to any |
| | particular coding style. |
+-------------------+----------------------------+
Clang diagnostics are treated in a similar way as check diagnostics.
Clang diagnostics are displayed by clang-tidy and can be filtered out
using -checks= option. However, the -checks= option does not affect
compilation arguments, so it can not turn on Clang warnings which are
not already turned on in build configuration. The -warnings-as-errors=
option upgrades any warnings emitted under the -checks= flag to errors
(but it does not enable any checks itself).
Clang diagnostics have check names starting with clang-diagnostic-.
Diagnostics which have a corresponding warning option, are named
clang-diagnostic-<warning-option>, e.g. Clang warning controlled by
-Wliteral-conversion will be reported with check name clang-diagnos-
tic-literal-conversion.
The -fix flag instructs clang-tidy to fix found errors if supported by
corresponding checks.
An overview of all the command-line options:
$ clang-tidy -help
USAGE: clang-tidy [options] <source0> [... <sourceN>]
OPTIONS:
Generic Options:
-help - Display available options (-help-hidden for more)
-help-list - Display list of available options (-help-list-hidden for more)
-version - Display the version of this program
clang-tidy options:
-analyze-temporary-dtors -
Enable temporary destructor-aware analysis in
clang-analyzer- checks.
This option overrides the value read from a
.clang-tidy file.
-checks=<string> -
Comma-separated list of globs with optional '-'
prefix. Globs are processed in order of
appearance in the list. Globs without '-'
prefix add checks with matching names to the
set, globs with the '-' prefix remove checks
with matching names from the set of enabled
checks. This option's value is appended to the
value of the 'Checks' option in .clang-tidy
file, if any.
-config=<string> -
Specifies a configuration in YAML/JSON format:
-config="{Checks: '*',
CheckOptions: [{key: x,
value: y}]}"
When the value is empty, clang-tidy will
attempt to find a file named .clang-tidy for
each source file in its parent directories.
-dump-config -
Dumps configuration in the YAML format to
stdout. This option can be used along with a
file name (and '--' if the file is outside of a
project with configured compilation database).
The configuration used for this file will be
printed.
Use along with -checks=* to include
configuration of all checks.
-enable-check-profile -
Enable per-check timing profiles, and print a
report to stderr.
-explain-config -
For each enabled check explains, where it is
enabled, i.e. in clang-tidy binary, command
line or a specific configuration file.
-export-fixes=<filename> -
YAML file to store suggested fixes in. The
stored fixes can be applied to the input source
code with clang-apply-replacements.
-extra-arg=<string> - Additional argument to append to the compiler command line
-extra-arg-before=<string> - Additional argument to prepend to the compiler command line
-fix -
Apply suggested fixes. Without -fix-errors
clang-tidy will bail out if any compilation
errors were found.
-fix-errors -
Apply suggested fixes even if compilation
errors were found. If compiler errors have
attached fix-its, clang-tidy will apply them as
well.
-header-filter=<string> -
Regular expression matching the names of the
headers to output diagnostics from. Diagnostics
from the main file of each translation unit are
always displayed.
Can be used together with -line-filter.
This option overrides the 'HeaderFilter' option
in .clang-tidy file, if any.
-line-filter=<string> -
List of files with line ranges to filter the
warnings. Can be used together with
-header-filter. The format of the list is a
JSON array of objects:
[
{"name":"file1.cpp","lines":[[1,3],[5,7]]},
{"name":"file2.h"}
]
-list-checks -
List all enabled checks and exit. Use with
-checks=* to list all available checks.
-p=<string> - Build path
-style=<string> -
Fallback style for reformatting after inserting fixes
if there is no clang-format config file found.
-system-headers - Display the errors from system headers.
-warnings-as-errors=<string> -
Upgrades warnings to errors. Same format as
'-checks'.
This option's value is appended to the value of
the 'WarningsAsErrors' option in .clang-tidy
file, if any.
-p <build-path> is used to read a compile command database.
For example, it can be a CMake build directory in which a file named
compile_commands.json exists (use -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
CMake option to get this output). When no build path is specified,
a search for compile_commands.json will be attempted through all
parent paths of the first input file . See:
http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html for an
example of setting up Clang Tooling on a source tree.
<source0> ... specify the paths of source files. These paths are
looked up in the compile command database. If the path of a file is
absolute, it needs to point into CMake's source tree. If the path is
relative, the current working directory needs to be in the CMake
source tree and the file must be in a subdirectory of the current
working directory. "./" prefixes in the relative files will be
automatically removed, but the rest of a relative path must be a
suffix of a path in the compile command database.
Configuration files:
clang-tidy attempts to read configuration for each source file from a
.clang-tidy file located in the closest parent directory of the source
file. If any configuration options have a corresponding command-line
option, command-line option takes precedence. The effective
configuration can be inspected using -dump-config:
$ clang-tidy -dump-config - --
---
Checks: '-*,some-check'
WarningsAsErrors: ''
HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false
User: user
CheckOptions:
- key: some-check.SomeOption
value: 'some value'
...
Getting Involved
clang-tidy has several own checks and can run Clang static analyzer
checks, but its power is in the ability to easily write custom checks.
Checks are organized in modules, which can be linked into clang-tidy
with minimal or no code changes in clang-tidy.
Checks can plug into the analysis on the preprocessor level using
PPCallbacks or on the AST level using AST Matchers. When an error is
found, checks can report them in a way similar to how Clang diagnostics
work. A fix-it hint can be attached to a diagnostic message.
The interface provided by clang-tidy makes it easy to write useful and
precise checks in just a few lines of code. If you have an idea for a
good check, the rest of this document explains how to do this.
There are a few tools particularly useful when developing clang-tidy
checks:
o add_new_check.py is a script to automate the process of adding
a new check, it will create the check, update the CMake file
and create a test;
o rename_check.py does what the script name suggests, renames an
existing check;
o clang-query is invaluable for interactive prototyping of AST
matchers and exploration of the Clang AST;
o clang-check with the -ast-dump (and optionally -ast-dump-fil-
ter) provides a convenient way to dump AST of a C++ program.
Choosing the Right Place for your Check
If you have an idea of a check, you should decide whether it should be
implemented as a:
o Clang diagnostic: if the check is generic enough, targets code pat-
terns that most probably are bugs (rather than style or readability
issues), can be implemented effectively and with extremely low false
positive rate, it may make a good Clang diagnostic.
o Clang static analyzer check: if the check requires some sort of con-
trol flow analysis, it should probably be implemented as a static
analyzer check.
o clang-tidy check is a good choice for linter-style checks, checks
that are related to a certain coding style, checks that address code
readability, etc.
Preparing your Workspace
If you are new to LLVM development, you should read the Getting Started
with the LLVM System, Using Clang Tools and How To Setup Tooling For
LLVM documents to check out and build LLVM, Clang and Clang Extra Tools
with CMake.
Once you are done, change to the llvm/tools/clang/tools/extra direc-
tory, and letas start!
The Directory Structure
clang-tidy source code resides in the llvm/tools/clang/tools/extra
directory and is structured as follows:
clang-tidy/ # Clang-tidy core.
|-- ClangTidy.h # Interfaces for users and checks.
|-- ClangTidyModule.h # Interface for clang-tidy modules.
|-- ClangTidyModuleRegistry.h # Interface for registering of modules.
...
|-- google/ # Google clang-tidy module.
|-+
|-- GoogleTidyModule.cpp
|-- GoogleTidyModule.h
...
|-- llvm/ # LLVM clang-tidy module.
|-+
|-- LLVMTidyModule.cpp
|-- LLVMTidyModule.h
...
|-- tool/ # Sources of the clang-tidy binary.
...
test/clang-tidy/ # Integration tests.
...
unittests/clang-tidy/ # Unit tests.
|-- ClangTidyTest.h
|-- GoogleModuleTest.cpp
|-- LLVMModuleTest.cpp
...
Writing a clang-tidy Check
So you have an idea of a useful check for clang-tidy.
First, if youare not familiar with LLVM development, read through the
Getting Started with LLVM document for instructions on setting up your
workflow and the LLVM Coding Standards document to familiarize yourself
with the coding style used in the project. For code reviews we mostly
use LLVM Phabricator.
Next, you need to decide which module the check belongs to. Modules are
located in subdirectories of clang-tidy/ and contain checks targeting a
certain aspect of code quality (performance, readability, etc.), cer-
tain coding style or standard (Google, LLVM, CERT, etc.) or a widely
used API (e.g. MPI). Their names are same as user-facing check groups
names described above.
After choosing the module and the name for the check, run the
clang-tidy/add_new_check.py script to create the skeleton of the check
and plug it to clang-tidy. Itas the recommended way of adding new
checks.
If we want to create a readability-awesome-function-names, we would
run:
$ clang-tidy/add_new_check.py readability awesome-function-names
The add_new_check.py script will:
o create the class for your check inside the specified moduleas
directory and register it in the module and in the build sys-
tem;
o create a lit test file in the test/clang-tidy/ directory;
o create a documentation file and include it into the
docs/clang-tidy/checks/list.rst.
Letas see in more detail at the check class definition:
...
#include "../ClangTidy.h"
namespace clang {
namespace tidy {
namespace readability {
...
class AwesomeFunctionNamesCheck : public ClangTidyCheck {
public:
AwesomeFunctionNamesCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context) {}
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
};
} // namespace readability
} // namespace tidy
} // namespace clang
...
Constructor of the check receives the Name and Context parameters, and
must forward them to the ClangTidyCheck constructor.
In our case the check needs to operate on the AST level and it over-
rides the registerMatchers and check methods. If we wanted to analyze
code on the preprocessor level, wead need instead to override the reg-
isterPPCallbacks method.
In the registerMatchers method we create an AST Matcher (see AST Match-
ers for more information) that will find the pattern in the AST that we
want to inspect. The results of the matching are passed to the check
method, which can further inspect them and report diagnostics.
using namespace ast_matchers;
void AwesomeFunctionNamesCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(functionDecl().bind("x"), this);
}
void AwesomeFunctionNamesCheck::check(const MatchFinder::MatchResult &Result) {
const auto *MatchedDecl = Result.Nodes.getNodeAs<FunctionDecl>("x");
if (MatchedDecl->getName().startswith("awesome_"))
return;
diag(MatchedDecl->getLocation(), "function %0 is insufficiently awesome")
<< MatchedDecl
<< FixItHint::CreateInsertion(MatchedDecl->getLocation(), "awesome_");
}
(If you want to see an example of a useful check, look at
clang-tidy/google/ExplicitConstructorCheck.h and
clang-tidy/google/ExplicitConstructorCheck.cpp).
Registering your Check
(The add_new_check.py takes care of registering the check in an exist-
ing module. If you want to create a new module or know the details,
read on.)
The check should be registered in the corresponding module with a dis-
tinct name:
class MyModule : public ClangTidyModule {
public:
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
CheckFactories.registerCheck<ExplicitConstructorCheck>(
"my-explicit-constructor");
}
};
Now we need to register the module in the ClangTidyModuleRegistry using
a statically initialized variable:
static ClangTidyModuleRegistry::Add<MyModule> X("my-module",
"Adds my lint checks.");
When using LLVM build system, we need to use the following hack to
ensure the module is linked into the clang-tidy binary:
Add this near the ClangTidyModuleRegistry::Add<MyModule> variable:
// This anchor is used to force the linker to link in the generated object file
// and thus register the MyModule.
volatile int MyModuleAnchorSource = 0;
And this to the main translation unit of the clang-tidy binary (or the
binary you link the clang-tidy library in) clang-tidy/tool/ClangTidy-
Main.cpp:
// This anchor is used to force the linker to link the MyModule.
extern volatile int MyModuleAnchorSource;
static int MyModuleAnchorDestination = MyModuleAnchorSource;
Configuring Checks
If a check needs configuration options, it can access check-specific
options using the Options.get<Type>("SomeOption", DefaultValue) call in
the check constructor. In this case the check should also override the
ClangTidyCheck::storeOptions method to make the options provided by the
check discoverable. This method lets clang-tidy know which options the
check implements and what the current values are (e.g. for the
-dump-config command line option).
class MyCheck : public ClangTidyCheck {
const unsigned SomeOption1;
const std::string SomeOption2;
public:
MyCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
SomeOption(Options.get("SomeOption1", -1U)),
SomeOption(Options.get("SomeOption2", "some default")) {}
void storeOptions(ClangTidyOptions::OptionMap &Opts) override {
Options.store(Opts, "SomeOption1", SomeOption1);
Options.store(Opts, "SomeOption2", SomeOption2);
}
...
Assuming the check is registered with the name amy-checka, the option
can then be set in a .clang-tidy file in the following way:
CheckOptions:
- key: my-check.SomeOption1
value: 123
- key: my-check.SomeOption2
value: 'some other value'
If you need to specify check options on a command line, you can use the
inline YAML format:
$ clang-tidy -config="{CheckOptions: [{key: a, value: b}, {key: x, value: y}]}" ...
Testing Checks
clang-tidy checks can be tested using either unit tests or lit tests.
Unit tests may be more convenient to test complex replacements with
strict checks. Lit tests allow using partial text matching and regular
expressions which makes them more suitable for writing compact tests
for diagnostic messages.
The check_clang_tidy.py script provides an easy way to test both diag-
nostic messages and fix-its. It filters out CHECK lines from the test
file, runs clang-tidy and verifies messages and fixes with two separate
FileCheck invocations: once with FileCheckas directive prefix set to
CHECK-MESSAGES, validating the diagnostic messages, and once with the
directive prefix set to CHECK-FIXES, running against the fixed code
(i.e., the code after generated fixits are applied). In particular,
CHECK-FIXES: can be used to check that code was not modified by fixits,
by checking that it is present unchanged in the fixed code. The full
set of FileCheck directives is available (e.g., CHECK-MESSAGES-SAME:,
CHECK-MESSAGES-NOT:), though typically the basic CHECK forms
(CHECK-MESSAGES and CHECK-FIXES) are sufficient for clang-tidy tests.
Note that the FileCheck documentation mostly assumes the default prefix
(CHECK), and hence describes the directive as CHECK:, CHECK-SAME:,
CHECK-NOT:, etc. Replace CHECK by either CHECK-FIXES or CHECK-MESSAGES
for clang-tidy tests.
An additional check enabled by check_clang_tidy.py ensures that if
CHECK-MESSAGES: is used in a file then every warning or error must have
an associated CHECK in that file.
To use the check_clang_tidy.py script, put a .cpp file with the appro-
priate RUN line in the test/clang-tidy directory. Use CHECK-MESSAGES:
and CHECK-FIXES: lines to write checks against diagnostic messages and
fixed code.
Itas advised to make the checks as specific as possible to avoid checks
matching to incorrect parts of the input. Use [[@LINE+X]]/[[@LINE-X]]
substitutions and distinct function and variable names in the test
code.
Hereas an example of a test using the check_clang_tidy.py script (the
full source code is at test/clang-tidy/google-readability-casting.cpp):
// RUN: %check_clang_tidy %s google-readability-casting %t
void f(int a) {
int b = (int)a;
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant cast to the same type [google-readability-casting]
// CHECK-FIXES: int b = a;
}
There are many dark corners in the C++ language, and it may be diffi-
cult to make your check work perfectly in all cases, especially if it
issues fix-it hints. The most frequent pitfalls are macros and tem-
plates:
1. code written in a macro body/template definition may have a differ-
ent meaning depending on the macro expansion/template instantiation;
2. multiple macro expansions/template instantiations may result in the
same code being inspected by the check multiple times (possibly,
with different meanings, see 1), and the same warning (or a slightly
different one) may be issued by the check multiple times; clang-tidy
will deduplicate _identical_ warnings, but if the warnings are
slightly different, all of them will be shown to the user (and used
for applying fixes, if any);
3. making replacements to a macro body/template definition may be fine
for some macro expansions/template instantiations, but easily break
some other expansions/instantiations.
Running clang-tidy on LLVM
To test a check itas best to try it out on a larger code base. LLVM and
Clang are the natural targets as you already have the source code
around. The most convenient way to run clang-tidy is with a compile
command database; CMake can automatically generate one, for a descrip-
tion of how to enable it see How To Setup Tooling For LLVM. Once com-
pile_commands.json is in place and a working version of clang-tidy is
in PATH the entire code base can be analyzed with
clang-tidy/tool/run-clang-tidy.py. The script executes clang-tidy with
the default set of checks on every translation unit in the compile com-
mand database and displays the resulting warnings and errors. The
script provides multiple configuration flags.
o The default set of checks can be overridden using the -checks argu-
ment, taking the identical format as clang-tidy does. For example
-checks=-*,modernize-use-override will run the modernize-use-override
check only.
o To restrict the files examined you can provide one or more regex
arguments that the file names are matched against. run-clang-tidy.py
clang-tidy/.*Check\.cpp will only analyze clang-tidy checkers. It may
also be necessary to restrict the header files warnings are displayed
from using the -header-filter flag. It has the same behavior as the
corresponding clang-tidy flag.
o To apply suggested fixes -fix can be passed as an argument. This
gathers all changes in a temporary directory and applies them. Pass-
ing -format will run clang-format over changed lines.
CLANG-INCLUDE-FIXER
Contents
o Clang-Include-Fixer
o Setup
o Creating a Symbol Index From a Compilation Database
o Integrate with Vim
o Integrate with Emacs
o How it Works
One of the major nuisances of C++ compared to other languages is the
manual management of #include directives in any file.
clang-include-fixer addresses one aspect of this problem by providing
an automated way of adding #include directives for missing symbols in
one translation unit.
While inserting missing #include, clang-include-fixer adds missing
namespace qualifiers to all instances of an unidentified symbol if the
symbol is missing some prefix namespace qualifiers.
Setup
To use clang-include-fixer two databases are required. Both can be gen-
erated with existing tools.
o Compilation database. Contains the compiler commands for any given
file in a project and can be generated by CMake, see How To Setup
Tooling For LLVM.
o Symbol index. Contains all symbol information in a project to match a
given identifier to a header file.
Ideally both databases (compile_commands.json and find_all_sym-
bols_db.yaml) are linked into the root of the source tree they corre-
spond to. Then the clang-include-fixer can automatically pick them up
if called with a source file from that tree. Note that by default com-
pile_commands.json as generated by CMake does not include header files,
so only implementation files can be handled by tools.
Creating a Symbol Index From a Compilation Database
The include fixer contains find-all-symbols, a tool to create a symbol
database in YAML format from a compilation database by parsing all
source files listed in it. The following list of commands shows how to
set up a database for LLVM, any project built by CMake should follow
similar steps.
$ cd path/to/llvm-build
$ ninja find-all-symbols // build find-all-symbols tool.
$ ninja clang-include-fixer // build clang-include-fixer tool.
$ ls compile_commands.json # Make sure compile_commands.json exists.
compile_commands.json
$ path/to/llvm/source/tools/clang/tools/extra/include-fixer/find-all-symbols/tool/run-find-all-symbols.py
... wait as clang indexes the code base ...
$ ln -s $PWD/find_all_symbols_db.yaml path/to/llvm/source/ # Link database into the source tree.
$ ln -s $PWD/compile_commands.json path/to/llvm/source/ # Also link compilation database if it's not there already.
$ cd path/to/llvm/source
$ /path/to/clang-include-fixer -db=yaml path/to/file/with/missing/include.cpp
Added #include "foo.h"
Integrate with Vim
To run clang-include-fixer on a potentially unsaved buffer in Vim. Add
the following key binding to your .vimrc:
noremap <leader>cf :pyf path/to/llvm/source/tools/clang/tools/extra/include-fixer/tool/clang-include-fixer.py<cr>
This enables clang-include-fixer for NORMAL and VISUAL mode. Change
<leader>cf to another binding if you need clang-include-fixer on a dif-
ferent key. The <leader> key is a reference to a specific key defined
by the mapleader variable and is bound to backslash by default.
Make sure vim can find clang-include-fixer:
o Add the path to clang-include-fixer to the PATH environment variable.
o Or set g:clang_include_fixer_path in vimrc: let
g:clang_include_fixer_path=path/to/clang-include-fixer
You can customize the number of headers being shown by setting let
g:clang_include_fixer_maximum_suggested_headers=5
Customized settings in .vimrc:
o let g:clang_include_fixer_path = "clang-include-fixer"
Set clang-include-fixer binary file path.
o let g:clang_include_fixer_maximum_suggested_headers = 3
Set the maximum number of #includes to show. Default is 3.
o let g:clang_include_fixer_increment_num = 5
Set the increment number of #includes to show every time when press-
ing m. Default is 5.
o let g:clang_include_fixer_jump_to_include = 0
Set to 1 if you want to jump to the new inserted #include line.
Default is 0.
o let g:clang_include_fixer_query_mode = 0
Set to 1 if you want to insert #include for the symbol under the cur-
sor. Default is 0. Compared to normal mode, this mode wonat parse
the source file and only search the sysmbol from database, which is
faster than normal mode.
See clang-include-fixer.py for more details.
Integrate with Emacs
To run clang-include-fixer on a potentially unsaved buffer in Emacs.
Ensure that Emacs finds clang-include-fixer.el by adding the directory
containing the file to the load-path and requiring the
clang-include-fixer in your .emacs:
(add-to-list 'load-path "path/to/llvm/source/tools/clang/tools/extra/include-fixer/tool/"
(require 'clang-include-fixer)
Within Emacs the tool can be invoked with the command M-x
clang-include-fixer. This will insert the header that defines the first
undefined symbol; if there is more than one header that would define
the symbol, the user is prompted to select one.
To include the header that defines the symbol at point, run M-x
clang-include-fixer-at-point.
Make sure Emacs can find clang-include-fixer:
o Either add the parent directory of clang-include-fixer to the PATH
environment variable, or customize the Emacs user option
clang-include-fixer-executable to point to the file name of the pro-
gram.
How it Works
To get the most information out of Clang at parse time,
clang-include-fixer runs in tandem with the parse and receives call-
backs from Clangas semantic analysis. In particular it reuses the
existing support for typo corrections. Whenever Clang tries to correct
a potential typo it emits a callback to the include fixer which then
looks for a corresponding file. At this point rich lookup information
is still available, which is not available in the AST at a later stage.
The identifier that should be typo corrected is then sent to the data-
base, if a header file is returned it is added as an include directive
at the top of the file.
Currently clang-include-fixer only inserts a single include at a time
to avoid getting caught in follow-up errors. If multiple #include addi-
tions are desired the program can be rerun until a fix-point is
reached.
MODULARIZE USERaS MANUAL
Modularize Usage
modularize [<modularize-options>] [<module-map>|<include-files-list>]*
[<front-end-options>...]
<modularize-options> is a place-holder for options specific to modular-
ize, which are described below in Modularize Command Line Options.
<module-map> specifies the path of a file name for an existing module
map. The module map must be well-formed in terms of syntax. Modularize
will extract the header file names from the map. Only normal headers
are checked, assuming headers marked aprivatea, atextuala, or aexcludea
are not to be checked as a top-level include, assuming they either are
included by other headers which are checked, or they are not suitable
for modules.
<include-files-list> specifies the path of a file name for a file con-
taining the newline-separated list of headers to check with respect to
each other. Lines beginning with a#a and empty lines are ignored.
Header file names followed by a colon and other space-separated file
names will include those extra files as dependencies. The file names
can be relative or full paths, but must be on the same line. For exam-
ple:
header1.h
header2.h
header3.h: header1.h header2.h
Note that unless a -prefix (header path) option is specified, non-abso-
lute file paths in the header list file will be relative to the header
list file directory. Use -prefix to specify a different directory.
<front-end-options> is a place-holder for regular Clang front-end argu-
ments, which must follow the <include-files-list>. Note that by
default, modularize assumes .h files contain C++ source, so if you are
using a different language, you might need to use a -x option to tell
Clang that the header contains another language, i.e.: -x c
Note also that because modularize does not use the clang driver, you
will likely need to pass in additional compiler front-end arguments to
match those passed in by default by the driver.
Modularize Command Line Options
-prefix=<header-path>
Prepend the given path to non-absolute file paths in the header
list file. By default, headers are assumed to be relative to
the header list file directory. Use -prefix to specify a differ-
ent directory.
-module-map-path=<module-map-path>
Generate a module map and output it to the given file. See the
description in module-map-generation.
-problem-files-list=<problem-files-list-file-name>
For use only with module map assistant. Input list of files that
have problems with respect to modules. These will still be
included in the generated module map, but will be marked as
aexcludeda headers.
-root-module=<root-name>
Put modules generated by the -module-map-path option in an
enclosing module with the given name. See the description in
module-map-generation.
-block-check-header-list-only
Limit the #include-inside-extern-or-namespace-block check to
only those headers explicitly listed in the header list. This
is a work-around for avoiding error messages for private
includes that purposefully get included inside blocks.
-no-coverage-check
Donat do the coverage check for a module map.
-coverage-check-only
Only do the coverage check for a module map.
-display-file-lists
Display lists of good files (no compile errors), problem files,
and a combined list with problem files preceded by a a#a. This
can be used to quickly determine which files have problems. The
latter combined list might be useful in starting to modularize a
set of headers. You can start with a full list of headers, use
-display-file-lists option, and then use the combined list as
your intermediate list, uncommenting-out headers as you fix
them.
modularize is a standalone tool that checks whether a set of headers
provides the consistent definitions required to use modules. For exam-
ple, it detects whether the same entity (say, a NULL macro or size_t
typedef) is defined in multiple headers or whether a header produces
different definitions under different circumstances. These conditions
cause modules built from the headers to behave poorly, and should be
fixed before introducing a module map.
modularize also has an assistant mode option for generating a module
map file based on the provided header list. The generated file is a
functional module map that can be used as a starting point for a mod-
ule.map file.
Getting Started
To build from source:
1. Read Getting Started with the LLVM System and Clang Tools Documenta-
tion for information on getting sources for LLVM, Clang, and Clang
Extra Tools.
2. Getting Started with the LLVM System and Building LLVM with CMake
give directions for how to build. With sources all checked out into
the right place the LLVM build will build Clang Extra Tools and
their dependencies automatically.
o If using CMake, you can also use the modularize target to build
just the modularize tool and its dependencies.
Before continuing, take a look at ModularizeUsage to see how to invoke
modularize.
What Modularize Checks
Modularize will check for the following:
o Duplicate global type and variable definitions
o Duplicate macro definitions
o Macro instances, adefined(macro)a, or #if, #elif, #ifdef, #ifndef
conditions that evaluate differently in a header
o #include directives inside aextern aC/C++a {}a or anamespace (name)
{}a blocks
o Module map header coverage completeness (in the case of a module map
input only)
Modularize will do normal C/C++ parsing, reporting normal errors and
warnings, but will also report special error messages like the follow-
ing:
error: '(symbol)' defined at multiple locations:
(file):(row):(column)
(file):(row):(column)
error: header '(file)' has different contents depending on how it was included
The latter might be followed by messages like the following:
note: '(symbol)' in (file) at (row):(column) not always provided
Checks will also be performed for macro expansions, defined(macro)
expressions, and preprocessor conditional directives that evaluate
inconsistently, and can produce error messages like the following:
(...)/SubHeader.h:11:5:
#if SYMBOL == 1
^
error: Macro instance 'SYMBOL' has different values in this header,
depending on how it was included.
'SYMBOL' expanded to: '1' with respect to these inclusion paths:
(...)/Header1.h
(...)/SubHeader.h
(...)/SubHeader.h:3:9:
#define SYMBOL 1
^
Macro defined here.
'SYMBOL' expanded to: '2' with respect to these inclusion paths:
(...)/Header2.h
(...)/SubHeader.h
(...)/SubHeader.h:7:9:
#define SYMBOL 2
^
Macro defined here.
Checks will also be performed for a#includea directives that are nested
inside aextern aC/C++a {}a or anamespace (name) {}a blocks, and can
produce error message like the following:
IncludeInExtern.h:2:3:
#include "Empty.h"
^
error: Include directive within extern "C" {}.
IncludeInExtern.h:1:1:
extern "C" {
^
The "extern "C" {}" block is here.
Module Map Coverage Check
The coverage check uses the Clang library to read and parse the module
map file. Starting at the module map file directory, or just the
include paths, if specified, it will collect the names of all the files
it considers headers (no extension, .h, or .incaif you need more, mod-
ify the isHeader function). It then compares the headers against those
referenced in the module map, either explicitly named, or implicitly
named via an umbrella directory or umbrella file, as parsed by the Mod-
uleMap object. If headers are found which are not referenced or cov-
ered by an umbrella directory or file, warning messages will be pro-
duced, and this program will return an error code of 1. If no problems
are found, an error code of 0 is returned.
Note that in the case of umbrella headers, this tool invokes the com-
piler to preprocess the file, and uses a callback to collect the header
files included by the umbrella header or any of its nested includes. If
any front end options are needed for these compiler invocations, these
can be included on the command line after the module map file argument.
Warning message have the form:
warning: module.modulemap does not account for file: Level3A.h
Note that for the case of the module map referencing a file that does
not exist, the module map parser in Clang will (at the time of this
writing) display an error message.
To limit the checks modularize does to just the module map coverage
check, use the -coverage-check-only option.
For example:
modularize -coverage-check-only module.modulemap
Module Map Generation
If you specify the -module-map-path=<module map file>, modularize will
output a module map based on the input header list. A module will be
created for each header. Also, if the header in the header list is a
partial path, a nested module hierarchy will be created in which a mod-
ule will be created for each subdirectory component in the header path,
with the header itself represented by the innermost module. If other
headers use the same subdirectories, they will be enclosed in these
same modules also.
For example, for the header list:
SomeTypes.h
SomeDecls.h
SubModule1/Header1.h
SubModule1/Header2.h
SubModule2/Header3.h
SubModule2/Header4.h
SubModule2.h
The following module map will be generated:
// Output/NoProblemsAssistant.txt
// Generated by: modularize -module-map-path=Output/NoProblemsAssistant.txt \
-root-module=Root NoProblemsAssistant.modularize
module SomeTypes {
header "SomeTypes.h"
export *
}
module SomeDecls {
header "SomeDecls.h"
export *
}
module SubModule1 {
module Header1 {
header "SubModule1/Header1.h"
export *
}
module Header2 {
header "SubModule1/Header2.h"
export *
}
}
module SubModule2 {
module Header3 {
header "SubModule2/Header3.h"
export *
}
module Header4 {
header "SubModule2/Header4.h"
export *
}
header "SubModule2.h"
export *
}
An optional -root-module=<root-name> option can be used to cause a root
module to be created which encloses all the modules.
An optional -problem-files-list=<problem-file-name> can be used to
input a list of files to be excluded, perhaps as a temporary stop-gap
measure until problem headers can be fixed.
For example, with the same header list from above:
// Output/NoProblemsAssistant.txt
// Generated by: modularize -module-map-path=Output/NoProblemsAssistant.txt \
-root-module=Root NoProblemsAssistant.modularize
module Root {
module SomeTypes {
header "SomeTypes.h"
export *
}
module SomeDecls {
header "SomeDecls.h"
export *
}
module SubModule1 {
module Header1 {
header "SubModule1/Header1.h"
export *
}
module Header2 {
header "SubModule1/Header2.h"
export *
}
}
module SubModule2 {
module Header3 {
header "SubModule2/Header3.h"
export *
}
module Header4 {
header "SubModule2/Header4.h"
export *
}
header "SubModule2.h"
export *
}
}
Note that headers with dependents will be ignored with a warning, as
the Clang module mechanism doesnat support headers the rely on other
headers to be included first.
The module map format defines some keywords which canat be used in mod-
ule names. If a header has one of these names, an underscore (a_a) will
be prepended to the name. For example, if the header name is header.h,
because header is a keyword, the module name will be _header. For a
list of the module map keywords, please see: Lexical structure
PP-TRACE USERaS MANUAL
pp-trace is a standalone tool that traces preprocessor activity. Itas
also used as a test of Clangas PPCallbacks interface. It runs a given
source file through the Clang preprocessor, displaying selected infor-
mation from callback functions overridden in a PPCallbacks derivation.
The output is in a high-level YAML format, described in pp-trace Output
Format.
pp-trace Usage
Command Line Format
pp-trace [<pp-trace-options>] <source-file> [<front-end-options>]
<pp-trace-options> is a place-holder for options specific to pp-trace,
which are described below in Command Line Options.
<source-file> specifies the source file to run through the preproces-
sor.
<front-end-options> is a place-holder for regular Clang Compiler
Options, which must follow the <source-file>.
Command Line Options
-ignore <callback-name-list>
This option specifies a comma-separated list of names of call-
backs that shouldnat be traced. It can be used to eliminate
unwanted trace output. The callback names are the name of the
actual callback function names in the PPCallbacks class:
o FileChanged
o FileSkipped
o FileNotFound
o InclusionDirective
o moduleImport
o EndOfMainFile
o Ident
o PragmaDirective
o PragmaComment
o PragmaDetectMismatch
o PragmaDebug
o PragmaMessage
o PragmaDiagnosticPush
o PragmaDiagnosticPop
o PragmaDiagnostic
o PragmaOpenCLExtension
o PragmaWarning
o PragmaWarningPush
o PragmaWarningPop
o MacroExpands
o MacroDefined
o MacroUndefined
o Defined
o SourceRangeSkipped
o If
o Elif
o Ifdef
o Ifndef
o Else
o Endif
-output <output-file>
By default, pp-trace outputs the trace information to stdout.
Use this option to output the trace information to a file.
pp-trace Output Format
The pp-trace output is formatted as YAML. See http://yaml.org/ for gen-
eral YAML information. Itas arranged as a sequence of information about
the callback call, including the callback name and argument informa-
tion, for example::
---
- Callback: Name
Argument1: Value1
Argument2: Value2
(etc.)
...
With real data::
---
- Callback: FileChanged
Loc: "c:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-include.cpp:1:1"
Reason: EnterFile
FileType: C_User
PrevFID: (invalid)
(etc.)
- Callback: FileChanged
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-include.cpp:5:1"
Reason: ExitFile
FileType: C_User
PrevFID: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/Input/Level1B.h"
- Callback: EndOfMainFile
...
In all but one case (MacroDirective) the aArgumenta scalars have the
same name as the argument in the corresponding PPCallbacks callback
function.
Callback Details
The following sections describe the pupose and output format for each
callback.
Click on the callback name in the section heading to see the Doxygen
documentation for the callback.
The argument descriptions table describes the callback argument infor-
mation displayed.
The Argument Name field in most (but not all) cases is the same name as
the callback function parameter.
The Argument Value Syntax field describes the values that will be dis-
played for the argument value. It uses an ad hoc representation that
mixes literal and symbolic representations. Enumeration member symbols
are shown as the actual enum member in a (member1|member2|a|) form. A
name in parentheses can either represent a place holder for the
described value, or confusingly, it might be a literal, such as (null),
for a null pointer. Locations are shown as quoted only to avoid con-
fusing the documentation generator.
The Clang C++ Type field is the type from the callback function decla-
ration.
The description describes the argument or what is displayed for it.
Note that in some cases, such as when a structure pointer is an argu-
ment value, only some key member or members are shown to represent the
value, instead of trying to display all members of the structure.
FileChanged Callback
FileChanged is called when the preprocessor enters or exits a file,
both the top level file being compiled, as well as any #include direc-
tives. It will also be called as a result of a system header pragma or
in internal renaming of a file.
Argument descriptions:
+--------------+-----------------------+------------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+-----------------------+------------------+------------------+
|Loc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the directive. |
+--------------+-----------------------+------------------+------------------+
|Reason | (EnterFile|Exit- | PPCall- | Reason for |
| | File|SystemHeader- | backs::FileChan- | change. |
| | Pragma|RenameFile) | geReason | |
+--------------+-----------------------+------------------+------------------+
|FileType | (C_User|C_Sys- | SrcMgr::Charac- | Include type. |
| | tem|C_ExternCSystem) | teristicKind | |
+--------------+-----------------------+------------------+------------------+
|PrevFID | ((file)|(invalid)) | FileID | Previous file, |
| | | | if any. |
+--------------+-----------------------+------------------+------------------+
Example::
- Callback: FileChanged
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-include.cpp:1:1"
Reason: EnterFile
FileType: C_User
PrevFID: (invalid)
FileSkipped Callback
FileSkipped is called when a source file is skipped as the result of
header guard optimization.
Argument descriptions:
+--------------+------------------+-----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+------------------+-----------------+------------------+
|ParentFile | (a(file)a or | const FileEntry | The file that |
| | (null)) | | #included the |
| | | | skipped file. |
+--------------+------------------+-----------------+------------------+
|FilenameTok | (token) | const Token | The token in |
| | | | ParentFile that |
| | | | indicates the |
| | | | skipped file. |
+--------------+------------------+-----------------+------------------+
|FileType | (C_User|C_Sys- | SrcMgr::Charac- | The file type. |
| | tem|C_ExternC- | teristicKind | |
| | System) | | |
+--------------+------------------+-----------------+------------------+
Example::
- Callback: FileSkipped
ParentFile: "/path/filename.h"
FilenameTok: "filename.h"
FileType: C_User
FileNotFound Callback
FileNotFound is called when an inclusion directive results in a
file-not-found error.
Argument descriptions:
+--------------+------------------+----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+------------------+----------------+------------------+
|FileName | a(file)a | StringRef | The name of the |
| | | | file being |
| | | | included, as |
| | | | written in the |
| | | | source code. |
+--------------+------------------+----------------+------------------+
|RecoveryPath | (path) | SmallVec- | If this client |
| | | torImpl<char> | indicates that |
| | | | it can recover |
| | | | from this miss- |
| | | | ing file, the |
| | | | client should |
| | | | set this as an |
| | | | additional |
| | | | header search |
| | | | patch. |
+--------------+------------------+----------------+------------------+
Example::
- Callback: FileNotFound
FileName: "/path/filename.h"
RecoveryPath:
InclusionDirective Callback
InclusionDirective is called when an inclusion directive of any kind
(#include</code>, #import</code>, etc.) has been processed, regardless
of whether the inclusion will actually result in an inclusion.
Argument descriptions:
+--------------+-----------------------+-----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+-----------------------+-----------------+------------------+
|HashLoc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the a#a that |
| | | | starts the |
| | | | inclusion direc- |
| | | | tive. |
+--------------+-----------------------+-----------------+------------------+
|IncludeTok | (token) | const Token | The token that |
| | | | indicates the |
| | | | kind of inclu- |
| | | | sion directive, |
| | | | e.g., aincludea |
| | | | or aimporta. |
+--------------+-----------------------+-----------------+------------------+
|FileName | a(file)a | StringRef | The name of the |
| | | | file being |
| | | | included, as |
| | | | written in the |
| | | | source code. |
+--------------+-----------------------+-----------------+------------------+
|IsAngled | (true|false) | bool | Whether the file |
| | | | name was |
| | | | enclosed in |
| | | | angle brackets; |
| | | | otherwise, it |
| | | | was enclosed in |
| | | | quotes. |
+--------------+-----------------------+-----------------+------------------+
|FilenameRange | a(file)a | CharSourceRange | The character |
| | | | range of the |
| | | | quotes or angle |
| | | | brackets for the |
| | | | written file |
| | | | name. |
+--------------+-----------------------+-----------------+------------------+
|File | a(file)a | const FileEntry | The actual file |
| | | | that may be |
| | | | included by this |
| | | | inclusion direc- |
| | | | tive. |
+--------------+-----------------------+-----------------+------------------+
|SearchPath | a(path)a | StringRef | Contains the |
| | | | search path |
| | | | which was used |
| | | | to find the file |
| | | | in the file sys- |
| | | | tem. |
+--------------+-----------------------+-----------------+------------------+
|RelativePath | a(path)a | StringRef | The path rela- |
| | | | tive to Search- |
| | | | Path, at which |
| | | | the include file |
| | | | was found. |
+--------------+-----------------------+-----------------+------------------+
|Imported | ((module | const Module | The module, |
| | name)|(null)) | | whenever an |
| | | | inclusion direc- |
| | | | tive was auto- |
| | | | matically turned |
| | | | into a module |
| | | | import or null |
| | | | otherwise. |
+--------------+-----------------------+-----------------+------------------+
Example::
- Callback: InclusionDirective
IncludeTok: include
FileName: "Input/Level1B.h"
IsAngled: false
FilenameRange: "Input/Level1B.h"
File: "D:/Clang/llvmnewmod/tools/clang/tools/extra/test/pp-trace/Input/Level1B.h"
SearchPath: "D:/Clang/llvmnewmod/tools/clang/tools/extra/test/pp-trace"
RelativePath: "Input/Level1B.h"
Imported: (null)
moduleImport Callback
moduleImport is called when there was an explicit module-import syntax.
Argument descriptions:
+--------------+-----------------------+----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+-----------------------+----------------+------------------+
|ImportLoc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | import directive |
| | | | token. |
+--------------+-----------------------+----------------+------------------+
|Path | a(path)a | ModuleIdPath | The identifiers |
| | | | (and their loca- |
| | | | tions) of the |
| | | | module apatha. |
+--------------+-----------------------+----------------+------------------+
|Imported | ((module | const Module | The imported |
| | name)|(null)) | | module; can be |
| | | | null if import- |
| | | | ing failed. |
+--------------+-----------------------+----------------+------------------+
Example::
- Callback: moduleImport
ImportLoc: "d:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-modules.cpp:4:2"
Path: [{Name: Level1B, Loc: "d:/Clang/llvmnewmod/tools/clang/tools/extra/test/pp-trace/pp-trace-modules.cpp:4:9"}, {Name: Level2B, Loc: "d:/Clang/llvmnewmod/tools/clang/tools/extra/test/pp-trace/pp-trace-modules.cpp:4:17"}]
Imported: Level2B
EndOfMainFile Callback
EndOfMainFile is called when the end of the main file is reached.
Argument descriptions:
+---------------+------------------+----------------+-------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+---------------+------------------+----------------+-------------+
|(no arguments) | | | |
+---------------+------------------+----------------+-------------+
Example::
- Callback: EndOfMainFile
Ident Callback
Ident is called when a #ident or #sccs directive is read.
Argument descriptions:
+--------------+-----------------------+----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+-----------------------+----------------+------------------+
|Loc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the directive. |
+--------------+-----------------------+----------------+------------------+
|str | (name) | const | The text of the |
| | | std::string | directive. |
+--------------+-----------------------+----------------+------------------+
Example::
- Callback: Ident
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-ident.cpp:3:1"
str: "$Id$"
PragmaDirective Callback
PragmaDirective is called when start reading any pragma directive.
Argument descriptions:
+--------------+----------------------------------+-----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+----------------------------------+-----------------+------------------+
|Loc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the directive. |
+--------------+----------------------------------+-----------------+------------------+
|Introducer | (PIK_Hash- | PragmaIntroduc- | The type of the |
| | Pragma|PIK__Pragma|PIK___pragma) | erKind | pragma direc- |
| | | | tive. |
+--------------+----------------------------------+-----------------+------------------+
Example::
- Callback: PragmaDirective
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1"
Introducer: PIK_HashPragma
PragmaComment Callback
PragmaComment is called when a #pragma comment directive is read.
Argument descriptions:
+--------------+-----------------------+------------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+-----------------------+------------------+------------------+
|Loc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the directive. |
+--------------+-----------------------+------------------+------------------+
|Kind | ((name)|(null)) | const Identi- | The comment kind |
| | | fierInfo | symbol. |
+--------------+-----------------------+------------------+------------------+
|Str | (message directive) | const | The comment mes- |
| | | std::string | sage directive. |
+--------------+-----------------------+------------------+------------------+
Example::
- Callback: PragmaComment
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1"
Kind: library
Str: kernel32.lib
PragmaDetectMismatch Callback
PragmaDetectMismatch is called when a #pragma detect_mismatch directive
is read.
Argument descriptions:
+--------------+-----------------------+----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+-----------------------+----------------+------------------+
|Loc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the directive. |
+--------------+-----------------------+----------------+------------------+
|Name | a(name)a | const | The name. |
| | | std::string | |
+--------------+-----------------------+----------------+------------------+
|Value | (string) | const | The value. |
| | | std::string | |
+--------------+-----------------------+----------------+------------------+
Example::
- Callback: PragmaDetectMismatch
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1"
Name: name
Value: value
PragmaDebug Callback
PragmaDebug is called when a #pragma clang __debug directive is read.
Argument descriptions:
+--------------+-----------------------+----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+-----------------------+----------------+------------------+
|Loc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the directive. |
+--------------+-----------------------+----------------+------------------+
|DebugType | (string) | StringRef | Indicates type |
| | | | of debug mes- |
| | | | sage. |
+--------------+-----------------------+----------------+------------------+
Example::
- Callback: PragmaDebug
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1"
DebugType: warning
PragmaMessage Callback
PragmaMessage is called when a #pragma message directive is read.
Argument descriptions:
+--------------+-----------------------+----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+-----------------------+----------------+------------------+
|Loc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the directive. |
+--------------+-----------------------+----------------+------------------+
|Namespace | (name) | StringRef | The namespace of |
| | | | the message |
| | | | directive. |
+--------------+-----------------------+----------------+------------------+
|Kind | (PMK_Mes- | PPCall- | The type of the |
| | sage|PMK_Warn- | backs::Prag- | message direc- |
| | ing|PMK_Error) | maMessageKind | tive. |
+--------------+-----------------------+----------------+------------------+
|Str | (string) | StringRef | The text of the |
| | | | message direc- |
| | | | tive. |
+--------------+-----------------------+----------------+------------------+
Example::
- Callback: PragmaMessage
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1"
Namespace: "GCC"
Kind: PMK_Message
Str: The message text.
PragmaDiagnosticPush Callback
PragmaDiagnosticPush is called when a #pragma gcc dianostic push direc-
tive is read.
Argument descriptions:
+--------------+-----------------------+----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+-----------------------+----------------+------------------+
|Loc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the directive. |
+--------------+-----------------------+----------------+------------------+
|Namespace | (name) | StringRef | Namespace name. |
+--------------+-----------------------+----------------+------------------+
Example::
- Callback: PragmaDiagnosticPush
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1"
Namespace: "GCC"
PragmaDiagnosticPop Callback
PragmaDiagnosticPop is called when a #pragma gcc dianostic pop direc-
tive is read.
Argument descriptions:
+--------------+-----------------------+----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+-----------------------+----------------+------------------+
|Loc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the directive. |
+--------------+-----------------------+----------------+------------------+
|Namespace | (name) | StringRef | Namespace name. |
+--------------+-----------------------+----------------+------------------+
Example::
- Callback: PragmaDiagnosticPop
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1"
Namespace: "GCC"
PragmaDiagnostic Callback
PragmaDiagnostic is called when a #pragma gcc dianostic directive is
read.
Argument descriptions:
+--------------+--------------------------+----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+--------------------------+----------------+------------------+
|Loc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the directive. |
+--------------+--------------------------+----------------+------------------+
|Namespace | (name) | StringRef | Namespace name. |
+--------------+--------------------------+----------------+------------------+
|mapping | (0|MAP_IGNORE|MAP_WARN- | diag::Severity | Mapping type. |
| | ING|MAP_ERROR|MAP_FATAL) | | |
+--------------+--------------------------+----------------+------------------+
|Str | (string) | StringRef | Warning/error |
| | | | name. |
+--------------+--------------------------+----------------+------------------+
Example::
- Callback: PragmaDiagnostic
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1"
Namespace: "GCC"
mapping: MAP_WARNING
Str: WarningName
PragmaOpenCLExtension Callback
PragmaOpenCLExtension is called when OpenCL extension is either dis-
abled or enabled with a pragma.
Argument descriptions:
+--------------+-----------------------+------------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+-----------------------+------------------+------------------+
|NameLoc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the name. |
+--------------+-----------------------+------------------+------------------+
|Name | (name) | const Identi- | Name symbol. |
| | | fierInfo | |
+--------------+-----------------------+------------------+------------------+
|StateLoc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the state. |
+--------------+-----------------------+------------------+------------------+
|State | (1|0) | unsigned | Enabled/disabled |
| | | | state. |
+--------------+-----------------------+------------------+------------------+
Example::
- Callback: PragmaOpenCLExtension
NameLoc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:10"
Name: Name
StateLoc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:18"
State: 1
PragmaWarning Callback
PragmaWarning is called when a #pragma warning directive is read.
Argument descriptions:
+--------------+-----------------------+----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+-----------------------+----------------+------------------+
|Loc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the directive. |
+--------------+-----------------------+----------------+------------------+
|WarningSpec | (string) | StringRef | The warning |
| | | | specifier. |
+--------------+-----------------------+----------------+------------------+
|Ids | [(number)[, a|]] | ArrayRef<int> | The warning num- |
| | | | bers. |
+--------------+-----------------------+----------------+------------------+
Example::
- Callback: PragmaWarning
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1"
WarningSpec: disable
Ids: 1,2,3
PragmaWarningPush Callback
PragmaWarningPush is called when a #pragma warning(push) directive is
read.
Argument descriptions:
+--------------+-----------------------+----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+-----------------------+----------------+------------------+
|Loc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the directive. |
+--------------+-----------------------+----------------+------------------+
|Level | (number) | int | Warning level. |
+--------------+-----------------------+----------------+------------------+
Example::
- Callback: PragmaWarningPush
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1"
Level: 1
PragmaWarningPop Callback
PragmaWarningPop is called when a #pragma warning(pop) directive is
read.
Argument descriptions:
+--------------+-----------------------+----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+-----------------------+----------------+------------------+
|Loc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the directive. |
+--------------+-----------------------+----------------+------------------+
Example::
- Callback: PragmaWarningPop
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1"
MacroExpands Callback
MacroExpands is called when ::HandleMacroExpandedIdentifier when a
macro invocation is found.
Argument descriptions:
+---------------+-------------------------+------------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+---------------+-------------------------+------------------+------------------+
|MacroNameTok | (token) | const Token | The macro name |
| | | | token. |
+---------------+-------------------------+------------------+------------------+
|MacroDirective | (MD_Define|MD_Unde- | const MacroDi- | The kind of |
| | fine|MD_Visibil- | rective | macro directive |
| | ity) | | from the |
| | | | MacroDirective |
| | | | structure. |
+---------------+-------------------------+------------------+------------------+
|Range | [a(file):(line):(col)a, | SourceRange | The source range |
| | a(file):(line):(col)a] | | for the expan- |
| | | | sion. |
+---------------+-------------------------+------------------+------------------+
|Args | [(name)|(num- | const MacroArgs | The argument |
| | ber)|<(token name)>[, | | tokens. Names |
| | a|]] | | and numbers are |
| | | | literal, every- |
| | | | thing else is of |
| | | | the form a<a |
| | | | tokenName a>a. |
+---------------+-------------------------+------------------+------------------+
Example::
- Callback: MacroExpands
MacroNameTok: X_IMPL
MacroDirective: MD_Define
Range: [(nonfile), (nonfile)]
Args: [a <plus> y, b]
MacroDefined Callback
MacroDefined is called when a macro definition is seen.
Argument descriptions:
+---------------+---------------------+------------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+---------------+---------------------+------------------+------------------+
|MacroNameTok | (token) | const Token | The macro name |
| | | | token. |
+---------------+---------------------+------------------+------------------+
|MacroDirective | (MD_Define|MD_Unde- | const MacroDi- | The kind of |
| | fine|MD_Visibil- | rective | macro directive |
| | ity) | | from the |
| | | | MacroDirective |
| | | | structure. |
+---------------+---------------------+------------------+------------------+
Example::
- Callback: MacroDefined
MacroNameTok: X_IMPL
MacroDirective: MD_Define
MacroUndefined Callback
MacroUndefined is called when a macro #undef is seen.
Argument descriptions:
+---------------+---------------------+------------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+---------------+---------------------+------------------+------------------+
|MacroNameTok | (token) | const Token | The macro name |
| | | | token. |
+---------------+---------------------+------------------+------------------+
|MacroDirective | (MD_Define|MD_Unde- | const MacroDi- | The kind of |
| | fine|MD_Visibil- | rective | macro directive |
| | ity) | | from the |
| | | | MacroDirective |
| | | | structure. |
+---------------+---------------------+------------------+------------------+
Example::
- Callback: MacroUndefined
MacroNameTok: X_IMPL
MacroDirective: MD_Define
Defined Callback
Defined is called when the adefineda operator is seen.
Argument descriptions:
+---------------+-------------------------+------------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+---------------+-------------------------+------------------+------------------+
|MacroNameTok | (token) | const Token | The macro name |
| | | | token. |
+---------------+-------------------------+------------------+------------------+
|MacroDirective | (MD_Define|MD_Unde- | const MacroDi- | The kind of |
| | fine|MD_Visibil- | rective | macro directive |
| | ity) | | from the |
| | | | MacroDirective |
| | | | structure. |
+---------------+-------------------------+------------------+------------------+
|Range | [a(file):(line):(col)a, | SourceRange | The source range |
| | a(file):(line):(col)a] | | for the direc- |
| | | | tive. |
+---------------+-------------------------+------------------+------------------+
Example::
- Callback: Defined
MacroNameTok: MACRO
MacroDirective: (null)
Range: ["D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:5", "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:19"]
SourceRangeSkipped Callback
SourceRangeSkipped is called when a source range is skipped.
Argument descriptions:
+--------------+-------------------------+----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+-------------------------+----------------+------------------+
|Range | [a(file):(line):(col)a, | SourceRange | The source range |
| | a(file):(line):(col)a] | | skipped. |
+--------------+-------------------------+----------------+------------------+
Example::
- Callback: SourceRangeSkipped
Range: [":/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:2", ":/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:9:2"]
If Callback
If is called when an #if is seen.
Argument descriptions:
+---------------+-------------------------+----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+---------------+-------------------------+----------------+------------------+
|Loc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the directive. |
+---------------+-------------------------+----------------+------------------+
|ConditionRange | [a(file):(line):(col)a, | SourceRange | The source range |
| | a(file):(line):(col)a] | | for the condi- |
| | | | tion. |
+---------------+-------------------------+----------------+------------------+
|ConditionValue | (true|false) | bool | The condition |
| | | | value. |
+---------------+-------------------------+----------------+------------------+
Example::
- Callback: If
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:2"
ConditionRange: ["D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:4", "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:9:1"]
ConditionValue: false
Elif Callback
Elif is called when an #elif is seen.
Argument descriptions:
+---------------+-------------------------+----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+---------------+-------------------------+----------------+------------------+
|Loc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the directive. |
+---------------+-------------------------+----------------+------------------+
|ConditionRange | [a(file):(line):(col)a, | SourceRange | The source range |
| | a(file):(line):(col)a] | | for the condi- |
| | | | tion. |
+---------------+-------------------------+----------------+------------------+
|ConditionValue | (true|false) | bool | The condition |
| | | | value. |
+---------------+-------------------------+----------------+------------------+
|IfLoc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the directive. |
+---------------+-------------------------+----------------+------------------+
Example::
- Callback: Elif
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:10:2"
ConditionRange: ["D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:10:4", "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:11:1"]
ConditionValue: false
IfLoc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:2"
Ifdef Callback
Ifdef is called when an #ifdef is seen.
Argument descriptions:
+---------------+-----------------------+------------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+---------------+-----------------------+------------------+------------------+
|Loc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the directive. |
+---------------+-----------------------+------------------+------------------+
|MacroNameTok | (token) | const Token | The macro name |
| | | | token. |
+---------------+-----------------------+------------------+------------------+
|MacroDirective | (MD_Define|MD_Unde- | const MacroDi- | The kind of |
| | fine|MD_Visibility) | rective | macro directive |
| | | | from the |
| | | | MacroDirective |
| | | | structure. |
+---------------+-----------------------+------------------+------------------+
Example::
- Callback: Ifdef
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-conditional.cpp:3:1"
MacroNameTok: MACRO
MacroDirective: MD_Define
Ifndef Callback
Ifndef is called when an #ifndef is seen.
Argument descriptions:
+---------------+-----------------------+------------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+---------------+-----------------------+------------------+------------------+
|Loc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the directive. |
+---------------+-----------------------+------------------+------------------+
|MacroNameTok | (token) | const Token | The macro name |
| | | | token. |
+---------------+-----------------------+------------------+------------------+
|MacroDirective | (MD_Define|MD_Unde- | const MacroDi- | The kind of |
| | fine|MD_Visibility) | rective | macro directive |
| | | | from the |
| | | | MacroDirective |
| | | | structure. |
+---------------+-----------------------+------------------+------------------+
Example::
- Callback: Ifndef
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-conditional.cpp:3:1"
MacroNameTok: MACRO
MacroDirective: MD_Define
Else Callback
Else is called when an #else is seen.
Argument descriptions:
+--------------+-----------------------+----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+-----------------------+----------------+------------------+
|Loc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the else direc- |
| | | | tive. |
+--------------+-----------------------+----------------+------------------+
|IfLoc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the if direc- |
| | | | tive. |
+--------------+-----------------------+----------------+------------------+
Example::
- Callback: Else
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:10:2"
IfLoc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:2"
Endif Callback
Endif is called when an #endif is seen.
Argument descriptions:
+--------------+-----------------------+----------------+------------------+
|Argument Name | Argument Value | Clang C++ Type | Description |
| | Syntax | | |
+--------------+-----------------------+----------------+------------------+
|Loc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the endif direc- |
| | | | tive. |
+--------------+-----------------------+----------------+------------------+
|IfLoc | a(file):(line):(col)a | SourceLocation | The location of |
| | | | the if direc- |
| | | | tive. |
+--------------+-----------------------+----------------+------------------+
Example::
- Callback: Endif
Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:10:2"
IfLoc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:2"
Building pp-trace
To build from source:
1. Read Getting Started with the LLVM System and Clang Tools Documenta-
tion for information on getting sources for LLVM, Clang, and Clang
Extra Tools.
2. Getting Started with the LLVM System and Building LLVM with CMake
give directions for how to build. With sources all checked out into
the right place the LLVM build will build Clang Extra Tools and
their dependencies automatically.
o If using CMake, you can also use the pp-trace target to build just
the pp-trace tool and its dependencies.
CLANG-RENAME
Contents
o Clang-Rename
o Using Clang-Rename
o Vim Integration
o Emacs Integration
See also:
clang-rename is a C++ refactoring tool. Its purpose is to perform effi-
cient renaming actions in large-scale projects such as renaming
classes, functions, variables, arguments, namespaces etc.
The tool is in a very early development stage, so you might encounter
bugs and crashes. Submitting reports with information about how to
reproduce the issue to the LLVM bugtracker will definitely help the
project. If you have any ideas or suggestions, you might want to put a
feature request there.
Using Clang-Rename
clang-rename is a LibTooling-based tool, and itas easier to work with
if you set up a compile command database for your project (for an exam-
ple of how to do this see How To Setup Tooling For LLVM). You can also
specify compilation options on the command line after ^<i>a:
$ clang-rename -offset=42 -new-name=foo test.cpp -- -Imy_project/include -DMY_DEFINES ...
To get an offset of a symbol in a file run
$ grep -FUbo 'foo' file.cpp
The tool currently supports renaming actions inside a single transla-
tion unit only. It is planned to extend the toolas functionality to
support multi-TU renaming actions in the future.
clang-rename also aims to be easily integrated into popular text edi-
tors, such as Vim and Emacs, and improve the workflow of users.
Although a command line interface exists, it is highly recommended to
use the text editor interface instead for better experience.
You can also identify one or more symbols to be renamed by giving the
fully qualified name:
$ clang-rename -qualified-name=foo -new-name=bar test.cpp
Renaming multiple symbols at once is supported, too. However,
clang-rename doesnat accept both -offset and -qualified-name at the
same time. So, you can either specify multiple -offset or -quali-
fied-name.
$ clang-rename -offset=42 -new-name=bar1 -offset=150 -new-name=bar2 test.cpp
or
$ clang-rename -qualified-name=foo1 -new-name=bar1 -qualified-name=foo2 -new-name=bar2 test.cpp
Alternatively, {offset | qualified-name} / new-name pairs can be put
into a YAML file:
---
- Offset: 42
NewName: bar1
- Offset: 150
NewName: bar2
...
or
---
- QualifiedName: foo1
NewName: bar1
- QualifiedName: foo2
NewName: bar2
...
That way you can avoid spelling out all the names as command line argu-
ments:
$ clang-rename -input=test.yaml test.cpp
clang-rename offers the following options:
$ clang-rename --help
USAGE: clang-rename [subcommand] [options] <source0> [... <sourceN>]
OPTIONS:
Generic Options:
-help - Display available options (-help-hidden for more)
-help-list - Display list of available options (-help-list-hidden for more)
-version - Display the version of this program
clang-rename common options:
-export-fixes=<filename> - YAML file to store suggested fixes in.
-extra-arg=<string> - Additional argument to append to the compiler command line
-extra-arg-before=<string> - Additional argument to prepend to the compiler command line
-i - Overwrite edited <file>s.
-input=<string> - YAML file to load oldname-newname pairs from.
-new-name=<string> - The new name to change the symbol to.
-offset=<uint> - Locates the symbol by offset as opposed to <line>:<column>.
-p=<string> - Build path
-pl - Print the locations affected by renaming to stderr.
-pn - Print the found symbol's name prior to renaming to stderr.
-qualified-name=<string> - The fully qualified name of the symbol.
Vim Integration
You can call clang-rename directly from Vim! To set up clang-rename
integration for Vim see clang-rename/tool/clang-rename.py.
Please note that you have to save all buffers, in which the replacement
will happen before running the tool.
Once installed, you can point your cursor to symbols you want to
rename, press <leader>cr and type new desired name. The <leader> key is
a reference to a specific key defined by the mapleader variable and is
bound to backslash by default.
Emacs Integration
You can also use clang-rename while using Emacs! To set up clang-rename
integration for Emacs see clang-rename/tool/clang-rename.el.
Once installed, you can point your cursor to symbols you want to
rename, press M-X, type clang-rename and new desired name.
Please note that you have to save all buffers, in which the replacement
will happen before running the tool.
o genindex
o search
AUTHOR
The Clang Team
COPYRIGHT
2007-2019, The Clang Team
4 Jan 30, 2019 EXTRACLANGTOOLS(1)