Studying note of GCC-3.4.6 source (97)

5.12.3.2.1.1.2.1.    Build self reference

At line 2082, routine build_self_reference builds a dummy reference to itself so Derived::Base (and A::A) works, according to ISO-IEC-14882-2003:

“The class-name is also inserted into the scope of the class itself. For purposes of access checking, the inserted class name is treated as if it were a public member name."

 

6290 void

6291 build_self_reference (void)                                                                         in class.c

6292 {

6293   tree name = constructor_name (current_class_type);

6294   tree value = build_lang_decl (TYPE_DECL, name, current_class_type);

6295   tree saved_cas;

6296

6297   DECL_NONLOCAL (value) = 1;

6298   DECL_CONTEXT (value) = current_class_type;

6299   DECL_ARTIFICIAL (value) = 1;

6300   SET_DECL_SELF_REFERENCE_P (value);

6301

6302   if (processing_template_decl)

6303     value = push_template_decl (value);

6304

6305   saved_cas = current_access_specifier;

6306   current_access_specifier = access_public_node;

6307   finish_member_declaration (value);

6308   current_access_specifier = saved_cas;

6309 }

 

It is responsibilty of constructor_name to fetch the correct name for the class. It must give consideration to name of template specialization.

 

1792 tree

1793 constructor_name (tree type)                                                               in name-lookup.c

1794 {

1795   tree name;

1796   name = constructor_name_full (type);

1797   if (IDENTIFIER_TEMPLATE (name))

1798     name = IDENTIFIER_TEMPLATE (name);

1799   return name;

1800 }

 

Here we give name “SingleThreaded” to the class, constructor_name_full faithfully returns that identifier node for us.

 

1777 tree

1778 constructor_name_full (tree type)                                                         in name-lookup.c

1779 {

1780   type = TYPE_MAIN_VARIANT (type);

1781   if (CLASS_TYPE_P (type) && TYPE_WAS_ANONYMOUS (type)

1782       && TYPE_HAS_CONSTRUCTOR (type))

1783     return DECL_NAME (OVL_CURRENT (CLASSTYPE_CONSTRUCTORS (type)));

1784   else

1785     return TYPE_IDENTIFIER (type);

1786 }

 

See that it assumes public access for the self reference at line 6306 above, and then it can push this reference as class member. Notice that argument decl contains a node of lang_specific allocated by build_lang_decl, which makes DECL_LANG_SPECIFIC return non-null. And its DECL_CONTEXT field indicates the binding scope it declared. Here it contains itself at line 6298.

5.12.3.2.1.1.2.2.    Create TEMPLATE_DECL for self reference

Being a template class, in build_self_reference at line 6302, processing_template_parms is non-zero which indicates template declaration is not finish.

 

3048 tree

3049 push_template_decl (tree decl)                                                                           in pt.c

3050 {

3051   return push_template_decl_real (decl, 0);

3052 }

 

When entering push_template_decl_real this time, ctx fetched below is the RECORD_TYPE of the class template, which is set as the context of the TYPE_DECL here in build_self_reference. Also now current_binding_level refers to the scope of the class, so primary below is zero.

 

2770 tree

2771 push_template_decl_real (tree decl, int is_friend)                                                in pt.c

2772 {

2773   tree tmpl;

2774   tree args;

2775   tree info;

2776   tree ctx;

2777   int primary;

2778   int is_partial;

2779   int new_template_p = 0;

2780

2781   /* See if this is a partial specialization.  */

2782   is_partial = (DECL_IMPLICIT_TYPEDEF_P (decl)

2783        && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE

2784        && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)));

2785

2786   is_friend |= (TREE_CODE (decl) == FUNCTION_DECL && DECL_FRIEND_P (decl));

2787

2788   if (is_friend)

2789     /* For a friend, we want the context of the friend function, not

2790       the type of which it is a friend.  */

2791     ctx = DECL_CONTEXT (decl);

2792   else if (CP_DECL_CONTEXT (decl)

2793         && TREE_CODE (CP_DECL_CONTEXT (decl)) != NAMESPACE_DECL)

2794     /* In the case of a virtual function, we want the class in which

2795       it is defined.  */

2796     ctx = CP_DECL_CONTEXT (decl);

2797   else

2798     /* Otherwise, if we're currently defining some class, the DECL

2799       is assumed to be a member of the class.  */

2800    ctx = current_scope ();

2801

2802   if (ctx && TREE_CODE (ctx) == NAMESPACE_DECL)

2803     ctx = NULL_TREE;

2804

2805   if (!DECL_CONTEXT (decl))

2806     DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);

2807

2808   /* See if this is a primary template.  */

2809   primary = template_parm_scope_p ();

2810

2811   if (primary)

2812   {

        

2852   }

2853

2854   /* Check to see that the rules regarding the use of default

2855     arguments are not being violated.  */

2856   check_default_tmpl_args (decl, current_template_parms,

2857                        primary, is_partial);

2858

2859   if (is_partial)

2860     return process_partial_specialization (decl);

2861

2862   args = current_template_args ();

2863

2864   if (!ctx

2865       || TREE_CODE (ctx) == FUNCTION_DECL

2866       || (CLASS_TYPE_P (ctx) && TYPE_BEING_DEFINED (ctx))

2867       || (is_friend && !DECL_TEMPLATE_INFO (decl)))

2868   {

2869     if (DECL_LANG_SPECIFIC (decl)

2870          && DECL_TEMPLATE_INFO (decl)

2871         && DECL_TI_TEMPLATE (decl))

2872       tmpl = DECL_TI_TEMPLATE (decl);

2873     /* If DECL is a TYPE_DECL for a class-template, then there won't

2874       be DECL_LANG_SPECIFIC. The information equivalent to

2875       DECL_TEMPLATE_INFO is found in TYPE_TEMPLATE_INFO instead.  */

2876     else if (DECL_IMPLICIT_TYPEDEF_P (decl)

2877           && TYPE_TEMPLATE_INFO (TREE_TYPE (decl))

2878           && TYPE_TI_TEMPLATE (TREE_TYPE (decl)))

2879     {

          

2888     }

2889     else

2890     {

2891       tmpl = build_template_decl (decl, current_template_parms);

2892       new_template_p = 1;

2893

2894       if (DECL_LANG_SPECIFIC (decl)

2895          && DECL_TEMPLATE_SPECIALIZATION (decl))

2896       {

            

2902       }

2903     }

2904   }

      

2997   DECL_TEMPLATE_RESULT (tmpl) = decl;

2998   TREE_TYPE (tmpl) = TREE_TYPE (decl);

      

3031   info = tree_cons (tmpl, args, NULL_TREE);

3032

3033   if (DECL_IMPLICIT_TYPEDEF_P (decl))

3034   {

        

3041   }

3042   else if (DECL_LANG_SPECIFIC (decl))

3043     DECL_TEMPLATE_INFO (decl) = info;

3044

3045   return DECL_TEMPLATE_RESULT (tmpl);

3046 }

 

The class is under defining, so above condition at line 2866 is satisfied; but as decl is new created, with DECL_TEMPLATE_INFO and DECL_IMPLICIT_TYPEDEF_P unset, code in ELSE block at line 2889 is executed to create another TEMPLATE_DECL.

 

(Click for open)

Figure 60: create self reference – step 1

5.12.3.2.1.1.2.3.    Insert self reference as member

As last step, it inserts self reference as the class member, the corresponding relation between member and the class will be setup.

 

2089 void

2090 finish_member_declaration (tree decl)                                                         in semantics.c

2091 {

      

2103   /* Set up access control for DECL.  */

2104   TREE_PRIVATE (decl)

2105     = (current_access_specifier == access_private_node);

2106   TREE_PROTECTED (decl)

2107     = (current_access_specifier == access_protected_node);

2108   if (TREE_CODE (decl) == TEMPLATE_DECL)

2109   {

2110     TREE_PRIVATE (DECL_TEMPLATE_RESULT (decl)) = TREE_PRIVATE (decl);

2111     TREE_PROTECTED (DECL_TEMPLATE_RESULT (decl)) = TREE_PROTECTED (decl);

2112   }

2113

2114   /* Mark the DECL as a member of the current class.  */

2115   DECL_CONTEXT (decl) = current_class_type;

2116

2117   /* [dcl.link]

2118

2119      A C language linkage is ignored for the names of class members

2120      and the member function type of class member functions.  */

2121   if (DECL_LANG_SPECIFIC (decl) && DECL_LANGUAGE (decl) == lang_c)

2122     SET_DECL_LANGUAGE (decl, lang_cplusplus);

2123

2124   /* Put functions on the TYPE_METHODS list and everything else on the

2125     TYPE_FIELDS list. Note that these are built up in reverse order.

2126    We reverse them (to obtain declaration order) in finish_struct.  */

2127   if (TREE_CODE (decl) == FUNCTION_DECL

2128       || DECL_FUNCTION_TEMPLATE_P (decl))

2129   {

         

2139   }

2140   /* Enter the DECL into the scope of the class.  */

2141   else if ((TREE_CODE (decl) == USING_DECL && TREE_TYPE (decl))

2142          || pushdecl_class_level (decl))

2143   {

2144     /* All TYPE_DECLs go at the end of TYPE_FIELDS. Ordinary fields

2145       go at the beginning. The reason is that lookup_field_1

2146       searches the list in order, and we want a field name to

2147       override a type name so that the "struct stat hack" will

2148       work. In particular:

2149

2150         struct S { enum E { }; int E } s;

2151         s.E = 3;

2152

2153       is valid. In addition, the FIELD_DECLs must be maintained in

2154       declaration order so that class layout works as expected.

2155       However, we don't need that order until class layout, so we

2156       save a little time by putting FIELD_DECLs on in reverse order

2157       here, and then reversing them in finish_struct_1. (We could

2158       also keep a pointer to the correct insertion points in the

2159       list.)  */

2160

2161     if (TREE_CODE (decl) == TYPE_DECL)

2162       TYPE_FIELDS (current_class_type)

2163           = chainon (TYPE_FIELDS (current_class_type), decl);

2164     else

2165     {

2166       TREE_CHAIN (decl) = TYPE_FIELDS (current_class_type);

2167       TYPE_FIELDS (current_class_type) = decl;

2168     }

2169

2170     maybe_add_class_template_decl_list (current_class_type, decl,

2171                                    /*friend_p=*/0);

2172   }

2173 }

 

Self reference is not a method declaration, nor is using declaration, so it should added as member by pushdecl_class_level at line 2142. Code between line 2748 and 2763 handles anonymous union, which according to ISO-IEC-14882-2003, should obey following rules:

A union of the form

union { member-specification } ;

defines an unnamed object of unnamed type. The member-specification of an anonymous union shall only define non-static data members (nested types and functions cannot be declared within an anonymous union). The names of the members of an anonymous union shall be distinct from the names of any other entity in the scope in which the anonymous union is declared. For the purpose of name lookup, after the anonymous union definition, the members of the anonymous union are considered to have been defined in the scope in which the anonymous union is declared. For example:

void f()

{

union { int a; char* p; };

a = 1;

// ...

p = "Jennifer";

// ...

}

Here a and p are used like ordinary (nonmember) variables, but since they are union members they have the same address.

Anonymous unions declared in a named namespace or in the global namespace shall be declared static. Anonymous unions declared at block scope shall be declared with any storage class allowed for a blockscope variable, or with no storage class. A storage class is not allowed in a declaration of an anonymous union in a class scope. An anonymous union shall not have private or protected members (clause 11). An anonymous union shall not have function members.

 

2729 bool

2730 pushdecl_class_level (tree x)                                                               in name-lookup.c

2731 {

2732   tree name;

2733   bool is_valid = true;

2734

2735   timevar_push (TV_NAME_LOOKUP);

2736   /* Get the name of X.  */

2737   if (TREE_CODE (x) == OVERLOAD)

2738     name = DECL_NAME (get_first_fn (x));

2739   else

2740     name = DECL_NAME (x);

2741

2742   if (name)

2743   {

2744     is_valid = push_class_level_binding (name, x);

2745     if (TREE_CODE (x) == TYPE_DECL)

2746       set_identifier_type_value (name, x);

2747   }

2748   else if (ANON_AGGR_TYPE_P (TREE_TYPE (x)))

2749   {

        

2763   }

2764   timevar_pop (TV_NAME_LOOKUP);

2765

2766   return is_valid;

2767 }

 

By below function, we try to add declaration x of name name into current class scope. Here x and name come from TYPE_DECL of the self reference.

 

2772 bool

2773 push_class_level_binding (tree name, tree x)                                         in name-lookup.c

2774 {

2775   cxx_binding *binding;

2776

2777   timevar_push (TV_NAME_LOOKUP);

2778   /* The class_binding_level will be NULL if x is a template

2779     parameter name in a member template.  */

2780   if (!class_binding_level)

2781     POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);

2782

2783   /* Make sure that this new member does not have the same name

2784     as a template parameter.  */

2785   if (TYPE_BEING_DEFINED (current_class_type))

2786     check_template_shadow (x);

2787

2788   /* [class.mem]

2789

2790      If T is the name of a class, then each of the following shall

2791      have a name different from T:

2792

2793      -- every static data member of class T;

2794

2795      -- every member of class T that is itself a type;

2796

2797      -- every enumerator of every member of class T that is an

2798        enumerated type;

2799

2800      -- every member of every anonymous union that is a member of

2801        class T.

2802

2803      (Non-static data members were also forbidden to have the same

2804      name as T until TC1.)  */

2805   if ((TREE_CODE (x) == VAR_DECL

2806        || TREE_CODE (x) == CONST_DECL

2807        || (TREE_CODE (x) == TYPE_DECL

2808          && !DECL_SELF_REFERENCE_P (x))

2809        || DECL_CLASS_TEMPLATE_P (x)

2810        /* A data member of an anonymous union.  */

2811        || (TREE_CODE (x) == FIELD_DECL

2812          && DECL_CONTEXT (x) != current_class_type))

2813          && DECL_NAME (x) == constructor_name (current_class_type))

2814   {

        

2822   }

 

Being a    template class, the class definition is bound within scope of sk_template_parms (in figure use SingleThreaded as current binding scope, we can see level_chain of the class scope points to sk_template_parms, but names field of sk_template_parms doesn’t include the class definition as usual, which indicates a special relation between template parameter and the class). In scope of sk_template_parms, there live template parameters; of course, if we declare a member of the same name in the class, it will shadow the corresponding template parameter.

Being part of grammar, a template parameter shall not be redeclared within its scope (including nested scopes). Routine check_template_shadow checks for this error.

 

2063 void

2064 check_template_shadow (tree decl)                                                                    in pt.c

2065 {

2066   tree olddecl;

2067

2068   /* If we're not in a template, we can't possibly shadow a template

2069     parameter.  */

2070   if (!current_template_parms)

2071     return;

2072

2073   /* Figure out what we're shadowing.  */

2074   if (TREE_CODE (decl) == OVERLOAD)

2075     decl = OVL_CURRENT (decl);

2076   olddecl = IDENTIFIER_VALUE (DECL_NAME (decl));

2077

2078   /* If there's no previous binding for this name, we're not shadowing

2079     anything, let alone a template parameter.  */

2080   if (!olddecl)

2081     return;

2082

2083  /* If we're not shadowing a template parameter, we're done. Note

2084     that OLDDECL might be an OVERLOAD (or perhaps even an

2085     ERROR_MARK), so we can't just blithely assume it to be a _DECL

2086     node.  */

2087   if (!DECL_P (olddecl) || !DECL_TEMPLATE_PARM_P (olddecl))

2088     return;

2089

2090  /* We check for decl != olddecl to avoid bogus errors for using a

2091     name inside a class. We check TPFI to avoid duplicate errors for

2092     inline member templates.  */

2093   if (decl == olddecl

2094       || TEMPLATE_PARMS_FOR_INLINE (current_template_parms))

2095     return;

2096

2097   cp_error_at ("declaration of `%#D'", decl);

2098   cp_error_at (" shadows template parm `%#D'", olddecl);

2099 }

 

Here the identifier node of the class still hasn’t its bindings field set, IDENTIFIER_VALUE at line 2076 returns NULL as result.

 

push_class_level_binding (continue)

 

2824   /* If this declaration shadows a declaration from an enclosing

2825     class, then we will need to restore IDENTIFIER_CLASS_VALUE when

2826     we leave this class. Record the shadowed declaration here.  */

2827   binding = IDENTIFIER_BINDING (name);

2828   if (binding && binding->value)

2829   {

        

2878   }

2879

2880   /* If we didn't replace an existing binding, put the binding on the

2881     stack of bindings for the identifier, and update the shadowed list.  */

2882   if (push_class_binding (name, x))

2883   {

2884     class_binding_level->class_shadowed

2885               = tree_cons (name, NULL,

2886                         class_binding_level->class_shadowed);

2887     /* Record the value we are binding NAME to so that we can know

2888       what to pop later.  */

2889     TREE_TYPE (class_binding_level->class_shadowed) = x;

2890     POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);

2891   }

2892

2893   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);

2894 }

 

As IDENTIFIER_VALUE returns NULL here, it then jumps to execute push_class_binding at line 2882 above.

 

2657 int

2658 push_class_binding (tree id, tree decl)                                                         in name-lookup.c

2659 {

2660   int result = 1;

2661   cxx_binding *binding = IDENTIFIER_BINDING (id);

2662   tree context;

2663

2664   timevar_push (TV_NAME_LOOKUP);

2665   /* Note that we declared this value so that we can issue an error if

2666     this is an invalid redeclaration of a name already used for some

2667     other purpose.  */

2668   note_name_declared_in_class (id, decl);

2669

2670   if (binding && binding->scope == class_binding_level)

2671     /* Supplement the existing binding.  */

2672     result = supplement_binding (IDENTIFIER_BINDING (id), decl);

2673   else

2674     /* Create a new binding.  */

2675     push_binding (id, decl, class_binding_level);

 

For every cached entity, it needs check that it is valid declaration. For every class, there is a splay tree associated to record names used within the class.

 

6415 void

6416 note_name_declared_in_class (tree name, tree decl)                                      in class.c

6417 {

6418   splay_tree names_used;

6419   splay_tree_node n;

6420

6421   /* Look to see if we ever used this name.  */

6422   names_used

6423     = current_class_stack[current_class_depth - 1].names_used;

6424   if (!names_used)

6425     return;

6426

6427   n = splay_tree_lookup (names_used, (splay_tree_key) name);

6428   if (n)

6429   {

6430     /* [basic.scope.class]

6431  

6432       A name N used in a class S shall refer to the same declaration

6433       in its context and when re-evaluated in the completed scope of

6434       S.  */

6435     error ("declaration of `%#D'", decl);

6436     cp_error_at ("changes meaning of `%D' from `%+#D'",

6437                DECL_NAME (OVL_CURRENT (decl)),

6438                (tree) n->value);

6439   }

6440 }

 

Above names_used slot of current_class_stack is the root of splay tree for every class definition to record fields’ declarations. For inserting new field, we need ensure the same namse is not used before by above routine. [3] gives an example:

typedef int c;

enum { i = 1 };

class X {

char v[i]; // error: i refers to ::i but when reevaluated is X::i

int f() { return sizeof(c); } // OK: X::c

char c;

enum { i = 2 };

};

Above declaration “char v[i]” will be caught by note_name_declared_in_class as error. It is because parsing class member is done in order. If we exchange “char v[i]” and “enum { i=2 }”, the meaning of “char v[i]” changes, for which [3] claims ill-formed. But for class inline method, its analysis is done after pasing the closing “};” of class declaration. So above method “f()” is not affected.

And condition at line 2670 checks the redeclaration. For new declaration, a cxx_binding object records the binding information.

 

358  static void

359  push_binding (tree id, tree decl, cxx_scope* level)                                in name-lookup.c

360  {

361    cxx_binding *binding = cxx_binding_make (decl, NULL);

362 

363    /* Now, fill in the binding information.  */

364    binding->previous = IDENTIFIER_BINDING (id);

365    binding->scope = level;

366    INHERITED_VALUE_BINDING_P (binding) = 0;

367    LOCAL_BINDING_P (binding) = (level != class_binding_level);

368 

369    /* And put it on the front of the list of bindings for ID.  */

370    IDENTIFIER_BINDING (id) = binding;

371  }

 

Field IDENTIFIER_CLASS_VALUE is a tree_list if no empty and records all members declared within the class. However, value field of the cxx_binding created in push_binding is empty (because it is not an overload method), so code below just does nothing but returns result of 1.

 

push_class_binding (continue)

 

2677   /* Update the IDENTIFIER_CLASS_VALUE for this ID to be the

2678     class-level declaration. Note that we do not use DECL here

2679     because of the possibility of the `struct stat' hack; if DECL is

2680     a class-name or enum-name we might prefer a field-name, or some

2681     such.  */

2682   IDENTIFIER_CLASS_VALUE (id) = IDENTIFIER_BINDING (id)->value;

2683

2684   /* If this is a binding from a base class, mark it as such.  */

2685   binding = IDENTIFIER_BINDING (id);

2686   if (binding->value == decl && TREE_CODE (decl) != TREE_LIST)

2687   {

2688     if (TREE_CODE (decl) == OVERLOAD)

2689       context = CP_DECL_CONTEXT (OVL_CURRENT (decl));

2690     else

2691     {

2692       my_friendly_assert (DECL_P (decl), 0);

2693       context = context_for_name_lookup (decl);

2694     }

2695

2696     if (is_properly_derived_from (current_class_type, context))

2697       INHERITED_VALUE_BINDING_P (binding) = 1;

2698     else

2699       INHERITED_VALUE_BINDING_P (binding) = 0;

2700   }

2701   else if (binding->value == decl)

2702     /* We only encounter a TREE_LIST when push_class_decls detects an

2703       ambiguity. Such an ambiguity can be overridden by a definition

2704       in this class.  */

2705     INHERITED_VALUE_BINDING_P (binding) = 1;

2706

2707   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result);

2708 }

 

As push_class_binding returns 1 at line 2882 in push_class_level_binding, this member is chained into class_shadowed list which caches members of current classs. And the function returns true as success.

When returns back pushdecl_class_level at line 2744, variable x is a TYPE_DECL (refer to build_lang_decl in build_self_reference), further bindings are built by set_identifier_type_value. At this step, the type field of the identifier node is updated to point to the RECORD_TYPE of the class, and at the same time the original value of the type field (global_type_node) is cached in type_shadowed field of the corresponding cxx_binding node.

 

(Click for open)

Figure 61: create self reference – step 2

Note the revisions of the IDENTIFIER_NODE and the cxx_scope object of “SingleThreaded” are coordinated. After pushdecl_class_level returns 1 to finish_member_declaration, self reference is chained into the end of the field declaration chain of the class (e.g., values field of RECORD_TYPE). Further maybe_add_class_template_decl_list is executed. For class templates, CLASSTYPE_DECL_LIST is a tree_list of all member data, functions, types, and friends in the order of declaration. The TREE_PURPOSE of each tree_list is NULL_TREE for a friend, and the RECORD_TYPE for the class template otherwise.

 

2583 void

2584 maybe_add_class_template_decl_list (tree type, tree t, int friend_p)               in class.c

2585 {

2586   /* Save some memory by not creating TREE_LIST if TYPE is not template.  */

2587   if (CLASSTYPE_TEMPLATE_INFO (type))

2588     CLASSTYPE_DECL_LIST (type)

2589       = tree_cons (friend_p ? NULL_TREE : type,

2590                  t, CLASSTYPE_DECL_LIST (type));

2591 }

 

(Click for open)

Figure 62: create self reference – step 3

你可能感兴趣的:(Studying note of GCC-3.4.6 source (97))