Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorNathan Ridge2017-06-02 07:00:26 +0000
committerNathan Ridge2017-12-31 05:18:29 +0000
commit1213755167106193fa9e1389caa22d3ab2a2b607 (patch)
tree849147e1e6bc8051fcd159a2bc20dd93a3e0b0b8 /core
parenta8ff78b531d599ebfa99464a897bb4957ed8bf3f (diff)
downloadorg.eclipse.cdt-1213755167106193fa9e1389caa22d3ab2a2b607.tar.gz
org.eclipse.cdt-1213755167106193fa9e1389caa22d3ab2a2b607.tar.xz
org.eclipse.cdt-1213755167106193fa9e1389caa22d3ab2a2b607.zip
Bug 517670 - Handle instantiation of closure types
Diffstat (limited to 'core')
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/VariableTemplateTests.java16
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureSpecialization.java105
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java10
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java5
4 files changed, 128 insertions, 8 deletions
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 4b0b0afe021..360ce84a7db 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
@@ -11,7 +11,6 @@
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.cxx14;
-import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
@@ -23,13 +22,13 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
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.AST2TestBase;
+import org.eclipse.cdt.core.parser.tests.ast2.AST2CPPTestBase;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFieldTemplateSpecialization;
import junit.framework.TestSuite;
-public class VariableTemplateTests extends AST2TestBase {
+public class VariableTemplateTests extends AST2CPPTestBase {
public static TestSuite suite() {
return suite(VariableTemplateTests.class);
@@ -362,8 +361,13 @@ public class VariableTemplateTests extends AST2TestBase {
ICPPVariable waldo2 = ah.assertNonProblem("waldo2");
assertVariableValue(waldo2, 0);
}
-
- private IASTTranslationUnit parseAndCheckBindings() throws Exception {
- return parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP);
+
+ // template <typename R>
+ // auto L = []{ return R{}; };
+ //
+ // decltype(L<int>()) waldo;
+ public void testLambdaValue_517670() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+ helper.assertVariableType("waldo", CommonCPPTypes.int_);
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureSpecialization.java
new file mode 100644
index 00000000000..8399bccbba9
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureSpecialization.java
@@ -0,0 +1,105 @@
+package org.eclipse.cdt.internal.core.dom.parser.cpp;
+
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.IBinding;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
+
+/**
+ * Specialization of a closure type.
+ */
+public class CPPClosureSpecialization extends CPPClosureType implements ICPPClassSpecialization {
+ private CPPClosureType fSpecialized;
+ private ICPPTemplateParameterMap fMap;
+
+ public CPPClosureSpecialization(ICPPASTLambdaExpression lambda, CPPClosureType specialized,
+ InstantiationContext context) {
+ super(lambda);
+ fSpecialized = specialized;
+ fMap = context.getParameterMap();
+ ICPPMethod[] methods = specialized.getMethods();
+ fMethods = new ICPPMethod[methods.length];
+ for (int i = 0; i < methods.length; ++i) {
+ fMethods[i] = (ICPPMethod) specializeMember(methods[i]);
+ }
+ }
+
+ @Override
+ public ICPPTemplateParameterMap getTemplateParameterMap() {
+ return fMap;
+ }
+
+ @Override
+ public ICPPClassType getSpecializedBinding() {
+ return fSpecialized;
+ }
+
+ @Override
+ public IBinding specializeMember(IBinding binding) {
+ // TODO: Cache specialized members the way class template specializations do?
+ return CPPTemplates.createSpecialization(this, binding);
+ }
+
+ @Override
+ public IBinding specializeMember(IBinding binding, IASTNode point) {
+ return specializeMember(binding);
+ }
+
+ @Override
+ public ICPPBase[] getBases(IASTNode point) {
+ return ICPPBase.EMPTY_BASE_ARRAY;
+ }
+
+ @Override
+ public ICPPConstructor[] getConstructors(IASTNode point) {
+ return getConstructors();
+ }
+
+ @Override
+ public ICPPField[] getDeclaredFields(IASTNode point) {
+ return ICPPField.EMPTY_CPPFIELD_ARRAY;
+ }
+
+ @Override
+ public ICPPMethod[] getMethods(IASTNode point) {
+ return getMethods();
+ }
+
+ @Override
+ public ICPPMethod[] getAllDeclaredMethods(IASTNode point) {
+ return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
+ }
+
+ @Override
+ public ICPPMethod[] getDeclaredMethods(IASTNode point) {
+ return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
+ }
+
+ @Override
+ public IBinding[] getFriends(IASTNode point) {
+ return IBinding.EMPTY_BINDING_ARRAY;
+ }
+
+ @Override
+ public ICPPField[] getFields(IASTNode point) {
+ return ICPPField.EMPTY_CPPFIELD_ARRAY;
+ }
+
+ @Override
+ public ICPPClassType[] getNestedClasses(IASTNode point) {
+ return ICPPClassType.EMPTY_CLASS_ARRAY;
+ }
+
+ @Override
+ public ICPPUsingDeclaration[] getUsingDeclarations(IASTNode point) {
+ return ICPPUsingDeclaration.EMPTY_USING_DECL_ARRAY;
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java
index 492651e84bb..2c062d53131 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java
@@ -69,7 +69,7 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
private final ICPPASTLambdaExpression fLambdaExpression;
private IType[] fParameterTypes;
private ICPPParameter[] fParameters;
- private ICPPMethod[] fMethods;
+ protected ICPPMethod[] fMethods;
private ClassScope fScope;
// Used for generic lambdas; null otherwise.
private ICPPTemplateParameter[] fInventedTemplateParameters;
@@ -77,7 +77,7 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
public CPPClosureType(ICPPASTLambdaExpression lambdaExpr) {
fLambdaExpression= lambdaExpr;
}
-
+
private ICPPMethod[] createMethods() {
boolean needConversionOperator=
fLambdaExpression.getCaptureDefault() == CaptureDefault.UNSPECIFIED &&
@@ -451,6 +451,12 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
throw new IllegalArgumentException(member.getName() + " is not a member of closure type '" //$NON-NLS-1$
+ fLambdaExpression.getRawSignature() + "'"); //$NON-NLS-1$
}
+
+ // A lambda expression can appear in a dependent context, such as in the value of
+ // a variable template, so it needs to be instantiable.
+ public CPPClosureType instantiate(InstantiationContext context) {
+ return new CPPClosureSpecialization(fLambdaExpression, this, context);
+ }
private final class ClassScope implements ICPPClassScope {
@Override
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
index b575b455836..58c6af7f199 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
@@ -143,6 +143,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassSpecialization.Recur
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassTemplatePartialSpecializationSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassTemplateSpecialization;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClosureType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructorInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructorSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructorTemplateSpecialization;
@@ -1663,6 +1664,10 @@ public class CPPTemplates {
default: return null; // shouldn't happen
}
}
+
+ if (type instanceof CPPClosureType) {
+ return ((CPPClosureType) type).instantiate(context);
+ }
return type;
} catch (DOMException e) {

Back to the top