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

来源:互联网 发布:淘宝达人个人简介模版 编辑:程序博客网 时间:2024/06/11 01:00

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

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

 

cp_parser_init_declarator (continue)

 

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

9976       further.  */

9977     if (declarator == error_mark_node)

9978       returnerror_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 whatscope 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'reallowing GNU extensions, look for an asm-specification

9990       and attributes.  */

9991     if (cp_parser_allow_gnu_extensions_p(parser))

9992     {

9993       /* Look for anasm-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 nexttoken.  */

10005   token = cp_lexer_peek_token(parser->lexer);

10006   /* Check to see ifthe 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 afunction-definition should not appear here, issue an

10013         error message.  */

10014      cp_parser_error (parser,

10015                     "a function-definitionis not allowed here");

10016      return error_mark_node;

10017    }

10018    else

10019    {

10020       /* Neitherattributes nor an asm-specification are allowed

10021         on a function-definition.  */

10022       if (asm_specification)

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

10024       if (attributes)

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

10026       /* This is afunction-definition.  */

10027       *function_definition_p = true;

10028

10029       /* Parse thefunction 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       returndecl;

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 thefunction-definition.  */

14325   success_p = begin_function_definition(decl_specifiers,

14326                                   attributes,

14327                                   declarator);

 

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

 

1897   int

1898   begin_function_definition (treedecl_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'reabout to see are not directly qualified by any

1904       template headers we've seenthus 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   /* Sanitycheck.  */

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 onlybe 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_TYPEFUNCTION_DECL节点应该被构建,作为容器来保存以中间形式产生的定义。

 

6462   tree

6463   grokdeclarator(tree declarator,                                                                         in decl.c

6464                tree declspecs,

6465                enumdecl_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     intexplicit_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     enumtree_code innermost_code = ERROR_MARK;

6487     int bitfield = 0;

6488   #if 0

6489    /* See the codebelow that used this.  */

6490     tree decl_attr = NULL_TREE;

6491   #endif

6492  

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

6494       so that we can warn aboutdefault return values, or explicit

6495       return values which do notmatch 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 adeclarator for the name being declared

6519       and get it as a string, for anerror 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           caseCALL_EXPR:

6592             innermost_code = TREE_CODE (decl);

                ...

6601             next = &TREE_OPERAND (decl, 0);

6602             decl = *next;

                ...

6610             ctype = NULL_TREE;

6611             break;

              ...

6629           caseIDENTIFIER_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. Forexample,

6850         `int class;' is not caughtby 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 indeclaration of `%s'", name);

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

6950       {

            ...

6960       }

6961       else if (id != error_mark_node)

6962         /* Can't changeCLASS nodes into RECORD nodes here!  */

6963         type = id;

6964  

6965   found: ;

6966     }

6967  

6968   #if 0

6969     /* See the codebelow 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         caseCALL_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           /* Declaringa function type.

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

7441  

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

7443             decl, but to its returntype.  */

7444           type_quals = TYPE_UNQUALIFIED;

              ...

7471           /* Say it's adefinition only for the CALL_EXPR

7472             closest to theidentifier.  */

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           /* Constructthe function type and go to the next

7577             inner layer ofdeclarator.  */

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 saysthat `const int foo ();'

7600             does not make thefunction foo const.  */

7601           type = build_function_type (type, arg_types);

7602         }

7603         break;

            ...

7839       }

7840     }

 

因为声明符已经被验证,可以为之构建树节点了。CALL_DECLARATOR_PARMS提取函数的参数列表。在7581行,因为inner_parmsvoid_list_nodegrokparms所返回的值是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           returnNULL_TREE;

8436  

8437         if (TREE_CODE (declarator) ==TEMPLATE_ID_EXPR)

8438           original_name = dname;

8439         else

8440           original_name = declarator;

8441      

8442         /* Recordpresence 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           returnNULL_TREE;

8454  

8455         if (staticp == 1)

8456         {

              ...

8461         }

8462       }

8463       else

8464       {

            ...

8470       }

 

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

 

5582   static tree

5583   grokfndecl (treectype,                                                                                   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     /* Propagatevolatile out from type to decl.  */

5611     if (TYPE_VOLATILE (type))

5612       TREE_THIS_VOLATILE (decl) = 1;

5613  

5614     /* If this decl hasnamespace 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' andbuiltins 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_TREEmeans global namespace.  */

5629          && DECL_CONTEXT (decl) ==NULL_TREE)

5630       SET_DECL_LANGUAGE(decl, lang_c);

 

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

t2

原创粉丝点击