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

5.12.5.2.2.        函数定义 函数体部分
5.12.5.2.2.1.  准备函数体解析

现在我们在 decl_specifiers 中得到了 return-type-specifier declarator 指向 CALL_EXPR ,而 declares_class_or_enum 0 。记得如果我们正在定义新类型, declares_class_or_enum 2 ,这在 function-definition 中不被允许。

 

cp_parser_init_declarator (continue)

 

9975     /* If the DECLARATOR was erroneous, there's no need to go

9976       further.  */

9977     if (declarator == error_mark_node)

9978       return error_mark_node;

9979  

9980     if (declares_class_or_enum & 2)

9981       cp_parser_check_for_definition_in_return_type

9982            (declarator, TREE_VALUE (decl_specifiers));

9983  

9984     /* Figure out what scope the entity declared by the DECLARATOR is

9985       located in. `grokdeclarator' sometimes changes the scope, so

9986       we compute it now.  */

9987     scope = get_scope_of_declarator (declarator);

9988  

9989     /* If we're allowing GNU extensions, look for an asm-specification

9990       and attributes.  */

9991     if (cp_parser_allow_gnu_extensions_p (parser))

9992     {

9993       /* Look for an asm-specification.  */

9994       asm_specification = cp_parser_asm_specification_opt (parser);

9995        /* And attributes.  */

9996       attributes = cp_parser_attributes_opt (parser);

9997     }

9998     else

9999     {

10000     asm_specification = NULL_TREE;

10001     attributes = NULL_TREE;

10002   }

10003

10004   /* Peek at the next token.  */

10005   token = cp_lexer_peek_token (parser->lexer);

10006   /* Check to see if the token indicates the start of a

10007     function-definition.  */

10008   if (cp_parser_token_starts_function_definition_p (token))

10009   {

10010     if (!function_definition_allowed_p)

10011     {

10012       /* If a function-definition should not appear here, issue an

10013         error message.  */

10014       cp_parser_error (parser,

10015                     "a function-definition is not allowed here");

10016       return error_mark_node;

10017     }

10018     else

10019     {

10020       /* Neither attributes nor an asm-specification are allowed

10021         on a function-definition.  */

10022       if (asm_specification)

10023         error ("an asm-specification is not allowed on a function-definition");

10024       if (attributes)

10025         error ("attributes are not allowed on a function-definition");

10026       /* This is a function-definition.  */

10027       *function_definition_p = true;

10028

10029       /* Parse the function definition.  */

10030       if (member_p)

10031         decl = cp_parser_save_member_function_body (parser,

10032                                                decl_specifiers,

10033                                                 declarator,

10034                                                prefix_attributes);

10035       else

10036         decl

10037            = (cp_parser_function_definition_from_specifiers_and_declarator

10038                 (parser, decl_specifiers, prefix_attributes, declarator));

10039

10040       return decl;

10041     }

10042   }

        …

10197   return decl;

10198 }

 

如果我们在声明符后找到“ { ”,这表示 function-definition 。我们在 10037 行继续。

 

14314 static tree

14315 cp_parser_function_definition_from_specifiers_and_declarator                      in parser.c

14316   (cp_parser* parser,

14317    tree decl_specifiers,

14318    tree attributes,

14319    tree declarator)

14320 {

14321   tree fn;

14322   bool success_p;

14323

14324   /* Begin the function-definition.  */

14325   success_p = begin_function_definition (decl_specifiers,

14326                                   attributes,

14327                                   declarator);

 

首先,我们需要设立用于函数定义的框架,并把它合并入中间树。这个框架对于所有非类绑定的函数定义都是通用的。而每个定义都以自己的方式填充该框架。

 

1897   int

1898   begin_function_definition (tree decl_specs, tree attributes, tree declarator)    in parser.c

1899   {

1900     if (!start_function (decl_specs, declarator, attributes, SF_DEFAULT))

1901       return 0;

1902  

1903     /* The things we're about to see are not directly qualified by any

1904       template headers we've seen thus far.  */

1905     reset_specialization ();

1906  

1907     return 1;

1908   }

 

这里的参数 flags 具有值 SF_DEFAULT ,这表示一个普通的未解析的函数。下面的 have_extern_spec 仅在看到“ extern ”时为 true

 

10181 int

10182 start_function (tree declspecs, tree declarator, tree attrs, int flags)                       in decl.c

10183 {

10184   tree decl1;

10185   tree ctype = NULL_TREE;

10186   tree fntype;

10187   tree restype;

10188   int doing_friend = 0;

10189   struct cp_binding_level *bl;

10190   tree current_function_parms;

10191

10192   /* Sanity check.  */

10193   my_friendly_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE, 160);

10194   my_friendly_assert (TREE_CHAIN (void_list_node) == NULL_TREE, 161);

10195

10196   /* This should only be done once on the top most decl.  */

10197   if (have_extern_spec )

10198   {

10199     declspecs = tree_cons (NULL_TREE, get_identifier ("extern"), declspecs);

10200     have_extern_spec = false;

10201   }

10202

10203   if (flags & SF_PRE_PARSED)

10204   {

          ...

10225   }

10226   else

10227   {

10228     decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs);

 

因为这是未解析的函数, FUNCTION_TYPE FUNCTION_DECL 节点应该被构建,作为容器来保存以中间形式产生的定义。

 

6462   tree

6463   grokdeclarator (tree declarator,                                                                         i n decl.c

6464                tree declspecs,

6465                enum decl_context decl_context,

6466                int initialized,

6467                tree* attrlist)

6468   {

6469     RID_BIT_TYPE specbits;

6470     int nclasses = 0;

6471     tree spec;

6472     tree type = NULL_TREE;

6473     int longlong = 0;

6474     int type_quals;

6475     int virtualp, explicitp, friendp, inlinep, staticp;

6476     int explicit_int = 0;

6477     int explicit_char = 0;

6478     int defaulted_int = 0;

6479     int extern_langp = 0;

6480     tree dependant_name = NULL_TREE;

6481    

6482     tree typedef_decl = NULL_TREE;

6483     const char *name;

6484     tree typedef_type = NULL_TREE;

6485     int funcdef_flag = 0;

6486     enum tree_code innermost_code = ERROR_MARK;

6487     int bitfield = 0;

6488   #if 0

6489     /* See the code below that used this.  */

6490     tree decl_attr = NULL_TREE;

6491   #endif

6492  

6493     /* Keep track of what sort of function is being processed

6494       so that we can warn about default return values, or explicit

6495       return values which do not match prescribed defaults.  */

6496     special_function_kind sfk = sfk_none;

6497  

6498     tree dname = NULL_TREE;

6499     tree ctype = current_class_type ;

6500     tree ctor_return_type = NULL_TREE;

6501     enum overload_flags flags = NO_SPECIAL;

6502     tree quals = NULL_TREE;

6503     tree raises = NULL_TREE;

6504     int template_count = 0;

6505     tree in_namespace = NULL_TREE;

6506     tree returned_attrs = NULL_TREE;

6507     tree scope = NULL_TREE;

6508     tree parms = NULL_TREE;

6509  

6510     RIDBIT_RESET_ALL (specbits);

6511     if (decl_context == FUNCDEF)

6512       funcdef_flag = 1, decl_context = NORMAL;

6513     else if (decl_context == MEMFUNCDEF)

6514       funcdef_flag = -1, decl_context = FIELD;

6515     else if (decl_context == BITFIELD)

6516       bitfield = 1, decl_context = FIELD;

6517  

6518     /* Look inside a declarator for the name being declared

6519       and get it as a string, for an error message.  */

6520     {

6521       tree *next = &declarator;

6522       tree decl;

6523       name = NULL;

6524  

6525       while (next && *next)

6526       {

6527         decl = *next;

6528         switch (TREE_CODE (decl))

6529         {

              ...

6591           case CALL_EXPR:

6592             innermost_code = TREE_CODE (decl);

                ...

6601             next = &TREE_OPERAND (decl, 0);

6602             decl = *next;

                ...

6610             ctype = NULL_TREE;

6611             break ;

              ...

6629           case IDENTIFIER_NODE:

6630             if (TREE_CODE (decl) == IDENTIFIER_NODE)

6631               dname = decl;

6632  

6633             next = 0;

6634  

6635             if (C_IS_RESERVED_WORD (dname))

6636             {

                  ...

6640             }

6641             else if (!IDENTIFIER_TYPENAME_P (dname))

6642               name = IDENTIFIER_POINTER (dname);

6643             else

6644             {

                  ...

6653             }

6654             break ;

              ...

6784         }

6785       }

6786     }

        ...

6844     for (spec = declspecs; spec; spec = TREE_CHAIN (spec))

6845     {

6846       int i;

6847       tree id;

6848  

6849        /* Certain parse errors slip through. For example,

6850         `int class;' is not caught by the parser. Try

6851         weakly to recover here.  */

6852       if (TREE_CODE (spec) != TREE_LIST)

6853         return 0;

6854  

6855       id = TREE_VALUE (spec);

          ...

6947       if (type)

6948         error ("two or more data types in declaration of `%s'", name);

6949       else if (TREE_CODE (id) == IDENTIFIER_NODE)

6950       {

            ...

6960       }

6961       else if (id != error_mark_node)

6962         /* Can't change CLASS nodes into RECORD nodes here!  */

6963         type = id;

6964  

6965   found: ;

6966     }

6967  

6968   #if 0

6969     /* See the code below that used this.  */

6970     if (typedef_decl)

6971       decl_attr = DECL_ATTRIBUTES (typedef_decl);

6972   #endif

6973     typedef_type = type;

        ...

7179     staticp = 0;

7180     inlinep = !! RIDBIT_SETP (RID_INLINE, specbits);

7181     virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits);

7182     RIDBIT_RESET (RID_VIRTUAL, specbits);

7183     explicitp = RIDBIT_SETP (RID_EXPLICIT, specbits) != 0;

7184     RIDBIT_RESET (RID_EXPLICIT, specbits);

 

仅就执行到的代码而言,我们可以看到这第一部分的处理相当简单,在 6963 行, type 指向 integer_type_node ,其类型是 INTEGER_TYPE

 

grokdeclarator (continue)

 

7343     while (declarator && TREE_CODE (declarator) != IDENTIFIER_NODE

7344           && TREE_CODE (declarator) != TEMPLATE_ID_EXPR)

7345     {

          ...

7392       switch (TREE_CODE (declarator))

7393       {

            ...

7432         case CALL_EXPR:

7433         {

7434           tree arg_types;

7435           int funcdecl_p;

7436           tree inner_parms = CALL_DECLARATOR_PARMS (declarator);

7437           tree inner_decl = TREE_OPERAND (declarator, 0);

7438  

7439           /* Declaring a function type.

7440             Make sure we have a valid type for the function to return.  */

7441  

7442           /* We now know that the TYPE_QUALS don't apply to the

7443             decl, but to its return type.  */

7444           type_quals = TYPE_UNQUALIFIED;

               ...

7471           /* Say it's a definition only for the CALL_EXPR

7472             closest to the identifier.  */

7473           funcdecl_p

7474              = inner_decl

7475                 && (TREE_CODE (inner_decl) == IDENTIFIER_NODE

7476                      || TREE_CODE (inner_decl) == TEMPLATE_ID_EXPR

7477                     || TREE_CODE (inner_decl) == BIT_NOT_EXPR);

              ...

7576           /* Construct the function type and go to the next

7577             inner layer of declarator.  */

7578  

7579           declarator = TREE_OPERAND (declarator, 0);

7580  

7581           arg_types = grokparms (inner_parms, &parms);

7582  

7583           if (declarator && flags == DTOR_FLAG)

7584           {

                ...

7597           }

7598  

7599           /* ANSI says that `const int foo ();'

7600             does not make the function foo const.  */

7601           type = build_function_type (type, arg_types);

7602         }

7603         break ;

            ...

7839       }

7840     }

 

因为声明符已经被验证,可以为之构建树节点了。 CALL_DECLARATOR_PARMS 提取函数的参数列表。在 7581 行,因为 inner_parms void_list_node grokparms 所返回的值是 NULL 。然后在 7601 行,如下的一个 FUNCTION_TYPE 被构建。

t1

 

grokdeclarator (continue)

 

8163     {

8164       tree decl;

8165  

8166       if (decl_context == PARM)

8167       {

            ...

8172       }

8173       else if (decl_context == FIELD)

8174       {

            ...

8427       }

8428       else if (TREE_CODE (type) == FUNCTION_TYPE

8429             || TREE_CODE (type) == METHOD_TYPE)

8430       {

8431         tree original_name;

8432         int publicp = 0;

8433  

8434         if (! declarator)

8435           return NULL_TREE;

8436  

8437         if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)

8438           original_name = dname;

8439         else

8440           original_name = declarator;

8441      

8442         /* Record presence of `static'.  */

8443         publicp = (ctype != NULL_TREE

8444                  || RIDBIT_SETP (RID_EXTERN, specbits)

8445                  || !RIDBIT_SETP (RID_STATIC, specbits));

8446  

8447         decl = grokfndecl (ctype, type, original_name, parms, declarator,

8448                        virtualp, flags, quals, raises,

8449                        1, friendp,

8450                        publicp, inlinep, funcdef_flag,

8451                        template_count, in_namespace);

8452         if (decl == NULL_TREE)

8453           return NULL_TREE;

8454  

8455         if (staticp == 1)

8456         {

              ...

8461         }

8462       }

8463       else

8464       {

            ...

8470       }

 

在这里,下面函数的参数 declarator 来自 original_name ,它在 8440 行获得其内容;而同一行的 declarator 则在 7579 行被更新为“ main ”的 IDENTIFIER_NODE 。另外,参数 parms grokparms 7581 行得到值 NULL

 

5582   static tree

5583   grokfndecl (tree ctype,                                                                                   in decl.c

5584             tree type,

5585             tree declarator,

5586             tree parms,

5587             tree orig_declarator,

5588             int virtualp,

5589             enum overload_flags flags,

5590             tree quals,

5591             tree raises,

5592             int check,

5593             int friendp,

5594             int publicp,

5595             int inlinep,

5596             int funcdef_flag,

5597             int template_count,

5598             tree in_namespace)

5599   {

5600     tree decl;

5601     int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;

5602     int has_default_arg = 0;

5603     tree t;

5604  

5605     if (raises)

5606       type = build_exception_variant (type, raises);

5607  

5608     decl = build_lang_decl (FUNCTION_DECL, declarator, type);

5609     DECL_ARGUMENTS (decl) = parms;

5610     /* Propagate volatile out from type to decl.  */

5611     if (TYPE_VOLATILE (type))

5612       TREE_THIS_VOLATILE (decl) = 1;

5613  

5614     /* If this decl has namespace scope, set that up.  */

5615     if (in_namespace)

5616       set_decl_namespace (decl, in_namespace, friendp);

5617     else if (!ctype)

5618       DECL_CONTEXT (decl) = FROB_CONTEXT ( current_namespace );

5619  

5620     /* `main' and builtins have implicit 'C' linkage.  */

5621     if ((MAIN_NAME_P (declarator)

5622        || (IDENTIFIER_LENGTH (declarator) > 10

5623          && IDENTIFIER_POINTER (declarator)[0] == '_'

5624          && IDENTIFIER_POINTER (declarator)[1] == '_'

5625          && strncmp (IDENTIFIER_POINTER (declarator)+2, "builtin_", 8) == 0))

5626          && current_lang_name == lang_name_cplusplus

5627          && ctype == NULL_TREE

5628          /* NULL_TREE means global namespace.  */

5629          && DECL_CONTEXT (decl) == NULL_TREE)

5630       SET_DECL_LANGUAGE (decl, lang_c);

 

首先,下面的 FUNCTION_DECL 被构建。记得 null context 域中表示我们正在全局名字空间中。

t2

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值