mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-11 02:05:39 +02:00
Bug 517670 - Handle instantiation of closure types
Change-Id: I82208dbb2ec0e11760cbd78a073acefa627d8d36
This commit is contained in:
parent
27b9230cad
commit
0a639043fa
4 changed files with 128 additions and 8 deletions
|
@ -11,7 +11,6 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.parser.tests.ast2.cxx14;
|
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.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
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.ICPPVariableInstance;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate;
|
||||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
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.CPPClassInstance;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFieldTemplateSpecialization;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFieldTemplateSpecialization;
|
||||||
|
|
||||||
import junit.framework.TestSuite;
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
public class VariableTemplateTests extends AST2TestBase {
|
public class VariableTemplateTests extends AST2CPPTestBase {
|
||||||
|
|
||||||
public static TestSuite suite() {
|
public static TestSuite suite() {
|
||||||
return suite(VariableTemplateTests.class);
|
return suite(VariableTemplateTests.class);
|
||||||
|
@ -363,7 +362,12 @@ public class VariableTemplateTests extends AST2TestBase {
|
||||||
assertVariableValue(waldo2, 0);
|
assertVariableValue(waldo2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IASTTranslationUnit parseAndCheckBindings() throws Exception {
|
// template <typename R>
|
||||||
return parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP);
|
// auto L = []{ return R{}; };
|
||||||
|
//
|
||||||
|
// decltype(L<int>()) waldo;
|
||||||
|
public void testLambdaValue_517670() throws Exception {
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableType("waldo", CommonCPPTypes.int_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -69,7 +69,7 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
|
||||||
private final ICPPASTLambdaExpression fLambdaExpression;
|
private final ICPPASTLambdaExpression fLambdaExpression;
|
||||||
private IType[] fParameterTypes;
|
private IType[] fParameterTypes;
|
||||||
private ICPPParameter[] fParameters;
|
private ICPPParameter[] fParameters;
|
||||||
private ICPPMethod[] fMethods;
|
protected ICPPMethod[] fMethods;
|
||||||
private ClassScope fScope;
|
private ClassScope fScope;
|
||||||
// Used for generic lambdas; null otherwise.
|
// Used for generic lambdas; null otherwise.
|
||||||
private ICPPTemplateParameter[] fInventedTemplateParameters;
|
private ICPPTemplateParameter[] fInventedTemplateParameters;
|
||||||
|
@ -452,6 +452,12 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
|
||||||
+ fLambdaExpression.getRawSignature() + "'"); //$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 {
|
private final class ClassScope implements ICPPClassScope {
|
||||||
@Override
|
@Override
|
||||||
public EScopeKind getKind() {
|
public EScopeKind getKind() {
|
||||||
|
|
|
@ -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.CPPClassTemplatePartialSpecialization;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassTemplatePartialSpecializationSpecialization;
|
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.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.CPPConstructorInstance;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructorSpecialization;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructorSpecialization;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructorTemplateSpecialization;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructorTemplateSpecialization;
|
||||||
|
@ -1664,6 +1665,10 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type instanceof CPPClosureType) {
|
||||||
|
return ((CPPClosureType) type).instantiate(context);
|
||||||
|
}
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
return e.getProblem();
|
return e.getProblem();
|
||||||
|
|
Loading…
Add table
Reference in a new issue