Studying note of GCC-3.4.6 source (103)

5.12.3.2.1.1.3.5.2.            Create DECL nodes for parameter

Then after parsing the parameters list, at line 10492 in cp_parser_direct_declarator , make_call_declarator creates following tree nodes.

(Click here for open )

Figure 76 : CALL_EXPR for non-default constructor

Following the same path as default constructor, then in grokdeclarator , it handles the declarator differently as following. Below CALL_DECLARATOR_PARMS accesses the TREE_PURPOSE field of second operand of declarator (which is the CALL_EXPR in above figure), which holds the parameters of the function. And the first operand refers to the TYPE_DECL of the class containing the method.

 

grokdeclarator (continue)

 

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;

7445  

7446         /* Warn about some types functions can't return.  */

7447  

7448         if (TREE_CODE (type) == FUNCTION_TYPE)

7449         {

7450           error ("`%s' declared as function returning a function", name);

7451           type = integer_type_node;

7452         }

7453         if (TREE_CODE (type) == ARRAY_TYPE)

7454         {

7455           error ("`%s' declared as function returning an array", name);

7456           type = integer_type_node;

7457         }

7458  

7459         if (inner_decl && TREE_CODE (inner_decl) == SCOPE_REF)

7460           inner_decl = TREE_OPERAND (inner_decl, 1);

7461  

7462         if (inner_decl && TREE_CODE (inner_decl) == TEMPLATE_ID_EXPR)

7463           inner_decl = dname;

7464  

7465         /* Pick up type qualifiers which should be applied to `this'.  */

7466         quals = CALL_DECLARATOR_QUALS (declarator);

7467  

7468         /* Pick up the exception specifications.  */

7469         raises = CALL_DECLARATOR_EXCEPTION_SPEC (declarator);

7470  

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

7478  

7479         if (ctype == NULL_TREE

7480            && decl_context == FIELD

7481            && funcdecl_p

7482            && (friendp == 0 || dname == current_class_name))

7483           ctype = current_class_type ;

7484  

7485         if (ctype && sfk == sfk_conversion)

7486           TYPE_HAS_CONVERSION (ctype) = 1;

7487         if (ctype && constructor_name_p (dname, ctype))

7488         {

7489            /* We are within a class's scope. If our declarator name

7490             is the same as the class name, and we are defining

7491             a function, then it is a constructor/destructor, and

7492             therefore returns a void type.  */

7493  

7494           if (flags == DTOR_FLAG)

7495           {

7496              /* ISO C++ 12.4/2. A destructor may not be

7497               declared const or volatile. A destructor may

7498                not be static.  */

7499             if (staticp == 2)

7500               error ("destructor cannot be static member function");

7501             if (quals)

7502             {

7503               error ("destructors may not be `%s'",

7504                     IDENTIFIER_POINTER (TREE_VALUE (quals)));

7505               quals = NULL_TREE;

7506             }

7507             if (decl_context == FIELD)

7508             {

7509               if (! member_function_or_else (ctype,

7510                                         current_class_type ,

7511                                         flags))

7512                 return void_type_node;

7513             }

7514           }

7515           else            /* It's a constructor.  */

7516           {

7517             if (explicitp == 1)

7518                explicitp = 2;

7519             /* ISO C++ 12.1. A constructor may not be

7520               declared const or volatile. A constructor may

7521               not be virtual. A constructor may not be

7522               static.  */

7523             if (staticp == 2)

7524               error ("constructor cannot be static member function");

7525             if (virtualp)

7526             {

7527               pedwarn ("constructors cannot be declared virtual");

7528               virtualp = 0;

7529             }

7530             if (quals)

7531             {

7532               error ("constructors may not be `%s'",

7533                     IDENTIFIER_POINTER (TREE_VALUE (quals)));

7534               quals = NULL_TREE;

7535             }

7536             {

7537               RID_BIT_TYPE tmp_bits;

7538               memcpy (&tmp_bits, &specbits, sizeof (RID_BIT_TYPE));

7539               RIDBIT_RESET (RID_INLINE, tmp_bits);

7540               RIDBIT_RESET (RID_STATIC, tmp_bits);

7541               if (RIDBIT_ANY_SET (tmp_bits))

7542                 error ("return value type specifier for constructor ignored");

7543             }

7544             if (decl_context == FIELD)

7545             {

7546               if (! member_function_or_else (ctype,

7547                                         current_class_type ,

7548                                         flags))

7549                 return void_type_node;

7550               TYPE_HAS_CONSTRUCTOR (ctype) = 1;

7551               if (sfk != sfk_constructor)

7552                 return NULL_TREE;

7553             }

7554           }

7555           if (decl_context == FIELD)

7556             staticp = 0;

7557         }

7558         else if (friendp)

7559         {

7560           if (initialized)

7561             error ("can't initialize friend function `%s'", name);

7562           if (virtualp)

7563            {

7564             /* Cannot be both friend and virtual.  */

7565             error ("virtual functions cannot be friends");

7566             RIDBIT_RESET (RID_FRIEND, specbits);

7567             friendp = 0;

7568           }

7569           if (decl_context == NORMAL)

7570             error ("friend declaration not in class definition");

7571           if (current_function_decl && funcdef_flag)

7572             error ("can't define friend function `%s' in a local class definition",

7573                   name);

7574         }

7575  

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         {

7585           /* A destructor declared in the body of a class will

7586             be represented as a BIT_NOT_EXPR. But, we just

7587             want the underlying IDENTIFIER.  */

7588           if (TREE_CODE (declarator) == BIT_NOT_EXPR)

7589             declarator = TREE_OPERAND (declarator, 0);

7590  

7591           if (arg_types != void_list_node)

7592           {

7593             error ("destructors may not have parameters");

7594              arg_types = void_list_node;

7595             parms = NULL_TREE;

7596           }

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 ;

 

Above at line 7473, funcdecl_p is true. Then if the declarator is valid, it needs to handle the function parameters.

 

8722   static tree

8723   grokparms (tree first_parm, tree *parms)                                                          in decl.c

8724   {

8725     tree result = NULL_TREE;

8726     tree decls = NULL_TREE;

8727     int ellipsis = !first_parm || PARMLIST_ELLIPSIS_P (first_parm);

8728     tree parm, chain;

8729     int any_error = 0;

8730  

8731     my_friendly_assert (!first_parm || TREE_PARMLIST (first_parm), 20001115);

8732  

8733     for (parm = first_parm; parm != NULL_TREE; parm = chain)

8734     {

8735       tree type = NULL_TREE;

8736       tree decl = TREE_VALUE (parm);

8737       tree init = TREE_PURPOSE (parm);

8738       tree specs, attrs;

8739  

8740       chain = TREE_CHAIN (parm);

8741       /* @@ weak defense against parse errors.  */

8742       if (TREE_CODE (decl) != VOID_TYPE

8743          && TREE_CODE (decl) != TREE_LIST)

8744       {

8745         /* Give various messages as the need arises.  */

8746         if (TREE_CODE (decl) == STRING_CST)

8747           error ("invalid string constant `%E'", decl);

8748         else if (TREE_CODE (decl) == INTEGER_CST)

8749           error ("invalid integer constant in parameter list, did you forget to give parameter name?");

8750         continue ;

8751       }

8752  

8753       if (parm == void_list_node)

8754         break ;

8755  

8756       split_specs_attrs (TREE_PURPOSE (decl), &specs, &attrs);

8757       decl = grokdeclarator (TREE_VALUE (decl), specs,

8758                           PARM, init != NULL_TREE, &attrs);

8759       if (! decl || TREE_TYPE (decl) == error_mark_node)

8760         continue ;

 

Here attrs at line 8756 is NULL_TREE, so split_specs_attrs just returns the sub-tree at TREE_PURPOSE field of decl . From the figure of the created CALL_EXPR above, see that field TREE_VALUE field of decl refers to the declarator.

 

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         {

6530           case TREE_LIST:

6531              /* For attributes.  */

6532             next = &TREE_VALUE (decl);

6533             break ;

             

6582           case ADDR_EXPR:     /* C++ reference declaration */

6583           /* Fall through.  */

6584           case ARRAY_REF:

6585           case INDIRECT_REF:

6586             ctype = NULL_TREE;

6587             innermost_code = TREE_CODE (decl);

6588             next = &TREE_OPERAND (decl, 0);

6589             break ;

     

6784         }

6785       }

6786     }

 

First, is the pre-processing of the declarator. In fact, for this parameter the pre-processing just does the validation (compared with the handling for method, during which node of CALL_EXPR has node of FUNCTION_DECL built). So below name is NULL as the declarator is nameless, and is assigned as “parameter” as result.

 

grokdeclarator (continue)

 

6825     if (name == NULL)

6826       name = decl_context == PARM ? "parameter" : "type name";

6827  

6828     /* Look through the decl specs and record which ones appear.

6829       Some typespecs are defined as built-in typenames.

6830       Others, the ones that are modifiers of other types,

6831       are represented by bits in SPECBITS: set the bits for

6832       the modifiers that appear. Storage class keywords are also in SPECBITS.

6833  

6834       If there is a typedef name or a type, store the type in TYPE.

6835       This includes builtin typedefs such as `int'.

6836  

6837       Set EXPLICIT_INT if the type is `int' or `char' and did not

6838       come from a user typedef.

6839  

6840       Set LONGLONG if `long' is mentioned twice.

6841  

6842       For C++, constructors and destructors have their own fast treatment.  */

6843  

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

6856  

6857       /* If the entire declaration is itself tagged as deprecated then

6858         suppress reports of deprecated items.  */

6859       if (!adding_implicit_members && id && TREE_DEPRECATED (id))

6860       {

6861         if (deprecated_state != DEPRECATED_SUPPRESS)

6862           warn_deprecated_use (id);

6863       }

6864  

6865       if (TREE_CODE (id) == IDENTIFIER_NODE)

6866       {

6867         if (id == ridpointers [(int) RID_INT]

6868            || id == ridpointers [(int) RID_CHAR]

6869            || id == ridpointers [(int) RID_BOOL]

6870            || id == ridpointers [(int) RID_WCHAR])

6871         {

6872           if (type)

6873           {

6874             if (id == ridpointers [(int) RID_BOOL])

6875               error ("`bool' is now a keyword");

6876             else

6877               error ("extraneous `%T' ignored", id);

6878           }

6879           else

6880           {

6881             if (id == ridpointers [(int) RID_INT])

6882               explicit_int = 1;

6883             else if (id == ridpointers [(int) RID_CHAR])

6884               explicit_char = 1;

6885             type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id));

6886           }

6887           goto found;

6888         }

6889         /* C++ aggregate types.  */

6890         if (IDENTIFIER_HAS_TYPE_VALUE (id))

6891         {

6892           if (type)

6893             error ("multiple declarations `%T' and `%T'", type, id);

6894           else

6895             type = IDENTIFIER_TYPE_VALUE (id);

6896           goto found;

6897         }

6898  

6899         for (i = (int) RID_FIRST_MODIFIER; i <= (int) RID_LAST_MODIFIER; i++)

6900         {

6901           if (ridpointers [i] == id)

6902           {

6903             if (i == (int) RID_LONG && RIDBIT_SETP (i, specbits))

6904             {

6905               if (pedantic && ! in_system_header && warn_long_long )

6906                 pedwarn ("ISO C++ does not support `long long'");

6907               if (longlong)

6908                 error ("`long long long' is too long for GCC");

6909               else

6910                 longlong = 1;

6911             }

6912             else if (RIDBIT_SETP (i, specbits))

6913               pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));

6914  

6915             /* Diagnose "__thread extern" or "__thread static".  */

6916             if (RIDBIT_SETP (RID_THREAD, specbits))

6917             {

6918                if (i == (int)RID_EXTERN)

6919                 error ("`__thread' before `extern'");

6920               else if (i == (int)RID_STATIC)

6921                 error ("`__thread' before `static'");

6922             }

6923  

6924             if (i == (int)RID_EXTERN

6925                && TREE_PURPOSE (spec) == error_mark_node)

6926               /* This extern was part of a language linkage.  */

6927               extern_langp = 1;

6928  

6929             RIDBIT_SET (i, specbits);

6930             goto found;

6931           }

6932         }

6933       }

6934       else if (TREE_CODE (id) == TYPE_DECL)

6935       {

6936         if (type)

6937           error ("multiple declarations `%T' and `%T'", type,

6938                 TREE_TYPE (id));

6939         else

6940         {

6941           type = TREE_TYPE (id);

6942           TREE_VALUE (spec) = type;

6943           typedef_decl = id;

6944         }

6945         goto found;

6946       }

6947       if (type)

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

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

6950       {

6951         tree t = lookup_name (id, 1);

6952         if (!t || TREE_CODE (t) != TYPE_DECL)

6953           error ("`%s' fails to be a typedef or built in type",

6954                IDENTIFIER_POINTER (id));

6955         else

6956          {

6957           type = TREE_TYPE (t);

6958           typedef_decl = t;

6959         }

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     }

 

Nodes forming decl-specifier-seq, if valid, should be defined already. The first node of the keyword “const” can be recognized in FOR block at line 6899 and this cv-qualifier information is saved within specbits at line 6929. Every declarator should only have single type specified, so when seeing a TYPE_DECL, type must be NULL.

 

grokdeclarator (continue)

 

7161     type_quals = TYPE_UNQUALIFIED;

7162     if (RIDBIT_SETP (RID_CONST, specbits))

7163       type_quals |= TYPE_QUAL_CONST;

       

7172     type_quals |= cp_type_quals (type);

7173     type = cp_build_qualified_type_real

7174        (type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl)

7175                        ? tf_ignore_bad_quals : 0) | tf_error | tf_warning));

7176     /* We might have ignored or rejected some of the qualifiers.  */

7177     type_quals = cp_type_quals (type);

 

Considering the code:

       typedef const int A;

       void func (A&);

Though parameter A is declared as non-constant, however itself is a type of constant. To generate correct code, the front-end must be able to find out the one exactly used. It is the task of cp_build_qualified_type_real .

 

427    tree

428    cp_build_qualified_type_real (tree type,                                                           in tree.c

429                              int type_quals,

430                             tsubst_flags_t complain)

431    {

432      tree result;

433      int bad_quals = TYPE_UNQUALIFIED;

434   

435      if (type == error_mark_node)

436        return type;

437   

438      if (type_quals == cp_type_quals (type))

439        return type;

440   

441      if (TREE_CODE (type) == ARRAY_TYPE)

442      {

        

481      }

482      else if (TYPE_PTRMEMFUNC_P (type))

483      {

        

493      }

494     

495      /* A reference, function or method type shall not be cv qualified.

496        [dcl.ref], [dct.fct]  */

497      if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)

498         && (TREE_CODE (type) == REFERENCE_TYPE

499              || TREE_CODE (type) == FUNCTION_TYPE

500              || TREE_CODE (type) == METHOD_TYPE))

501      {

502        bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);

503        type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);

504      }

505     

506      /* A restrict-qualified type must be a pointer (or reference)

507        to object or incomplete type.  */

508      if ((type_quals & TYPE_QUAL_RESTRICT)

509          && TREE_CODE (type) != TEMPLATE_TYPE_PARM

510          && TREE_CODE (type) != TYPENAME_TYPE

511           && !POINTER_TYPE_P (type))

512      {

513        bad_quals |= TYPE_QUAL_RESTRICT;

514        type_quals &= ~TYPE_QUAL_RESTRICT;

515      }

516   

517      if (bad_quals == TYPE_UNQUALIFIED)

518        /*OK*/ ;

519      else if (!(complain & (tf_error | tf_ignore_bad_quals)))

520        return error_mark_node;

521      else

522      {

523        if (complain & tf_ignore_bad_quals)

524          /* We're not going to warn about constifying things that can't

525            be constified.  */

526          bad_quals &= ~TYPE_QUAL_CONST;

527        if (bad_quals)

528        {

529          tree bad_type = build_qualified_type (ptr_type_node, bad_quals);

530   

531          if (!(complain & tf_ignore_bad_quals))

532            error ("`%V' qualifiers cannot be applied to `%T'",

533                 bad_type, type);

534        }

535      }

536     

537      /* Retrieve (or create) the appropriately qualified variant.  */

538      result = build_qualified_type (type, type_quals);

539   

540      /* If this was a pointer-to-method type, and we just made a copy,

541        then we need to unshare the record that holds the cached

542        pointer-to-member-function type, because these will be distinct

543        between the unqualified and qualified types.  */

544      if (result != type

545         && TREE_CODE (type) == POINTER_TYPE

546         && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)

547        TYPE_LANG_SPECIFIC (result) = NULL;

548   

549      return result;

550    }

 

Notice that at line 438, if the cv-qualifier flag returned by the type is the same as the expected cv-qualifier, that argument is what we want. However, here type just refers to the native “Host”, nodes for “const Host” should be created by build_qualified_type . Then the intermediate tree is as below:

(Click here for open )

Figure 77 : cv-qualified parameter created

After handling decl-specifier-seq, it can apply this type-specifier to the declarator. Below WHILE block iterates the list of declarator, the first node in the list has specified attributes in the field of TREE_PURPOSE. For example: “void func (const int) const ;” the second “const” is the attribute for the declarator “func” and goes here. And in this statement, type should refer to the return type of “func”, so attr_flags has field ATTR_FLAG_FUNCTION_NEXT set which causes attribute of “const” be returned without install in decl_attributes .

 

grokdeclarator (continue)

 

  /* Now figure out the structure of the declarator proper.

    Descend through it, creating more complex types, until we reach

    the declared identifier (or NULL_TREE, in an abstract declarator).  */

 

7339     /* Now figure out the structure of the declarator proper.

7340       Descend through it, creating more complex types, until we reach

7341       the declared identifier (or NULL_TREE, in an abstract declarator).  */

7342  

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

7344          && TREE_CODE (declarator) != TEMPLATE_ID_EXPR)

7345     {

         

7392       switch (TREE_CODE (declarator))

7393       {

7394         case TREE_LIST:

7395         {

7396           /* We encode a declarator with embedded attributes using

7397             a TREE_LIST.  */

7398           tree attrs = TREE_PURPOSE (declarator);

7399           tree inner_decl;

7400           int attr_flags;

7401  

7402           declarator = TREE_VALUE (declarator);

7403           inner_decl = declarator;

7404           while (inner_decl != NULL_TREE

7405                 && TREE_CODE (inner_decl) == TREE_LIST)

7406             inner_decl = TREE_VALUE (inner_decl);

7407           attr_flags = 0;

7408           if (inner_decl == NULL_TREE

7409              || TREE_CODE (inner_decl) == IDENTIFIER_NODE)

7410             attr_flags |= (int) ATTR_FLAG_DECL_NEXT;

7411           if (TREE_CODE (inner_decl) == CALL_EXPR)

7412             attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;

7413           if (TREE_CODE (inner_decl) == ARRAY_REF)

7414             attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;

7415           returned_attrs = decl_attributes (&type,

7416                                      chainon (returned_attrs, attrs),

7417                                      attr_flags);

7418         }

7419         break ;

          

7605         case ADDR_EXPR:

7606         case INDIRECT_REF:

7607            /* Filter out pointers-to-references and references-to-references.

7608             We can get these if a TYPE_DECL is used.  */

7609  

7610           if (TREE_CODE (type) == REFERENCE_TYPE)

7611           {

7612             error (TREE_CODE (declarator) == ADDR_EXPR

7613                  ? "cannot declare reference to `%#T'"

7614                  : "cannot declare pointer to `%#T'", type);

7615             type = TREE_TYPE (type);

7616           }

7617           else if (VOID_TYPE_P (type)

7618                 && (ctype || TREE_CODE (declarator) == ADDR_EXPR))

7619             error (ctype ? "cannot declare pointer to `%#T' member"

7620                  : "cannot declare reference to `%#T'", type);

7621  

7622           /* Merge any constancy or volatility into the target type

7623             for the pointer.  */

7624  

7625           /* We now know that the TYPE_QUALS don't apply to the decl,

7626             but to the target of the pointer.  */

7627           type_quals = TYPE_UNQUALIFIED;

7628  

7629           if (TREE_CODE (declarator) == ADDR_EXPR)

7630           {

7631             if (!VOID_TYPE_P (type))

7632               type = build_reference_type (type);

7633           }

7634           else if (TREE_CODE (type) == METHOD_TYPE)

7635             type = build_ptrmemfunc_type (build_pointer_type (type));

7636           else if (ctype)

7637             type = build_ptrmem_type (ctype, type);

7638           else

7639             type = build_pointer_type (type);

7640  

7641           /* Process a list of type modifier keywords (such as

7642             const or volatile) that were given inside the `*' or `&'.  */

7643  

7644           if (TREE_TYPE (declarator))

7645           {

7646             tree typemodlist;

7647             int erred = 0;

7648             int constp = 0;

7649             int volatilep = 0;

7650             int restrictp = 0;

7651             

7652             for (typemodlist = TREE_TYPE (declarator); typemodlist;

7653                 typemodlist = TREE_CHAIN (typemodlist))

7654             {

7655               tree qualifier = TREE_VALUE (typemodlist);

7656  

7657               if (qualifier == ridpointers [(int) RID_CONST])

7658               {

7659                 constp++;

7660                 type_quals |= TYPE_QUAL_CONST;

7661               }

7662               else if (qualifier == ridpointers [(int) RID_VOLATILE])

7663               {

7664                 volatilep++;

7665                 type_quals |= TYPE_QUAL_VOLATILE;

7666               }

7667               else if (qualifier == ridpointers [(int) RID_RESTRICT])

7668               {

7669                  restrictp++;

7670                 type_quals |= TYPE_QUAL_RESTRICT;

7671               }

7672               else if (!erred)

7673               {

7674                 erred = 1;

7675                 error ("invalid type modifier within pointer declarator");

7676               }

7677             }

7678             if (constp > 1)

7679               pedwarn ("duplicate `const'");

7680             if (volatilep > 1)

7681               pedwarn ("duplicate `volatile'");

7682             if (restrictp > 1)

7683               pedwarn ("duplicate `restrict'");

7684             type = cp_build_qualified_type (type, type_quals);

7685             type_quals = cp_type_quals (type);

7686           }

7687           declarator = TREE_OPERAND (declarator, 0);

7688           ctype = NULL_TREE;

7689            break ;

             ...

7839         }

7840       }

 

See at line 7402 above, node of ADDR_EXPR is retrieved from declarator , and as type refers to “const Host”, node of REFERENCE_TYPE which is what the language expected is generated. Notice that for declarator , field TREE_TYPE records the cv-qualifiers if present. For example: “const int * const a;” the second “const” will go here which defines the declarator “a”. And see that for the example, type at line 7684 represents “const int*”, and the constant variant of the type (e.g., “const int* const”) is created by cp_build_qualified_type (which is a simple wrapper of cp_build_qualified_type_real ).

As here is “const Host&”, so field TREE_TYPE of declarator is NULL_TREE. With new nodes created, intermediate tree is enlarged as below:

(Click here for open )

Figure 78 : reference node created

Now type refers to the REFERENCE_TYPE just created. And declarator is updated to the first operand of the ADDR_EXPR which is NULL_TREE.

 

grokdeclarator (continue)

 

8163     {

8164       tree decl;

8165  

8166       if (decl_context == PARM)

8167       {

8168         decl = cp_build_parm_decl (declarator, type);

8169  

8170         bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE,

8171                      inlinep, friendp, raises != NULL_TREE);

8172       }

         

8570       return decl;

8571     }

8572   }

 

Then the PARM_DECL in below figure is returned by grokdeclarator . Below decl just refers to the PARM_DECL created.

(Click here for open )

Figure 79 : PARM_DECL node created

 

grokparms (continue)

 

8762       if (attrs)

8763         cplus_decl_attributes (&decl, attrs, 0);

8764  

8765       type = TREE_TYPE (decl);

8766       if (VOID_TYPE_P (type))

8767       {

8768         if (same_type_p (type, void_type_node)

8769            && !DECL_NAME (decl) && !result && !chain && !ellipsis)

8770           /* this is a parmlist of `(void)', which is ok.  */

8771           break ;

8772         cxx_incomplete_type_error (decl, type);

8773         /* It's not a good idea to actually create parameters of

8774           type `void'; other parts of the compiler assume that a

8775           void type terminates the parameter list.  */

8776         type = error_mark_node;

8777         TREE_TYPE (decl) = error_mark_node;

8778       }

8779  

8780       if (type != error_mark_node)

8781       {

8782         /* Top-level qualifiers on the parameters are

8783           ignored for function types.  */

8784         type = cp_build_qualified_type (type, 0);

8785         if (TREE_CODE (type) == METHOD_TYPE)

8786         {

8787           error ("parameter `%D' invalidly declared method type", decl);

8788           type = build_pointer_type (type);

8789           TREE_TYPE (decl) = type;

8790         }

8791         else if (abstract_virtuals_error (decl, type))

8792           any_error = 1;  /* Seems like a good idea.  */

8793         else if (POINTER_TYPE_P (type))

8794         {

8795           /* [dcl.fct]/6, parameter types cannot contain pointers

8796             (references) to arrays of unknown bound.  */

8797           tree t = TREE_TYPE (type);

8798           int ptr = TYPE_PTR_P (type);

8799  

8800           while (1)

8801           {

8802             if (TYPE_PTR_P (t))

8803               ptr = 1;

8804             else if (TREE_CODE (t) != ARRAY_TYPE)

8805               break ;

8806              else if (!TYPE_DOMAIN (t))

8807               break ;

8808             t = TREE_TYPE (t);

8809           }

8810           if (TREE_CODE (t) == ARRAY_TYPE)

8811             error ("parameter `%D' includes %s to array of unknown bound `%T'",

8812                    decl, ptr ? "pointer" : "reference", t);

8813         }

8814  

8815         if (!any_error && init)

8816           init = check_default_argument (decl, init);

8817         else

8818           init = NULL_TREE;

8819       }

8820  

8821       TREE_CHAIN (decl) = decls;

8822       decls = decl;

8823       result = tree_cons (init, type, result);

8824     }

8825     decls = nreverse (decls);

8826     result = nreverse (result);

8827     if (!ellipsis)

8828       result = chainon (result, void_list_node);

8829     *parms = decls;

8830  

8831     return result;

8832   }

 

When getting decl for the identifier , as indicated by the grammar, it must be an identifier or template-id. Again consider previous example:

typedef const int A;

void func(A&);

For this example, type at line 8784 will refer to the type of “const int”, but “const” is not present in the declaration of func; to generate correct representation for the function declaration, no “const” needs be considered. At line 8784, cp_build_qualified_type finds out the unqualified variant of the type. Then in below figure, result and parms are those returned by grokparms .

(Click here for open )

Figure 80 : result & parms returned by grokparms

 

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