blob: c860b1807cae5c497914014ba96e53663195cdb7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2015 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 - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
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;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
/**
* Implementation for lambda expressions.
*/
public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpression {
private static final ICPPASTCapture[] NO_CAPTURES = {};
private CaptureDefault fCaptureDefault;
private ICPPASTCapture[] fCaptures;
private ICPPASTFunctionDeclarator fDeclarator;
private IASTCompoundStatement fBody;
private IASTImplicitName fClosureTypeName;
private IASTImplicitName fImplicitFunctionCallName;
private IASTImplicitName fImplicitConversionOperatorName;
private ICPPEvaluation fEvaluation;
public CPPASTLambdaExpression() {
fCaptureDefault= CaptureDefault.UNSPECIFIED;
}
@Override
public CPPASTLambdaExpression copy() {
return copy(CopyStyle.withoutLocations);
}
@Override
public CPPASTLambdaExpression copy(CopyStyle style) {
CPPASTLambdaExpression copy = new CPPASTLambdaExpression();
copy.fCaptureDefault = fCaptureDefault;
if (fCaptures != null) {
for (ICPPASTCapture capture : fCaptures) {
if (capture != null) {
copy.addCapture(capture.copy(style));
}
}
}
if (fDeclarator != null) {
copy.setDeclarator(fDeclarator.copy(style));
}
if (fBody != null) {
copy.setBody(fBody.copy(style));
}
return copy(copy, style);
}
@Override
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;
}
@Override
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;
}
private IASTImplicitName getConversionOperatorName() {
if (fImplicitConversionOperatorName == null) {
final CPPClosureType closureType = getExpressionType();
ICPPFunction conversionOperator = closureType.getConversionOperator();
if (conversionOperator != null) {
CPPASTImplicitName name = new CPPASTImplicitName(closureType.getNameCharArray(), this);
name.setBinding(conversionOperator);
name.setIsDefinition(true);
if (fBody instanceof ASTNode) {
name.setOffsetAndLength(((ASTNode) fBody).getOffset(), 1);
}
fImplicitConversionOperatorName = name;
}
}
return fImplicitConversionOperatorName;
}
@Override
public IASTImplicitName[] getImplicitNames() {
IASTImplicitName conversionOperatorName = getConversionOperatorName();
if (conversionOperatorName == null) {
return new IASTImplicitName[] { getFunctionCallOperatorName() };
}
return new IASTImplicitName[] { getFunctionCallOperatorName(), getConversionOperatorName() };
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
return IASTImplicitDestructorName.EMPTY_NAME_ARRAY; // Lambda expression is never a full-expression.
}
@Override
public boolean accept(ASTVisitor visitor) {
if (visitor.shouldVisitExpressions) {
switch (visitor.visit(this)) {
case ASTVisitor.PROCESS_ABORT: return false;
case ASTVisitor.PROCESS_SKIP: return true;
default: break;
}
}
if (visitor.shouldVisitImplicitNames && !getClosureTypeName().accept(visitor))
return false;
if (fCaptures != null) {
for (ICPPASTCapture cap : fCaptures) {
if (cap != null && !cap.accept(visitor))
return false;
}
}
if (fDeclarator != null && !fDeclarator.accept(visitor))
return false;
if (visitor.shouldVisitImplicitNames) {
for (IASTImplicitName name : getImplicitNames()) {
if (!name.accept(visitor)) {
return false;
}
}
}
if (fBody != null && !fBody.accept(visitor))
return false;
if (visitor.shouldVisitExpressions && visitor.leave(this) == ASTVisitor.PROCESS_ABORT)
return false;
return true;
}
@Override
public IASTCompoundStatement getBody() {
return fBody;
}
@Override
public CaptureDefault getCaptureDefault() {
return fCaptureDefault;
}
@Override
public ICPPASTCapture[] getCaptures() {
if (fCaptures == null)
return NO_CAPTURES;
return fCaptures= ArrayUtil.trim(fCaptures);
}
@Override
public ICPPASTFunctionDeclarator getDeclarator() {
return fDeclarator;
}
@Override
public void addCapture(ICPPASTCapture capture) {
assertNotFrozen();
capture.setParent(this);
capture.setPropertyInParent(CAPTURE);
if (fCaptures == null) {
fCaptures= new ICPPASTCapture[] {capture, null};
} else {
fCaptures= ArrayUtil.append(fCaptures, capture);
}
}
@Override
public void setBody(IASTCompoundStatement body) {
assertNotFrozen();
body.setParent(this);
body.setPropertyInParent(BODY);
fBody= body;
}
@Override
public void setCaptureDefault(CaptureDefault value) {
fCaptureDefault= value;
}
@Override
public void setDeclarator(ICPPASTFunctionDeclarator dtor) {
assertNotFrozen();
dtor.setParent(this);
dtor.setPropertyInParent(DECLARATOR);
fDeclarator= dtor;
}
@Override
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null) {
fEvaluation= new EvalFixed(new CPPClosureType(this), PRVALUE, IntegralValue.UNKNOWN);
}
return fEvaluation;
}
@Override
public CPPClosureType getExpressionType() {
return (CPPClosureType) CPPEvaluation.getType(this);
}
@Override
public boolean isLValue() {
return false;
}
@Override
public ValueCategory getValueCategory() {
return ValueCategory.PRVALUE;
}
}