mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 08:55:25 +02:00
Bug 413527: [C++14] Support Lambda init-captures
This patch adds parsing and semantic support for lambda init-captures. Change-Id: Ia5f39ea6f8780ecd6a9685f432bcbdf39e09c82a Signed-off-by: Hansruedi Patzen <hansruedi.patzen@hsr.ch>
This commit is contained in:
parent
74c80478d9
commit
957dae8f4e
14 changed files with 556 additions and 83 deletions
|
@ -14,6 +14,7 @@
|
|||
package org.eclipse.cdt.core.parser.tests.ast2;
|
||||
|
||||
import org.eclipse.cdt.core.parser.tests.ast2.cxx14.GenericLambdaTests;
|
||||
import org.eclipse.cdt.core.parser.tests.ast2.cxx14.InitCaptureTests;
|
||||
import org.eclipse.cdt.core.parser.tests.ast2.cxx14.ReturnTypeDeductionTests;
|
||||
import org.eclipse.cdt.core.parser.tests.ast2.cxx14.VariableTemplateTests;
|
||||
import org.eclipse.cdt.core.parser.tests.ast2.cxx17.TemplateAutoTests;
|
||||
|
@ -65,6 +66,7 @@ public class DOMParserTestSuite extends TestCase {
|
|||
suite.addTest(VariableTemplateTests.suite());
|
||||
suite.addTestSuite(ReturnTypeDeductionTests.class);
|
||||
suite.addTestSuite(GenericLambdaTests.class);
|
||||
suite.addTestSuite(InitCaptureTests.class);
|
||||
// C++17 tests
|
||||
suite.addTest(TemplateAutoTests.suite());
|
||||
return suite;
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Institute for Software, HSR Hochschule fuer Technik
|
||||
* Rapperswil, University of applied sciences and others
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Hansruedi Patzen (IFS)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.parser.tests.ast2.cxx14;
|
||||
|
||||
import org.eclipse.cdt.core.parser.tests.ast2.AST2CPPTestBase;
|
||||
|
||||
/**
|
||||
* AST tests for C++14 lambda init captures.
|
||||
*/
|
||||
public class InitCaptureTests extends AST2CPPTestBase {
|
||||
|
||||
// int main() {
|
||||
// [var1 { 3 }] { }();
|
||||
// }
|
||||
public void testLambdaInitCaptures_413527_1a() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
// int main() {
|
||||
// int var2 {};
|
||||
// [var1 { 3 }, var2] { }();
|
||||
// }
|
||||
public void testLambdaInitCaptures_413527_1b() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
// int main() {
|
||||
// int var2 {};
|
||||
// [var1 { 3 }, var2] { }();
|
||||
// }
|
||||
public void testLambdaInitCaptures_413527_1c() throws Exception {
|
||||
BindingAssertionHelper helper = getAssertionHelper();
|
||||
helper.assertVariableType("var2", CommonCPPTypes.int_);
|
||||
helper.assertVariableType("var1", CommonCPPTypes.int_);
|
||||
}
|
||||
|
||||
// int main() {
|
||||
// [var1(3)] { }();
|
||||
// }
|
||||
public void testLambdaInitCaptures_413527_2a() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
// int main() {
|
||||
// int var2 { };
|
||||
// [var1(3), var2] { }();
|
||||
// }
|
||||
public void testLambdaInitCaptures_413527_2b() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
// int main() {
|
||||
// int var2 { };
|
||||
// [var1(3), var2] { }();
|
||||
// }
|
||||
public void testLambdaInitCaptures_413527_2c() throws Exception {
|
||||
BindingAssertionHelper helper = getAssertionHelper();
|
||||
helper.assertVariableType("var2", CommonCPPTypes.int_);
|
||||
helper.assertVariableType("var1", CommonCPPTypes.int_);
|
||||
}
|
||||
|
||||
// int main() {
|
||||
// int var2 { };
|
||||
// [var1( { 3, 3 } ), var2] { }();
|
||||
// }
|
||||
public void testLambdaInitCaptures_413527_2d() throws Exception {
|
||||
BindingAssertionHelper helper = getAssertionHelper();
|
||||
helper.assertVariableType("var2", CommonCPPTypes.int_);
|
||||
// #include <initalizer_list> missing
|
||||
helper.assertVariableTypeProblem("var1");
|
||||
}
|
||||
|
||||
// int main() {
|
||||
// [var1 = 3] { }();
|
||||
// }
|
||||
public void testLambdaInitCaptures_413527_3a() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
// int main() {
|
||||
// int var2 { };
|
||||
// [var1 = 3, var2] { }();
|
||||
// }
|
||||
public void testLambdaInitCaptures_413527_3b() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
// int main() {
|
||||
// int var2 { };
|
||||
// [var1 = 3, var2] { }();
|
||||
// }
|
||||
public void testLambdaInitCaptures_413527_3c() throws Exception {
|
||||
BindingAssertionHelper helper = getAssertionHelper();
|
||||
helper.assertVariableType("var2", CommonCPPTypes.int_);
|
||||
helper.assertVariableType("var1", CommonCPPTypes.int_);
|
||||
}
|
||||
|
||||
// struct S {
|
||||
// int i;
|
||||
// int j;
|
||||
// };
|
||||
// int main() {
|
||||
// int var2 { };
|
||||
// [var1 = { 3, 4 }, var2] { }();
|
||||
// }
|
||||
public void testLambdaInitCaptures_413527_3d() throws Exception {
|
||||
BindingAssertionHelper helper = getAssertionHelper();
|
||||
helper.assertVariableType("var2", CommonCPPTypes.int_);
|
||||
// #include <initalizer_list> missing
|
||||
helper.assertVariableTypeProblem("var1");
|
||||
}
|
||||
|
||||
// int main() {
|
||||
// [var1 { 3 }] {
|
||||
// auto var3 = var1;
|
||||
// }();
|
||||
// }
|
||||
public void testLambdaInitCaptures_413527_4a() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
BindingAssertionHelper helper = getAssertionHelper();
|
||||
helper.assertVariableType("var1", CommonCPPTypes.int_);
|
||||
helper.assertVariableType("var3", CommonCPPTypes.int_);
|
||||
}
|
||||
|
||||
// int main() {
|
||||
// [var1 { 3 }] {
|
||||
// var1++;
|
||||
// }();
|
||||
// }
|
||||
public void testLambdaInitCaptures_413527_4b() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
BindingAssertionHelper helper = getAssertionHelper();
|
||||
helper.assertVariableType("var1", CommonCPPTypes.int_);
|
||||
}
|
||||
}
|
|
@ -122,4 +122,40 @@ template<typename... T> struct Tpl
|
|||
template<typename... T>
|
||||
void foo(Tpl<T...>)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
//!Lambda init capture equals
|
||||
//%CPP
|
||||
int main()
|
||||
{
|
||||
[c = {3, 3}] {
|
||||
}
|
||||
;
|
||||
}
|
||||
|
||||
//!Lambda init capture braces
|
||||
//%CPP
|
||||
int main()
|
||||
{
|
||||
[c{3, 3}] {
|
||||
}
|
||||
;
|
||||
}
|
||||
|
||||
//!Lambda init capture parenthesis
|
||||
//%CPP
|
||||
int main()
|
||||
{
|
||||
[c({3, 3})] {
|
||||
}
|
||||
;
|
||||
}
|
||||
|
||||
//!Lambda init equals by ref
|
||||
//%CPP
|
||||
int main()
|
||||
{
|
||||
[&c = {3, 3}] {
|
||||
}
|
||||
;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Institute for Software, HSR Hochschule fuer Technik
|
||||
* Rapperswil, University of applied sciences and others
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Hansruedi Patzen (IFS) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||
|
||||
/**
|
||||
* Init capture for a lambda expression, introduced in C++14.
|
||||
*
|
||||
* @since 6.5
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface ICPPASTInitCapture extends ICPPASTCapture, IASTDeclaration {
|
||||
ASTNodeProperty DECLARATOR = new ASTNodeProperty("ICPPASTInitCapture - DECLARATOR [IASTDeclarator]"); //$NON-NLS-1$
|
||||
|
||||
@Override
|
||||
ICPPASTInitCapture copy();
|
||||
|
||||
@Override
|
||||
ICPPASTInitCapture copy(CopyStyle style);
|
||||
|
||||
ICPPASTDeclarator getDeclarator();
|
||||
|
||||
void setDeclarator(ICPPASTDeclarator declarator);
|
||||
}
|
|
@ -105,6 +105,11 @@ public interface ICPPNodeFactory extends INodeFactory {
|
|||
*/
|
||||
public ICPPASTCapture newCapture();
|
||||
|
||||
/**
|
||||
* @since 6.5
|
||||
*/
|
||||
public ICPPASTInitCapture newInitCapture(ICPPASTDeclarator declarator);
|
||||
|
||||
@Override
|
||||
public ICPPASTCastExpression newCastExpression(int operator, IASTTypeId typeId, IASTExpression operand);
|
||||
|
||||
|
|
|
@ -12,15 +12,12 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
|||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
|
||||
/**
|
||||
* Implementation for captures.
|
||||
*/
|
||||
public class CPPASTCapture extends ASTNode implements ICPPASTCapture {
|
||||
public class CPPASTCapture extends CPPASTCaptureBase {
|
||||
private boolean fByReference;
|
||||
private boolean fPackExpansion;
|
||||
private IASTName fIdentifier;
|
||||
|
||||
public CPPASTCapture() {
|
||||
|
@ -34,10 +31,8 @@ public class CPPASTCapture extends ASTNode implements ICPPASTCapture {
|
|||
@Override
|
||||
public CPPASTCapture copy(CopyStyle style) {
|
||||
final CPPASTCapture copy = new CPPASTCapture();
|
||||
if (fIdentifier != null)
|
||||
copy.setIdentifier(fIdentifier.copy(style));
|
||||
copy.fByReference = fByReference;
|
||||
copy.fPackExpansion = fPackExpansion;
|
||||
copy.setIsByReference(fByReference);
|
||||
copy.setIdentifier(fIdentifier == null ? null : fIdentifier.copy(style));
|
||||
return copy(copy, style);
|
||||
}
|
||||
|
||||
|
@ -46,16 +41,6 @@ public class CPPASTCapture extends ASTNode implements ICPPASTCapture {
|
|||
return fIdentifier == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isByReference() {
|
||||
return fByReference;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPackExpansion() {
|
||||
return fPackExpansion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IASTName getIdentifier() {
|
||||
return fIdentifier;
|
||||
|
@ -63,12 +48,15 @@ public class CPPASTCapture extends ASTNode implements ICPPASTCapture {
|
|||
|
||||
@Override
|
||||
public boolean accept(ASTVisitor visitor) {
|
||||
if (visitor.shouldVisitCaptures) {
|
||||
switch (visitor.visit(this)) {
|
||||
case ASTVisitor.PROCESS_ABORT: return false;
|
||||
case ASTVisitor.PROCESS_SKIP: return true;
|
||||
default: break;
|
||||
}
|
||||
if (visitor.shouldVisitCaptures) {
|
||||
switch (visitor.visit(this)) {
|
||||
case ASTVisitor.PROCESS_ABORT:
|
||||
return false;
|
||||
case ASTVisitor.PROCESS_SKIP:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fIdentifier != null && !fIdentifier.accept(visitor))
|
||||
|
@ -77,8 +65,8 @@ public class CPPASTCapture extends ASTNode implements ICPPASTCapture {
|
|||
if (visitor.shouldVisitCaptures && visitor.leave(this) == ASTVisitor.PROCESS_ABORT)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdentifier(IASTName identifier) {
|
||||
|
@ -90,25 +78,23 @@ public class CPPASTCapture extends ASTNode implements ICPPASTCapture {
|
|||
fIdentifier= identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsByReference(boolean value) {
|
||||
assertNotFrozen();
|
||||
fByReference= value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsPackExpansion(boolean val) {
|
||||
assertNotFrozen();
|
||||
fPackExpansion= val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRoleForName(IASTName name) {
|
||||
if (name == fIdentifier) {
|
||||
// Treat the capture as a reference to the captured variable.
|
||||
// This choice may be revisited when C++14 init-captures are implemented.
|
||||
return r_reference;
|
||||
}
|
||||
return r_unclear;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isByReference() {
|
||||
return fByReference;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsByReference(boolean value) {
|
||||
assertNotFrozen();
|
||||
fByReference = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Institute for Software, HSR Hochschule fuer Technik
|
||||
* Rapperswil, University of applied sciences and others
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Hansruedi Patzen (IFS) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
|
||||
/**
|
||||
* Base class for C++ Lambda Captures
|
||||
*/
|
||||
public abstract class CPPASTCaptureBase extends ASTNode implements ICPPASTCapture {
|
||||
private boolean fPackExpansion;
|
||||
|
||||
protected <T extends CPPASTCaptureBase> T copy(T copy, CopyStyle style) {
|
||||
copy.setIsPackExpansion(fPackExpansion);
|
||||
return super.copy(copy, style);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPackExpansion() {
|
||||
return fPackExpansion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsPackExpansion(boolean val) {
|
||||
assertNotFrozen();
|
||||
fPackExpansion = val;
|
||||
}
|
||||
}
|
|
@ -136,6 +136,15 @@ public class CPPASTDeclarator extends CPPASTAttributeOwner implements ICPPASTDec
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a pointer operator from the pointer operators
|
||||
* @param operator Pointer operator to be removed
|
||||
*/
|
||||
public void removePointerOperator(IASTPointerOperator operator) {
|
||||
assertNotFrozen();
|
||||
ArrayUtil.remove(pointerOps, operator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNestedDeclarator(IASTDeclarator nested) {
|
||||
assertNotFrozen();
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Institute for Software, HSR Hochschule fuer Technik
|
||||
* Rapperswil, University of applied sciences and others
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Hansruedi Patzen (IFS) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitCapture;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator;
|
||||
|
||||
/**
|
||||
* Implementation for init captures.
|
||||
*/
|
||||
public class CPPASTInitCapture extends CPPASTCaptureBase implements ICPPASTInitCapture {
|
||||
private ICPPASTDeclarator fDeclarator;
|
||||
|
||||
public CPPASTInitCapture(ICPPASTDeclarator declarator) {
|
||||
setDeclarator(declarator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CPPASTInitCapture copy() {
|
||||
return copy(CopyStyle.withoutLocations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CPPASTInitCapture copy(CopyStyle style) {
|
||||
final CPPASTInitCapture copy = new CPPASTInitCapture((ICPPASTDeclarator) fDeclarator.copy(style));
|
||||
copy.setIsByReference(false);
|
||||
return copy(copy, style);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(ASTVisitor visitor) {
|
||||
if (visitor.shouldVisitCaptures) {
|
||||
switch (visitor.visit((ICPPASTCapture) this)) {
|
||||
case ASTVisitor.PROCESS_ABORT:
|
||||
return false;
|
||||
case ASTVisitor.PROCESS_SKIP:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (visitor.shouldVisitDeclarations) {
|
||||
switch (visitor.visit((IASTDeclaration) this)) {
|
||||
case ASTVisitor.PROCESS_ABORT:
|
||||
return false;
|
||||
case ASTVisitor.PROCESS_SKIP:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (fDeclarator != null && !fDeclarator.accept(visitor)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (visitor.shouldVisitDeclarations && visitor.leave((IASTDeclaration) this) == ASTVisitor.PROCESS_ABORT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (visitor.shouldVisitCaptures && visitor.leave((ICPPASTCapture) this) == ASTVisitor.PROCESS_ABORT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean capturesThisPointer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRoleForName(IASTName name) {
|
||||
if (name == fDeclarator.getName()) {
|
||||
return r_declaration;
|
||||
}
|
||||
return r_unclear;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isByReference() {
|
||||
IASTPointerOperator[] pointerOperators = fDeclarator.getPointerOperators();
|
||||
return pointerOperators.length == 1 && pointerOperators[0] instanceof ICPPASTReferenceOperator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsByReference(boolean value) {
|
||||
assertNotFrozen();
|
||||
boolean isReferenceCapture = isByReference();
|
||||
if (value && !isReferenceCapture) {
|
||||
fDeclarator.addPointerOperator(CPPNodeFactory.getDefault().newReferenceOperator(false));
|
||||
} else if (!value && isReferenceCapture) {
|
||||
// Use non API removePointerOperator
|
||||
((CPPASTDeclarator) fDeclarator).removePointerOperator(fDeclarator.getPointerOperators()[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPASTDeclarator getDeclarator() {
|
||||
return fDeclarator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDeclarator(ICPPASTDeclarator declarator) {
|
||||
assertNotFrozen();
|
||||
Objects.requireNonNull(declarator, "An init capture declarator must not be null."); //$NON-NLS-1$
|
||||
fDeclarator = declarator;
|
||||
fDeclarator.setParent(this);
|
||||
fDeclarator.setPropertyInParent(DECLARATOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IASTName getIdentifier() {
|
||||
return fDeclarator.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdentifier(IASTName identifier) {
|
||||
assertNotFrozen();
|
||||
Objects.requireNonNull(identifier, "An init capture must have an identifier."); //$NON-NLS-1$
|
||||
fDeclarator.setName(identifier);
|
||||
}
|
||||
}
|
|
@ -90,6 +90,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionWithTryBlock;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitCapture;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
|
||||
|
@ -261,6 +262,11 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
|
|||
return new CPPASTCapture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPASTInitCapture newInitCapture(ICPPASTDeclarator declarator) {
|
||||
return new CPPASTInitCapture(declarator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IASTCaseStatement newCaseStatement(IASTExpression expr) {
|
||||
return new CPPASTCaseStatement(expr);
|
||||
|
|
|
@ -106,6 +106,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator.RefQualifier;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionWithTryBlock;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitCapture;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
|
||||
|
@ -2102,28 +2103,56 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
return setRange(lambdaExpr, offset, calculateEndOffset(body));
|
||||
}
|
||||
|
||||
private ICPPASTInitCapture createInitCapture(IASTName identifier, IASTInitializer initializer, boolean isReference, int offset)
|
||||
throws EndOfFileException, BacktrackException {
|
||||
ICPPASTDeclarator declarator = getNodeFactory().newDeclarator(identifier);
|
||||
declarator.setInitializer(initializer);
|
||||
if (isReference) {
|
||||
declarator.addPointerOperator(getNodeFactory().newReferenceOperator(false));
|
||||
}
|
||||
setRange(declarator, offset, calculateEndOffset(initializer));
|
||||
ICPPASTInitCapture initCapture = getNodeFactory().newInitCapture(declarator);
|
||||
return setRange(initCapture, offset, calculateEndOffset(initializer));
|
||||
}
|
||||
|
||||
private ICPPASTCapture capture() throws EndOfFileException, BacktrackException {
|
||||
final int offset= LA().getOffset();
|
||||
final ICPPASTCapture result = getNodeFactory().newCapture();
|
||||
final int offset = LA().getOffset();
|
||||
ICPPASTCapture result = getNodeFactory().newCapture();
|
||||
boolean referenceCapture = false;
|
||||
|
||||
switch (LT(1)) {
|
||||
case IToken.t_this:
|
||||
return setRange(result, offset, consume().getEndOffset());
|
||||
case IToken.tAMPER:
|
||||
consume();
|
||||
result.setIsByReference(true);
|
||||
referenceCapture = true;
|
||||
break;
|
||||
}
|
||||
|
||||
final IASTName identifier= identifier();
|
||||
final IASTName identifier = identifier();
|
||||
result.setIdentifier(identifier);
|
||||
result.setIsByReference(referenceCapture);
|
||||
setRange(result, offset, calculateEndOffset(identifier));
|
||||
|
||||
switch(LT(1)) {
|
||||
case IToken.tASSIGN:
|
||||
result = createInitCapture(identifier, equalsInitalizerClause(false), referenceCapture, offset);
|
||||
break;
|
||||
case IToken.tLBRACE:
|
||||
case IToken.tLPAREN:
|
||||
result = createInitCapture(identifier, bracedOrCtorStyleInitializer(), referenceCapture, offset);
|
||||
break;
|
||||
}
|
||||
|
||||
if (LT(1) == IToken.tELLIPSIS) {
|
||||
// Note this will probably change with C++20 such that the
|
||||
// pack expansion of a CPPASTInitCapture will be part of the IASTDeclarator
|
||||
// and not the capture. [See: P0780R2]
|
||||
result.setIsPackExpansion(true);
|
||||
return setRange(result, offset, consume().getEndOffset());
|
||||
}
|
||||
|
||||
return setRange(result, offset, calculateEndOffset(identifier));
|
||||
return result;
|
||||
}
|
||||
|
||||
protected IASTExpression specialCastExpression(int kind) throws EndOfFileException, BacktrackException {
|
||||
|
@ -3947,6 +3976,20 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
}
|
||||
}
|
||||
|
||||
private IASTEqualsInitializer equalsInitalizerClause(boolean allowSkipping)
|
||||
throws EndOfFileException, BacktrackException {
|
||||
// Check for deleted or defaulted function syntax.
|
||||
final int lt2 = LTcatchEOF(2);
|
||||
if (lt2 == IToken.t_delete || lt2 == IToken.t_default) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int offset = consume(IToken.tASSIGN).getOffset();
|
||||
IASTInitializerClause initClause = initClause(allowSkipping);
|
||||
IASTEqualsInitializer initExpr = getNodeFactory().newEqualsInitializer(initClause);
|
||||
return setRange(initExpr, offset, calculateEndOffset(initClause));
|
||||
}
|
||||
|
||||
/**
|
||||
* initializer:
|
||||
* brace-or-equal-initializer
|
||||
|
@ -3963,16 +4006,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
|
||||
// = initializer-clause
|
||||
if (lt1 == IToken.tASSIGN) {
|
||||
// Check for deleted or defaulted function syntax.
|
||||
final int lt2= LTcatchEOF(2);
|
||||
if (lt2 == IToken.t_delete || lt2 == IToken.t_default)
|
||||
return null;
|
||||
|
||||
int offset= consume().getOffset();
|
||||
final boolean allowSkipping = LT(1) == IToken.tLBRACE && specifiesArray(dtor);
|
||||
IASTInitializerClause initClause = initClause(allowSkipping);
|
||||
IASTEqualsInitializer initExpr= getNodeFactory().newEqualsInitializer(initClause);
|
||||
return setRange(initExpr, offset, calculateEndOffset(initClause));
|
||||
return equalsInitalizerClause(LTcatchEOF(2) == IToken.tLBRACE && specifiesArray(dtor));
|
||||
}
|
||||
|
||||
// braced-init-list
|
||||
|
|
|
@ -104,6 +104,7 @@ import org.eclipse.cdt.core.dom.ast.IType;
|
|||
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAliasDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||
|
@ -121,6 +122,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitCapture;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
|
||||
|
@ -1582,9 +1584,18 @@ public class CPPSemantics {
|
|||
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) ((IASTFunctionDefinition) p).getDeclarator();
|
||||
nodes = dtor.getParameters();
|
||||
} else if (p instanceof ICPPASTLambdaExpression) {
|
||||
ICPPASTFunctionDeclarator dtor = ((ICPPASTLambdaExpression) p).getDeclarator();
|
||||
if (dtor != null) {
|
||||
nodes = dtor.getParameters();
|
||||
ICPPASTLambdaExpression lambdaExpression = (ICPPASTLambdaExpression) p;
|
||||
for (ICPPASTCapture capture : lambdaExpression.getCaptures()) {
|
||||
if (capture instanceof ICPPASTInitCapture) {
|
||||
IASTName name = capture.getIdentifier();
|
||||
if (name != null) {
|
||||
ASTInternal.addName(scope, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
ICPPASTFunctionDeclarator lambdaDeclarator = lambdaExpression.getDeclarator();
|
||||
if (lambdaDeclarator != null) {
|
||||
nodes = lambdaDeclarator.getParameters();
|
||||
}
|
||||
}
|
||||
if (p instanceof ICPPASTCatchHandler) {
|
||||
|
|
|
@ -118,6 +118,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator.RefQualifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitCapture;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
|
||||
|
@ -270,7 +271,7 @@ public class CPPVisitor extends ASTQueries {
|
|||
if (parent instanceof IASTNamedTypeSpecifier ||
|
||||
parent instanceof ICPPASTBaseSpecifier ||
|
||||
parent instanceof ICPPASTConstructorChainInitializer ||
|
||||
parent instanceof ICPPASTCapture ||
|
||||
(parent instanceof ICPPASTCapture && !(parent instanceof ICPPASTInitCapture)) ||
|
||||
name.getPropertyInParent() == ICPPASTNamespaceAlias.MAPPING_NAME) {
|
||||
if (name.getLookupKey().length == 0)
|
||||
return null;
|
||||
|
@ -755,6 +756,11 @@ public class CPPVisitor extends ASTQueries {
|
|||
|
||||
private static IBinding createBinding(IASTDeclarator declarator) {
|
||||
IASTNode parent = findOutermostDeclarator(declarator).getParent();
|
||||
|
||||
if (parent instanceof ICPPASTInitCapture) {
|
||||
return new CPPVariable(declarator.getName());
|
||||
}
|
||||
|
||||
declarator= findInnermostDeclarator(declarator);
|
||||
|
||||
final IASTDeclarator typeRelevantDtor= findTypeRelevantDeclarator(declarator);
|
||||
|
@ -2094,7 +2100,16 @@ public class CPPVisitor extends ASTQueries {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static IType createType(ICPPASTInitCapture capture) {
|
||||
IASTDeclarator declarator = capture.getDeclarator();
|
||||
ICPPASTInitializerClause initClause = getAutoInitClauseForDeclarator(declarator);
|
||||
if (initClause == null) {
|
||||
return ProblemType.CANNOT_DEDUCE_AUTO_TYPE;
|
||||
}
|
||||
return createAutoType(initClause.getEvaluation(), null, declarator);
|
||||
}
|
||||
|
||||
public static IType createType(IASTDeclarator declarator) {
|
||||
// Resolve placeholders by default.
|
||||
return createType(declarator, RESOLVE_PLACEHOLDERS);
|
||||
|
@ -2121,6 +2136,8 @@ public class CPPVisitor extends ASTQueries {
|
|||
final ICPPASTTypeId typeId = (ICPPASTTypeId) parent;
|
||||
declSpec = typeId.getDeclSpecifier();
|
||||
isPackExpansion= typeId.isPackExpansion();
|
||||
} else if (parent instanceof ICPPASTInitCapture) {
|
||||
return createType((ICPPASTInitCapture) parent);
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
@ -2191,7 +2208,28 @@ public class CPPVisitor extends ASTQueries {
|
|||
}
|
||||
return ProblemType.CANNOT_DEDUCE_AUTO_TYPE;
|
||||
}
|
||||
|
||||
|
||||
private static ICPPASTInitializerClause getAutoInitClauseForDeclarator(IASTDeclarator declarator) {
|
||||
IASTInitializer initClause= declarator.getInitializer();
|
||||
if (initClause instanceof IASTEqualsInitializer) {
|
||||
return (ICPPASTInitializerClause) ((IASTEqualsInitializer) initClause).getInitializerClause();
|
||||
} else if (initClause instanceof ICPPASTConstructorInitializer) {
|
||||
IASTInitializerClause[] arguments = ((ICPPASTConstructorInitializer) initClause).getArguments();
|
||||
if (arguments.length == 1) {
|
||||
return (ICPPASTInitializerClause) arguments[0];
|
||||
}
|
||||
} else if (initClause instanceof ICPPASTInitializerClause) {
|
||||
if (initClause instanceof ICPPASTInitializerList) {
|
||||
IASTInitializerClause[] clauses = ((ICPPASTInitializerList) initClause).getClauses();
|
||||
if (clauses.length == 1) {
|
||||
return (ICPPASTInitializerClause) clauses[0];
|
||||
}
|
||||
}
|
||||
return (ICPPASTInitializerClause) initClause;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static IType createAutoType(final IASTDeclSpecifier declSpec, IASTDeclarator declarator,
|
||||
int flags, PlaceholderKind placeholderKind) {
|
||||
IType cannotDeduce = placeholderKind == PlaceholderKind.Auto ?
|
||||
|
@ -2271,24 +2309,7 @@ public class CPPVisitor extends ASTQueries {
|
|||
// Non-static auto-typed class members are not allowed.
|
||||
return ProblemType.AUTO_FOR_NON_STATIC_FIELD;
|
||||
} else {
|
||||
IASTInitializer initClause= declarator.getInitializer();
|
||||
if (initClause instanceof IASTEqualsInitializer) {
|
||||
autoInitClause= (ICPPASTInitializerClause) ((IASTEqualsInitializer) initClause).getInitializerClause();
|
||||
} else if (initClause instanceof ICPPASTConstructorInitializer) {
|
||||
IASTInitializerClause[] arguments = ((ICPPASTConstructorInitializer) initClause).getArguments();
|
||||
if (arguments.length == 1)
|
||||
autoInitClause = (ICPPASTInitializerClause) arguments[0];
|
||||
} else if (initClause instanceof ICPPASTInitializerClause) {
|
||||
if (initClause instanceof ICPPASTInitializerList) {
|
||||
IASTInitializerClause[] clauses = ((ICPPASTInitializerList) initClause).getClauses();
|
||||
if (clauses.length == 1) {
|
||||
autoInitClause = (ICPPASTInitializerClause) clauses[0];
|
||||
}
|
||||
}
|
||||
if (autoInitClause == null) {
|
||||
autoInitClause= (ICPPASTInitializerClause) initClause;
|
||||
}
|
||||
}
|
||||
autoInitClause = getAutoInitClauseForDeclarator(declarator);
|
||||
}
|
||||
if (autoInitClause == null) {
|
||||
return cannotDeduce;
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitCapture;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPackExpansionExpression;
|
||||
|
@ -571,10 +572,14 @@ public class ExpressionWriter extends NodeWriter{
|
|||
if (capture.capturesThisPointer()) {
|
||||
scribe.print(THIS);
|
||||
} else {
|
||||
if (capture.isByReference()) {
|
||||
scribe.print(AMPERSAND_OP);
|
||||
if (capture instanceof ICPPASTInitCapture) {
|
||||
((ICPPASTInitCapture) capture).getDeclarator().accept(visitor);
|
||||
} else {
|
||||
if (capture.isByReference()) {
|
||||
scribe.print(AMPERSAND_OP);
|
||||
}
|
||||
capture.getIdentifier().accept(visitor);
|
||||
}
|
||||
capture.getIdentifier().accept(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue