diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.h b/clang-tools-extra/clang-tidy/ClangTidyOptions.h --- a/clang-tools-extra/clang-tidy/ClangTidyOptions.h +++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.h @@ -72,6 +72,10 @@ /// WarningsAsErrors filter. std::optional WarningsAsErrors; + /// Header file extensions to consider to determine if a given diagnostic + /// is located in the main source file or in a header. + std::optional HeaderFileExtensions; + /// Output warnings from headers matching this filter. Warnings from /// main files will always be displayed. std::optional HeaderFilterRegex; diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp --- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp @@ -123,6 +123,7 @@ bool Ignored = false; IO.mapOptional("Checks", Options.Checks); IO.mapOptional("WarningsAsErrors", Options.WarningsAsErrors); + IO.mapOptional("HeaderFileExtensions", Options.HeaderFileExtensions); IO.mapOptional("HeaderFilterRegex", Options.HeaderFilterRegex); IO.mapOptional("AnalyzeTemporaryDtors", Ignored); // legacy compatibility IO.mapOptional("FormatStyle", Options.FormatStyle); @@ -145,6 +146,7 @@ ClangTidyOptions Options; Options.Checks = ""; Options.WarningsAsErrors = ""; + Options.HeaderFileExtensions = ";h;hh;hpp;hxx"; Options.HeaderFilterRegex = ""; Options.SystemHeaders = false; Options.FormatStyle = "none"; @@ -181,6 +183,7 @@ unsigned Order) { mergeCommaSeparatedLists(Checks, Other.Checks); mergeCommaSeparatedLists(WarningsAsErrors, Other.WarningsAsErrors); + overrideValue(HeaderFileExtensions, Other.HeaderFileExtensions); overrideValue(HeaderFilterRegex, Other.HeaderFilterRegex); overrideValue(SystemHeaders, Other.SystemHeaders); overrideValue(FormatStyle, Other.FormatStyle); diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp --- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp +++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp @@ -46,12 +46,13 @@ $ clang-tidy -dump-config --- - Checks: '-*,some-check' - WarningsAsErrors: '' - HeaderFilterRegex: '' - FormatStyle: none - InheritParentConfig: true - User: user + Checks: '-*,some-check' + WarningsAsErrors: '' + HeaderFileExtensions: ';h;hh;hpp;hxx' + HeaderFilterRegex: '' + FormatStyle: none + InheritParentConfig: true + User: user CheckOptions: some-check.SomeOption: 'some value' ... @@ -85,6 +86,21 @@ cl::init(""), cl::cat(ClangTidyCategory)); +static cl::opt HeaderFileExtensions("header-file-extensions", cl::desc(R"( +A semicolon-separated list of filename extensions +of header files (the filename extensions should +not include "." prefix). Default is ";h;hh;hpp;hxx". +This is needed to determine if a given diagnostic +is located in the main source file or in a header. +For extension-less header files, use an empty +string or leave an empty string between ";" if +there are other filename extensions. This option +overrides the 'HeaderFileExtensions' option in +.clang-tidy file, if any. +)"), + cl::init(""), + cl::cat(ClangTidyCategory)); + static cl::opt HeaderFilter("header-filter", cl::desc(R"( Regular expression matching the names of the headers to output diagnostics from. Diagnostics @@ -130,10 +146,10 @@ cl::init(false), cl::cat(ClangTidyCategory)); static cl::opt FixNotes("fix-notes", cl::desc(R"( -If a warning has no fix, but a single fix can -be found through an associated diagnostic note, -apply the fix. -Specifying this flag will implicitly enable the +If a warning has no fix, but a single fix can +be found through an associated diagnostic note, +apply the fix. +Specifying this flag will implicitly enable the '--fix' flag. )"), cl::init(false), cl::cat(ClangTidyCategory)); @@ -306,6 +322,7 @@ ClangTidyOptions DefaultOptions; DefaultOptions.Checks = DefaultChecks; DefaultOptions.WarningsAsErrors = ""; + DefaultOptions.HeaderFileExtensions = HeaderFileExtensions; DefaultOptions.HeaderFilterRegex = HeaderFilter; DefaultOptions.SystemHeaders = SystemHeaders; DefaultOptions.FormatStyle = FormatStyle; @@ -319,6 +336,8 @@ OverrideOptions.Checks = Checks; if (WarningsAsErrors.getNumOccurrences() > 0) OverrideOptions.WarningsAsErrors = WarningsAsErrors; + if (HeaderFileExtensions.getNumOccurrences() > 0) + OverrideOptions.HeaderFileExtensions = HeaderFileExtensions; if (HeaderFilter.getNumOccurrences() > 0) OverrideOptions.HeaderFilterRegex = HeaderFilter; if (SystemHeaders.getNumOccurrences() > 0) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -99,6 +99,9 @@ - Change to Python 3 in the shebang of `add_new_check.py` and `rename_check.py`, as the existing code is not compatible with Python 2. +- New global option `HeaderFileExtensions` (config file) and + `--header-file-extensions` (command line). + New checks ^^^^^^^^^^ diff --git a/clang-tools-extra/docs/clang-tidy/index.rst b/clang-tools-extra/docs/clang-tidy/index.rst --- a/clang-tools-extra/docs/clang-tidy/index.rst +++ b/clang-tools-extra/docs/clang-tidy/index.rst @@ -116,164 +116,165 @@ 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 + --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: - --checks= - - 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= - - Specifies a configuration in YAML/JSON format: - -config="{Checks: '*', - CheckOptions: {x, 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. - --config-file= - - Specify the path of .clang-tidy or custom config file: - e.g. --config-file=/some/path/myTidyConfigFile - This option internally works exactly the same way as - --config option after reading specified config file. - Use either --config-file or --config, not both. - --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= - - YAML file to store suggested fixes in. The - stored fixes can be applied to the input source - code with clang-apply-replacements. - --extra-arg= - Additional argument to append to the compiler command line. - Can be used several times. - --extra-arg-before= - Additional argument to prepend to the compiler command line. - Can be used several times. - --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. - --fix-notes - - If a warning has no fix, but a single fix can - be found through an associated diagnostic note, - apply the fix. - Specifying this flag will implicitly enable the - '--fix' flag. - --format-style= - - Style for formatting code around applied fixes: - - 'none' (default) turns off formatting - - 'file' (literally 'file', not a placeholder) - uses .clang-format file in the closest parent - directory - - '{ }' specifies options inline, e.g. - -format-style='{BasedOnStyle: llvm, IndentWidth: 8}' - - 'llvm', 'google', 'webkit', 'mozilla' - See clang-format documentation for the up-to-date - information about formatting styles and options. - This option overrides the 'FormatStyle` option in - .clang-tidy file, if any. - --header-filter= - - 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 'HeaderFilterRegex' - option in .clang-tidy file, if any. - --line-filter= - - 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. - -load= - - Load the dynamic object ``plugin``. This - object should register new static analyzer - or clang-tidy passes. Once loaded, the - object will add new command line options - to run various analyses. To see the new - complete list of passes, use the - :option:`--list-checks` and - :option:`-load` options together. - -p - Build path - --quiet - - Run clang-tidy in quiet mode. This suppresses - printing statistics about ignored warnings and - warnings treated as errors if the respective - options are specified. - --store-check-profile= - - By default reports are printed in tabulated - format to stderr. When this option is passed, - these per-TU profiles are instead stored as JSON. - --system-headers - Display the errors from system headers. - --use-color - - Use colors in diagnostics. If not set, colors - will be used if the terminal connected to - standard output supports colors. - This option overrides the 'UseColor' option in - .clang-tidy file, if any. - --verify-config - - Check the config files to ensure each check and - option is recognized. - --vfsoverlay= - - Overlay the virtual filesystem described by file - over the real file system. - --warnings-as-errors= - - 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. + --checks= - + 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= - + Specifies a configuration in YAML/JSON format: + -config="{Checks: '*', + CheckOptions: {x: 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. + --config-file= - + Specify the path of .clang-tidy or custom config file: + e.g. --config-file=/some/path/myTidyConfigFile + This option internally works exactly the same way as + --config option after reading specified config file. + Use either --config-file or --config, not both. + --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= - + YAML file to store suggested fixes in. The + stored fixes can be applied to the input source + code with clang-apply-replacements. + --extra-arg= - Additional argument to append to the compiler command line + --extra-arg-before= - 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. + --fix-notes - + If a warning has no fix, but a single fix can + be found through an associated diagnostic note, + apply the fix. + Specifying this flag will implicitly enable the + '--fix' flag. + --format-style= - + Style for formatting code around applied fixes: + - 'none' (default) turns off formatting + - 'file' (literally 'file', not a placeholder) + uses .clang-format file in the closest parent + directory + - '{ }' specifies options inline, e.g. + -format-style='{BasedOnStyle: llvm, IndentWidth: 8}' + - 'llvm', 'google', 'webkit', 'mozilla' + See clang-format documentation for the up-to-date + information about formatting styles and options. + This option overrides the 'FormatStyle` option in + .clang-tidy file, if any. + --header-file-extensions= - + A semicolon-separated list of filename extensions + of header files (the filename extensions should + not include "." prefix). Default is ";h;hh;hpp;hxx". + This is needed to determine if a given diagnostic + is located in the main source file or in a header. + For extension-less header files, use an empty + string or leave an empty string between ";" if + there are other filename extensions. This option + overrides the 'HeaderFileExtensions' option in + .clang-tidy file, if any. + --header-filter= - + 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 'HeaderFilterRegex' + option in .clang-tidy file, if any. + --line-filter= - + 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. + --load= - Load the specified plugin + -p - Build path + --quiet - + Run clang-tidy in quiet mode. This suppresses + printing statistics about ignored warnings and + warnings treated as errors if the respective + options are specified. + --store-check-profile= - + By default reports are printed in tabulated + format to stderr. When this option is passed, + these per-TU profiles are instead stored as JSON. + --system-headers - Display the errors from system headers. + --use-color - + Use colors in diagnostics. If not set, colors + will be used if the terminal connected to + standard output supports colors. + This option overrides the 'UseColor' option in + .clang-tidy file, if any. + --verify-config - + Check the config files to ensure each check and + option is recognized. + --vfsoverlay= - + Overlay the virtual filesystem described by file + over the real file system. + --warnings-as-errors= - + 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 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: - https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html for an - example of setting up Clang Tooling on a source tree. + 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: + https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html for an + example of setting up Clang Tooling on a source tree. ... 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. + 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: @@ -287,16 +288,18 @@ $ clang-tidy -dump-config --- - Checks: '-*,some-check' - WarningsAsErrors: '' - HeaderFilterRegex: '' - FormatStyle: none - InheritParentConfig: true - User: user + Checks: '-*,some-check' + WarningsAsErrors: '' + HeaderFileExtensions: ';h;hh;hpp;hxx' + HeaderFilterRegex: '' + FormatStyle: none + InheritParentConfig: true + User: user CheckOptions: some-check.SomeOption: 'some value' ... + .. _clang-tidy-nolint: Suppressing Undesired Diagnostics diff --git a/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp b/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp --- a/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp +++ b/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp @@ -76,12 +76,14 @@ TEST(ParseConfiguration, ValidConfiguration) { llvm::ErrorOr Options = parseConfiguration(llvm::MemoryBufferRef("Checks: \"-*,misc-*\"\n" + "HeaderFileExtensions: \";h;hh;hpp;hxx\"\n" "HeaderFilterRegex: \".*\"\n" "AnalyzeTemporaryDtors: true\n" "User: some.user", "Options")); EXPECT_TRUE(!!Options); EXPECT_EQ("-*,misc-*", *Options->Checks); + EXPECT_EQ(";h;hh;hpp;hxx", *Options->HeaderFileExtensions); EXPECT_EQ(".*", *Options->HeaderFilterRegex); EXPECT_EQ("some.user", *Options->User); } @@ -104,6 +106,7 @@ llvm::ErrorOr Options1 = parseConfiguration(llvm::MemoryBufferRef(R"( Checks: "check1,check2" + HeaderFileExtensions: ";h;hh" HeaderFilterRegex: "filter1" AnalyzeTemporaryDtors: true User: user1 @@ -116,6 +119,7 @@ llvm::ErrorOr Options2 = parseConfiguration(llvm::MemoryBufferRef(R"( Checks: "check3,check4" + HeaderFileExtensions: ";hpp;hxx" HeaderFilterRegex: "filter2" AnalyzeTemporaryDtors: false User: user2 @@ -127,6 +131,7 @@ ASSERT_TRUE(!!Options2); ClangTidyOptions Options = Options1->merge(*Options2, 0); EXPECT_EQ("check1,check2,check3,check4", *Options.Checks); + EXPECT_EQ(";hpp;hxx", *Options.HeaderFileExtensions); EXPECT_EQ("filter2", *Options.HeaderFilterRegex); EXPECT_EQ("user2", *Options.User); ASSERT_TRUE(Options.ExtraArgs.has_value());