aboutsummaryrefslogtreecommitdiff
path: root/clang-tidy/FixIncludes.cc
diff options
context:
space:
mode:
authorJade Lovelace <lix@jade.fyi>2024-03-29 20:26:38 -0700
committerjade <lix@jade.fyi>2024-04-06 04:40:19 +0000
commit43cf487c256395e03f2e10f1f66b3933f201a4e8 (patch)
tree7cd40af4daf8f3c40f50596bbaeb00f5bbe43676 /clang-tidy/FixIncludes.cc
parent194a1b91af6d8848e4cc0dfbdcc153ee2dbed140 (diff)
Create clang-tidy check to rename all our includes
It is a little bit scuffed, but it seems to produce correct results. We can run it at a later date when we want to explode every in-flight commit in existence and then need to filter-branch them. Fixes: https://git.lix.systems/lix-project/lix/issues/188 Change-Id: Id97e4651f78804a941d941df02c7c1b21ce453b6
Diffstat (limited to 'clang-tidy/FixIncludes.cc')
-rw-r--r--clang-tidy/FixIncludes.cc81
1 files changed, 81 insertions, 0 deletions
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