GCC-3.4.6源代码学习笔记(90)

5.12.3.1.1.        解析模板类型参数

首先尝试类型参数。

 

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 }

 

当看到 <class Host> ”, 因为 Host 后面只跟着 > ”, 解析器明白这是个类型参数 在上面的 7689 进入 cp_parser_type_parameter

 

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     }

 

因为认出了用于模板参数的标识符 ,一个树节点需要为之创建,这是一个 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     }

 

所产生的模板参数看起来如下图(它没有默认参数)。

GCC-3.4.6源代码学习笔记(90)_第1张图片

48 :模板参数“ Host ”的布局

你可能感兴趣的:(list,tree,Class,Build,Parameters,token)