xref: /llvm-project/clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h (revision ec6c3448d31056db5d63d7aed3e9f207edb49321)
1 //===--- Analysis.h - Analyze symbol references in AST ------------- 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 /// A library that provides usage analysis for symbols based on AST analysis.
9 //===----------------------------------------------------------------------===//
10 
11 #ifndef CLANG_INCLUDE_CLEANER_ANALYSIS_H
12 #define CLANG_INCLUDE_CLEANER_ANALYSIS_H
13 
14 #include "clang-include-cleaner/Record.h"
15 #include "clang-include-cleaner/Types.h"
16 #include "clang/Format/Format.h"
17 #include "clang/Lex/HeaderSearch.h"
18 #include "clang/Lex/Preprocessor.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/STLFunctionalExtras.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/ADT/StringRef.h"
23 #include <string>
24 #include <utility>
25 
26 namespace clang {
27 class SourceLocation;
28 class SourceManager;
29 class Decl;
30 class FileEntry;
31 class HeaderSearch;
32 namespace tooling {
33 class Replacements;
34 struct IncludeStyle;
35 } // namespace tooling
36 namespace include_cleaner {
37 
38 /// A UsedSymbolCB is a callback invoked for each symbol reference seen.
39 ///
40 /// References occur at a particular location, refer to a single symbol, and
41 /// that symbol may be provided by several headers.
42 /// FIXME: Provide signals about the providing headers so the caller can filter
43 /// and rank the results.
44 using UsedSymbolCB = llvm::function_ref<void(const SymbolReference &SymRef,
45                                              llvm::ArrayRef<Header> Providers)>;
46 
47 /// Find and report all references to symbols in a region of code.
48 /// It only reports references from main file.
49 ///
50 /// The AST traversal is rooted at ASTRoots - typically top-level declarations
51 /// of a single source file.
52 /// The references to macros must be recorded separately and provided.
53 ///
54 /// This is the main entrypoint of the include-cleaner library, and can be used:
55 ///  - to diagnose missing includes: a referenced symbol is provided by
56 ///    headers which don't match any #include in the main file
57 ///  - to diagnose unused includes: an #include in the main file does not match
58 ///    the headers for any referenced symbol
59 void walkUsed(llvm::ArrayRef<Decl *> ASTRoots,
60               llvm::ArrayRef<SymbolReference> MacroRefs,
61               const PragmaIncludes *PI, const Preprocessor &PP,
62               UsedSymbolCB CB);
63 
64 struct AnalysisResults {
65   std::vector<const Include *> Unused;
66   // Spellings, like "<vector>" paired with the Header that generated it.
67   std::vector<std::pair<std::string, Header>> Missing;
68 };
69 
70 /// Determine which headers should be inserted or removed from the main file.
71 /// This exposes conclusions but not reasons: use lower-level walkUsed for that.
72 ///
73 /// The HeaderFilter is a predicate that receives absolute path or spelling
74 /// without quotes/brackets, when a phyiscal file doesn't exist.
75 /// No analysis will be performed for headers that satisfy the predicate.
76 AnalysisResults
77 analyze(llvm::ArrayRef<Decl *> ASTRoots,
78         llvm::ArrayRef<SymbolReference> MacroRefs, const Includes &I,
79         const PragmaIncludes *PI, const Preprocessor &PP,
80         llvm::function_ref<bool(llvm::StringRef)> HeaderFilter = nullptr);
81 
82 /// Removes unused includes and inserts missing ones in the main file.
83 /// Returns the modified main-file code.
84 /// The FormatStyle must be C++ or ObjC (to support include ordering).
85 std::string fixIncludes(const AnalysisResults &Results,
86                         llvm::StringRef FileName, llvm::StringRef Code,
87                         const format::FormatStyle &IncludeStyle);
88 
89 /// Gets all the providers for a symbol by traversing each location.
90 /// Returned headers are sorted by relevance, first element is the most
91 /// likely provider for the symbol.
92 llvm::SmallVector<Header> headersForSymbol(const Symbol &S,
93                                            const Preprocessor &PP,
94                                            const PragmaIncludes *PI);
95 } // namespace include_cleaner
96 } // namespace clang
97 
98 #endif
99