Studying note of GCC-3.4.6 source (103)

来源:互联网 发布:海尔冰箱 知乎 编辑:程序博客网 时间:2024/05/19 02:04

5.12.3.2.1.1.3.5.2.           Create DECL nodes forparameter

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

(Clickhere 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_PARMSaccesses the TREE_PURPOSE field of second operand of declarator (which is the CALL_EXPRin above figure), which holds the parameters of the function. And the firstoperand refers to the TYPE_DECL of the class containing the method.

 

grokdeclarator (continue)

 

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         /*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            /* ISOC++ 12.4/2. A destructor maynot 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 aconstructor.  */

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_TYPEtmp_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 ("returnvalue 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'tinitialize friend function `%s'", name);

7562           if (virtualp)

7563           {

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

7565             error ("virtualfunctions cannot be friends");

7566             RIDBIT_RESET(RID_FRIEND, specbits);

7567             friendp = 0;

7568           }

7569           if (decl_context == NORMAL)

7570             error ("frienddeclaration not in class definition");

7571           if (current_function_decl&& funcdef_flag)

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

7573                   name);

7574         }

7575  

7576         /* Construct the function type and go to thenext

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 isvalid, 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 ("invalidstring constant `%E'", decl);

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

8749           error ("invalid integer constantin 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 attrsat line 8756 is NULL_TREE, so split_specs_attrs just returns the sub-treeat TREE_PURPOSE field of decl. From the figure of the created CALL_EXPRabove, 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     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     constchar *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 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       sothat we can warn about default return values, or explicit

6495       returnvalues 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       andget 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             /* Forattributes.  */

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 thisparameter the pre-processing just does the validation (compared with thehandling for method, during which node of CALL_EXPR has node of FUNCTION_DECLbuilt). So below nameis NULL as the declarator is nameless, and is assigned as “parameter” asresult.

 

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       Sometypespecs are defined as built-in typenames.

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

6831       arerepresented by bits in SPECBITS: set the bits for

6832       themodifiers that appear. Storage class keywords are also in SPECBITS.

6833  

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

6835       Thisincludes builtin typedefs such as `int'.

6836  

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

6838       comefrom a user typedef.

6839  

6840       SetLONGLONG if `long' is mentioned twice.

6841  

6842       ForC++, 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         `intclass;' 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 "__threadstatic".  */

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 ("multipledeclarations `%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         gotofound;

6946       }

6947       if (type)

6948         error ("two or moredata 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 definedalready. The first node of the keyword “const” can be recognized in FOR block at line 6899 and thiscv-qualifier information is saved within specbits at line 6929. Every declarator shouldonly have single type specified, so when seeing a TYPE_DECL, typemust 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 constint A;

       void func (A&);

Though parameter A isdeclared as non-constant, however itself is a type of constant. To generatecorrect code, the front-end must be able to find out the one exactly used. Itis 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_tcomplain)

431    {

432      tree result;

433      int bad_quals =TYPE_UNQUALIFIED;

434   

435      if (type == error_mark_node)

436        returntype;

437   

438      if (type_quals ==cp_type_quals (type))

439        returntype;

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        toobject 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            beconstified.  */

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        thenwe 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      returnresult;

550    }

 

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

(Clickhere for open)

Figure 77:cv-qualified parameter created

After handling decl-specifier-seq, it can apply this type-specifierto the declarator. Below WHILE blockiterates the list of declarator, the first node in the list has specified attributesin the field of TREE_PURPOSE. For example: “void func (constint) const;” the second “const” is theattribute for the declarator “func” and goes here. And in this statement, typeshould refer to the return type of “func”, so attr_flags has fieldATTR_FLAG_FUNCTION_NEXT set which causes attribute of “const” be returnedwithout install in decl_attributes.

 

grokdeclarator (continue)

 

 /* Now figure out the structure of the declaratorproper.

    Descend through it, creating more complextypes, until we reach

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

 

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

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

7341       thedeclared 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         caseTREE_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         caseADDR_EXPR:

7606         caseINDIRECT_REF:

7607           /* Filter outpointers-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                  ? "cannotdeclare reference to `%#T'"

7614                  : "cannotdeclare 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                  : "cannotdeclare 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 typerefers to “const Host”, node of REFERENCE_TYPE which is what the languageexpected is generated. Notice that for declarator, field TREE_TYPE records thecv-qualifiers if present. For example: “constint * const a;” the second “const” will go herewhich defines the declarator “a”. And see that for the example, type atline 7684 represents “const int*”, and the constant variant of the type (e.g., “constint* const”) is created by cp_build_qualified_type (which is a simplewrapper 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:

(Clickhere for open)

Figure 78:reference node created

Now typerefers to the REFERENCE_TYPE just created. And declarator is updated to the firstoperand 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       returndecl;

8571     }

8572   }

 

Then thePARM_DECL in below figure is returned by grokdeclarator. Below decl just refers to the PARM_DECLcreated.

(Clickhere 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 agood 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     returnresult;

8832   }

 

When getting decl forthe identifier,as indicated by the grammar, it must be an identifier or template-id. Againconsider 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 generatecorrect representation for the function declaration, no “const” needs beconsidered. At line 8784, cp_build_qualified_type finds out the unqualifiedvariant of the type. Then in below figure, result and parms are those returned by grokparms.

(Clickhere for open)

Figure 80: result & parms returned by grokparms

 

原创粉丝点击