This revision was automatically updated to reflect the committed changes. Closed by commit rGc526426f5cba: [lldb] Don't reject empty or unnamed template parameter packs (authored by teemperor). Herald added a project: LLDB. Herald added a subscriber: lldb-commits.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D92425/new/ https://reviews.llvm.org/D92425 Files: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h lldb/test/API/lang/cpp/class-template-non-type-parameter-pack/Makefile lldb/test/API/lang/cpp/class-template-non-type-parameter-pack/TestClassTemplateNonTypeParameterPack.py lldb/test/API/lang/cpp/class-template-non-type-parameter-pack/main.cpp lldb/test/API/lang/cpp/class-template-type-parameter-pack/Makefile lldb/test/API/lang/cpp/class-template-type-parameter-pack/TestClassTemplateTypeParameterPack.py lldb/test/API/lang/cpp/class-template-type-parameter-pack/main.cpp lldb/unittests/Symbol/TestTypeSystemClang.cpp
Index: lldb/unittests/Symbol/TestTypeSystemClang.cpp =================================================================== --- lldb/unittests/Symbol/TestTypeSystemClang.cpp +++ lldb/unittests/Symbol/TestTypeSystemClang.cpp @@ -516,6 +516,12 @@ } } +TEST_F(TestTypeSystemClang, OnlyPackName) { + TypeSystemClang::TemplateParameterInfos infos; + infos.pack_name = "A"; + EXPECT_FALSE(infos.IsValid()); +} + static QualType makeConstInt(clang::ASTContext &ctxt) { QualType result(ctxt.IntTy); result.addConst(); Index: lldb/test/API/lang/cpp/class-template-type-parameter-pack/main.cpp =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/class-template-type-parameter-pack/main.cpp @@ -0,0 +1,69 @@ +// Named type parameter pack. +template <typename... Is> +struct TypePack { int a; }; +TypePack<> emptyTypePack; +TypePack<int> oneElemTypePack; +TypePack<int, float> twoElemTypePack; + +// Unnamed type parameter pack. +template <typename... > +struct AnonTypePack { int b; }; +AnonTypePack<> emptyAnonTypePack; +AnonTypePack<int> oneElemAnonTypePack; +AnonTypePack<int, float> twoElemAnonTypePack; + +// Test type parameter packs combined with non-pack type template parameters. + +// Unnamed type parameter pack behind a named type parameter. +template <typename T, typename... > +struct AnonTypePackAfterTypeParam { T c; }; +AnonTypePackAfterTypeParam<int> emptyAnonTypePackAfterTypeParam; +AnonTypePackAfterTypeParam<int, float> oneElemAnonTypePackAfterTypeParam; + +// Unnamed type parameter pack behind an unnamed type parameter. +template <typename, typename... > +struct AnonTypePackAfterAnonTypeParam { float d; }; +AnonTypePackAfterAnonTypeParam<int> emptyAnonTypePackAfterAnonTypeParam; +AnonTypePackAfterAnonTypeParam<int, float> oneElemAnonTypePackAfterAnonTypeParam; + +// Named type parameter pack behind an unnamed type parameter. +template <typename, typename... Ts> +struct TypePackAfterAnonTypeParam { int e; }; +TypePackAfterAnonTypeParam<int> emptyTypePackAfterAnonTypeParam; +TypePackAfterAnonTypeParam<int, float> oneElemTypePackAfterAnonTypeParam; + +// Named type parameter pack behind a named type parameter. +template <typename T, typename... Ts> +struct TypePackAfterTypeParam { int f; }; +TypePackAfterTypeParam<int> emptyTypePackAfterTypeParam; +TypePackAfterTypeParam<int, float> oneElemTypePackAfterTypeParam; + +// Test type parameter packs combined with non-pack non-type template parameters. + +// Unnamed type parameter pack behind a named type parameter. +template <int I, typename... > +struct AnonTypePackAfterNonTypeParam { int g; }; +AnonTypePackAfterNonTypeParam<1> emptyAnonTypePackAfterNonTypeParam; +AnonTypePackAfterNonTypeParam<1, int> oneElemAnonTypePackAfterNonTypeParam; + +// Unnamed type parameter pack behind an unnamed type parameter. +template <int, typename... > +struct AnonTypePackAfterAnonNonTypeParam { float h; }; +AnonTypePackAfterAnonNonTypeParam<1> emptyAnonTypePackAfterAnonNonTypeParam; +AnonTypePackAfterAnonNonTypeParam<1, int> oneElemAnonTypePackAfterAnonNonTypeParam; + +// Named type parameter pack behind an unnamed type parameter. +template <int, typename... Ts> +struct TypePackAfterAnonNonTypeParam { int i; }; +TypePackAfterAnonNonTypeParam<1> emptyTypePackAfterAnonNonTypeParam; +TypePackAfterAnonNonTypeParam<1, int> oneElemTypePackAfterAnonNonTypeParam; + +// Named type parameter pack behind an unnamed type parameter. +template <int I, typename... Ts> +struct TypePackAfterNonTypeParam { int j; }; +TypePackAfterNonTypeParam<1> emptyTypePackAfterNonTypeParam; +TypePackAfterNonTypeParam<1, int> oneElemTypePackAfterNonTypeParam; + +int main() { + return 0; // break here +} Index: lldb/test/API/lang/cpp/class-template-type-parameter-pack/TestClassTemplateTypeParameterPack.py =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/class-template-type-parameter-pack/TestClassTemplateTypeParameterPack.py @@ -0,0 +1,76 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class TestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @no_debug_info_test + def test(self): + self.build() + self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + + self.expect_expr("emptyTypePack", result_type="TypePack<>", + result_children=[ValueCheck(name="a", type="int")]) + self.expect_expr("oneElemTypePack", result_type="TypePack<int>", + result_children=[ValueCheck(name="a", type="int")]) + self.expect_expr("twoElemTypePack", result_type="TypePack<int, float>", + result_children=[ValueCheck(name="a", type="int")]) + + + self.expect_expr("emptyAnonTypePack", result_type="AnonTypePack<>", + result_children=[ValueCheck(name="b", type="int")]) + self.expect_expr("oneElemAnonTypePack", result_type="AnonTypePack<int>", + result_children=[ValueCheck(name="b", type="int")]) + self.expect_expr("twoElemAnonTypePack", result_type="AnonTypePack<int, float>", + result_children=[ValueCheck(name="b", type="int")]) + + + self.expect_expr("emptyAnonTypePackAfterTypeParam", result_type="AnonTypePackAfterTypeParam<int>", + result_children=[ValueCheck(name="c", type="int")]) + self.expect_expr("oneElemAnonTypePackAfterTypeParam", result_type="AnonTypePackAfterTypeParam<int, float>", + result_children=[ValueCheck(name="c", type="int")]) + + + + self.expect_expr("emptyAnonTypePackAfterAnonTypeParam", result_type="AnonTypePackAfterAnonTypeParam<int>", + result_children=[ValueCheck(name="d", type="float")]) + self.expect_expr("oneElemAnonTypePackAfterAnonTypeParam", result_type="AnonTypePackAfterAnonTypeParam<int, float>", + result_children=[ValueCheck(name="d", type="float")]) + + + self.expect_expr("emptyTypePackAfterAnonTypeParam", result_type="TypePackAfterAnonTypeParam<int>", + result_children=[ValueCheck(name="e", type="int")]) + self.expect_expr("oneElemTypePackAfterAnonTypeParam", result_type="TypePackAfterAnonTypeParam<int, float>", + result_children=[ValueCheck(name="e", type="int")]) + + + self.expect_expr("emptyTypePackAfterTypeParam", result_type="TypePackAfterTypeParam<int>", + result_children=[ValueCheck(name="f", type="int")]) + self.expect_expr("oneElemTypePackAfterTypeParam", result_type="TypePackAfterTypeParam<int, float>", + result_children=[ValueCheck(name="f", type="int")]) + + self.expect_expr("emptyAnonTypePackAfterNonTypeParam", result_type="AnonTypePackAfterNonTypeParam<1>", + result_children=[ValueCheck(name="g", type="int")]) + self.expect_expr("oneElemAnonTypePackAfterNonTypeParam", result_type="AnonTypePackAfterNonTypeParam<1, int>", + result_children=[ValueCheck(name="g", type="int")]) + + + self.expect_expr("emptyAnonTypePackAfterAnonNonTypeParam", result_type="AnonTypePackAfterAnonNonTypeParam<1>", + result_children=[ValueCheck(name="h", type="float")]) + self.expect_expr("oneElemAnonTypePackAfterAnonNonTypeParam", result_type="AnonTypePackAfterAnonNonTypeParam<1, int>", + result_children=[ValueCheck(name="h", type="float")]) + + + self.expect_expr("emptyTypePackAfterAnonNonTypeParam", result_type="TypePackAfterAnonNonTypeParam<1>", + result_children=[ValueCheck(name="i", type="int")]) + self.expect_expr("oneElemTypePackAfterAnonNonTypeParam", result_type="TypePackAfterAnonNonTypeParam<1, int>", + result_children=[ValueCheck(name="i", type="int")]) + + + self.expect_expr("emptyTypePackAfterNonTypeParam", result_type="TypePackAfterNonTypeParam<1>", + result_children=[ValueCheck(name="j", type="int")]) + self.expect_expr("oneElemTypePackAfterNonTypeParam", result_type="TypePackAfterNonTypeParam<1, int>", + result_children=[ValueCheck(name="j", type="int")]) \ No newline at end of file Index: lldb/test/API/lang/cpp/class-template-type-parameter-pack/Makefile =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/class-template-type-parameter-pack/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules Index: lldb/test/API/lang/cpp/class-template-non-type-parameter-pack/main.cpp =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/class-template-non-type-parameter-pack/main.cpp @@ -0,0 +1,69 @@ +// Named type parameter pack. +template <int... Is> +struct NonTypePack { int a; }; +NonTypePack<> emptyNonTypePack; +NonTypePack<1> oneElemNonTypePack; +NonTypePack<1, 2> twoElemNonTypePack; + +// Unnamed type parameter pack. +template <int... > +struct AnonNonTypePack { int b; }; +AnonNonTypePack<> emptyAnonNonTypePack; +AnonNonTypePack<1> oneElemAnonNonTypePack; +AnonNonTypePack<1, 2> twoElemAnonNonTypePack; + +// Test type parameter packs combined with non-pack type template parameters. + +// Unnamed non-type parameter pack behind a named type parameter. +template <typename T, int... > +struct AnonNonTypePackAfterTypeParam { T c; }; +AnonNonTypePackAfterTypeParam<int> emptyAnonNonTypePackAfterTypeParam; +AnonNonTypePackAfterTypeParam<int, 1> oneElemAnonNonTypePackAfterTypeParam; + +// Unnamed non-type parameter pack behind an unnamed type parameter. +template <typename, int... > +struct AnonNonTypePackAfterAnonTypeParam { float d; }; +AnonNonTypePackAfterAnonTypeParam<int> emptyAnonNonTypePackAfterAnonTypeParam; +AnonNonTypePackAfterAnonTypeParam<int, 1> oneElemAnonNonTypePackAfterAnonTypeParam; + +// Named non-type parameter pack behind an unnamed type parameter. +template <typename, int... Is> +struct NonTypePackAfterAnonTypeParam { int e; }; +NonTypePackAfterAnonTypeParam<int> emptyNonTypePackAfterAnonTypeParam; +NonTypePackAfterAnonTypeParam<int, 1> oneElemNonTypePackAfterAnonTypeParam; + +// Named non-type parameter pack behind a named type parameter. +template <typename T, int... Is> +struct NonTypePackAfterTypeParam { int f; }; +NonTypePackAfterTypeParam<int> emptyNonTypePackAfterTypeParam; +NonTypePackAfterTypeParam<int, 1> oneElemNonTypePackAfterTypeParam; + +// Test non-type parameter packs combined with non-pack non-type template parameters. + +// Unnamed non-type parameter pack behind a named non-type parameter. +template <int I, int... > +struct AnonNonTypePackAfterNonTypeParam { int g; }; +AnonNonTypePackAfterNonTypeParam<1> emptyAnonNonTypePackAfterNonTypeParam; +AnonNonTypePackAfterNonTypeParam<1, 2> oneElemAnonNonTypePackAfterNonTypeParam; + +// Unnamed non-type parameter pack behind an unnamed non-type parameter. +template <int, int... > +struct AnonNonTypePackAfterAnonNonTypeParam { float h; }; +AnonNonTypePackAfterAnonNonTypeParam<1> emptyAnonNonTypePackAfterAnonNonTypeParam; +AnonNonTypePackAfterAnonNonTypeParam<1, 2> oneElemAnonNonTypePackAfterAnonNonTypeParam; + +// Named non-type parameter pack behind an unnamed non-type parameter. +template <int, int... Is> +struct NonTypePackAfterAnonNonTypeParam { int i; }; +NonTypePackAfterAnonNonTypeParam<1> emptyNonTypePackAfterAnonNonTypeParam; +NonTypePackAfterAnonNonTypeParam<1, 2> oneElemNonTypePackAfterAnonNonTypeParam; + +// Named non-type parameter pack behind an unnamed non-type parameter. +template <int I, int... Is> +struct NonTypePackAfterNonTypeParam { int j; }; +NonTypePackAfterNonTypeParam<1> emptyNonTypePackAfterNonTypeParam; +NonTypePackAfterNonTypeParam<1, 2> oneElemNonTypePackAfterNonTypeParam; + +int main() { + return 0; // break here +} Index: lldb/test/API/lang/cpp/class-template-non-type-parameter-pack/TestClassTemplateNonTypeParameterPack.py =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/class-template-non-type-parameter-pack/TestClassTemplateNonTypeParameterPack.py @@ -0,0 +1,76 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class TestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @no_debug_info_test + def test(self): + self.build() + self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + + self.expect_expr("emptyNonTypePack", result_type="NonTypePack<>", + result_children=[ValueCheck(name="a", type="int")]) + self.expect_expr("oneElemNonTypePack", result_type="NonTypePack<1>", + result_children=[ValueCheck(name="a", type="int")]) + self.expect_expr("twoElemNonTypePack", result_type="NonTypePack<1, 2>", + result_children=[ValueCheck(name="a", type="int")]) + + + self.expect_expr("emptyAnonNonTypePack", result_type="AnonNonTypePack<>", + result_children=[ValueCheck(name="b", type="int")]) + self.expect_expr("oneElemAnonNonTypePack", result_type="AnonNonTypePack<1>", + result_children=[ValueCheck(name="b", type="int")]) + self.expect_expr("twoElemAnonNonTypePack", result_type="AnonNonTypePack<1, 2>", + result_children=[ValueCheck(name="b", type="int")]) + + + self.expect_expr("emptyAnonNonTypePackAfterTypeParam", result_type="AnonNonTypePackAfterTypeParam<int>", + result_children=[ValueCheck(name="c", type="int")]) + self.expect_expr("oneElemAnonNonTypePackAfterTypeParam", result_type="AnonNonTypePackAfterTypeParam<int, 1>", + result_children=[ValueCheck(name="c", type="int")]) + + + + self.expect_expr("emptyAnonNonTypePackAfterAnonTypeParam", result_type="AnonNonTypePackAfterAnonTypeParam<int>", + result_children=[ValueCheck(name="d", type="float")]) + self.expect_expr("oneElemAnonNonTypePackAfterAnonTypeParam", result_type="AnonNonTypePackAfterAnonTypeParam<int, 1>", + result_children=[ValueCheck(name="d", type="float")]) + + + self.expect_expr("emptyNonTypePackAfterAnonTypeParam", result_type="NonTypePackAfterAnonTypeParam<int>", + result_children=[ValueCheck(name="e", type="int")]) + self.expect_expr("oneElemNonTypePackAfterAnonTypeParam", result_type="NonTypePackAfterAnonTypeParam<int, 1>", + result_children=[ValueCheck(name="e", type="int")]) + + + self.expect_expr("emptyNonTypePackAfterTypeParam", result_type="NonTypePackAfterTypeParam<int>", + result_children=[ValueCheck(name="f", type="int")]) + self.expect_expr("oneElemNonTypePackAfterTypeParam", result_type="NonTypePackAfterTypeParam<int, 1>", + result_children=[ValueCheck(name="f", type="int")]) + + self.expect_expr("emptyAnonNonTypePackAfterNonTypeParam", result_type="AnonNonTypePackAfterNonTypeParam<1>", + result_children=[ValueCheck(name="g", type="int")]) + self.expect_expr("oneElemAnonNonTypePackAfterNonTypeParam", result_type="AnonNonTypePackAfterNonTypeParam<1, 2>", + result_children=[ValueCheck(name="g", type="int")]) + + + self.expect_expr("emptyAnonNonTypePackAfterAnonNonTypeParam", result_type="AnonNonTypePackAfterAnonNonTypeParam<1>", + result_children=[ValueCheck(name="h", type="float")]) + self.expect_expr("oneElemAnonNonTypePackAfterAnonNonTypeParam", result_type="AnonNonTypePackAfterAnonNonTypeParam<1, 2>", + result_children=[ValueCheck(name="h", type="float")]) + + + self.expect_expr("emptyNonTypePackAfterAnonNonTypeParam", result_type="NonTypePackAfterAnonNonTypeParam<1>", + result_children=[ValueCheck(name="i", type="int")]) + self.expect_expr("oneElemNonTypePackAfterAnonNonTypeParam", result_type="NonTypePackAfterAnonNonTypeParam<1, 2>", + result_children=[ValueCheck(name="i", type="int")]) + + + self.expect_expr("emptyNonTypePackAfterNonTypeParam", result_type="NonTypePackAfterNonTypeParam<1>", + result_children=[ValueCheck(name="j", type="int")]) + self.expect_expr("oneElemNonTypePackAfterNonTypeParam", result_type="NonTypePackAfterNonTypeParam<1, 2>", + result_children=[ValueCheck(name="j", type="int")]) \ No newline at end of file Index: lldb/test/API/lang/cpp/class-template-non-type-parameter-pack/Makefile =================================================================== --- /dev/null +++ lldb/test/API/lang/cpp/class-template-non-type-parameter-pack/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h =================================================================== --- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -332,10 +332,11 @@ class TemplateParameterInfos { public: bool IsValid() const { - if (args.empty()) + // Having a pack name but no packed args doesn't make sense, so mark + // these template parameters as invalid. + if (pack_name && !packed_args) return false; return args.size() == names.size() && - ((bool)pack_name == (bool)packed_args) && (!packed_args || !packed_args->packed_args); } Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -1944,8 +1944,6 @@ break; } } - if (template_param_infos.args.empty()) - return false; return template_param_infos.args.size() == template_param_infos.names.size(); }
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits