| 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 ; |
| 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)> = 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 | |