[PATCH] D59599: [clangd] Fix a crash while printing Template Arguments

Kadir Cetinkaya via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 20 08:49:06 PDT 2019


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

Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D59599

Files:
  clangd/AST.cpp
  unittests/clangd/SymbolCollectorTests.cpp


Index: unittests/clangd/SymbolCollectorTests.cpp
===================================================================
--- unittests/clangd/SymbolCollectorTests.cpp
+++ unittests/clangd/SymbolCollectorTests.cpp
@@ -1222,6 +1222,22 @@
   EXPECT_THAT(Symbols, Contains(QName("std::foo")));
 }
 
+TEST_F(SymbolCollectorTest, TemplateSpecForwardDecl) {
+  // FIXME: This should be fixed in AST to point at specialization. Exercised
+  // just to make sure we don't crash.
+  Annotations Header(R"(
+  template <typename T> struct [[Foo]];
+  struct Bar {
+  friend class Foo<int>;
+  };
+  template <> struct Foo<int> {};
+  )");
+  runSymbolCollector(Header.code(), /*Main=*/"");
+  EXPECT_THAT(Symbols,
+              Contains(AllOf(QName("Foo<int>"), DeclRange(Header.range()),
+                             ForCodeCompletion(true))));
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
Index: clangd/AST.cpp
===================================================================
--- clangd/AST.cpp
+++ clangd/AST.cpp
@@ -12,6 +12,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/TemplateBase.h"
+#include "clang/AST/Type.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
@@ -82,14 +83,19 @@
   if (auto Args = getTemplateSpecializationArgLocs(ND))
     printTemplateArgumentList(OS, *Args, Policy);
   else if (auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) {
-    if (auto STL = Cls->getTypeAsWritten()
-                       ->getTypeLoc()
-                       .getAs<TemplateSpecializationTypeLoc>()) {
-      llvm::SmallVector<TemplateArgumentLoc, 8> ArgLocs;
-      ArgLocs.reserve(STL.getNumArgs());
-      for (unsigned I = 0; I < STL.getNumArgs(); ++I)
-        ArgLocs.push_back(STL.getArgLoc(I));
-      printTemplateArgumentList(OS, ArgLocs, Policy);
+    if (auto *TSI = Cls->getTypeAsWritten()) {
+      if (auto STL = TSI->getTypeLoc().getAs<TemplateSpecializationTypeLoc>()) {
+        llvm::SmallVector<TemplateArgumentLoc, 8> ArgLocs;
+        ArgLocs.reserve(STL.getNumArgs());
+        for (unsigned I = 0; I < STL.getNumArgs(); ++I)
+          ArgLocs.push_back(STL.getArgLoc(I));
+        printTemplateArgumentList(OS, ArgLocs, Policy);
+      }
+    } else {
+      // FIXME: Cls->getTypeAsWritten might return null in some cases, e.g.
+      // clang sees first sees a friend declaration and then the specialization.
+      // In that case fall back to TemplateArguments without Location info,
+      printTemplateArgumentList(OS, Cls->getTemplateArgs().asArray(), Policy);
     }
   }
   OS.flush();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D59599.191505.patch
Type: text/x-patch
Size: 2666 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190320/c6c9f2f5/attachment.bin>


More information about the cfe-commits mailing list