Studying note of GCC-3.4.6 source (129)

5.12.5.2.2.        Function-definition – body part
5.12.5.2.2.1.  Prepare for body parsing

Now we get the return-type-specifier in decl_specifiers , declarator of CALL_EXPR and declares_class_or_enum of 0. Remember that if we defining new type, declares_class_or_enum is 2, it is not allowed for 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 }

 

If we find “{” after the declarator, it indicates the function-definition. We continue at line 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);

 

First, we needs setup the framework for the function-definition and concantenate it into the intermediate tree. This framework is common for all non-class binding function-definition. And every definition fills the framework in its own way.

 

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   }

 

Here argument flags has value SF_DEFAULT means a common unparsed function. Below have_extern_spec is true only seeing “extern”.

 

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);

 

As it is the unparsed function, nodes of FUNCTION_TYPE and FUNCTION_DECL should be created as the container to hold the definition generated in intermediate form.

 

6462   tree

6463   grokdeclarator (tree declarator,                                                                         in 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);

 

Just with code executed, we can see that the first part processing is quite simple, at line 6963 type refers to integer_type_node which has code of 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     }

 

As declarator is verified, it can build tree node for it. CALL_DECLARATOR_PARMS retrieves the parameter-list of the function. At line 7581, as inner_parms is void_list_node , the returned value of grokparms is NULL. Then at line 7601, a FUNCTION_TYPE of below is created.

 

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       }

 

Here argument declarator of below function comes from original_name which gets its content at line 8440; and declarator at the same line was updated to IDENTIFIER_NODE of “main” at line 7579. And argument parms gets value of NULL in grokparms at line 7581.

 

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);

 

First of all, following FUNCTION_DECL is created. Remember that null in context field means we are within global namespace.


你可能感兴趣的:(Studying note of GCC-3.4.6 source (129))