Issue 090112.1: Support C++0x template aliases

Author: Kendrick Wong
Champion: Kendrick Wong
Date submitted: 2009-01-12
Date revised:
Date closed:
Type: Enhancement
Status: Accepted
DWARF Version: 4
Background
----------

For detail description of the feature, please refer to:
http://www.research.att.com/~bs/C++0xFAQ.html#template-alias
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf 

Overview
--------

The motivation behind this feature is to allow a shorthand notation 
to create a template base on another template, and optionally have 
zero or more template arguments specified. The keyword *using* is 
introduced to allow this behavior.

template<class T>
using Vec = std::vector<T,My_alloc<T>>;    // alias declaration:
                                           // standard vector using my allocator

Vec<int> fib = { 1, 2, 3, 5, 8, 13 };      // allocates elements using My_alloc 
vector<int,My_alloc<int>> verbose = fib;   // verbose and fib are of the same type

In the above example, fib is a template alias of vector<int,My_alloc<int>>, 
therefore both fib and verbose have identical types.

The using keywords acts like similar to typedef, in that both keywords 
introduces a typedef-name.

Proposed change to DWARF
========================

New DWARF tag:
DW_TAG_template_alias   0x42  template alias

Allowable attributes: (modeled after DW_TAG_typedef)
    * DECL
    * DW_AT_abstract_origin
    * DW_AT_accessibility
    * DW_AT_allocated
    * DW_AT_assocated
    * DW_AT_data_location
    * DW_AT_declaration
    * DW_AT_description
    * DW_AT_name
    * DW_AT_sibling
    * DW_AT_start_scope
    * DW_AT_type
    * DW_AT_visibility

5.17: Template Alias Entries

  Any arbitrary type named via template alias is represented by a 
  debugging information entry with the tag DW_TAG_template_alias. 
  The template alias entry has a DW_AT_name attribute whose value 
  is a null-terminated string containing the name of the template 
  alias as it appears in the source program. The template alias entry 
  also contains a DW_AT_type attribute. The template alias entry will 
  have the following child entries:

   1. Each formal parameterized type declaration appearing in the 
      template alias declaration is represented by a debugging 
      information entry with the tag DW_TAG_template_type_parameter. 
      Each such entry may have a DW_AT_name attribute, whose value is 
      a null-terminated string containing the name of the formal 
      type parameter as it appears in the source program. The template 
      type parameter entry also has a DW_AT_type attribute describing 
      the actual type by which the formal is replaced for this instantiation.

   2. Each formal parameterized value declaration appearing in the 
      template alias declaration is represented by a debugging information 
      entry with the tag DW_TAG_template_value_parameter. Each such entry 
      may have a DW_AT_name attribute, whose value is a null-terminated 
      string containing the name of the formal value parameter as it appears 
      in the source program. The template value parameter entry also has a 
      DW_AT_type attribute describing the type of the parameterized value. 
      Finally, the template value parameter entry has a DW_AT_const_value 
      attribute, whose value is the actual constant value of the value 
      parameter for this instantiation as represented on the target 
      architecture.

Appendix

D.10.1 Template Aliases example

First, no aliases at all. This is just plain old ordinary template instance DWARF:

template<typename T, typename U>
struct Alpha {
   T tango;
   U uniform;
};

There's no DWARF for just that. But now we have an instance like this:

Alpha<int,short>  a;

DWARF for variable 'a':

10$:  DW_TAG_structure_type
          DW_AT_name "Alpha"
11$:      DW_TAG_template_type_parameter
              DW_AT_name("T")
              DW_AT_type(reference to type "int")
12$:      DW_TAG_template_type_parameter
              DW_AT_name("U")
              DW_AT_type(reference to type "short")
13$:      DW_TAG_member
              DW_AT_name("tango")
              DW_AT_type(reference to 11$)
14$:      DW_TAG_member
              DW_AT_name("uniform")
              DW_AT_type(reference to 12$)
15$:  DW_TAG_variable
          DW_AT_name("a")
          DW_AT_type(reference to $10)

Now to introduce the first template alias:

template<typename V> using Beta = Alpha<V,V>;

Again, no DWARF for just that. But now there's an instance like this:

Beta<long> b;

DWARF for variable 'b':

20$:  DW_TAG_structure_type
          DW_AT_name "Alpha"
21$:      DW_TAG_template_type_parameter
              DW_AT_name("T")
              DW_AT_type(reference to type "long")
22$:      DW_TAG_template_type_parameter
              DW_AT_name("U")
              DW_AT_type(reference to type "long")
23$:      DW_TAG_member
              DW_AT_name("tango")
              DW_AT_type(reference to 21$)
24$:      DW_TAG_member
              DW_AT_name("uniform")
              DW_AT_type(reference to 22$)
25$:  DW_TAG_template_alias
          DW_AT_name("Beta")
          DW_AT_type(reference to 20$)
26$:      DW_TAG_template_type_parameter
              DW_AT_name("V")
              DW_AT_type(reference to "long")
27$:  DW_TAG_variable
          DW_AT_name("b")
          DW_AT_type(reference to 25$)

D.10.2 Template Aliases example

template<class TX> struct X { };
template<class TY> struct Y { };
template<class T> using Z = Y<T>;
X<Y<int>> y;
X<Z<int>> z;
X<Y<int>> instantiates the following structures:

30$:  DW_TAG_structure_type                         // struct Y<int>
          DW_AT_name("Y")
31$:      DW_TAG_template_type_parameter
              DW_AT_name("TY")
              DW_AT_type(reference to base type "int")
32$:  DW_TAG_structure_type                         // struct X<Y<int>>
          DW_AT_name("X")
33$:      DW_TAG_template_type_parameter
              DW_AT_name("TX")
              DW_AT_type(reference to 30$)

X<Z<int>> instantiates the following structures:

40$:  DW_TAG_template_alias                         // template<class T> using Z = Y<int>;
          DW_AT_name("Z")
          DW_AT_type(reference to 30$)
41$:      DW_TAG_template_type_parameter
              DW_AT_name("T")
              DW_AT_type(reference to base type "int")
42$:  DW_TAG_structure_type                         // struct X<Z<int>>
          DW_AT_name("X")
43$:      DW_TAG_template_type_parameter
              DW_AT_name("TX")
              DW_AT_type(reference to 40$)

Note that $32 and $42 are actually the same type:

50$:  DW_TAG_variable             
          DW_AT_name("y")
          DW_AT_type(reference to $32)
51$:  DW_TAG_variable             
          DW_AT_name("z")
          DW_AT_type(reference to $42)

 
Change History

April 20, 2009.

    * Re-format DWARF description in Example section to match current documentation.

May 5, 2009.

    * Todd Allen suggests a simpler example to illustrate template alias.
    * Todd Allen made a suggestion that the template type parameter within the 
      structure/class can point directly to the template type parameter within 
      the template alias declaration.
    * Todd Allen suggests using a different TAG for describing template alias.

June 2, 2009.

    * Remove mentioning of template parameter pack
    * Remove mentioning of C++0x within normative text

--

August 11, 2009 -- Accepted without changes.