ANSI Doc No: X3J16/93-0066 ISO Doc No: WG21/N0273 Date: June 22, 1993 Project: Programming Language C++ Ref Doc: Reply To: Eric J. Krohn krohn@bae.bellcore.com +1 908 699-2708 Combining Qualifiers in the Draft Syntax for C++ 1. Abstract The C++ grammar in the working paper uses class-name :: qualifiers in many places. The introduction of namespaces (X3J16/93-0055) will further multiply these rules since anywhere that class-name :: is used in the grammar a similar rule using namespace-name :: must be added. This paper proposes creating a new grammar rule, qualifier, to handle qualifier names uniformly and using that rule in the rest of the grammar. 2. The Current Syntax The current grammar rules relevant to qualifiers are shown in Appendix I. 3. Consolidation of Qualifiers Note that the token sequence class-name:: appears in the rules for qualified-type-name-specifier, nested-class-specifier. Similarly, the sequence qualified-class-specifier:: appears in the rules for new-declarator and ptr-operator. Note, too, that qualified-class-specifier and nested-class-specifier are used for two different purposes: 1. qualified-class-specifier without an immediately following :: represents the name of a nested class in simple-type- specifier, base-specifier, and mem-initializer 2. qualified-class-specifier with an immediately following :: represents a class qualifier in new-declarator, elaborated-type-specifier, and ptr-operator. 3. nested-class-specifier with an immediately following :: represents a class qualifier in qualified-id 4. nested-class-specifier without an immediately following :: is used only in qualified-class-specifier and represents whatever the qualified-class-specifier represents (either a class qualifier or a nested class name). I propose to eliminate this duplication of uses by introducing a new rule, qualifier, to represent a qualifier beginning with a name and ending with a ::. June 22, 1993 Page 2 X3J16/93-0066 WG21/N0273 qualifier: identifier :: qualifier(opt) template-class-id :: qualifier(opt) The identifier immediately preceding a :: may be a class-name, a typedef of a class-name, a namespace name, or a namespace alias. 3.1 Working Paper 5.1p8 Note that the Working Paper refers to nested-class-specifier in the text, so we have to repair those references. A nested-class-specifier (f9.1) followed by :: and the name of a member of that class (f9.2), or a member of a base of that class (f10), is a qualified-id; its type is the type of the member. Possible rewording: A qualifier naming a class (f?.?) followed by the name of a member of that class (f9.2), or a member of a base of that class (f10), is a qualified-id; its type is the type of the member. 3.2 Working Paper 11.5p1 When a protected member of a base class appears in a qualified-id in a friend or a member function of a derived class the nested-class-specifier must name the derived class. Possible rewording: When a protected member of a base class appears in a qualified-id in a friend or a member function of a derived class the qualifier must name the derived class. 3.3 Working Paper 7.1.6p7 qualified-class-specifier is mentioned in the text thus: When a qualified-class-specifier is used, the identifier must already have been declared as a class-name. Rewording should apply this statement to enums as well. When a qualifier is used with class-key, the identifier must already have been declared as a class-name. When a qualifier is used with enum, the identifier must already have been declared as a enum-name. June 22, 1993 Page 3 X3J16/93-0066 WG21/N0273 3.4 Working Paper 8.2.3p1 In a declaration T D where D has the form qualified-class-specifier :: * cv-qualifier-seq(opt) D1 the type of the contained declarator-id is ... cv- qualifier-seq pointer to member of class class-name of type T1, where T1 is the type assigned to the contained declarator-id in the declaration T D1. Possible rewording: In a declaration T D where D has the form qualifier * cv-qualifier-seq(opt) D1 the type of the contained declarator-id is ... cv- qualifier-seq pointer to member of class class-name of type T1, where T1 is the type assigned to the contained declarator-id in the declaration T D1. 3.5 Consolidated Grammar Rules Here are the changes to use qualifier. I retain the rule qualified-class-specifier solely for use in mem-initializer and base-specifier. new-declarator: * cv-qualifier-seq(opt) new-declarator(opt) ::(opt) qualifier * cv-qualifier-seq(opt) new-declarator(opt) new-declarator(opt) [ expression ] qualified-id: qualifier id-expression elaborated-type-specifier: class-key ::(opt) qualifier(opt) identifier enum ::(opt) qualifier(opt) identifier qualified-type-name-specifier: DELETED qualified-class-specifier: ::(opt) qualifier(opt) class-name nested-class-specifier: DELETED ptr-operator: * cv-qualifier-seq(opt) & cv-qualifier-seq(opt) ::(opt) qualifier * cv-qualifier-seq(opt) declarator-id: id-expression ~ class-name qualifier(opt) type-name namespace-alias-definition: namespace identifier = ::(opt) qualifier(opt) identifier ; using-declaration: using ::(opt) qualifier id-expression using ::(opt) qualifier ( using-list ) ; using-directive: using namespace ::(opt) qualifier(opt) identifier ; June 22, 1993 Page 4 X3J16/93-0066 WG21/N0273 namespace-name: DELETED With this change, the description of using-declaration must state that the qualifier must name a namespace. 4. Other Problems Noted The rules for id-expression and qualified-id are mutually recursive leaving ambiguous which rule gets the qualifier. Rewrite qualified-id without the recursive reference to id- expression. qualified-id: qualifier identifier qualifier operator-function-id qualifier conversion-function-id qualifier ~ class-name The grammar in the working paper makes no allowance for enum ::identifier, nor class ::identifier, though both enum :: qualifier identifier and class :: qualifier identifier are well- formed. The proposed change to elaborated-type-specifier allows both forms. The proposed namespace-name differs from the pattern of existing rules class-name, enum-name, template-name, and type-name in that it already contains a qualifier. More uniform would be namespace-name: identifier There are various places in both the prose and the grammar rules where shorthand names might be useful for brevity. qualified-class-name: ::(opt) qualifier(opt) class-name qualified-enum-name: ::(opt) qualifier(opt) enum-name qualified-type-name: ::(opt) qualifier(opt) type-name qualified-namespace-name: ::(opt) qualifier(opt) namespace-name June 22, 1993 Page 5 X3J16/93-0066 WG21/N0273 Appendix I - Original Grammar Rules These grammar rules assume the changes proposed in X3J16/93-0065 WG21/N0272. new-declarator: * cv-qualifier-seq(opt) new-declarator(opt) qualified-class-specifier :: * cv-qualifier-seq(opt) new-declarator(opt) direct-new-declarator id-expression: identifier operator-function-id conversion-function-id ~ class-name qualified-id qualified-id: nested-class-specifier :: id-expression type-specifier: simple-type-specifier class-specifier enum-specifier elaborated-type-specifier const volatile simple-type-specifier: ::(opt) qualified-type-name-specifier char short int long signed unsigned float double void elaborated-type-specifier: class-key identifier class-key qualified-class-specifier :: identifier enum identifier enum qualified-class-specifier :: identifier qualified-type-name-specifier: type-name class-name :: qualified-type-name-specifier qualified-class-specifier: nested-class-specifier :: nested-class-specifier nested-class-specifier: class-name class-name :: nested-class-specifier ptr-operator: * cv-qualifier-seq(opt) & cv-qualifier-seq(opt) qualified-class-specifier :: * cv-qualifier-seq(opt) June 22, 1993 Page 6 X3J16/93-0066 WG21/N0273 declarator-id: id-expression ~ class-name qualified-type-name-specifier base-specifier: qualified-class-specifier virtual access-specifier(opt) qualified-class-specifier access-specifier virtual(opt) qualified-class-specifier mem-initializer: qualified-class-specifier ( expression-list(opt) ) identifier ( expression-list(opt) ) namespace-alias-definition: namespace identifier = namespace-name ; using-declaration: using qualified-namespace-name :: id-expression ; using qualified-namespace-name :: ( using-list ) ; using-directive: using namespace namespace-name ; namespace-name: identifier identifier :: namespace-name June 22, 1993 Page 7 X3J16/93-0066 WG21/N0273 Appendix II - Grammar Changes Proposed grammar changes showing all proposed modifications. qualifier: identifier :: qualifier(opt) template-class-id :: qualifier(opt) new-declarator: * cv-qualifier-seq(opt) new-declarator(opt) ::(opt) qualifier * cv-qualifier-seq(opt) new-declarator(opt) new-declarator(opt) [ expression ] id-expression: identifier operator-function-id conversion-function-id ~ class-name qualified-id qualified-id: qualifier identifier qualifier operator-function-id qualifier conversion-function-id qualifier ~ class-name type-specifier: simple-type-specifier class-specifier enum-specifier elaborated-type-specifier const volatile simple-type-specifier: ::(opt) qualifier(opt) type-name char short int long signed unsigned float double void elaborated-type-specifier: class-key ::(opt) qualifier(opt) identifier enum ::(opt) qualifier(opt) identifier qualified-type-name-specifier: DELETED qualified-class-specifier: ::(opt) qualifier(opt) class-name nested-class-specifier: DELETED ptr-operator: * cv-qualifier-seq(opt) & cv-qualifier-seq(opt) June 22, 1993 Page 8 X3J16/93-0066 WG21/N0273 ::(opt) qualifier * cv-qualifier-seq(opt) declarator-id: id-expression ~ class-name qualifier(opt) type-name base-specifier: qualified-class-specifier virtual access-specifier(opt) qualified-class-specifier access-specifier virtual(opt) qualified-class-specifier mem-initializer: ::(opt) qualifier(opt) class-name ( expression-list(opt) ) identifier ( expression-list(opt) ) namespace-alias-definition: namespace identifier = ::(opt) qualifier(opt) identifier ; using-declaration: using ::(opt) qualifier id-expression using ::(opt) qualifier ( using-list ) ; using-directive: using namespace ::(opt) qualifier(opt) identifier ; namespace-name: identifier