Studying note of GCC-3.4.6 source (100)

5.12.3.2.1.1.3.4.2.            Build nodes for method

Clearly, now declarator is node of tree_list, and declares_class_or_enum remains zero and which if nonzero means seeing elaborate-type-specifier or class-specifier or enum-specifier in the decl-specifier (here no decl-specifier presents as constructor is declarator).

 

cp_parser_member_declaration (continue)

 

12672          /* If something went wrong parsing the declarator, make sure

12673            that we at least consume some tokens.  */

12674          if (declarator == error_mark_node)

12675         {

12676            /* Skip to the end of the statement.  */

12677            cp_parser_skip_to_end_of_statement (parser);

12678             /* If the next token is not a semicolon, that is

12679              probably because we just skipped over the body of

12680              a function. So, we consume a semicolon if

12681              present, but do not issue an error message if it

12682              is not present.  */

12683            if (cp_lexer_next_token_is (parser->lexer,

12684                                  CPP_SEMICOLON))

12685             cp_lexer_consume_token (parser->lexer);

12686           return ;

12687         }

12688

12689          if (declares_class_or_enum & 2)

12690           cp_parser_check_for_definition_in_return_type

12691                      (declarator, TREE_VALUE (decl_specifiers));

12692

12693          /* Look for an asm-specification.  */

12694          asm_specification = cp_parser_asm_specification_opt (parser);

12695           /* Look for attributes that apply to the declaration.  */

12696          attributes = cp_parser_attributes_opt (parser);

12697         /* Remember which attributes are prefix attributes and

12698           which are not.  */

12699         first_attribute = attributes;

12700          /* Combine the attributes.  */

12701         attributes = chainon (prefix_attributes, attributes);

12702

12703         /* If it's an `=', then we have a constant-initializer or a

12704            pure-specifier. It is not correct to parse the

12705             initializer before registering the member declaration

12706            since the member declaration should be in scope while

12707            its initializer is processed. However, the rest of the

12708            front end does not yet provide an interface that allows

12709            us to handle this correctly.  */

12710          if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))

12711         {

               

12730         }

12731          /* Otherwise, there is no initializer.  */

12732          else

12733           initializer = NULL_TREE;

12734

12735          /* See if we are probably looking at a function

12736            definition. We are certainly not looking at at a

12737            member-declarator. Calling `grokfield' has

12738            side-effects, so we must not do it unless we are sure

12739            that we are looking at a member-declarator.  */

12740          if (cp_parser_token_starts_function_definition_p

12741                   ( cp_lexer_peek_token (parser->lexer)))

12742         {

12743           /* The grammar does not allow a pure-specifier to be

12744             used when a member function is defined. (It is

12745             possible that this fact is an oversight in the

12746             standard, since a pure function may be defined

12747             outside of the class-specifier.  */

12748           if (initializer)

12749              error ("pure-specifier on function-definition");

12750           decl = cp_parser_save_member_function_body (parser,

12751                                                  decl_specifiers,

12752                                                  declarator,

12753                                                  attributes);

12754            /* If the member was not a friend, declare it here.  */

12755           if (!friend_p)

12756             finish_member_declaration (decl);

12757           /* Peek at the next token.  */

12758           token = cp_lexer_peek_token (parser->lexer);

12759           /* If the next token is a semicolon, consume it.  */

12760           if (token->type == CPP_SEMICOLON)

12761             cp_lexer_consume_token (parser->lexer);

12762           return ;

12763         }

             

12775       }

           

12811     }

12812   }

12813

12814   cp_parser_require (parser, CPP_SEMICOLON, "`;'");

12815 }

 

Arriving here, it needs to see if it is not just function declaration but definition. See that at line 15191 below, the code checks the present of function-try-block. A function-try-block associates a handler-seq with the ctor-initializer, if present, and the function-body. An exception thrown during the execution of the initializer expressions in the ctor-initializer or during the execution of the function-body transfers control to a handler in a function-try-block in the same way as an exception thrown during the execution of a try-block transfers control to other handlers. For example:

int f(int);

class C {

int i;

double d;

public :

C(int, double);

};

 

C::C(int ii, double id)

try

: i(f(ii)), d(id) {

// constructor function body

}

catch (...) {

// handles exceptions thrown from the ctor-initializer

// and from the constructor function body

}

Further GNU C++ extends the function-definition syntax to allow you to specify a name for the result of a function outside the body of the definition, in C++ programs. You can use this feature to avoid an extra constructor call when a function result has a class type. For example, consider a function m , declared as `X v = m ();', whose result is of class X:

X m () {

  X b;

  b.a = 23;

  return b;

}

Although m appears to have no arguments, in fact it has one implicit argument: the address of the return value. At invocation, the address of enough space to hold v is sent in as the implicit argument. Then b is constructed and its a field is set to the value 23. Finally, a copy constructor (a constructor of the form `X(X&)') is applied to b , with the (implicit) return value location as the target, so that v is now bound to the return value.

But this is wasteful. The local b is declared just to hold something that will be copied right out. While a compiler that combined an "elision" algorithm with interprocedural data flow analysis could conceivably eliminate all of this, it is much more practical to allow you to assist the compiler in generating efficient code by manipulating the return value explicitly, thus avoiding the local variable and copy constructor altogether.

Using the extended GNU C++ function-definition syntax, you can avoid the temporary allocation and copying by naming r as your return value as the outset, and assigning to its a field directly:

X m () return r;

{

  r.a = 23;

}

The declaration of r is a standard, proper declaration, whose effects are executed before any of the body of m .

Functions of this type impose no additional restrictions; in particular, you can execute return statements, or return implicitly by reaching the end of the function body ("falling off the edge"). Cases like

X m () return r (23);

{

  return ;

}

(or even `X m () return r (23); { }') are unambiguous, since the return value r has been initialized in either case. The following code may be hard to read, but also works predictably:

X m () return r;

{

  X b;

  return b;

}

The return value slot denoted by r is initialized at the outset, but the statement `return b;' overrides this value. The compiler deals with this by destroying r (calling the destructor if there is one, or doing nothing if there is not), and then reinitializing r with b .

This extension is provided primarily to help people who use overloaded operators, where there is a great need to control not just the arguments, but the return values of functions. For classes where the copy constructor incurs a heavy performance penalty (especially in the common case where there is a quick default constructor), this is a major savings. The disadvantage of this extension is that you do not control when the default constructor for the return value is called: it is always called at the beginning.

This feature is deprecated, and is removed in v4 g++, as the situation mentioned above can be avioded by carefully design.

 

15183 static bool

15184 cp_parser_token_starts_function_definition_p (cp_token* token)                  in parser.c

15185 {

15186   return (/* An ordinary function-body begins with an `{'.  */

15187         token->type == CPP_OPEN_BRACE

15188         /* A ctor-initializer begins with a `:'.  */

15189         || token->type == CPP_COLON

15190         /* A function-try-block begins with `try'.  */

15191         || token->keyword == RID_TRY

15192         /* The named return value extension begins with `return'.  */

15193         || token->keyword == RID_RETURN);

15194 }

 

After seeing that it is a function definition, it drops to line 12750 entering below function. Especially now argument decl_specifiers is NULL for the constructor.

 

14635 static tree

14636 cp_parser_save_member_function_body (cp_parser* parser,                        in parser.c

14637                                   tree decl_specifiers,

14638                                   tree declarator,

14639                                   tree attributes)

14640 {

14641   cp_token_cache *cache;

14642   tree fn;

14643

14644   /* Create the function-declaration.  */

14645   fn = start_method (decl_specifiers, declarator, attributes);

14646   /* If something went badly wrong, bail out now.  */

14647   if (fn == error_mark_node)

14648   {

14649     /* If there's a function-body, skip it.  */

14650     if (cp_parser_token_starts_function_definition_p

14651                  (cp_lexer_peek_token (parser->lexer)))

14652       cp_parser_skip_to_end_of_block_or_statement (parser);

14653     return error_mark_node;

14654   }

 

Creating and pushing nodes for specifier method into the intermediate tree is a complex task. It is initiated by start_method .

 

11032 tree

11033 start_method (tree declspecs, tree declarator, tree attrlist)                                           in decl.c

11034 {

11035   tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0,

11036                          &attrlist);

 

Here argument decl_context of grokdeclarator is MEMFUNCDEF. Following enums are used within the function to hold the specific information of the declarator throughout the procedure.

 

22      enum decl_context                                                                                           in decl.h

23      { NORMAL,                     /* Ordinary declaration */

24        FUNCDEF,                   /* Function definition */

25        PARM,                          /* Declaration of parm before function body */

26        CATCHPARM,               /* Declaration of catch parm */

27        FIELD,                /* Declaration inside struct or union */

28        BITFIELD,                    /* Likewise but with specified width */

29        TYPENAME,                /* Typename (inside cast or sizeof)  */

30        MEMFUNCDEF            /* Member function definition */

31      };

 

3003   typedef enum special_function_kind {                                                        in cp-tree.h

3004     sfk_none = 0,            /* Not a special function. This enumeral

3005                               must have value zero; see

3006                               special_function_p.  */

3007     sfk_constructor,          /* A constructor.  */

3008     sfk_copy_constructor,    /* A copy constructor.  */

3009     sfk_assignment_operator, /* An assignment operator.  */

3010     sfk_destructor,           /* A destructor.  */

3011     sfk_complete_destructor, /* A destructor for complete objects.  */

3012     sfk_base_destructor,     /* A destructor for base subobjects.  */

3013     sfk_deleting_destructor, /* A destructor for complete objects that

3014                            deletes the object after it has been

3015                             destroyed.  */

3016     sfk_conversion           /* A conversion operator.  */

3017   } special_function_kind;

 

3314   enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };

 

At beginning of the function, a long list of flags are initialized. At line 6469, RID_BIT_TYPE is an alias of unsigned long. And RIDBIT_RESET_ALL at line 6510 resets the variable.

 

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 ;

         

6591           case CALL_EXPR:

6592             innermost_code = TREE_CODE (decl);

6593             if (decl_context == FIELD && ctype == NULL_TREE)

6594               ctype = current_class_type ;

6595             if (ctype

6596                 && TREE_OPERAND (decl, 0)

6597                && (TREE_CODE (TREE_OPERAND (decl, 0)) == TYPE_DECL

6598                && constructor_name_p (DECL_NAME (TREE_OPERAND (decl, 0)),

6599                                     ctype)))

6600               TREE_OPERAND (decl, 0) = constructor_name (ctype);

6601             next = &TREE_OPERAND (decl, 0);

6602             decl = *next;

6603             if (ctype != NULL_TREE

6604                && decl != NULL_TREE && flags != DTOR_FLAG

6605                && constructor_name_p (decl, ctype))

6606             {

6607               sfk = sfk_constructor;

6608               ctor_return_type = ctype;

6609             }

6610             ctype = NULL_TREE;

6611             break ;

       

6629           case IDENTIFIER_NODE:

6630             if (TREE_CODE (decl) == IDENTIFIER_NODE)

6631               dname = decl;

6632  

6633             next = 0;

6634  

6635             if (C_IS_RESERVED_WORD (dname))

6636             {

6637               error ("declarator-id missing; using reserved word `%D'",

6638                      dname);

6639               name = IDENTIFIER_POINTER (dname);

6640             }

6641             else if (!IDENTIFIER_TYPENAME_P (dname))

6642               name = IDENTIFIER_POINTER (dname);

6643             else

6644             {

6645               my_friendly_assert (flags == NO_SPECIAL, 154);

6646               flags = TYPENAME_FLAG;

6647               ctor_return_type = TREE_TYPE (dname);

6648               sfk = sfk_conversion;

6649               if (is_typename_at_global_scope (dname))

6650                 name = IDENTIFIER_POINTER (dname);

6651               else

6652                 name = "<invalid operator>";

6653             }

6654             break ;

             

6684         }

6685       }

6686     }

 

First WHILE loop gropes for the declarator, and sets controlling flags accordingly. See that for our example statement, in first iteration, TREE_CODE is tree_list, and in second iteration, TREE_CODE is CALL_EXPR. For the constructor, constructor_name_p at line 6605 returns true, and at the same time ctype refers to current class. Note that operand 0 of the CALL_EXPR is the IDENTIFIER_NODE. At last entry, being IDENTIFIER_NODE but not operator, just code at line 6642 is executed, IDENTIFIER_POINTER returns the string of the name.

At this point, we get ctype (NULL), sfk (sfk_constructor), name (“Lock”), ctor_return_type (current_class_type), funcdef_flag (-1), decl_context (FIELD), innermost_code (CALL_EXPR).

 

grokdeclarator (continue)

 

6788     /* A function definition's declarator must have the form of

6789       a function declarator.  */

6790  

6791     if (funcdef_flag && innermost_code != CALL_EXPR)

6792       return 0;

6793  

6794     if (((dname && IDENTIFIER_OPNAME_P (dname)) || flags == TYPENAME_FLAG)

6795         && innermost_code != CALL_EXPR

6796         && ! (ctype && declspecs == NULL_TREE))

6797     {

6798       error ("declaration of `%D' as non-function", dname);

6799       return void_type_node;

6800     }

       

6973     typedef_type = type;

6974  

6975     /* No type at all: default to `int', and set DEFAULTED_INT

6976       because it was not a user-defined typedef.  */

6977  

6978     if (type == NULL_TREE

6979        && (RIDBIT_SETP (RID_SIGNED, specbits)

6980            || RIDBIT_SETP (RID_UNSIGNED, specbits)

6981            || RIDBIT_SETP (RID_LONG, specbits)

6982            || RIDBIT_SETP (RID_SHORT, specbits)))

6983     {

6984       /* These imply 'int'.  */

6985       type = integer_type_node;

6986       defaulted_int = 1;

6987     }

6988  

6989     if (sfk != sfk_none)

6990       type = check_special_function_return_type (sfk, type,

6991                                           ctor_return_type);

6992     else if (type == NULL_TREE)

6993     {

        

7017     }

7018    

7019     ctype = NULL_TREE;

 

If sfk is sfk_none, it means the declarator is not one of special function enumerated by special_function_kind. Among special functions, constructor, destructor and conversion operator do not allow specifying return type. And except conversion operator, type is set as void.

 

6361   static tree

6362   check_special_function_return_type (special_function_kind sfk,                          in decl.c

6363                                  tree type,

6364                                  tree optype)

6365   {

6366     switch (sfk)

6367     {

6368       case sfk_constructor:

6369         if (type)

6370           error ("return type specification for constructor invalid");

6371  

6372         type = void_type_node;

6373         break ;

6374  

6375       case sfk_destructor:

6376         if (type)

6377           error ("return type specification for destructor invalid");

6378         type = void_type_node;

6379         break ;

6380  

6381       case sfk_conversion:

6382         if (type && !same_type_p (type, optype))

6383           error ("operator `%T' declared to return `%T'", optype, type);

6384         else if (type)

6385           pedwarn ("return type specified for `operator %T'",  optype);

6386         type = optype;

6387         break ;

6388  

6389       default :

6390         abort ();

6391         break ;

6392     }

6393  

6394     return type;

6395   }

 

Obviously, below type_quals holds information about cv-qualifier. Notice that for conversion operator, no cv-qualifier can be specified. Then front-end needs create corresponding cv-qualifier type from unqualified type (remember types varied with cv-qualifier are chained tegother, then TYPE_MAIN_VARIANT returns unqualified ones, and TYPE_NEXT_VARIANT returns qualified ones one after one.

 

grokdeclarator (continue)

 

7161     type_quals = TYPE_UNQUALIFIED;

7162     if (RIDBIT_SETP (RID_CONST, specbits))

7163       type_quals |= TYPE_QUAL_CONST;

7164     if (RIDBIT_SETP (RID_VOLATILE, specbits))

7165       type_quals |= TYPE_QUAL_VOLATILE;

7166     if (RIDBIT_SETP (RID_RESTRICT, specbits))

7167       type_quals |= TYPE_QUAL_RESTRICT;

7168     if (sfk == sfk_conversion && type_quals != TYPE_UNQUALIFIED)

7169       error ("qualifiers are not allowed on declaration of `operator %T'",

7170             ctor_return_type);

 

Now, after above preparation and checking, at here type (void_type_node), scope (NULL), quals (NULL), and type_quals (TYPE_UNQUALIFIED).

 

grokdeclarator (continue)

 

7337     scope = get_scope_of_declarator (declarator);

7338  

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     {

7346       /* Each level of DECLARATOR is either an ARRAY_REF (for ...[..]),

7347         an INDIRECT_REF (for *...),

7348         a CALL_EXPR (for ...(...)),

7349          an identifier (for the name being declared)

7350          or a null pointer (for the place in an absolute declarator

7351          where the name was omitted).

7352          For the last two cases, we have just exited the loop.

7353  

7354         For C++ it could also be

7355          a SCOPE_REF (for class :: ...). In this case, we have converted

7356          sensible names to types, and those are the values we use to

7357          qualify the member name.

7358          an ADDR_EXPR (for &...),

7359          a BIT_NOT_EXPR (for destructors)

7360  

7361          At this point, TYPE is the type of elements of an array,

7362          or for a function to return, or for a pointer to point to.

7363          After this sequence of ifs, TYPE is the type of the

7364          array or function or pointer, and DECLARATOR has had its

7365          outermost layer removed.  */

7366  

7367       if (type == error_mark_node)

7368       {

7369         if (declarator == error_mark_node)

7370           return error_mark_node;

7371         else if (TREE_CODE (declarator) == SCOPE_REF)

7372           declarator = TREE_OPERAND (declarator, 1);

7373         else

7374           declarator = TREE_OPERAND (declarator, 0);

7375         continue ;

7376       }

7377       if (quals != NULL_TREE

7378         && (declarator == NULL_TREE

7379             || TREE_CODE (declarator) != SCOPE_REF))

7380       {

7381         if (ctype == NULL_TREE && TREE_CODE (type) == METHOD_TYPE)

7382           ctype = TYPE_METHOD_BASETYPE (type);

7383         if (ctype != NULL_TREE)

7384         {

7385           tree dummy = build_decl (TYPE_DECL, NULL_TREE, type);

7386           grok_method_quals (ctype, dummy, quals);

7387           type = TREE_TYPE (dummy);

7388           quals = NULL_TREE;

7389         }

7390       }

7391  

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 ;

 

In the first execution of the WHILE loop, declarator is the tree_list with attributes list in TREE_PURPOSE and CALL_EXPR in TREE_VALUE. Routine decl_attributes will install specified attributes in the node of type ; however here attribute list is empty. Anyway, declarator at line 7402 now refers to the node of CALL_EXPR.

 

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 ;

 

For the node of CALL_EXPR, we have seen the layout in cp_parser_direct_declarator and make_call_declarator ; here macro CALL_DECLARATOR_* fetches related child node. At this point, ctype (current_class_type), funcdecl_p (1), decl_context (FIELD), quals (NULL_TREE), raises (NULL_TREE), inner_parms (void_list_node), explicitp (0), staticp (0), specbits (0), type (void_type_node), and virtualp (0).

 

grokdeclarator (continue)

 

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             {

                 

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            {

               

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 ;

           

7839       }

7840     }

 

Most code above verifies the good health of the code compiled, among which at line 7546, member_function_or_else ensures that ctype is the same as current_class_type for constructor or destructor. And FUNCTION_TYPE is created and which indicates void return type and argument list at line 7601 by build_function_type . And as declarator is updated to INDENTIFIER_NODE at line 7579, it breaks out of WHILE loop as result.

 

grokdeclarator (continue)

 

7850     /* Now TYPE has the actual type.  */

7851  

7852     /* Did array size calculations overflow?  */

7853  

7854     if (TREE_CODE (type) == ARRAY_TYPE

7855        && COMPLETE_TYPE_P (type)

7856        && TREE_OVERFLOW (TYPE_SIZE (type)))

7857     {

7858       error ("size of array `%s' is too large", name);

7859       /* If we proceed with the array type as it is, we'll eventually

7860          crash in tree_low_cst().  */

7861       type = error_mark_node;

7862     }

7863  

7864     if ((decl_context == FIELD || decl_context == PARM)

7865        && !processing_template_decl

7866        && variably_modified_type_p (type))

7867     {

7868       if (decl_context == FIELD)

7869         error ("data member may not have variably modified type `%T'", type);

7870       else

7871         error ("parameter may not have variably modified type `%T'", type);

7872       type = error_mark_node;

7873     }

7874  

7875     if (explicitp == 1 || (explicitp && friendp))

7876     {

7877       /* [dcl.fct.spec] The explicit specifier shall only be used in

7878         declarations of constructors within a class definition.  */

7879       error ("only declarations of constructors can be `explicit'");

7880       explicitp = 0;

7881     }

7882  

7883     if (RIDBIT_SETP (RID_MUTABLE, specbits))

7884     {

         

7911     }

7912  

7913     if (declarator == NULL_TREE

7914        || TREE_CODE (declarator) == IDENTIFIER_NODE

7915        || (TREE_CODE (declarator) == TEMPLATE_ID_EXPR

7916          && (TREE_CODE (type) == FUNCTION_TYPE

7917              || TREE_CODE (type) == METHOD_TYPE)))

7918       /* OK */ ;

7919     else if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)

7920     {

7921       error ("template-id `%D' used as a declarator", declarator);

7922       declarator = dname;

7923     }

7924     else

7925       /* Unexpected declarator format.  */

7926       abort ();

7927  

7928     /* If this is declaring a typedef name, return a TYPE_DECL.  */

7929  

7930     if (RIDBIT_SETP (RID_TYPEDEF, specbits) && decl_context != TYPENAME)

7931     {

         

8013     }

8014  

8015     /* Detect the case of an array type of unspecified size

8016       which came, as such, direct from a typedef name.

8017       We must copy the type, so that the array's domain can be

8018       individually set by the object's initializer.  */

8019  

8020     if (type && typedef_type

8021        && TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)

8022        && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (typedef_type))

8023       type = build_cplus_array_type (TREE_TYPE (type), NULL_TREE);

8024  

8025     /* Detect where we're using a typedef of function type to declare a

8026       function. PARMS will not be set, so we must create it now.  */

8027    

8028     if (type == typedef_type && TREE_CODE (type) == FUNCTION_TYPE)

8029     {

         

8042     }

8043  

8044     /* If this is a type name (such as, in a cast or sizeof),

8045       compute the type and return it now.  */

8046  

8047     if (decl_context == TYPENAME)

8048     {

         

8115     }

8116     else if (declarator == NULL_TREE && decl_context != PARM

8117           && decl_context != CATCHPARM

8118           && TREE_CODE (type) != UNION_TYPE

8119           && ! bitfield)

8120     {

8121       error ("abstract declarator `%T' used as declaration", type);

8122       return error_mark_node;

8123     }

8124  

8125     /* Only functions may be declared using an operator-function-id.  */

8126     if (declarator

8127         && TREE_CODE (declarator) == IDENTIFIER_NODE

8128         && IDENTIFIER_OPNAME_P (declarator)

8129         && TREE_CODE (type) != FUNCTION_TYPE

8130         && TREE_CODE (type) != METHOD_TYPE)

8131     {

8132       error ("declaration of `%D' as non-function", declarator);

8133       return error_mark_node;

8134     }

8135  

8136     /* We don't check parameter types here because we can emit a better

8137       error message later.  */

8138     if (decl_context != PARM)

8139       type = check_var_type (declarator, type);

8140  

8141     /* Now create the decl, which may be a VAR_DECL, a PARM_DECL

8142       or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE.  */

8143  

8144     if (decl_context == PARM || decl_context == CATCHPARM)

8145     {

         

8161     }

 

If any small disagreement is left out, it may be propragted throughout the whole program as the created nodes may be refered by lots other nodes in the intermediate tree. Heavy sainty checking is taken, it is interesting to see the conditions to applied. Above at line 7866 variably_modified_type_p returns true if type has variable size. And check_var_type at line 8139 makes sure that type is not declared as “void”.

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