xref: /llvm-project/clang-tools-extra/clangd/IncludeCleaner.h (revision 1f90797f6a9d91d61e0f66b465b0467e4c66d0e0)
1 //===--- IncludeCleaner.h - Unused/Missing Headers Analysis -----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// Include Cleaner is clangd functionality for providing diagnostics for misuse
11 /// of transitive headers and unused includes. It is inspired by
12 /// Include-What-You-Use tool (https://include-what-you-use.org/). Our goal is
13 /// to provide useful warnings in most popular scenarios but not 1:1 exact
14 /// feature compatibility.
15 ///
16 //===----------------------------------------------------------------------===//
17 
18 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INCLUDECLEANER_H
19 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INCLUDECLEANER_H
20 
21 #include "Diagnostics.h"
22 #include "Headers.h"
23 #include "ParsedAST.h"
24 #include "Protocol.h"
25 #include "clang-include-cleaner/Types.h"
26 #include "clang/Basic/SourceManager.h"
27 #include "clang/Tooling/Syntax/Tokens.h"
28 #include "llvm/ADT/ArrayRef.h"
29 #include "llvm/ADT/StringRef.h"
30 #include <functional>
31 #include <optional>
32 #include <string>
33 #include <tuple>
34 #include <vector>
35 
36 namespace clang {
37 namespace clangd {
38 
39 // Data needed for missing include diagnostics.
40 struct MissingIncludeDiagInfo {
41   include_cleaner::Symbol Symbol;
42   syntax::FileRange SymRefRange;
43   std::vector<include_cleaner::Header> Providers;
44 
45   bool operator==(const MissingIncludeDiagInfo &Other) const {
46     return std::tie(SymRefRange, Providers, Symbol) ==
47            std::tie(Other.SymRefRange, Other.Providers, Other.Symbol);
48   }
49 };
50 
51 struct IncludeCleanerFindings {
52   std::vector<const Inclusion *> UnusedIncludes;
53   std::vector<MissingIncludeDiagInfo> MissingIncludes;
54 };
55 
56 IncludeCleanerFindings
57 computeIncludeCleanerFindings(ParsedAST &AST,
58                               bool AnalyzeAngledIncludes = false);
59 
60 std::vector<Diag>
61 issueIncludeCleanerDiagnostics(ParsedAST &AST, llvm::StringRef Code,
62                                const IncludeCleanerFindings &Findings,
63                                const ThreadsafeFS &TFS,
64                                HeaderFilter IgnoreHeader = {});
65 
66 /// Converts the clangd include representation to include-cleaner
67 /// include representation.
68 include_cleaner::Includes convertIncludes(const ParsedAST &);
69 
70 std::vector<include_cleaner::SymbolReference>
71 collectMacroReferences(ParsedAST &AST);
72 
73 /// Whether this #include is considered to provide a particular symbol.
74 ///
75 /// This means it satisfies the reference, and no other #include does better.
76 /// `Providers` is the symbol's candidate headers according to walkUsed().
77 bool isPreferredProvider(const Inclusion &, const include_cleaner::Includes &,
78                          llvm::ArrayRef<include_cleaner::Header> Providers);
79 
80 } // namespace clangd
81 } // namespace clang
82 
83 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INCLUDECLEANER_H
84