diff options
author | Carlos Galvez <carlosgalvezp@gmail.com> | 2023-01-25 05:26:07 +0000 |
---|---|---|
committer | Carlos Galvez <carlosgalvezp@gmail.com> | 2023-02-19 13:44:11 +0000 |
commit | 5b37cddff8e0140420ad776066529cf8f41d64d2 (patch) | |
tree | e217c546cd0c7f193d6b354c38a800bf2a49417d | |
parent | 1235ed913356d493563d730cb7997bcca633397d (diff) | |
download | llvm-5b37cddff8e0140420ad776066529cf8f41d64d2.zip llvm-5b37cddff8e0140420ad776066529cf8f41d64d2.tar.gz llvm-5b37cddff8e0140420ad776066529cf8f41d64d2.tar.bz2 |
[clang-tidy] Introduce HeaderFileExtensions and ImplementationFileExtensions options
Re-introduce the patch that was reverted previously.
In the first attempt, the checks would not be able to
read from the global option, since getLocalOrGlobal
only works with string types. Additional logic is needed
in order to support both use cases in the transition
period. All that logic will be removed when the local
options are fully removed.
We have a number of checks designed to analyze problems
in header files only, for example:
bugprone-suspicious-include
google-build-namespaces
llvm-header-guard
misc-definitions-in-header
...
All these checks duplicate the same logic and options
to determine whether a location is placed in the main
source file or in the header. More checks are coming
up with similar requirements.
Thus, to remove duplication, let's move this option
to the top-level configuration of clang-tidy (since
it's something all checks should share).
Add a deprecation notice for all checks that use the
local option, prompting to update to the global option.
Differential Revision: https://reviews.llvm.org/D142655
36 files changed, 365 insertions, 147 deletions
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp index 11ee7a0..9d693bd 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -22,6 +22,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/ASTDiagnostic.h" #include "clang/AST/Attr.h" +#include "clang/Basic/CharInfo.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileManager.h" @@ -222,12 +223,30 @@ void ClangTidyContext::setSourceManager(SourceManager *SourceMgr) { DiagEngine->setSourceManager(SourceMgr); } +static bool parseFileExtensions(llvm::ArrayRef<std::string> AllFileExtensions, + FileExtensionsSet &FileExtensions) { + FileExtensions.clear(); + for (StringRef Suffix : AllFileExtensions) { + StringRef Extension = Suffix.trim(); + if (!llvm::all_of(Extension, isAlphanumeric)) + return false; + FileExtensions.insert(Extension); + } + return true; +} + void ClangTidyContext::setCurrentFile(StringRef File) { CurrentFile = std::string(File); CurrentOptions = getOptionsForFile(CurrentFile); CheckFilter = std::make_unique<CachedGlobList>(*getOptions().Checks); WarningAsErrorFilter = std::make_unique<CachedGlobList>(*getOptions().WarningsAsErrors); + if (!parseFileExtensions(*getOptions().HeaderFileExtensions, + HeaderFileExtensions)) + this->configurationDiag("Invalid header file extensions"); + if (!parseFileExtensions(*getOptions().ImplementationFileExtensions, + ImplementationFileExtensions)) + this->configurationDiag("Invalid implementation file extensions"); } void ClangTidyContext::setASTContext(ASTContext *Context) { diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h index ac5e896..15f1b67 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h +++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h @@ -11,6 +11,7 @@ #include "ClangTidyOptions.h" #include "ClangTidyProfiling.h" +#include "FileExtensionsSet.h" #include "NoLintDirectiveHandler.h" #include "clang/Basic/Diagnostic.h" #include "clang/Tooling/Core/Diagnostic.h" @@ -160,6 +161,14 @@ public: /// \c CurrentFile. ClangTidyOptions getOptionsForFile(StringRef File) const; + const FileExtensionsSet &getHeaderFileExtensions() const { + return HeaderFileExtensions; + } + + const FileExtensionsSet &getImplementationFileExtensions() const { + return ImplementationFileExtensions; + } + /// Returns \c ClangTidyStats containing issued and ignored diagnostic /// counters. const ClangTidyStats &getStats() const { return Stats; } @@ -221,6 +230,9 @@ private: std::unique_ptr<CachedGlobList> CheckFilter; std::unique_ptr<CachedGlobList> WarningAsErrorFilter; + FileExtensionsSet HeaderFileExtensions; + FileExtensionsSet ImplementationFileExtensions; + LangOptions LangOpts; ClangTidyStats Stats; diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp index 808929b..84defcc 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp @@ -122,6 +122,9 @@ template <> struct MappingTraits<ClangTidyOptions> { bool Ignored = false; IO.mapOptional("Checks", Options.Checks); IO.mapOptional("WarningsAsErrors", Options.WarningsAsErrors); + IO.mapOptional("HeaderFileExtensions", Options.HeaderFileExtensions); + IO.mapOptional("ImplementationFileExtensions", + Options.ImplementationFileExtensions); IO.mapOptional("HeaderFilterRegex", Options.HeaderFilterRegex); IO.mapOptional("AnalyzeTemporaryDtors", Ignored); // deprecated IO.mapOptional("FormatStyle", Options.FormatStyle); @@ -142,6 +145,8 @@ ClangTidyOptions ClangTidyOptions::getDefaults() { ClangTidyOptions Options; Options.Checks = ""; Options.WarningsAsErrors = ""; + Options.HeaderFileExtensions = {"", "h", "hh", "hpp", "hxx"}; + Options.ImplementationFileExtensions = {"c", "cc", "cpp", "cxx"}; Options.HeaderFilterRegex = ""; Options.SystemHeaders = false; Options.FormatStyle = "none"; @@ -178,6 +183,9 @@ ClangTidyOptions &ClangTidyOptions::mergeWith(const ClangTidyOptions &Other, unsigned Order) { mergeCommaSeparatedLists(Checks, Other.Checks); mergeCommaSeparatedLists(WarningsAsErrors, Other.WarningsAsErrors); + overrideValue(HeaderFileExtensions, Other.HeaderFileExtensions); + overrideValue(ImplementationFileExtensions, + Other.ImplementationFileExtensions); overrideValue(HeaderFilterRegex, Other.HeaderFilterRegex); overrideValue(SystemHeaders, Other.SystemHeaders); overrideValue(FormatStyle, Other.FormatStyle); diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.h b/clang-tools-extra/clang-tidy/ClangTidyOptions.h index 4a6cdf0..d0df474 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyOptions.h +++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.h @@ -71,6 +71,14 @@ struct ClangTidyOptions { /// WarningsAsErrors filter. std::optional<std::string> WarningsAsErrors; + /// File extensions to consider to determine if a given diagnostic is located + /// in a header file. + std::optional<std::vector<std::string>> HeaderFileExtensions; + + /// File extensions to consider to determine if a given diagnostic is located + /// is located in an implementation file. + std::optional<std::vector<std::string>> ImplementationFileExtensions; + /// Output warnings from headers matching this filter. Warnings from /// main files will always be displayed. std::optional<std::string> HeaderFilterRegex; diff --git a/clang-tools-extra/clang-tidy/FileExtensionsSet.h b/clang-tools-extra/clang-tidy/FileExtensionsSet.h new file mode 100644 index 0000000..417b1b6 --- /dev/null +++ b/clang-tools-extra/clang-tidy/FileExtensionsSet.h @@ -0,0 +1,19 @@ +//===--- FileExtensionsSet.h - clang-tidy -----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FILE_EXTENSIONS_SET_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FILE_EXTENSIONS_SET_H + +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/StringRef.h" + +namespace clang::tidy { +typedef llvm::SmallSet<llvm::StringRef, 5> FileExtensionsSet; +} // namespace clang::tidy + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FILE_EXTENSIONS_SET_H diff --git a/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp index 79731ad..4a46712 100644 --- a/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "DynamicStaticInitializersCheck.h" +#include "../utils/FileExtensionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -24,17 +25,22 @@ AST_MATCHER(clang::VarDecl, hasConstantDeclaration) { return false; } -DynamicStaticInitializersCheck::DynamicStaticInitializersCheck(StringRef Name, - ClangTidyContext *Context) - : ClangTidyCheck(Name, Context), - RawStringHeaderFileExtensions(Options.getLocalOrGlobal( - "HeaderFileExtensions", utils::defaultHeaderFileExtensions())) { - if (!utils::parseFileExtensions(RawStringHeaderFileExtensions, - HeaderFileExtensions, - utils::defaultFileExtensionDelimiters())) { - this->configurationDiag("Invalid header file extension: '%0'") - << RawStringHeaderFileExtensions; - } +DynamicStaticInitializersCheck::DynamicStaticInitializersCheck( + StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) { + std::optional<StringRef> HeaderFileExtensionsOption = + Options.get("HeaderFileExtensions"); + RawStringHeaderFileExtensions = + HeaderFileExtensionsOption.value_or(utils::defaultHeaderFileExtensions()); + if (HeaderFileExtensionsOption) { + if (!utils::parseFileExtensions(RawStringHeaderFileExtensions, + HeaderFileExtensions, + utils::defaultFileExtensionDelimiters())) { + this->configurationDiag("Invalid header file extension: '%0'") + << RawStringHeaderFileExtensions; + } + } else + HeaderFileExtensions = Context->getHeaderFileExtensions(); } void DynamicStaticInitializersCheck::storeOptions( diff --git a/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.h b/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.h index b138572..d8ac31d 100644 --- a/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.h @@ -10,7 +10,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_DYNAMIC_STATIC_INITIALIZERS_CHECK_H #include "../ClangTidyCheck.h" -#include "../utils/FileExtensionsUtils.h" +#include "../FileExtensionsSet.h" namespace clang::tidy::bugprone { @@ -34,8 +34,8 @@ public: void check(const ast_matchers::MatchFinder::MatchResult &Result) override; private: - const StringRef RawStringHeaderFileExtensions; - utils::FileExtensionsSet HeaderFileExtensions; + StringRef RawStringHeaderFileExtensions; + FileExtensionsSet HeaderFileExtensions; }; } // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp index 13020bc..49293ab 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "SuspiciousIncludeCheck.h" +#include "../utils/FileExtensionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/Lex/Preprocessor.h" #include <optional> @@ -36,25 +37,35 @@ private: SuspiciousIncludeCheck::SuspiciousIncludeCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context), - RawStringHeaderFileExtensions(Options.getLocalOrGlobal( - "HeaderFileExtensions", utils::defaultHeaderFileExtensions())), - RawStringImplementationFileExtensions(Options.getLocalOrGlobal( - "ImplementationFileExtensions", - utils::defaultImplementationFileExtensions())) { - if (!utils::parseFileExtensions(RawStringImplementationFileExtensions, - ImplementationFileExtensions, - utils::defaultFileExtensionDelimiters())) { - this->configurationDiag("Invalid implementation file extension: '%0'") - << RawStringImplementationFileExtensions; - } - - if (!utils::parseFileExtensions(RawStringHeaderFileExtensions, - HeaderFileExtensions, - utils::defaultFileExtensionDelimiters())) { - this->configurationDiag("Invalid header file extension: '%0'") - << RawStringHeaderFileExtensions; - } + : ClangTidyCheck(Name, Context) { + std::optional<StringRef> ImplementationFileExtensionsOption = + Options.get("ImplementationFileExtensions"); + RawStringImplementationFileExtensions = + ImplementationFileExtensionsOption.value_or( + utils::defaultImplementationFileExtensions()); + if (ImplementationFileExtensionsOption) { + if (!utils::parseFileExtensions(RawStringImplementationFileExtensions, + ImplementationFileExtensions, + utils::defaultFileExtensionDelimiters())) { + this->configurationDiag("Invalid implementation file extension: '%0'") + << RawStringImplementationFileExtensions; + } + } else + ImplementationFileExtensions = Context->getImplementationFileExtensions(); + + std::optional<StringRef> HeaderFileExtensionsOption = + Options.get("HeaderFileExtensions"); + RawStringHeaderFileExtensions = + HeaderFileExtensionsOption.value_or(utils::defaultHeaderFileExtensions()); + if (HeaderFileExtensionsOption) { + if (!utils::parseFileExtensions(RawStringHeaderFileExtensions, + HeaderFileExtensions, + utils::defaultFileExtensionDelimiters())) { + this->configurationDiag("Invalid header file extension: '%0'") + << RawStringHeaderFileExtensions; + } + } else + HeaderFileExtensions = Context->getHeaderFileExtensions(); } void SuspiciousIncludeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.h b/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.h index 07edd85..0cc1639 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.h @@ -40,12 +40,12 @@ public: Preprocessor *ModuleExpanderPP) override; void storeOptions(ClangTidyOptions::OptionMap &Opts) override; - utils::FileExtensionsSet HeaderFileExtensions; - utils::FileExtensionsSet ImplementationFileExtensions; + FileExtensionsSet HeaderFileExtensions; + FileExtensionsSet ImplementationFileExtensions; private: - const StringRef RawStringHeaderFileExtensions; - const StringRef RawStringImplementationFileExtensions; + StringRef RawStringHeaderFileExtensions; + StringRef RawStringImplementationFileExtensions; }; } // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/google/GlobalNamesInHeadersCheck.cpp b/clang-tools-extra/clang-tidy/google/GlobalNamesInHeadersCheck.cpp index 1c2a4e1..59031b4 100644 --- a/clang-tools-extra/clang-tidy/google/GlobalNamesInHeadersCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/GlobalNamesInHeadersCheck.cpp @@ -18,15 +18,20 @@ namespace clang::tidy::google::readability { GlobalNamesInHeadersCheck::GlobalNamesInHeadersCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context), - RawStringHeaderFileExtensions(Options.getLocalOrGlobal( - "HeaderFileExtensions", utils::defaultHeaderFileExtensions())) { - if (!utils::parseFileExtensions(RawStringHeaderFileExtensions, - HeaderFileExtensions, - utils::defaultFileExtensionDelimiters())) { - this->configurationDiag("Invalid header file extension: '%0'") - << RawStringHeaderFileExtensions; - } + : ClangTidyCheck(Name, Context) { + std::optional<StringRef> HeaderFileExtensionsOption = + Options.get("HeaderFileExtensions"); + RawStringHeaderFileExtensions = + HeaderFileExtensionsOption.value_or(utils::defaultHeaderFileExtensions()); + if (HeaderFileExtensionsOption) { + if (!utils::parseFileExtensions(RawStringHeaderFileExtensions, + HeaderFileExtensions, + utils::defaultFileExtensionDelimiters())) { + this->configurationDiag("Invalid header file extension: '%0'") + << RawStringHeaderFileExtensions; + } + } else + HeaderFileExtensions = Context->getHeaderFileExtensions(); } void GlobalNamesInHeadersCheck::storeOptions( diff --git a/clang-tools-extra/clang-tidy/google/GlobalNamesInHeadersCheck.h b/clang-tools-extra/clang-tidy/google/GlobalNamesInHeadersCheck.h index a152e2c..625a191 100644 --- a/clang-tools-extra/clang-tidy/google/GlobalNamesInHeadersCheck.h +++ b/clang-tools-extra/clang-tidy/google/GlobalNamesInHeadersCheck.h @@ -35,8 +35,8 @@ public: void check(const ast_matchers::MatchFinder::MatchResult &Result) override; private: - const StringRef RawStringHeaderFileExtensions; - utils::FileExtensionsSet HeaderFileExtensions; + StringRef RawStringHeaderFileExtensions; + FileExtensionsSet HeaderFileExtensions; }; } // namespace clang::tidy::google::readability diff --git a/clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp b/clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp index 72de9c1..59766a1 100644 --- a/clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp @@ -17,15 +17,20 @@ namespace clang::tidy::google::build { UnnamedNamespaceInHeaderCheck::UnnamedNamespaceInHeaderCheck( StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context), - RawStringHeaderFileExtensions(Options.getLocalOrGlobal( - "HeaderFileExtensions", utils::defaultHeaderFileExtensions())) { - if (!utils::parseFileExtensions(RawStringHeaderFileExtensions, - HeaderFileExtensions, - utils::defaultFileExtensionDelimiters())) { - this->configurationDiag("Invalid header file extension: '%0'") - << RawStringHeaderFileExtensions; - } + : ClangTidyCheck(Name, Context) { + std::optional<StringRef> HeaderFileExtensionsOption = + Options.get("HeaderFileExtensions"); + RawStringHeaderFileExtensions = + HeaderFileExtensionsOption.value_or(utils::defaultHeaderFileExtensions()); + if (HeaderFileExtensionsOption) { + if (!utils::parseFileExtensions(RawStringHeaderFileExtensions, + HeaderFileExtensions, + utils::defaultFileExtensionDelimiters())) { + this->configurationDiag("Invalid header file extension: '%0'") + << RawStringHeaderFileExtensions; + } + } else + HeaderFileExtensions = Context->getHeaderFileExtensions(); } void UnnamedNamespaceInHeaderCheck::storeOptions( diff --git a/clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h b/clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h index ac26746..8a16e75 100644 --- a/clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h +++ b/clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h @@ -41,8 +41,8 @@ public: void check(const ast_matchers::MatchFinder::MatchResult &Result) override; private: - const StringRef RawStringHeaderFileExtensions; - utils::FileExtensionsSet HeaderFileExtensions; + StringRef RawStringHeaderFileExtensions; + FileExtensionsSet HeaderFileExtensions; }; } // namespace clang::tidy::google::build diff --git a/clang-tools-extra/clang-tidy/llvmlibc/InlineFunctionDeclCheck.cpp b/clang-tools-extra/clang-tidy/llvmlibc/InlineFunctionDeclCheck.cpp index 3f93521..803e32d 100644 --- a/clang-tools-extra/clang-tidy/llvmlibc/InlineFunctionDeclCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvmlibc/InlineFunctionDeclCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "InlineFunctionDeclCheck.h" +#include "../utils/FileExtensionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -19,30 +20,12 @@ namespace clang::tidy::llvm_libc { InlineFunctionDeclCheck::InlineFunctionDeclCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), - RawStringHeaderFileExtensions(Options.getLocalOrGlobal( - "HeaderFileExtensions", utils::defaultHeaderFileExtensions())) { - if (!utils::parseFileExtensions(RawStringHeaderFileExtensions, - HeaderFileExtensions, - utils::defaultFileExtensionDelimiters())) { - this->configurationDiag("Invalid header file extension: '%0'") - << RawStringHeaderFileExtensions; - } -} + HeaderFileExtensions(Context->getHeaderFileExtensions()) {} void InlineFunctionDeclCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher(decl(functionDecl()).bind("func_decl"), this); } -void InlineFunctionDeclCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { - Options.store(Opts, "HeaderFileExtensions", RawStringHeaderFileExtensions); - if (!utils::parseFileExtensions(RawStringHeaderFileExtensions, - HeaderFileExtensions, - utils::defaultFileExtensionDelimiters())) { - this->configurationDiag("Invalid header file extension: '%0'") - << RawStringHeaderFileExtensions; - } -} - void InlineFunctionDeclCheck::check(const MatchFinder::MatchResult &Result) { const auto *FuncDecl = Result.Nodes.getNodeAs<FunctionDecl>("func_decl"); diff --git a/clang-tools-extra/clang-tidy/llvmlibc/InlineFunctionDeclCheck.h b/clang-tools-extra/clang-tidy/llvmlibc/InlineFunctionDeclCheck.h index a69a5dc..85d87a5 100644 --- a/clang-tools-extra/clang-tidy/llvmlibc/InlineFunctionDeclCheck.h +++ b/clang-tools-extra/clang-tidy/llvmlibc/InlineFunctionDeclCheck.h @@ -10,7 +10,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVMLIBC_INLINEFUNCTIONDECLCHECK_H #include "../ClangTidyCheck.h" -#include "../utils/FileExtensionsUtils.h" +#include "../FileExtensionsSet.h" namespace clang::tidy::llvm_libc { @@ -30,13 +30,11 @@ public: return LangOpts.CPlusPlus; } - void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; private: - const StringRef RawStringHeaderFileExtensions; - utils::FileExtensionsSet HeaderFileExtensions; + FileExtensionsSet HeaderFileExtensions; }; } // namespace clang::tidy::llvm_libc diff --git a/clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.cpp b/clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.cpp index c894d7e..67e1a04 100644 --- a/clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.cpp @@ -16,7 +16,7 @@ namespace clang::tidy::misc { namespace { -AST_MATCHER_P(NamedDecl, usesHeaderFileExtension, utils::FileExtensionsSet, +AST_MATCHER_P(NamedDecl, usesHeaderFileExtension, FileExtensionsSet, HeaderFileExtensions) { return utils::isExpansionLocInHeaderFile( Node.getBeginLoc(), Finder->getASTContext().getSourceManager(), @@ -28,15 +28,20 @@ AST_MATCHER_P(NamedDecl, usesHeaderFileExtension, utils::FileExtensionsSet, DefinitionsInHeadersCheck::DefinitionsInHeadersCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), - UseHeaderFileExtension(Options.get("UseHeaderFileExtension", true)), - RawStringHeaderFileExtensions(Options.getLocalOrGlobal( - "HeaderFileExtensions", utils::defaultHeaderFileExtensions())) { - if (!utils::parseFileExtensions(RawStringHeaderFileExtensions, - HeaderFileExtensions, - utils::defaultFileExtensionDelimiters())) { - this->configurationDiag("Invalid header file extension: '%0'") - << RawStringHeaderFileExtensions; - } + UseHeaderFileExtension(Options.get("UseHeaderFileExtension", true)) { + std::optional<StringRef> HeaderFileExtensionsOption = + Options.get("HeaderFileExtensions"); + RawStringHeaderFileExtensions = + HeaderFileExtensionsOption.value_or(utils::defaultHeaderFileExtensions()); + if (HeaderFileExtensionsOption) { + if (!utils::parseFileExtensions(RawStringHeaderFileExtensions, + HeaderFileExtensions, + utils::defaultFileExtensionDelimiters())) { + this->configurationDiag("Invalid header file extension: '%0'") + << RawStringHeaderFileExtensions; + } + } else + HeaderFileExtensions = Context->getHeaderFileExtensions(); } void DefinitionsInHeadersCheck::storeOptions( diff --git a/clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.h b/clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.h index db32cab..e009549 100644 --- a/clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.h +++ b/clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.h @@ -41,8 +41,8 @@ public: private: const bool UseHeaderFileExtension; - const StringRef RawStringHeaderFileExtensions; - utils::FileExtensionsSet HeaderFileExtensions; + StringRef RawStringHeaderFileExtensions; + FileExtensionsSet HeaderFileExtensions; }; } // namespace clang::tidy::misc diff --git a/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp b/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp index 3602aa4..8aadb8f 100644 --- a/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp @@ -38,14 +38,20 @@ static bool shouldCheckDecl(const Decl *TargetDecl) { UnusedUsingDeclsCheck::UnusedUsingDeclsCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context), - RawStringHeaderFileExtensions(Options.getLocalOrGlobal( - "HeaderFileExtensions", utils::defaultHeaderFileExtensions())) { - if (!utils::parseFileExtensions(RawStringHeaderFileExtensions, - HeaderFileExtensions, - utils::defaultFileExtensionDelimiters())) - this->configurationDiag("Invalid header file extension: '%0'") - << RawStringHeaderFileExtensions; + : ClangTidyCheck(Name, Context) { + std::optional<StringRef> HeaderFileExtensionsOption = + Options.get("HeaderFileExtensions"); + RawStringHeaderFileExtensions = + HeaderFileExtensionsOption.value_or(utils::defaultHeaderFileExtensions()); + if (HeaderFileExtensionsOption) { + if (!utils::parseFileExtensions(RawStringHeaderFileExtensions, + HeaderFileExtensions, + utils::defaultFileExtensionDelimiters())) { + this->configurationDiag("Invalid header file extension: '%0'") + << RawStringHeaderFileExtensions; + } + } else + HeaderFileExtensions = Context->getHeaderFileExtensions(); } void UnusedUsingDeclsCheck::registerMatchers(MatchFinder *Finder) { diff --git a/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.h b/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.h index 5ca7aef..212139a 100644 --- a/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.h +++ b/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.h @@ -47,8 +47,8 @@ private: std::vector<UsingDeclContext> Contexts; - const StringRef RawStringHeaderFileExtensions; - utils::FileExtensionsSet HeaderFileExtensions; + StringRef RawStringHeaderFileExtensions; + FileExtensionsSet HeaderFileExtensions; }; } // namespace clang::tidy::misc diff --git a/clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.cpp index 7e4bba2..a6337f5 100644 --- a/clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.cpp @@ -17,7 +17,7 @@ namespace { AST_POLYMORPHIC_MATCHER_P(isInHeaderFile, AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, VarDecl), - utils::FileExtensionsSet, HeaderFileExtensions) { + FileExtensionsSet, HeaderFileExtensions) { return utils::isExpansionLocInHeaderFile( Node.getBeginLoc(), Finder->getASTContext().getSourceManager(), HeaderFileExtensions); @@ -31,15 +31,20 @@ AST_MATCHER(VarDecl, isStaticDataMember) { return Node.isStaticDataMember(); } UseAnonymousNamespaceCheck::UseAnonymousNamespaceCheck( StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context), - RawStringHeaderFileExtensions(Options.getLocalOrGlobal( - "HeaderFileExtensions", utils::defaultHeaderFileExtensions())) { - if (!utils::parseFileExtensions(RawStringHeaderFileExtensions, - HeaderFileExtensions, - utils::defaultFileExtensionDelimiters())) { - this->configurationDiag("Invalid header file extension: '%0'") - << RawStringHeaderFileExtensions; - } + : ClangTidyCheck(Name, Context) { + std::optional<StringRef> HeaderFileExtensionsOption = + Options.get("HeaderFileExtensions"); + RawStringHeaderFileExtensions = + HeaderFileExtensionsOption.value_or(utils::defaultHeaderFileExtensions()); + if (HeaderFileExtensionsOption) { + if (!utils::parseFileExtensions(RawStringHeaderFileExtensions, + HeaderFileExtensions, + utils::defaultFileExtensionDelimiters())) { + this->configurationDiag("Invalid header file extension: '%0'") + << RawStringHeaderFileExtensions; + } + } else + HeaderFileExtensions = Context->getHeaderFileExtensions(); } void UseAnonymousNamespaceCheck::storeOptions( diff --git a/clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.h b/clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.h index b3c10a1..4a5a867 100644 --- a/clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.h +++ b/clang-tools-extra/clang-tidy/misc/UseAnonymousNamespaceCheck.h @@ -38,8 +38,8 @@ public: void check(const ast_matchers::MatchFinder::MatchResult &Result) override; private: - const StringRef RawStringHeaderFileExtensions; - utils::FileExtensionsSet HeaderFileExtensions; + StringRef RawStringHeaderFileExtensions; + FileExtensionsSet HeaderFileExtensions; }; } // namespace clang::tidy::misc diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp index ff673e7..0916299 100644 --- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp +++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp @@ -56,7 +56,12 @@ Configuration files: ExtraArgs - Same as '--extra-args'. ExtraArgsBefore - Same as '--extra-args-before'. FormatStyle - Same as '--format-style'. + HeaderFileExtensions - File extensions to consider to determine if a + given diagnostic is located in a header file. HeaderFilterRegex - Same as '--header-filter-regex'. + ImplementationFileExtensions - File extensions to consider to determine if a + given diagnostic is located in an + implementation file. InheritParentConfig - If this option is true in a config file, the configuration file in the parent directory (if any exists) will be taken and the current @@ -74,12 +79,14 @@ Configuration files: $ clang-tidy --dump-config --- - Checks: '-*,some-check' - WarningsAsErrors: '' - HeaderFilterRegex: '' - FormatStyle: none - InheritParentConfig: true - User: user + Checks: '-*,some-check' + WarningsAsErrors: '' + HeaderFileExtensions: ['', 'h','hh','hpp','hxx'] + ImplementationFileExtensions: ['c','cc','cpp','cxx'] + HeaderFilterRegex: '' + FormatStyle: none + InheritParentConfig: true + User: user CheckOptions: some-check.SomeOption: 'some value' ... @@ -484,6 +491,26 @@ static bool verifyChecks(const StringSet<> &AllChecks, StringRef CheckGlob, return AnyInvalid; } +static bool verifyFileExtensions( + const std::vector<std::string> &HeaderFileExtensions, + const std::vector<std::string> &ImplementationFileExtensions, + StringRef Source) { + bool AnyInvalid = false; + for (const auto &HeaderExtension : HeaderFileExtensions) { + for (const auto &ImplementationExtension : ImplementationFileExtensions) { + if (HeaderExtension == ImplementationExtension) { + AnyInvalid = true; + auto &Output = llvm::WithColor::warning(llvm::errs(), Source) + << "HeaderFileExtension '" << HeaderExtension << '\'' + << " is the same as ImplementationFileExtension '" + << ImplementationExtension << '\''; + Output << VerifyConfigWarningEnd; + } + } + } + return AnyInvalid; +} + int clangTidyMain(int argc, const char **argv) { llvm::InitLLVM X(argc, argv); @@ -587,6 +614,11 @@ int clangTidyMain(int argc, const char **argv) { if (Opts.Checks) AnyInvalid |= verifyChecks(Valid.Names, *Opts.Checks, Source); + if (Opts.HeaderFileExtensions && Opts.ImplementationFileExtensions) + AnyInvalid |= + verifyFileExtensions(*Opts.HeaderFileExtensions, + *Opts.ImplementationFileExtensions, Source); + for (auto Key : Opts.CheckOptions.keys()) { if (Valid.Options.contains(Key)) continue; diff --git a/clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.h b/clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.h index e429967..e23f6b7 100644 --- a/clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.h +++ b/clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.h @@ -9,6 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_FILE_EXTENSIONS_UTILS_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_FILE_EXTENSIONS_UTILS_H +#include "../FileExtensionsSet.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "llvm/ADT/SmallSet.h" @@ -17,8 +18,6 @@ namespace clang::tidy::utils { -typedef llvm::SmallSet<llvm::StringRef, 5> FileExtensionsSet; - /// Checks whether expansion location of \p Loc is in header file. bool isExpansionLocInHeaderFile(SourceLocation Loc, const SourceManager &SM, const FileExtensionsSet &HeaderFileExtensions); diff --git a/clang-tools-extra/clang-tidy/utils/HeaderGuard.h b/clang-tools-extra/clang-tidy/utils/HeaderGuard.h index 89429e6..b1ce783 100644 --- a/clang-tools-extra/clang-tidy/utils/HeaderGuard.h +++ b/clang-tools-extra/clang-tidy/utils/HeaderGuard.h @@ -25,12 +25,20 @@ namespace clang::tidy::utils { class HeaderGuardCheck : public ClangTidyCheck { public: HeaderGuardCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context), - RawStringHeaderFileExtensions(Options.getLocalOrGlobal( - "HeaderFileExtensions", utils::defaultHeaderFileExtensions())) { - utils::parseFileExtensions(RawStringHeaderFileExtensions, - HeaderFileExtensions, - utils::defaultFileExtensionDelimiters()); + : ClangTidyCheck(Name, Context) { + std::optional<StringRef> HeaderFileExtensionsOption = + Options.get("HeaderFileExtensions"); + RawStringHeaderFileExtensions = HeaderFileExtensionsOption.value_or( + utils::defaultHeaderFileExtensions()); + if (HeaderFileExtensionsOption) { + if (!utils::parseFileExtensions( + RawStringHeaderFileExtensions, HeaderFileExtensions, + utils::defaultFileExtensionDelimiters())) { + this->configurationDiag("Invalid header file extension: '%0'") + << RawStringHeaderFileExtensions; + } + } else + HeaderFileExtensions = Context->getHeaderFileExtensions(); } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, @@ -58,7 +66,7 @@ public: private: std::string RawStringHeaderFileExtensions; - utils::FileExtensionsSet HeaderFileExtensions; + FileExtensionsSet HeaderFileExtensions; }; } // namespace clang::tidy::utils diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 48e7da0..69d89c3 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -94,6 +94,10 @@ The improvements are... Improvements to clang-tidy -------------------------- +- New global configuration file options `HeaderFileExtensions` and + `ImplementationFileExtensions`, replacing the check-local options of the + same name. + New checks ^^^^^^^^^^ @@ -130,6 +134,41 @@ New check aliases Changes in existing checks ^^^^^^^^^^^^^^^^^^^^^^^^^^ +- Deprecated check-local options `HeaderFileExtensions` + in :doc:`bugprone-dynamic-static-initializers + <clang-tidy/checks/bugprone/dynamic-static-initializers>` check. + Global options of the same name should be used instead. + +- Deprecated check-local options `HeaderFileExtensions` and `ImplementationFileExtensions` + in :doc:`bugprone-suspicious-include + <clang-tidy/checks/bugprone/suspicious-include>` check. + Global options of the same name should be used instead. + +- Deprecated check-local options `HeaderFileExtensions` + in :doc:`google-build-namespaces + <clang-tidy/checks/google/build-namespaces>` check. + Global options of the same name should be used instead. + +- Deprecated check-local options `HeaderFileExtensions` + in :doc:`google-global-names-in-headers + <clang-tidy/checks/google/global-names-in-headers>` check. + Global options of the same name should be used instead. + +- Deprecated check-local options `HeaderFileExtensions` + in :doc:`llvm-header-guard + <clang-tidy/checks/llvm/header-guard>` check. + Global options of the same name should be used instead. + +- Deprecated check-local options `HeaderFileExtensions` + in :doc:`misc-definitions-in-headers + <clang-tidy/checks/misc/definitions-in-headers>` check. + Global options of the same name should be used instead. + +- Deprecated check-local options `HeaderFileExtensions` + in :doc:`misc-unused-using-decls + <clang-tidy/checks/misc/misc-unused-using-decls>` check. + Global options of the same name should be used instead. + Removed checks ^^^^^^^^^^^^^^ diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-include.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-include.rst index 3c05f39..7abcc13 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-include.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/suspicious-include.rst @@ -19,6 +19,10 @@ Options ------- .. option:: HeaderFileExtensions + Note: this option is deprecated, it will be removed in :program:`clang-tidy` + version 19. Please use the global configuration option + `HeaderFileExtensions`. + Default value: ``";h;hh;hpp;hxx"`` A semicolon-separated list of filename extensions of header files (the filename extensions should not contain a "." prefix). For extension-less @@ -27,6 +31,10 @@ Options .. option:: ImplementationFileExtensions + Note: this option is deprecated, it will be removed in :program:`clang-tidy` + version 19. Please use the global configuration option + `ImplementationFileExtensions`. + Default value: ``"c;cc;cpp;cxx"`` Likewise, a semicolon-separated list of filename extensions of implementation files. diff --git a/clang-tools-extra/docs/clang-tidy/checks/google/build-namespaces.rst b/clang-tools-extra/docs/clang-tidy/checks/google/build-namespaces.rst index ca40f99..59b5673 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/google/build-namespaces.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/google/build-namespaces.rst @@ -17,6 +17,10 @@ Options .. option:: HeaderFileExtensions + Note: this option is deprecated, it will be removed in :program:`clang-tidy` + version 19. Please use the global configuration option + `HeaderFileExtensions`. + A comma-separated list of filename extensions of header files (the filename extensions should not include "." prefix). Default is "h,hh,hpp,hxx". For header files without an extension, use an empty string (if there are no diff --git a/clang-tools-extra/docs/clang-tidy/checks/google/global-names-in-headers.rst b/clang-tools-extra/docs/clang-tidy/checks/google/global-names-in-headers.rst index 32740ea..e71ac46 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/google/global-names-in-headers.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/google/global-names-in-headers.rst @@ -14,6 +14,10 @@ Options .. option:: HeaderFileExtensions + Note: this option is deprecated, it will be removed in :program:`clang-tidy` + version 19. Please use the global configuration option + `HeaderFileExtensions`. + A comma-separated list of filename extensions of header files (the filename extensions should not contain "." prefix). Default is "h". For header files without an extension, use an empty string (if there are no diff --git a/clang-tools-extra/docs/clang-tidy/checks/llvm/header-guard.rst b/clang-tools-extra/docs/clang-tidy/checks/llvm/header-guard.rst index b27002a..725ef63 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/llvm/header-guard.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/llvm/header-guard.rst @@ -10,6 +10,10 @@ Options .. option:: HeaderFileExtensions + Note: this option is deprecated, it will be removed in :program:`clang-tidy` + version 19. Please use the global configuration option + `HeaderFileExtensions`. + A comma-separated list of filename extensions of header files (the filename extensions should not include "." prefix). Default is "h,hh,hpp,hxx". For header files without an extension, use an empty string (if there are no diff --git a/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/inline-function-decl.rst b/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/inline-function-decl.rst index d3b658e..da60a1f 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/inline-function-decl.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/inline-function-decl.rst @@ -6,14 +6,3 @@ llvmlibc-inline-function-decl Checks that all implicit and explicit inline functions in header files are tagged with the ``LIBC_INLINE`` macro. See the `libc style guide <https://libc.llvm.org/code_style.html>`_ for more information about this macro. - -Options -------- - -.. option:: HeaderFileExtensions - - A comma-separated list of filename extensions of header files (the filename - extensions should not include "." prefix). Default is "h,hh,hpp,hxx". - 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., - "h,hh,hpp,hxx," (note the trailing comma). diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/definitions-in-headers.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/definitions-in-headers.rst index a1fa09a..dcded6a 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/misc/definitions-in-headers.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/misc/definitions-in-headers.rst @@ -92,6 +92,10 @@ Options .. option:: HeaderFileExtensions + Note: this option is deprecated, it will be removed in :program:`clang-tidy` + version 19. Please use the global configuration option + `HeaderFileExtensions`. + A comma-separated list of filename extensions of header files (the filename extensions should not include "." prefix). Default is "h,hh,hpp,hxx". For header files without an extension, use an empty string (if there are no @@ -100,5 +104,9 @@ Options .. option:: UseHeaderFileExtension + Note: this option is deprecated, it will be removed in :program:`clang-tidy` + version 19. The check will unconditionally use the global option + `HeaderFileExtensions`. + When `true`, the check will use the file extension to distinguish header files. Default is `true`. diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/unused-using-decls.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/unused-using-decls.rst index 26dcf40..11b4450 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/misc/unused-using-decls.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/misc/unused-using-decls.rst @@ -22,6 +22,10 @@ Options .. option:: HeaderFileExtensions + Note: this option is deprecated, it will be removed in :program:`clang-tidy` + version 19. Please use the global configuration option + `HeaderFileExtensions`. + A semicolon-separated list of filename extensions of header files (the filename extensions should not include "." prefix). Default is "h,hh,hpp,hxx". For extension-less header files, use an empty string or leave an diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/use-anonymous-namespace.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/use-anonymous-namespace.rst index 6b25670..b825e95 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/misc/use-anonymous-namespace.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/misc/use-anonymous-namespace.rst @@ -38,6 +38,10 @@ Options .. option:: HeaderFileExtensions + Note: this option is deprecated, it will be removed in :program:`clang-tidy` + version 19. Please use the global configuration option + `HeaderFileExtensions`. + A semicolon-separated list of filename extensions of header files (the filename extensions should not include "." prefix). Default is ";h;hh;hpp;hxx". For extension-less header files, using an empty string or leaving an diff --git a/clang-tools-extra/docs/clang-tidy/index.rst b/clang-tools-extra/docs/clang-tidy/index.rst index 1db828a..899c3ea 100644 --- a/clang-tools-extra/docs/clang-tidy/index.rst +++ b/clang-tools-extra/docs/clang-tidy/index.rst @@ -263,7 +263,12 @@ An overview of all the command-line options: ExtraArgs - Same as '--extra-args'. ExtraArgsBefore - Same as '--extra-args-before'. FormatStyle - Same as '--format-style'. + HeaderFileExtensions - File extensions to consider to determine if a + given diagnostic is located in a header file. HeaderFilterRegex - Same as '--header-filter-regex'. + ImplementationFileExtensions - File extensions to consider to determine if a + given diagnostic is located in an + implementation file. InheritParentConfig - If this option is true in a config file, the configuration file in the parent directory (if any exists) will be taken and the current @@ -283,6 +288,8 @@ An overview of all the command-line options: --- Checks: '-*,some-check' WarningsAsErrors: '' + HeaderFileExtensions: ['', 'h','hh','hpp','hxx'] + ImplementationFileExtensions: ['c','cc','cpp','cxx'] HeaderFilterRegex: '' FormatStyle: none InheritParentConfig: true diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/verify-config.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/verify-config.cpp index edd6a9e..e127c23 100644 --- a/clang-tools-extra/test/clang-tidy/infrastructure/verify-config.cpp +++ b/clang-tools-extra/test/clang-tidy/infrastructure/verify-config.cpp @@ -3,6 +3,8 @@ // RUN: not clang-tidy -verify-config \ // RUN: --checks='-*,bad*glob,llvm*,llvm-includeorder,my-made-up-check' --config='{Checks: "readability-else-after-ret", \ +// RUN: HeaderFileExtensions: ["h", "hh", "hpp"], \ +// RUN: ImplementationFileExtensions: ["c", "cc", "hpp"], \ // RUN: CheckOptions: [{key: "IgnoreMacros", value: "true"}, \ // RUN: {key: "StriceMode", value: "true"}, \ // RUN: {key: modernize-lop-convert.UseCxx20ReverseRanges, value: true} \ @@ -12,6 +14,7 @@ // CHECK-VERIFY-DAG: command-line option '-config': warning: unknown check 'readability-else-after-ret'; did you mean 'readability-else-after-return' [-verify-config] // CHECK-VERIFY-DAG: command-line option '-config': warning: unknown check option 'modernize-lop-convert.UseCxx20ReverseRanges'; did you mean 'modernize-loop-convert.UseCxx20ReverseRanges' [-verify-config] // CHECK-VERIFY-DAG: command-line option '-config': warning: unknown check option 'StriceMode'; did you mean 'StrictMode' [-verify-config] +// CHECK-VERIFY-DAG: command-line option '-config': warning: HeaderFileExtension 'hpp' is the same as ImplementationFileExtension 'hpp' [-verify-config] // CHECK-VERIFY: command-line option '-checks': warning: check glob 'bad*glob' doesn't match any known check [-verify-config] // CHECK-VERIFY: command-line option '-checks': warning: unknown check 'llvm-includeorder'; did you mean 'llvm-include-order' [-verify-config] // CHECK-VERIFY: command-line option '-checks': warning: unknown check 'my-made-up-check' [-verify-config] diff --git a/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp b/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp index 4b88102..06f27d8 100644 --- a/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp +++ b/clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp @@ -76,13 +76,20 @@ TEST(ParseLineFilter, ValidFilter) { TEST(ParseConfiguration, ValidConfiguration) { llvm::ErrorOr<ClangTidyOptions> Options = - parseConfiguration(llvm::MemoryBufferRef("Checks: \"-*,misc-*\"\n" - "HeaderFilterRegex: \".*\"\n" - "AnalyzeTemporaryDtors: true\n" - "User: some.user", - "Options")); + parseConfiguration(llvm::MemoryBufferRef( + "Checks: \"-*,misc-*\"\n" + "HeaderFileExtensions: [\"\",\"h\",\"hh\",\"hpp\",\"hxx\"]\n" + "ImplementationFileExtensions: [\"c\",\"cc\",\"cpp\",\"cxx\"]\n" + "HeaderFilterRegex: \".*\"\n" + "AnalyzeTemporaryDtors: true\n" + "User: some.user", + "Options")); EXPECT_TRUE(!!Options); EXPECT_EQ("-*,misc-*", *Options->Checks); + EXPECT_EQ(std::vector<std::string>({"", "h", "hh", "hpp", "hxx"}), + *Options->HeaderFileExtensions); + EXPECT_EQ(std::vector<std::string>({"c", "cc", "cpp", "cxx"}), + *Options->ImplementationFileExtensions); EXPECT_EQ(".*", *Options->HeaderFilterRegex); EXPECT_EQ("some.user", *Options->User); } @@ -105,6 +112,8 @@ TEST(ParseConfiguration, MergeConfigurations) { llvm::ErrorOr<ClangTidyOptions> Options1 = parseConfiguration(llvm::MemoryBufferRef(R"( Checks: "check1,check2" + HeaderFileExtensions: ["h","hh"] + ImplementationFileExtensions: ["c","cc"] HeaderFilterRegex: "filter1" AnalyzeTemporaryDtors: true User: user1 @@ -117,6 +126,8 @@ TEST(ParseConfiguration, MergeConfigurations) { llvm::ErrorOr<ClangTidyOptions> Options2 = parseConfiguration(llvm::MemoryBufferRef(R"( Checks: "check3,check4" + HeaderFileExtensions: ["hpp","hxx"] + ImplementationFileExtensions: ["cpp","cxx"] HeaderFilterRegex: "filter2" AnalyzeTemporaryDtors: false User: user2 @@ -128,6 +139,10 @@ TEST(ParseConfiguration, MergeConfigurations) { ASSERT_TRUE(!!Options2); ClangTidyOptions Options = Options1->merge(*Options2, 0); EXPECT_EQ("check1,check2,check3,check4", *Options.Checks); + EXPECT_EQ(std::vector<std::string>({"hpp", "hxx"}), + *Options.HeaderFileExtensions); + EXPECT_EQ(std::vector<std::string>({"cpp", "cxx"}), + *Options.ImplementationFileExtensions); EXPECT_EQ("filter2", *Options.HeaderFilterRegex); EXPECT_EQ("user2", *Options.User); ASSERT_TRUE(Options.ExtraArgs.has_value()); |