During parsing, we may encounter error statement, to continue parsing as possible, it is prefer to advance to the nearest “>” (of course, if the statement is correct, the next token should be “>”). Next for parsing member template like:
template<class T> class string {
public:
template<class T2> int compare(const T2&);
template<class T2> string(const string<T2>& s) { /* ... */ }
// ...
};
template<class T> template<class T2> int string<T>::compare(const T2& s) {}
At line 14458 checks for the part “template<class T2>” of the method and processes it in recursion at line 14460.
cp_parser_template_declaration_after_export (continue)
14452 /* Look for the `>'. */
14453 cp_parser_skip_until_found (parser, CPP_GREATER, "`>'");
14454 /* We just processed one more parameter list. */
14455 ++parser->num_template_parameter_lists;
14456 /* If the next token is `template', there are more template
14457 parameters. */
14458 if (cp_lexer_next_token_is_keyword (parser->lexer,
14459 RID_TEMPLATE))
14460 cp_parser_template_declaration_after_export (parser, member_p);
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 }
In the statement of our run-through example, the unparsed part is: “class SingleThreaded {…”; according to the syntax rule, it should be decl-specifier-seq. Structure decl-specifier-seq contains sequence of decl-specifier, which is a complex structure shown in below.
14508 static tree
14509 cp_parser_single_declaration (cp_parser* parser, in parser.c
14510 bool member_p,
14511 bool* friend_p)
14512 {
14513 int declares_class_or_enum;
14514 tree decl = NULL_TREE;
14515 tree decl_specifiers;
14516 tree attributes;
14517 bool function_definition_p = false;
14518
14519 /* This function is only used when processing a template
14520 declaration. */
14521 if (innermost_scope_kind () != sk_template_parms
14522 && innermost_scope_kind () != sk_template_spec)
14523 abort ();
14524
14525 /* Defer access checks until we know what is being declared. */
14526 push_deferring_access_checks (dk_deferred);
14527
14528 /* Try the `decl-specifier-seq [opt] init-declarator [opt]'
14529 alternative. */
14530 decl_specifiers
14531 = cp_parser_decl_specifier_seq (parser,
14532 CP_PARSER_FLAGS_OPTIONAL,
14533 &attributes,
14534 &declares_class_or_enum);
14535 if (friend_p)
14536 *friend_p = cp_parser_friend_p (decl_specifiers);
14537
14538 /* There are no template typedefs. */
14539 if (cp_parser_typedef_p (decl_specifiers))
14540 {
14541 error ("template declaration of `typedef'");
14542 decl = error_mark_node;
14543 }
14544
14545 /* Gather up the access checks that occurred the
14546 decl-specifier-seq. */
14547 stop_deferring_access_checks ();
In below function, if declares_class_or_enum is non-null, *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)
6642 static tree
6643 cp_parser_decl_specifier_seq (cp_parser* parser, in parser.c
6644 cp_parser_flags flags,
6645 tree* attributes,
6646 int* declares_class_or_enum)
6647 {
6648 tree decl_specs = NULL_TREE;
6649 bool friend_p = false;
6650 bool constructor_possible_p = !parser->in_declarator_p;
6651
6652 /* Assume no class or enumeration type is declared. */
6653 *declares_class_or_enum = 0;
6654
6655 /* Assume there are no attributes. */
6656 *attributes = NULL_TREE;
6657
6658 /* Keep reading specifiers until there are no more to read. */
6659 while (true)
6660 {
6661 tree decl_spec = NULL_TREE;
6662 bool constructor_p;
6663 cp_token *token;
6664
6665 /* Peek at the next token. */
6666 token = cp_lexer_peek_token (parser->lexer);
6667 /* Handle attributes. */
6668 if (token->keyword == RID_ATTRIBUTE)
6669 {
6670 /* Parse the attributes. */
6671 decl_spec = cp_parser_attributes_opt (parser);
6672 /* Add them to the list. */
6673 *attributes = chainon (*attributes, decl_spec);
6674 continue;
6675 }
We skip GCC entension attribution above and go on for the handling of decl-specifier excluding type-specifier. See that among these items, friend, function-specifier, typedef, storage-class-specifier must be followed by type-specifier (see the break statement). Local variable decl_spec records the information about these items.
cp_parser_decl_specifier_seq (continue)
6676 /* If the next token is an appropriate keyword, we can simply
6677 add it to the list. */
6678 switch (token->keyword)
6679 {
6680 case RID_FRIEND:
6681 /* decl-specifier:
6682 friend */
6683 if (friend_p)
6684 error ("duplicate `friend'");
6685 else
6686 friend_p = true;
6687 /* The representation of the specifier is simply the
6688 appropriate TREE_IDENTIFIER node. */
6689 decl_spec = token->value;
6690 /* Consume the token. */
6691 cp_lexer_consume_token (parser->lexer);
6692 break;
6693
6694 /* function-specifier:
6695 inline
6696 virtual
6697 explicit */
6698 case RID_INLINE:
6699 case RID_VIRTUAL:
6700 case RID_EXPLICIT:
6701 decl_spec = cp_parser_function_specifier_opt (parser);
6702 break;
6703
6704 /* decl-specifier:
6705 typedef */
6706 case RID_TYPEDEF:
6707 /* The representation of the specifier is simply the
6708 appropriate TREE_IDENTIFIER node. */
6709 decl_spec = token->value;
6710 /* Consume the token. */
6711 cp_lexer_consume_token (parser->lexer);
6712 /* A constructor declarator cannot appear in a typedef. */
6713 constructor_possible_p = false;
6714 /* The "typedef" keyword can only occur in a declaration; we
6715 may as well commit at this point. */
6716 cp_parser_commit_to_tentative_parse (parser);
6717 break;
6718
6719 /* storage-class-specifier:
6720 auto
6721 register
6722 static
6723 extern
6724 mutable
6725
6726 GNU Extension:
6727 thread */
6728 case RID_AUTO:
6729 case RID_REGISTER:
6730 case RID_STATIC:
6731 case RID_EXTERN:
6732 case RID_MUTABLE:
6733 case RID_THREAD:
6734 decl_spec = cp_parser_storage_class_specifier_opt (parser);
6735 break;
6736
6737 default:
6738 break;
6739 }
Routine cp_parser_function_specifier_opt and cp_parser_storage_class_specifier_opt just double check expected token fetched.
In the language, decl-specifier-seq specify how names are to be interpreted, while a declarator delcares a single object, function, or type, within a declaration. Considering constructor, for example:
class A {
public:
A();
};
In A(); A should not be parsed as decl-specifier, it is not declaration, instead it is declarator. Notice that A() aligns with the format of simple-declaration, it hasn’t decl-specifier part. As it is a such special case, it needs be handled specially. Of course, it will not be a problem during parsing declarator, note that at line 6713, constructor_possible_p is the reverse of in_declarator_p slot in parser which is true during parsing declarator.
cp_parser_decl_specifier_seq (continue)
6741 /* Constructors are a special case. The `S' in `S()' is not a
6742 decl-specifier; it is the beginning of the declarator. */
6743 constructor_p = (!decl_spec
6744 && constructor_possible_p
6745 && cp_parser_constructor_declarator_p (parser,
6746 friend_p));
Also notice that parsing of constructor here never consumes tokens no matter it successes or not as it is not decl-specifier but declarator. And finding it just means error. To avoid deviating to far away from our focus, we just skip the parsing of constructor here temperarily.
If above cases can’t be found, now we can try type-specifier as below. Type-specifier is the key part of decl-specifier-seq, which is the major part of the declaration.
cp_parser_decl_specifier_seq (continue)
6748 /* If we don't have a DECL_SPEC yet, then we must be looking at
6749 a type-specifier. */
6750 if (!decl_spec && !constructor_p)
6751 {
6752 int decl_spec_declares_class_or_enum;
6753 bool is_cv_qualifier;
6754
6755 decl_spec
6756 = cp_parser_type_specifier (parser, flags,
6757 friend_p,
6758 /*is_declaration=*/true,
6759 &decl_spec_declares_class_or_enum,
6760 &is_cv_qualifier);
6761
6762 *declares_class_or_enum |= decl_spec_declares_class_or_enum;
6763
6764 /* If this type-specifier referenced a user-defined type
6765 (a typedef, class-name, etc.), then we can't allow any
6766 more such type-specifiers henceforth.
6767
6768 [dcl.spec]
6769
6770 The longest sequence of decl-specifiers that could
6771 possibly be a type name is taken as the
6772 decl-specifier-seq of a declaration. The sequence shall
6773 be self-consistent as described below.
6774
6775 [dcl.type]
6776
6777 As a general rule, at most one type-specifier is allowed
6778 in the complete decl-specifier-seq of a declaration. The
6779 only exceptions are the following:
6780
6781 -- const or volatile can be combined with any other
6782 type-specifier.
6783
6784 -- signed or unsigned can be combined with char, long,
6785 short, or int.
6786
6787 -- ..
6788
6789 Example:
6790
6791 typedef char* Pc;
6792 void g (const int Pc);
6793
6794 Here, Pc is *not* part of the decl-specifier seq; it's
6795 the declarator. Therefore, once we see a type-specifier
6796 (other than a cv-qualifier), we forbid any additional
6797 user-defined types. We *do* still allow things like `int
6798 int' to be considered a decl-specifier-seq, and issue the
6799 error message later. */
6800 if (decl_spec && !is_cv_qualifier)
6801 flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES;
6802 /* A constructor declarator cannot follow a type-specifier. */
6803 if (decl_spec)
6804 constructor_possible_p = false;
6805 }
The abbreviate syntax tree of type-specifier is shown in below.
type-specifier
├ simple-type-specifier
├ class-specifier
├ enum-specifier
├ elaborated-type-specifier
├ cv-qualifier
GUN ext Ⅼ __complex__
In below function, parameter declares_class_or_enum if non-null, and the type-specifier is a class-specifier, enum-specifier, or elaborated-type-specifier, then *declares_class_or_enum is set to a nonzero value. The value is 1 if a type is declared, 2 if it is defined; otherwise, it is set to zero. And if is_cv_qualifier is non-null, and the type-specifier is a cv-qualifier, then *is_cv_qualifier is set to true; otherwise, it is set to false.
8713 static tree
8714 cp_parser_type_specifier (cp_parser* parser, in parser.c
8715 cp_parser_flags flags,
8716 bool is_friend,
8717 bool is_declaration,
8718 int* declares_class_or_enum,
8719 bool* is_cv_qualifier)
8720 {
8721 tree type_spec = NULL_TREE;
8722 cp_token *token;
8723 enum rid keyword;
8724
8725 /* Assume this type-specifier does not declare a new type. */
8726 if (declares_class_or_enum)
8727 *declares_class_or_enum = 0;
8728 /* And that it does not specify a cv-qualifier. */
8729 if (is_cv_qualifier)
8730 *is_cv_qualifier = false;
8731 /* Peek at the next token. */
8732 token = cp_lexer_peek_token (parser->lexer);
8733
8734 /* If we're looking at a keyword, we can use that to guide the
8735 production we choose. */
8736 keyword = token->keyword;
8737 switch (keyword)
8738 {
8739 case RID_ENUM:
...
8763 /* Any of these indicate either a class-specifier, or an
8764 elaborated-type-specifier. */
8765 case RID_CLASS:
8766 case RID_STRUCT:
8767 case RID_UNION:
8768 /* Parse tentatively so that we can back up if we don't find a
8769 class-specifier or enum-specifier. */
8770 cp_parser_parse_tentatively (parser);
8771 /* Look for the class-specifier. */
8772 type_spec = cp_parser_class_specifier (parser);
8773 /* If that worked, we're done. */
8774 if (cp_parser_parse_definitely (parser))
8775 {
8776 if (declares_class_or_enum)
8777 *declares_class_or_enum = 2;
8778 return type_spec;
8779 }
The coming tokens of the second statement of our example form the class-specifier. They are further handled by cp_parser_class_specifier.