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.