jroelofs created this revision.
jroelofs added a reviewer: aaron.ballman.
Herald added subscribers: cfe-commits, kbarton, xazax.hun, mgorny, nemanjai.
Herald added a project: clang.

Detects and fixes suspicious code like: `#include "foo.cpp"`.

      

Inspired by: https://twitter.com/lefticus/status/1228458240364687360?s=20


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D74669

Files:
  clang-tools-extra/clang-tidy/misc/CMakeLists.txt
  clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
  clang-tools-extra/clang-tidy/misc/NoIncludeCPPCheck.cpp
  clang-tools-extra/clang-tidy/misc/NoIncludeCPPCheck.h
  clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/a.cpp
  clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/c.c
  clang-tools-extra/test/clang-tidy/checkers/misc-no-include-cpp.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/misc-no-include-cpp.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/misc-no-include-cpp.cpp
@@ -0,0 +1,11 @@
+// RUN: %check_clang_tidy %s misc-no-include-cpp %t -- -- -isystem %S/Inputs/Headers
+
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: suspicious #include
+// CHECK-MESSAGES: [[@LINE+3]]:1: warning: suspicious #include
+#include "a.cpp"
+#include "b.h"
+#include <c.c>
+
+// CHECK-FIXES: #include "a.h"
+// CHECK-FIXES-NEXT: #include "b.h"
+// CHECK-FIXES-NEXT: #include <c.h>
Index: clang-tools-extra/clang-tidy/misc/NoIncludeCPPCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/misc/NoIncludeCPPCheck.h
@@ -0,0 +1,39 @@
+//===--- NoIncludeCPPCheck.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_MISC_NOINCLUDECPPCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NOINCLUDECPPCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+/// 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
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/misc-NoIncludeCPP.html
+class NoIncludeCPPCheck : public ClangTidyCheck {
+public:
+  NoIncludeCPPCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP);
+};
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NOINCLUDECPPCHECK_H
Index: clang-tools-extra/clang-tidy/misc/NoIncludeCPPCheck.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/misc/NoIncludeCPPCheck.cpp
@@ -0,0 +1,70 @@
+//===--- NoIncludeCPPCheck.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 "NoIncludeCPPCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+namespace {
+class NoIncludeCPPPPCallbacks : public PPCallbacks {
+public:
+  explicit NoIncludeCPPPPCallbacks(ClangTidyCheck &Check,
+                                   const SourceManager &SM)
+      : Check(Check) {}
+
+  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:
+  ClangTidyCheck &Check;
+};
+} // namespace
+
+void NoIncludeCPPCheck::registerPPCallbacks(const SourceManager &SM,
+                                            Preprocessor *PP,
+                                            Preprocessor *ModuleExpanderPP) {
+  PP->addPPCallbacks(::std::make_unique<NoIncludeCPPPPCallbacks>(*this, SM));
+}
+
+void NoIncludeCPPPPCallbacks::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) {
+
+  (void)FilenameRange;
+  (void)File;
+  (void)SearchPath;
+  (void)RelativePath;
+  (void)Imported;
+  (void)FileType;
+
+  const char *SuspiciousExtensions[] = {".cpp", ".c"};
+
+  for (const char *SE : SuspiciousExtensions)
+    if (FileName.consume_back(SE))
+      Check.diag(HashLoc, "suspicious #include")
+          << FixItHint::CreateReplacement(FilenameRange,
+                                          ((IsAngled ? "<" : "\"") + FileName +
+                                           ".h" + (IsAngled ? ">" : "\""))
+                                              .str());
+}
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
===================================================================
--- clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
+++ clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
@@ -12,6 +12,7 @@
 #include "DefinitionsInHeadersCheck.h"
 #include "MisplacedConstCheck.h"
 #include "NewDeleteOverloadsCheck.h"
+#include "NoIncludeCPPCheck.h"
 #include "NoRecursionCheck.h"
 #include "NonCopyableObjects.h"
 #include "NonPrivateMemberVariablesInClassesCheck.h"
@@ -36,6 +37,7 @@
     CheckFactories.registerCheck<MisplacedConstCheck>("misc-misplaced-const");
     CheckFactories.registerCheck<NewDeleteOverloadsCheck>(
         "misc-new-delete-overloads");
+    CheckFactories.registerCheck<NoIncludeCPPCheck>("misc-no-include-cpp");
     CheckFactories.registerCheck<NoRecursionCheck>("misc-no-recursion");
     CheckFactories.registerCheck<NonCopyableObjectsCheck>(
         "misc-non-copyable-objects");
Index: clang-tools-extra/clang-tidy/misc/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/misc/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/misc/CMakeLists.txt
@@ -6,6 +6,7 @@
   MisplacedConstCheck.cpp
   NewDeleteOverloadsCheck.cpp
   NoRecursionCheck.cpp
+  NoIncludeCPPCheck.cpp
   NonCopyableObjects.cpp
   NonPrivateMemberVariablesInClassesCheck.cpp
   RedundantExpressionCheck.cpp
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to