hokein created this revision. hokein added a reviewer: sammccall. Herald added a project: All. hokein requested review of this revision. Herald added a subscriber: alextsao1999. Herald added a project: clang-tools-extra.
The motivation is to eliminate a false ambiguous parse of tempalte-arugment-list, see test file for details. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D134302 Files: clang-tools-extra/pseudo/lib/cxx/CXX.cpp clang-tools-extra/pseudo/lib/cxx/cxx.bnf clang-tools-extra/pseudo/test/cxx/ellipsis-in-abstractor-declarator.cpp Index: clang-tools-extra/pseudo/test/cxx/ellipsis-in-abstractor-declarator.cpp =================================================================== --- /dev/null +++ clang-tools-extra/pseudo/test/cxx/ellipsis-in-abstractor-declarator.cpp @@ -0,0 +1,6 @@ +// RUN: clang-pseudo -grammar=cxx -source=%s --print-forest | FileCheck %s + +// Verify that we don't misparse T... as a complete type-id template argument +Foo<T...> abc; +// CHECK-NOT: template-argument-list := <ambiguous> +// CHECK: template-argument-list := template-argument ... Index: clang-tools-extra/pseudo/lib/cxx/cxx.bnf =================================================================== --- clang-tools-extra/pseudo/lib/cxx/cxx.bnf +++ clang-tools-extra/pseudo/lib/cxx/cxx.bnf @@ -681,7 +681,7 @@ template-argument-list := template-argument ..._opt template-argument-list := template-argument-list , template-argument ..._opt template-argument := constant-expression -template-argument := type-id +template-argument := type-id [guard] template-argument := id-expression constraint-expression := logical-or-expression deduction-guide := explicit-specifier_opt template-name ( parameter-declaration-list_opt ) -> simple-template-id ; Index: clang-tools-extra/pseudo/lib/cxx/CXX.cpp =================================================================== --- clang-tools-extra/pseudo/lib/cxx/CXX.cpp +++ clang-tools-extra/pseudo/lib/cxx/CXX.cpp @@ -182,6 +182,22 @@ return true; } +bool guardEllipsisInAbstractDeclarator(const GuardParams& P) { + const auto* TypeID = P.RHS[0]; + assert(TypeID->symbol() == Symbol::type_id); + if (TypeID->kind() == ForestNode::Sequence && + TypeID->rule() == rule::type_id::type_specifier_seq__abstract_declarator) { + const auto* AbstractDeclarator = TypeID->elements()[1]; + for (auto &Child : AbstractDeclarator->descendants()) { + if (Child.kind() == ForestNode::Terminal) + if (symbolToToken(Child.symbol()) == clang::tok::ellipsis) + return false; + } + return true; + } + return true; +} + // Whether this e.g. decl-specifier contains an "exclusive" type such as a class // name, and thus can't combine with a second exclusive type. // @@ -353,6 +369,16 @@ decl_specifier_seq__L_SQUARE__identifier_list__R_SQUARE__initializer__SEMI, specifiesStructuredBinding}, + // Per C++ [dcl.fct#25] -- A declarator-id or abstract-declarator containing + // an ellipsis shall only be used in a parameter-declaration. + // + // We should not misparse the `int...` in `vector<int...> abc;` as a + // type-id template argument (... is an abstractor-declarator). + { + rule::template_argument::type_id, + guardEllipsisInAbstractDeclarator + }, + // The grammar distinguishes (only) user-defined vs plain string literals, // where the clang lexer distinguishes (only) encoding types. {rule::user_defined_string_literal_chunk::STRING_LITERAL,
Index: clang-tools-extra/pseudo/test/cxx/ellipsis-in-abstractor-declarator.cpp =================================================================== --- /dev/null +++ clang-tools-extra/pseudo/test/cxx/ellipsis-in-abstractor-declarator.cpp @@ -0,0 +1,6 @@ +// RUN: clang-pseudo -grammar=cxx -source=%s --print-forest | FileCheck %s + +// Verify that we don't misparse T... as a complete type-id template argument +Foo<T...> abc; +// CHECK-NOT: template-argument-list := <ambiguous> +// CHECK: template-argument-list := template-argument ... Index: clang-tools-extra/pseudo/lib/cxx/cxx.bnf =================================================================== --- clang-tools-extra/pseudo/lib/cxx/cxx.bnf +++ clang-tools-extra/pseudo/lib/cxx/cxx.bnf @@ -681,7 +681,7 @@ template-argument-list := template-argument ..._opt template-argument-list := template-argument-list , template-argument ..._opt template-argument := constant-expression -template-argument := type-id +template-argument := type-id [guard] template-argument := id-expression constraint-expression := logical-or-expression deduction-guide := explicit-specifier_opt template-name ( parameter-declaration-list_opt ) -> simple-template-id ; Index: clang-tools-extra/pseudo/lib/cxx/CXX.cpp =================================================================== --- clang-tools-extra/pseudo/lib/cxx/CXX.cpp +++ clang-tools-extra/pseudo/lib/cxx/CXX.cpp @@ -182,6 +182,22 @@ return true; } +bool guardEllipsisInAbstractDeclarator(const GuardParams& P) { + const auto* TypeID = P.RHS[0]; + assert(TypeID->symbol() == Symbol::type_id); + if (TypeID->kind() == ForestNode::Sequence && + TypeID->rule() == rule::type_id::type_specifier_seq__abstract_declarator) { + const auto* AbstractDeclarator = TypeID->elements()[1]; + for (auto &Child : AbstractDeclarator->descendants()) { + if (Child.kind() == ForestNode::Terminal) + if (symbolToToken(Child.symbol()) == clang::tok::ellipsis) + return false; + } + return true; + } + return true; +} + // Whether this e.g. decl-specifier contains an "exclusive" type such as a class // name, and thus can't combine with a second exclusive type. // @@ -353,6 +369,16 @@ decl_specifier_seq__L_SQUARE__identifier_list__R_SQUARE__initializer__SEMI, specifiesStructuredBinding}, + // Per C++ [dcl.fct#25] -- A declarator-id or abstract-declarator containing + // an ellipsis shall only be used in a parameter-declaration. + // + // We should not misparse the `int...` in `vector<int...> abc;` as a + // type-id template argument (... is an abstractor-declarator). + { + rule::template_argument::type_id, + guardEllipsisInAbstractDeclarator + }, + // The grammar distinguishes (only) user-defined vs plain string literals, // where the clang lexer distinguishes (only) encoding types. {rule::user_defined_string_literal_chunk::STRING_LITERAL,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits