在解析过程中,我们可能会遇到错误的语句,为了尽可能的继续解析,最好前进到最近的“>”(显然,如果语句是正确的,下一个符号应该是“>”)。接下来为了解析如下类模板的成员模板函数:
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) {}
14458行检查方法的“template<class T2>”部分,并在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 }
在我们这个贯穿整章的例子的语句中,现在未解析的部分是“class SingleThreaded {…”,根据语法规则,它应该是decl-specifier-seq。decl-specifier-seq结构包含了decl-specifier序列,decl-specifier是如下的一个复杂结构。
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 ();
在下面的函数中,如果declares_class_or_enum非空,*declares_class_or_enum被按位设置为以下标记:
1:其中一个decl-specifiers是elaborated-type-specifier(即一个类型声明)。
2:其中一个decl-specifiers是enum-specifier或class-specifier(一个类型定义)。
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 }
我们跳过上面的GCC扩展的属性。继续除type-specifier以外的decl-specifier的解析。 看到在这些项中,friend,function-specifier,typedef,storage-class-specifier都必须在后面跟有type-specifier(注意break语句)。局部变量decl_spec记录这些项的信息。
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 }
例程cp_parser_function_specifier_opt及cp_parser_storage_class_specifier_opt只是再次确认以获取期望的符号。
在C++中,decl-specifier-seq指出如何解释名字,而一个声明符(declarator)则在声明中声明了一个对象,函数或者类型。例如,考虑构造函数:
class A {
public:
A();
};
在语句“A();”中,A不应该被按decl-specifier来解析,它不是声明,而是声明符。注意到A()与simple-declaration的格式相符,它没有decl-specifier部分。因为它是一个特殊的情况,需要特殊的处理。显然,在解析声明符的过程中,这不是一个问题,注意到在6713行,constructor_possible_p是parser的in_declarator_p域的取反,在解析声明符的过程中,in_declarator_p为true。
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));
同样注意到解析构造函数,不管成功与否,都不“消化”符号,因为构造函数不是decl-specifier而是声明符。而找到构造函数意味着错误。为了不至于离开我们的例子太远,我们暂时跳过对构造函数的解析。
如果上面的情形都未能发现,那么现在我们可以在下面尝试按type-specifier解析之。Type-specifier是decl-specifier-seq的关键部分,它是声明的主体。
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 }
type-specifier的简要语法树显示如下。
type-specifier
├ simple-type-specifier
├ class-specifier
├ enum-specifier
├ elaborated-type-specifier
├ cv-qualifier
GUN ext Ⅼ __complex__
在下面的函数中,参数declares_class_or_enum如果非空,并且type-specifier是一个class-specifier,enum-specifier或者elaborated-type-specifier,那么*declares_class_or_enum被设置为一个非0值;如果声明一个类型,其值为1,如果定义一个类型,其值则为2。否则,它被设置为0。而如果is_cv_qualifier非空,并且type-specifier是一个cv-qualifier,那么*is_cv_qualifier被设为true,否则设为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 }
我们例子的第二条语句剩下的符号构成了class-specifier。它们进一步由cp_parser_class_specifier处理。