diff options
author | Nathan Ridge | 2017-06-02 07:00:26 +0000 |
---|---|---|
committer | Nathan Ridge | 2017-12-31 05:18:29 +0000 |
commit | 1213755167106193fa9e1389caa22d3ab2a2b607 (patch) | |
tree | 849147e1e6bc8051fcd159a2bc20dd93a3e0b0b8 /core | |
parent | a8ff78b531d599ebfa99464a897bb4957ed8bf3f (diff) | |
download | org.eclipse.cdt-1213755167106193fa9e1389caa22d3ab2a2b607.tar.gz org.eclipse.cdt-1213755167106193fa9e1389caa22d3ab2a2b607.tar.xz org.eclipse.cdt-1213755167106193fa9e1389caa22d3ab2a2b607.zip |
Bug 517670 - Handle instantiation of closure types
Change-Id: I82208dbb2ec0e11760cbd78a073acefa627d8d36
Diffstat (limited to 'core')
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) { |