blob: 584d70e8e6bad3ee8c28fc2b361078472908edd9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2015 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* John Camelon (IBM) - Initial API and implementation
* Bryan Wilkinson (QNX)
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICPPASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalID;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.FunctionSetType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
public class CPPASTIdExpression extends ASTNode
implements IASTIdExpression, ICPPASTExpression, ICPPASTCompletionContext {
private IASTName fName;
private ICPPEvaluation fEvaluation;
private IASTImplicitDestructorName[] fImplicitDestructorNames;
public CPPASTIdExpression() {
}
public CPPASTIdExpression(IASTName name) {
setName(name);
}
@Override
public CPPASTIdExpression copy() {
return copy(CopyStyle.withoutLocations);
}
@Override
public CPPASTIdExpression copy(CopyStyle style) {
CPPASTIdExpression copy = new CPPASTIdExpression(fName == null ? null : fName.copy(style));
return copy(copy, style);
}
@Override
public IASTName getName() {
return fName;
}
@Override
public void setName(IASTName name) {
assertNotFrozen();
this.fName = name;
if (name != null) {
name.setParent(this);
name.setPropertyInParent(ID_NAME);
}
}
@Override
public IASTImplicitDestructorName[] getImplicitDestructorNames() {
if (fImplicitDestructorNames == null) {
fImplicitDestructorNames = DestructorCallCollector.getTemporariesDestructorCalls(this);
}
return fImplicitDestructorNames;
}
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitExpressions) {
switch (action.visit(this)) {
case ASTVisitor.PROCESS_ABORT: return false;
case ASTVisitor.PROCESS_SKIP: return true;
default: break;
}
}
if (fName != null && !fName.accept(action)) return false;
if (action.shouldVisitImplicitDestructorNames && !acceptByNodes(getImplicitDestructorNames(), action))
return false;
if (action.shouldVisitExpressions) {
switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT: return false;
case ASTVisitor.PROCESS_SKIP: return true;
default: break;
}
}
return true;
}
@Override
public int getRoleForName(IASTName n) {
if (fName == n)
return r_reference;
return r_unclear;
}
@Override
public IBinding[] findBindings(IASTName n, boolean isPrefix, String[] namespaces) {
return CPPSemantics.findBindingsForContentAssist(n, isPrefix, namespaces);
}
@Override
public String toString() {
return fName != null ? fName.toString() : "<unnamed>"; //$NON-NLS-1$
}
@Override
public IBinding[] findBindings(IASTName n, boolean isPrefix) {
return findBindings(n, isPrefix, null);
}
@Override
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null) {
fEvaluation= EvalID.create(this);
}
return fEvaluation;
}
@Override
public IType getExpressionType() {
CPPSemantics.pushLookupPoint(this);
try {
IType type= getEvaluation().getType();
if (type instanceof FunctionSetType) {
IBinding binding= fName.resolveBinding();
if (binding instanceof IFunction) {
return SemanticUtil.mapToAST(((IFunction) binding).getType());
}
return ProblemType.UNKNOWN_FOR_EXPRESSION;
}
return type;
} finally {
CPPSemantics.popLookupPoint();
}
}
@Override
public boolean isLValue() {
return getValueCategory() == LVALUE;
}
@Override
public ValueCategory getValueCategory() {
return CPPEvaluation.getValueCategory(this);
}
}