mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 17:35:35 +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;
|
||||
|
||||
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_);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 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
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Reference in a new issue