Studying note of GCC-3.4.6 source (94)

来源:互联网 发布:何时统一台湾 知乎 编辑:程序博客网 时间:2024/05/17 06:13

5.12.3.2.1.1.1.3.    Create TEMPLATE_DECL for the class

As it is a class template, it needs a node of TEMPLATE_DECL to describe the characteristics of the template. Now it’s going to create this node.

 

pushtag (continue)

 

4656       d = maybe_process_template_type_declaration (type,

4657                                              globalize, b);

 

Currently, processing_template_decl is non-zero as we are processing the class template. But processing_template_parmlist is zero as template parameters have been processed. Notice that argument type refers to the node of RECORD_TYPE of the class.

 

4525 static tree

4526 maybe_process_template_type_declaration (tree type, int globalize,         in name-lookup.c

4527                                     cxx_scope *b)

4528 {

4529   tree decl = TYPE_NAME (type);

4530

4531   if (processing_template_parmlist)

4532     /* You can't declare a new template type in a template parameter

4533       list. But, you can declare a non-template type:

4534

4535         template <class A*> struct S;

4536

4537       is a forward-declaration of `A'.  */

4538     ;

4539   else

4540   {

4541     my_friendly_assert (IS_AGGR_TYPE (type)

4542                     || TREE_CODE (type) == ENUMERAL_TYPE, 0);

4543

4544     if (processing_template_decl)

4545     {

4546       /* This may change after the call to

4547         push_template_decl_real, but we want the original value.  */

4548       tree name = DECL_NAME (decl);

4549

4550       decl = push_template_decl_real (decl, globalize);

4551       /* If the current binding level is the binding level for the

4552         template parameters (see the comment in

4553         begin_template_parm_list) and the enclosing level is a class

4554         scope, and we're not looking at a friend, push the

4555         declaration of the member class into the class scope.  In the

4556         friend case, push_template_decl will already have put the

4557         friend into global scope, if appropriate.  */

4558       if (TREE_CODE (type) != ENUMERAL_TYPE

4559         && !globalize && b->kind == sk_template_parms

4560         && b->level_chain->kind == sk_class)

4561       {

            

4577       }

4578     }

4579   }

4580

4581   return decl;

4582 }

 

Besides the nodes we have seen in the intermediate tree, extra nodes are needed for template declaration. Template introduces concept of instantion, specializaiton, partial specialization, new nodes will be created to record the relation among these concepts.

 

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 ();

 

Like other declaration, before handling, it first needs to find out the scope it declared. Here CP_DECL_CONTEXT in fact invokes DECL_CONTEXT. For this example, DECL_CONTEXT is the namespace of “Loki” which has been set at line 4652 in pushtag. Then ctx is set as NULL at line 2800.

 

1512 bool

1513 template_parm_scope_p (void)                                                            in name-lookup.c

1514 {

1515   return innermost_scope_kind () == sk_template_parms;

1516 }

 

Notice that current_binding_level refers to sk_template_parms.

 

1504 scope_kind

1505 innermost_scope_kind (void)                                                                      in name-lookup.c

1506 {

1507   return current_binding_level->kind;

1508 }

 

Template declaration not of partial specialization or full specialization is called primary declaration. Routine template_parm_scope_p discriminates these declarations by checking the closest enclosing scope. For our example, this scope is sk_template_parms, primary will be nonzero.

 

push_template_decl_real (continue)

 

2811   if (primary)

2812   {

2813     if (current_lang_name == lang_name_c)

2814       error ("template with C linkage");

2815     else if (TREE_CODE (decl) == TYPE_DECL

2816           && ANON_AGGRNAME_P (DECL_NAME (decl)))

2817       error ("template class without a name");

2818     else if (TREE_CODE (decl) == FUNCTION_DECL)

2819     {

          

2843     }

2844     else if (DECL_IMPLICIT_TYPEDEF_P (decl)

2845           && CLASS_TYPE_P (TREE_TYPE (decl)))

2846       /* OK */;

2847     else

2848     {

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

2850       return error_mark_node;

2851     }

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 ();

 

Above check_default_tmpl_args does nothing as we are still within the template declaration (in fact definition). As described in section Parse template type parameter, current_template_parms holds the applicable template parameters for the template declaration; and for nested template declaration, the innermost parameters will appear at the head of the list referred by the variable.

 

2297 tree

2298 current_template_args (void)                                                                             in pt.c

2299 {

2300   tree header;

2301   tree args = NULL_TREE;

2302   int length = TMPL_PARMS_DEPTH (current_template_parms);

2303   int l = length;

2304

2305   /* If there is only one level of template parameters, we do not

2306     create a TREE_VEC of TREE_VECs. Instead, we return a single

2307     TREE_VEC containing the arguments.  */

2308   if (length > 1)

2309     args = make_tree_vec (length);

2310

2311   for (header = current_template_parms; header; header = TREE_CHAIN (header))

2312   {

2313     tree a = copy_node (TREE_VALUE (header));

2314     int i;

2315

2316     TREE_TYPE (a) = NULL_TREE;

2317     for (i = TREE_VEC_LENGTH (a) - 1; i >= 0; --i)

2318     {

2319       tree t = TREE_VEC_ELT (a, i);

2320

2321       /* T will be a list if we are called from within a

2322         begin/end_template_parm_list pair, but a vector directly

2323         if within a begin/end_member_template_processing pair.  */

2324       if (TREE_CODE (t) == TREE_LIST)

2325       {

2326         t = TREE_VALUE (t);

2327        

2328         if (TREE_CODE (t) == TYPE_DECL

2329            || TREE_CODE (t) == TEMPLATE_DECL)

2330           t = TREE_TYPE (t);

2331         else

2332           t = DECL_INITIAL (t);

2333         TREE_VEC_ELT (a, i) = t;

2334       }

2335     }

2336

2337     if (length > 1)

2338       TREE_VEC_ELT (args, --l) = a;

2339     else

2340       args = a;

2341   }

2342

2343   return args;

2344 }

 

If takes example in figure layout of nested template parameters, TMPL_PARMS_DEPTH at line 2302 returns value stored at purpose field, and current_template_args will return args as following figure. See parameters just are returned in more packed form and by reversed order with outermost argument at head. Variable current_template_parms promises the correctness.

53

Figure 53: parameters returned by current_template_args

Continue with the funciton, here ctx as we see above, is NULL (it is set to NULL at line 2800 above), and condition at line 2864 is satisfied.

 

push_template_decl_real (continue)

 

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       {

2897         /* A specialization of a member template of a template

2898           class.  */

2899         SET_DECL_TEMPLATE_SPECIALIZATION (tmpl);

2900         DECL_TEMPLATE_INFO (tmpl) = DECL_TEMPLATE_INFO (decl);

2901         DECL_TEMPLATE_INFO (decl) = NULL_TREE;

2902       }

2903     }

2904   }

 

Being template in defining, both fields TYPE_TEMPLATE_INFO and TYPE_TI_TEMPLATE of the RECORD_TYPE node are NULL. It goes to create tree node for the template declaration.

 

2349 static tree

2350 build_template_decl (tree decl, tree parms)                                                                in pt.c

2351 {

2352   tree tmpl = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), NULL_TREE);

2353   DECL_TEMPLATE_PARMS (tmpl) = parms;

2354   DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl);

2355   if (DECL_LANG_SPECIFIC (decl))

2356   {

2357     DECL_STATIC_FUNCTION_P (tmpl) = DECL_STATIC_FUNCTION_P (decl);

2358     DECL_CONSTRUCTOR_P (tmpl) = DECL_CONSTRUCTOR_P (decl);

2359     DECL_DESTRUCTOR_P (tmpl) = DECL_DESTRUCTOR_P (decl);

2360     DECL_NONCONVERTING_P (tmpl) = DECL_NONCONVERTING_P (decl);

2361     DECL_ASSIGNMENT_OPERATOR_P (tmpl) = DECL_ASSIGNMENT_OPERATOR_P (decl);

2362     if (DECL_OVERLOADED_OPERATOR_P (decl))

2363       SET_OVERLOADED_OPERATOR_CODE (tmpl,

2364                                   DECL_OVERLOADED_OPERATOR_P (decl));

2365   }

2366

2367   return tmpl;

2368 }

 

Here argument decl is created by build_decl, which has slot lang_specific with NULL. So code enclosed in IF block at line 2355 is skipped. And code of IF block at line 2894 in push_template_decl_real is also skipped too.

In front-end, there are lots of macros defined to access vary fields of template related tree nodes. These macros are used widely across the source code. For convience for reading, below figure illustrates the path and field the specified macro accesses.

54

原创粉丝点击