File tree Expand file tree Collapse file tree 2 files changed +35
-1
lines changed Expand file tree Collapse file tree 2 files changed +35
-1
lines changed Original file line number Diff line number Diff line change 51
51
#include " llvm/Support/FormatVariadic.h"
52
52
#include " llvm/Support/Path.h"
53
53
#include " llvm/Support/Regex.h"
54
+ #include < cassert>
54
55
#include < iterator>
55
56
#include < optional>
56
57
#include < string>
58
+ #include < utility>
57
59
#include < vector>
58
60
59
61
namespace clang {
@@ -266,7 +268,6 @@ std::vector<Diag> generateUnusedIncludeDiagnostics(
266
268
}
267
269
} // namespace
268
270
269
-
270
271
std::vector<include_cleaner::SymbolReference>
271
272
collectMacroReferences (ParsedAST &AST) {
272
273
const auto &SM = AST.getSourceManager ();
@@ -398,6 +399,10 @@ IncludeCleanerFindings computeIncludeCleanerFindings(ParsedAST &AST) {
398
399
// FIXME: Use presumed locations to map such usages back to patched
399
400
// locations safely.
400
401
auto Loc = SM.getFileLoc (Ref.RefLocation );
402
+ // File locations can be outside of the main file if macro is expanded
403
+ // through an #include.
404
+ while (SM.getFileID (Loc) != SM.getMainFileID ())
405
+ Loc = SM.getIncludeLoc (SM.getFileID (Loc));
401
406
const auto *Token = AST.getTokens ().spelledTokenAt (Loc);
402
407
MissingIncludeDiagInfo DiagInfo{Ref.Target , Token->range (SM),
403
408
Providers};
Original file line number Diff line number Diff line change @@ -384,6 +384,35 @@ TEST(IncludeCleaner, UmbrellaUsesPrivate) {
384
384
EXPECT_THAT (Findings.UnusedIncludes , IsEmpty ());
385
385
}
386
386
387
+ TEST (IncludeCleaner, MacroExpandedThroughIncludes) {
388
+ Annotations MainFile (R"cpp(
389
+ #include "all.h"
390
+ #define FOO(X) const Foo *X
391
+ void foo() {
392
+ #include [["expander.inc"]]
393
+ }
394
+ )cpp" );
395
+
396
+ TestTU TU;
397
+ TU.AdditionalFiles [" expander.inc" ] = guard (" FOO(f1);FOO(f2);" );
398
+ TU.AdditionalFiles [" foo.h" ] = guard (" struct Foo {};" );
399
+ TU.AdditionalFiles [" all.h" ] = guard (" #include \" foo.h\" " );
400
+
401
+ TU.Code = MainFile.code ();
402
+ ParsedAST AST = TU.build ();
403
+
404
+ auto Findings = computeIncludeCleanerFindings (AST).MissingIncludes ;
405
+ // FIXME: Deduplicate references resulting from expansion of the same macro in
406
+ // multiple places.
407
+ EXPECT_THAT (Findings, testing::SizeIs (2 ));
408
+ auto RefRange = Findings.front ().SymRefRange ;
409
+ auto &SM = AST.getSourceManager ();
410
+ EXPECT_EQ (RefRange.file (), SM.getMainFileID ());
411
+ // FIXME: Point at the spelling location, rather than the include.
412
+ EXPECT_EQ (halfOpenToRange (SM, RefRange.toCharRange (SM)), MainFile.range ());
413
+ EXPECT_EQ (RefRange, Findings[1 ].SymRefRange );
414
+ }
415
+
387
416
} // namespace
388
417
} // namespace clangd
389
418
} // namespace clang
You can’t perform that action at this time.
0 commit comments