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