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     }

 

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

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值