Studying note of GCC-3.4.6 source (113)

来源:互联网 发布:floor php 编辑:程序博客网 时间:2024/06/12 20:23

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 codewill 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     thenext token is a `;', then this declaration does not declare

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

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

14565     Inthat 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     ofsomething 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   returndecl;

14591 }

 

As we have seen, declares_class_or_enum is set to the bitwise orof 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 aclass-specifier (i.e., a type definition)

So if declares_class_or_enumis non-zero, it needs further to see if it is the class definition. If so, somesainty check should be taken just like those executed for nested class informer 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 seeif 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 whichshould 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       returnNULL_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       sendsthat 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     returnt;

3636   }

 

Above check_tag_decl returns the type declared (nodeof *_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, meansit’s not a type declaration, as cp_parser_single_declaration is only invokedby cp_parser_explicit_specializationor cp_parser_template_declaration_after_export(here is the rear), the left possibility is of function template, which isparsed by cp_parser_init_declaratorat 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       endknow.  */

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     (Eventhough 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, soargument member_pis false. Then for the example, the only operation is done by finish_template_decl.

 

2208   void

2209   finish_template_decl (tree parms)                                                      insemantics.c

2210   {

2211     if (parms)

2212       end_template_decl ();

2213     else

2214       end_specialization ();

2215   }

 

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

 

2279   void

2280   end_template_decl (void)                                                                                inpt.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 edgeof its scope. The scope is closed by finish_scope too. And remember to decreasethe number of template declaration under processing. Refers to figurelayout of nested template parameters, above at line 2291, field TREE_CHAINof current_template_parmsrefers 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. Aswe are exiting from class scope, so argument functionbody is 0; and keep is0 then no BLOCK node will be created for the declarations within the scope.

 

423    tree

424    poplevel (int keep, int reverse, int functionbody)                                               indecl.c

425    {

426      tree link;

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

428        Put itinto 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        Butparameter 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        ifthey 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        warnabout 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 ifthis level is a function body,

535        createa 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 afor-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        thatwe 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 scoperecords the declarations within, and relevant IDENTIFIER_NODE has the bindingsfield to represent the binding between the name and the declaration in thescope. At exitting of the scope, it no doubt should remove these bindings. Thenit can safely jump up to the upper scope level.

 

原创粉丝点击