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