DWARF Debugging Standard Wiki |
---|
For detail description of the feature, please refer to:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2087.pdf
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2080.pdf
In the June 2 DWARF meeting, four proposals were presented for voting:
DW_TAG_template_parameter_pack
/DW_TAG_formal_parameter_pack
is
used as marker.DW_TAG_template_type_parameter
DIEs children of
DW_TAG_template_parameter_pack
. And make DW_TAG_formal_parameter
DIEs children of DW_TAG_formal_parameter_pack
.DW_TAG_template_parameter_pack
/DW_TAG_formal_parameter_pack
DIE
and add references to
DW_TAG_template_type_parameter
/DW_TAG_formal_parameter
respectively.The consensus is to reject the proposal and wait for a vendor to produce the information first. We can revisit the vendor implementation at a later time and re-evaluate the proposal then.
C++0x will allow function and class templates to take an arbitrary number of arguments. The motivation behind this language extension is to allow TR1 facilities such as tuple to accept variable number of parameters.
template<typename... Elements> class tuple;
tuple<int, long> tuple_int_long; // Elements is a template type parameter pack
// containing 2 arguments, int and long type
tuple<float> tuple_float; // Elements is a template type parameter pack
containing 1 argument: float type
template<typename T, unsigned PrimaryDimension, unsigned... Dimensions> class array;
array<double, 3, 3> t1; // Dimensions is a template value parameter pack
// containing a single argument: unsigned int 3.
array<double, 3, 3, 4, 5> t2; // Dimensions is a template value parameter pack
// containing three arguments: unsigned int 3, 4 and 5.
template<typename... Args> void eat(Args... args);
// The eat() function is a variadic template with template parameter pack Args.
// The ellipsis to the left of the identifier args indicates that args is a
// function parameter pack.
Purpose
New DWARF tag
DW_TAG_template_parameter_pack 0x43 template parameters pack
Allowable attributes:
DW_TAG_formal_parameter_pack 0x44 function parameters pack
Allowable attributes:
3.3.7: Function Template Instantiations
4. Each template parameter pack declaration appearing in the template
definition is represented by a debugging information entry with the tag
DW_TAG_template_parameter_pack
. Each such entry may have a
DW_AT_name
attribute, whose value is a null-terminated string
containing the name of the template parameter pack as it appears in the
source program.
5. Each argument within the template parameter pack is represented by a
debugging information entry with the tag
DW_TAG_template_type_parameter
. These entries are children of the
debugging information entry with the tag
DW_TAG_template_parameter_pack
. Each such entry does not have a
DW_AT_name
attribute. Each such entry has a DW_AT_type
attribute
describing the actual type by which the formal is replaced for this
instantiation.
6. Each function parameter pack declaration appearing in the template
definition is represented by a debugging information entry with the tag
DW_TAG_formal_parameter_pack
. Each such entry may have a DW_AT_name
attribute, whose value is a null-terminated string containing the name
of the template parameter pack as it appears in the source program.
7. Each argument within the function parameter pack is represented by a
debugging information entry with the tag DW_TAG_formal_parameter
.
These entries are children of the debugging information entry with the
tag DW_TAG_formal_parameter_pack
. Each such entry does not have a
DW_AT_name
attribute. Each such entry has a DW_AT_type
attribute
describing the actual type by which the formal is replaced for this
instantiation.
5.6.8: Class Template Instantiations
Each template parameter pack declaration appearing in the template
definition is represented by a debugging information entry with the tag
DW_TAG_template_parameter_pack
. Each such entry may have a
DW_AT_name
attribute, whose value is a null-terminated string
containing the name of the template parameter pack as it appears in the
source program.
If the template parameter pack entry represent a template value
parameter pack, it may contain a DW_AT_type
attribute to denote the
type of the arguments within the template value parameter pack.
Each argument within the template parameter pack can have one of the
tags DW_TAG_template_type_parameter
or
DW_TAG_template_value_parameter
, and will have same form as other
template parameter entries. These entries are children of the debugging
information entry with the tag DW_TAG_template_parameter_pack
. Each
such entry does not have a DW_AT_name
attribute. Each such entry has a
DW_AT_type
attribute describing the actual type by which the formal is
replaced for this instantiation.
D.8 Variadic Templates Examples
D.8.1 Function Template Instantiations
/* Base case for printf */
void printf(const char* s) {
while (*s) {
std::cout << *s++;
}
}
template<typename T, typename... PackTypes>
void printf(const char* s, T value, PackTypes... args) {
while (*s) {
if (*s == '%' && *++s != '%') {
std::cout << value;
return printf (++s, args...);
}
std::cout << *s++;
}
}
int x;
printf<int, char, int> ("%c %d", x, 'x', 3);
The base case for printf is not a template instantiation:
printf (const char* s);
1$: DW_TAG_subprogram
DW_AT_name("printf")
2$: DW_TAG_formal_parameter
DW_AT_name("s")
DW_AT_type(reference to type "const char*")
<pre>
Compiler may instantiate these 3 functions:
# printf<int,char,int> (const char* s, int value, char, int); // args => char, int
# printf<char,int> (const char* s, char value, int); // args => int
# printf<int> (const char* s, int value); // args => (empty)
<pre>
1) printf<int,char,int> (const char* s, int value, char, int); // args => char, int
10$: DW_TAG_subprogram
DW_AT_name("printf")
11$: DW_TAG_template_type_parameter
DW_AT_name("T")
DW_AT_type(reference to base type "int")
12$: DW_TAG_template_parameter_pack
DW_AT_name("PackTypes")
13$: DW_TAG_template_type_parameter
! no DW_AT_name attribute
DW_AT_type(reference to base type "char")
14$: DW_TAG_template_type_parameter
! no DW_AT_name attribute
DW_AT_type(reference to base type "int")
15$: DW_TAG_formal_parameter
DW_AT_name("s")
DW_AT_type(reference to type "const char*")
16$: DW_TAG_formal_parameter
DW_AT_name("value")
DW_AT_type(reference to 11$)
17$: DW_TAG_formal_parameter_pack
DW_AT_name("args")
18$: DW_TAG_formal_parameter
! no DW_AT_name attribute
DW_AT_type(reference to 13$)
19$: DW_TAG_formal_parameter
! no DW_AT_name attribute
DW_AT_type(reference to 14$)
2) printf<char,int> (const char* s, char value, int); // args => int
20$: DW_TAG_subprogram
DW_AT_name("printf")
21$: DW_TAG_template_type_parameter
DW_AT_name("T")
DW_AT_type(reference to base type "int")
22$: DW_TAG_template_parameter_pack
DW_AT_name("PackTypes")
23$: DW_TAG_template_type_parameter
! no DW_AT_name attribute
DW_AT_type(reference to base type "int")
24$: DW_TAG_formal_parameter
DW_AT_name("s")
DW_AT_type(reference to type "const char*")
25$: DW_TAG_formal_parameter
DW_AT_name("value")
DW_AT_type(reference to 21$)
26$: DW_TAG_formal_parameter_pack
DW_AT_name("args")
27$: DW_TAG_formal_parameter
! no DW_AT_name attribute
DW_AT_type(reference to 23$)
3) printf<int> (const char* s, int value); // args => (empty)
30$: DW_TAG_subprogram
DW_AT_name("printf")
31$: DW_TAG_template_type_parameter
DW_AT_name("T")
DW_AT_type(reference to base type "int")
32$: DW_TAG_template_parameter_pack
DW_AT_name("PackTypes")
33$: DW_TAG_formal_parameter
DW_AT_name("s")
DW_AT_type(reference to type "const char*")
34$: DW_TAG_formal_parameter
DW_AT_name("value")
DW_AT_type(reference to 31$)
35$: DW_TAG_formal_parameter_pack
DW_AT_name("args")
D.8.2 Class Template Instantiations
/* Template definition for counting number of template type arguments */
template<typename... PackTypes> struct count;
/* Full specialization for zero argument */
template <>
struct count<> {
static const int value = 0;
};
/* Partial specialization for peeling off the first argument */
template<typename T, typename... PackTypes>
struct count<T, PackTypes...> {
static const int value = 1 + count<PackTypes...>::value;
};
/* Template instantiation */
count<char, short, int> a;
The base case template:
1$: DW_TAG_structure_type
DW_AT_name("count")
2$: DW_TAG_member
DW_AT_name("value")
DW_AT_declaration(yes)
DW_AT_type(reference to type "const int")
3$: DW_TAG_variable
DW_AT_specification(reference to 2$)
DW_AT_location(...)
Compiler may instantiate these 3 types:
1) count<char, short, int> // PackTypes => short, int
11$: DW_TAG_structure_type
DW_AT_name("count")
12$: DW_TAG_template_type_parameter
DW_AT_name("T")
DW_AT_type(reference to base type "char")
13$: DW_TAG_template_parameter_pack
DW_AT_name("PackTypes")
14$: DW_TAG_template_type_parameter
DW_AT_type(reference to base type "short")
15$: DW_TAG_template_type_parameter
DW_AT_type(reference to base type "int")
16$: DW_TAG_member
DW_AT_name("value")
DW_AT_declaration(yes)
DW_AT_type(reference to type "const int")
17$: DW_TAG_variable
DW_AT_specification(reference to 16$)
DW_AT_location(...)
2) count<short, int> // PackTypes => int
21$: DW_TAG_structure_type
DW_AT_name("count")
22$: DW_TAG_template_type_parameter
DW_AT_name("T")
DW_AT_type(reference to base type "short")
23$: DW_TAG_template_parameter_pack
DW_AT_name("PackTypes")
24$: DW_TAG_template_type_parameter
DW_AT_type(reference to base type "int")
25$: DW_TAG_member
DW_AT_name("value")
DW_AT_declaration(yes)
DW_AT_type(reference to type "const int")
26$: DW_TAG_variable
DW_AT_specification(reference to 25$)
DW_AT_location(...)
3) count<int> // PackTypes => (empty)
31$: DW_TAG_structure_type
DW_AT_name("count")
32$: DW_TAG_template_type_parameter
DW_AT_name("T")
DW_AT_type(reference to base type "int")
33$: DW_TAG_template_parameter_pack
DW_AT_name("PackTypes")
34$: DW_TAG_member
DW_AT_name("value")
DW_AT_declaration(yes)
DW_AT_type(reference to type "const int")
35$: DW_TAG_variable
DW_AT_specification(reference to 34$)
DW_AT_location(...)
4) count<char, short, int> a;
41$: DW_TAG_variable
DW_AT_name("a")
DW_AT_type(reference to 11$)
DW_AT_location(...)
D.8.3 Multiple template packs in template definition
template <class X,int I>
struct pair {
void showself () {
std::cout << I << std::endl;
X local;
local.showself();
}
};
struct a1 { void showself () { std::cout << "a1" << std::endl; }};
struct a2 { void showself () { std::cout << "a2" << std::endl; }};
template <class headX, int headI, class... restX, int... restI>
void showself (pair<headX, headI> headArg, pair<restX, restI>... restArg) {
headArg.showself();
showself (restArg...);
}
/* Instantiations */
pair<a1,1> t1;
pair<a2,2> t2;
showself(t1,t2);
First the simple structures:
struct a1 { void showself () { std::cout << "a1" << std::endl; }};
11$: DW_TAG_structure_type
DW_AT_name("a1")
12$: DW_TAG_subprogram
DW_AT_name("showself")
DW_AT_type(reference to type "void")
struct a2 { void showself () { std::cout << "a2" << std::endl; }};
21$: DW_TAG_structure_type
DW_AT_name("a2")
22$: DW_TAG_subprogram
DW_AT_name("showself")
DW_AT_type(reference to type "void")
DWARF for ‘pair’ structures:
pair<a1,1> t1;
31$: DW_TAG_structure_type
DW_AT_name("pair")
32$: DW_TAG_template_type_parameter
DW_AT_name("X")
DW_AT_type(reference to 11$)
33$: DW_TAG_template_value_parameter
DW_AT_name("I")
DW_AT_type(reference to base type "int")
DW_AT_const_value(1)
33$: DW_TAG_subprogram
DW_AT_name("showself")
DW_AT_type(reference to type "void")
34$: DW_TAG_variable
DW_AT_name("t1")
DW_AT_type(reference to 31$)
DW_AT_location(...)
pair<a2,2> t2;
41$: DW_TAG_structure_type
DW_AT_name("pair")
42$: DW_TAG_template_type_parameter
DW_AT_name("X")
DW_AT_type(reference to 21$)
43$: DW_TAG_template_value_parameter
DW_AT_name("I")
DW_AT_type(reference to base type "int")
DW_AT_const_value(2)
43$: DW_TAG_subprogram
DW_AT_name("showself")
DW_AT_type(reference to type "void")
44$: DW_TAG_variable
DW_AT_name("t2")
DW_AT_type(reference to 41$)
DW_AT_location(...)
The variadic template function showself():
template <class headX, int headI, class... restX, int... restI>
void showself (pair<headX, headI> headArg, pair<restX, restI>... restArg) {
headArg.showself();
showself (restArg...);
}
showself (pair<struct a1,1>, pair<struct a2,2>):
51$: DW_TAG_subprogram
DW_AT_name("showself")
52$: DW_TAG_template_type_parameter
DW_AT_name("headX")
DW_AT_type(reference to 11$)
53$: DW_TAG_template_value_parameter
DW_AT_name("headI")
DW_AT_type(reference to base type "int")
DW_AT_const_value(1)
54$: DW_TAG_template_parameter_pack
DW_AT_name("restX")
55$: DW_TAG_template_type_parameter
DW_AT_type(reference to 21$)
56$: DW_TAG_template_parameter_pack
DW_AT_name("restI")
DW_AT_type(reference to base type "int")
57$: DW_TAG_template_value_parameter
DW_AT_const_value(2)
58$: DW_TAG_formal_parameter
DW_AT_name("headArg")
DW_AT_type(reference to 31$)
59$: DW_TAG_formal_parameter_pack
DW_AT_name("restArg")
60$: DW_TAG_formal_parameter
! no DW_AT_name attribute
DW_AT_type(reference to 41$)
showself (pair<struct a2,2>):
71$: DW_TAG_subprogram
DW_AT_name("showself")
72$: DW_TAG_template_type_parameter
DW_AT_name("headX")
DW_AT_type(reference to 21$)
73$: DW_TAG_template_value_parameter
DW_AT_name("headI")
DW_AT_type(reference to base type "int")
DW_AT_const_value(2)
74$: DW_TAG_template_parameter_pack
DW_AT_name("restX")
75$: DW_TAG_template_parameter_pack
DW_AT_name("restI")
76$: DW_TAG_formal_parameter
DW_AT_name("headArg")
DW_AT_type(reference to 41$)
77$: DW_TAG_formal_parameter_pack
DW_AT_name("restArg")
March 17, 2009.
DW_AT_parameter_pack
to indicate that a parameter is a part of
template parameter pack.April 13, 2009.
DW_AT_parameter_pack
attributeMay 5, 2009.
DW_TAG_formal_parameter_pack
to indicate the name of the
function parameter pack.DW_TAG_template_type_parameter
are not longer children of
DW_TAG_template_parameter_pack
. This is made so that consumer
don’t need to understand the new TAG, and still be able to process
the other information.June 2, 2009.
September 11, 2009.
DW_TAG_formal_parameter_pack
can
not be used as marker. And for consistency,
DW_TAG_template_parameter_pack
can follow the same behavior as
DW_TAG_formal_parameter_pack
DW_TAG_template_type_parameter
and
DW_TAG_formal_parameter
children of
DW_TAG_template_parameter_pack
and DW_TAG_formal_parameter_pack
respectively.
dwarfstd.org is supported by Sourceware. Contributions are welcome.
All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest © 2007-2022 by DWARF Standards Committee. |