Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Corbat2018-05-23 11:02:03 +0000
committerThomas Corbat2019-08-05 07:00:35 +0000
commitacbceb04ee9e472119ef3255a47986c833fcf4c2 (patch)
treec27f6cf457270d83047b8c01a9c790c2d0d5ef7b /core/org.eclipse.cdt.core.tests
parentaf88842969b538dc3a33eab84b3b9631194bd9a3 (diff)
downloadorg.eclipse.cdt-acbceb04ee9e472119ef3255a47986c833fcf4c2.tar.gz
org.eclipse.cdt-acbceb04ee9e472119ef3255a47986c833fcf4c2.tar.xz
org.eclipse.cdt-acbceb04ee9e472119ef3255a47986c833fcf4c2.zip
Bug 522200: [C++17] Add support for structured binding declarations
Adds support for structured bindings: - Parser updated - Semantics updated - Tests for parser and bindings added Change-Id: I1de7b760041ac4ce4601f1b5032fdb0a197212a1 Signed-off-by: Hansruedi Patzen <hansruedi.patzen@hsr.ch> Signed-off-by: Thomas Corbat <tcorbat@hsr.ch>
Diffstat (limited to 'core/org.eclipse.cdt.core.tests')
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPAttributeTests.java6
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CommonCPPTypes.java72
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CommonCTypes.java42
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java2
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/SemanticTestBase.java75
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/GenericLambdaIndexTests.java1
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/GenericLambdaTests.java1
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/InitCaptureTests.java1
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/ReturnTypeDeductionIndexTests.java1
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/ReturnTypeDeductionTests.java1
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/VariableTemplateTests.java1
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/constexpr/AllConstexprEvalTests.java2
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/constexpr/StructuredBindingTests.java468
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/constexpr/TestBase.java6
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/StructuredBindingIndexTests.java295
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/StructuredBindingTests.java418
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java2
-rw-r--r--core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterAttributeTestSource.awts7
-rw-r--r--core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterDeclarationTestSource.awts14
-rw-r--r--core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterStatementTestSource.awts15
20 files changed, 1358 insertions, 72 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPAttributeTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPAttributeTests.java
index 4ac1c542fc0..a579e8f1839 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPAttributeTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPAttributeTests.java
@@ -335,6 +335,12 @@ public class AST2CPPAttributeTests extends AST2TestBase {
checkAttributeRelations(getAttributeSpecifiers(tu), ICPPASTSimpleDeclSpecifier.class);
}
+ //auto [[maybe_unused]] variable;
+ public void testAttributeAutoDeclSpecifer() throws Exception {
+ IASTTranslationUnit tu = parseAndCheckBindings();
+ checkAttributeRelations(getAttributeSpecifiers(tu), ICPPASTSimpleDeclSpecifier.class);
+ }
+
// const volatile unsigned long int [[attr]] cvuli;
public void testAttributedTypeSpecifier() throws Exception {
IASTTranslationUnit tu = parseAndCheckBindings();
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CommonCPPTypes.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CommonCPPTypes.java
new file mode 100644
index 00000000000..24f4fa96327
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CommonCPPTypes.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Nathan Ridge.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.cdt.core.parser.tests.ast2;
+
+import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
+import org.eclipse.cdt.core.dom.ast.IType;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
+
+/**
+ *
+ * Helper class for common type wrapping operations for tests.
+ *
+ */
+public class CommonCPPTypes {
+ public static IType char_ = CPPBasicType.CHAR;
+ public static IType int_ = CPPBasicType.INT;
+ public static IType void_ = CPPBasicType.VOID;
+ public static IType double_ = new CPPBasicType(Kind.eDouble, 0);
+ public static IType float_ = new CPPBasicType(Kind.eFloat, 0);
+ public static IType constChar = constOf(char_);
+ public static IType constInt = constOf(int_);
+ public static IType pointerToInt = pointerTo(int_);
+ public static IType constPointerToInt = constPointerTo(int_);
+ public static IType pointerToConstChar = pointerTo(constChar);
+ public static IType pointerToConstInt = pointerTo(constInt);
+ public static IType referenceToInt = referenceTo(int_);
+ public static IType referenceToConstInt = referenceTo(constInt);
+ public static IType rvalueReferenceToInt = rvalueReferenceTo(int_);
+ public static IType rvalueReferenceToConstInt = rvalueReferenceTo(constInt);
+
+ public static IType pointerTo(IType type) {
+ return new CPPPointerType(type);
+ }
+
+ // Not quite the same as constOf(pointerTo(type)) because of the
+ // idiosyncratic way we represent cosnt pointers using a flag
+ // on the CPPPointerType rather than using CPPQualifierType.
+ private static IType constPointerTo(IType type) {
+ return new CPPPointerType(type, true, false, false);
+ }
+
+ public static IType constOf(IType type) {
+ return new CPPQualifierType(type, true, false);
+ }
+
+ public static IType volatileOf(IType type) {
+ return new CPPQualifierType(type, false, true);
+ }
+
+ public static IType constVolatileOf(IType type) {
+ return new CPPQualifierType(type, true, true);
+ }
+
+ public static IType referenceTo(IType type) {
+ return new CPPReferenceType(type, false);
+ }
+
+ public static IType rvalueReferenceTo(IType type) {
+ return new CPPReferenceType(type, true);
+ }
+}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CommonCTypes.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CommonCTypes.java
new file mode 100644
index 00000000000..d1548dc2cd8
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CommonCTypes.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Nathan Ridge.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+
+package org.eclipse.cdt.core.parser.tests.ast2;
+
+import org.eclipse.cdt.core.dom.ast.IType;
+import org.eclipse.cdt.internal.core.dom.parser.c.CBasicType;
+import org.eclipse.cdt.internal.core.dom.parser.c.CPointerType;
+import org.eclipse.cdt.internal.core.dom.parser.c.CQualifierType;
+
+public class CommonCTypes {
+ public static IType pointerToVoid = pointerTo(CBasicType.VOID);
+ public static IType pointerToConstVoid = pointerTo(constOf(CBasicType.VOID));
+ public static IType pointerToInt = pointerTo(CBasicType.INT);
+ public static IType pointerToConstInt = pointerTo(constOf(CBasicType.INT));
+ public static IType pointerToVolatileInt = pointerTo(volatileOf(CBasicType.INT));
+ public static IType pointerToConstVolatileInt = pointerTo(constVolatileOf(CBasicType.INT));
+
+ private static IType pointerTo(IType type) {
+ return new CPointerType(type, 0);
+ }
+
+ private static IType constOf(IType type) {
+ return new CQualifierType(type, true, false, false);
+ }
+
+ private static IType volatileOf(IType type) {
+ return new CQualifierType(type, false, true, false);
+ }
+
+ private static IType constVolatileOf(IType type) {
+ return new CQualifierType(type, true, true, false);
+ }
+} \ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java
index b7174a8adbb..5f17ae73f30 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java
@@ -21,6 +21,7 @@ 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.LambdaExpressionTests;
+import org.eclipse.cdt.core.parser.tests.ast2.cxx17.StructuredBindingTests;
import org.eclipse.cdt.core.parser.tests.ast2.cxx17.TemplateAutoTests;
import org.eclipse.cdt.core.parser.tests.prefix.CompletionTestSuite;
@@ -74,6 +75,7 @@ public class DOMParserTestSuite extends TestCase {
// C++17 tests
suite.addTest(TemplateAutoTests.suite());
suite.addTestSuite(LambdaExpressionTests.class);
+ suite.addTestSuite(StructuredBindingTests.class);
return suite;
}
}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/SemanticTestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/SemanticTestBase.java
index aff2182fed0..2c0eb1f6876 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/SemanticTestBase.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/SemanticTestBase.java
@@ -30,13 +30,6 @@ import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator;
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment;
-import org.eclipse.cdt.internal.core.dom.parser.c.CBasicType;
-import org.eclipse.cdt.internal.core.dom.parser.c.CPointerType;
-import org.eclipse.cdt.internal.core.dom.parser.c.CQualifierType;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
/**
@@ -51,70 +44,6 @@ public class SemanticTestBase extends BaseTestCase {
super(name);
}
- protected static class CommonCTypes {
- public static IType pointerToVoid = pointerTo(CBasicType.VOID);
- public static IType pointerToConstVoid = pointerTo(constOf(CBasicType.VOID));
- public static IType pointerToInt = pointerTo(CBasicType.INT);
- public static IType pointerToConstInt = pointerTo(constOf(CBasicType.INT));
- public static IType pointerToVolatileInt = pointerTo(volatileOf(CBasicType.INT));
- public static IType pointerToConstVolatileInt = pointerTo(constVolatileOf(CBasicType.INT));
-
- private static IType pointerTo(IType type) {
- return new CPointerType(type, 0);
- }
-
- private static IType constOf(IType type) {
- return new CQualifierType(type, true, false, false);
- }
-
- private static IType volatileOf(IType type) {
- return new CQualifierType(type, false, true, false);
- }
-
- private static IType constVolatileOf(IType type) {
- return new CQualifierType(type, true, true, false);
- }
- }
-
- protected static class CommonCPPTypes {
- public static IType char_ = CPPBasicType.CHAR;
- public static IType int_ = CPPBasicType.INT;
- public static IType void_ = CPPBasicType.VOID;
- public static IType constChar = constOf(char_);
- public static IType constInt = constOf(int_);
- public static IType pointerToInt = pointerTo(int_);
- public static IType constPointerToInt = constPointerTo(int_);
- public static IType pointerToConstChar = pointerTo(constChar);
- public static IType pointerToConstInt = pointerTo(constInt);
- public static IType referenceToInt = referenceTo(int_);
- public static IType referenceToConstInt = referenceTo(constInt);
- public static IType rvalueReferenceToInt = rvalueReferenceTo(int_);
- public static IType rvalueReferenceToConstInt = rvalueReferenceTo(constInt);
-
- // Not quite the same as constOf(pointerTo(type)) because of the
- // idiosyncratic way we represent cosnt pointers using a flag
- // on the CPPPointerType rather than using CPPQualifierType.
- private static IType constPointerTo(IType type) {
- return new CPPPointerType(type, true, false, false);
- }
-
- private static IType pointerTo(IType type) {
- return new CPPPointerType(type);
- }
-
- public static IType constOf(IType type) {
- return new CPPQualifierType(type, true, false);
- }
-
- private static IType referenceTo(IType type) {
- return new CPPReferenceType(type, false);
- }
-
- private static IType rvalueReferenceTo(IType type) {
- return new CPPReferenceType(type, true);
- }
- }
-
protected static void assertSameType(IType expected, IType actual) {
assertNotNull(expected);
assertNotNull(actual);
@@ -122,6 +51,10 @@ public class SemanticTestBase extends BaseTestCase {
+ ASTTypeUtil.getType(actual, false) + "'", expected.isSameType(actual));
}
+ protected static void assertType(IVariable variable, IType expectedType) {
+ assertSameType(expectedType, variable.getType());
+ }
+
protected static SizeAndAlignment getSizeAndAlignment(IType type, IASTNode lookupPoint) {
try {
CPPSemantics.pushLookupPoint(lookupPoint);
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/GenericLambdaIndexTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/GenericLambdaIndexTests.java
index 25013a2e934..f2733100340 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/GenericLambdaIndexTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/GenericLambdaIndexTests.java
@@ -11,6 +11,7 @@
package org.eclipse.cdt.core.parser.tests.ast2.cxx14;
import org.eclipse.cdt.core.dom.ast.IFunction;
+import org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes;
import org.eclipse.cdt.internal.index.tests.IndexBindingResolutionTestBase;
/**
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/GenericLambdaTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/GenericLambdaTests.java
index dd16e67f70d..58c73597d6b 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/GenericLambdaTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/GenericLambdaTests.java
@@ -12,6 +12,7 @@ package org.eclipse.cdt.core.parser.tests.ast2.cxx14;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.parser.tests.ast2.AST2CPPTestBase;
+import org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes;
/**
* AST tests for C++14 generic lambdas.
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/InitCaptureTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/InitCaptureTests.java
index 2e38a3f274f..1dd1795e0b5 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/InitCaptureTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/InitCaptureTests.java
@@ -15,6 +15,7 @@
package org.eclipse.cdt.core.parser.tests.ast2.cxx14;
import org.eclipse.cdt.core.parser.tests.ast2.AST2CPPTestBase;
+import org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes;
/**
* AST tests for C++14 lambda init captures.
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/ReturnTypeDeductionIndexTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/ReturnTypeDeductionIndexTests.java
index ebcbd0e93ff..0a152b27981 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/ReturnTypeDeductionIndexTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/ReturnTypeDeductionIndexTests.java
@@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.cxx14;
+import org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes;
import org.eclipse.cdt.internal.index.tests.IndexBindingResolutionTestBase;
public class ReturnTypeDeductionIndexTests extends IndexBindingResolutionTestBase {
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/ReturnTypeDeductionTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/ReturnTypeDeductionTests.java
index 6c86c338777..529e70904e4 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/ReturnTypeDeductionTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/ReturnTypeDeductionTests.java
@@ -18,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
import org.eclipse.cdt.core.parser.tests.ast2.AST2CPPTestBase;
+import org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClosureType;
public class ReturnTypeDeductionTests extends AST2CPPTestBase {
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/VariableTemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/VariableTemplateTests.java
index 599d01d92ad..df3a1b57109 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/VariableTemplateTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/VariableTemplateTests.java
@@ -26,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.tests.ast2.AST2CPPTestBase;
+import org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFieldTemplateSpecialization;
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/constexpr/AllConstexprEvalTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/constexpr/AllConstexprEvalTests.java
index 16deda4065f..79eb731d114 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/constexpr/AllConstexprEvalTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/constexpr/AllConstexprEvalTests.java
@@ -65,6 +65,8 @@ public class AllConstexprEvalTests {
suite.addTest(FloatingPointValueTests.SingleProject.suite());
suite.addTest(CStringValueTests.NonIndexing.suite());
suite.addTest(CStringValueTests.SingleProject.suite());
+ suite.addTest(StructuredBindingTests.NonIndexing.suite());
+ suite.addTest(StructuredBindingTests.SingleProject.suite());
return suite;
}
}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/constexpr/StructuredBindingTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/constexpr/StructuredBindingTests.java
new file mode 100644
index 00000000000..dd6b20c6cb9
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/constexpr/StructuredBindingTests.java
@@ -0,0 +1,468 @@
+/*******************************************************************************
+* Copyright (c) 2018 Institute for Software, HSR Hochschule fuer Technik
+* Rapperswil, University of applied sciences and others
+*
+* This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License 2.0
+* which accompanies this distribution, and is available at
+* https://www.eclipse.org/legal/epl-2.0/
+*
+* SPDX-License-Identifier: EPL-2.0
+*******************************************************************************/
+package org.eclipse.cdt.core.parser.tests.ast2.cxx14.constexpr;
+
+import junit.framework.TestSuite;
+
+public class StructuredBindingTests extends TestBase {
+ public static class NonIndexing extends StructuredBindingTests {
+ public NonIndexing() {
+ setStrategy(new NonIndexingTestStrategy());
+ }
+
+ public static TestSuite suite() {
+ return suite(NonIndexing.class);
+ }
+ }
+
+ public static class SingleProject extends StructuredBindingTests {
+ public SingleProject() {
+ setStrategy(new SinglePDOMTestStrategy(true, false));
+ }
+
+ public static TestSuite suite() {
+ return suite(SingleProject.class);
+ }
+ }
+
+ // constexpr int f() {
+ // int arr[]{8, 9};
+ // auto [first, second] = arr;
+ // return first;
+ // }
+
+ // constexpr int x = f();
+ public void testBindingFirstElementOfArray() throws Exception {
+ assertEvaluationEquals(8);
+ }
+
+ // constexpr int f() {
+ // int arr[]{8, 9};
+ // auto [first, second] = arr;
+ // return second;
+ // }
+
+ // constexpr int x = f();
+ public void testBindingSecondElementOfArray() throws Exception {
+ assertEvaluationEquals(9);
+ }
+
+ // constexpr int f() {
+ // int arr[]{8, 9};
+ // auto [first, second, third] = arr;
+ // return third;
+ // }
+
+ // constexpr int x = f();
+ public void testBindingOutOfBoundElementOfArray() throws Exception {
+ assertEvaluationProblem();
+ }
+
+ // struct Pair {
+ // int i;
+ // double d;
+ // } p{42, 5.0};
+ // constexpr auto f() {
+ // auto [first, second] = p;
+ // return first;
+ // }
+
+ // constexpr auto x = f();
+ public void testBindingFirstMemberOfObject() throws Exception {
+ assertEvaluationEquals(42);
+ }
+
+ // struct Pair {
+ // int i;
+ // double d;
+ // } p{42, 5.0};
+ // constexpr auto f() {
+ // auto [first, second] = p;
+ // return second;
+ // }
+
+ // constexpr auto x = f();
+ public void testBindingSecondMemberOfObject() throws Exception {
+ assertEvaluationEquals(5.0);
+ }
+
+ // struct Base {
+ // int i;
+ // };
+ // struct Sub : Base {
+ // } s{5};
+ // auto [inherited] = s;
+
+ // auto x = inherited;
+ public void testBindingInheritedMember() throws Exception {
+ assertEvaluationEquals(5);
+ }
+
+ // struct Mono {
+ // int i;
+ // } p{42};
+ // constexpr auto f() {
+ // auto [first, second] = p;
+ // return second;
+ // }
+
+ // constexpr auto x = f();
+ public void testBindingOutOfBoundElementOfObject() throws Exception {
+ assertEvaluationProblem();
+ }
+
+ // constexpr auto f() {
+ // auto [first, second];
+ // return second;
+ // }
+
+ // constexpr auto x = f();
+ public void testUninitializedStructuredBinding() throws Exception {
+ assertEvaluationProblem();
+ }
+
+ // namespace std {
+ // using size_t = unsigned long long;
+ // template <typename T, size_t N>
+ // struct array {
+ // T elements[N];
+ // template <size_t I>
+ // constexpr auto get() {
+ // return elements[I];
+ // }
+ // };
+ // template <typename T>
+ // struct tuple_size;
+ // template <typename T, size_t N>
+ // struct tuple_size<array<T, N>> {
+ // constexpr static size_t value = N;
+ // };
+ // template <size_t I, typename T>
+ // struct tuple_element;
+ // template <size_t I, typename T, size_t N>
+ // struct tuple_element<I, array<T, N>> {
+ // using type = T;
+ // };
+ // }
+ // constexpr auto createValues() {
+ // std::array<int, 3> values{{1, 2, 3}};
+ // return values;
+ // }
+ // constexpr auto foo() {
+ // auto [f, s, t] = createValues();
+ // return t;
+ // }
+
+ // constexpr auto x = foo();
+ public void testBindingOutOfTupleLikeObjectWithMemberGet() throws Exception {
+ assertEvaluationEquals(3);
+ }
+
+ // namespace std {
+ // using size_t = unsigned long long;
+ // template <typename T, size_t N>
+ // struct array {
+ // T elements[N];
+ // };
+ // template <typename T>
+ // struct tuple_size;
+ // template <typename T, size_t N>
+ // struct tuple_size<array<T, N>> {
+ // constexpr static size_t value = N;
+ // };
+ // template <size_t I, typename T>
+ // struct tuple_element;
+ // template <size_t I, typename T, size_t N>
+ // struct tuple_element<I, array<T, N>> {
+ // using type = T;
+ // };
+ // template <size_t I, typename T, size_t N>
+ // constexpr auto get(std::array<T, N> const & values) {
+ // return values.elements[I];
+ // }
+ // }
+ // constexpr auto createValues() {
+ // std::array<int, 3> values{{1, 2, 3}};
+ // return values;
+ // }
+ // constexpr auto foo() {
+ // auto [f, s, t] = createValues();
+ // return t;
+ // }
+
+ // constexpr auto x = foo();
+ public void testBindingOutOfTupleLikeObjectWithFreeGet() throws Exception {
+ assertEvaluationEquals(3);
+ }
+
+ // namespace std {
+ // using size_t = unsigned long long;
+ // template <typename T, size_t N>
+ // struct array {
+ // T elements[N];
+ // template <size_t I>
+ // constexpr auto get() {
+ // return elements[I];
+ // }
+ // };
+ // template <typename T>
+ // struct tuple_size;
+ // template <typename T, size_t N>
+ // struct tuple_size<array<T, N>> {
+ // constexpr static size_t value = N;
+ // };
+ // template <size_t I, typename T>
+ // struct tuple_element;
+ // template <size_t I, typename T, size_t N>
+ // struct tuple_element<I, array<T, N>> {
+ // using type = T;
+ // };
+ // }
+ // constexpr auto createValues() {
+ // std::array<int, 2> values{{1, 2}};
+ // return values;
+ // }
+ // constexpr auto foo() {
+ // auto [f, s, t] = createValues();
+ // return t;
+ // }
+
+ // constexpr auto x = foo();
+ public void testBindingOutOfTupleLikeObjectWithTooFewElements() throws Exception {
+ assertEvaluationProblem();
+ }
+
+ // namespace std {
+ // using size_t = unsigned long long;
+ // template <typename T, size_t N>
+ // struct array {
+ // T elements[N];
+ // template <size_t I>
+ // constexpr auto get() {
+ // return elements[I];
+ // }
+ // };
+ // template <typename T>
+ // struct tuple_size;
+ // template <typename T, size_t N>
+ // struct tuple_size<array<T, N>> {
+ // constexpr static size_t value = N;
+ // };
+ // template <size_t I, typename T>
+ // struct tuple_element;
+ // template <size_t I, typename T, size_t N>
+ // struct tuple_element<I, array<T, N>> {
+ // using type = T;
+ // };
+ // }
+ // constexpr auto createValues() {
+ // std::array<int, 3> values{{1, 2, 3}};
+ // return values;
+ // }
+ // constexpr auto foo() {
+ // auto [f, s] = createValues();
+ // return f;
+ // }
+
+ // constexpr auto x = foo();
+ public void testBindingOutOfTupleLikeObjectWithTooManyElements() throws Exception {
+ assertEvaluationProblem();
+ }
+
+ // namespace std {
+ // using size_t = unsigned long long;
+ // template <typename T, size_t N>
+ // struct array {
+ // T elements[N];
+ // template <size_t I>
+ // constexpr auto get() {
+ // return elements[I];
+ // }
+ // };
+ // template <typename T>
+ // struct tuple_size;
+ // template <typename T, size_t N>
+ // struct tuple_size<array<T, N>> {
+ // static const size_t value = N;
+ // };
+ // template <size_t I, typename T>
+ // struct tuple_element;
+ // template <size_t I, typename T, size_t N>
+ // struct tuple_element<I, array<T, N>> {
+ // using type = T;
+ // };
+ // }
+ // constexpr auto createValues() {
+ // std::array<int, 3> values{{1, 2, 3}};
+ // return values;
+ // }
+ // constexpr auto foo() {
+ // auto [f, s, t] = createValues();
+ // return s;
+ // }
+
+ // constexpr auto x = foo();
+ public void testBindingOutOfTupleLikeValueMemberIsStaticConst() throws Exception {
+ assertEvaluationEquals(2);
+ }
+
+ // namespace std {
+ // using size_t = unsigned long long;
+ // template <typename T, size_t N>
+ // struct array {
+ // T elements[N];
+ // template <size_t I>
+ // constexpr auto get() {
+ // return elements[I];
+ // }
+ // };
+ // template <typename T>
+ // struct tuple_size;
+ // template <typename T, size_t N>
+ // struct tuple_size<array<T, N>> {
+ // static size_t value = N;
+ // };
+ // template <size_t I, typename T>
+ // struct tuple_element;
+ // template <size_t I, typename T, size_t N>
+ // struct tuple_element<I, array<T, N>> {
+ // using type = T;
+ // };
+ // }
+ // constexpr auto createValues() {
+ // std::array<int, 3> values{{1, 2, 3}};
+ // return values;
+ // }
+ // constexpr auto foo() {
+ // auto [f, s, t] = createValues();
+ // return f;
+ // }
+
+ // constexpr auto x = foo();
+ public void testBindingOutOfTupleLikeValueMemberIsNonConstexpr() throws Exception {
+ assertEvaluationProblem();
+ }
+
+ // namespace std {
+ // using size_t = unsigned long long;
+ // template <typename T, size_t N>
+ // struct array {
+ // T elements[N];
+ // template <size_t I>
+ // constexpr auto get() {
+ // return elements[I];
+ // }
+ // };
+ // template <typename T>
+ // struct tuple_size;
+ // template <typename T, size_t N>
+ // struct tuple_size<array<T, N>> {
+ // constexpr size_t value = N;
+ // };
+ // template <size_t I, typename T>
+ // struct tuple_element;
+ // template <size_t I, typename T, size_t N>
+ // struct tuple_element<I, array<T, N>> {
+ // using type = T;
+ // };
+ // }
+ // constexpr auto createValues() {
+ // std::array<int, 3> values{{1, 2, 3}};
+ // return values;
+ // }
+ // constexpr auto foo() {
+ // auto [f, s, t] = createValues();
+ // return f;
+ // }
+
+ // constexpr auto x = foo();
+ public void testBindingOutOfTupleLikeValueMemberIsNonStatic() throws Exception {
+ assertEvaluationProblem();
+ }
+
+ // namespace std {
+ // using size_t = unsigned long long;
+ // template <typename T, size_t N>
+ // struct array {
+ // T elements[N];
+ // template <size_t I>
+ // constexpr auto get() {
+ // return elements[I];
+ // }
+ // };
+ // template <typename T>
+ // struct tuple_size;
+ // template <typename T, size_t N>
+ // struct tuple_size<array<T, N>> {
+ // constexpr static double value = static_cast<double>(N);
+ // };
+ // template <size_t I, typename T>
+ // struct tuple_element;
+ // template <size_t I, typename T, size_t N>
+ // struct tuple_element<I, array<T, N>> {
+ // using type = T;
+ // };
+ // }
+ // constexpr auto createValues() {
+ // std::array<int, 3> values{{1, 2, 3}};
+ // return values;
+ // }
+ // constexpr auto foo() {
+ // auto [f, s, t] = createValues();
+ // return f;
+ // }
+
+ // constexpr auto x = foo();
+ public void testBindingOutOfTupleLikeValueMemberIsNonIntegral() throws Exception {
+ assertEvaluationProblem();
+ }
+
+ // namespace std {
+ // using size_t = unsigned long long;
+ // template <typename T, size_t N>
+ // struct array {
+ // T elements[N];
+ // template <size_t I>
+ // constexpr auto get() {
+ // return elements[I];
+ // }
+ // };
+ // size_t nonConstexprFunction() {
+ // return 3;
+ // }
+ // template <typename T>
+ // struct tuple_size;
+ // template <typename T, size_t N>
+ // struct tuple_size<array<T, N>> {
+ // static const size_t value = nonConstexprFunction();
+ // };
+ // template <size_t I, typename T>
+ // struct tuple_element;
+ // template <size_t I, typename T, size_t N>
+ // struct tuple_element<I, array<T, N>> {
+ // using type = T;
+ // };
+ // }
+ // constexpr auto createValues() {
+ // std::array<int, 3> values{{1, 2, 3}};
+ // return values;
+ // }
+ // constexpr auto foo() {
+ // auto [f, s, t] = createValues();
+ // return s;
+ // }
+
+ // constexpr auto x = foo();
+ public void testBindingOutOfTupleLikeValueMemberWithNonConstexprInitialization() throws Exception {
+ assertEvaluationProblem();
+ }
+} \ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/constexpr/TestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/constexpr/TestBase.java
index 3083093cf5d..1c473cfbfda 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/constexpr/TestBase.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/constexpr/TestBase.java
@@ -41,6 +41,7 @@ import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser;
import org.eclipse.cdt.internal.core.dom.parser.CStringValue;
import org.eclipse.cdt.internal.core.dom.parser.FloatingPointValue;
+import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import org.eclipse.cdt.internal.core.dom.parser.cpp.GNUCPPSourceParser;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
@@ -63,6 +64,11 @@ public class TestBase extends IndexBindingResolutionTestBase {
return map;
}
+ protected void assertEvaluationProblem() throws Exception {
+ IValue value = getValue();
+ assertTrue(IntegralValue.ERROR.equals(value) || IntegralValue.UNKNOWN.equals(value));
+ }
+
protected void assertEvaluationEquals(boolean expectedValue) throws Exception {
IValue value = getValue();
Number num = value.numberValue();
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/StructuredBindingIndexTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/StructuredBindingIndexTests.java
new file mode 100644
index 00000000000..ed3a76cc238
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/StructuredBindingIndexTests.java
@@ -0,0 +1,295 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Institute for Software, HSR Hochschule fuer Technik
+ * Rapperswil, University of applied sciences.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Thomas Corbat (IFS) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core.parser.tests.ast2.cxx17;
+
+import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.char_;
+import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.double_;
+import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.int_;
+
+import org.eclipse.cdt.core.dom.ast.IType;
+import org.eclipse.cdt.core.dom.ast.IVariable;
+import org.eclipse.cdt.internal.index.tests.IndexBindingResolutionTestBase;
+
+public class StructuredBindingIndexTests extends IndexBindingResolutionTestBase {
+ public StructuredBindingIndexTests() {
+ setStrategy(new SinglePDOMTestStrategy(true));
+ }
+
+ //struct S {
+ // int i;
+ //} s{};
+
+ //auto [z] = s;
+ public void testLocalStructuredBindingFromMemberOfBasicType() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("z"), int_);
+ }
+
+ //struct S {
+ // int i;
+ //} s{};
+ //auto [z] = s;
+
+ //auto x = z;
+ public void testExternalStructuredBindingFromMemberOfBasicType() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("z"), int_);
+ }
+
+ //struct T {
+ //};
+ //struct S {
+ // T t;
+ //} s{};
+
+ //auto [z] = s;
+ //T localT{};
+ public void testLocalStructuredBindingFromMemberOfUserDefinedType() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ IVariable variable = helper.assertNonProblem("z");
+ IType variableType = variable.getType();
+
+ IVariable localT = helper.assertNonProblem("localT");
+ IType typeT = localT.getType();
+
+ assertSameType(typeT, variableType);
+ }
+
+ //struct T {
+ //};
+ //struct S {
+ // T t;
+ //} s{};
+ //auto [z] = s;
+
+ //auto x = z;
+ //T localT{};
+ public void testExternalStructuredBindingFromMemberOfUserDefinedType() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ IVariable variable = helper.assertNonProblem("z");
+ IType variableType = variable.getType();
+
+ IVariable localT = helper.assertNonProblem("localT");
+ IType typeT = localT.getType();
+
+ assertSameType(typeT, variableType);
+ }
+
+ //struct T {
+ //};
+ //struct Base1 {
+ //};
+ //struct Base2 {
+ // T t;
+ // int i;
+ // double d;
+ // char c;
+ //};
+ //struct S : Base1, Base2 {
+ //} s{};
+
+ //auto [t, i, d, c] = s;
+ //T localT{};
+ public void testMultipleVariablesInStructuredBindingFromMembers() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ IVariable variableT = helper.assertNonProblem("t,", 1);
+ IType variableTType = variableT.getType();
+ IVariable localT = helper.assertNonProblem("localT");
+ IType typeT = localT.getType();
+ assertSameType(typeT, variableTType);
+
+ assertType(helper.assertNonProblem("i,", 1), int_);
+ assertType(helper.assertNonProblem("d,", 1), double_);
+ assertType(helper.assertNonProblem("c]", 1), char_);
+ }
+
+ //struct T {
+ //};
+ //struct Base1 {
+ // T t;
+ // int i;
+ // double d;
+ // char c;
+ //};
+ //struct Base2 : Base1 {
+ //};
+ //struct S : Base2 {
+ //} s{};
+
+ //auto [t, i, d, c] = s;
+ //T localT{};
+ public void testMultipleVariablesDeepBaseStructure() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ IVariable variableT = helper.assertNonProblem("t,", 1);
+ IType variableTType = variableT.getType();
+ IVariable localT = helper.assertNonProblem("localT");
+ IType typeT = localT.getType();
+ assertSameType(typeT, variableTType);
+
+ assertType(helper.assertNonProblem("i,", 1), int_);
+ assertType(helper.assertNonProblem("d,", 1), double_);
+ assertType(helper.assertNonProblem("c]", 1), char_);
+ }
+
+ //struct S {
+ // int i;
+ // static float f;
+ // double d;
+ //} s{};
+
+ //auto [i, d] = s;
+ public void testStaticFieldsAreNotConsidered() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("i,", 1), int_);
+ assertType(helper.assertNonProblem("d]", 1), double_);
+ }
+
+ //namespace std {
+ // using size_t = unsigned long long;
+ // template <typename T, size_t N>
+ // struct array {
+ // T elements[N];
+ // };
+ // template <typename T>
+ // struct tuple_size;
+ // template <typename T, size_t N>
+ // struct tuple_size<array<T, N>> {
+ // constexpr static size_t value = N;
+ // };
+ // template <size_t I, typename T>
+ // struct tuple_element;
+ // template <size_t I, typename T, size_t N>
+ // struct tuple_element<I, array<T, N>> {
+ // using type = T;
+ // };
+ //}
+
+ //auto [f, s, t] = std::array<int, 3>{1, 2, 3};
+ public void testStandardArray() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ //Target code lacks the required get() functions determine the value of the names f, s and t.
+ //But the types can still be resolved with tuple_element
+ assertType(helper.assertNonProblem("f,", 1), int_);
+ assertType(helper.assertNonProblem("s,", 1), int_);
+ assertType(helper.assertNonProblem("t]", 1), int_);
+ }
+
+ //namespace std {
+ // using size_t = unsigned long long;
+ // template <typename T1, typename T2>
+ // struct pair {
+ // T1 t1;
+ // T2 t2;
+ // };
+ // template <typename T>
+ // struct tuple_size;
+ // template <typename T1, typename T2>
+ // struct tuple_size<pair<T1, T2>> {
+ // constexpr static size_t value = 2;
+ // };
+ // template <size_t I, typename T>
+ // struct tuple_element;
+ // template <typename T>
+ // struct tuple_element_base {
+ // using type = T;
+ // };
+ // template <typename T1, typename T2>
+ // struct tuple_element<0, pair<T1, T2>> : tuple_element_base<T1> {
+ // };
+ // template <typename T1, typename T2>
+ // struct tuple_element<1, pair<T1, T2>> : tuple_element_base<T2> {
+ // };
+ // template <size_t I, typename T1, typename T2>
+ // auto get(pair<T1, T2> const & p) {
+ // if constexpr (I == 0) {
+ // return p.t1;
+ // } else {
+ // return p.t2;
+ // }
+ // }
+ //}
+
+ //auto [a, b] = std::pair<int, double>{42, 3.14};
+ public void testRecursiveTupleElement() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("a,", 1), int_);
+ assertType(helper.assertNonProblem("b]", 1), double_);
+ }
+
+ //namespace std {
+ // using size_t = unsigned long long;
+ // template <typename T, size_t N>
+ // struct array {
+ // T elements[N];
+ // };
+ // template <typename T>
+ // struct tuple_size;
+ // template <typename T, size_t N>
+ // struct tuple_size<array<T, N>> {
+ // constexpr static size_t value = N;
+ // };
+ // template <size_t I, typename T>
+ // struct tuple_element;
+ // template <size_t I, typename T, size_t N>
+ // struct tuple_element<I, array<T, N>> {
+ // using type = T;
+ // };
+ //}
+ //struct X {
+ // int first;
+ // int second;
+ //};
+
+ //int main() {
+ // auto arr = std::array<X, 3>{X{1,2}, X{3,4}, X{5,6}};
+ // for (auto [firstX, secondX] : arr.elements) {
+ // auto sum = firstX + secondX;
+ // }
+ //}
+ public void testStandardArrayInLoop() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ //Target code lacks the required get() functions determine the value of the names f, s and t.
+ //But the types can still be resolved with tuple_element
+ assertType(helper.assertNonProblem("firstX,", 6), int_);
+ assertType(helper.assertNonProblem("secondX]", 7), int_);
+ assertType(helper.assertNonProblem("sum", 3), int_);
+ }
+
+ //struct X {
+ // int first;
+ // int second;
+ // void fun();
+ //};
+
+ //void X::fun() {
+ // auto [f, s] = *this;
+ //}
+ public void testBindStarThis() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("f,", 1), int_);
+ assertType(helper.assertNonProblem("s]", 1), int_);
+ }
+}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/StructuredBindingTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/StructuredBindingTests.java
new file mode 100644
index 00000000000..5bbaebd81fd
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/StructuredBindingTests.java
@@ -0,0 +1,418 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Institute for Software, HSR Hochschule fuer Technik
+ * Rapperswil, University of applied sciences.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Thomas Corbat (IFS) - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.core.parser.tests.ast2.cxx17;
+
+import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.char_;
+import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.constInt;
+import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.double_;
+import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.float_;
+import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.int_;
+import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.referenceTo;
+import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.referenceToConstInt;
+import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.referenceToInt;
+import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.rvalueReferenceTo;
+import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.rvalueReferenceToInt;
+import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.volatileOf;
+
+import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
+import org.eclipse.cdt.core.dom.ast.IBinding;
+import org.eclipse.cdt.core.dom.ast.IValue;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
+import org.eclipse.cdt.core.parser.tests.ast2.AST2CPPTestBase;
+import org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes;
+import org.eclipse.cdt.internal.core.dom.parser.CompositeValue;
+import org.eclipse.cdt.internal.core.dom.parser.FloatingPointValue;
+import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPStructuredBindingComposite;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
+
+public class StructuredBindingTests extends AST2CPPTestBase {
+
+ //struct S {
+ // int first;
+ // double second;
+ //};
+ //auto [f1, s1] = S{1, 2};
+ //auto f2 = f1;
+ //auto s2 = s1;
+ public void testFromTemporary() throws Exception {
+ parseAndCheckBindings();
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ IBinding f1Declaration = helper.assertNonProblem("f1, ", 2);
+ IBinding f1Reference = helper.assertNonProblem("f1;", 2);
+ assertSame(f1Declaration, f1Reference);
+
+ IBinding s1Declaration = helper.assertNonProblem("s1] ", 2);
+ IBinding s1Reference = helper.assertNonProblem("s1;", 2);
+ assertSame(s1Declaration, s1Reference);
+ }
+
+ //struct S {
+ // int first;
+ // double second;
+ //};
+ //S createS() {
+ // return {1, 2};
+ //}
+ //auto [f, s] = createS();
+ public void testFromReturnValue() throws Exception {
+ parseAndCheckBindings();
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("f,", 1), int_);
+ assertType(helper.assertNonProblem("s]", 1), double_);
+ }
+
+ //struct S {
+ // int first;
+ // double second;
+ //};
+ //S createS() {
+ // return {1, 2};
+ //}
+ //auto [f, s]{createS()};
+ public void testBracedInitialization() throws Exception {
+ parseAndCheckBindings();
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("f,", 1), int_);
+ assertType(helper.assertNonProblem("s]", 1), double_);
+ }
+
+ //struct S {
+ // int first;
+ // double second;
+ //};
+ //S createS() {
+ // return {1, 2};
+ //}
+ //auto [f, s](createS());
+ public void testCopyInitialization() throws Exception {
+ parseAndCheckBindings();
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("f,", 1), int_);
+ assertType(helper.assertNonProblem("s]", 1), double_);
+ }
+
+ //struct S {
+ // int first;
+ // int second;
+ // float third;
+ // double fourth;
+ // char fifth;
+ //};
+ //auto [f, s, t, fo, fif] = S{1, 2, 1.5f, 3.1415, '*'};
+ public void testWithManyInitializers() throws Exception {
+ parseAndCheckBindings();
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("f,", 1), int_);
+ assertType(helper.assertNonProblem("s,", 1), int_);
+ assertType(helper.assertNonProblem("t,", 1), float_);
+ assertType(helper.assertNonProblem("fo,", 2), double_);
+ assertType(helper.assertNonProblem("fif]", 3), char_);
+ }
+
+ //struct Base {
+ // int bi;
+ //};
+ //struct Sub : Base {
+ // static double sd;
+ //};
+ //auto [b] = Sub{1};
+ public void testWithBaseClass() throws Exception {
+ parseAndCheckBindings();
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("b]", 1), int_);
+ }
+
+ //auto f() -> int(&)[2];
+ //auto [x, y] = f();
+ //auto & [xr, yr] = f();
+ public void testStandardExample1() throws Exception {
+ parseAndCheckBindings();
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("xr,", 2), referenceToInt);
+ assertType(helper.assertNonProblem("yr]", 2), referenceToInt);
+ }
+
+ //struct S {
+ // int x1 : 2;
+ // volatile double y1;
+ //};
+ //S createS();
+ //auto const [x, y] = createS();
+ public void testStandardExample2() throws Exception {
+ parseAndCheckBindings();
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("x,", 1), constInt);
+ assertType(helper.assertNonProblem("y]", 1), CommonCPPTypes.constVolatileOf(double_));
+ }
+
+ //int arr[]{1, 2, 3};
+ //auto [f, s, t] = arr;
+ public void testFromArray() throws Exception {
+ parseAndCheckBindings();
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("f,", 1), int_);
+ assertType(helper.assertNonProblem("s,", 1), int_);
+ assertType(helper.assertNonProblem("t]", 1), int_);
+ }
+
+ //struct S {
+ // int i;
+ //} s{};
+ //auto && [f] = s;
+ public void testForwardingReferenceWithLvalue() throws Exception {
+ parseAndCheckBindings();
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("f]", 1), referenceToInt);
+ }
+
+ //struct S {
+ // int i;
+ //} s{};
+ //auto && [f] = static_cast<S&&>(s);
+ public void testForwardingReferenceWithXvalue() throws Exception {
+ parseAndCheckBindings();
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("f]", 1), rvalueReferenceToInt);
+ }
+
+ //struct S {
+ // int i;
+ //};
+ //auto && [f] = S{};
+ public void testForwardingReferenceWithRvalue() throws Exception {
+ parseAndCheckBindings();
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("f]", 1), rvalueReferenceToInt);
+ }
+
+ //struct S {
+ // int first;
+ // double second;
+ //};
+ //
+ //namespace std {
+ // template <typename>
+ // struct tuple_size;
+ //}
+ //auto [f, s] = S{};
+ public void testUnspecializedTupleSizeTemplate() throws Exception {
+ parseAndCheckBindings();
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("f,", 1), int_);
+ assertType(helper.assertNonProblem("s]", 1), double_);
+ }
+
+ //namespace std {
+ // using size_t = unsigned long long;
+ //}
+ //
+ //struct S {
+ // int first() const {
+ // return 1;
+ // }
+ // double second() const {
+ // return 2.0;
+ // }
+ // template <std::size_t V>
+ // auto get() {
+ // if constexpr (V == 0) {
+ // return first();
+ // } else if (V == 1) {
+ // return second();
+ // }
+ // static_assert(V < 2);
+ // }
+ //};
+ //
+ //namespace std {
+ // template <typename>
+ // struct tuple_size;
+ // template <>
+ // struct tuple_size<S> {
+ // constexpr static size_t value = 2;
+ // };
+ // template <std::size_t, typename>
+ // struct tuple_element;
+ // template <>
+ // struct tuple_element<0, S> {
+ // using type = int;
+ // };
+ // template <>
+ // struct tuple_element<1, S> {
+ // using type = double;
+ // };
+ //}
+ //auto [f, s] = S{};
+ public void testFromTupleLikeDecompositionWithMemberGet() throws Exception {
+ parseAndCheckBindings();
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("f,", 1), int_);
+ assertType(helper.assertNonProblem("s]", 1), double_);
+ }
+
+ //namespace std {
+ // using size_t = unsigned long long;
+ //}
+ //
+ //struct S {
+ // int first() const {
+ // return 1;
+ // }
+ // double second() const {
+ // return 2.0;
+ // }
+ //};
+ //template <std::size_t V>
+ //auto get(S s) {
+ // if constexpr (V == 0) {
+ // return s.first();
+ // } else if (V == 1) {
+ // return s.second();
+ // }
+ // static_assert(V < 2);
+ //}
+ //
+ //namespace std {
+ // template <typename>
+ // struct tuple_size;
+ // template <>
+ // struct tuple_size<S> {
+ // constexpr static size_t value = 2;
+ // };
+ // template <std::size_t, typename>
+ // struct tuple_element;
+ // template <>
+ // struct tuple_element<0, S> {
+ // using type = int;
+ // };
+ // template <>
+ // struct tuple_element<1, S> {
+ // using type = double;
+ // };
+ //}
+ //auto [f, s] = S{};
+ public void testFromTupleLikeDecompositionWithInheritedTupleElementType() throws Exception {
+ parseAndCheckBindings();
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("f,", 1), int_);
+ assertType(helper.assertNonProblem("s]", 1), double_);
+ }
+
+ //struct S {
+ // int member;
+ //} s{1};
+ //auto [valueLarg] = s;
+ //auto [valueRarg] = S{1};
+ //auto const [valueConstLarg] = s;
+ //auto const [valueConstRarg] = S{1};
+ //auto & [lrefLarg] = s;
+ //auto & [lrefRarg] = S{1};
+ //auto const & [lrefConstLarg] = s;
+ //auto const & [lrefConstRarg] = S{1};
+ //auto && [frefLarg] = s;
+ //auto && [frefRarg] = S{1};
+ //auto const && [rrefConstLarg] = s;
+ //auto const && [rrefConstRarg] = S{1};
+ //auto const sConst = s;
+ //auto & [lrefLConstarg] = sConst;
+ //auto && [frefLConstarg] = sConst;
+ //S volatile sVolatile{1};
+ //auto & [lrefLVolatilearg] = sVolatile;
+ //auto && [frefLVolatilearg] = sVolatile;
+ public void testResultingTypes() throws Exception {
+ parseAndCheckBindings();
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("valueLarg"), int_);
+ assertType(helper.assertNonProblem("valueRarg"), int_);
+ assertType(helper.assertNonProblem("valueConstLarg"), constInt);
+ assertType(helper.assertNonProblem("valueConstRarg"), constInt);
+ assertType(helper.assertNonProblem("lrefLarg"), referenceToInt);
+ assertType(helper.assertNonProblem("lrefRarg"), referenceToInt);
+ assertType(helper.assertNonProblem("lrefConstLarg"), referenceToConstInt);
+ assertType(helper.assertNonProblem("lrefConstRarg"), referenceToConstInt);
+ assertType(helper.assertNonProblem("frefLarg"), referenceToInt);
+ assertType(helper.assertNonProblem("frefRarg"), rvalueReferenceToInt);
+ assertType(helper.assertNonProblem("rrefConstLarg"), rvalueReferenceTo(constInt));
+ assertType(helper.assertNonProblem("rrefConstRarg"), rvalueReferenceTo(constInt));
+ assertType(helper.assertNonProblem("lrefLConstarg"), referenceToConstInt);
+ assertType(helper.assertNonProblem("frefLConstarg"), referenceToConstInt);
+ assertType(helper.assertNonProblem("lrefLVolatilearg"), referenceTo(volatileOf(int_)));
+ assertType(helper.assertNonProblem("frefLVolatilearg"), referenceTo(volatileOf(int_)));
+ }
+
+ //struct Aggregate {
+ // int i;
+ // double d;
+ // auto first() {
+ // auto [field1, _] = *this;
+ // return field1;
+ // }
+ // auto second() {
+ // auto [_, field2] = *this;
+ // return field2;
+ // }
+ //};
+ public void testThisDecomposition() throws Exception {
+ parseAndCheckBindings();
+ BindingAssertionHelper helper = getAssertionHelper();
+
+ assertType(helper.assertNonProblem("field1;", 6), int_);
+ assertType(helper.assertNonProblem("field2;", 6), double_);
+ }
+
+ //struct S {
+ // int first;
+ // double second;
+ //};
+ //constexpr S createS() {
+ // return S{1, 2.0};
+ //}
+ //auto [f, s] = createS();
+ public void testIVariablePropertiesOfImplicitNameForInitializer() throws Exception {
+ parseAndCheckBindings();
+ BindingAssertionHelper helper = getAssertionHelper();
+ ICPPClassType classS = helper.assertNonProblem("S", 1);
+ IASTImplicitName[] implicitNames = helper.getImplicitNames("= createS();", 11);
+ assertEquals(1, implicitNames.length);
+ IASTImplicitName implicitName = implicitNames[0];
+ IBinding binding = implicitName.getBinding();
+ CPPStructuredBindingComposite variable = assertInstance(binding, CPPStructuredBindingComposite.class);
+ assertType(variable, classS);
+ IValue initialValue = variable.getInitialValue();
+ CompositeValue compositeValue = assertInstance(initialValue, CompositeValue.class);
+ ICPPEvaluation[] subvalues = compositeValue.getAllSubValues();
+ assertEquals(2, subvalues.length);
+ assertEquals(IntegralValue.create(1), subvalues[0].getValue());
+ assertEquals(FloatingPointValue.create(2.0), subvalues[1].getValue());
+ }
+}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java
index 6543e396557..12a6ac0f346 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java
@@ -16,6 +16,7 @@ package org.eclipse.cdt.internal.index.tests;
import org.eclipse.cdt.core.parser.tests.ast2.cxx14.GenericLambdaIndexTests;
import org.eclipse.cdt.core.parser.tests.ast2.cxx14.ReturnTypeDeductionIndexTests;
+import org.eclipse.cdt.core.parser.tests.ast2.cxx17.StructuredBindingIndexTests;
import org.eclipse.cdt.core.parser.tests.ast2.cxx17.TemplateAutoIndexTests;
import junit.framework.Test;
@@ -48,6 +49,7 @@ public class IndexTests extends TestSuite {
// C++17 index test suites
suite.addTestSuite(TemplateAutoIndexTests.class);
+ suite.addTestSuite(StructuredBindingIndexTests.class);
IndexCPPBindingResolutionBugs.addTests(suite);
IndexCPPBindingResolutionTest.addTests(suite);
diff --git a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterAttributeTestSource.awts b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterAttributeTestSource.awts
index 64a636b5309..6b9412cb0de 100644
--- a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterAttributeTestSource.awts
+++ b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterAttributeTestSource.awts
@@ -376,4 +376,9 @@ int __declspec(selectany)* pi2 = 0;
//!MS declspec attribute on simple declaration
//%CPP GNU
-__declspec(thread) int tls_i = 1; \ No newline at end of file
+__declspec(thread) int tls_i = 1;
+
+//!Attributed structured binding declaration
+//%CPP
+int arr[]{1, 2, 3};
+[[nodiscard]] auto [a, b, c] = arr;
diff --git a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterDeclarationTestSource.awts b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterDeclarationTestSource.awts
index 0228c738221..e15e59ece6f 100644
--- a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterDeclarationTestSource.awts
+++ b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterDeclarationTestSource.awts
@@ -214,3 +214,17 @@ enum struct [[foo]] X{ };
//!Attributed scoped enum declaration with keyword class
//%CPP
enum class [[foo]] X{ };
+
+//!Structured binding declarations
+//%CPP
+struct S
+{
+ int first, second, third;
+} s{};
+int arr[]{1, 2, 3};
+auto [a, b, c] = arr;
+auto [d, e, f]{s};
+auto [g, h, i](arr);
+auto& [j, k, l] = arr;
+const auto& [m, n, o] = S{};
+auto&& [p, q, r] = S{};
diff --git a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterStatementTestSource.awts b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterStatementTestSource.awts
index 41cd52b2d28..64fe167a370 100644
--- a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterStatementTestSource.awts
+++ b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterStatementTestSource.awts
@@ -421,4 +421,19 @@ void f()
case 42:
break;
}
+}
+
+//!Range-based for with structured binding
+//%CPP
+struct S
+{
+ int i;
+ float f;
+};
+
+void rangedBasedForContext()
+{
+ S esses[] = {S{}, S{}, S{}};
+ for (auto [l, r]: esses){
+ }
} \ No newline at end of file

Back to the top