diff --git a/clang-tools-extra/pseudo/lib/cxx.bnf b/clang-tools-extra/pseudo/lib/cxx.bnf --- a/clang-tools-extra/pseudo/lib/cxx.bnf +++ b/clang-tools-extra/pseudo/lib/cxx.bnf @@ -76,17 +76,17 @@ nested-name-specifier := nested-name-specifier TEMPLATE_opt simple-template-id :: lambda-expression := lambda-introducer lambda-declarator_opt compound-statement lambda-expression := lambda-introducer < template-parameter-list > requires-clause_opt lambda-declarator_opt compound-statement -lambda-introducer := [ lambda-capture_opt ] +#! We allow a capture-default to appear anywhere in a capture-list. +# This simplifies the grammar and error recovery. +lambda-introducer := [ capture-list_opt ] lambda-declarator := ( parameter-declaration-clause_opt ) decl-specifier-seq_opt noexcept-specifier_opt trailing-return-type_opt requires-clause_opt -lambda-capture := capture-default -lambda-capture := capture-list -lambda-capture := capture-default , capture-list -capture-default := & -capture-default := = capture-list := capture capture-list := capture-list , capture +capture := capture-default capture := simple-capture capture := init-capture +capture-default := & +capture-default := = simple-capture := IDENTIFIER ..._opt simple-capture := & IDENTIFIER ..._opt simple-capture := THIS diff --git a/clang-tools-extra/pseudo/test/cxx/capture-list.cpp b/clang-tools-extra/pseudo/test/cxx/capture-list.cpp new file mode 100644 --- /dev/null +++ b/clang-tools-extra/pseudo/test/cxx/capture-list.cpp @@ -0,0 +1,23 @@ +// RUN: clang-pseudo -grammar=%cxx-bnf-file -source=%s --print-forest | FileCheck %s +// We loosely allow capture defaults in any position/multiple times. +auto lambda = [&, &foo, bar(x), =]{}; +// CHECK: lambda-introducer := [ capture-list ] +// CHECK-NEXT: ├─[ +// CHECK-NEXT: ├─capture-list +// CHECK-NEXT: │ ├─capture-list +// CHECK-NEXT: │ │ ├─capture-list +// CHECK-NEXT: │ │ │ ├─capture-list~& := tok[4] +// CHECK-NEXT: │ │ │ ├─, +// CHECK-NEXT: │ │ │ └─capture~simple-capture +// CHECK-NEXT: │ │ │ ├─& +// CHECK-NEXT: │ │ │ └─IDENTIFIER := tok[7] +// CHECK-NEXT: │ │ ├─, +// CHECK-NEXT: │ │ └─capture~init-capture +// CHECK-NEXT: │ │ ├─IDENTIFIER := tok[9] +// CHECK-NEXT: │ │ └─initializer := ( expression-list ) +// CHECK-NEXT: │ │ ├─( +// CHECK-NEXT: │ │ ├─expression-list~IDENTIFIER := tok[11] +// CHECK-NEXT: │ │ └─) +// CHECK-NEXT: │ ├─, +// CHECK-NEXT: │ └─capture~= +// CHECK-NEXT: └─]