Studying note of GCC-3.4.6 source (90)
2010-08-24 12:06
423 查看
5.12.3.1.1. Parse template type parameter
The function first tries type parameter.
7654 static tree
7655 cp_parser_template_parameter (cp_parser* parser) in parser.c
7656 {
7657 cp_token *token;
7658
7659 /* Peek at the next token. */
7660 token = cp_lexer_peek_token (parser->lexer);
…
7677 if (token->keyword == RID_TYPENAME || token->keyword == RID_CLASS)
7678 {
7679 /* Peek at the token after `class' or `typename'. */
7680 token = cp_lexer_peek_nth_token (parser->lexer, 2);
7681 /* If it's an identifier, skip it. */
7682 if (token->type == CPP_NAME)
7683 token = cp_lexer_peek_nth_token (parser->lexer, 3);
7684 /* Now, see if the token looks like the end of a template
7685 parameter. */
7686 if (token->type == CPP_COMMA
7687 || token->type == CPP_EQ
7688 || token->type == CPP_GREATER)
7689 return cp_parser_type_parameter (parser);
7690 }
…
7703 }
When seeing “<class Host>”, parser now knows it’s the type parameter as “Host” is followed by “>”; it enters cp_parser_type_parameter at line 7689 above.
7720 static tree
7721 cp_parser_type_parameter (cp_parser* parser) in parser.c
7722 {
7723 cp_token *token;
7724 tree parameter;
7725
7726 /* Look for a keyword to tell us what kind of parameter this is. */
7727 token = cp_parser_require (parser, CPP_KEYWORD,
7728 "`class', `typename', or `template'");
7729 if (!token)
7730 return error_mark_node;
7731
7732 switch (token->keyword)
7733 {
7734 case RID_CLASS:
7735 case RID_TYPENAME:
7736 {
7737 tree identifier;
7738 tree default_argument;
7739
7740 /* If the next token is an identifier, then it names the
7741 parameter. */
7742 if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
7743 identifier = cp_parser_identifier (parser);
7744 else
7745 identifier = NULL_TREE;
7746
7747 /* Create the parameter. */
7748 parameter = finish_template_type_parm (class_type_node , identifier);
7749
7750 /* If the next token is an `=', we have a default argument. */
7751 if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
7752 {
7753 /* Consume the `=' token. */
7754 cp_lexer_consume_token (parser->lexer);
7755 /* Parse the default-argument. */
7756 default_argument = cp_parser_type_id (parser);
7757 }
7758 else
7759 default_argument = NULL_TREE;
7760
7761 /* Create the combined representation of the parameter and the
7762 default argument. */
7763 parameter = build_tree_list (default_argument, parameter);
7764 }
7765 break ;
7766
7767 case RID_TEMPLATE:
7768 {
...
7842 }
7843 break ;
7844
7845 default:
7846 abort ();
7847 break ;
7848 }
7849
7850 return parameter;
7851 }
As identifier for the template parameter is recognized, a tree node should be created for it, which is a node of tree_list .
1928 tree
1929 finish_template_type_parm (tree aggr, tree identifier) in sematics.c
1930 {
1931 if (aggr != class_type_node )
1932 {
1933 pedwarn ("template type parameters must use the keyword `class' or `typename'");
1934 aggr = class_type_node ;
1935 }
1936
1937 return build_tree_list (aggr, identifier);
1938 }
The generated template parameter will take following look (it hasn’t default argument).
Figure 48 : layout of template parameter of “Host”
The function first tries type parameter.
7654 static tree
7655 cp_parser_template_parameter (cp_parser* parser) in parser.c
7656 {
7657 cp_token *token;
7658
7659 /* Peek at the next token. */
7660 token = cp_lexer_peek_token (parser->lexer);
…
7677 if (token->keyword == RID_TYPENAME || token->keyword == RID_CLASS)
7678 {
7679 /* Peek at the token after `class' or `typename'. */
7680 token = cp_lexer_peek_nth_token (parser->lexer, 2);
7681 /* If it's an identifier, skip it. */
7682 if (token->type == CPP_NAME)
7683 token = cp_lexer_peek_nth_token (parser->lexer, 3);
7684 /* Now, see if the token looks like the end of a template
7685 parameter. */
7686 if (token->type == CPP_COMMA
7687 || token->type == CPP_EQ
7688 || token->type == CPP_GREATER)
7689 return cp_parser_type_parameter (parser);
7690 }
…
7703 }
When seeing “<class Host>”, parser now knows it’s the type parameter as “Host” is followed by “>”; it enters cp_parser_type_parameter at line 7689 above.
7720 static tree
7721 cp_parser_type_parameter (cp_parser* parser) in parser.c
7722 {
7723 cp_token *token;
7724 tree parameter;
7725
7726 /* Look for a keyword to tell us what kind of parameter this is. */
7727 token = cp_parser_require (parser, CPP_KEYWORD,
7728 "`class', `typename', or `template'");
7729 if (!token)
7730 return error_mark_node;
7731
7732 switch (token->keyword)
7733 {
7734 case RID_CLASS:
7735 case RID_TYPENAME:
7736 {
7737 tree identifier;
7738 tree default_argument;
7739
7740 /* If the next token is an identifier, then it names the
7741 parameter. */
7742 if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
7743 identifier = cp_parser_identifier (parser);
7744 else
7745 identifier = NULL_TREE;
7746
7747 /* Create the parameter. */
7748 parameter = finish_template_type_parm (class_type_node , identifier);
7749
7750 /* If the next token is an `=', we have a default argument. */
7751 if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
7752 {
7753 /* Consume the `=' token. */
7754 cp_lexer_consume_token (parser->lexer);
7755 /* Parse the default-argument. */
7756 default_argument = cp_parser_type_id (parser);
7757 }
7758 else
7759 default_argument = NULL_TREE;
7760
7761 /* Create the combined representation of the parameter and the
7762 default argument. */
7763 parameter = build_tree_list (default_argument, parameter);
7764 }
7765 break ;
7766
7767 case RID_TEMPLATE:
7768 {
...
7842 }
7843 break ;
7844
7845 default:
7846 abort ();
7847 break ;
7848 }
7849
7850 return parameter;
7851 }
As identifier for the template parameter is recognized, a tree node should be created for it, which is a node of tree_list .
1928 tree
1929 finish_template_type_parm (tree aggr, tree identifier) in sematics.c
1930 {
1931 if (aggr != class_type_node )
1932 {
1933 pedwarn ("template type parameters must use the keyword `class' or `typename'");
1934 aggr = class_type_node ;
1935 }
1936
1937 return build_tree_list (aggr, identifier);
1938 }
The generated template parameter will take following look (it hasn’t default argument).
Figure 48 : layout of template parameter of “Host”
相关文章推荐
- Studying note of GCC-3.4.6 source (30)
- Studying note of GCC-3.4.6 source (168)
- Studying note of GCC-3.4.6 source (43)
- Studying note of GCC-3.4.6 source (46)
- Studying note of GCC-3.4.6 source (75)
- Studying note of GCC-3.4.6 source (82)
- Studying note of GCC-3.4.6 source (87)
- Studying note of GCC-3.4.6 source (91)
- Studying note of GCC-3.4.6 source (95)
- Studying note of GCC-3.4.6 source (107)
- Studying note of GCC-3.4.6 source (120)
- Studying note of GCC-3.4.6 source (136)
- Studying note of GCC-3.4.6 source (3)
- Studying note of GCC-3.4.6 source (12)
- Studying note of GCC-3.4.6 source (142 - continue)
- Studying note of GCC-3.4.6 source (18)
- Studying note of GCC-3.4.6 source (154)
- Studying note of GCC-3.4.6 source (166)
- Studying note of GCC-3.4.6 source (36)
- Studying note of GCC-3.4.6 source (37)