diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
index c4986dcb3e7..475c8aa5b3e 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
@@ -8856,7 +8856,7 @@ public class AST2CPPTests extends AST2BaseTest {
// return abs(a) < abs(b);
// });
// }
- public void _testLambdaExpression_316307b() throws Exception {
+ public void testLambdaExpression_316307b() throws Exception {
String code= getAboveComment();
parseAndCheckBindings(code);
}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java
index 40cff12b865..066846e11f5 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java
@@ -869,7 +869,6 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// foo/*i*/(23489); // IASTLiteralExpression
// foo/*j*/(sizeof(C));/*9*/ // IASTTypeIdExpression
// foo/*k*/(*cp);/*10*/ // IASTUnaryExpression
- // foo/*l*/(delete cp);/*11*/ // ICPPASTDeleteExpression
// foo/*m*/(new C());/*12*/ // ICPPASTNewExpression
// // ?? foo/*n*/(); // ICPPASTSimpleTypeConstructorExpression
// // ?? foo/*o*/(); // ICPPASTTypenameExprssion
@@ -916,9 +915,6 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
IBinding b10 = getBindingFromASTName("foo/*k*/", 3);
IBinding b10a = getBindingFromASTName("cp);/*10*/", 2);
- IBinding b11 = getBindingFromASTName("foo/*l*/", 3);
- IBinding b11a = getBindingFromASTName("cp);/*11*/", 2);
-
IBinding b12 = getBindingFromASTName("foo/*m*/", 3);
IBinding b12a = getBindingFromASTName("C());/*12*/", 1);
// IBinding b13 = getBindingFromASTName(ast, "foo/*n*/", 3);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTLambdaExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTLambdaExpression.java
index 41ecd0f3e98..78608a1f211 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTLambdaExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTLambdaExpression.java
@@ -13,6 +13,8 @@ package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
+import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
+import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
/**
* Lambda expression, introduced in C++0x.
@@ -21,7 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
-public interface ICPPASTLambdaExpression extends IASTExpression {
+public interface ICPPASTLambdaExpression extends IASTExpression, IASTImplicitNameOwner {
ASTNodeProperty CAPTURE = new ASTNodeProperty("ICPPASTLambdaExpression - CAPTURE [ICPPASTCapture]"); //$NON-NLS-1$
ASTNodeProperty DECLARATOR = new ASTNodeProperty("ICPPASTLambdaExpression - DECLARATOR [ICPPASTFunctionDeclarator]"); //$NON-NLS-1$
ASTNodeProperty BODY = new ASTNodeProperty("ICPPASTLambdaExpression - BODY [IASTCompoundStatement]"); //$NON-NLS-1$
@@ -40,13 +42,24 @@ public interface ICPPASTLambdaExpression extends IASTExpression {
* Returns the array of captures for this lambda expression.
*/
ICPPASTCapture[] getCaptures();
-
+
+ /**
+ * Returns an implicit name that represents the closure type.
+ */
+ IASTImplicitName getClosureTypeName();
+
/**
* Returns the lambda declarator for this lambda expression, or null
* in case it was not specified.
*/
ICPPASTFunctionDeclarator getDeclarator();
+ /**
+ * Returns an implicit name that represents the implicit function call operator of
+ * the closure.
+ */
+ IASTImplicitName getFunctionCallOperatorName();
+
/**
* Returns the compound statement of this lambda expression. Can be null
* when creating AST for content assist.
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 4090744e8e5..06c87d02aa1 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2008 IBM Corporation and others.
+ * Copyright (c) 2005, 2010 IBM Corporation 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
@@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
@@ -91,25 +92,31 @@ public class CPPASTConversionName extends CPPASTNameBase implements ICPPASTConve
public char[] toCharArray() {
if (fName == null) {
- StringBuilder buf= new StringBuilder();
- buf.append(Keywords.cOPERATOR);
- buf.append(' ');
+ IType t= null;
if (typeId != null) {
- IType t= CPPVisitor.createType(typeId);
- if (t != null) {
- buf.append(ASTTypeUtil.getType(t, true));
- } else {
- buf.append(typeId.getRawSignature());
- WHITESPACE_SEQ.matcher(buf).replaceAll(" "); //$NON-NLS-1$
- }
+ t= CPPVisitor.createType(typeId);
}
- final int len= buf.length();
- fName= new char[len];
- buf.getChars(0, len, fName, 0);
+ fName= createName(t, typeId);
}
return fName;
}
+ public static char[] createName(IType t, IASTNode typeId) {
+ StringBuilder buf= new StringBuilder();
+ buf.append(Keywords.cOPERATOR);
+ buf.append(' ');
+ if (t != null) {
+ buf.append(ASTTypeUtil.getType(t, true));
+ } else {
+ buf.append(typeId.getRawSignature());
+ WHITESPACE_SEQ.matcher(buf).replaceAll(" "); //$NON-NLS-1$
+ }
+ final int len= buf.length();
+ char[] name= new char[len];
+ buf.getChars(0, len, name, 0);
+ return name;
+ }
+
public char[] getSimpleID() {
return toCharArray();
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java
index 7b6bc969e8d..0288025321d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java
@@ -32,6 +32,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression;
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.ICPPFunction;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
@@ -109,8 +110,11 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
public IASTImplicitName[] getImplicitNames() {
if (implicitNames == null) {
ICPPFunction overload = getOperator();
- if (overload == null || overload instanceof CPPImplicitFunction)
- return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
+ if (overload == null || overload instanceof CPPImplicitFunction) {
+ if (!(overload instanceof ICPPMethod) || ((ICPPMethod) overload).isImplicit()) {
+ return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
+ }
+ }
// create separate implicit names for the two brackets
CPPASTImplicitName n1 = new CPPASTImplicitName(OverloadableOperator.PAREN, this);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTImplicitName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTImplicitName.java
index bee62bfccb0..c3b5d23df4e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTImplicitName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTImplicitName.java
@@ -25,6 +25,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
public class CPPASTImplicitName extends CPPASTName implements IASTImplicitName {
private boolean alternate;
private boolean isOperator;
+ private boolean isDefinition= false;
public CPPASTImplicitName(char[] name, IASTNode parent) {
super(name);
@@ -74,12 +75,16 @@ public class CPPASTImplicitName extends CPPASTName implements IASTImplicitName {
@Override
public boolean isDefinition() {
- return false;
+ return isDefinition;
}
@Override
public boolean isReference() {
- return true;
+ return !isDefinition;
+ }
+
+ public void setIsDefinition(boolean val) {
+ isDefinition= val;
}
/**
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLambdaExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLambdaExpression.java
index 72832388ab4..7b26865abff 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLambdaExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLambdaExpression.java
@@ -13,10 +13,11 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
-import org.eclipse.cdt.core.dom.ast.IType;
+import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
@@ -29,7 +30,12 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr
private CaptureDefault fCaptureDefault;
private ICPPASTCapture[] fCaptures;
private ICPPASTFunctionDeclarator fDeclarator;
+
private IASTCompoundStatement fBody;
+
+ private CPPClosureType fClosureType;
+ private IASTImplicitName fClosureTypeName;
+ private IASTImplicitName fImplicitFunctionCallName;
public CPPASTLambdaExpression() {
fCaptureDefault= CaptureDefault.UNSPECIFIED;
@@ -59,6 +65,41 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr
return result;
}
+ public IASTImplicitName[] getImplicitNames() {
+ return new IASTImplicitName[] {getFunctionCallOperatorName()};
+ }
+
+ public IASTImplicitName getClosureTypeName() {
+ if (fClosureTypeName == null) {
+ final CPPClosureType closureType = getExpressionType();
+ CPPASTImplicitName name = new CPPASTImplicitName(closureType.getNameCharArray(), this);
+ name.setBinding(closureType);
+ name.setIsDefinition(true);
+
+ name.setOffsetAndLength(getOffset(), 1);
+ fClosureTypeName= name;
+ }
+ return fClosureTypeName;
+ }
+
+ public IASTImplicitName getFunctionCallOperatorName() {
+ if (fImplicitFunctionCallName == null) {
+ final CPPClosureType closureType = getExpressionType();
+ ICPPFunction callOperator= closureType.getFunctionCallOperator();
+
+ CPPASTImplicitName name = new CPPASTImplicitName(closureType.getNameCharArray(), this);
+ name.setBinding(callOperator);
+ name.setIsDefinition(true);
+
+ if (fBody instanceof ASTNode) {
+ ASTNode bodyNode= (ASTNode) fBody;
+ name.setOffsetAndLength(bodyNode.getOffset(), 1);
+ }
+ fImplicitFunctionCallName= name;
+ }
+ return fImplicitFunctionCallName;
+ }
+
@Override
public boolean accept(ASTVisitor visitor) {
if (visitor.shouldVisitExpressions) {
@@ -69,6 +110,9 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr
}
}
+ if (visitor.shouldVisitImplicitNames && !getClosureTypeName().accept(visitor))
+ return false;
+
if (fCaptures != null) {
for (ICPPASTCapture cap : fCaptures) {
if (cap != null && !cap.accept(visitor))
@@ -77,6 +121,10 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr
}
if (fDeclarator != null && !fDeclarator.accept(visitor))
return false;
+
+ if (visitor.shouldVisitImplicitNames && !getFunctionCallOperatorName().accept(visitor))
+ return false;
+
if (fBody != null && !fBody.accept(visitor))
return false;
@@ -133,9 +181,11 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr
fDeclarator= dtor;
}
- public IType getExpressionType() {
- // mstodo type for lambda expressions
- return null;
+ public CPPClosureType getExpressionType() {
+ if (fClosureType == null)
+ fClosureType= new CPPClosureType(this);
+
+ return fClosureType;
}
public boolean isLValue() {
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
new file mode 100644
index 00000000000..b71af457f09
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java
@@ -0,0 +1,400 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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 java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.cdt.core.dom.ILinkage;
+import org.eclipse.cdt.core.dom.IName;
+import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
+import org.eclipse.cdt.core.dom.ast.EScopeKind;
+import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
+import org.eclipse.cdt.core.dom.ast.IASTExpression;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
+import org.eclipse.cdt.core.dom.ast.IASTStatement;
+import org.eclipse.cdt.core.dom.ast.IASTTypeId;
+import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
+import org.eclipse.cdt.core.dom.ast.IBinding;
+import org.eclipse.cdt.core.dom.ast.IField;
+import org.eclipse.cdt.core.dom.ast.IScope;
+import org.eclipse.cdt.core.dom.ast.IType;
+import org.eclipse.cdt.core.dom.ast.ITypedef;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression.CaptureDefault;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
+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.ICPPFunctionType;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
+import org.eclipse.cdt.core.index.IIndexBinding;
+import org.eclipse.cdt.core.index.IIndexFileSet;
+import org.eclipse.cdt.core.parser.util.CharArrayUtils;
+import org.eclipse.cdt.internal.core.dom.Linkage;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
+import org.eclipse.core.runtime.PlatformObject;
+
+/**
+ * Binding for a class type.
+ */
+public class CPPClosureType extends PlatformObject implements ICPPClassType, ICPPInternalBinding {
+ private static final CPPBasicType NO_RETURN_TYPE = new CPPBasicType(Kind.eUnspecified, 0);
+
+ private final ICPPASTLambdaExpression fLambdaExpression;
+ private ICPPMethod[] fMethods;
+ private ClassScope fScope;
+
+ public CPPClosureType(ICPPASTLambdaExpression lambdaExpr) {
+ fLambdaExpression= lambdaExpr;
+ }
+
+ private ICPPMethod[] createMethods() {
+ boolean needConversionOperator=
+ fLambdaExpression.getCaptureDefault() == CaptureDefault.UNSPECIFIED &&
+ fLambdaExpression.getCaptures().length == 0;
+
+ final ICPPClassScope scope= getCompositeScope();
+ ICPPMethod[] result= new ICPPMethod[needConversionOperator ? 6 : 5];
+
+ // Deleted default constructor: A()
+ CPPImplicitConstructor ctor= new CPPImplicitConstructor(scope, CharArrayUtils.EMPTY, ICPPParameter.EMPTY_CPPPARAMETER_ARRAY);
+ ctor.setDeleted(true);
+ result[0]= ctor;
+
+ // Copy constructor: A(const A &)
+ IType pType = new CPPReferenceType(SemanticUtil.addQualifiers(this, true, false), false);
+ ICPPParameter[] ps = new ICPPParameter[] { new CPPParameter(pType, 0) };
+ ctor = new CPPImplicitConstructor(scope, CharArrayUtils.EMPTY, ps);
+ result[1]= ctor;
+
+ // Deleted copy assignment operator: A& operator = (const A &)
+ IType refType = new CPPReferenceType(this, false);
+ ICPPFunctionType ft= CPPVisitor.createImplicitFunctionType(refType, ps, false, false);
+ ICPPMethod m = new CPPImplicitMethod(scope, OverloadableOperator.ASSIGN.toCharArray(), ft, ps);
+ result[2]= m;
+
+ // Destructor: ~A()
+ ft= CPPVisitor.createImplicitFunctionType(NO_RETURN_TYPE, ICPPParameter.EMPTY_CPPPARAMETER_ARRAY, false, false);
+ m = new CPPImplicitMethod(scope, new char[] {'~'}, ft, ICPPParameter.EMPTY_CPPPARAMETER_ARRAY);
+ result[3]= m;
+
+ // Function call operator
+ final IType returnType= getReturnType();
+ final IType[] parameterTypes= getParameterTypes();
+ ft= new CPPFunctionType(returnType, parameterTypes, isMutable(), false, false);
+
+ ICPPParameter[] params = new ICPPParameter[parameterTypes.length];
+ for (int i = 0; i < params.length; i++) {
+ params[i]= new CPPParameter(parameterTypes[i], 0);
+ }
+ m= new CPPImplicitMethod(scope, OverloadableOperator.PAREN.toCharArray(), ft, params) {
+ @Override
+ public boolean isImplicit() {return false;}
+ };
+ result[4]= m;
+
+ // Conversion operator
+ if (needConversionOperator) {
+ final CPPFunctionType conversionTarget = new CPPFunctionType(returnType, parameterTypes);
+ ft= new CPPFunctionType(conversionTarget, IType.EMPTY_TYPE_ARRAY, true, false, false);
+ m= new CPPImplicitMethod(scope, CPPASTConversionName.createName(conversionTarget, null), ft, params);
+ result[5]= m;
+ }
+ return result;
+ }
+
+ public ICPPMethod getFunctionCallOperator() {
+ return getMethods()[4];
+ }
+
+ private boolean isMutable() {
+ ICPPASTFunctionDeclarator lambdaDtor = fLambdaExpression.getDeclarator();
+ return lambdaDtor != null && lambdaDtor.isMutable();
+ }
+
+ private IType getReturnType() {
+ ICPPASTFunctionDeclarator lambdaDtor = fLambdaExpression.getDeclarator();
+ if (lambdaDtor != null) {
+ IASTTypeId trailingReturnType = lambdaDtor.getTrailingReturnType();
+ if (trailingReturnType != null) {
+ IType type= CPPVisitor.createType(trailingReturnType);
+ if (type != null)
+ return type;
+ return CPPSemantics.VOID_TYPE;
+ }
+ }
+ IASTCompoundStatement body = fLambdaExpression.getBody();
+ if (body != null) {
+ IASTStatement[] stmts = body.getStatements();
+ if (stmts.length > 0) {
+ // Gnu extension allows to deduce return type in complex compound statements
+ IASTStatement stmt= stmts[stmts.length-1];
+ if (stmt instanceof IASTReturnStatement) {
+ IASTReturnStatement rtstmt= (IASTReturnStatement) stmt;
+ IASTExpression expr= rtstmt.getReturnValue();
+ if (expr != null) {
+ IType type= expr.getExpressionType();
+ type= Conversions.lvalue_to_rvalue(type);
+ type= Conversions.array_to_pointer(type);
+ type= Conversions.function_to_pointer(type);
+ if (type != null) {
+ return type;
+ }
+ }
+ }
+ }
+ }
+ return CPPSemantics.VOID_TYPE;
+ }
+
+ private IType[] getParameterTypes() {
+ ICPPASTFunctionDeclarator lambdaDtor = fLambdaExpression.getDeclarator();
+ if (lambdaDtor != null) {
+ return CPPVisitor.createParameterTypes(lambdaDtor);
+ }
+ return IType.EMPTY_TYPE_ARRAY;
+ }
+
+ public final String getName() {
+ return ""; //$NON-NLS-1$
+ }
+
+ public char[] getNameCharArray() {
+ return CharArrayUtils.EMPTY;
+ }
+
+ public IScope getScope() {
+ return CPPVisitor.getContainingScope(fLambdaExpression);
+ }
+
+ public ICPPClassScope getCompositeScope() {
+ if (fScope == null) {
+ fScope= new ClassScope();
+ }
+ return fScope;
+ }
+
+ public int getKey() {
+ return k_class;
+ }
+
+ public String[] getQualifiedName() {
+ return CPPVisitor.getQualifiedName(this);
+ }
+
+ public char[][] getQualifiedNameCharArray() {
+ return CPPVisitor.getQualifiedNameCharArray(this);
+ }
+
+ public boolean isGloballyQualified() {
+ return getOwner() == null;
+ }
+
+ public ILinkage getLinkage() {
+ return Linkage.CPP_LINKAGE;
+ }
+
+ public boolean isSameType(IType type) {
+ if (type == this)
+ return true;
+ if (type instanceof ITypedef || type instanceof IIndexBinding)
+ return type.isSameType(this);
+ return false;
+ }
+
+ public ICPPBase[] getBases() {
+ return ICPPBase.EMPTY_BASE_ARRAY;
+ }
+
+ public ICPPField[] getFields() {
+ return ICPPField.EMPTY_CPPFIELD_ARRAY;
+ }
+
+ public ICPPField[] getDeclaredFields() {
+ return ICPPField.EMPTY_CPPFIELD_ARRAY;
+ }
+
+ public ICPPMethod[] getMethods() {
+ if (fMethods == null) {
+ fMethods= createMethods();
+ }
+ return fMethods;
+ }
+
+ public ICPPMethod[] getAllDeclaredMethods() {
+ return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
+ }
+
+ public ICPPMethod[] getDeclaredMethods() {
+ return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
+ }
+
+ public ICPPConstructor[] getConstructors() {
+ ICPPMethod[] methods= getMethods();
+ int i= 0;
+ for (; i < methods.length; i++) {
+ if (!(methods[i] instanceof ICPPConstructor)) {
+ break;
+ }
+ }
+ ICPPConstructor[] result= new ICPPConstructor[i];
+ System.arraycopy(methods, 0, result, 0, i);
+ return result;
+ }
+
+ public IBinding[] getFriends() {
+ return IBinding.EMPTY_BINDING_ARRAY;
+ }
+
+ public ICPPClassType[] getNestedClasses() {
+ return ICPPClassType.EMPTY_CLASS_ARRAY;
+ }
+
+ public IField findField(String name) {
+ return null;
+ }
+
+ @Override
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ }
+ return null;
+ }
+
+ /**
+ * For debugging purposes, only.
+ */
+ @Override
+ public String toString() {
+ char[] name= ASTTypeUtil.createNameForAnonymous(this);
+ if (name != null)
+ return new String(name);
+ return null;
+ }
+
+ public IBinding getOwner() {
+ return CPPVisitor.findDeclarationOwner(fLambdaExpression, true);
+ }
+
+ public boolean isAnonymous() {
+ return false;
+ }
+
+ public IASTNode getDefinition() {
+ return fLambdaExpression;
+ }
+
+ public IASTNode[] getDeclarations() {
+ return IASTNode.EMPTY_NODE_ARRAY;
+ }
+
+ public void addDefinition(IASTNode node) {
+ }
+
+ public void addDeclaration(IASTNode node) {
+ }
+
+
+ private final class ClassScope implements ICPPClassScope {
+ public EScopeKind getKind() {
+ return EScopeKind.eClassType;
+ }
+
+ public IName getScopeName() {
+ return null;
+ }
+
+ public IScope getParent() {
+ return getScope();
+ }
+
+ private IBinding getBinding(char[] name) {
+ for (ICPPMethod m : getMethods()) {
+ if (!(m instanceof ICPPConstructor) && CharArrayUtils.equals(name, m.getNameCharArray())) {
+ return m;
+ }
+ }
+ return null;
+ }
+
+ private IBinding[] getBindings(char[] name) {
+ IBinding m= getBinding(name);
+ if (m != null) {
+ return new IBinding[] {m};
+ }
+ return IBinding.EMPTY_BINDING_ARRAY;
+ }
+
+ private IBinding[] getPrefixBindings(char[] name) {
+ List result= new ArrayList();
+ for (ICPPMethod m : getMethods()) {
+ if (!(m instanceof ICPPConstructor)) {
+ if (CharArrayUtils.equals(name, 0, name.length, m.getNameCharArray(), true)) {
+ result.add(m);
+ }
+ }
+ }
+ return result.toArray(new IBinding[result.size()]);
+ }
+
+ public IBinding[] find(String name) {
+ return getBindings(name.toCharArray());
+ }
+
+ public IBinding getBinding(IASTName name, boolean resolve) {
+ if (name instanceof ICPPASTTemplateId)
+ return null;
+ return getBinding(name.getSimpleID());
+ }
+
+ public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet acceptLocalBindings) {
+ return getBinding(name, resolve);
+ }
+
+ public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup) {
+ if (name instanceof ICPPASTTemplateId)
+ return IBinding.EMPTY_BINDING_ARRAY;
+
+ if (prefixLookup)
+ return getPrefixBindings(name.getSimpleID());
+ return getBindings(name.getSimpleID());
+ }
+
+ public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup,
+ IIndexFileSet acceptLocalBindings) {
+ return getBindings(name, resolve, prefixLookup);
+ }
+
+ public ICPPClassType getClassType() {
+ return CPPClosureType.this;
+ }
+
+ public ICPPMethod[] getImplicitMethods() {
+ return getMethods();
+ }
+
+ public ICPPConstructor[] getConstructors() {
+ return CPPClosureType.this.getConstructors();
+ }
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitFunction.java
index 09324a31b5f..5e50718b1fd 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitFunction.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitFunction.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2009 IBM Corporation and others.
+ * Copyright (c) 2005, 2010 IBM Corporation 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
@@ -27,8 +27,9 @@ public class CPPImplicitFunction extends CPPFunction {
private ICPPParameter[] parms=null;
private IScope scope=null;
private ICPPFunctionType functionType=null;
- private boolean takesVarArgs=false;
- private char[] name=null;
+ private final boolean takesVarArgs;
+ private boolean isDeleted;
+ private final char[] name;
public CPPImplicitFunction(char[] name, IScope scope, ICPPFunctionType type, ICPPParameter[] parms, boolean takesVarArgs) {
super( null );
@@ -82,8 +83,17 @@ public class CPPImplicitFunction extends CPPFunction {
return takesVarArgs;
}
+ @Override
+ public boolean isDeleted() {
+ return isDeleted;
+ }
+
@Override
public IBinding getOwner() {
return null;
}
+
+ public void setDeleted(boolean val) {
+ isDeleted= val;
+ }
}
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
new file mode 100644
index 00000000000..3603c92f523
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPLambdaExpressionParameter.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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 = null;
+ private IASTName fDeclaration = null;
+
+ public CPPLambdaExpressionParameter(IASTName name) {
+ fDeclaration = name;
+ }
+
+ public boolean isParameterPack() {
+ return getType() instanceof ICPPParameterPackType;
+ }
+
+ public String getName() {
+ return new String(getNameCharArray());
+ }
+
+ public char[] getNameCharArray() {
+ return fDeclaration.getSimpleID();
+ }
+
+ public IScope getScope() {
+ return CPPVisitor.getContainingScope(fDeclaration);
+ }
+
+ public IType getType() {
+ if (fType == null) {
+ IASTNode parent= fDeclaration.getParent();
+ while (parent != null) {
+ if (parent instanceof ICPPASTParameterDeclaration) {
+ fType= CPPVisitor.createParameterType((ICPPASTParameterDeclaration) parent, false);
+ break;
+ }
+ parent= parent.getParent();
+ }
+ }
+ return fType;
+ }
+
+ public boolean isStatic() {
+ return false;
+ }
+ public String[] getQualifiedName() {
+ return new String[] { getName() };
+ }
+ public char[][] getQualifiedNameCharArray() {
+ return new char[][] { getNameCharArray() };
+ }
+ public boolean isGloballyQualified() {
+ return false;
+ }
+
+ public boolean isExtern() {
+ //7.1.1-5 extern can not be used in the declaration of a parameter
+ return false;
+ }
+
+ public boolean isMutable() {
+ //7.1.1-8 mutable can only apply to class members
+ return false;
+ }
+
+ public boolean isAuto() {
+ return hasStorageClass(IASTDeclSpecifier.sc_auto);
+ }
+
+ 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;
+ }
+
+ public boolean hasDefaultValue() {
+ return false;
+ }
+
+ public ILinkage getLinkage() {
+ return Linkage.CPP_LINKAGE;
+ }
+
+ public boolean isExternC() {
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ String name = getName();
+ return name.length() != 0 ? name : ""; //$NON-NLS-1$
+ }
+
+ 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;
+ }
+
+ public IValue getInitialValue() {
+ return null;
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
index 6c7e64ed2c8..adfe0de5c70 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
@@ -96,6 +96,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
@@ -1322,7 +1323,12 @@ public class CPPSemantics {
if (p instanceof IASTFunctionDefinition) {
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) ((IASTFunctionDefinition) p).getDeclarator();
nodes = dtor.getParameters();
- }
+ } else if (p instanceof ICPPASTLambdaExpression) {
+ ICPPASTFunctionDeclarator dtor = ((ICPPASTLambdaExpression) p).getDeclarator();
+ if (dtor != null) {
+ nodes = dtor.getParameters();
+ }
+ }
if (p instanceof ICPPASTCatchHandler) {
parent = p;
} else if (nodes == null || nodes.length == 0) {
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 cda9d215924..18562160336 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
@@ -15,11 +15,15 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
+import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
+import org.eclipse.cdt.core.dom.ast.ASTGenericVisitor;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
+import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.EScopeKind;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
@@ -80,7 +84,6 @@ import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IVariable;
-import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
@@ -97,6 +100,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
@@ -161,6 +165,7 @@ 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;
@@ -603,16 +608,24 @@ public class CPPVisitor extends ASTQueries {
if (parent instanceof IASTStandardFunctionDeclarator) {
IASTStandardFunctionDeclarator fdtor = (IASTStandardFunctionDeclarator) param.getParent();
// Create parameter bindings only if the declarator declares a function
- if (!(findOutermostDeclarator(fdtor).getParent() instanceof IASTDeclaration) ||
- findTypeRelevantDeclarator(fdtor) != fdtor)
+ if (findTypeRelevantDeclarator(fdtor) != fdtor)
return null;
- IASTParameterDeclaration[] params = fdtor.getParameters();
- int i= 0;
- for (; i < params.length; i++) {
- if (params[i] == param)
- break;
+
+ final IASTNode dtorParent= findOutermostDeclarator(fdtor).getParent();
+ if (dtorParent instanceof ICPPASTLambdaExpression) {
+ return new CPPLambdaExpressionParameter(name);
}
- return new CPPParameter(name, i);
+
+ 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);
+ }
+ return null;
} else if (parent instanceof ICPPASTTemplateDeclaration) {
return CPPTemplates.createBinding(param);
}
@@ -894,14 +907,21 @@ public class CPPVisitor extends ASTQueries {
while (parent.getParent() instanceof IASTDeclarator)
parent = parent.getParent();
ASTNodeProperty prop = parent.getPropertyInParent();
- if (prop == IASTSimpleDeclaration.DECLARATOR)
+ if (prop == IASTSimpleDeclaration.DECLARATOR) {
return dtor.getFunctionScope();
- else if (prop == IASTFunctionDefinition.DECLARATOR) {
+ }
+ if (prop == IASTFunctionDefinition.DECLARATOR) {
final IASTCompoundStatement body = (IASTCompoundStatement) ((IASTFunctionDefinition) parent.getParent()).getBody();
if (body != null)
return body.getScope();
return dtor.getFunctionScope();
- }
+ }
+ if (prop == ICPPASTLambdaExpression.DECLARATOR) {
+ final IASTCompoundStatement body = ((ICPPASTLambdaExpression) parent.getParent()).getBody();
+ if (body != null)
+ return body.getScope();
+ return dtor.getFunctionScope();
+ }
}
} else if (parent instanceof ICPPASTTemplateDeclaration) {
return CPPTemplates.getContainingScope(node);
@@ -1222,95 +1242,37 @@ public class CPPVisitor extends ASTQueries {
return null;
}
- public static class CollectProblemsAction extends CPPASTVisitor {
- {
- shouldVisitDeclarations = true;
- shouldVisitExpressions = true;
- shouldVisitStatements = true;
- shouldVisitTypeIds = true;
- }
+ private static class CollectProblemsAction extends ASTGenericVisitor {
+ private List fProblems = null;
- private static final int DEFAULT_CHILDREN_LIST_SIZE = 8;
- private IASTProblem[] problems = null;
- int numFound = 0;
+ CollectProblemsAction() {
+ super(true);
+ }
- public CollectProblemsAction() {
- problems = new IASTProblem[DEFAULT_CHILDREN_LIST_SIZE];
- }
-
private void addProblem(IASTProblem problem) {
- if (problems.length == numFound) { // if the found array is full, then double the array
- IASTProblem[] old = problems;
- problems = new IASTProblem[old.length * 2];
- for (int j = 0; j < old.length; ++j)
- problems[j] = old[j];
- }
- problems[numFound++] = problem;
- }
-
- private IASTProblem[] removeNullFromProblems() {
- if (problems[problems.length-1] != null) { // if the last element in the list is not null then return the list
- return problems;
- } else if (problems[0] == null) { // if the first element in the list is null, then return empty list
- return new IASTProblem[0];
+ if (fProblems == null) {
+ fProblems= new ArrayList();
}
-
- IASTProblem[] results = new IASTProblem[numFound];
- for (int i=0; i OPERATOR_CHARS.length + 1 &&
- CharArrayUtils.equals(name, 0, OPERATOR_CHARS.length, OPERATOR_CHARS)) {
- if (name[OPERATOR_CHARS.length] == ' ') {
- result= !cas.containsKey(name, OPERATOR_CHARS.length + 1, name.length - (OPERATOR_CHARS.length+1));
- }
- }
+ final char[] name= method.getNameCharArray();
+ if (name.length > OPERATOR_CHARS.length + 1 && name[OPERATOR_CHARS.length] == ' ' &&
+ CharArrayUtils.equals(name, 0, OPERATOR_CHARS.length, OPERATOR_CHARS)) {
+ return !cas.containsKey(name, OPERATOR_CHARS.length + 1, name.length - (OPERATOR_CHARS.length+1));
}
- return result;
+ return false;
}
/**
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
index 5473ead91b2..6cd2a680165 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
@@ -71,6 +71,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArrayType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClosureType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameterPackType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
@@ -273,6 +274,9 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
pdomBinding = createBinding(parent, binding, fileLocalRec[0]);
if (pdomBinding != null) {
getPDOM().putCachedResult(inputBinding, pdomBinding);
+ if (inputBinding instanceof CPPClosureType) {
+ addImplicitMethods(pdomBinding, (ICPPClassType) binding);
+ }
}
} catch (DOMException e) {
throw new CoreException(Util.createStatus(e));
@@ -395,7 +399,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
if (parent2 != null) {
parent2.addChild(pdomBinding);
}
- if (parent2 != this) {
+ if (parent != this && parent2 != this) {
insertIntoNestedBindingsIndex(pdomBinding);
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerASTVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerASTVisitor.java
index 5b2b6393340..980954445e2 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerASTVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerASTVisitor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2009 Wind River Systems, Inc. and others.
+ * Copyright (c) 2006, 2010 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
@@ -14,9 +14,11 @@ import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
+import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
@@ -25,7 +27,10 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
@@ -51,6 +56,7 @@ abstract public class IndexerASTVisitor extends ASTVisitor {
shouldVisitInitializers= true;
shouldVisitDeclSpecifiers= true;
shouldVisitProblems= true;
+ shouldVisitExpressions= true;
}
public List getProblems() {
@@ -112,13 +118,11 @@ abstract public class IndexerASTVisitor extends ASTVisitor {
IASTName name= getLastInQualified(nestedDeclarator.getName());
visit(name, fDefinitionName);
push(name, decl);
- }
- else if (decl instanceof IASTSimpleDeclaration) {
+ } else if (decl instanceof IASTSimpleDeclaration) {
IASTSimpleDeclaration sdecl= (IASTSimpleDeclaration) decl;
if (sdecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef) {
IASTDeclarator[] declarators= sdecl.getDeclarators();
- for (int i = 0; i < declarators.length; i++) {
- IASTDeclarator declarator = declarators[i];
+ for (IASTDeclarator declarator : declarators) {
if (declarator.getPointerOperators().length == 0 &&
declarator.getNestedDeclarator() == null) {
IASTName name= getLastInQualified(declarator.getName());
@@ -127,7 +131,7 @@ abstract public class IndexerASTVisitor extends ASTVisitor {
}
}
}
- }
+ }
return PROCESS_CONTINUE;
}
@@ -185,4 +189,40 @@ abstract public class IndexerASTVisitor extends ASTVisitor {
pop(initializer);
return PROCESS_CONTINUE;
}
+
+ // Lambda expressions
+ @Override
+ public int visit(IASTExpression expr) {
+ if (expr instanceof ICPPASTLambdaExpression) {
+ return visit((ICPPASTLambdaExpression) expr);
+ }
+ return PROCESS_CONTINUE;
+ }
+
+ private int visit(final ICPPASTLambdaExpression lambdaExpr) {
+ // Captures
+ for (ICPPASTCapture cap : lambdaExpr.getCaptures()) {
+ if (!cap.accept(this))
+ return PROCESS_ABORT;
+ }
+ // Definition of closure type
+ final IASTName closureName = lambdaExpr.getClosureTypeName();
+ visit(closureName, fDefinitionName);
+
+ // Definition of call operator
+ IASTName callOp= lambdaExpr.getFunctionCallOperatorName();
+ visit(callOp, closureName);
+ push(callOp, lambdaExpr);
+
+ ICPPASTFunctionDeclarator dtor = lambdaExpr.getDeclarator();
+ if (dtor != null && !dtor.accept(this))
+ return PROCESS_ABORT;
+
+ IASTCompoundStatement body = lambdaExpr.getBody();
+ if (body != null && !body.accept(this))
+ return PROCESS_ABORT;
+
+ pop(lambdaExpr);
+ return PROCESS_SKIP;
+ }
}
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CppCallHierarchyTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CppCallHierarchyTest.java
index 96a143e7808..284a6b0c698 100644
--- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CppCallHierarchyTest.java
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/CppCallHierarchyTest.java
@@ -465,4 +465,41 @@ public class CppCallHierarchyTest extends CallHierarchyBaseTest {
checkTreeNode(tree, 0, 0, "testchar()");
checkTreeNode(tree, 0, 1, null);
}
+
+ // void a() {}
+ // auto b= [] {a();};
+ // void c() {
+ // b();
+ // }
+ // void d() {
+ // []{c();}();
+ // }
+ public void testClosures_316307() throws Exception {
+ StringBuffer[] content= getContentsForTest(1);
+ String source = content[0].toString();
+ IFile file= createFile(getProject(), "testClosures.cpp", source);
+ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ waitForIndexer(fIndex, file, CallHierarchyBaseTest.INDEXER_WAIT_TIME);
+ CCorePlugin.getIndexManager().joinIndexer(INDEXER_WAIT_TIME, npm());
+
+ CEditor editor= openEditor(file);
+ int pos= source.indexOf("a(");
+ editor.selectAndReveal(pos, 1);
+ openCallHierarchy(editor, true);
+ Tree tree = getCHTreeViewer().getTree();
+
+ checkTreeNode(tree, 0, "a()");
+ TreeItem node = checkTreeNode(tree, 0, 0, "(anonymous)::operator ()()");
+ expandTreeItem(node);
+ node= checkTreeNode(node, 0, "c()");
+ checkTreeNode(node, 1, null);
+ expandTreeItem(node);
+ node= checkTreeNode(node, 0, "(anonymous)::operator ()()");
+ checkTreeNode(node, 1, null);
+ expandTreeItem(node);
+ node= checkTreeNode(node, 0, "d()");
+ checkTreeNode(node, 1, null);
+ expandTreeItem(node);
+ checkTreeNode(node, 0, null);
+ }
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java
index b37af1a34d2..7b1aec94966 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java
@@ -405,6 +405,9 @@ public class SemanticHighlightings {
@Override
public boolean consumes(SemanticToken token) {
IASTNode node= token.getNode();
+ if (node instanceof IASTImplicitName)
+ return false;
+
if (node instanceof IASTName) {
IASTName name= (IASTName)node;
if (!name.isReference()) {
@@ -659,6 +662,9 @@ public class SemanticHighlightings {
@Override
public boolean consumes(SemanticToken token) {
IASTNode node= token.getNode();
+ if (node instanceof IASTImplicitName)
+ return false;
+
if (node instanceof IASTName) {
IASTName name= (IASTName)node;
if (name.isDeclaration()) {
@@ -1989,17 +1995,21 @@ public class SemanticHighlightings {
public boolean consumes(SemanticToken token) {
IASTNode node = token.getNode();
// so far we only have implicit names for overloaded operators and destructors, so this works
- if(node instanceof IASTImplicitName) {
+ if (node instanceof IASTImplicitName) {
IASTImplicitName name = (IASTImplicitName) node;
- IBinding binding = name.resolveBinding();
- if(binding instanceof ICPPMethod && !(binding instanceof IProblemBinding) && ((ICPPMethod)binding).isImplicit()) {
- return false;
+ if (name.isReference() && name.isOperator()) {
+ IBinding binding = name.resolveBinding();
+ if (binding instanceof ICPPMethod && !(binding instanceof IProblemBinding)
+ && ((ICPPMethod) binding).isImplicit()) {
+ return false;
+ }
+ char[] chars = name.toCharArray();
+ if (chars[0] == '~' || OverloadableOperator.isNew(chars)
+ || OverloadableOperator.isDelete(chars)) {
+ return false;
+ }
+ return true;
}
- char[] chars = name.toCharArray();
- if(chars[0] == '~' || OverloadableOperator.isNew(chars) || OverloadableOperator.isDelete(chars)) {
- return false;
- }
- return true;
}
return false;
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java
index 12e793bfda3..191090d73cd 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java
@@ -417,6 +417,9 @@ public class IndexUI {
if (ast != null) {
final IASTNodeSelector nodeSelector = ast.getNodeSelector(null);
IASTName name= nodeSelector.findEnclosingName(offset, length);
+ if (name == null) {
+ name= nodeSelector.findImplicitName(offset, length);
+ }
if (name != null && name.getParent() instanceof IASTPreprocessorMacroExpansion) {
IASTFileLocation floc= name.getParent().getFileLocation();
IASTNode node= nodeSelector.findEnclosingNodeInExpansion(floc.getNodeOffset(), floc.getNodeLength());