Issue 131105.1: C++11 ref-qualifiers on non-static member functions

Author: Adrian Prantl
Champion: Adrian Prantl
Date submitted: 2013-11-05
Date revised:
Date closed:
Type: Enhancement
Status: Accepted
DWARF Version: 5
Section 3, pg 
C++11 adds a feature that allows putting ref-qualifiers (&, &&) on
non-static member functions. It's like putting a const qualifier on a
method, except it limits the kinds of value you can call the method on
(&: only on l-values; &&: on either pr-values or x-values).

For example::
  struct A {
    void foo() &;
    void bar() &;
    void bar() &&;
  };

It is important to encode this in DWARF, because it affects overload
resolution and the name mangling for the functions.

To encode const-volatile qualifiers of non-static member functions,
clang currently uses the type of the artificial "this" argument. This
aligns with the C++11 spec (section 9.3.2):
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf

  "In the body of a non-static (9.3) member function, the keyword this
   is a prvalue expression whose value is the address of the object
   for which the function is called. The type of this in a member
   function of a class X is X*. If the member function is declared
   const, the type of this is const X*, if the member function is
   declared volatile, the type of this is volatile X*, and if the
   member function is declared const volatile, the type of this is
   const volatile X*."

In contrast to cv-modifiers it does not make sense to wrap the type of
"this" in a DW_TAG_reference_type (or DW_TAG_rvalue_reference_type)
because a ref-qualifier does not actually change the type of "this"
into a reference.

We suggest to add a DW_AT_reference_qualifier /
DW_AT_rvalue_reference_qualifier attribute to the DW_TAG_subprogram
describing the member function.

Changes
=======

Table 2.2: Attribute names
--------------------------
DW_AT_reference        | &-qualified non-static member function
DW_AT_rvalue_reference | &&-qualified non-static member function


5.7.7 Member Function Entries
-----------------------------
[ORIGINAL TEXT]
If the member function entry describes a non-static member function
that has a const-volatile qualification, then the entry describes a
non-static member function whose object formal parameter has a type
that has an equivalent const-volatile qualification.

[REPLACE WITH]
*In C++, non-static member functions can have const-volatile
 qualifiers, which affect the type of the first formal parameter (the
 "this"-pointer).*

If the member function entry describes a non-static member function
that has a const-volatile qualification, then the entry describes a
non-static member function whose object formal parameter has a type
that has an equivalent const-volatile qualification.

*In C++11, non-static member functions can also have one of the
 ref-qualifiers, & and &&. They do not change the type of the
 "this"-pointer, but they affect the types of object values the
 function can be invoked on.*

The member function entry may have an DW_AT_reference attribute to
indicate a non-static member function that can only be called on
l-value objects, or the attribute DW_AT_rvalue_reference to indicate
that it can only be called on pr-values and x-values.

5.10: Subroutine Type Entries
-----------------------------
*C++ const-volatile qualifiers are encoded as part of the type of the
 "this"-pointer. C++11 rvalue-reference qualifiers are stored using
 the DW_AT_reference / DW_AT_rvalue_reference attributes. See also
 Section 5.7.7.*

A subroutine type entry may have the DW_AT_reference or
DW_AT_rvalue_reference attribute to indicate that it describes the
type of a member function with (rvalue) reference semantics.

Table 7.3: Data representation
------------------------------
DW_AT_reference        | 0x77 | flag
DW_AT_rvalue_reference | 0x78 | flag



Table 7.26: Attributes used in type signature computation
---------------------------------------------------------
DW_AT_reference
DW_AT_rvalue_reference



A. Attributes by TAG
---------------------
DW_TAG_subprogram      | DW_AT_reference
                         DW_AT_rvalue_reference
DW_TAG_subroutine_type | DW_AT_reference
                         DW_AT_rvalue_reference


Section D.4, Member Function Example
-----------------------------------

The following example shows how to encode qualifiers for C++11::
   
  class A {
  public:
    void f() const &&;
  };
   
  void g() {
    A a;
    // The type of pointer_to_member_function is "void (A::*)() const &&".
    auto pointer_to_member_function = &A::f;
  }

The DWARF type information for this example looks as follows::

            DW_TAG_subprogram
                DW_AT_name( "g" )
               
                DW_TAG_variable
                    DW_AT_name( "a" )
                    DW_AT_type( {ref to A} )
             
                DW_TAG_variable
                    DW_AT_name( "pointer_to_member_function" )
                    DW_AT_type( {ref to mfptr} )
              
  A:        DW_TAG_class_type
               DW_AT_name( "A" )
              
               DW_TAG_subprogram
                   DW_AT_name( "f" )
                   DW_AT_rvalue_reference( 0x01 )
              
                   DW_TAG_formal_parameter
                       DW_AT_type( {ref to const A*} )
                       DW_AT_artificial( 0x01 )
             
  const A*: DW_TAG_pointer_type
                DW_AT_type( {ref to const A} )
   
  const A:  DW_TAG_const_type
                DW_AT_type( {ref to A} )
   
  mfptr:    DW_TAG_ptr_to_member_type
                DW_AT_type( {ref to functype} )
                DW_AT_containing_type( {ref to A} )
   
  functype: DW_TAG_subroutine_type
                DW_AT_rvalue_reference( 0x01 )
   
                DW_TAG_formal_parameter
                    DW_AT_type( {ref to const A*} )
                    DW_AT_artificial( 0x01 )


---
Updated - 12/16/2013
Accepted - 12/17/2013
Updated example - 12/19/2013