mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-17 00:26:43 +00:00

The solution is to favor the longest possible nest-name-specifier, and drop other alternatives by using the guard, per per C++ [basic.lookup.qual.general]. 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 } ``` Differential Revision: https://reviews.llvm.org/D130511
29 lines
1.3 KiB
C++
29 lines
1.3 KiB
C++
// RUN: clang-pseudo -grammar=cxx -source=%s --print-forest | FileCheck %s
|
|
|
|
// Verify that we don't form a complete `::` nested-name-specifier if there is
|
|
// an identifier preceding it.
|
|
Foo::Foo() {} // No "Foo ::Foo()" false parse
|
|
// CHECK: ├─declaration-seq~function-definition := function-declarator function-body
|
|
// CHECK-NEXT: │ ├─function-declarator~noptr-declarator := noptr-declarator parameters-and-qualifiers
|
|
|
|
int ::x;
|
|
// CHECK: declaration~simple-declaration := decl-specifier-seq init-declarator-list ;
|
|
// CHECK-NEXT: ├─decl-specifier-seq~INT
|
|
|
|
void test() {
|
|
X::Y::Z; // No false qualified-declarator parses "X ::Y::Z" and "X::Y ::Z".
|
|
// CHECK: statement-seq~statement := <ambiguous>
|
|
// CHECK: statement~expression-statement := expression ;
|
|
// CHECK: statement~simple-declaration := decl-specifier-seq ;
|
|
// CHECK-NOT: simple-declaration := decl-specifier-seq init-declarator-list ;
|
|
|
|
// FIXME: eliminate the false `a<b> ::c` declaration parse.
|
|
a<b>::c;
|
|
// CHECK: statement := <ambiguous>
|
|
// CHECK-NEXT: ├─statement~expression-statement := expression ;
|
|
// CHECK-NEXT: │ ├─expression~relational-expression :=
|
|
// CHECK: └─statement~simple-declaration := <ambiguous>
|
|
// CHECK-NEXT: ├─simple-declaration := decl-specifier-seq ;
|
|
// CHECK: └─simple-declaration := decl-specifier-seq init-declarator-list ;
|
|
}
|