Index: clang-tools-extra/clang-tidy/readability/AbsoluteIncludesOnlyCheck.h =================================================================== --- /dev/null +++ clang-tools-extra/clang-tidy/readability/AbsoluteIncludesOnlyCheck.h @@ -0,0 +1,31 @@ +//===--- AbsoluteIncludesOnlyCheck.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_READABILITY_ABSOLUTEINCLUDESONLYCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_ABSOLUTEINCLUDESONLYCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::readability { + +/// A check to not allow relative includes (includes using quotes). +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/readability/absolute-includes-only.html +class AbsoluteIncludesOnlyCheck : public ClangTidyCheck { +public: + AbsoluteIncludesOnlyCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + + void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, + Preprocessor *ModuleExpanderPP) override; +}; + +} // namespace clang::tidy::readability + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_ABSOLUTEINCLUDESONLYCHECK_H Index: clang-tools-extra/clang-tidy/readability/AbsoluteIncludesOnlyCheck.cpp =================================================================== --- /dev/null +++ clang-tools-extra/clang-tidy/readability/AbsoluteIncludesOnlyCheck.cpp @@ -0,0 +1,58 @@ +//===--- AbsoluteIncludesOnlyCheck.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 "AbsoluteIncludesOnlyCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/Preprocessor.h" + +namespace clang::tidy::readability { + +namespace { +class AbsoluteIncludesOnlyPPCallbacks : public PPCallbacks { +public: + explicit AbsoluteIncludesOnlyPPCallbacks(AbsoluteIncludesOnlyCheck &Check, + const SourceManager &SM) + : Check(Check) {} + + void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, + StringRef FileName, bool IsAngled, + CharSourceRange FilenameRange, + OptionalFileEntryRef File, StringRef SearchPath, + StringRef RelativePath, const Module *Imported, + SrcMgr::CharacteristicKind FileType) override; + +private: + AbsoluteIncludesOnlyCheck &Check; +}; +} // namespace + +void AbsoluteIncludesOnlyCheck::registerPPCallbacks( + const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + PP->addPPCallbacks( + ::std::make_unique(*this, SM)); +} + +void AbsoluteIncludesOnlyPPCallbacks::InclusionDirective( + SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, + bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, + StringRef SearchPath, StringRef RelativePath, const Module *Imported, + SrcMgr::CharacteristicKind FileType) { + if (IncludeTok.getIdentifierInfo()->getPPKeywordID() == tok::pp_import) + return; + + SourceLocation DiagLoc = FilenameRange.getBegin().getLocWithOffset(0); + if (!IsAngled) { + Check.diag(DiagLoc, "relative include found, use only absolute includes", + DiagnosticIDs::Warning); + } +} + +} // namespace clang::tidy::readability Index: clang-tools-extra/clang-tidy/readability/CMakeLists.txt =================================================================== --- clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -4,6 +4,7 @@ ) add_clang_library(clangTidyReadabilityModule + AbsoluteIncludesOnlyCheck.cpp AvoidConstParamsInDecls.cpp AvoidUnconditionalPreprocessorIfCheck.cpp BracesAroundStatementsCheck.cpp Index: clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp =================================================================== --- clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp +++ clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp @@ -9,6 +9,7 @@ #include "../ClangTidy.h" #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" +#include "AbsoluteIncludesOnlyCheck.h" #include "AvoidConstParamsInDecls.h" #include "AvoidUnconditionalPreprocessorIfCheck.h" #include "BracesAroundStatementsCheck.h" @@ -60,6 +61,8 @@ class ReadabilityModule : public ClangTidyModule { public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { + CheckFactories.registerCheck( + "readability-absolute-includes-only"); CheckFactories.registerCheck( "readability-avoid-const-params-in-decls"); CheckFactories.registerCheck( Index: clang-tools-extra/docs/ReleaseNotes.rst =================================================================== --- clang-tools-extra/docs/ReleaseNotes.rst +++ clang-tools-extra/docs/ReleaseNotes.rst @@ -181,6 +181,12 @@ Finds uses of ``std::endl`` on streams and replaces them with ``'\n'``. +- New :doc:`readability-absolute-includes-only + ` check. + +Finds relative includes in your code and warn about them. for example +don't use "readability/absolute-includes-only", use + - New :doc:`readability-avoid-unconditional-preprocessor-if ` check. Index: clang-tools-extra/docs/clang-tidy/checks/list.rst =================================================================== --- clang-tools-extra/docs/clang-tidy/checks/list.rst +++ clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -337,6 +337,7 @@ `portability-restrict-system-includes `_, "Yes" `portability-simd-intrinsics `_, `portability-std-allocator-const `_, + `readability-absolute-includes-only `_, `readability-avoid-const-params-in-decls `_, "Yes" `readability-avoid-unconditional-preprocessor-if `_, `readability-braces-around-statements `_, "Yes" Index: clang-tools-extra/docs/clang-tidy/checks/readability/absolute-includes-only.rst =================================================================== --- /dev/null +++ clang-tools-extra/docs/clang-tidy/checks/readability/absolute-includes-only.rst @@ -0,0 +1,21 @@ +.. title:: clang-tidy - readability-absolute-includes-only + +readability-absolute-includes-only +================================== + +Finds relative includes inside of the code and warn about them. + +Meaning this check disallow the use of quote includes (""), and allow only angular brackets includes (<>). + +This is relevant for the canonical project structure specified in paper p1204r0. +The relevant part is the src-dir where relative includes are discussed: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1204r0.html#src-dir + +Example (taken from the paper): + +.. code-block:: c++ + + // #include "utility.hpp" // Wrong. + // #include // Wrong. + // #include "../hello/utility.hpp" // Wrong. + + #include Index: clang-tools-extra/test/clang-tidy/checkers/readability/absolute-includes-only.cpp =================================================================== --- /dev/null +++ clang-tools-extra/test/clang-tidy/checkers/readability/absolute-includes-only.cpp @@ -0,0 +1,18 @@ +// RUN: %check_clang_tidy %s readability-absolute-includes-only %t -- -- -isystem %clang_tidy_headers -fmodules + +// clang-format off + +// CHECK-MESSAGES: [[@LINE+1]]:10: warning: relative include found, use only absolute includes +#include "j.h" + +// CHECK-MESSAGES: [[@LINE+1]]:10: warning: relative include found, use only absolute includes +#include "llvm/a.h" + +// CHECK-MESSAGES: [[@LINE+1]]:10: warning: relative include found, use only absolute includes +#include "clang/../b.h" + + +#include + +#include +