[PATCH] D78740: [clangd] Handle PresumedLocations in IncludeCollector

Kadir Cetinkaya via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 23 11:53:39 PDT 2020


kadircet created this revision.
kadircet added a reviewer: sammccall.
Herald added subscribers: cfe-commits, usaxena95, arphaman, jkorous, MaskRay, ilya-biryukov.
Herald added a project: clang.

This will enable extraction of correct line locations in preamble patch
for includes.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D78740

Files:
  clang-tools-extra/clangd/Headers.cpp
  clang-tools-extra/clangd/unittests/HeadersTests.cpp


Index: clang-tools-extra/clangd/unittests/HeadersTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/HeadersTests.cpp
+++ clang-tools-extra/clangd/unittests/HeadersTests.cpp
@@ -16,6 +16,7 @@
 #include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Frontend/FrontendActions.h"
 #include "clang/Lex/PreprocessorOptions.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/Path.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
@@ -302,6 +303,29 @@
             llvm::None);
 }
 
+TEST_F(HeadersTest, PresumedLocations) {
+  FS.Files[MainFile] = R"cpp(
+#include "a.h"
+// #include "b.h"
+// nothing on this line
+// #include "c.h"
+)cpp";
+  std::string HeaderFile = testPath("a.h");
+  std::string HeaderContents = llvm::formatv("#line 0 \"{0}\"", MainFile);
+  HeaderContents += R"cpp(
+#line 3
+#include <b.h>
+#line 5
+#include <c.h>
+#include <d.h>)cpp";
+  FS.Files[HeaderFile] = HeaderContents;
+
+  EXPECT_THAT(collectIncludes().MainFileIncludes,
+              UnorderedElementsAre(AllOf(IncludeLine(1), Written("\"a.h\"")),
+                                   AllOf(IncludeLine(2), Written("<b.h>")),
+                                   AllOf(IncludeLine(4), Written("<c.h>")),
+                                   AllOf(IncludeLine(5), Written("<d.h>"))));
+}
 } // namespace
 } // namespace clangd
 } // namespace clang
Index: clang-tools-extra/clangd/Headers.cpp
===================================================================
--- clang-tools-extra/clangd/Headers.cpp
+++ clang-tools-extra/clangd/Headers.cpp
@@ -35,6 +35,27 @@
                           llvm::StringRef /*RelativePath*/,
                           const Module * /*Imported*/,
                           SrcMgr::CharacteristicKind FileKind) override {
+    if (!isInsideMainFile(HashLoc, SM)) {
+      auto PreLoc = SM.getPresumedLoc(HashLoc);
+      if (auto FE = SM.getFileManager().getFile(PreLoc.getFilename())) {
+        if (SM.getFileEntryForID(SM.getMainFileID()) == *FE) {
+          HashLoc = SM.translateLineCol(SM.getMainFileID(), PreLoc.getLine(),
+                                        PreLoc.getColumn());
+          PreLoc = SM.getPresumedLoc(FilenameRange.getBegin());
+          auto FileNameBegin = SM.translateLineCol(
+              SM.getMainFileID(), PreLoc.getLine(), PreLoc.getColumn());
+          PreLoc = SM.getPresumedLoc(FilenameRange.getEnd());
+          // translateLineCol doesn't allow offsetting into a line past its end.
+          // But FilenameRange can be a charrange and point past the line, as
+          // the endpoint is exclusive.
+          auto FileNameEnd =
+              SM.translateLineCol(SM.getMainFileID(), PreLoc.getLine(), 1)
+                  .getLocWithOffset(PreLoc.getColumn() - 1);
+          FilenameRange = CharSourceRange({FileNameBegin, FileNameEnd},
+                                          FilenameRange.isTokenRange());
+        }
+      }
+    }
     if (isInsideMainFile(HashLoc, SM)) {
       Out->MainFileIncludes.emplace_back();
       auto &Inc = Out->MainFileIncludes.back();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D78740.259655.patch
Type: text/x-patch
Size: 3135 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200423/16ae47fd/attachment.bin>


More information about the cfe-commits mailing list