Studying note of GCC-3.4.6 source (124)
来源:互联网 发布:淘宝代理数据包下载 编辑:程序博客网 时间:2024/05/01 23:38
5.12.4.2.2.2.3. Finish template-id
If template-name is an IDENTIFER_NODE, it maybe a member template;and if it is a TEMPLATE_DECL of class template, the template-id itself is aclass-name; and if it is FUNCTION_DECL, OVERLOAD or METHOD_DECL, thetemplate-id is a function-name.
So if template-name is a class template, the template-id may name anew class, for which case we should create corresponding class type by finish_template_type.It is a very complex procedure, later section will give an example to gothrough the function.
cp_parser_template_id (continue)
7991 /*Build a representation of the specialization. */
7992 if (TREE_CODE (template) ==IDENTIFIER_NODE)
7993 template_id = build_min_nt (TEMPLATE_ID_EXPR, template, arguments);
7994 else if(DECL_CLASS_TEMPLATE_P (template)
7995 ||DECL_TEMPLATE_TEMPLATE_PARM_P (template))
7996 template_id
7997 = finish_template_type (template, arguments,
7998 cp_lexer_next_token_is (parser->lexer,
7999 CPP_SCOPE));
8000 else
8001 {
8002 /*If it's not a class-template or a template-template, it should be
8003 a function-template. */
8004 my_friendly_assert((DECL_FUNCTION_TEMPLATE_P (template)
8005 ||TREE_CODE (template) == OVERLOAD
8006 ||BASELINK_P (template)),
8007 20010716);
8008
8009 template_id = lookup_template_function (template,arguments);
8010 }
8011
8012 /*Retrieve any deferred checks. Do not pop this access checks yet
8013 so thememory will not be reclaimed during token replacing below. */
8014 access_check =get_deferred_access_checks ();
If template-name is an IDNETIFIER_NODE, the resultingTEMPLATE_ID_EXPR is built by build_min_nt. The function builds a tree nodeof tree_exp.
4069 tree
4070 build_min_nt (enumtree_code code, ...) intree.c
4071 {
4072 tree t;
4073 int length;
4074 int i;
4075 va_list p;
4076
4077 va_start (p, code);
4078
4079 t= make_node(code);
4080 length = TREE_CODE_LENGTH (code);
4081 TREE_COMPLEXITY (t) = input_line;
4082
4083 for (i = 0; i< length; i++)
4084 {
4085 tree x = va_arg (p, tree);
4086 TREE_OPERAND (t, i) = x;
4087 }
4088
4089 va_end (p);
4090 return t;
4091 }
If the template-name names a function template, the TEMPLATE_ID_EXPRnode is created by lookup_template_function. A BASELINK node is a reference to a memberfunction or member functions from a base class. Note that in this case in theTEMPLATE_ID_EXPR generated, its type is unknonw_type_node, which will force the front-endto invoke instantiate_typelater to resolve its type.
4069 tree
4070 lookup_template_function (tree fns, tree arglist) inpt.c
4071 {
4072 tree type;
4073
4074 if (fns == error_mark_node || arglist ==error_mark_node)
4075 returnerror_mark_node;
4076
4077 my_friendly_assert (!arglist || TREE_CODE(arglist) == TREE_VEC, 20030726);
4078 my_friendly_assert (fns && (is_overloaded_fn (fns)
4079 || TREE_CODE (fns) ==IDENTIFIER_NODE),
4080 20050608);
4081
4082 if (BASELINK_P (fns))
4083 {
4084 BASELINK_FUNCTIONS (fns) = build(TEMPLATE_ID_EXPR,
4085 unknown_type_node,
4086 BASELINK_FUNCTIONS(fns),
4087 arglist);
4088 return fns;
4089 }
4090
4091 type = TREE_TYPE (fns);
4092 if (TREE_CODE (fns) == OVERLOAD || !type)
4093 type = unknown_type_node;
4094
4095 return build (TEMPLATE_ID_EXPR, type, fns, arglist);
4096 }
Then corresponding tokens are grouped as CPP_TEMPLATE_ID; similarlythere is another group - NESTED_NAME_SPECFIER.
cp_parser_template_id (continue)
8016 /* If parsingtentatively, replace the sequence of tokens that makes
8017 up thetemplate-id with a CPP_TEMPLATE_ID token. That way,
8018 should were-parse the token stream, we will not have to repeat
8019 the effortrequired to do the parse, nor will we issue duplicate
8020 error messagesabout problems during instantiation of the
8021 template. */
8022 if (start_of_id >= 0)
8023 {
8024 cp_token *token;
8025
8026 /* Find the tokenthat corresponds to the start of the
8027 template-id. */
8028 token = cp_lexer_advance_token(parser->lexer,
8029 parser->lexer->first_token,
8030 start_of_id);
8031
8032 /* Reset thecontents of the START_OF_ID token. */
8033 token->type = CPP_TEMPLATE_ID;
8034 token->value = build_tree_list(access_check, template_id);
8035 token->keyword = RID_MAX;
8036 /* Purge allsubsequent tokens. */
8037 cp_lexer_purge_tokens_after(parser->lexer, token);
8038
8039 /* ??? Can weactually assume that, if template_id ==
8040 error_mark_node, we will have issued adiagnostic to the
8041 user, asopposed to simply marking the tentative parse as
8042 failed? */
8043 if (cp_parser_error_occurred (parser)&& template_id != error_mark_node)
8044 error ("parse error in templateargument list");
8045 }
8046
8047 pop_deferring_access_checks();
8048 returntemplate_id;
8049 }
5.12.4.2.2.3. Finish lookup class name
When get decl for the identifier, as indicated by the grammar, it mustbe an identifier or template-id. If argument typename_p is true, it meanskeyword typenamehas been seen. So invoke make_typename_type to resolve “typenameCONTEXT::NAME" and return appropriate type.
cp_parser_class_name (continue)
11812 decl = cp_parser_maybe_treat_template_as_class(decl, class_head_p);
11813
11814 /* If this is a typename, create aTYPENAME_TYPE. */
11815 if (typename_p &&decl != error_mark_node)
11816 {
11817 decl = make_typename_type (scope, decl, /*complain=*/1);
11818 if (decl !=error_mark_node)
11819 decl = TYPE_NAME (decl);
11820 }
11821
11822 /*Check to see that it is really the name of a class. */
11823 if (TREE_CODE (decl) ==TEMPLATE_ID_EXPR
11824 && TREE_CODE(TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE
11825 &&cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
11826 /*Situations like this:
11827
11828 template <typename T> struct A {
11829 typename T::template X<int>::I i;
11830 };
11831
11832 are problematic. Is `T::templateX<int>' a class-name? The
11833 standard does not seem to be definitive,but there is no other
11834 valid interpretation of the following`::'. Therefore, those
11835 names are considered class-names. */
11836 decl = TYPE_NAME (make_typename_type (scope, decl, tf_error));
11837 else if (decl ==error_mark_node
11838 || TREE_CODE (decl) !=TYPE_DECL
11839 || !IS_AGGR_TYPE (TREE_TYPE (decl)))
11840 {
11841 cp_parser_error (parser,"expected class-name");
11842 returnerror_mark_node;
11843 }
11844
11845 returndecl;
11846 }
Refer to maybe_get_template_decl_from_type_declthat invoked in cp_parser_template_id, it can betterunderstand cp_parser_maybe_treat_template_as_class.Argument tag_name_pif true, declindicates the class being defined in a class-head, or declared in an elaborated-type-specifier.
13901 static tree
13902 cp_parser_maybe_treat_template_as_class (tree decl, bool tag_name_p) in parser.c
13903 {
13904 /*If the TEMPLATE_DECL is being declared as part of a class-head,
13905 thetranslation from TEMPLATE_DECL to TYPE_DECL occurs:
13906
13907 struct A {
13908 template <typename T> struct B;
13909 };
13910
13911 template <typename T> struct A::B {};
13912
13913 Similarly, in a elaborated-type-specifier:
13914
13915 namespace N { struct X{}; }
13916
13917 struct A {
13918 template <typename T> friend struct N::X;
13919 };
13920
13921 However, if the DECL refers to a class type, and we are in
13922 thescope of the class, then the name lookup automatically
13923 findsthe TYPE_DECL created by build_self_reference rather
13924 than aTEMPLATE_DECL. For example, in:
13925
13926 template <class T> struct S {
13927 Ss;
13928 };
13929
13930 thereis no need to handle such case. */
13931
13932 if (DECL_CLASS_TEMPLATE_P(decl) && tag_name_p)
13933 returnDECL_TEMPLATE_RESULT (decl);
13934
13935 returndecl;
13936 }
The effect of the routine is if decl isa TEMPLATE_DECL that can be treated like a TYPE_DECL in the current context,returns the TYPE_DECL.
Below if name is a template class (by CLASSTYPE_IS_TEMPLATE) or a template instantiation or specialization (by CLASSTYPE_USE_TEMPLATE), a TMEPLATE_ID_EXPR is built. Its processinginvolves lookup_template_classwhich is a complex function and we will see it later with example.
2608 tree
2609 make_typename_type (tree context, treename, tsubst_flags_t complain) in decl.c
2610 {
2611 tree fullname;
2612
2613 if (name == error_mark_node
2614 || context == NULL_TREE
2615 || context == error_mark_node)
2616 returnerror_mark_node;
2617
2618 if (TYPE_P (name))
2619 {
2620 if (!(TYPE_LANG_SPECIFIC (name)
2621 && (CLASSTYPE_IS_TEMPLATE(name)
2622 || CLASSTYPE_USE_TEMPLATE (name))))
2623 name= TYPE_IDENTIFIER (name);
2624 else
2625 /* Create a TEMPLATE_ID_EXPR for the type. */
2626 name= build_nt (TEMPLATE_ID_EXPR,
2627 CLASSTYPE_TI_TEMPLATE(name),
2628 CLASSTYPE_TI_ARGS (name));
2629 }
2630 else if (TREE_CODE (name) == TYPE_DECL)
2631 name = DECL_NAME (name);
2632
2633 fullname = name;
2634
2635 if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
2636 {
2637 name = TREE_OPERAND (name, 0);
2638 if (TREE_CODE (name) == TEMPLATE_DECL)
2639 name= TREE_OPERAND (fullname, 0) = DECL_NAME (name);
2640 }
2641 if (TREE_CODE (name) == TEMPLATE_DECL)
2642 {
2643 error ("`%D' used without templateparameters", name);
2644 returnerror_mark_node;
2645 }
2646 my_friendly_assert (TREE_CODE (name) ==IDENTIFIER_NODE, 20030802);
2647 my_friendly_assert (TYPE_P (context),20050905);
2648
2649 if (!dependent_type_p(context)
2650 ||currently_open_class (context))
2651 {
2652 if (TREE_CODE (fullname) ==TEMPLATE_ID_EXPR)
2653 {
2654 tree tmpl = NULL_TREE;
2655 if (IS_AGGR_TYPE (context))
2656 tmpl = lookup_field(context, name, 0, false);
2657 if (!tmpl || !DECL_CLASS_TEMPLATE_P(tmpl))
2658 {
2659 if (complain & tf_error)
2660 error ("no class template named `%#T' in`%#T'",
2661 name, context);
2662 returnerror_mark_node;
2663 }
2664
2665 if (complain & tf_error)
2666 perform_or_defer_access_check(TYPE_BINFO (context), tmpl);
2667
2668 return lookup_template_class (tmpl,
2669 TREE_OPERAND (fullname, 1),
2670 NULL_TREE, context,
2671 /*entering_scope=*/0,
2672 tf_error | tf_warning| tf_user);
2673 }
2674 else
2675 {
2676 tree t;
2677
2678 if(!IS_AGGR_TYPE (context))
2679 {
2680 if (complain & tf_error)
2681 error ("no type named `%#T' in`%#T'", name, context);
2682 returnerror_mark_node;
2683 }
2684
2685 t =lookup_field (context, name, 0, true);
2686 if(t)
2687 {
2688 if (TREE_CODE (t) != TYPE_DECL)
2689 {
2690 if (complain & tf_error)
2691 error ("no type named `%#T' in`%#T'", name, context);
2692 returnerror_mark_node;
2693 }
2694
2695 if (complain & tf_error)
2696 perform_or_defer_access_check(TYPE_BINFO (context), t);
2697
2698 if (DECL_ARTIFICIAL (t) || !(complain &tf_keep_type_decl))
2699 t = TREE_TYPE (t);
2700
2701 returnt;
2702 }
2703 }
2704 }
2705
2706 /* If the CONTEXTis not a template type, then either the field is
2707 there now or itsnever going to be. */
2708 if (!dependent_type_p(context))
2709 {
2710 if (complain & tf_error)
2711 error ("no type named `%#T' in `%#T'",name, context);
2712 returnerror_mark_node;
2713 }
2714
2715 return build_typename_type (context, name, fullname);
2716 }
And for expression “typenameCONTEXT::NAME”, if CONTEXT is non-dependent, or is currently opened class, NAMEis first looked up within the class by lookup_field.
1372 tree
1373 lookup_field(tree xbasetype, tree name, int protect, bool want_type) in search.c
1374 {
1375 tree rval = lookup_member(xbasetype, name, protect, want_type);
1376
1377 /* Ignorefunctions. */
1378 if (rval && BASELINK_P (rval))
1379 returnNULL_TREE;
1380
1381 return rval;
1382 }
See that argument want_typein invocation at line 2656 is false for template-id; and invocation at line2685 is true for normal type. And want_type is true, indicates we only acceptTYPE_DECL.
If nothing found and the scope isdependent, it must build a placeholder for the type. It is the node of TYPENAME_TYPE.
2566 static tree
2567 build_typename_type (tree context, tree name, tree fullname) in decl.c
2568 {
2569 tree t;
2570 tree d;
2571 void **e;
2572
2573 if (typename_htab == NULL)
2574 {
2575 typename_htab = htab_create_ggc(61, &typename_hash,
2576 &typename_compare,NULL);
2577 }
2578
2579 /*Build the TYPENAME_TYPE. */
2580 t = make_aggr_type(TYPENAME_TYPE);
2581 TYPE_CONTEXT (t) = FROB_CONTEXT (context);
2582 TYPENAME_TYPE_FULLNAME (t) =fullname;
2583
2584 /*Build the corresponding TYPE_DECL. */
2585 d = build_decl(TYPE_DECL, name, t);
2586 TYPE_NAME (TREE_TYPE (d)) =d;
2587 TYPE_STUB_DECL (TREE_TYPE(d)) = d;
2588 DECL_CONTEXT (d) =FROB_CONTEXT (context);
2589 DECL_ARTIFICIAL (d) = 1;
2590
2591 /*See if we already have this type. */
2592 e = htab_find_slot (typename_htab,t, INSERT);
2593 if (*e)
2594 t = (tree) *e;
2595 else
2596 *e = t;
2597
2598 returnt;
2599 }
Node of TYPENAME_TYPE represents structure “typenameT::t”. In the node, its TYPE_CONTEXT is `T', TYPE_NAME is an IDENTIFIER_NODEfor `t'. If the type was named via template-id, TYPENAME_TYPE_FULLNAME willhold the TEMPLATE_ID_EXPR.
Note that handling “typename T::t”here, ‘T’ has been resolved in previous step, it may be a template or templateparameter, and with a subtree already built. So in fact “typename T::t” underdifferent context ‘T’ stands for different structure. To ensure unique instanceof such structure within the translation-unit, these nodes are stored withinthe hashtable of typename_htab.
- Studying note of GCC-3.4.6 source (124)
- Studying note of GCC-3.4.6 source (6)
- Studying note of GCC-3.4.6 source (1)
- Studying note of GCC-3.4.6 source (2)
- Studying note of GCC-3.4.6 source (3)
- Studying note of GCC-3.4.6 source (4)
- Studying note of GCC-3.4.6 source (5)
- Studying note of GCC-3.4.6 source (7)
- Studying note of GCC-3.4.6 source (8)
- Studying note of GCC-3.4.6 source (9)
- Studying note of GCC-3.4.6 source (10)
- Studying note of GCC-3.4.6 source (10 cont1)
- Studying note of GCC-3.4.6 source (10 cont2)
- Studying note of GCC-3.4.6 source (10 cont3)
- Studying note of GCC-3.4.6 source (10 cont4)
- Studying note of GCC-3.4.6 source (11)
- Studying note of GCC-3.4.6 source (12)
- Studying note of GCC-3.4.6 source (13)
- GCC-3.4.6源代码学习笔记(124)
- ORACLE数据存储空间的管理
- uboot的一些简单应用
- Reflection——利用反射调用构造函数和私有字段
- DataReader与Dataset有什么区别?
- Studying note of GCC-3.4.6 source (124)
- 最好玩儿的补字符方法,以VB为例
- 类加载器
- ASP.NET Web DataList控件介绍
- 自定义命名空间使用技巧之——命名空间与XML
- 腾讯反360秘密会议
- 测试
- C#多线程函数如何传参数和返回值
- 程序员的无线互联创业陷阱