sammccall created this revision.
sammccall added a reviewer: kadircet.
Herald added a project: All.
sammccall requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D137644

Files:
  clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
  clang-tools-extra/include-cleaner/lib/Analysis.cpp
  clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp

Index: clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
===================================================================
--- clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
@@ -50,12 +50,13 @@
 
   auto &SM = AST.sourceManager();
   llvm::DenseMap<size_t, std::vector<Header>> OffsetToProviders;
-  walkUsed(TopLevelDecls, [&](SourceLocation RefLoc, Symbol S,
-                              llvm::ArrayRef<Header> Providers) {
-    auto [FID, Offset] = SM.getDecomposedLoc(RefLoc);
-    EXPECT_EQ(FID, SM.getMainFileID());
-    OffsetToProviders.try_emplace(Offset, Providers.vec());
-  });
+  walkUsed(
+      SM, TopLevelDecls, /*MacroRefs=*/{},
+      [&](SourceLocation RefLoc, Symbol S, llvm::ArrayRef<Header> Providers) {
+        auto [FID, Offset] = SM.getDecomposedLoc(RefLoc);
+        EXPECT_EQ(FID, SM.getMainFileID());
+        OffsetToProviders.try_emplace(Offset, Providers.vec());
+      });
   auto HeaderFile = Header(AST.fileManager().getFile("header.h").get());
   auto MainFile = Header(SM.getFileEntryForID(SM.getMainFileID()));
   auto VectorSTL = Header(tooling::stdlib::Header::named("<vector>").value());
@@ -68,5 +69,41 @@
           Pair(Code.point("vconstructor"), UnorderedElementsAre(VectorSTL))));
 }
 
+TEST(WalkUsed, MacroRefs) {
+  llvm::Annotations Hdr(R"cpp(
+    #define ^ANSWER 42
+  )cpp");
+  llvm::Annotations Main(R"cpp(
+    #include "hdr.h"
+    int x = ^ANSWER;
+  )cpp");
+
+  SourceManagerForFile SMF("main.cpp", Main.code());
+  auto &SM = SMF.get();
+  const FileEntry *HdrFile =
+      SM.getFileManager().getVirtualFile("hdr.h", Hdr.code().size(), 0);
+  SM.overrideFileContents(HdrFile,
+                          llvm::MemoryBuffer::getMemBuffer(Hdr.code().str()));
+  FileID HdrID = SM.createFileID(HdrFile, SourceLocation(), SrcMgr::C_User);
+
+  IdentifierTable Idents;
+  Symbol Answer =
+      Macro{&Idents.get("ANSWER"), SM.getComposedLoc(HdrID, Hdr.point())};
+  llvm::DenseMap<size_t, std::vector<Header>> OffsetToProviders;
+  walkUsed(
+      SM, /*ASTRoots=*/{}, /*MacroRefs=*/
+      {SymbolReference{Answer,
+                       SM.getComposedLoc(SM.getMainFileID(), Main.point())}},
+      [&](SourceLocation RefLoc, Symbol S, llvm::ArrayRef<Header> Providers) {
+        auto [FID, Offset] = SM.getDecomposedLoc(RefLoc);
+        EXPECT_EQ(FID, SM.getMainFileID());
+        OffsetToProviders.try_emplace(Offset, Providers.vec());
+      });
+
+  EXPECT_THAT(
+      OffsetToProviders,
+      UnorderedElementsAre(Pair(Main.point(), UnorderedElementsAre(HdrFile))));
+}
+
 } // namespace
 } // namespace clang::include_cleaner
Index: clang-tools-extra/include-cleaner/lib/Analysis.cpp
===================================================================
--- clang-tools-extra/include-cleaner/lib/Analysis.cpp
+++ clang-tools-extra/include-cleaner/lib/Analysis.cpp
@@ -7,8 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang-include-cleaner/Analysis.h"
-#include "clang-include-cleaner/Types.h"
 #include "AnalysisInternal.h"
+#include "clang-include-cleaner/Types.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Tooling/Inclusions/StandardLibrary.h"
@@ -26,9 +26,10 @@
   });
   return Result;
 }
-
 } // namespace
-void walkUsed(llvm::ArrayRef<Decl *> ASTRoots, UsedSymbolCB CB) {
+
+void walkUsed(const SourceManager &SM, llvm::ArrayRef<Decl *> ASTRoots,
+              llvm::ArrayRef<SymbolReference> MacroRefs, UsedSymbolCB CB) {
   tooling::stdlib::Recognizer Recognizer;
   for (auto *Root : ASTRoots) {
     auto &SM = Root->getASTContext().getSourceManager();
@@ -45,7 +46,14 @@
         return CB(Loc, Symbol(ND), {Header(FE)});
     });
   }
-  // FIXME: Handle references of macros.
+  for (const SymbolReference &MacroRef : MacroRefs) {
+    assert(MacroRef.Symbol.kind() == Symbol::Macro);
+    // FIXME: Handle IWYU pragmas, non self-contained files.
+    // FIXME: Handle macro locations.
+    if (auto *FE = SM.getFileEntryForID(
+            SM.getFileID(MacroRef.Symbol.macro().Definition)))
+      CB(MacroRef.RefLocation, MacroRef.Symbol, {Header(FE)});
+  }
 }
 
 } // namespace clang::include_cleaner
Index: clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
===================================================================
--- clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
+++ clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
@@ -35,7 +35,7 @@
 ///
 /// The AST traversal is rooted at ASTRoots - typically top-level declarations
 /// of a single source file.
-/// FIXME: Handle macro uses.
+/// The references to macros must be recorded separately and provided.
 ///
 /// This is the main entrypoint of the include-cleaner library, and can be used:
 ///  - to diagnose missing includes: a referenced symbol is provided by
@@ -44,7 +44,8 @@
 ///    the headers for any referenced symbol
 /// FIXME: Take in an include structure to improve location to header mappings
 /// (e.g. IWYU pragmas).
-void walkUsed(llvm::ArrayRef<Decl *> ASTRoots, UsedSymbolCB CB);
+void walkUsed(const SourceManager &, llvm::ArrayRef<Decl *> ASTRoots,
+              llvm::ArrayRef<SymbolReference> MacroRefs, UsedSymbolCB CB);
 
 } // namespace include_cleaner
 } // namespace clang
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to