5.12.3.2.1.1.3.6.1. Exit nested class
Further, when consuming the tailing “;” of the class, it means we are going to exit the class scope and re-enter its containing scope. This operation is done by popclass at line 5257.
5564 void
5565 popclass (void) in class.c
5566 {
5567 poplevel_class ();
5568 pop_class_decls ();
5569
5570 current_class_depth --;
5571 current_class_name = current_class_stack [current_class_depth ].name;
5572 current_class_type = current_class_stack [current_class_depth ].type;
5573 current_access_specifier = current_class_stack [current_class_depth ].access;
5574 if (current_class_stack [current_class_depth ].names_used)
5575 splay_tree_delete (current_class_stack [current_class_depth ].names_used);
5576 }
In poplevel_class , sees that when we exit from class stack, previous_class_type and previous_class_values caches the toppest class which may be reused in pushclass . However, for non-top class, it is not reasonable to cache them, but releases the built relation of identifers declared within the class. Considering following example:
// Global scope
int j;
class A
{
public :
int j;
typedef int inner_type;
class B {
int j;
inner_type k; // inner_type is A:: inner_type
public :
int get_j() const {
return j; // should return B::j
}
inner_type get_k() const { return k; }
};
int get_j() const {
return j; // should return A::j
}
};
int get_j() {
return j; // should return ::j
}
Variable j are declared within global scope, class A and class B. But, in the front-end, the identifier node for j must be unique, so the three definitions should bind at this unique node. However according to the rule of name-lookup, the j used can be determined by the current scopes. For example, searching inner_type above within class B will finally result in searching class A and find out the definition. Nevertheless the regular searching is complex. Fortunately, many searchings can be avoided if we update the identifier’s definition when entering a scope. That is the purpose of field IDENTIFIER_CLASS_VALUE to record current definition for the identifier.
2581 void
2582 poplevel_class (void) in name-lookup.c
2583 {
2584 struct cp_binding_level *level = class_binding_level;
2585 tree shadowed;
2586
2587 timevar_push (TV_NAME_LOOKUP);
2588 my_friendly_assert (level != 0, 354);
2589
2590 /* If we're leaving a toplevel class, don't bother to do the setting
2591 of IDENTIFIER_CLASS_VALUE to NULL_TREE, since first of all this slot
2592 shouldn't even be used when current_class_type isn't set, and second,
2593 if we don't touch it here, we're able to use the cache effect if the
2594 next time we're entering a class scope, it is the same class. */
2595 if (current_class_depth != 1)
2596 {
2597 struct cp_binding_level* b;
2598
2599 /* Clear out our IDENTIFIER_CLASS_VALUEs. */
2600 for (shadowed = level->class_shadowed;
2601 shadowed;
2602 shadowed = TREE_CHAIN (shadowed))
2603 IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) = NULL_TREE;
2604
2605 /* Find the next enclosing class, and recreate
2606 IDENTIFIER_CLASS_VALUEs appropriate for that class. */
2607 b = level->level_chain;
2608 while (b && b->kind != sk_class)
2609 b = b->level_chain;
2610
2611 if (b)
2612 for (shadowed = b->class_shadowed;
2613 shadowed;
2614 shadowed = TREE_CHAIN (shadowed))
2615 {
2616 cxx_binding *binding;
2617
2618 binding = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed));
2619 while (binding && binding->scope != b)
2620 binding = binding->previous;
2621
2622 if (binding)
2623 IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed))
2624 = binding->value;
2625 }
2626 }
2627 else
2628 /* Remember to save what IDENTIFIER's were bound in this scope so we
2629 can recover from cache misses. */
2630 {
2631 previous_class_type = current_class_type ;
2632 previous_class_values = class_binding_level->class_shadowed;
2633 }
2634 for (shadowed = level->type_shadowed;
2635 shadowed;
2636 shadowed = TREE_CHAIN (shadowed))
2637 SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed));
2638
2639 /* Remove the bindings for all of the class-level declarations. */
2640 for (shadowed = level->class_shadowed;
2641 shadowed;
2642 shadowed = TREE_CHAIN (shadowed))
2643 pop_binding (TREE_PURPOSE (shadowed), TREE_TYPE (shadowed));
2644
2645 /* Now, pop out of the binding level which we created up in the
2646 `pushlevel_class' routine. */
2647 if (ENABLE_SCOPE_CHECKING)
2648 is_class_level = 1;
2649
2650 leave_scope ();
2651 timevar_pop (TV_NAME_LOOKUP);
2652 }
Clearly, above from line 2600 to 2603, the associated definition/declarator of the identifiers declared within the class are cleaned. Further, if the identifier in the class shadows the same identifier outside, type_shadowed field of the class node will record the definition/declarator shadowed, it is time to restore the shadowed definitions in FOR loop at line 2634 does.
As exiting from the class, the identifiers declared within can’t be visible in current scope without nested-name-specifier, it needs to remove the cxx_binding nodes of the identifiers leading to the class by pop_binding which is the reverse of push_binding .
376 void
377 pop_binding (tree id, tree decl) in name-lookup.c
378 {
379 cxx_binding *binding;
380
381 if (id == NULL_TREE)
382 /* It's easiest to write the loops that call this function without
383 checking whether or not the entities involved have names. We
384 get here for such an entity. */
385 return ;
386
387 /* Get the innermost binding for ID. */
388 binding = IDENTIFIER_BINDING (id);
389
390 /* The name should be bound. */
391 my_friendly_assert (binding != NULL, 0);
392
393 /* The DECL will be either the ordinary binding or the type
394 binding for this identifier. Remove that binding. */
395 if (binding->value == decl)
396 binding->value = NULL_TREE;
397 else if (binding->type == decl)
398 binding->type = NULL_TREE;
399 else
400 abort ();
401
402 if (!binding->value && !binding->type)
403 {
404 /* We're completely done with the innermost binding for this
405 identifier. Unhook it from the list of bindings. */
406 IDENTIFIER_BINDING (id) = binding->previous;
407
408 /* Add it to the free list. */
409 cxx_binding_free (binding);
410 }
411 }
Notice that the innermost binding is always at head of the bindings field of the identifier node which is fetched by IDENTIFIER_BINDING at line 388.
Also when entering the class, cache all of the fields that that class provides within its inheritance lattice may accelerate the searching within specified class, especially for those large ones greatly. It is done by push_class_decls in pushclass , so when leaving, the cache should be released by pop_class_decls from search_stack .
2323 void
2324 pop_class_decls (void) in search.c
2325 {
2326 /* We haven't pushed a search level when dealing with cached classes,
2327 so we'd better not try to pop it. */
2328 if (search_stack )
2329 search_stack = pop_search_level (search_stack );
2330 }
What’s more, the cxx_scope represents the binding scope of the class should also need be removed from the tree rooted by global namespace scope, as its members are invisible from global namespace. If the front-end doesn’t open ENABLE_SCOPE_CHECKING, the released cxx_scopes are chained by free_binding_level in leave_scope , and can be reused in begin_scope . If this switch is not opened, leave_scope will leave free_binding_level as following.
Figure 85 : freeing cxx_scope by leave_scope
After finializing the parsing by finish_struct , if the class is referred by elaberator-type-specifier like: “A::B::f”, at line 11926 pop_p refers to the scope of A::B:: which also have cxx_scope built and linked into the scope tree rooted by global namespace scope. When encountering the ending “;” just means it is going to exit to current binding scope. Then the scopes of A and B similarly need be removed from the tree.
We have seen and cached the definitions of the inline method of struct “Lock”, but they are still not handled. However, considering the example:
struct A {
struct B { void f() { sizeof (A); } };
};
It makes expand inline function f at the end of definition of B inapplicable. The appropriate point is the end of A – the outermost class. That is why all inline functions no matter which class they belonged are cached within unparsed_functions_queues in parser.
So in rest code of cp_parser_class_specifier , just pops up the deferring accessing control block from the control stack for struct “Lock”.
cp_parser_class_specifier (continue)
11928 /* If this class is not itself within the scope of another class,
11929 then we need to parse the bodies of all of the queued function
11930 definitions. Note that the queued functions defined in a class
11931 are not always processed immediately following the
11932 class-specifier for that class. Consider:
11933
11934 struct A {
11935 struct B { void f() { sizeof (A); } };
11936 };
11937
11938 If `f' were processed before the processing of `A' were
11939 completed, there would be no way to compute the size of `A'.
11940 Note that the nesting we are interested in here is lexical --
11941 not the semantic nesting given by TYPE_CONTEXT. In particular,
11942 for:
11943
11944 struct A { struct B; };
11945 struct A::B { void f() { } };
11946
11947 there is no need to delay the parsing of `A::B::f'. */
11948 if (--parser->num_classes_being_defined == 0)
11949 {
…
11996 }
11997
11998 /* Put back any saved access checks. */
11999 pop_deferring_access_checks ();
12000
12001 /* Restore the count of active template-parameter-lists. */
12002 parser->num_template_parameter_lists
12003 = saved_num_template_parameter_lists;
12004
12005 return type;
12006 }
And at last, the intermediate tree looks like following figure, and type returned refers to the node of RECORD_TYPE.
Figure 86 : At point of exiting struct Lock
5.12.3.2.1.1.3.6.1. Finish parsing as member
Return back to cp_parser_type_specifier from cp_parser_class_specifier , type_spec in turn refers to the RECORD_TYPE and declares_class_or_enum is set as 2 if the buffer provided. Further back to cp_parser_decl_specifier_seq , notice that the tailing “;” is not consumed yet. So it immediately make the function terminates (using GCC, if missing “;” for class definition, you may get lot of error, as cp_parser_decl_specifier_seq continues parsing for decl-specifier-seq), and as result, reference to the RECORD_TYPE is kept within decl_specs and returned.
Then back in cp_parser_member_declaration , following code will be executed.
cp_parser_member_declaration (continue)
12513 if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
12514 {
12515 /* If there was no decl-specifier-seq, and the next token is a
12516 `;', then we have something like:
12517
12518 struct S { ; };
12519
12520 [class.mem]
12521
12522 Each member-declaration shall declare at least one member
12523 name of the class. */
12524 if (!decl_specifiers)
12525 {
12526 if (pedantic )
12527 pedwarn ("extra semicolon");
12528 }
12529 else
12530 {
12531 tree type;
12532
12533 /* See if this declaration is a friend. */
12534 friend_p = cp_parser_friend_p (decl_specifiers);
12535 /* If there were decl-specifiers, check to see if there was
12536 a class-declaration. */
12537 type = check_tag_decl (decl_specifiers);
12538 /* Nested classes have already been added to the class, but
12539 a `friend' needs to be explicitly registered. */
12540 if (friend_p)
12541 {
…
12581 }
12582 /* If there is no TYPE, an error message will already have
12583 been issued. */
12584 else if (!type)
12585 ;
12586 /* An anonymous aggregate has to be handled specially; such
12587 a declaration really declares a data member (with a
12588 particular type), as opposed to a nested class. */
12589 else if (ANON_AGGR_TYPE_P (type))
12590 {
12591 /* Remove constructors and such from TYPE, now that we
12592 know it is an anonymous aggregate. */
12593 fixup_anonymous_aggr (type);
12594 /* And make the corresponding data member. */
12595 decl = build_decl (FIELD_DECL, NULL_TREE, type);
12596 /* Add it to the class. */
12597 finish_member_declaration (decl);
12598 }
12599 else
12600 cp_parser_check_access_in_redeclaration (TYPE_NAME (type));
12601 }
12602 }
…
12814 cp_parser_require (parser, CPP_SEMICOLON, "`;'");
12815 }
And arriving at here, the whole decl-specifier-seq is parsed, and we can have a better view about it. It is the right time to pick up contradictory components. For instance, using more than one type in declaration.
3474 tree
3475 check_tag_decl (tree declspecs) in decl.c
3476 {
3477 int found_type = 0;
3478 int saw_friend = 0;
3479 int saw_typedef = 0;
3480 tree ob_modifier = NULL_TREE;
3481 tree link;
3482 /* If a class, struct, or enum type is declared by the DECLSPECS
3483 (i.e, if a class-specifier, enum-specifier, or non-typename
3484 elaborated-type-specifier appears in the DECLSPECS),
3485 DECLARED_TYPE is set to the corresponding type. */
3486 tree declared_type = NULL_TREE;
3487 bool error_p = false;
3488
3489 for (link = declspecs; link; link = TREE_CHAIN (link))
3490 {
3491 tree value = TREE_VALUE (link);
3492
3493 if (TYPE_P (value) || TREE_CODE (value) == TYPE_DECL
3494 || (TREE_CODE (value) == IDENTIFIER_NODE
3495 && is_typename_at_global_scope (value)))
3496 {
3497 ++found_type;
3498
3499 if (found_type == 2 && TREE_CODE (value) == IDENTIFIER_NODE)
3500 {
3501 if (! in_system_header )
3502 pedwarn ("redeclaration of C++ built-in type `%T'", value);
3503 return NULL_TREE;
3504 }
3505
3506 if (TYPE_P (value)
3507 && ((TREE_CODE (value) != TYPENAME_TYPE && IS_AGGR_TYPE (value))
3508 || TREE_CODE (value) == ENUMERAL_TYPE))
3509 {
3510 my_friendly_assert (TYPE_MAIN_DECL (value) != NULL_TREE, 261);
3511 declared_type = value;
3512 }
3513 }
3514 else if (value == ridpointers [(int) RID_TYPEDEF])
3515 saw_typedef = 1;
3516 else if (value == ridpointers [(int) RID_FRIEND])
3517 {
3518 if (current_class_type == NULL_TREE
3519 || current_scope () != current_class_type )
3520 ob_modifier = value;
3521 else
3522 saw_friend = 1;
3523 }
3524 else if (value == ridpointers [(int) RID_STATIC]
3525 || value == ridpointers [(int) RID_EXTERN]
3526 || value == ridpointers [(int) RID_AUTO]
3527 || value == ridpointers [(int) RID_REGISTER]
3528 || value == ridpointers [(int) RID_INLINE]
3529 || value == ridpointers [(int) RID_VIRTUAL]
3530 || value == ridpointers [(int) RID_CONST]
3531 || value == ridpointers [(int) RID_VOLATILE]
3532 || value == ridpointers [(int) RID_EXPLICIT]
3533 || value == ridpointers [(int) RID_THREAD])
3534 ob_modifier = value;
3535 else if (value == error_mark_node)
3536 error_p = true;
3537 }
3538
3539 if (found_type > 1)
3540 error ("multiple types in one declaration");
3541
3542 if (declared_type == NULL_TREE && ! saw_friend && !error_p)
3543 pedwarn ("declaration does not declare anything");
3544 /* Check for an anonymous union. */
3545 else if (declared_type && IS_AGGR_TYPE_CODE (TREE_CODE (declared_type))
3546 && TYPE_ANONYMOUS_P (declared_type))
3547 {
3548 /* 7/3 In a simple-declaration, the optional init-declarator-list
3549 can be omitted only when declaring a class (clause 9) or
3550 enumeration (7.2), that is, when the decl-specifier-seq contains
3551 either a class-specifier, an elaborated-type-specifier with
3552 a class-key (9.1), or an enum-specifier. In these cases and
3553 whenever a class-specifier or enum-specifier is present in the
3554 decl-specifier-seq, the identifiers in these specifiers are among
3555 the names being declared by the declaration (as class-name,
3556 enum-names, or enumerators, depending on the syntax). In such
3557 cases, and except for the declaration of an unnamed bit-field (9.6),
3558 the decl-specifier-seq shall introduce one or more names into the
3559 program, or shall redeclare a name introduced by a previous
3560 declaration. [Example:
3561 enum { }; // ill-formed
3562 typedef class { }; // ill-formed
3563 --end example] */
3564 if (saw_typedef)
3565 {
3566 error ("missing type-name in typedef-declaration");
3567 return NULL_TREE;
3568 }
3569 /* Anonymous unions are objects, so they can have specifiers. */ ;
3570 SET_ANON_AGGR_TYPE_P (declared_type);
3571
3572 if (TREE_CODE (declared_type) != UNION_TYPE && pedantic
3573 && !in_system_header )
3574 pedwarn ("ISO C++ prohibits anonymous structs");
3575 }
3576
3577 else if (ob_modifier)
3578 {
3579 if (ob_modifier == ridpointers [(int) RID_INLINE]
3580 || ob_modifier == ridpointers [(int) RID_VIRTUAL])
3581 error ("`%D' can only be specified for functions", ob_modifier);
3582 else if (ob_modifier == ridpointers [(int) RID_FRIEND])
3583 error ("`%D' can only be specified inside a class", ob_modifier);
3584 else if (ob_modifier == ridpointers [(int) RID_EXPLICIT])
3585 error ("`%D' can only be specified for constructors",
3586 ob_modifier);
3587 else
3588 error ("`%D' can only be specified for objects and functions",
3589 ob_modifier);
3590 }
3591
3592 return declared_type;
3593 }
Note that if the using of keywords is valid, at here, their meaning should be integrated into flags in node of decl-specifier-seq, nodes of these keywords shouldn’t be present. Once found, it means error, which is handled by block at line 3577. Anyway the node of type declared is returned by the function. For the type returned by check_tag_decl , if it is not an annoymous class, it checks if decl is redeclared with different access than its original declaration. This applies to nested classes and nested class templates and done by below function.
15282 static void cp_parser_check_access_in_redeclaration (tree decl) in parser.c
15283 {
15284 if (!CLASS_TYPE_P (TREE_TYPE (decl)))
15285 return ;
15286
15287 if ((TREE_PRIVATE (decl)
15288 != (current_access_specifier == access_private_node))
15289 || (TREE_PROTECTED (decl)
15290 != (current_access_specifier == access_protected_node)))
15291 error ("%D redeclared with different access", decl);
15292 }