Index: clang-tidy/misc/CMakeLists.txt =================================================================== --- clang-tidy/misc/CMakeLists.txt +++ clang-tidy/misc/CMakeLists.txt @@ -2,6 +2,7 @@ add_clang_library(clangTidyMiscModule DefinitionsInHeadersCheck.cpp + HeaderGuardCheck.cpp MiscTidyModule.cpp MisplacedConstCheck.cpp NewDeleteOverloadsCheck.cpp Index: clang-tidy/misc/HeaderGuardCheck.h =================================================================== --- /dev/null +++ clang-tidy/misc/HeaderGuardCheck.h @@ -0,0 +1,33 @@ +//===--- HeaderGuardCheck.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_HEADERGUARDCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_HEADERGUARDCHECK_H + +#include "../utils/HeaderGuard.h" + +namespace clang { +namespace tidy { +namespace misc { + +/// Finds and fixes missing header guards and does not enforce any style. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/misc-header-guard.html +class MiscHeaderGuardCheck : public utils::HeaderGuardCheck { +public: + MiscHeaderGuardCheck(StringRef Name, ClangTidyContext *Context); + bool shouldSuggestEndifComment(StringRef Filename) override { return false; } + std::string getHeaderGuard(StringRef Filename, StringRef OldGuard) override; +}; + +} // namespace misc +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_HEADERGUARDCHECK_H Index: clang-tidy/misc/HeaderGuardCheck.cpp =================================================================== --- /dev/null +++ clang-tidy/misc/HeaderGuardCheck.cpp @@ -0,0 +1,33 @@ +//===--- HeaderGuardCheck.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 "HeaderGuardCheck.h" + +namespace clang { +namespace tidy { +namespace misc { + +MiscHeaderGuardCheck::MiscHeaderGuardCheck(StringRef Name, + ClangTidyContext *Context) + : HeaderGuardCheck(Name, Context) {} + +std::string MiscHeaderGuardCheck::getHeaderGuard(StringRef Filename, + StringRef OldGuard) { + if (OldGuard.size()) { + return OldGuard; + } else { + std::string Guard = llvm::sys::path::filename(Filename); + std::replace(Guard.begin(), Guard.end(), '.', '_'); + std::replace(Guard.begin(), Guard.end(), '-', '_'); + return StringRef(Guard).upper(); + } +} + +} // namespace misc +} // namespace tidy +} // namespace clang Index: clang-tidy/misc/MiscTidyModule.cpp =================================================================== --- clang-tidy/misc/MiscTidyModule.cpp +++ clang-tidy/misc/MiscTidyModule.cpp @@ -10,6 +10,7 @@ #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" #include "DefinitionsInHeadersCheck.h" +#include "HeaderGuardCheck.h" #include "MisplacedConstCheck.h" #include "NewDeleteOverloadsCheck.h" #include "NonCopyableObjects.h" @@ -32,6 +33,8 @@ void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { CheckFactories.registerCheck( "misc-definitions-in-headers"); + CheckFactories.registerCheck( + "misc-header-guard"); CheckFactories.registerCheck("misc-misplaced-const"); CheckFactories.registerCheck( "misc-new-delete-overloads"); Index: docs/ReleaseNotes.rst =================================================================== --- docs/ReleaseNotes.rst +++ docs/ReleaseNotes.rst @@ -108,6 +108,11 @@ Checks whether there are underscores in googletest test and test case names in test macros, which is prohibited by the Googletest FAQ. +- New :doc:`misc-header-guard + ` check. + + Finds and fixes missing header guards and does not enforce any style. + - New :doc:`objc-super-self ` check. Finds invocations of ``-self`` on super instances in initializers of Index: docs/clang-tidy/checks/list.rst =================================================================== --- docs/clang-tidy/checks/list.rst +++ docs/clang-tidy/checks/list.rst @@ -181,6 +181,7 @@ llvm-prefer-isa-or-dyn-cast-in-conditionals llvm-twine-local misc-definitions-in-headers + misc-header-guard misc-misplaced-const misc-new-delete-overloads misc-non-copyable-objects Index: docs/clang-tidy/checks/misc-header-guard.rst =================================================================== --- /dev/null +++ docs/clang-tidy/checks/misc-header-guard.rst @@ -0,0 +1,18 @@ +.. title:: clang-tidy - misc-header-guard + +misc-header-guard +================= + +Finds and fixes missing header guards and does not enforce any style. + +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). + Index: test/clang-tidy/misc-header-guard.cpp =================================================================== --- /dev/null +++ test/clang-tidy/misc-header-guard.cpp @@ -0,0 +1,9 @@ +// RUN: %check_clang_tidy %s misc-header-guard %t -- \ +// RUN: -config="{CheckOptions: [{key: misc-header-guard.HeaderFileExtensions, value: 'cpp'}]}" \ +// RUN: -header-filter=.* -- + +// CHECK-MESSAGES: 1:1: warning: header is missing header guard + +// CHECK-FIXES: #ifndef MISC_HEADER_GUARD_CPP_TMP_CPP +// CHECK-FIXES-NEXT: #define MISC_HEADER_GUARD_CPP_TMP_CPP +// CHECK-FIXES: #endif