This revision was automatically updated to reflect the committed changes.
Closed by commit rL302833: [DWARF parser] Produce correct template parameter 
packs (authored by spyffe).

Changed prior to commit:
  https://reviews.llvm.org/D33025?vs=98388&id=98687#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D33025

Files:
  lldb/trunk/include/lldb/Symbol/ClangASTContext.h
  
lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/Makefile
  
lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/TestClassTemplateParameterPack.py
  
lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/main.cpp
  
lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/Makefile
  
lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/TestFunctionTemplateParameterPack.py
  
lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/main.cpp
  lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
  lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
  lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
  lldb/trunk/source/Symbol/ClangASTContext.cpp

Index: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
===================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h
@@ -275,17 +275,16 @@
     bool IsValid() const {
       if (args.empty())
         return false;
-      return args.size() == names.size();
-    }
-
-    size_t GetSize() const {
-      if (IsValid())
-        return args.size();
-      return 0;
+      return args.size() == names.size() &&
+        ((bool)pack_name == (bool)packed_args) &&
+        (!packed_args || !packed_args->packed_args);
     }
 
     llvm::SmallVector<const char *, 2> names;
     llvm::SmallVector<clang::TemplateArgument, 2> args;
+    
+    const char * pack_name = nullptr;
+    std::unique_ptr<TemplateParameterInfos> packed_args;
   };
 
   clang::FunctionTemplateDecl *
Index: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/TestFunctionTemplateParameterPack.py
===================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/TestFunctionTemplateParameterPack.py
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/TestFunctionTemplateParameterPack.py
@@ -0,0 +1,6 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(
+    __file__, globals(), [
+        decorators.expectedFailureAll(bugnumber="rdar://problem/32096064")])
Index: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/main.cpp
===================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/main.cpp
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/main.cpp
@@ -0,0 +1,24 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LIDENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+template <class T> int staticSizeof() {
+  return sizeof(T);
+}
+
+template <class T1, class T2, class... Ts> int staticSizeof() {
+  return staticSizeof<T2, Ts...>() + sizeof(T1);
+}
+
+int main (int argc, char const *argv[])
+{
+  int sz = staticSizeof<long, int, char>();
+  return staticSizeof<long, int, char>() != sz; //% self.expect("expression -- sz == staticSizeof<long, int, char>()", "staticSizeof<long, int, char> worked", substrs = ["true"])
+                                  //% self.expect("expression -- sz == staticSizeof<long, int>() + sizeof(char)", "staticSizeof<long, int> worked", substrs = ["true"])
+                                  //% self.expect("expression -- sz == staticSizeof<long>() + sizeof(int) + sizeof(char)", "staticSizeof<long> worked", substrs = ["true"])
+}
Index: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/Makefile
===================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/Makefile
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/Makefile
@@ -0,0 +1,3 @@
+LEVEL = ../../../make
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules
Index: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/Makefile
===================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/Makefile
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/Makefile
@@ -0,0 +1,3 @@
+LEVEL = ../../../make
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules
Index: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/TestClassTemplateParameterPack.py
===================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/TestClassTemplateParameterPack.py
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/TestClassTemplateParameterPack.py
@@ -0,0 +1,7 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(
+    __file__, globals(), [
+        decorators.expectedFailureAll(
+            oslist=["windows"], bugnumber="llvm.org/pr24764")])
Index: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/main.cpp
===================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/main.cpp
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/main.cpp
@@ -0,0 +1,61 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LIDENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+template <class T, int... Args> struct C {
+  T member;
+  bool isSixteenThirtyTwo() { return false; }
+};
+
+template <> struct C<int, 16> {
+  int member;
+  bool isSixteenThirtyTwo() { return false; }
+};
+
+template <> struct C<int, 16, 32> : C<int, 16> {
+  bool isSixteenThirtyTwo() { return true; }
+};
+
+template <class T, typename... Args> struct D {
+  T member;
+  bool isIntBool() { return false; }
+};
+
+template <> struct D<int, int> {
+  int member;
+  bool isIntBool() { return false; }
+};
+
+template <> struct D<int, int, bool> : D<int, int> {
+  bool isIntBool() { return true; }
+};
+
+int main (int argc, char const *argv[])
+{
+    C<int,16,32> myC;
+    C<int,16> myLesserC;
+    myC.member = 64;
+    (void)C<int,16,32>().isSixteenThirtyTwo();
+    (void)C<int,16>().isSixteenThirtyTwo();
+    (void)(myC.member != 64);   //% self.expect("expression -- myC", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["64"])
+                                //% self.expect("expression -- C<int, 16>().isSixteenThirtyTwo()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["false"])
+                                //% self.expect("expression -- C<int, 16, 32>().isSixteenThirtyTwo()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["true"])
+                                //% self.expect("expression -- myLesserC.isSixteenThirtyTwo()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["false"])
+                                //% self.expect("expression -- myC.isSixteenThirtyTwo()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["true"])
+   
+    D<int,int,bool> myD;
+    D<int,int> myLesserD;
+    myD.member = 64;
+    (void)D<int,int,bool>().isIntBool();
+    (void)D<int,int>().isIntBool();
+    return myD.member != 64;	//% self.expect("expression -- myD", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["64"])
+                                //% self.expect("expression -- D<int, int>().isIntBool()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["false"])
+                                //% self.expect("expression -- D<int, int, bool>().isIntBool()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["true"])
+                                //% self.expect("expression -- myLesserD.isIntBool()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["false"])
+                                //% self.expect("expression -- myD.isIntBool()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["true"])
+}
Index: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
===================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -1987,8 +1987,33 @@
                 .GetOpaqueDeclContext();
         clang::FunctionDecl *src_function_decl =
             llvm::dyn_cast_or_null<clang::FunctionDecl>(src_decl_context);
-
-        if (src_function_decl) {
+        if (src_function_decl &&
+            src_function_decl->getTemplateSpecializationInfo()) {
+          clang::FunctionTemplateDecl *function_template =
+              src_function_decl->getTemplateSpecializationInfo()->getTemplate();
+          clang::FunctionTemplateDecl *copied_function_template =
+              llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(
+                 m_ast_importer_sp->CopyDecl(m_ast_context,
+                                             src_ast->getASTContext(),
+                                             function_template));
+          if (copied_function_template) {
+            if (log) {
+              ASTDumper ast_dumper((clang::Decl *)copied_function_template);
+              
+              StreamString ss;
+              
+              function->DumpSymbolContext(&ss);
+              
+              log->Printf("  CEDM::FEVD[%u] Imported decl for function template"
+                          " %s (description %s), returned %s",
+                          current_id,
+                          copied_function_template->getNameAsString().c_str(),
+                          ss.GetData(), ast_dumper.GetCString());
+            }
+            
+            context.AddNamedDecl(copied_function_template);
+          }
+        } else if (src_function_decl) {
           if (clang::FunctionDecl *copied_function_decl =
                   llvm::dyn_cast_or_null<clang::FunctionDecl>(
                       m_ast_importer_sp->CopyDecl(m_ast_context,
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
@@ -610,6 +610,8 @@
     return TagCategoryType;
   case DW_TAG_template_value_parameter:
     return TagCategoryType;
+  case DW_TAG_GNU_template_parameter_pack:
+    return TagCategoryType;
   case DW_TAG_thrown_type:
     return TagCategoryType;
   case DW_TAG_try_block:
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1595,24 +1595,17 @@
                                             : containing_decl_ctx,
                   type_name_cstr, clang_type, storage, is_inline);
 
-              //                            if (template_param_infos.GetSize() >
-              //                            0)
-              //                            {
-              //                                clang::FunctionTemplateDecl
-              //                                *func_template_decl =
-              //                                CreateFunctionTemplateDecl
-              //                                (containing_decl_ctx,
-              //                                                                                                              function_decl,
-              //                                                                                                              type_name_cstr,
-              //                                                                                                              template_param_infos);
-              //
-              //                                CreateFunctionTemplateSpecializationInfo
-              //                                (function_decl,
-              //                                                                          func_template_decl,
-              //                                                                          template_param_infos);
-              //                            }
-              // Add the decl to our DIE to decl context map
-
+              if (has_template_params) {
+                ClangASTContext::TemplateParameterInfos template_param_infos;
+                ParseTemplateParameterInfos(die, template_param_infos);
+                clang::FunctionTemplateDecl *func_template_decl =
+                    m_ast.CreateFunctionTemplateDecl(
+                        containing_decl_ctx, function_decl, type_name_cstr,
+                        template_param_infos);
+                m_ast.CreateFunctionTemplateSpecializationInfo(
+                    function_decl, func_template_decl, template_param_infos);
+              }
+              
               lldbassert(function_decl);
 
               if (function_decl) {
@@ -1951,6 +1944,19 @@
   const dw_tag_t tag = die.Tag();
 
   switch (tag) {
+  case DW_TAG_GNU_template_parameter_pack: {
+    template_param_infos.packed_args.reset(
+      new ClangASTContext::TemplateParameterInfos);
+    for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid();
+         child_die = child_die.GetSibling()) {
+      if (!ParseTemplateDIE(child_die, *template_param_infos.packed_args))
+        return false;
+    }
+    if (const char *name = die.GetName()) {
+      template_param_infos.pack_name = name;
+    }
+    return true;
+  }
   case DW_TAG_template_type_parameter:
   case DW_TAG_template_value_parameter: {
     DWARFAttributes attributes;
@@ -2040,6 +2046,7 @@
     switch (tag) {
     case DW_TAG_template_type_parameter:
     case DW_TAG_template_value_parameter:
+    case DW_TAG_GNU_template_parameter_pack:
       ParseTemplateDIE(die, template_param_infos);
       break;
 
@@ -3450,6 +3457,7 @@
 
     case DW_TAG_template_type_parameter:
     case DW_TAG_template_value_parameter:
+    case DW_TAG_GNU_template_parameter_pack:
       // The one caller of this was never using the template_param_infos,
       // and the local variable was taking up a large amount of stack space
       // in SymbolFileDWARF::ParseType() so this was removed. If we ever need
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -1647,6 +1647,8 @@
       break;
     case DW_TAG_template_value_parameter:
       break;
+    case DW_TAG_GNU_template_parameter_pack:
+      break;
     case DW_TAG_thrown_type:
       break;
     case DW_TAG_try_block:
Index: lldb/trunk/source/Symbol/ClangASTContext.cpp
===================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp
@@ -1394,38 +1394,64 @@
   return CompilerType();
 }
 
+namespace {
+  bool IsValueParam(const clang::TemplateArgument &argument) {
+    return argument.getKind() == TemplateArgument::Integral;
+  }
+}
+
 static TemplateParameterList *CreateTemplateParameterList(
     ASTContext *ast,
     const ClangASTContext::TemplateParameterInfos &template_param_infos,
     llvm::SmallVector<NamedDecl *, 8> &template_param_decls) {
   const bool parameter_pack = false;
   const bool is_typename = false;
   const unsigned depth = 0;
-  const size_t num_template_params = template_param_infos.GetSize();
+  const size_t num_template_params = template_param_infos.args.size();
+  DeclContext *const decl_context =
+      ast->getTranslationUnitDecl(); // Is this the right decl context?,
   for (size_t i = 0; i < num_template_params; ++i) {
     const char *name = template_param_infos.names[i];
 
     IdentifierInfo *identifier_info = nullptr;
     if (name && name[0])
       identifier_info = &ast->Idents.get(name);
-    if (template_param_infos.args[i].getKind() == TemplateArgument::Integral) {
+    if (IsValueParam(template_param_infos.args[i])) {
       template_param_decls.push_back(NonTypeTemplateParmDecl::Create(
-          *ast,
-          ast->getTranslationUnitDecl(), // Is this the right decl context?,
-                                         // SourceLocation StartLoc,
+          *ast, decl_context,
           SourceLocation(), SourceLocation(), depth, i, identifier_info,
           template_param_infos.args[i].getIntegralType(), parameter_pack,
           nullptr));
 
     } else {
       template_param_decls.push_back(TemplateTypeParmDecl::Create(
-          *ast,
-          ast->getTranslationUnitDecl(), // Is this the right decl context?
+          *ast, decl_context,
           SourceLocation(), SourceLocation(), depth, i, identifier_info,
           is_typename, parameter_pack));
     }
   }
-
+  
+  if (template_param_infos.packed_args &&
+      template_param_infos.packed_args->args.size()) {
+    IdentifierInfo *identifier_info = nullptr;
+    if (template_param_infos.pack_name && template_param_infos.pack_name[0])
+      identifier_info = &ast->Idents.get(template_param_infos.pack_name);
+    const bool parameter_pack_true = true;
+    if (IsValueParam(template_param_infos.packed_args->args[0])) {
+      template_param_decls.push_back(NonTypeTemplateParmDecl::Create(
+          *ast, decl_context,
+          SourceLocation(), SourceLocation(), depth, num_template_params,
+          identifier_info,
+          template_param_infos.packed_args->args[0].getIntegralType(),
+          parameter_pack_true, nullptr));
+    } else {
+      template_param_decls.push_back(TemplateTypeParmDecl::Create(
+          *ast, decl_context,
+          SourceLocation(), SourceLocation(), depth, num_template_params,
+          identifier_info,
+          is_typename, parameter_pack_true));
+    }
+  }
   clang::Expr *const requires_clause = nullptr; // TODO: Concepts
   TemplateParameterList *template_param_list = TemplateParameterList::Create(
       *ast, SourceLocation(), SourceLocation(), template_param_decls,
@@ -1535,10 +1561,19 @@
     DeclContext *decl_ctx, ClassTemplateDecl *class_template_decl, int kind,
     const TemplateParameterInfos &template_param_infos) {
   ASTContext *ast = getASTContext();
+  llvm::SmallVector<clang::TemplateArgument, 2> args(
+      template_param_infos.args.size() +
+      (template_param_infos.packed_args ? 1 : 0));
+  std::copy(template_param_infos.args.begin(), template_param_infos.args.end(),
+            args.begin());
+  if (template_param_infos.packed_args) {
+    args[args.size() - 1] = TemplateArgument::CreatePackCopy(
+        *ast, template_param_infos.packed_args->args);
+  }
   ClassTemplateSpecializationDecl *class_template_specialization_decl =
       ClassTemplateSpecializationDecl::Create(
           *ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(),
-          SourceLocation(), class_template_decl, template_param_infos.args,
+          SourceLocation(), class_template_decl, args,
           nullptr);
 
   class_template_specialization_decl->setSpecializationKind(
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to