summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Symbol/ClangASTContext.h13
-rw-r--r--lldb/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/Makefile3
-rw-r--r--lldb/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/TestClassTemplateParameterPack.py7
-rw-r--r--lldb/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/main.cpp61
-rw-r--r--lldb/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/Makefile3
-rw-r--r--lldb/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/TestFunctionTemplateParameterPack.py6
-rw-r--r--lldb/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/main.cpp24
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp29
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp44
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp2
-rw-r--r--lldb/source/Symbol/ClangASTContext.cpp53
12 files changed, 211 insertions, 36 deletions
diff --git a/lldb/include/lldb/Symbol/ClangASTContext.h b/lldb/include/lldb/Symbol/ClangASTContext.h
index ef165915969..9d0a08414e9 100644
--- a/lldb/include/lldb/Symbol/ClangASTContext.h
+++ b/lldb/include/lldb/Symbol/ClangASTContext.h
@@ -275,17 +275,16 @@ public:
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 *
diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/Makefile b/lldb/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/Makefile
new file mode 100644
index 00000000000..99bfa7e03b4
--- /dev/null
+++ b/lldb/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
diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/TestClassTemplateParameterPack.py b/lldb/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/TestClassTemplateParameterPack.py
new file mode 100644
index 00000000000..af362f5be5d
--- /dev/null
+++ b/lldb/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")])
diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/main.cpp b/lldb/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/main.cpp
new file mode 100644
index 00000000000..90e63b40f41
--- /dev/null
+++ b/lldb/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"])
+}
diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/Makefile b/lldb/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/Makefile
new file mode 100644
index 00000000000..99bfa7e03b4
--- /dev/null
+++ b/lldb/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
diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/TestFunctionTemplateParameterPack.py b/lldb/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/TestFunctionTemplateParameterPack.py
new file mode 100644
index 00000000000..810aefee0f0
--- /dev/null
+++ b/lldb/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")])
diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/main.cpp b/lldb/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/main.cpp
new file mode 100644
index 00000000000..e802d40e5f8
--- /dev/null
+++ b/lldb/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"])
+}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index 1f78fb96bc3..a3cdfa9d5f1 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -1987,8 +1987,33 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
.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,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 8aec35d09ce..cb00e840673 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1595,24 +1595,17 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
: 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 @@ bool DWARFASTParserClang::ParseTemplateDIE(
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 @@ bool DWARFASTParserClang::ParseTemplateParameterInfos(
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 @@ size_t DWARFASTParserClang::ParseChildParameters(
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
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index e00eda4f35c..022ce5523a0 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -1647,6 +1647,8 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
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:
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
index f0d66720c55..2ff0fe3aac4 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
@@ -610,6 +610,8 @@ DW_TAG_CategoryEnum get_tag_category(uint16_t tag) {
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:
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index 8e2576aaec9..d03c5a684a1 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -1394,6 +1394,12 @@ CompilerType ClangASTContext::CreateRecordType(DeclContext *decl_ctx,
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,
@@ -1401,31 +1407,51 @@ static TemplateParameterList *CreateTemplateParameterList(
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 @@ ClangASTContext::CreateClassTemplateSpecializationDecl(
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(
OpenPOWER on IntegriCloud