[Lldb-commits] [lldb] r328984 - Support template template parameters

Frederic Riss via lldb-commits lldb-commits at lists.llvm.org
Mon Apr 2 09:18:32 PDT 2018


Author: friss
Date: Mon Apr  2 09:18:32 2018
New Revision: 328984

URL: http://llvm.org/viewvc/llvm-project?rev=328984&view=rev
Log:
Support template template parameters

Summary:
We would fail to resolve (and thus display the value of) any
templated type which contained a template template argument even
though we don't really use template arguments.

This patch adds minimal support for template template arguments,
but I doubt we need any more than that.

Reviewers: clayborg, jingham

Subscribers: JDevlieghere, lldb-commits

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

Modified:
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/template/TestTemplateArgs.py
    lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/template/main.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
    lldb/trunk/source/Symbol/ClangASTContext.cpp

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=328984&r1=328983&r2=328984&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Mon Apr  2 09:18:32 2018
@@ -305,6 +305,9 @@ public:
                           lldb::AccessType access_type, const char *class_name,
                           int kind, const TemplateParameterInfos &infos);
 
+  clang::TemplateTemplateParmDecl *
+  CreateTemplateTemplateParmDecl(const char *template_name);
+
   clang::ClassTemplateSpecializationDecl *CreateClassTemplateSpecializationDecl(
       clang::DeclContext *decl_ctx,
       clang::ClassTemplateDecl *class_template_decl, int kind,

Modified: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/template/TestTemplateArgs.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/template/TestTemplateArgs.py?rev=328984&r1=328983&r2=328984&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/template/TestTemplateArgs.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/template/TestTemplateArgs.py Mon Apr  2 09:18:32 2018
@@ -83,6 +83,34 @@ class TemplateArgsTestCase(TestBase):
             expr_result.GetType().GetName() == "int",
             'expr_result.GetType().GetName() == "int"')
 
+    def test_template_template_args(self):
+        frame = self.prepareProcess()
+
+        c1 = frame.FindVariable('c1')
+        self.assertTrue(
+            c1.IsValid(),
+            'make sure we find a local variabble named "c1"')
+        self.assertTrue(c1.GetType().GetName() == 'C<float, T1>')
+        f1 = c1.GetChildMemberWithName("V").GetChildAtIndex(0).GetChildMemberWithName("f")
+        self.assertTrue(f1.GetType().GetName() == 'float')
+        self.assertTrue(f1.GetValue() == '1.5')
+
+        c2 = frame.FindVariable('c2')
+        self.assertTrue(
+            c2.IsValid(),
+            'make sure we find a local variabble named "c2"')
+        self.assertTrue(c2.GetType().GetName() == 'C<double, T1, T2>')
+        f2 = c2.GetChildMemberWithName("V").GetChildAtIndex(0).GetChildMemberWithName("f")
+        self.assertTrue(f2.GetType().GetName() == 'double')
+        self.assertTrue(f2.GetValue() == '1.5')
+        f3 = c2.GetChildMemberWithName("V").GetChildAtIndex(1).GetChildMemberWithName("f")
+        self.assertTrue(f3.GetType().GetName() == 'double')
+        self.assertTrue(f3.GetValue() == '2.5')
+        f4 = c2.GetChildMemberWithName("V").GetChildAtIndex(1).GetChildMemberWithName("i")
+        self.assertTrue(f4.GetType().GetName() == 'int')
+        self.assertTrue(f4.GetValue() == '42')
+
+
     # Gcc does not generate the necessary DWARF attribute for enum template
     # parameters.
     @expectedFailureAll(bugnumber="llvm.org/pr28354", compiler="gcc")

Modified: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/template/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/template/main.cpp?rev=328984&r1=328983&r2=328984&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/template/main.cpp (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/template/main.cpp Mon Apr  2 09:18:32 2018
@@ -6,6 +6,7 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+#include <tuple>
 
 template <int Arg>
 class TestObj
@@ -62,11 +63,17 @@ public:
     }    
 };
 
+template <typename FLOAT> struct T1 { FLOAT f = 1.5; };
+template <typename FLOAT> struct T2 { FLOAT f = 2.5; int i = 42; };
+template <typename FLOAT, template <typename> class ...Args> class C { std::tuple<Args<FLOAT>...> V; };
+
 int main(int argc, char **argv)
 {
   TestObj<1> testpos;
   TestObj<-1> testneg;
   EnumTemplate<EnumType::Member> member(123);
   EnumTemplate<EnumType::Subclass> subclass(123*2);
+  C<float, T1> c1;
+  C<double, T1, T2> c2;
   return testpos.getArg() - testneg.getArg() + member.getMember()*2 - subclass.getMember(); // Breakpoint 1
 }

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp?rev=328984&r1=328983&r2=328984&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp Mon Apr  2 09:18:32 2018
@@ -41,6 +41,7 @@
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
 
 #include <map>
 #include <vector>
@@ -2042,6 +2043,7 @@ bool DWARFASTParserClang::ParseTemplateD
     const DWARFDIE &die,
     ClangASTContext::TemplateParameterInfos &template_param_infos) {
   const dw_tag_t tag = die.Tag();
+  bool is_template_template_argument = false;
 
   switch (tag) {
   case DW_TAG_GNU_template_parameter_pack: {
@@ -2057,11 +2059,15 @@ bool DWARFASTParserClang::ParseTemplateD
     }
     return true;
   }
+  case DW_TAG_GNU_template_template_param:
+    is_template_template_argument = true;
+    LLVM_FALLTHROUGH;
   case DW_TAG_template_type_parameter:
   case DW_TAG_template_value_parameter: {
     DWARFAttributes attributes;
     const size_t num_attributes = die.GetAttributes(attributes);
     const char *name = nullptr;
+    const char *template_name = nullptr;
     CompilerType clang_type;
     uint64_t uval64 = 0;
     bool uval64_valid = false;
@@ -2076,6 +2082,11 @@ bool DWARFASTParserClang::ParseTemplateD
             name = form_value.AsCString();
           break;
 
+        case DW_AT_GNU_template_name:
+          if (attributes.ExtractFormValueAtIndex(i, form_value))
+            template_name = form_value.AsCString();
+          break;
+
         case DW_AT_type:
           if (attributes.ExtractFormValueAtIndex(i, form_value)) {
             Type *lldb_type = die.ResolveTypeUID(DIERef(form_value));
@@ -2099,7 +2110,7 @@ bool DWARFASTParserClang::ParseTemplateD
       if (!clang_type)
         clang_type = m_ast.GetBasicType(eBasicTypeVoid);
 
-      if (clang_type) {
+      if (!is_template_template_argument) {
         bool is_signed = false;
         if (name && name[0])
           template_param_infos.names.push_back(name);
@@ -2119,7 +2130,10 @@ bool DWARFASTParserClang::ParseTemplateD
               clang::TemplateArgument(ClangUtil::GetQualType(clang_type)));
         }
       } else {
-        return false;
+        auto *tplt_type = m_ast.CreateTemplateTemplateParmDecl(template_name);
+        template_param_infos.names.push_back(name);
+        template_param_infos.args.push_back(
+            clang::TemplateArgument(clang::TemplateName(tplt_type)));
       }
     }
   }
@@ -2146,6 +2160,7 @@ bool DWARFASTParserClang::ParseTemplateP
     case DW_TAG_template_type_parameter:
     case DW_TAG_template_value_parameter:
     case DW_TAG_GNU_template_parameter_pack:
+    case DW_TAG_GNU_template_template_param:
       ParseTemplateDIE(die, template_param_infos);
       break;
 

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=328984&r1=328983&r2=328984&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Mon Apr  2 09:18:32 2018
@@ -1482,6 +1482,29 @@ ClassTemplateDecl *ClangASTContext::Crea
   return class_template_decl;
 }
 
+TemplateTemplateParmDecl *
+ClangASTContext::CreateTemplateTemplateParmDecl(const char *template_name) {
+  ASTContext *ast = getASTContext();
+
+  auto *decl_ctx = ast->getTranslationUnitDecl();
+
+  IdentifierInfo &identifier_info = ast->Idents.get(template_name);
+  llvm::SmallVector<NamedDecl *, 8> template_param_decls;
+
+  ClangASTContext::TemplateParameterInfos template_param_infos;
+  TemplateParameterList *template_param_list = CreateTemplateParameterList(
+      ast, template_param_infos, template_param_decls);
+
+  // LLDB needs to create those decls only to be able to display a
+  // type that includes a template template argument. Only the name
+  // matters for this purpose, so we use dummy values for the other
+  // characterisitcs of the type.
+  return TemplateTemplateParmDecl::Create(
+      *ast, decl_ctx, SourceLocation(),
+      /*Depth*/ 0, /*Position*/ 0,
+      /*IsParameterPack*/ false, &identifier_info, template_param_list);
+}
+
 ClassTemplateSpecializationDecl *
 ClangASTContext::CreateClassTemplateSpecializationDecl(
     DeclContext *decl_ctx, ClassTemplateDecl *class_template_decl, int kind,




More information about the lldb-commits mailing list