Studying note of GCC-3.4.6 source (113)

5.12.3.2.1.2.2.          Close the class definition

Returns from expand_or_defer_fn à cp_parser_late_parsing_for_member à cp_parser_late_parsing_for_member à cp_parser_class_specifier à cp_parser_type_specifier à cp_parser_decl_specifier_seq à cp_parser_single_declaration , following code will be executed.

 

cp_parser_single_declaration (continue)

 

14549   /* Check for the declaration of a template class.  */

14550   if (declares_class_or_enum)

14551   {

14552     if (cp_parser_declares_only_class_p (parser))

14553     {

14554       decl = shadow_tag (decl_specifiers);

14555        if (decl)

14556         decl = TYPE_NAME (decl);

14557       else

14558         decl = error_mark_node;

14559     }

14560   }

14561   /* If it's not a template class, try for a template function. If

14562     the next token is a `;', then this declaration does not declare

14563     anything. But, if there were errors in the decl-specifiers, then

14564     the error might well have come from an attempted class-specifier.

14565     In that case, there's no need to warn about a missing declarator.  */

14566   if (!decl

14567       && (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)

14568           || !value_member (error_mark_node, decl_specifiers)))

14569     decl = cp_parser_init_declarator (parser,

14570                               decl_specifiers,

14571                                attributes,

14572                                /*function_definition_allowed_p=*/ true,

14573                                member_p,

14574                                declares_class_or_enum,

14575                                 &function_definition_p);

14576

14577   pop_deferring_access_checks ();

14578

14579   /* Clear any current qualification; whatever comes next is the start

14580     of something new.  */

14581   parser->scope = NULL_TREE;

14582   parser->qualifying_scope = NULL_TREE;

14583   parser->object_scope = NULL_TREE;

14584   /* Look for a trailing `;' after the declaration.  */

14585   if (!function_definition_p

14586       && (decl == error_mark_node

14587            || !cp_parser_require (parser, CPP_SEMICOLON, "`;'")))

14588     cp_parser_skip_to_end_of_block_or_statement (parser);

14589

14590   return decl;

14591 }

 

As we have seen, declares_class_or_enum is set to the bitwise or of the following flags:

1: one of the decl-specifiers is an elaborated-type-specifier (i.e., a type declaration)

2: one of the decl-specifiers is an enum-specifier or a class-specifier (i.e., a type definition)

So if declares_class_or_enum is non-zero, it needs further to see if it is the class definition. If so, some sainty check should be taken just like those executed for nested class in former section.

As now only finish decl-specifier-seq part in “decl-specifier-seq[opt] init-declarator [opt];”, cp_parser_declares_only_class_p is used to see if declarator exists.

 

15029 static bool

15030 cp_parser_declares_only_class_p (cp_parser *parser)                                   in parser.c

15031 {

15032   /* If the next token is a `;' or a `,' then there is no

15033      declarator.  */

15034   return (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)

15035          || cp_lexer_next_token_is (parser->lexer, CPP_COMMA));

15036 }

 

If there is not delcarator, it should be type declaration which should be verified.

 

3608   tree

3609   shadow_tag (tree declspecs)                                                                             in decl.c

3610   {

3611     tree t = check_tag_decl (declspecs);

3612  

3613     if (!t)

3614       return NULL_TREE;

3615  

3616     maybe_process_partial_specialization (t);

3617  

3618     /* This is where the variables in an anonymous union are

3619       declared. An anonymous union declaration looks like:

3620       union { ... } ;

3621       because there is no declarator after the union, the parser

3622       sends that declaration here.  */

3623     if (ANON_AGGR_TYPE_P (t))

3624     {

3625       fixup_anonymous_aggr (t);

3626  

3627       if (TYPE_FIELDS (t))

3628       {

3629         tree decl = grokdeclarator (NULL_TREE, declspecs, NORMAL, 0,

3630                               NULL);

3631         finish_anon_union (decl);

3632       }

3633     }

3634  

3635     return t;

3636   }

 

Above check_tag_decl returns the type declared (node of *_TYPE) or NULL if none, which in turn is returned by shadow_tag . Then in cp_parser_single_declaration , at line 14556, decl points to the TYPE_DECL node. At line 14566, decl if NULL, means it’s not a type declaration, as cp_parser_single_declaration is only invoked by cp_parser_explicit_specialization or cp_parser_template_declaration_after_export (here is the rear), the left possibility is of function template, which is parsed by cp_parser_init_declarator at line 14569.

From cp_parser_single_declaration back to cp_parser_template_declaration_after_export .

 

cp_parser_template_declaration_after_export (continue)

 

14461   else

14462   {

14463     decl = cp_parser_single_declaration (parser,

14464                                    member_p,

14465                                   &friend_p);

14466

14467     /* If this is a member template declaration, let the front

14468       end know.  */

14469     if (member_p && !friend_p && decl)

14470     {

14471       if (TREE_CODE (decl) == TYPE_DECL)

14472         cp_parser_check_access_in_redeclaration (decl);

14473

14474       decl = finish_member_template_decl (decl);

14475     }

14476     else if (friend_p && decl && TREE_CODE (decl) == TYPE_DECL)

14477       make_friend_class (current_class_type , TREE_TYPE (decl),

14478                       /*complain=*/ true);

14479   }

14480   /* We are done with the current parameter list.  */

14481   --parser->num_template_parameter_lists;

14482

14483   /* Finish up.  */

14484   finish_template_decl (parameter_list);

14485

14486   /* Register member declarations.  */

14487   if (member_p && !friend_p && decl && !DECL_CLASS_TEMPLATE_P (decl))

14488     finish_member_declaration (decl);

14489

14490   /* If DECL is a function template, we must return to parse it later.

14491     (Even though there is no definition, there might be default

14492     arguments that need handling.)  */

14493   if (member_p && decl

14494      && (TREE_CODE (decl) == FUNCTION_DECL

14495          || DECL_FUNCTION_TEMPLATE_P (decl)))

14496     TREE_VALUE (parser->unparsed_functions_queues)

14497              = tree_cons (NULL_TREE, decl,

14498                         TREE_VALUE (parser->unparsed_functions_queues));

14499 }

 

Above, for our example template declaration, it is not a member, so argument member_p is false. Then for the example, the only operation is done by finish_template_decl .

 

2208   void

2209   finish_template_decl (tree parms)                                                      in semantics.c

2210   {

2211     if (parms)

2212       end_template_decl ();

2213     else

2214       end_specialization ();

2215   }

 

Argument parms is extracted within “<>”, so if it is NULL, it must be a specialization.

 

2279   void

2280   end_template_decl (void)                                                                                in pt.c

2281   {

2282     reset_specialization ();

2283  

2284     if (! processing_template_decl)

2285       return ;

2286  

2287     /* This matches the pushlevel in begin_template_parm_list.  */

2288     finish_scope ();

2289  

2290     --processing_template_decl ;

2291     current_template_parms = TREE_CHAIN (current_template_parms);

2292   }

 

At finishing template declaration, it means we arriving at the edge of its scope. The scope is closed by finish_scope too. And remember to decrease the number of template declaration under processing. Refers to figure layout of nested template parameters , above at line 2291, field TREE_CHAIN of current_template_parms refers to the template argument of the containing template if it exits.

 

354    void

355    finish_scope (void)                                                                                         in decl.c

356    {

357      poplevel (0, 0, 0);

358    }

 

For convience, we present the code of poplevel in below again. As we are exiting from class scope, so argument functionbody is 0; and keep is 0 then no BLOCK node will be created for the declarations within the scope.

 

423    tree

424    poplevel (int keep, int reverse, int functionbody)                                               in decl.c

425    {

426      tree link;

427      /* The chain of decls was accumulated in reverse order.

428        Put it into forward order, just for cleanliness.  */

429      tree decls;

430      int tmp = functionbody;

431      int real_functionbody;

432      tree subblocks;

433      tree block = NULL_TREE;

434      tree decl;

435      int leaving_for_scope;

436      scope_kind kind;

       

454      if (current_binding_level ->keep)

455        keep = 1;

       

493      /* Get the decls in the order they were written.

494        Usually current_binding_level->names is in reverse order.

495        But parameter decls were previously put in forward order.  */

496   

497      if (reverse)

498        current_binding_level->names

499          = decls = nreverse (current_binding_level->names);

500      else

501        decls = current_binding_level->names;

502   

503      /* Output any nested inline functions within this block

504        if they weren't already output.  */

505      for (decl = decls; decl; decl = TREE_CHAIN (decl))

506        if (TREE_CODE (decl) == FUNCTION_DECL

507           && ! TREE_ASM_WRITTEN (decl)

508           && DECL_INITIAL (decl) != NULL_TREE

509           && TREE_ADDRESSABLE (decl)

510           && decl_function_context (decl) == current_function_decl )

511         {

           

523        }

524   

525      /* When not in function-at-a-time mode, expand_end_bindings will

526        warn about unused variables. But, in function-at-a-time mode

527        expand_end_bindings is not passed the list of variables in the

528        current scope, and therefore no warning is emitted. So, we

529        explicitly warn here.  */

530      if (!processing_template_decl )

531        warn_about_unused_variables (getdecls ());

532   

533      /* If there were any declarations or structure tags in that level,

534        or if this level is a function body,

535        create a BLOCK to record them for the life of this function.  */

536      block = NULL_TREE;

       

550      /* We still support the old for-scope rules, whereby the variables

551        in a for-init statement were in scope after the for-statement

552        ended. We only use the new rules if flag_new_for_scope is

553        nonzero.  */

554      leaving_for_scope

555        = current_binding_level->kind == sk_for && flag_new_for_scope == 1;

556   

557      /* Remove declarations for all the DECLs in this level.  */

558      for (link = decls; link; link = TREE_CHAIN (link))

559      {

560        if (leaving_for_scope && TREE_CODE (link) == VAR_DECL

561           && DECL_NAME (link))

562        {

           

619        }

620        else

621        {

622          /* Remove the binding.  */

623          decl = link;

624          if (TREE_CODE (decl) == TREE_LIST)

625            decl = TREE_VALUE (decl);

626          if (DECL_P (decl))

627            pop_binding (DECL_NAME (decl), decl);

628          else if (TREE_CODE (decl) == OVERLOAD)

629            pop_binding (DECL_NAME (OVL_FUNCTION (decl)), decl);

630          else

631            abort ();

632        }

633      }

634   

635      /* Remove declarations for any `for' variables from inner scopes

636        that we kept around.  */

637      for (link = current_binding_level->dead_vars_from_for;

638          link; link = TREE_CHAIN (link))

639        pop_binding (DECL_NAME (TREE_VALUE (link)), TREE_VALUE (link));

640   

641      /* Restore the IDENTIFIER_TYPE_VALUEs.  */

642      for (link = current_binding_level->type_shadowed;

643          link; link = TREE_CHAIN (link))

644        SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link), TREE_VALUE (link));

645   

646      /* Restore the IDENTIFIER_LABEL_VALUEs for local labels.  */

647      for (link = current_binding_level->shadowed_labels;

648          link;

649          link = TREE_CHAIN (link))

650        pop_label (TREE_VALUE (link), TREE_PURPOSE (link));

       

682      kind = current_binding_level->kind;

683   

684      leave_scope ();

       

722      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, block);

723    }

 

As names field of the associated cxx_scope of the binding scope records the declarations within, and relevant IDENTIFIER_NODE has the bindings field to represent the binding between the name and the declaration in the scope. At exitting of the scope, it no doubt should remove these bindings. Then it can safely jump up to the upper scope level.

 

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