diff options
Diffstat (limited to 'clang-tidy')
-rw-r--r-- | clang-tidy/.editorconfig | 4 | ||||
-rw-r--r-- | clang-tidy/FixIncludes.cc | 81 | ||||
-rw-r--r-- | clang-tidy/FixIncludes.hh | 21 | ||||
-rw-r--r-- | clang-tidy/LixClangTidyChecks.cc (renamed from clang-tidy/NixClangTidyChecks.cc) | 6 | ||||
-rw-r--r-- | clang-tidy/meson.build | 11 |
5 files changed, 118 insertions, 5 deletions
diff --git a/clang-tidy/.editorconfig b/clang-tidy/.editorconfig new file mode 100644 index 000000000..19ee09eec --- /dev/null +++ b/clang-tidy/.editorconfig @@ -0,0 +1,4 @@ +# LLVM style code is 2-space indented +[*.{cc,hh}] +indent_style = space +indent_size = 2 diff --git a/clang-tidy/FixIncludes.cc b/clang-tidy/FixIncludes.cc new file mode 100644 index 000000000..8ba350243 --- /dev/null +++ b/clang-tidy/FixIncludes.cc @@ -0,0 +1,81 @@ +#include "FixIncludes.hh" +#include <clang-tidy/ClangTidyCheck.h> +#include <clang/Basic/Diagnostic.h> +#include <clang/Basic/SourceManager.h> +#include <clang/Lex/PPCallbacks.h> +#include <clang/Lex/Preprocessor.h> +#include <llvm/ADT/StringRef.h> +#include <llvm/Support/Debug.h> +#include <memory> +#include <set> +#include <string> + +namespace nix::clang_tidy { + +using namespace clang; +using namespace clang::tidy; + +class FixIncludesCallbacks : public PPCallbacks { +public: + ClangTidyCheck &Check; + Preprocessor &PP; + FixIncludesCallbacks(ClangTidyCheck &Check, Preprocessor &PP) + : Check(Check), PP(PP) {} + +private: + bool Ignore = false; + virtual void LexedFileChanged(FileID FID, LexedFileChangeReason Reason, + SrcMgr::CharacteristicKind FileType, + FileID PrevFID, SourceLocation Loc) override; + + virtual 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; +}; + +void FixIncludesCallbacks::LexedFileChanged(FileID, LexedFileChangeReason, + SrcMgr::CharacteristicKind FileType, + FileID, SourceLocation) { + Ignore = FileType != SrcMgr::C_User; +} + +void FixIncludesCallbacks::InclusionDirective( + SourceLocation, const Token &, StringRef, bool, + CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef, + StringRef, const Module *, SrcMgr::CharacteristicKind) { + if (Ignore) + return; + + // FIXME: this is kinda evil, but this is a one-time fixup + const std::string SourceDir = "src/"; + + if (File && File->getNameAsRequested().contains(SourceDir)) { + StringRef Name = File->getNameAsRequested(); + auto Idx = Name.find(SourceDir); + assert(Idx != std::string::npos); + StringRef Suffix = Name.drop_front(Idx + SourceDir.length()); + + if (!Suffix.starts_with("lib")) { + llvm::dbgs() << "ignored: " << Suffix << "\n"; + return; + } + + auto Diag = Check.diag(FilenameRange.getBegin(), + "include needs to specify the source subdir"); + + Diag << FilenameRange + << FixItHint::CreateReplacement(FilenameRange, + ("\"" + Suffix + "\"").str()); + } +} + +void FixIncludesCheck::registerPPCallbacks(const SourceManager &, + Preprocessor *PP, Preprocessor *) { + PP->addPPCallbacks(std::make_unique<FixIncludesCallbacks>(*this, *PP)); +} + +}; // namespace nix::clang_tidy diff --git a/clang-tidy/FixIncludes.hh b/clang-tidy/FixIncludes.hh new file mode 100644 index 000000000..ea890cd39 --- /dev/null +++ b/clang-tidy/FixIncludes.hh @@ -0,0 +1,21 @@ +#pragma once +///@file + +#include <clang-tidy/ClangTidyCheck.h> +#include <clang/ASTMatchers/ASTMatchFinder.h> +#include <llvm/ADT/StringRef.h> + +namespace nix::clang_tidy { + +using namespace clang; +using namespace clang::tidy; + +class FixIncludesCheck : public ClangTidyCheck { + public: + FixIncludesCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + + void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override; +}; + +}; diff --git a/clang-tidy/NixClangTidyChecks.cc b/clang-tidy/LixClangTidyChecks.cc index 8f0309107..b3503dd3a 100644 --- a/clang-tidy/NixClangTidyChecks.cc +++ b/clang-tidy/LixClangTidyChecks.cc @@ -1,5 +1,6 @@ #include <clang-tidy/ClangTidyModule.h> #include <clang-tidy/ClangTidyModuleRegistry.h> +#include "FixIncludes.hh" #include "HasPrefixSuffix.hh" namespace nix::clang_tidy { @@ -9,9 +10,10 @@ using namespace clang::tidy; class NixClangTidyChecks : public ClangTidyModule { public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { - CheckFactories.registerCheck<HasPrefixSuffixCheck>("nix-hasprefixsuffix"); + CheckFactories.registerCheck<HasPrefixSuffixCheck>("lix-hasprefixsuffix"); + CheckFactories.registerCheck<FixIncludesCheck>("lix-fixincludes"); } }; -static ClangTidyModuleRegistry::Add<NixClangTidyChecks> X("nix-module", "Adds nix specific checks"); +static ClangTidyModuleRegistry::Add<NixClangTidyChecks> X("lix-module", "Adds lix specific checks"); }; diff --git a/clang-tidy/meson.build b/clang-tidy/meson.build index 48770e39f..c59164a72 100644 --- a/clang-tidy/meson.build +++ b/clang-tidy/meson.build @@ -1,8 +1,13 @@ -project('nix-clang-tidy', ['cpp', 'c'], +project('lix-clang-tidy', ['cpp', 'c'], version : '0.1', default_options : ['warning_level=3', 'cpp_std=c++20']) llvm = dependency('Clang', version: '>= 14', modules: ['libclang']) -sources = ['HasPrefixSuffix.cc', 'NixClangTidyChecks.cc'] -shared_module('nix-clang-tidy', sources, +sources = files( + 'HasPrefixSuffix.cc', + 'LixClangTidyChecks.cc', + 'FixIncludes.cc', +) + +shared_module('lix-clang-tidy', sources, dependencies: llvm) |