mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 22:22:11 +02:00
Bug 528457 - Store lambda parameters in index
The special binding type CPPLambdaExpressionParameter is removed. Instead, a lambda expression parameters's are represented as regular CPPParameters owned by the closure type's generated function call operator. Change-Id: I4afeac90c2595a1f84dfa59f057d0494b64d079c
This commit is contained in:
parent
ce18aad766
commit
a8ff78b531
7 changed files with 76 additions and 205 deletions
|
@ -72,8 +72,7 @@ public class GenericLambdaIndexTests extends IndexBindingResolutionTestBase {
|
|||
// waldo(foo(L(42, 'x')));
|
||||
// waldo(bar(L(42, 'x', 42.0f)));
|
||||
// }
|
||||
public void _testVariadicAutoParameter() throws Exception {
|
||||
// TODO: To pass this test, we need to store lambda parameters in the index.
|
||||
public void testVariadicAutoParameter() throws Exception {
|
||||
checkBindings();
|
||||
}
|
||||
|
||||
|
|
|
@ -109,6 +109,17 @@ public class CPPASTConversionName extends CPPASTNameBase implements ICPPASTConve
|
|||
return fName;
|
||||
}
|
||||
|
||||
public static char[] createName(String targetName) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(Keywords.cOPERATOR);
|
||||
buf.append(' ');
|
||||
buf.append(targetName);
|
||||
final int len= buf.length();
|
||||
char[] name= new char[len];
|
||||
buf.getChars(0, len, name, 0);
|
||||
return name;
|
||||
}
|
||||
|
||||
public static char[] createName(IType t, IASTNode typeId) {
|
||||
StringBuilder buf= new StringBuilder();
|
||||
buf.append(Keywords.cOPERATOR);
|
||||
|
|
|
@ -67,6 +67,8 @@ import org.eclipse.core.runtime.PlatformObject;
|
|||
*/
|
||||
public class CPPClosureType extends PlatformObject implements ICPPClassType, ICPPInternalBinding {
|
||||
private final ICPPASTLambdaExpression fLambdaExpression;
|
||||
private IType[] fParameterTypes;
|
||||
private ICPPParameter[] fParameters;
|
||||
private ICPPMethod[] fMethods;
|
||||
private ClassScope fScope;
|
||||
// Used for generic lambdas; null otherwise.
|
||||
|
@ -113,10 +115,7 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
|
|||
final IType[] parameterTypes= getParameterTypes();
|
||||
ft= new CPPFunctionType(returnType, parameterTypes, !isMutable(), false, false, false, false);
|
||||
|
||||
ICPPParameter[] params = new ICPPParameter[parameterTypes.length];
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
params[i]= new CPPParameter(parameterTypes[i], i);
|
||||
}
|
||||
ICPPParameter[] params = getParameters();
|
||||
char[] operatorParensName = OverloadableOperator.PAREN.toCharArray();
|
||||
if (isGeneric()) {
|
||||
m = new CPPImplicitMethodTemplate(getInventedTemplateParameterList(), scope, operatorParensName,
|
||||
|
@ -136,7 +135,10 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
|
|||
if (needConversionOperator) {
|
||||
final CPPFunctionType conversionTarget = new CPPFunctionType(returnType, parameterTypes);
|
||||
ft= new CPPFunctionType(conversionTarget, IType.EMPTY_TYPE_ARRAY, true, false, false, false, false);
|
||||
char[] conversionOperatorName = CPPASTConversionName.createName(conversionTarget, null);
|
||||
// Calling CPPASTConversionName.createName(IType) would try to stringize the type to
|
||||
// construct a name, which is unnecessary work (not to mention prone to recursion with
|
||||
// dependent types). Since the name doesn't matter anyways, just make one up.
|
||||
char[] conversionOperatorName = CPPASTConversionName.createName("__fptr"); //$NON-NLS-1$
|
||||
if (isGeneric()) {
|
||||
ICPPTemplateParameter[] templateParams = getInventedTemplateParameterList();
|
||||
// Clone the template parameters, since they are used by the function call operator,
|
||||
|
@ -236,11 +238,32 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
|
|||
}
|
||||
|
||||
private IType[] getParameterTypes() {
|
||||
ICPPASTFunctionDeclarator lambdaDtor = fLambdaExpression.getDeclarator();
|
||||
if (lambdaDtor != null) {
|
||||
return CPPVisitor.createParameterTypes(lambdaDtor);
|
||||
if (fParameterTypes == null) {
|
||||
ICPPASTFunctionDeclarator lambdaDtor = fLambdaExpression.getDeclarator();
|
||||
if (lambdaDtor != null) {
|
||||
fParameterTypes = CPPVisitor.createParameterTypes(lambdaDtor);
|
||||
} else {
|
||||
fParameterTypes = IType.EMPTY_TYPE_ARRAY;
|
||||
}
|
||||
}
|
||||
return IType.EMPTY_TYPE_ARRAY;
|
||||
return fParameterTypes;
|
||||
}
|
||||
|
||||
public ICPPParameter[] getParameters() {
|
||||
if (fParameters == null) {
|
||||
final IType[] parameterTypes= getParameterTypes();
|
||||
fParameters = new ICPPParameter[parameterTypes.length];
|
||||
ICPPASTFunctionDeclarator lambdaDtor = fLambdaExpression.getDeclarator();
|
||||
if (lambdaDtor != null) {
|
||||
ICPPASTParameterDeclaration[] paramDecls = lambdaDtor.getParameters();
|
||||
for (int i = 0; i < fParameters.length; i++) {
|
||||
CPPParameter param = new CPPParameter(parameterTypes[i], i);
|
||||
param.addDeclaration(paramDecls[i].getDeclarator().getName());
|
||||
fParameters[i] = param;
|
||||
}
|
||||
}
|
||||
}
|
||||
return fParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,180 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010, 2014 Wind River Systems, Inc. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn (Wind River Systems) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ILinkage;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.IValue;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType;
|
||||
import org.eclipse.cdt.internal.core.dom.Linkage;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||
import org.eclipse.core.runtime.PlatformObject;
|
||||
|
||||
/**
|
||||
* Binding for a c++ function parameter
|
||||
*/
|
||||
public class CPPLambdaExpressionParameter extends PlatformObject implements ICPPParameter {
|
||||
private IType fType;
|
||||
private IASTName fDeclaration;
|
||||
|
||||
public CPPLambdaExpressionParameter(IASTName name) {
|
||||
fDeclaration = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isParameterPack() {
|
||||
return getType() instanceof ICPPParameterPackType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return new String(getNameCharArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getNameCharArray() {
|
||||
return fDeclaration.getSimpleID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IScope getScope() {
|
||||
return CPPVisitor.getContainingScope(fDeclaration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType getType() {
|
||||
if (fType == null) {
|
||||
IASTNode parent= fDeclaration.getParent();
|
||||
while (parent != null) {
|
||||
if (parent instanceof ICPPASTParameterDeclaration) {
|
||||
fType= CPPVisitor.createType((ICPPASTParameterDeclaration) parent, false);
|
||||
break;
|
||||
}
|
||||
parent= parent.getParent();
|
||||
}
|
||||
}
|
||||
return fType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getQualifiedName() {
|
||||
return new String[] { getName() };
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[][] getQualifiedNameCharArray() {
|
||||
return new char[][] { getNameCharArray() };
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGloballyQualified() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExtern() {
|
||||
//7.1.1-5 extern can not be used in the declaration of a parameter
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMutable() {
|
||||
//7.1.1-8 mutable can only apply to class members
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConstexpr() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAuto() {
|
||||
return hasStorageClass(IASTDeclSpecifier.sc_auto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegister() {
|
||||
return hasStorageClass(IASTDeclSpecifier.sc_register);
|
||||
}
|
||||
|
||||
private boolean hasStorageClass(int storage) {
|
||||
IASTNode parent = fDeclaration.getParent();
|
||||
while (parent != null && !(parent instanceof IASTParameterDeclaration))
|
||||
parent = parent.getParent();
|
||||
if (parent != null) {
|
||||
IASTDeclSpecifier declSpec = ((IASTParameterDeclaration) parent).getDeclSpecifier();
|
||||
if (declSpec.getStorageClass() == storage)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDefaultValue() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IValue getDefaultValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ILinkage getLinkage() {
|
||||
return Linkage.CPP_LINKAGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExternC() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String name = getName();
|
||||
return name.length() != 0 ? name : "<unnamed>"; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinding getOwner() {
|
||||
IASTNode node= fDeclaration;
|
||||
while (node != null && !(node instanceof ICPPASTLambdaExpression))
|
||||
node= node.getParent();
|
||||
|
||||
if (node instanceof ICPPASTLambdaExpression) {
|
||||
IType type= ((ICPPASTLambdaExpression) node).getExpressionType();
|
||||
if (type instanceof IBinding) {
|
||||
return (IBinding) type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IValue getInitialValue() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -26,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
|
|||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.IValue;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType;
|
||||
|
@ -277,6 +278,10 @@ public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPI
|
|||
ASTQueries.findAncestorWithType(fDeclarations[0], IASTFunctionDeclarator.class);
|
||||
if (decl == null)
|
||||
return null;
|
||||
if (decl.getParent() instanceof ICPPASTLambdaExpression) {
|
||||
CPPClosureType closure = (CPPClosureType) ((ICPPASTLambdaExpression) decl.getParent()).getExpressionType();
|
||||
return closure.getFunctionCallOperator();
|
||||
}
|
||||
IASTName name= decl.getName();
|
||||
return name != null ? name.resolveBinding() : null;
|
||||
}
|
||||
|
@ -299,9 +304,11 @@ public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPI
|
|||
}
|
||||
if (node instanceof IASTFunctionDeclarator) {
|
||||
IASTName funcName= ASTQueries.findInnermostDeclarator((IASTFunctionDeclarator) node).getName();
|
||||
IBinding b= funcName.resolvePreBinding();
|
||||
if (b instanceof ICPPInternalFunction) {
|
||||
return ((ICPPInternalFunction) b).resolveParameter(this);
|
||||
if (funcName != null) { // will be null for lambda declarator
|
||||
IBinding b= funcName.resolvePreBinding();
|
||||
if (b instanceof ICPPInternalFunction) {
|
||||
return ((ICPPInternalFunction) b).resolveParameter(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
|
|
|
@ -163,6 +163,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
||||
|
@ -207,7 +208,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
|
|||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionTemplate;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPLabel;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPLambdaExpressionParameter;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethod;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodTemplate;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNamespace;
|
||||
|
@ -744,6 +744,15 @@ public class CPPVisitor extends ASTQueries {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static int findParameterIndex(IASTParameterDeclaration param, IASTParameterDeclaration[] params) {
|
||||
int i= 0;
|
||||
for (; i < params.length; i++) {
|
||||
if (params[i] == param)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static IBinding createBinding(IASTDeclarator declarator) {
|
||||
IASTNode parent = findOutermostDeclarator(declarator).getParent();
|
||||
declarator= findInnermostDeclarator(declarator);
|
||||
|
@ -796,17 +805,18 @@ public class CPPVisitor extends ASTQueries {
|
|||
|
||||
final IASTNode dtorParent= findOutermostDeclarator(fdtor).getParent();
|
||||
if (dtorParent instanceof ICPPASTLambdaExpression) {
|
||||
return new CPPLambdaExpressionParameter(name);
|
||||
CPPClosureType closure = (CPPClosureType)
|
||||
((ICPPASTLambdaExpression) dtorParent).getExpressionType();
|
||||
ICPPParameter[] paramBindings = closure.getParameters();
|
||||
int index = findParameterIndex(param, fdtor.getParameters());
|
||||
if (index >= 0 && index < paramBindings.length) {
|
||||
return paramBindings[index];
|
||||
}
|
||||
}
|
||||
|
||||
if (dtorParent instanceof IASTDeclaration) {
|
||||
IASTParameterDeclaration[] params = fdtor.getParameters();
|
||||
int i= 0;
|
||||
for (; i < params.length; i++) {
|
||||
if (params[i] == param)
|
||||
break;
|
||||
}
|
||||
return new CPPParameter(name, i);
|
||||
int index = findParameterIndex(param, fdtor.getParameters());
|
||||
return new CPPParameter(name, index);
|
||||
}
|
||||
return null;
|
||||
} else if (parent instanceof ICPPASTTemplateDeclaration) {
|
||||
|
|
|
@ -63,8 +63,9 @@ public class EvalBinding extends CPPDependentEvaluation {
|
|||
private int fParameterPosition;
|
||||
/**
|
||||
* The binding represented by this evaluation. For a function parameter binding may be computed
|
||||
* lazily to avoid infinite recursion during unmarshalling of the evaluation. If #fBinding is
|
||||
* {@code null}, {@link #fParameterOwner} is guaranteed to be not {@code null} and vice versa.
|
||||
* lazily to avoid infinite recursion during unmarshalling of the evaluation. If
|
||||
* {@link #fBinding} is {@code null}, {@link #fParameterOwner} is guaranteed to be not {@code null}
|
||||
* and vice versa.
|
||||
*/
|
||||
private IBinding fBinding;
|
||||
private final boolean fFixedType;
|
||||
|
|
Loading…
Add table
Reference in a new issue