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
- Studying note of GCC-3.4.6 source (103)
- Studying note of GCC-3.4.6 source (6)
- Studying note of GCC-3.4.6 source (1)
- Studying note of GCC-3.4.6 source (2)
- Studying note of GCC-3.4.6 source (3)
- Studying note of GCC-3.4.6 source (4)
- Studying note of GCC-3.4.6 source (5)
- Studying note of GCC-3.4.6 source (7)
- Studying note of GCC-3.4.6 source (8)
- Studying note of GCC-3.4.6 source (9)
- Studying note of GCC-3.4.6 source (10)
- Studying note of GCC-3.4.6 source (10 cont1)
- Studying note of GCC-3.4.6 source (10 cont2)
- Studying note of GCC-3.4.6 source (10 cont3)
- Studying note of GCC-3.4.6 source (10 cont4)
- Studying note of GCC-3.4.6 source (11)
- Studying note of GCC-3.4.6 source (12)
- Studying note of GCC-3.4.6 source (13)
- ssh junit4报错
- SqlServer 2005 全文索引 实例
- NT是怎么载入NTLDR的 NT引导研究 ( MBR->DBR->NTLDR )
- GCC-3.4.6源代码学习笔记 (103)
- ZTSF知多少?
- Studying note of GCC-3.4.6 source (103)
- 260Il Gioco dell'X
- ARM ADS集成开发环境的使用
- 不同数据库服务器间数据的导入导出
- C 语言的谜题
- sqlserve2000 关于100万数据查询优化
- ls -l 命令详解
- 解析百度搜索结果页面的python脚本(Linux/Win都可以运行)
- C中调用带参数的exe并接收返回值