From aacefc817d9385835db5b5e30a21687ddb4f3f93 Mon Sep 17 00:00:00 2001 From: Sam McCall Date: Tue, 28 Jun 2022 10:18:45 +0200 Subject: [PATCH] [pseudo] Simplify/loosen the grammar around lambda captures. Treat captures as a uniform list, rather than default-captures being special snowflakes that may only appear at the start. This accepts a larger set of (incorrect) code, and simplifies error-handling by making this fit into the usual homogeneous-list pattern. Differential Revision: https://reviews.llvm.org/D128708 --- clang-tools-extra/pseudo/lib/cxx.bnf | 12 +++++------ clang-tools-extra/pseudo/test/cxx/capture-list.cpp | 23 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 clang-tools-extra/pseudo/test/cxx/capture-list.cpp diff --git a/clang-tools-extra/pseudo/lib/cxx.bnf b/clang-tools-extra/pseudo/lib/cxx.bnf index aa243db..d6f292d 100644 --- 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 IDENTIFIER :: 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 index 0000000..8659a6a --- /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: └─] -- 2.7.4