VitaNuo created this revision.
Herald added subscribers: kadircet, arphaman.
Herald added a project: All.
VitaNuo updated this revision to Diff 531275.
VitaNuo added a comment.
VitaNuo updated this revision to Diff 531278.
VitaNuo added a reviewer: kadircet.
VitaNuo published this revision for review.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

Remove redundant variables.


VitaNuo added a comment.

Remove redundancy.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D152900

Files:
  clang-tools-extra/clangd/index/IndexAction.cpp
  clang-tools-extra/clangd/index/SymbolCollector.cpp
  clang-tools-extra/clangd/index/SymbolCollector.h
  clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp

Index: clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
+++ clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
@@ -9,6 +9,7 @@
 #include "Annotations.h"
 #include "TestFS.h"
 #include "TestTU.h"
+#include "URI.h"
 #include "index/SymbolCollector.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileSystemOptions.h"
@@ -226,23 +227,18 @@
 
 class SymbolIndexActionFactory : public tooling::FrontendActionFactory {
 public:
-  SymbolIndexActionFactory(SymbolCollector::Options COpts,
-                           CommentHandler *PragmaHandler)
-      : COpts(std::move(COpts)), PragmaHandler(PragmaHandler) {}
+  SymbolIndexActionFactory(SymbolCollector::Options COpts)
+      : COpts(std::move(COpts)) {}
 
   std::unique_ptr<FrontendAction> create() override {
     class IndexAction : public ASTFrontendAction {
     public:
       IndexAction(std::shared_ptr<index::IndexDataConsumer> DataConsumer,
-                  const index::IndexingOptions &Opts,
-                  CommentHandler *PragmaHandler)
-          : DataConsumer(std::move(DataConsumer)), Opts(Opts),
-            PragmaHandler(PragmaHandler) {}
+                  const index::IndexingOptions &Opts)
+          : DataConsumer(std::move(DataConsumer)), Opts(Opts) {}
 
       std::unique_ptr<ASTConsumer>
       CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) override {
-        if (PragmaHandler)
-          CI.getPreprocessor().addCommentHandler(PragmaHandler);
         return createIndexingASTConsumer(DataConsumer, Opts,
                                          CI.getPreprocessorPtr());
       }
@@ -256,20 +252,17 @@
     private:
       std::shared_ptr<index::IndexDataConsumer> DataConsumer;
       index::IndexingOptions Opts;
-      CommentHandler *PragmaHandler;
     };
     index::IndexingOptions IndexOpts;
     IndexOpts.SystemSymbolFilter =
         index::IndexingOptions::SystemSymbolFilterKind::All;
     IndexOpts.IndexFunctionLocals = true;
     Collector = std::make_shared<SymbolCollector>(COpts);
-    return std::make_unique<IndexAction>(Collector, std::move(IndexOpts),
-                                         PragmaHandler);
+    return std::make_unique<IndexAction>(Collector, std::move(IndexOpts));
   }
 
   std::shared_ptr<SymbolCollector> Collector;
   SymbolCollector::Options COpts;
-  CommentHandler *PragmaHandler;
 };
 
 class SymbolCollectorTest : public ::testing::Test {
@@ -289,8 +282,7 @@
     llvm::IntrusiveRefCntPtr<FileManager> Files(
         new FileManager(FileSystemOptions(), InMemoryFileSystem));
 
-    auto Factory = std::make_unique<SymbolIndexActionFactory>(
-        CollectorOpts, PragmaHandler.get());
+    auto Factory = std::make_unique<SymbolIndexActionFactory>(CollectorOpts);
 
     std::vector<std::string> Args = {"symbol_collector", "-fsyntax-only",
                                      "-xc++", "-include", TestHeaderName};
@@ -324,7 +316,6 @@
   RefSlab Refs;
   RelationSlab Relations;
   SymbolCollector::Options CollectorOpts;
-  std::unique_ptr<CommentHandler> PragmaHandler;
 };
 
 TEST_F(SymbolCollectorTest, CollectSymbols) {
@@ -1573,9 +1564,6 @@
 
 TEST_F(SymbolCollectorTest, IWYUPragma) {
   CollectorOpts.CollectIncludePath = true;
-  CanonicalIncludes Includes;
-  PragmaHandler = collectIWYUHeaderMaps(&Includes);
-  CollectorOpts.Includes = &Includes;
   const std::string Header = R"(
     // IWYU pragma: private, include the/good/header.h
     class Foo {};
@@ -1588,9 +1576,6 @@
 
 TEST_F(SymbolCollectorTest, IWYUPragmaWithDoubleQuotes) {
   CollectorOpts.CollectIncludePath = true;
-  CanonicalIncludes Includes;
-  PragmaHandler = collectIWYUHeaderMaps(&Includes);
-  CollectorOpts.Includes = &Includes;
   const std::string Header = R"(
     // IWYU pragma: private, include "the/good/header.h"
     class Foo {};
@@ -1601,6 +1586,27 @@
                                  includeHeader("\"the/good/header.h\""))));
 }
 
+TEST_F(SymbolCollectorTest, IWYUPragmaExport) {
+  CollectorOpts.CollectIncludePath = true;
+  const std::string Header = R"cpp(#pragma once
+    #include "exporter.h"
+  )cpp";
+  auto ExporterFile = testPath("exporter.h");
+  InMemoryFileSystem->addFile(
+      ExporterFile, 0, llvm::MemoryBuffer::getMemBuffer(R"cpp(#pragma once
+    #include "private.h" // IWYU pragma: export
+  )cpp"));
+  auto PrivateFile = testPath("private.h");
+  InMemoryFileSystem->addFile(
+      PrivateFile, 0, llvm::MemoryBuffer::getMemBuffer("class Foo {};"));
+  runSymbolCollector(Header, /*Main=*/"",
+                     /*ExtraArgs=*/{"-I", testRoot()});
+  EXPECT_THAT(Symbols, UnorderedElementsAre(AllOf(
+                           qName("Foo"),
+                           includeHeader(URI::create(ExporterFile).toString()),
+                           declURI(URI::create(PrivateFile).toString()))));
+}
+
 TEST_F(SymbolCollectorTest, SkipIncFileWhenCanonicalizeHeaders) {
   auto IncFile = testPath("test.inc");
   auto IncURI = URI::create(IncFile).toString();
Index: clang-tools-extra/clangd/index/SymbolCollector.h
===================================================================
--- clang-tools-extra/clangd/index/SymbolCollector.h
+++ clang-tools-extra/clangd/index/SymbolCollector.h
@@ -9,6 +9,8 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOLCOLLECTOR_H
 
 #include "CollectMacros.h"
+#include "clang-include-cleaner/Record.h"
+#include "clang-include-cleaner/Types.h"
 #include "index/CanonicalIncludes.h"
 #include "index/Ref.h"
 #include "index/Relation.h"
@@ -24,6 +26,7 @@
 #include "clang/Sema/CodeCompleteConsumer.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
 #include <functional>
 #include <optional>
 
@@ -123,8 +126,12 @@
 
   void setPreprocessor(std::shared_ptr<Preprocessor> PP) override {
     this->PP = PP.get();
+    PI.record(*this->PP);
+  }
+  void setPreprocessor(Preprocessor &PP) {
+    this->PP = &PP;
+    PI.record(*this->PP);
   }
-  void setPreprocessor(Preprocessor &PP) { this->PP = &PP; }
 
   bool
   handleDeclOccurrence(const Decl *D, index::SymbolRoleSet Roles,
@@ -166,13 +173,24 @@
 
   // All Symbols collected from the AST.
   SymbolSlab::Builder Symbols;
-  // File IDs for Symbol.IncludeHeaders.
-  // The final spelling is calculated in finish().
+  // File IDs to distinguish imports from includes.
   llvm::DenseMap<SymbolID, FileID> IncludeFiles;
+  void setIncludeLocation(const Symbol &S, SourceLocation);
+
+  // Providers for Symbol.IncludeHeaders.
+  // The final spelling is calculated in finish().
+  llvm::DenseMap<SymbolID, llvm::SmallVector<include_cleaner::Header>>
+      SymbolProviders;
+  // Mapping from symbol ID to final include spelling.
+  // Needs to be persisted here because Symbols don't store any of their data.
+  llvm::DenseMap<SymbolID, std::string> SymbolIncludeSpelling;
   // Files which contain ObjC symbols.
   // This is finalized and used in finish().
   llvm::DenseSet<FileID> FilesWithObjCConstructs;
-  void setIncludeLocation(const Symbol &S, SourceLocation);
+
+  void
+  setSymbolProviders(const Symbol &S,
+                     const llvm::SmallVector<include_cleaner::Header> &Headers);
   // Indexed macros, to be erased if they turned out to be include guards.
   llvm::DenseSet<const IdentifierInfo *> IndexedMacros;
   // All refs collected from the AST. It includes:
@@ -184,6 +202,7 @@
   RelationSlab::Builder Relations;
   ASTContext *ASTCtx;
   Preprocessor *PP = nullptr;
+  include_cleaner::PragmaIncludes PI;
   std::shared_ptr<GlobalCodeCompletionAllocator> CompletionAllocator;
   std::unique_ptr<CodeCompletionTUInfo> CompletionTUInfo;
   Options Opts;
Index: clang-tools-extra/clangd/index/SymbolCollector.cpp
===================================================================
--- clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -13,8 +13,12 @@
 #include "ExpectedTypes.h"
 #include "SourceCode.h"
 #include "URI.h"
+#include "clang-include-cleaner/Analysis.h"
+#include "clang-include-cleaner/Record.h"
+#include "clang-include-cleaner/Types.h"
 #include "index/CanonicalIncludes.h"
 #include "index/Relation.h"
+#include "index/Symbol.h"
 #include "index/SymbolID.h"
 #include "index/SymbolLocation.h"
 #include "clang/AST/Decl.h"
@@ -30,10 +34,15 @@
 #include "clang/Lex/Token.h"
 #include "clang/Tooling/Inclusions/HeaderAnalysis.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 #include <optional>
+#include <string>
 
 namespace clang {
 namespace clangd {
@@ -196,12 +205,14 @@
   llvm::StringMap<std::string> CachePathToFrameworkSpelling;
   llvm::StringMap<FrameworkUmbrellaSpelling>
       CacheFrameworkToUmbrellaHeaderSpelling;
+  const include_cleaner::PragmaIncludes &PI;
 
 public:
   HeaderFileURICache(Preprocessor *&PP, const SourceManager &SM,
-                     const SymbolCollector::Options &Opts)
-      : PP(PP), SM(SM), Includes(Opts.Includes), FallbackDir(Opts.FallbackDir) {
-  }
+                     const SymbolCollector::Options &Opts,
+                     const include_cleaner::PragmaIncludes &PI)
+      : PP(PP), SM(SM), Includes(Opts.Includes), FallbackDir(Opts.FallbackDir),
+        PI(PI) {}
 
   // Returns a canonical URI for the file \p FE.
   // We attempt to make the path absolute first.
@@ -377,6 +388,15 @@
     if (!FE || FE->getName().empty())
       return "";
     llvm::StringRef Filename = FE->getName();
+
+    // Fallback pragma handling for Objective-C.
+    const auto *FileEntry = SM.getFileEntryForID(FID);
+    for (const auto *Export : PI.getExporters(FileEntry, SM.getFileManager()))
+      return toURI(Export->tryGetRealPathName());
+
+    if (auto Verbatim = PI.getPublic(FileEntry); !Verbatim.empty())
+      return Verbatim;
+
     // If a file is mapped by canonical headers, use that mapping, regardless
     // of whether it's an otherwise-good header (header guards etc).
     if (Includes) {
@@ -436,7 +456,7 @@
 void SymbolCollector::initialize(ASTContext &Ctx) {
   ASTCtx = &Ctx;
   HeaderFileURIs = std::make_unique<HeaderFileURICache>(
-      this->PP, ASTCtx->getSourceManager(), Opts);
+      this->PP, ASTCtx->getSourceManager(), Opts, PI);
   CompletionAllocator = std::make_shared<GlobalCodeCompletionAllocator>();
   CompletionTUInfo =
       std::make_unique<CodeCompletionTUInfo>(CompletionAllocator);
@@ -765,6 +785,11 @@
 
   IndexedMacros.insert(Name);
   setIncludeLocation(S, DefLoc);
+  llvm::SmallVector<include_cleaner::Header> Headers =
+      include_cleaner::headersForSymbol(
+          include_cleaner::Macro{const_cast<IdentifierInfo *>(Name), DefLoc},
+          ASTCtx->getSourceManager(), &PI);
+  setSymbolProviders(S, Headers);
   Symbols.insert(S);
   return true;
 }
@@ -807,6 +832,14 @@
         PP->getSourceManager().getDecomposedExpansionLoc(Loc).first;
 }
 
+void SymbolCollector::setSymbolProviders(
+    const Symbol &S,
+    const llvm::SmallVector<include_cleaner::Header> &Headers) {
+  if (Opts.CollectIncludePath &&
+      shouldCollectIncludePath(S.SymInfo.Kind) != Symbol::Invalid)
+    SymbolProviders[S.ID] = Headers;
+}
+
 void SymbolCollector::finish() {
   // At the end of the TU, add 1 to the refcount of all referenced symbols.
   for (const auto &ID : ReferencedSymbols) {
@@ -847,37 +880,77 @@
             IncludeHeader = "<algorithm>";
         }
       }
-      // Otherwise find the approprate include header for the defining file.
-      if (IncludeHeader.empty())
-        IncludeHeader = HeaderFileURIs->getIncludeHeader(FID);
-
-      // Symbols in slabs aren't mutable, insert() has to walk all the strings
-      if (!IncludeHeader.empty()) {
-        Symbol::IncludeDirective Directives = Symbol::Invalid;
-        auto CollectDirectives = shouldCollectIncludePath(S->SymInfo.Kind);
-        if ((CollectDirectives & Symbol::Include) != 0)
-          Directives |= Symbol::Include;
-        // Only allow #import for symbols from ObjC-like files.
-        if ((CollectDirectives & Symbol::Import) != 0) {
-          auto [It, Inserted] = FileToContainsImportsOrObjC.try_emplace(FID);
-          if (Inserted)
-            It->second = FilesWithObjCConstructs.contains(FID) ||
-                         tooling::codeContainsImports(
-                             ASTCtx->getSourceManager().getBufferData(FID));
-          if (It->second)
-            Directives |= Symbol::Import;
-        }
-        if (Directives != Symbol::Invalid) {
-          Symbol NewSym = *S;
+
+      // Determine if the FID is #include'd or #import'ed.
+      Symbol::IncludeDirective Directives = Symbol::Invalid;
+      auto CollectDirectives = shouldCollectIncludePath(S->SymInfo.Kind);
+      if ((CollectDirectives & Symbol::Include) != 0)
+        Directives |= Symbol::Include;
+      // Only allow #import for symbols from ObjC-like files.
+      if ((CollectDirectives & Symbol::Import) != 0) {
+        auto [It, Inserted] = FileToContainsImportsOrObjC.try_emplace(FID);
+        if (Inserted)
+          It->second = FilesWithObjCConstructs.contains(FID) ||
+                       tooling::codeContainsImports(
+                           ASTCtx->getSourceManager().getBufferData(FID));
+        if (It->second)
+          Directives |= Symbol::Import;
+      }
+
+      Symbol NewSym;
+      if (Directives != Symbol::Invalid) {
+        NewSym = *S;
+        if (!IncludeHeader.empty()) {
           NewSym.IncludeHeaders.push_back({IncludeHeader, 1, Directives});
           Symbols.insert(NewSym);
+          continue;
+        }
+      }
+
+      // Use the include location-based logic for Objective-C symbols.
+      if (Directives & Symbol::Import) {
+        // If not overridden manually, find the approprate include header for
+        // the defining file.
+        NewSym.IncludeHeaders.push_back(
+            {HeaderFileURIs->getIncludeHeader(FID), 1, Directives});
+        Symbols.insert(NewSym);
+        continue;
+      }
+
+      // For #include's, use the providers computed by the include-cleaner
+      // library.
+      if (Directives == Symbol::Include) {
+        auto It = SymbolProviders.find(SID);
+        if (It != SymbolProviders.end()) {
+          for (const auto &H : It->second) {
+            switch (H.kind()) {
+            case include_cleaner::Header::Kind::Verbatim:
+              SymbolIncludeSpelling[SID] = H.verbatim().str();
+              break;
+            case include_cleaner::Header::Kind::Standard:
+              SymbolIncludeSpelling[SID] = H.standard().name().str();
+              break;
+            case include_cleaner::Header::Kind::Physical:
+              SymbolIncludeSpelling[SID] = HeaderFileURIs->getIncludeHeader(
+                  ASTCtx->getSourceManager().getOrCreateFileID(
+                      H.physical(), SrcMgr::CharacteristicKind::C_User));
+              break;
+            }
+            if (!SymbolIncludeSpelling[SID].empty()) {
+              NewSym.IncludeHeaders.push_back(
+                  {SymbolIncludeSpelling[SID], 1, Directives});
+              break;
+            }
+          }
         }
+        Symbols.insert(NewSym);
       }
     }
   }
 
   ReferencedSymbols.clear();
   IncludeFiles.clear();
+  SymbolProviders.clear();
   FilesWithObjCConstructs.clear();
 }
 
@@ -952,6 +1025,10 @@
 
   Symbols.insert(S);
   setIncludeLocation(S, ND.getLocation());
+  llvm::SmallVector<include_cleaner::Header> Headers =
+      include_cleaner::headersForSymbol(include_cleaner::Symbol{ND},
+                                        ASTCtx->getSourceManager(), &PI);
+  setSymbolProviders(S, Headers);
   if (S.SymInfo.Lang == index::SymbolLanguage::ObjC)
     FilesWithObjCConstructs.insert(FID);
   return Symbols.find(S.ID);
Index: clang-tools-extra/clangd/index/IndexAction.cpp
===================================================================
--- clang-tools-extra/clangd/index/IndexAction.cpp
+++ clang-tools-extra/clangd/index/IndexAction.cpp
@@ -135,8 +135,7 @@
       : SymbolsCallback(SymbolsCallback), RefsCallback(RefsCallback),
         RelationsCallback(RelationsCallback),
         IncludeGraphCallback(IncludeGraphCallback), Collector(C),
-        Includes(std::move(Includes)), Opts(Opts),
-        PragmaHandler(collectIWYUHeaderMaps(this->Includes.get())) {
+        Includes(std::move(Includes)), Opts(Opts) {
     this->Opts.ShouldTraverseDecl = [this](const Decl *D) {
       // Many operations performed during indexing is linear in terms of depth
       // of the decl (USR generation, name lookups, figuring out role of a
@@ -154,7 +153,6 @@
 
   std::unique_ptr<ASTConsumer>
   CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) override {
-    CI.getPreprocessor().addCommentHandler(PragmaHandler.get());
     Includes->addSystemHeadersMapping(CI.getLangOpts());
     if (IncludeGraphCallback != nullptr)
       CI.getPreprocessor().addPPCallbacks(
@@ -203,7 +201,6 @@
   std::shared_ptr<SymbolCollector> Collector;
   std::unique_ptr<CanonicalIncludes> Includes;
   index::IndexingOptions Opts;
-  std::unique_ptr<CommentHandler> PragmaHandler;
   IncludeGraph IG;
 };
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to