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
36namespace clang {
37namespace clangd {
38
39// Data needed for missing include diagnostics.
40struct 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
51struct IncludeCleanerFindings {
52 std::vector<const Inclusion *> UnusedIncludes;
53 std::vector<MissingIncludeDiagInfo> MissingIncludes;
54};
55
56IncludeCleanerFindings computeIncludeCleanerFindings(ParsedAST &AST);
57
58using HeaderFilter = llvm::ArrayRef<std::function<bool(llvm::StringRef)>>;
59std::vector<Diag>
60issueIncludeCleanerDiagnostics(ParsedAST &AST, llvm::StringRef Code,
61 const IncludeCleanerFindings &Findings,
62 HeaderFilter IgnoreHeader = {});
63
64/// Affects whether standard library includes should be considered for
65/// removal. This is off by default for now due to implementation limitations:
66/// - macros are not tracked
67/// - symbol names without a unique associated header are not tracked
68/// - references to std-namespaced C types are not properly tracked:
69/// instead of std::size_t -> <cstddef> we see ::size_t -> <stddef.h>
70/// FIXME: remove this hack once the implementation is good enough.
71void setIncludeCleanerAnalyzesStdlib(bool B);
72
73/// Converts the clangd include representation to include-cleaner
74/// include representation.
75include_cleaner::Includes
76convertIncludes(const SourceManager &SM,
77 const llvm::ArrayRef<Inclusion> Includes);
78
79std::vector<include_cleaner::SymbolReference>
80collectMacroReferences(ParsedAST &AST);
81
82/// Find the first provider in the list that is matched by the includes.
83std::optional<include_cleaner::Header>
84firstMatchedProvider(const include_cleaner::Includes &Includes,
85 llvm::ArrayRef<include_cleaner::Header> Providers);
86} // namespace clangd
87} // namespace clang
88
89#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INCLUDECLEANER_H
90