jroelofs updated this revision to Diff 246604.
jroelofs added a comment.
Implement review feedback:
- Re-purpose `HeaderFileExtensionsUtils.h` to support headers *and* sources.
- Surround file extension in diagnostic with `''`s.
I have these as two separate patches locally, but I don't know how to represent
that in phabricator, so I've uploaded the diff across both. If this gets
approved, I intend to push them as separate commits.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D74669/new/
https://reviews.llvm.org/D74669
Files:
clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp
clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.h
clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp
clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.h
clang-tools-extra/clang-tidy/google/GlobalNamesInHeadersCheck.cpp
clang-tools-extra/clang-tidy/google/GlobalNamesInHeadersCheck.h
clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp
clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h
clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.cpp
clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.h
clang-tools-extra/clang-tidy/utils/CMakeLists.txt
clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.cpp
clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.h
clang-tools-extra/clang-tidy/utils/HeaderFileExtensionsUtils.cpp
clang-tools-extra/clang-tidy/utils/HeaderFileExtensionsUtils.h
clang-tools-extra/clang-tidy/utils/HeaderGuard.cpp
clang-tools-extra/clang-tidy/utils/HeaderGuard.h
clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/a
clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/a.cpp
clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/a.hpp
clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/c.c
clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/c.cc
clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/c.cxx
clang-tools-extra/test/clang-tidy/checkers/bugprone-suspicious-include.cpp
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-suspicious-include.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-suspicious-include.cpp
@@ -0,0 +1,21 @@
+// RUN: %check_clang_tidy %s bugprone-suspicious-include %t -- -- -isystem %S/Inputs/Headers -fmodules
+
+// CHECK-MESSAGES: [[@LINE+4]]:11: warning: suspicious #include of file with '.cpp' extension
+// CHECK-MESSAGES: [[@LINE+3]]:11: note: did you mean to include 'a'?
+// CHECK-MESSAGES: [[@LINE+2]]:11: note: did you mean to include 'a.h'?
+// CHECK-MESSAGES: [[@LINE+1]]:11: note: did you mean to include 'a.hpp'?
+#include "a.cpp"
+
+#include "b.h"
+
+// CHECK-MESSAGES: [[@LINE+1]]:10: warning: suspicious #import of file with '.c' extension
+#import "c.c"
+
+// CHECK-MESSAGES: [[@LINE+1]]:16: warning: suspicious #include_next of file with '.c' extension
+#include_next <c.c>
+
+// CHECK-MESSAGES: [[@LINE+1]]:13: warning: suspicious #include of file with '.cc' extension
+# include <c.cc>
+
+// CHECK-MESSAGES: [[@LINE+1]]:14: warning: suspicious #include of file with '.cxx' extension
+# include <c.cxx>
Index: clang-tools-extra/clang-tidy/utils/HeaderGuard.h
===================================================================
--- clang-tools-extra/clang-tidy/utils/HeaderGuard.h
+++ clang-tools-extra/clang-tidy/utils/HeaderGuard.h
@@ -10,7 +10,7 @@
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_HEADERGUARD_H
#include "../ClangTidy.h"
-#include "../utils/HeaderFileExtensionsUtils.h"
+#include "../utils/FileExtensionsUtils.h"
namespace clang {
namespace tidy {
@@ -29,8 +29,8 @@
: ClangTidyCheck(Name, Context),
RawStringHeaderFileExtensions(Options.getLocalOrGlobal(
"HeaderFileExtensions", utils::defaultHeaderFileExtensions())) {
- utils::parseHeaderFileExtensions(RawStringHeaderFileExtensions,
- HeaderFileExtensions, ',');
+ utils::parseFileExtensions(RawStringHeaderFileExtensions,
+ HeaderFileExtensions, ',');
}
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
Preprocessor *ModuleExpanderPP) override;
@@ -54,7 +54,7 @@
private:
std::string RawStringHeaderFileExtensions;
- utils::HeaderFileExtensionsSet HeaderFileExtensions;
+ utils::FileExtensionsSet HeaderFileExtensions;
};
} // namespace utils
Index: clang-tools-extra/clang-tidy/utils/HeaderGuard.cpp
===================================================================
--- clang-tools-extra/clang-tidy/utils/HeaderGuard.cpp
+++ clang-tools-extra/clang-tidy/utils/HeaderGuard.cpp
@@ -273,13 +273,13 @@
}
bool HeaderGuardCheck::shouldSuggestEndifComment(StringRef FileName) {
- return utils::isHeaderFileExtension(FileName, HeaderFileExtensions);
+ return utils::isFileExtension(FileName, HeaderFileExtensions);
}
bool HeaderGuardCheck::shouldFixHeaderGuard(StringRef FileName) { return true; }
bool HeaderGuardCheck::shouldSuggestToAddHeaderGuard(StringRef FileName) {
- return utils::isHeaderFileExtension(FileName, HeaderFileExtensions);
+ return utils::isFileExtension(FileName, HeaderFileExtensions);
}
std::string HeaderGuardCheck::formatEndIf(StringRef HeaderGuard) {
Index: clang-tools-extra/clang-tidy/utils/HeaderFileExtensionsUtils.h
===================================================================
--- clang-tools-extra/clang-tidy/utils/HeaderFileExtensionsUtils.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//===--- HeaderFileExtensionsUtils.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_UTILS_HEADER_FILE_EXTENSIONS_UTILS_H
-#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_HEADER_FILE_EXTENSIONS_UTILS_H
-
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-namespace tidy {
-namespace utils {
-
-typedef llvm::SmallSet<llvm::StringRef, 5> HeaderFileExtensionsSet;
-
-/// Checks whether expansion location of \p Loc is in header file.
-bool isExpansionLocInHeaderFile(
- SourceLocation Loc, const SourceManager &SM,
- const HeaderFileExtensionsSet &HeaderFileExtensions);
-
-/// Checks whether presumed location of \p Loc is in header file.
-bool isPresumedLocInHeaderFile(
- SourceLocation Loc, SourceManager &SM,
- const HeaderFileExtensionsSet &HeaderFileExtensions);
-
-/// Checks whether spelling location of \p Loc is in header file.
-bool isSpellingLocInHeaderFile(
- SourceLocation Loc, SourceManager &SM,
- const HeaderFileExtensionsSet &HeaderFileExtensions);
-
-/// Returns recommended default value for the list of header file
-/// extensions.
-inline StringRef defaultHeaderFileExtensions() { return ",h,hh,hpp,hxx"; }
-
-/// Parses header file extensions from a semicolon-separated list.
-bool parseHeaderFileExtensions(StringRef AllHeaderFileExtensions,
- HeaderFileExtensionsSet &HeaderFileExtensions,
- char delimiter);
-
-/// Decides whether a file has a header file extension.
-bool isHeaderFileExtension(StringRef FileName,
- const HeaderFileExtensionsSet &HeaderFileExtensions);
-
-} // namespace utils
-} // namespace tidy
-} // namespace clang
-
-#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_HEADER_FILE_EXTENSIONS_UTILS_H
Index: clang-tools-extra/clang-tidy/utils/HeaderFileExtensionsUtils.cpp
===================================================================
--- clang-tools-extra/clang-tidy/utils/HeaderFileExtensionsUtils.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-//===--- HeaderFileExtensionsUtils.cpp - 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "HeaderFileExtensionsUtils.h"
-#include "clang/Basic/CharInfo.h"
-#include "llvm/Support/Path.h"
-
-namespace clang {
-namespace tidy {
-namespace utils {
-
-bool isExpansionLocInHeaderFile(
- SourceLocation Loc, const SourceManager &SM,
- const HeaderFileExtensionsSet &HeaderFileExtensions) {
- SourceLocation ExpansionLoc = SM.getExpansionLoc(Loc);
- return isHeaderFileExtension(SM.getFilename(ExpansionLoc),
- HeaderFileExtensions);
-}
-
-bool isPresumedLocInHeaderFile(
- SourceLocation Loc, SourceManager &SM,
- const HeaderFileExtensionsSet &HeaderFileExtensions) {
- PresumedLoc PresumedLocation = SM.getPresumedLoc(Loc);
- return isHeaderFileExtension(PresumedLocation.getFilename(),
- HeaderFileExtensions);
-}
-
-bool isSpellingLocInHeaderFile(
- SourceLocation Loc, SourceManager &SM,
- const HeaderFileExtensionsSet &HeaderFileExtensions) {
- SourceLocation SpellingLoc = SM.getSpellingLoc(Loc);
- return isHeaderFileExtension(SM.getFilename(SpellingLoc),
- HeaderFileExtensions);
-}
-
-bool parseHeaderFileExtensions(StringRef AllHeaderFileExtensions,
- HeaderFileExtensionsSet &HeaderFileExtensions,
- char delimiter) {
- SmallVector<StringRef, 5> Suffixes;
- AllHeaderFileExtensions.split(Suffixes, delimiter);
- HeaderFileExtensions.clear();
- for (StringRef Suffix : Suffixes) {
- StringRef Extension = Suffix.trim();
- for (StringRef::const_iterator it = Extension.begin();
- it != Extension.end(); ++it) {
- if (!isAlphanumeric(*it))
- return false;
- }
- HeaderFileExtensions.insert(Extension);
- }
- return true;
-}
-
-bool isHeaderFileExtension(
- StringRef FileName, const HeaderFileExtensionsSet &HeaderFileExtensions) {
- StringRef extension = llvm::sys::path::extension(FileName);
- if (extension.empty())
- return false;
- // Skip "." prefix.
- return HeaderFileExtensions.count(extension.substr(1)) > 0;
-}
-
-} // namespace utils
-} // namespace tidy
-} // namespace clang
Index: clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.h
@@ -0,0 +1,63 @@
+//===--- FileExtensionsUtils.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_UTILS_HEADER_FILE_EXTENSIONS_UTILS_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_HEADER_FILE_EXTENSIONS_UTILS_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+namespace tidy {
+namespace 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);
+
+/// Checks whether presumed location of \p Loc is in header file.
+bool isPresumedLocInHeaderFile(SourceLocation Loc, SourceManager &SM,
+ const FileExtensionsSet &HeaderFileExtensions);
+
+/// Checks whether spelling location of \p Loc is in header file.
+bool isSpellingLocInHeaderFile(SourceLocation Loc, SourceManager &SM,
+ const FileExtensionsSet &HeaderFileExtensions);
+
+/// Returns recommended default value for the list of header file
+/// extensions.
+inline StringRef defaultHeaderFileExtensions() { return ",h,hh,hpp,hxx"; }
+
+/// Returns recommended default value for the list of implementaiton file
+/// extensions.
+inline StringRef defaultImplementationFileExtensions() {
+ return "c,cc,cpp,cxx";
+}
+
+/// Parses header file extensions from a semicolon-separated list.
+bool parseFileExtensions(StringRef AllFileExtensions,
+ FileExtensionsSet &FileExtensions, char delimiter);
+
+/// Decides whether a file has a header file extension.
+/// Returns the file extension, if included in the provided set.
+llvm::Optional<StringRef>
+getFileExtension(StringRef FileName, const FileExtensionsSet &FileExtensions);
+
+/// Decides whether a file has one of the specified file extensions.
+bool isFileExtension(StringRef FileName,
+ const FileExtensionsSet &FileExtensions);
+
+} // namespace utils
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_HEADER_FILE_EXTENSIONS_UTILS_H
Index: clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.cpp
@@ -0,0 +1,70 @@
+//===--- FileExtensionsUtils.cpp - 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "FileExtensionsUtils.h"
+#include "clang/Basic/CharInfo.h"
+#include "llvm/Support/Path.h"
+
+namespace clang {
+namespace tidy {
+namespace utils {
+
+bool isExpansionLocInHeaderFile(SourceLocation Loc, const SourceManager &SM,
+ const FileExtensionsSet &HeaderFileExtensions) {
+ SourceLocation ExpansionLoc = SM.getExpansionLoc(Loc);
+ return isFileExtension(SM.getFilename(ExpansionLoc), HeaderFileExtensions);
+}
+
+bool isPresumedLocInHeaderFile(SourceLocation Loc, SourceManager &SM,
+ const FileExtensionsSet &HeaderFileExtensions) {
+ PresumedLoc PresumedLocation = SM.getPresumedLoc(Loc);
+ return isFileExtension(PresumedLocation.getFilename(), HeaderFileExtensions);
+}
+
+bool isSpellingLocInHeaderFile(SourceLocation Loc, SourceManager &SM,
+ const FileExtensionsSet &HeaderFileExtensions) {
+ SourceLocation SpellingLoc = SM.getSpellingLoc(Loc);
+ return isFileExtension(SM.getFilename(SpellingLoc), HeaderFileExtensions);
+}
+
+bool parseFileExtensions(StringRef AllFileExtensions,
+ FileExtensionsSet &FileExtensions, char delimiter) {
+ SmallVector<StringRef, 5> Suffixes;
+ AllFileExtensions.split(Suffixes, delimiter);
+ FileExtensions.clear();
+ for (StringRef Suffix : Suffixes) {
+ StringRef Extension = Suffix.trim();
+ for (StringRef::const_iterator it = Extension.begin();
+ it != Extension.end(); ++it) {
+ if (!isAlphanumeric(*it))
+ return false;
+ }
+ FileExtensions.insert(Extension);
+ }
+ return true;
+}
+
+llvm::Optional<StringRef>
+getFileExtension(StringRef FileName, const FileExtensionsSet &FileExtensions) {
+ StringRef extension = llvm::sys::path::extension(FileName);
+ if (extension.empty())
+ return llvm::None;
+ // Skip "." prefix.
+ if (!FileExtensions.count(extension.substr(1)))
+ return llvm::None;
+ return extension;
+}
+
+bool isFileExtension(StringRef FileName,
+ const FileExtensionsSet &FileExtensions) {
+ return getFileExtension(FileName, FileExtensions).hasValue();
+}
+
+} // namespace utils
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/utils/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/utils/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/utils/CMakeLists.txt
@@ -5,8 +5,8 @@
DeclRefExprUtils.cpp
ExceptionAnalyzer.cpp
ExprSequence.cpp
+ FileExtensionsUtils.cpp
FixItHintUtils.cpp
- HeaderFileExtensionsUtils.cpp
HeaderGuard.cpp
IncludeInserter.cpp
IncludeSorter.cpp
Index: clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.h
===================================================================
--- clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.h
+++ clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.h
@@ -10,7 +10,7 @@
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_DEFINITIONS_IN_HEADERS_H
#include "../ClangTidyCheck.h"
-#include "../utils/HeaderFileExtensionsUtils.h"
+#include "../utils/FileExtensionsUtils.h"
namespace clang {
namespace tidy {
@@ -40,7 +40,7 @@
private:
const bool UseHeaderFileExtension;
const std::string RawStringHeaderFileExtensions;
- utils::HeaderFileExtensionsSet HeaderFileExtensions;
+ utils::FileExtensionsSet HeaderFileExtensions;
};
} // namespace misc
Index: clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.cpp
+++ clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.cpp
@@ -18,8 +18,8 @@
namespace {
-AST_MATCHER_P(NamedDecl, usesHeaderFileExtension,
- utils::HeaderFileExtensionsSet, HeaderFileExtensions) {
+AST_MATCHER_P(NamedDecl, usesHeaderFileExtension, utils::FileExtensionsSet,
+ HeaderFileExtensions) {
return utils::isExpansionLocInHeaderFile(
Node.getBeginLoc(), Finder->getASTContext().getSourceManager(),
HeaderFileExtensions);
@@ -33,8 +33,8 @@
UseHeaderFileExtension(Options.get("UseHeaderFileExtension", true)),
RawStringHeaderFileExtensions(Options.getLocalOrGlobal(
"HeaderFileExtensions", utils::defaultHeaderFileExtensions())) {
- if (!utils::parseHeaderFileExtensions(RawStringHeaderFileExtensions,
- HeaderFileExtensions, ',')) {
+ if (!utils::parseFileExtensions(RawStringHeaderFileExtensions,
+ HeaderFileExtensions, ',')) {
// FIXME: Find a more suitable way to handle invalid configuration
// options.
llvm::errs() << "Invalid header file extension: "
Index: clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h
===================================================================
--- clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h
+++ clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h
@@ -10,7 +10,7 @@
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_UNNAMEDNAMESPACEINHEADERCHECK_H
#include "../ClangTidyCheck.h"
-#include "../utils/HeaderFileExtensionsUtils.h"
+#include "../utils/FileExtensionsUtils.h"
namespace clang {
namespace tidy {
@@ -38,7 +38,7 @@
private:
const std::string RawStringHeaderFileExtensions;
- utils::HeaderFileExtensionsSet HeaderFileExtensions;
+ utils::FileExtensionsSet HeaderFileExtensions;
};
} // namespace build
Index: clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp
+++ clang-tools-extra/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp
@@ -23,8 +23,8 @@
: ClangTidyCheck(Name, Context),
RawStringHeaderFileExtensions(Options.getLocalOrGlobal(
"HeaderFileExtensions", utils::defaultHeaderFileExtensions())) {
- if (!utils::parseHeaderFileExtensions(RawStringHeaderFileExtensions,
- HeaderFileExtensions, ',')) {
+ if (!utils::parseFileExtensions(RawStringHeaderFileExtensions,
+ HeaderFileExtensions, ',')) {
llvm::errs() << "Invalid header file extension: "
<< RawStringHeaderFileExtensions << "\n";
}
Index: clang-tools-extra/clang-tidy/google/GlobalNamesInHeadersCheck.h
===================================================================
--- clang-tools-extra/clang-tidy/google/GlobalNamesInHeadersCheck.h
+++ clang-tools-extra/clang-tidy/google/GlobalNamesInHeadersCheck.h
@@ -10,7 +10,7 @@
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_GLOBALNAMESINHEADERSCHECK_H
#include "../ClangTidyCheck.h"
-#include "../utils/HeaderFileExtensionsUtils.h"
+#include "../utils/FileExtensionsUtils.h"
namespace clang {
namespace tidy {
@@ -35,7 +35,7 @@
private:
const std::string RawStringHeaderFileExtensions;
- utils::HeaderFileExtensionsSet HeaderFileExtensions;
+ utils::FileExtensionsSet HeaderFileExtensions;
};
} // namespace readability
Index: clang-tools-extra/clang-tidy/google/GlobalNamesInHeadersCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/google/GlobalNamesInHeadersCheck.cpp
+++ clang-tools-extra/clang-tidy/google/GlobalNamesInHeadersCheck.cpp
@@ -24,8 +24,8 @@
: ClangTidyCheck(Name, Context),
RawStringHeaderFileExtensions(Options.getLocalOrGlobal(
"HeaderFileExtensions", utils::defaultHeaderFileExtensions())) {
- if (!utils::parseHeaderFileExtensions(RawStringHeaderFileExtensions,
- HeaderFileExtensions, ',')) {
+ if (!utils::parseFileExtensions(RawStringHeaderFileExtensions,
+ HeaderFileExtensions, ',')) {
llvm::errs() << "Invalid header file extension: "
<< RawStringHeaderFileExtensions << "\n";
}
Index: clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.h
@@ -0,0 +1,57 @@
+//===--- SuspiciousIncludeCheck.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_BUGPRONE_SUSPICIOUSINCLUDECHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SUSPICIOUSINCLUDECHECK_H
+
+#include "../ClangTidyCheck.h"
+#include "../utils/FileExtensionsUtils.h"
+
+namespace clang {
+namespace tidy {
+namespace bugprone {
+
+/// Warns on inclusion of files whose names suggest that they're implementation
+/// files, instead of headers. E.g:
+///
+/// #include "foo.cpp" // warning
+/// #include "bar.c" // warning
+/// #include "baz.h" // no diagnostic
+///
+/// The check supports these options:
+/// - `SuspiciousExtensions`: a comma-separated list of filename extensions of
+/// implementation files (The filename extensions should not contain "."
+/// prefix) "c,cc,cpp,cxx" by default.
+///
+/// - `RecommendedExtensions`: likewise, a comma-separated list of filename
+/// extensions of header files. ",h,hh,hpp,hxx" by default.
+/// For extension-less header files, using an empty string or leaving an
+/// empty string between "," if there are other filename extensions.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone-suspicious-include.html
+class SuspiciousIncludeCheck : public ClangTidyCheck {
+public:
+ SuspiciousIncludeCheck(StringRef Name, ClangTidyContext *Context);
+ void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+ Preprocessor *ModuleExpanderPP) override;
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+
+ utils::FileExtensionsSet SuspiciousExtensions;
+ utils::FileExtensionsSet RecommendedExtensions;
+
+private:
+ const std::string RawStringSuspiciousExtensions;
+ const std::string RawStringRecommendedExtensions;
+};
+
+} // namespace bugprone
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SUSPICIOUSINCLUDECHECK_H
Index: clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp
@@ -0,0 +1,101 @@
+//===--- SuspiciousIncludeCheck.cpp - clang-tidy --------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "SuspiciousIncludeCheck.h"
+#include "clang/AST/ASTContext.h"
+
+namespace clang {
+namespace tidy {
+namespace bugprone {
+
+namespace {
+class SuspiciousIncludePPCallbacks : public PPCallbacks {
+public:
+ explicit SuspiciousIncludePPCallbacks(SuspiciousIncludeCheck &Check,
+ const SourceManager &SM,
+ Preprocessor *PP)
+ : Check(Check), PP(PP) {}
+
+ void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+ StringRef FileName, bool IsAngled,
+ CharSourceRange FilenameRange, const FileEntry *File,
+ StringRef SearchPath, StringRef RelativePath,
+ const Module *Imported,
+ SrcMgr::CharacteristicKind FileType) override;
+
+private:
+ SuspiciousIncludeCheck &Check;
+ Preprocessor *PP;
+};
+} // namespace
+
+SuspiciousIncludeCheck::SuspiciousIncludeCheck(StringRef Name,
+ ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ RawStringSuspiciousExtensions(Options.getLocalOrGlobal(
+ "SuspiciousExtensions",
+ utils::defaultImplementationFileExtensions())),
+ RawStringRecommendedExtensions(Options.getLocalOrGlobal(
+ "RecommendedExtensions", utils::defaultHeaderFileExtensions())) {
+ if (!utils::parseFileExtensions(RawStringSuspiciousExtensions,
+ SuspiciousExtensions, ',')) {
+ llvm::errs() << "Invalid implementation file extension: "
+ << RawStringSuspiciousExtensions << "\n";
+ }
+
+ if (!utils::parseFileExtensions(RawStringRecommendedExtensions,
+ RecommendedExtensions, ',')) {
+ llvm::errs() << "Invalid header file extension: "
+ << RawStringRecommendedExtensions << "\n";
+ }
+}
+
+void SuspiciousIncludeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "SuspiciousExtensions", RawStringSuspiciousExtensions);
+ Options.store(Opts, "RecommendedExtensions", RawStringRecommendedExtensions);
+}
+
+void SuspiciousIncludeCheck::registerPPCallbacks(
+ const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
+ PP->addPPCallbacks(
+ ::std::make_unique<SuspiciousIncludePPCallbacks>(*this, SM, PP));
+}
+
+void SuspiciousIncludePPCallbacks::InclusionDirective(
+ SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
+ bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File,
+ StringRef SearchPath, StringRef RelativePath, const Module *Imported,
+ SrcMgr::CharacteristicKind FileType) {
+ SourceLocation DiagLoc = FilenameRange.getBegin().getLocWithOffset(1);
+
+ const auto SE = utils::getFileExtension(FileName, Check.SuspiciousExtensions);
+ if (!SE)
+ return;
+
+ Check.diag(DiagLoc, "suspicious #%0 of file with '%1' extension")
+ << IncludeTok.getIdentifierInfo()->getName() << *SE;
+
+ for (const auto &RE : Check.RecommendedExtensions) {
+ SmallString<128> GuessedFileName(FileName);
+ llvm::sys::path::replace_extension(GuessedFileName,
+ (RE.size() ? "." : "") + RE);
+
+ const DirectoryLookup *CurDir;
+ Optional<FileEntryRef> File =
+ PP->LookupFile(DiagLoc, GuessedFileName, IsAngled, nullptr, nullptr,
+ CurDir, nullptr, nullptr, nullptr, nullptr, nullptr);
+ if (File) {
+ Check.diag(DiagLoc, "did you mean to include '%0'?", DiagnosticIDs::Note)
+ << GuessedFileName;
+ }
+ }
+}
+
+} // namespace bugprone
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.h
===================================================================
--- clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.h
+++ 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/HeaderFileExtensionsUtils.h"
+#include "../utils/FileExtensionsUtils.h"
namespace clang {
namespace tidy {
@@ -33,7 +33,7 @@
private:
const std::string RawStringHeaderFileExtensions;
- utils::HeaderFileExtensionsSet HeaderFileExtensions;
+ utils::FileExtensionsSet HeaderFileExtensions;
};
} // namespace bugprone
Index: clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp
@@ -31,8 +31,8 @@
: ClangTidyCheck(Name, Context),
RawStringHeaderFileExtensions(Options.getLocalOrGlobal(
"HeaderFileExtensions", utils::defaultHeaderFileExtensions())) {
- if (!utils::parseHeaderFileExtensions(RawStringHeaderFileExtensions,
- HeaderFileExtensions, ',')) {
+ if (!utils::parseFileExtensions(RawStringHeaderFileExtensions,
+ HeaderFileExtensions, ',')) {
llvm::errs() << "Invalid header file extension: "
<< RawStringHeaderFileExtensions << "\n";
}
Index: clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
@@ -37,6 +37,7 @@
StringIntegerAssignmentCheck.cpp
StringLiteralWithEmbeddedNulCheck.cpp
SuspiciousEnumUsageCheck.cpp
+ SuspiciousIncludeCheck.cpp
SuspiciousMemsetUsageCheck.cpp
SuspiciousMissingCommaCheck.cpp
SuspiciousSemicolonCheck.cpp
Index: clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
===================================================================
--- clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -45,6 +45,7 @@
#include "StringIntegerAssignmentCheck.h"
#include "StringLiteralWithEmbeddedNulCheck.h"
#include "SuspiciousEnumUsageCheck.h"
+#include "SuspiciousIncludeCheck.h"
#include "SuspiciousMemsetUsageCheck.h"
#include "SuspiciousMissingCommaCheck.h"
#include "SuspiciousSemicolonCheck.h"
@@ -140,6 +141,8 @@
"bugprone-string-literal-with-embedded-nul");
CheckFactories.registerCheck<SuspiciousEnumUsageCheck>(
"bugprone-suspicious-enum-usage");
+ CheckFactories.registerCheck<SuspiciousIncludeCheck>(
+ "bugprone-suspicious-include");
CheckFactories.registerCheck<SuspiciousMemsetUsageCheck>(
"bugprone-suspicious-memset-usage");
CheckFactories.registerCheck<SuspiciousMissingCommaCheck>(
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits