]> granicus.if.org Git - clang/commitdiff
Debug info: When collecting the parameters of C++ partial template
authorAdrian Prantl <aprantl@apple.com>
Thu, 17 Apr 2014 00:30:48 +0000 (00:30 +0000)
committerAdrian Prantl <aprantl@apple.com>
Thu, 17 Apr 2014 00:30:48 +0000 (00:30 +0000)
specializations collect all arguments and not just the ones from the
class template partial specialization from which this class template
specialization was instantiated. The debug info does not represent the
partial specialization otherwise and so specialized parameters would
go missing.

rdar://problem/16636569.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@206430 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGDebugInfo.cpp
test/CodeGenCXX/debug-info-template-partial-specialization.cpp [new file with mode: 0644]

index 8e06bbd34b6f1d60df6aec9bc7092b7c5c014244..dc49e1865ed765ef7a84ad28a92af047bd6c680e 100644 (file)
@@ -1360,10 +1360,16 @@ CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TSpecial,
                      ClassTemplatePartialSpecializationDecl *>
     PU = TSpecial->getSpecializedTemplateOrPartial();
 
-  TemplateParameterList *TPList = PU.is<ClassTemplateDecl *>() ?
-    PU.get<ClassTemplateDecl *>()->getTemplateParameters() :
-    PU.get<ClassTemplatePartialSpecializationDecl *>()->getTemplateParameters();
-  const TemplateArgumentList &TAList = TSpecial->getTemplateInstantiationArgs();
+  TemplateParameterList *TPList;
+  if (auto *CTD = PU.dyn_cast<ClassTemplateDecl *>())
+    TPList = CTD->getTemplateParameters();
+  else {
+    // Always get the full list of parameters, not just the ones from
+    // the specialization.
+    auto *CTPSD = PU.get<ClassTemplatePartialSpecializationDecl *>();
+    TPList = CTPSD->getSpecializedTemplate()->getTemplateParameters();
+  }
+  const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
   return CollectTemplateParams(TPList, TAList.asArray(), Unit);
 }
 
diff --git a/test/CodeGenCXX/debug-info-template-partial-specialization.cpp b/test/CodeGenCXX/debug-info-template-partial-specialization.cpp
new file mode 100644 (file)
index 0000000..cce84af
--- /dev/null
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -g %s -o - -fstandalone-debug | FileCheck %s
+namespace __pointer_type_imp
+{
+  template <class _Tp, class _Dp, bool > struct __pointer_type1 {};
+
+  // CHECK: metadata ![[PARAMS:[0-9]+]], metadata !"_ZTSN18__pointer_type_imp15__pointer_type1I1C14default_deleteIS1_ELb0EEE"} ; [ DW_TAG_structure_type ] [__pointer_type1<C, default_delete<C>, false>] [line [[@LINE+1]], size 8, align 8, offset 0] [def] [from ]
+  template <class _Tp, class _Dp> struct __pointer_type1<_Tp, _Dp, false>
+  {
+    typedef _Tp* type;
+  };
+}
+template <class _Tp, class _Dp>
+struct __pointer_type2
+{
+  // Test that the bool template type parameter is emitted.
+  //
+  // CHECK: ![[PARAMS]] = metadata !{metadata !{{.*}}, metadata !{{.*}}, metadata ![[FALSE:[0-9]+]]}
+  // CHECK: ![[FALSE]] = {{.*}} i8 0, {{.*}}} ; [ DW_TAG_template_value_parameter ]
+  typedef typename __pointer_type_imp::__pointer_type1<_Tp, _Dp, false>::type type;
+};
+template <class _Tp> struct default_delete {};
+template <class _Tp, class _Dp = default_delete<_Tp> > class unique_ptr
+{
+  typedef typename __pointer_type2<_Tp, _Dp>::type pointer;
+  unique_ptr(pointer __p, _Dp __d) {}
+};
+class C {
+  unique_ptr<C> Ptr;
+};
+void foo(C &c) {
+}