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 solution is to favor the longest possible nest-name-specifier, and drop other alternatives by using the guard. This is my attempt, this might not be a right approach, looking for initial thoughts. Motivated cases: Foo::Foo() {}; // the constructor can be parsed as: // - Foo ::Foo(); // where the first Foo is return-type, and ::Foo is the function declarator // + Foo::Foo(); // where Foo::Foo is the function declarator void test() { // a very slow parsing case when there are many qualifers! X::Y::Z; // The statement can be parsed as: // - X ::Y::Z; // ::Y::Z is the declarator // - X::Y ::Z; // ::Z is the declarator // + X::Y::Z; // a declaration without declarator (X::Y::Z is decl-specifier-seq) // + X::Y::Z; // a qualifed-id expression } Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D130511 Files: clang-tools-extra/pseudo/lib/cxx/CXX.cpp clang-tools-extra/pseudo/lib/cxx/cxx.bnf 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 @@ -370,11 +370,11 @@ defining-type-specifier := enum-specifier defining-type-specifier-seq := defining-type-specifier defining-type-specifier-seq := defining-type-specifier defining-type-specifier-seq [guard] -simple-type-specifier := nested-name-specifier_opt type-name +simple-type-specifier := nested-name-specifier_opt type-name [guard] simple-type-specifier := nested-name-specifier TEMPLATE simple-template-id simple-type-specifier := decltype-specifier simple-type-specifier := placeholder-type-specifier -simple-type-specifier := nested-name-specifier_opt template-name +simple-type-specifier := nested-name-specifier_opt template-name [guard] simple-type-specifier := builtin-type builtin-type := CHAR builtin-type := CHAR8_T 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 @@ -162,6 +162,10 @@ return symbolToToken(P.Lookahead) != tok::kw_else; } +bool guardNextTokenNotColCol(const GuardParams &P) { + return symbolToToken(P.Lookahead) != tok::coloncolon; +} + // 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. // @@ -308,6 +312,16 @@ selection_statement_0if_1constexpr_2l_paren_3condition_4r_paren_5statement, guardNextTokenNotElse}, + {(RuleID)Rule::simple_type_specifier_0nested_name_specifier_1type_name, + guardNextTokenNotColCol}, + {(RuleID)Rule::simple_type_specifier_0nested_name_specifier_1template_name, + guardNextTokenNotColCol}, + {(RuleID)Rule::simple_type_specifier_0type_name, + guardNextTokenNotColCol}, + {(RuleID)Rule::simple_type_specifier_0template_name, + guardNextTokenNotColCol + }, + // The grammar distinguishes (only) user-defined vs plain string literals, // where the clang lexer distinguishes (only) encoding types. {(RuleID)Rule::user_defined_string_literal_chunk_0string_literal,
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 @@ -370,11 +370,11 @@ defining-type-specifier := enum-specifier defining-type-specifier-seq := defining-type-specifier defining-type-specifier-seq := defining-type-specifier defining-type-specifier-seq [guard] -simple-type-specifier := nested-name-specifier_opt type-name +simple-type-specifier := nested-name-specifier_opt type-name [guard] simple-type-specifier := nested-name-specifier TEMPLATE simple-template-id simple-type-specifier := decltype-specifier simple-type-specifier := placeholder-type-specifier -simple-type-specifier := nested-name-specifier_opt template-name +simple-type-specifier := nested-name-specifier_opt template-name [guard] simple-type-specifier := builtin-type builtin-type := CHAR builtin-type := CHAR8_T 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 @@ -162,6 +162,10 @@ return symbolToToken(P.Lookahead) != tok::kw_else; } +bool guardNextTokenNotColCol(const GuardParams &P) { + return symbolToToken(P.Lookahead) != tok::coloncolon; +} + // 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. // @@ -308,6 +312,16 @@ selection_statement_0if_1constexpr_2l_paren_3condition_4r_paren_5statement, guardNextTokenNotElse}, + {(RuleID)Rule::simple_type_specifier_0nested_name_specifier_1type_name, + guardNextTokenNotColCol}, + {(RuleID)Rule::simple_type_specifier_0nested_name_specifier_1template_name, + guardNextTokenNotColCol}, + {(RuleID)Rule::simple_type_specifier_0type_name, + guardNextTokenNotColCol}, + {(RuleID)Rule::simple_type_specifier_0template_name, + guardNextTokenNotColCol + }, + // The grammar distinguishes (only) user-defined vs plain string literals, // where the clang lexer distinguishes (only) encoding types. {(RuleID)Rule::user_defined_string_literal_chunk_0string_literal,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits