From d6611cfcfaa19597f17ee42b156dd6a1e5cb493d Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Mon, 22 Feb 2016 21:03:49 -0800 Subject: [PATCH] Bug 488265 - Syntax error lambda with capture in initializer list Change-Id: I5505a47d33317287b0463e06eaf84ec0067b9e46 --- .../core/parser/tests/ast2/AST2CPPTests.java | 36 +++++++++++--- .../dom/parser/cpp/GNUCPPSourceParser.java | 49 ++++++++++++------- 2 files changed, 59 insertions(+), 26 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index d8eccb528c2..206546acae9 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -8533,6 +8533,18 @@ public class AST2CPPTests extends AST2TestBase { parseAndCheckBindings(); } + // template + // void f(T p); + // + // class A { + // void m() { + // f([this] (int x) {}); + // } + // }; + public void testLambdaWithCapture() throws Exception { + parseAndCheckBindings(); + } + // int foo = 0; // auto bar = [foo] { return foo; }; public void testLambdaWithCapture_446225() throws Exception { @@ -8544,14 +8556,25 @@ public class AST2CPPTests extends AST2TestBase { } // template - // void f(T p); + // class B; // - // class A { - // void m() { - // f([this] (int x) {}); - // } + // template + // struct B { + // template + // B(V); // }; - public void testLambdaWithCapture() throws Exception { + // + // struct A { + // B f; + // }; + // + // void waldo(A a); + // + // void test() { + // int p; + // waldo({[p](int arg) { return true; }}); + // } + public void testLambdaWithCaptureInInitializerList_488265() throws Exception { parseAndCheckBindings(); } @@ -8582,7 +8605,6 @@ public class AST2CPPTests extends AST2TestBase { // }; // // S::S(int a) : f{a} {} // Member initializer - public void testInitSyntax_302412() throws Exception { parseAndCheckBindings(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index 26f2420d0cb..7131ce3f0e0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -2856,7 +2856,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { private ICPPASTFunctionDefinition functionDefinition(final int firstOffset, IASTDeclSpecifier declSpec, IASTDeclarator outerDtor) throws EndOfFileException, BacktrackException { - final IASTDeclarator dtor= ASTQueries.findTypeRelevantDeclarator(outerDtor); if (!(dtor instanceof ICPPASTFunctionDeclarator)) throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset); @@ -3985,7 +3984,36 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { List result= new ArrayList<>(); // List of initializer clauses loop: while (true) { - List designators= allowDesignators ? designatorList() : null; + List designators = null; + IToken mark = mark(); + if (allowDesignators) { + designators= designatorList(); + } + + if (designators != null) { + try { + ICPPASTDesignatedInitializer desigInitializer = getNodeFactory().newDesignatedInitializer(null); + setRange(desigInitializer, designators.get(0)); + for (ICPPASTDesignator d : designators) { + desigInitializer.addDesignator(d); + } + + if (LT(1) != IToken.tEOC) { + // GNU extension: the assign operator is optional. + if (LT(1) == IToken.tASSIGN) + consume(IToken.tASSIGN); + + ICPPASTInitializerClause clause= initClause(false); + desigInitializer.setOperand(clause); + adjustLength(desigInitializer, clause); + } + result.add(desigInitializer); + } catch (BacktrackException e) { + backup(mark); + designators = null; // Retry without designators. + } + } + if (designators == null) { // Clause may be null, add to initializer anyways, so that the size can be computed. ICPPASTInitializerClause clause = initClause(allowSkipping); @@ -4007,23 +4035,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } } result.add(clause); - } else { - ICPPASTDesignatedInitializer desigInitializer = getNodeFactory().newDesignatedInitializer(null); - setRange(desigInitializer, designators.get(0)); - for (ICPPASTDesignator d : designators) { - desigInitializer.addDesignator(d); - } - - if (LT(1) != IToken.tEOC) { - // GNU extension: the assign operator is optional. - if (LT(1) == IToken.tASSIGN) - consume(IToken.tASSIGN); - - ICPPASTInitializerClause clause= initClause(false); - desigInitializer.setOperand(clause); - adjustLength(desigInitializer, clause); - } - result.add(desigInitializer); } if (LT(1) != IToken.tCOMMA)