kbobyrev updated this revision to Diff 410490.
kbobyrev added a comment.

Move suffix map to CanonicalIncludes (where it logically belongs), remove
component limit there.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D120306/new/

https://reviews.llvm.org/D120306

Files:
  clang-tools-extra/clangd/Headers.cpp
  clang-tools-extra/clangd/Headers.h
  clang-tools-extra/clangd/IncludeCleaner.cpp
  clang-tools-extra/clangd/IncludeCleaner.h
  clang-tools-extra/clangd/ParsedAST.cpp
  clang-tools-extra/clangd/Preamble.cpp
  clang-tools-extra/clangd/index/CanonicalIncludes.cpp
  clang-tools-extra/clangd/index/CanonicalIncludes.h
  clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp

Index: clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
+++ clang-tools-extra/clangd/unittests/IncludeCleanerTests.cpp
@@ -266,8 +266,9 @@
 
     ReferencedLocations Locs = findReferencedLocations(AST);
     EXPECT_THAT(Locs.Stdlib, ElementsAreArray(WantSyms));
-    ReferencedFiles Files = findReferencedFiles(Locs, AST.getIncludeStructure(),
-                                                AST.getSourceManager());
+    ReferencedFiles Files =
+        findReferencedFiles(Locs, AST.getIncludeStructure(),
+                            AST.getCanonicalIncludes(), AST.getSourceManager());
     EXPECT_THAT(Files.Stdlib, ElementsAreArray(WantHeaders));
   }
 }
@@ -378,8 +379,8 @@
   auto &SM = AST.getSourceManager();
   auto &Includes = AST.getIncludeStructure();
 
-  auto ReferencedFiles =
-      findReferencedFiles(findReferencedLocations(AST), Includes, SM);
+  auto ReferencedFiles = findReferencedFiles(
+      findReferencedLocations(AST), Includes, AST.getCanonicalIncludes(), SM);
   llvm::StringSet<> ReferencedFileNames;
   for (FileID FID : ReferencedFiles.User)
     ReferencedFileNames.insert(
@@ -427,9 +428,9 @@
 
   ParsedAST AST = TU.build();
 
-  auto ReferencedFiles =
-      findReferencedFiles(findReferencedLocations(AST),
-                          AST.getIncludeStructure(), AST.getSourceManager());
+  auto ReferencedFiles = findReferencedFiles(
+      findReferencedLocations(AST), AST.getIncludeStructure(),
+      AST.getCanonicalIncludes(), AST.getSourceManager());
   llvm::StringSet<> ReferencedFileNames;
   auto &SM = AST.getSourceManager();
   for (FileID FID : ReferencedFiles.User)
@@ -461,9 +462,9 @@
 
   ParsedAST AST = TU.build();
 
-  auto ReferencedFiles =
-      findReferencedFiles(findReferencedLocations(AST),
-                          AST.getIncludeStructure(), AST.getSourceManager());
+  auto ReferencedFiles = findReferencedFiles(
+      findReferencedLocations(AST), AST.getIncludeStructure(),
+      AST.getCanonicalIncludes(), AST.getSourceManager());
   llvm::StringSet<> ReferencedFileNames;
   auto &SM = AST.getSourceManager();
   for (FileID FID : ReferencedFiles.User)
@@ -483,9 +484,9 @@
   TU.AdditionalFiles["behind_keep.h"] = guard("");
   ParsedAST AST = TU.build();
 
-  auto ReferencedFiles =
-      findReferencedFiles(findReferencedLocations(AST),
-                          AST.getIncludeStructure(), AST.getSourceManager());
+  auto ReferencedFiles = findReferencedFiles(
+      findReferencedLocations(AST), AST.getIncludeStructure(),
+      AST.getCanonicalIncludes(), AST.getSourceManager());
   EXPECT_TRUE(ReferencedFiles.User.empty());
   EXPECT_THAT(AST.getDiagnostics(), llvm::ValueIs(IsEmpty()));
 }
Index: clang-tools-extra/clangd/index/CanonicalIncludes.h
===================================================================
--- clang-tools-extra/clangd/index/CanonicalIncludes.h
+++ clang-tools-extra/clangd/index/CanonicalIncludes.h
@@ -19,6 +19,7 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_CANONICALINCLUDES_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_CANONICALINCLUDES_H
 
+#include "clang/Lex/PPCallbacks.h"
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
@@ -54,9 +55,14 @@
   /// headers.
   void addSystemHeadersMapping(const LangOptions &Language);
 
+  void addHeader(llvm::StringRef Header);
+
+  llvm::StringRef suffixToHeader(llvm::StringRef Suffix) const;
+
 private:
   /// A map from full include path to a canonical path.
   llvm::StringMap<std::string> FullPathMapping;
+  llvm::StringMap<std::string> SuffixToFullPathMapping;
   /// A map from a suffix (one or components of a path) to a canonical path.
   /// Used only for mapping standard headers.
   const llvm::StringMap<llvm::StringRef> *StdSuffixHeaderMapping = nullptr;
@@ -89,6 +95,8 @@
 std::unique_ptr<CommentHandler>
 collectIWYUHeaderMaps(CanonicalIncludes *Includes);
 
+std::unique_ptr<PPCallbacks> collectSuffixMappings(CanonicalIncludes *Includes);
+
 } // namespace clangd
 } // namespace clang
 
Index: clang-tools-extra/clangd/index/CanonicalIncludes.cpp
===================================================================
--- clang-tools-extra/clangd/index/CanonicalIncludes.cpp
+++ clang-tools-extra/clangd/index/CanonicalIncludes.cpp
@@ -9,6 +9,7 @@
 #include "CanonicalIncludes.h"
 #include "Headers.h"
 #include "clang/Driver/Types.h"
+#include "clang/Lex/PPCallbacks.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Path.h"
 #include <algorithm>
@@ -55,9 +56,26 @@
   return StdSymbolMapping ? StdSymbolMapping->lookup(QName) : "";
 }
 
+void CanonicalIncludes::addHeader(llvm::StringRef Header) {
+  for (auto It = llvm::sys::path::rbegin(Header),
+            End = llvm::sys::path::rend(Header);
+       It != End; ++It, ++Components) {
+    auto Suffix = Header.substr(It->data() - Header.begin());
+    SuffixToFullPathMapping[Suffix] = Header.str();
+  }
+}
+
+llvm::StringRef
+CanonicalIncludes::suffixToHeader(llvm::StringRef Suffix) const {
+  auto It = SuffixToFullPathMapping.find(Suffix);
+  if (It == SuffixToFullPathMapping.end())
+    return StringRef();
+  return It->second;
+}
+
 std::unique_ptr<CommentHandler>
 collectIWYUHeaderMaps(CanonicalIncludes *Includes) {
-  class PragmaCommentHandler : public clang::CommentHandler {
+  class PragmaCommentHandler : public CommentHandler {
   public:
     PragmaCommentHandler(CanonicalIncludes *Includes) : Includes(Includes) {}
 
@@ -81,6 +99,29 @@
   return std::make_unique<PragmaCommentHandler>(Includes);
 }
 
+std::unique_ptr<PPCallbacks>
+collectSuffixMappings(CanonicalIncludes *Includes) {
+  class SuffixMappingCollector : public PPCallbacks {
+  public:
+    SuffixMappingCollector(CanonicalIncludes *Includes) : Includes(Includes) {}
+
+    void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+                            llvm::StringRef FileName, bool IsAngled,
+                            CharSourceRange /*FilenameRange*/,
+                            const FileEntry *File,
+                            llvm::StringRef /*SearchPath*/,
+                            llvm::StringRef /*RelativePath*/,
+                            const clang::Module * /*Imported*/,
+                            SrcMgr::CharacteristicKind FileKind) override {
+      if (File)
+        Includes->addHeader(File->getName());
+    }
+
+  private:
+    CanonicalIncludes *const Includes;
+  };
+  return std::make_unique<SuffixMappingCollector>(Includes);
+}
 void CanonicalIncludes::addSystemHeadersMapping(const LangOptions &Language) {
   if (Language.CPlusPlus) {
     static const auto *Symbols = new llvm::StringMap<llvm::StringRef>({
Index: clang-tools-extra/clangd/Preamble.cpp
===================================================================
--- clang-tools-extra/clangd/Preamble.cpp
+++ clang-tools-extra/clangd/Preamble.cpp
@@ -11,6 +11,7 @@
 #include "Config.h"
 #include "Headers.h"
 #include "SourceCode.h"
+#include "index/CanonicalIncludes.h"
 #include "support/Logger.h"
 #include "support/ThreadsafeFS.h"
 #include "support/Trace.h"
@@ -107,7 +108,9 @@
 
     return std::make_unique<PPChainedCallbacks>(
         std::make_unique<CollectMainFileMacros>(*SourceMgr, Macros),
-        collectPragmaMarksCallback(*SourceMgr, Marks));
+        std::make_unique<PPChainedCallbacks>(
+            collectPragmaMarksCallback(*SourceMgr, Marks),
+            collectSuffixMappings(&CanonIncludes)));
   }
 
   CommentHandler *getCommentHandler() override {
Index: clang-tools-extra/clangd/ParsedAST.cpp
===================================================================
--- clang-tools-extra/clangd/ParsedAST.cpp
+++ clang-tools-extra/clangd/ParsedAST.cpp
@@ -544,9 +544,10 @@
     CanonIncludes = Preamble->CanonIncludes;
   else
     CanonIncludes.addSystemHeadersMapping(Clang->getLangOpts());
-  std::unique_ptr<CommentHandler> IWYUHandler =
-      collectIWYUHeaderMaps(&CanonIncludes);
+  auto IWYUHandler = collectIWYUHeaderMaps(&CanonIncludes);
   Clang->getPreprocessor().addCommentHandler(IWYUHandler.get());
+  auto SuffixMappingCollector = collectSuffixMappings(&CanonIncludes);
+  Clang->getPreprocessor().addPPCallbacks(move(SuffixMappingCollector));
 
   // Collect tokens of the main file.
   syntax::TokenCollector CollectTokens(Clang->getPreprocessor());
Index: clang-tools-extra/clangd/IncludeCleaner.h
===================================================================
--- clang-tools-extra/clangd/IncludeCleaner.h
+++ clang-tools-extra/clangd/IncludeCleaner.h
@@ -13,9 +13,6 @@
 /// to provide useful warnings in most popular scenarios but not 1:1 exact
 /// feature compatibility.
 ///
-/// FIXME(kirillbobyrev): Add support for IWYU pragmas.
-/// FIXME(kirillbobyrev): Add support for standard library headers.
-///
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INCLUDECLEANER_H
@@ -23,6 +20,7 @@
 
 #include "Headers.h"
 #include "ParsedAST.h"
+#include "index/CanonicalIncludes.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Tooling/Inclusions/StandardLibrary.h"
 #include "llvm/ADT/DenseSet.h"
@@ -72,6 +70,7 @@
                     llvm::function_ref<FileID(FileID)> HeaderResponsible);
 ReferencedFiles findReferencedFiles(const ReferencedLocations &Locs,
                                     const IncludeStructure &Includes,
+                                    const CanonicalIncludes &CanonIncludes,
                                     const SourceManager &SM);
 
 /// Maps FileIDs to the internal IncludeStructure representation (HeaderIDs).
Index: clang-tools-extra/clangd/IncludeCleaner.cpp
===================================================================
--- clang-tools-extra/clangd/IncludeCleaner.cpp
+++ clang-tools-extra/clangd/IncludeCleaner.cpp
@@ -12,6 +12,7 @@
 #include "ParsedAST.h"
 #include "Protocol.h"
 #include "SourceCode.h"
+#include "index/CanonicalIncludes.h"
 #include "support/Logger.h"
 #include "support/Trace.h"
 #include "clang/AST/ASTContext.h"
@@ -266,7 +267,8 @@
 // include, so it will be responsible for bringing the symbols from given
 // header into the scope.
 FileID headerResponsible(FileID ID, const SourceManager &SM,
-                         const IncludeStructure &Includes) {
+                         const IncludeStructure &Includes,
+                         const CanonicalIncludes &CanonIncludes) {
   // Unroll the chain of non self-contained headers until we find the one that
   // can be included.
   for (const FileEntry *FE = SM.getFileEntryForID(ID); ID != SM.getMainFileID();
@@ -277,11 +279,25 @@
     auto HID = Includes.getID(FE);
     assert(HID && "We're iterating over headers already existing in "
                   "IncludeStructure");
-    if (Includes.isSelfContained(*HID))
-      break;
-    // The header is not self-contained: put the responsibility for its symbols
-    // on its includer.
-    ID = SM.getFileID(SM.getIncludeLoc(ID));
+    if (!Includes.isSelfContained(*HID)) {
+      // The header is not self-contained: put the responsibility for its
+      // symbols on its includer.
+      ID = SM.getFileID(SM.getIncludeLoc(ID));
+      continue;
+    }
+    if (auto Filename = SM.getNonBuiltinFilenameForID(ID)) {
+      auto CanonicalHeaderSuffix = CanonIncludes.mapHeader(*Filename);
+      if (CanonicalHeaderSuffix.empty())
+        break;
+      CanonicalHeaderSuffix = CanonicalHeaderSuffix.drop_front().drop_back();
+      auto FullHeader = CanonIncludes.suffixToHeader(CanonicalHeaderSuffix);
+      if (FullHeader.empty())
+        break;
+      auto Entry = SM.getFileManager().getFile(FullHeader);
+      assert(Entry);
+      ID = SM.translateFile(*Entry);
+    }
+    break;
   }
   return ID;
 }
@@ -339,10 +355,12 @@
 
 ReferencedFiles findReferencedFiles(const ReferencedLocations &Locs,
                                     const IncludeStructure &Includes,
+                                    const CanonicalIncludes &CanonIncludes,
                                     const SourceManager &SM) {
-  return findReferencedFiles(Locs, SM, [&SM, &Includes](FileID ID) {
-    return headerResponsible(ID, SM, Includes);
-  });
+  return findReferencedFiles(
+      Locs, SM, [&SM, &Includes, &CanonIncludes](FileID ID) {
+        return headerResponsible(ID, SM, Includes, CanonIncludes);
+      });
 }
 
 std::vector<const Inclusion *>
@@ -402,8 +420,9 @@
   const auto &SM = AST.getSourceManager();
 
   auto Refs = findReferencedLocations(AST);
-  auto ReferencedFileIDs = findReferencedFiles(Refs, AST.getIncludeStructure(),
-                                               AST.getSourceManager());
+  auto ReferencedFileIDs =
+      findReferencedFiles(Refs, AST.getIncludeStructure(),
+                          AST.getCanonicalIncludes(), AST.getSourceManager());
   auto ReferencedHeaders =
       translateToHeaderIDs(ReferencedFileIDs, AST.getIncludeStructure(), SM);
   return getUnused(AST, ReferencedHeaders);
Index: clang-tools-extra/clangd/Headers.h
===================================================================
--- clang-tools-extra/clangd/Headers.h
+++ clang-tools-extra/clangd/Headers.h
@@ -25,6 +25,8 @@
 #include "clang/Tooling/Inclusions/StandardLibrary.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/Support/Error.h"
Index: clang-tools-extra/clangd/Headers.cpp
===================================================================
--- clang-tools-extra/clangd/Headers.cpp
+++ clang-tools-extra/clangd/Headers.cpp
@@ -19,6 +19,7 @@
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/PPCallbacks.h"
 #include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Path.h"
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to