Skip to content

Commit 38cccb9

Browse files
committed
[include-cleaner] pass through recorded macro refs in walkUsed
Differential Revision: https://reviews.llvm.org/D137644
1 parent 98fa954 commit 38cccb9

File tree

3 files changed

+50
-6
lines changed

3 files changed

+50
-6
lines changed

clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ using UsedSymbolCB = llvm::function_ref<void(SymbolReference SymRef,
3535
///
3636
/// The AST traversal is rooted at ASTRoots - typically top-level declarations
3737
/// of a single source file.
38-
/// FIXME: Handle macro uses.
38+
/// The references to macros must be recorded separately and provided.
3939
///
4040
/// This is the main entrypoint of the include-cleaner library, and can be used:
4141
/// - to diagnose missing includes: a referenced symbol is provided by
@@ -44,7 +44,8 @@ using UsedSymbolCB = llvm::function_ref<void(SymbolReference SymRef,
4444
/// the headers for any referenced symbol
4545
/// FIXME: Take in an include structure to improve location to header mappings
4646
/// (e.g. IWYU pragmas).
47-
void walkUsed(llvm::ArrayRef<Decl *> ASTRoots, UsedSymbolCB CB);
47+
void walkUsed(const SourceManager &, llvm::ArrayRef<Decl *> ASTRoots,
48+
llvm::ArrayRef<SymbolReference> MacroRefs, UsedSymbolCB CB);
4849

4950
} // namespace include_cleaner
5051
} // namespace clang

clang-tools-extra/include-cleaner/lib/Analysis.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ toHeader(llvm::ArrayRef<tooling::stdlib::Header> Headers) {
2626
});
2727
return Result;
2828
}
29-
3029
} // namespace
31-
void walkUsed(llvm::ArrayRef<Decl *> ASTRoots, UsedSymbolCB CB) {
30+
31+
void walkUsed(const SourceManager &SM, llvm::ArrayRef<Decl *> ASTRoots,
32+
llvm::ArrayRef<SymbolReference> MacroRefs, UsedSymbolCB CB) {
3233
tooling::stdlib::Recognizer Recognizer;
3334
for (auto *Root : ASTRoots) {
3435
auto &SM = Root->getASTContext().getSourceManager();
@@ -45,7 +46,14 @@ void walkUsed(llvm::ArrayRef<Decl *> ASTRoots, UsedSymbolCB CB) {
4546
return CB({Loc, Symbol(ND), RT}, {Header(FE)});
4647
});
4748
}
48-
// FIXME: Handle references of macros.
49+
for (const SymbolReference &MacroRef : MacroRefs) {
50+
assert(MacroRef.Target.kind() == Symbol::Macro);
51+
// FIXME: Handle IWYU pragmas, non self-contained files.
52+
// FIXME: Handle macro locations.
53+
if (auto *FE = SM.getFileEntryForID(
54+
SM.getFileID(MacroRef.Target.macro().Definition)))
55+
CB(MacroRef, {Header(FE)});
56+
}
4957
}
5058

5159
} // namespace clang::include_cleaner

clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ TEST(WalkUsed, Basic) {
5050

5151
auto &SM = AST.sourceManager();
5252
llvm::DenseMap<size_t, std::vector<Header>> OffsetToProviders;
53-
walkUsed(TopLevelDecls,
53+
walkUsed(SM, TopLevelDecls, /*MacroRefs=*/{},
5454
[&](SymbolReference SymRef, llvm::ArrayRef<Header> Providers) {
5555
auto [FID, Offset] = SM.getDecomposedLoc(SymRef.RefLocation);
5656
EXPECT_EQ(FID, SM.getMainFileID());
@@ -68,5 +68,40 @@ TEST(WalkUsed, Basic) {
6868
Pair(Code.point("vconstructor"), UnorderedElementsAre(VectorSTL))));
6969
}
7070

71+
TEST(WalkUsed, MacroRefs) {
72+
llvm::Annotations Hdr(R"cpp(
73+
#define ^ANSWER 42
74+
)cpp");
75+
llvm::Annotations Main(R"cpp(
76+
#include "hdr.h"
77+
int x = ^ANSWER;
78+
)cpp");
79+
80+
SourceManagerForFile SMF("main.cpp", Main.code());
81+
auto &SM = SMF.get();
82+
const FileEntry *HdrFile =
83+
SM.getFileManager().getVirtualFile("hdr.h", Hdr.code().size(), 0);
84+
SM.overrideFileContents(HdrFile,
85+
llvm::MemoryBuffer::getMemBuffer(Hdr.code().str()));
86+
FileID HdrID = SM.createFileID(HdrFile, SourceLocation(), SrcMgr::C_User);
87+
88+
IdentifierTable Idents;
89+
Symbol Answer =
90+
Macro{&Idents.get("ANSWER"), SM.getComposedLoc(HdrID, Hdr.point())};
91+
llvm::DenseMap<size_t, std::vector<Header>> OffsetToProviders;
92+
walkUsed(SM, /*ASTRoots=*/{}, /*MacroRefs=*/
93+
{SymbolReference{SM.getComposedLoc(SM.getMainFileID(), Main.point()),
94+
Answer, RefType::Explicit}},
95+
[&](SymbolReference SymRef, llvm::ArrayRef<Header> Providers) {
96+
auto [FID, Offset] = SM.getDecomposedLoc(SymRef.RefLocation);
97+
EXPECT_EQ(FID, SM.getMainFileID());
98+
OffsetToProviders.try_emplace(Offset, Providers.vec());
99+
});
100+
101+
EXPECT_THAT(
102+
OffsetToProviders,
103+
UnorderedElementsAre(Pair(Main.point(), UnorderedElementsAre(HdrFile))));
104+
}
105+
71106
} // namespace
72107
} // namespace clang::include_cleaner

0 commit comments

Comments
 (0)