Skip to main content
summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorNathan Ridge2017-05-18 05:10:45 +0000
committerNathan Ridge2018-01-10 05:08:21 +0000
commit27b9230cadf2a2010c60de86eed3e7b8ec59e92b (patch)
tree219c24ec31f05701850677067cbeea4846e9c267 /core
parent4b6c70fd5bfc26e4b0b66b834ca58465a6725cd0 (diff)
downloadorg.eclipse.cdt-27b9230cadf2a2010c60de86eed3e7b8ec59e92b.tar.gz
org.eclipse.cdt-27b9230cadf2a2010c60de86eed3e7b8ec59e92b.tar.xz
org.eclipse.cdt-27b9230cadf2a2010c60de86eed3e7b8ec59e92b.zip
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
Diffstat (limited to 'core')
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/GenericLambdaIndexTests.java3
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConversionName.java11
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java41
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPLambdaExpressionParameter.java180
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java13
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java28
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java5
7 files changed, 76 insertions, 205 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/GenericLambdaIndexTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/GenericLambdaIndexTests.java
index 65c546bc2d2..561d511f262 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/GenericLambdaIndexTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/GenericLambdaIndexTests.java
@@ -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();
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConversionName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConversionName.java
index 477d711cb94..53b6c1c055e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConversionName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConversionName.java
@@ -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);
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 99d967081ef..492651e84bb 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
@@ -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 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 IType.EMPTY_TYPE_ARRAY;
+ return fParameters;
}
@Override
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPLambdaExpressionParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPLambdaExpressionParameter.java
deleted file mode 100644
index 713b14b6bfd..00000000000
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPLambdaExpressionParameter.java
+++ /dev/null
@@ -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;
- }
-}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java
index e65fa986494..629daec5aa3 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java
@@ -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;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
index 4ccbc5f2741..9d65fb1daa7 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
@@ -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) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java
index dea9a222a87..51eca0ef32f 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java
@@ -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;

Back to the top