Skip to content

Commit 089d9c5

Browse files
committed
[clangd] IncludeCleaner: Decrease API dependency on clangd
Reviewed By: sammccall Differential Revision: https://reviews.llvm.org/D118882
1 parent 005fd8a commit 089d9c5

File tree

2 files changed

+44
-18
lines changed

2 files changed

+44
-18
lines changed

clang-tools-extra/clangd/IncludeCleaner.cpp

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@
1414
#include "SourceCode.h"
1515
#include "support/Logger.h"
1616
#include "support/Trace.h"
17+
#include "clang/AST/ASTContext.h"
1718
#include "clang/AST/ExprCXX.h"
1819
#include "clang/AST/RecursiveASTVisitor.h"
1920
#include "clang/Basic/SourceLocation.h"
2021
#include "clang/Basic/SourceManager.h"
2122
#include "clang/Lex/HeaderSearch.h"
2223
#include "clang/Lex/Preprocessor.h"
2324
#include "clang/Tooling/Syntax/Tokens.h"
25+
#include "llvm/ADT/STLFunctionalExtras.h"
2426
#include "llvm/Support/FormatVariadic.h"
2527
#include "llvm/Support/Path.h"
2628

@@ -207,10 +209,10 @@ clangd::Range getDiagnosticRange(llvm::StringRef Code, unsigned HashOffset) {
207209

208210
// Finds locations of macros referenced from within the main file. That includes
209211
// references that were not yet expanded, e.g `BAR` in `#define FOO BAR`.
210-
void findReferencedMacros(ParsedAST &AST, ReferencedLocations &Result) {
212+
void findReferencedMacros(const SourceManager &SM, Preprocessor &PP,
213+
const syntax::TokenBuffer *Tokens,
214+
ReferencedLocations &Result) {
211215
trace::Span Tracer("IncludeCleaner::findReferencedMacros");
212-
auto &SM = AST.getSourceManager();
213-
auto &PP = AST.getPreprocessor();
214216
// FIXME(kirillbobyrev): The macros from the main file are collected in
215217
// ParsedAST's MainFileMacros. However, we can't use it here because it
216218
// doesn't handle macro references that were not expanded, e.g. in macro
@@ -220,8 +222,7 @@ void findReferencedMacros(ParsedAST &AST, ReferencedLocations &Result) {
220222
// this mechanism (as opposed to iterating through all tokens) will improve
221223
// the performance of findReferencedMacros and also improve other features
222224
// relying on MainFileMacros.
223-
for (const syntax::Token &Tok :
224-
AST.getTokens().spelledTokens(SM.getMainFileID())) {
225+
for (const syntax::Token &Tok : Tokens->spelledTokens(SM.getMainFileID())) {
225226
auto Macro = locateMacroAt(Tok, PP);
226227
if (!Macro)
227228
continue;
@@ -287,18 +288,26 @@ FileID headerResponsible(FileID ID, const SourceManager &SM,
287288

288289
} // namespace
289290

290-
ReferencedLocations findReferencedLocations(ParsedAST &AST) {
291+
ReferencedLocations findReferencedLocations(const SourceManager &SM,
292+
ASTContext &Ctx, Preprocessor &PP,
293+
const syntax::TokenBuffer *Tokens) {
291294
trace::Span Tracer("IncludeCleaner::findReferencedLocations");
292295
ReferencedLocations Result;
293-
ReferencedLocationCrawler Crawler(Result, AST.getSourceManager());
294-
Crawler.TraverseAST(AST.getASTContext());
295-
findReferencedMacros(AST, Result);
296+
ReferencedLocationCrawler Crawler(Result, SM);
297+
Crawler.TraverseAST(Ctx);
298+
if (Tokens)
299+
findReferencedMacros(SM, PP, Tokens, Result);
296300
return Result;
297301
}
298302

299-
ReferencedFiles findReferencedFiles(const ReferencedLocations &Locs,
300-
const IncludeStructure &Includes,
301-
const SourceManager &SM) {
303+
ReferencedLocations findReferencedLocations(ParsedAST &AST) {
304+
return findReferencedLocations(AST.getSourceManager(), AST.getASTContext(),
305+
AST.getPreprocessor(), &AST.getTokens());
306+
}
307+
308+
ReferencedFiles
309+
findReferencedFiles(const ReferencedLocations &Locs, const SourceManager &SM,
310+
llvm::function_ref<FileID(FileID)> HeaderResponsible) {
302311
std::vector<SourceLocation> Sorted{Locs.User.begin(), Locs.User.end()};
303312
llvm::sort(Sorted); // Group by FileID.
304313
ReferencedFilesBuilder Builder(SM);
@@ -318,7 +327,7 @@ ReferencedFiles findReferencedFiles(const ReferencedLocations &Locs,
318327
// HeaderIDs, as each inclusion of a non-self-contained file is distinct.
319328
llvm::DenseSet<FileID> UserFiles;
320329
for (FileID ID : Builder.Files)
321-
UserFiles.insert(headerResponsible(ID, SM, Includes));
330+
UserFiles.insert(HeaderResponsible(ID));
322331

323332
llvm::DenseSet<stdlib::Header> StdlibFiles;
324333
for (const auto &Symbol : Locs.Stdlib)
@@ -328,6 +337,14 @@ ReferencedFiles findReferencedFiles(const ReferencedLocations &Locs,
328337
return {std::move(UserFiles), std::move(StdlibFiles)};
329338
}
330339

340+
ReferencedFiles findReferencedFiles(const ReferencedLocations &Locs,
341+
const IncludeStructure &Includes,
342+
const SourceManager &SM) {
343+
return findReferencedFiles(Locs, SM, [&SM, &Includes](FileID ID) {
344+
return headerResponsible(ID, SM, Includes);
345+
});
346+
}
347+
331348
std::vector<const Inclusion *>
332349
getUnused(ParsedAST &AST,
333350
const llvm::DenseSet<IncludeStructure::HeaderID> &ReferencedFiles) {

clang-tools-extra/clangd/IncludeCleaner.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "ParsedAST.h"
2626
#include "clang/Basic/SourceLocation.h"
2727
#include "llvm/ADT/DenseSet.h"
28+
#include "llvm/ADT/STLFunctionalExtras.h"
2829
#include <vector>
2930

3031
namespace clang {
@@ -41,15 +42,17 @@ struct ReferencedLocations {
4142
/// associated locations. These may be macro expansions, and are not resolved
4243
/// to their spelling or expansion location. These locations are later used to
4344
/// determine which headers should be marked as "used" and "directly used".
44-
/// - We also examine all identifier tokens in the file in case they reference
45-
/// macros.
46-
///
45+
/// - If \p Tokens is not nullptr, we also examine all identifier tokens in the
46+
/// file in case they reference macros macros.
4747
/// We use this to compute unused headers, so we:
4848
///
4949
/// - cover the whole file in a single traversal for efficiency
5050
/// - don't attempt to describe where symbols were referenced from in
5151
/// ambiguous cases (e.g. implicitly used symbols, multiple declarations)
5252
/// - err on the side of reporting all possible locations
53+
ReferencedLocations findReferencedLocations(const SourceManager &SM,
54+
ASTContext &Ctx, Preprocessor &PP,
55+
const syntax::TokenBuffer *Tokens);
5356
ReferencedLocations findReferencedLocations(ParsedAST &AST);
5457

5558
struct ReferencedFiles {
@@ -60,6 +63,12 @@ struct ReferencedFiles {
6063
/// Retrieves IDs of all files containing SourceLocations from \p Locs.
6164
/// The output only includes things SourceManager sees as files (not macro IDs).
6265
/// This can include <built-in>, <scratch space> etc that are not true files.
66+
/// \p HeaderResponsible returns the public header that should be included given
67+
/// symbols from a file with the given FileID (example: public headers should be
68+
/// preferred to non self-contained and private headers).
69+
ReferencedFiles
70+
findReferencedFiles(const ReferencedLocations &Locs, const SourceManager &SM,
71+
llvm::function_ref<FileID(FileID)> HeaderResponsible);
6372
ReferencedFiles findReferencedFiles(const ReferencedLocations &Locs,
6473
const IncludeStructure &Includes,
6574
const SourceManager &SM);
@@ -81,8 +90,8 @@ std::vector<const Inclusion *> computeUnusedIncludes(ParsedAST &AST);
8190
std::vector<Diag> issueUnusedIncludesDiagnostics(ParsedAST &AST,
8291
llvm::StringRef Code);
8392

84-
/// Affects whether standard library includes should be considered for removal.
85-
/// This is off by default for now due to implementation limitations:
93+
/// Affects whether standard library includes should be considered for
94+
/// removal. This is off by default for now due to implementation limitations:
8695
/// - macros are not tracked
8796
/// - symbol names without a unique associated header are not tracked
8897
/// - references to std-namespaced C types are not properly tracked:

0 commit comments

Comments
 (0)