[llvm-branch-commits] [clang-tools-extra] 30d05b8 - [clangd][Hover] Handle uninstantiated default args

Sam McCall via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Jun 10 02:54:28 PDT 2020


Author: Kadir Cetinkaya
Date: 2020-06-10T11:53:19+02:00
New Revision: 30d05b898c6e84160507a66aabba6aceb129a9c7

URL: https://github.com/llvm/llvm-project/commit/30d05b898c6e84160507a66aabba6aceb129a9c7
DIFF: https://github.com/llvm/llvm-project/commit/30d05b898c6e84160507a66aabba6aceb129a9c7.diff

LOG: [clangd][Hover] Handle uninstantiated default args

Summary:
Default args might exist but be unparsed or uninstantiated.
getDefaultArg asserts on those. This patch makes sure we don't crash in such
scenarios.

Reviewers: sammccall, ilya-biryukov

Subscribers: MaskRay, jkorous, arphaman, usaxena95, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D73723

(cherry-picked from commit 9c903d0373ff940f9143efab8d948edf776de9f1)

Fixes https://github.com/clangd/clangd/issues/424

Added: 
    

Modified: 
    clang-tools-extra/clangd/Hover.cpp
    clang-tools-extra/clangd/unittests/HoverTests.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index 834c9d041872..e41b4b8e5e1d 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -249,6 +249,20 @@ void enhanceFromIndex(HoverInfo &Hover, const NamedDecl &ND,
       Req, [&](const Symbol &S) { Hover.Documentation = S.Documentation; });
 }
 
+// Default argument might exist but be unavailable, in the case of unparsed
+// arguments for example. This function returns the default argument if it is
+// available.
+const Expr *getDefaultArg(const ParmVarDecl *PVD) {
+  // Default argument can be unparsed or uninstatiated. For the former we
+  // can't do much, as token information is only stored in Sema and not
+  // attached to the AST node. For the latter though, it is safe to proceed as
+  // the expression is still valid.
+  if (!PVD->hasDefaultArg() || PVD->hasUnparsedDefaultArg())
+    return nullptr;
+  return PVD->hasUninstantiatedDefaultArg() ? PVD->getUninstantiatedDefaultArg()
+                                            : PVD->getDefaultArg();
+}
+
 // Populates Type, ReturnType, and Parameters for function-like decls.
 void fillFunctionTypeAndParams(HoverInfo &HI, const Decl *D,
                                const FunctionDecl *FD,
@@ -268,10 +282,10 @@ void fillFunctionTypeAndParams(HoverInfo &HI, const Decl *D,
     }
     if (!PVD->getName().empty())
       P.Name = PVD->getNameAsString();
-    if (PVD->hasDefaultArg()) {
+    if (const Expr *DefArg = getDefaultArg(PVD)) {
       P.Default.emplace();
       llvm::raw_string_ostream Out(*P.Default);
-      PVD->getDefaultArg()->printPretty(Out, nullptr, Policy);
+      DefArg->printPretty(Out, nullptr, Policy);
     }
   }
 

diff  --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index bdac5be0ac35..89b529d9b419 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -1615,6 +1615,22 @@ TEST(Hover, All) {
             HI.Type = "unsigned long";
             HI.Value = "1";
           }},
+      {
+          R"cpp(
+          template <typename T = int>
+          void foo(const T& = T()) {
+            [[f^oo]]<>(3);
+          })cpp",
+          [](HoverInfo &HI) {
+            HI.Name = "foo";
+            HI.Kind = index::SymbolKind::Function;
+            HI.Type = "void (const int &)";
+            HI.ReturnType = "void";
+            HI.Parameters = {
+                {std::string("const int &"), llvm::None, std::string("T()")}};
+            HI.Definition = "template <> void foo<int>(const int &)";
+            HI.NamespaceScope = "";
+          }},
   };
 
   // Create a tiny index, so tests above can verify documentation is fetched.


        


More information about the llvm-branch-commits mailing list