[PATCH] D87253: [libTooling] Change CDB heuristic to look further for files in a given language.

Adam Czachorowski via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 7 11:29:15 PDT 2020


adamcz created this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
adamcz requested review of this revision.

When looking for compile commands for file of type X, other files of
type X will be preferred over files of any other type, regardless of
score.

However, when gathering the set of candidates, we only look for files
with similar name and files close to the requested one. If it happens
that none of them are in language X, we previously (before this change)
would choose one of the existing candidates of some other type.

This patch adds all files in language X (regardless of name and
location) to the list of candidates if the initial set of candidates did
not contain any files of type X. This means we will always choose a file
of type X if one exists anywhere in the project.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D87253

Files:
  clang/lib/Tooling/InterpolatingCompilationDatabase.cpp
  clang/unittests/Tooling/CompilationDatabaseTest.cpp


Index: clang/unittests/Tooling/CompilationDatabaseTest.cpp
===================================================================
--- clang/unittests/Tooling/CompilationDatabaseTest.cpp
+++ clang/unittests/Tooling/CompilationDatabaseTest.cpp
@@ -755,6 +755,7 @@
 }
 
 TEST_F(InterpolateTest, Language) {
+  add("aaa/bbb/ccc/ddd/file.c", "");
   add("dir/foo.cpp", "-std=c++17");
   add("dir/bar.c", "");
   add("dir/baz.cee", "-x c");
@@ -774,7 +775,10 @@
   EXPECT_EQ(getCommand("baz.h"), "clang -D dir/baz.cee -x c-header");
   // prefer a worse match with the right extension.
   EXPECT_EQ(getCommand("foo.c"), "clang -D dir/bar.c");
+  // even when it is far away.
+  EXPECT_EQ(getCommand("aaa/bbb/ccc/ddd/file.hpp"), "clang -D dir/aux.cpp");
   Entries.erase(path(StringRef("dir/bar.c")));
+  Entries.erase(path(StringRef("aaa/bbb/ccc/ddd/file.c")));
   // Now we transfer across languages, so drop -std too.
   EXPECT_EQ(getCommand("foo.c"), "clang -D dir/foo.cpp");
   // Prefer -x over -std when overriding language.
Index: clang/lib/Tooling/InterpolatingCompilationDatabase.cpp
===================================================================
--- clang/lib/Tooling/InterpolatingCompilationDatabase.cpp
+++ clang/lib/Tooling/InterpolatingCompilationDatabase.cpp
@@ -352,7 +352,7 @@
                         types::ID PreferLanguage) const {
     assert(!empty() && "need at least one candidate!");
     std::string Filename = OriginalFilename.lower();
-    auto Candidates = scoreCandidates(Filename);
+    auto Candidates = scoreCandidates(Filename, PreferLanguage);
     std::pair<size_t, int> Best =
         pickWinner(Candidates, Filename, PreferLanguage);
 
@@ -378,7 +378,8 @@
 
   // Award points to candidate entries that should be considered for the file.
   // Returned keys are indexes into paths, and the values are (nonzero) scores.
-  DenseMap<size_t, int> scoreCandidates(StringRef Filename) const {
+  DenseMap<size_t, int> scoreCandidates(StringRef Filename,
+                                        types::ID PreferredLanguage) const {
     // Decompose Filename into the parts we care about.
     // /some/path/complicated/project/Interesting.h
     // [-prefix--][---dir---] [-dir-] [--stem---]
@@ -410,6 +411,25 @@
     // Award one more point if the whole rest of the path matches.
     if (sys::path::root_directory(Prefix) != Prefix)
       Award(1, indexLookup</*Prefix=*/true>(Prefix, Paths));
+
+    bool CandidateWithMatchingLanguageFound = false;
+    for (const auto &C : Candidates) {
+      if (Types[C.first] == PreferredLanguage) {
+        CandidateWithMatchingLanguageFound = true;
+        break;
+      }
+    }
+    if (!CandidateWithMatchingLanguageFound) {
+      // If none of the candidates we found so far use preferred language, try
+      // all other files, even if they are far away in the dir hierarchy.
+      for (size_t I = 0; I < OriginalPaths.size(); ++I) {
+        // Increase score by one. The actual value doesn't matter, the point is
+        // to have some candidates matching PreferredLanguage in the Candidates
+        // set at all.
+        if (Types[I] == PreferredLanguage)
+          Candidates[I] += 1;
+      }
+    }
     return Candidates;
   }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D87253.290335.patch
Type: text/x-patch
Size: 3229 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200907/b08e54f9/attachment.bin>


More information about the cfe-commits mailing list