1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 324096: [C++0x] Value categories.

This commit is contained in:
Markus Schorn 2010-09-06 13:52:47 +00:00
parent 55296a05be
commit 703afbd706
56 changed files with 803 additions and 394 deletions

View file

@ -7313,7 +7313,8 @@ public class AST2CPPTests extends AST2BaseTest {
IASTExpressionStatement stmt= getStatement(test, 1); IASTExpressionStatement stmt= getStatement(test, 1);
long now= System.currentTimeMillis(); long now= System.currentTimeMillis();
IType t= stmt.getExpression().getExpressionType(); IType t= stmt.getExpression().getExpressionType();
assertInstance(t, ICPPReferenceType.class); assertInstance(t, ICPPClassType.class);
assertTrue(stmt.getExpression().isLValue());
final long time = System.currentTimeMillis() - now; final long time = System.currentTimeMillis() - now;
assertTrue("Lasted " + time + "ms", time < 5000); assertTrue("Lasted " + time + "ms", time < 5000);
} }

View file

@ -11,6 +11,7 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast; package org.eclipse.cdt.core.dom.ast;
/** /**
* This is the root class of expressions. * This is the root class of expressions.
* *
@ -18,6 +19,37 @@ package org.eclipse.cdt.core.dom.ast;
* @noimplement This interface is not intended to be implemented by clients. * @noimplement This interface is not intended to be implemented by clients.
*/ */
public interface IASTExpression extends IASTInitializerClause { public interface IASTExpression extends IASTInitializerClause {
/**
* @since 5.3
*/
public enum ValueCategory {
/**
* Traditional lvalue
*/
LVALUE,
/**
* Expiring value as introduced by c++ 0x.
*/
XVALUE,
/**
* Pure rvalue.
*/
PRVALUE;
/**
* Both prvalues and xvalues are rvalues.
*/
public boolean isRValue() {
return this != LVALUE;
}
/**
* A generalized lvalue is either an lvalue or an xvalue.
*/
public boolean isGLValue() {
return this != PRVALUE;
}
}
/** /**
* Empty expression array. * Empty expression array.
*/ */
@ -32,6 +64,12 @@ public interface IASTExpression extends IASTInitializerClause {
*/ */
public boolean isLValue(); public boolean isLValue();
/**
* Returns the value category of this expression.
* @since 5.3
*/
ValueCategory getValueCategory();
/** /**
* @since 5.1 * @since 5.1
*/ */

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others. * Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -36,8 +36,9 @@ public interface ICPPASTLiteralExpression extends IASTLiteralExpression {
public static final int lk_false = IASTLiteralExpression.lk_false; public static final int lk_false = IASTLiteralExpression.lk_false;
/** /**
* <code>lk_last</code> is maintained for future subinterfaces. * @deprecated All constants must be defined in {@link IASTLiteralExpression}.
*/ */
@Deprecated
public static final int lk_last = lk_false; public static final int lk_last = lk_false;

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -19,7 +19,9 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
* *
* @noextend This interface is not intended to be extended by clients. * @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients. * @noimplement This interface is not intended to be implemented by clients.
* @deprecated Use {@link IASTTypeIdExpression}, instead.
*/ */
@Deprecated
public interface IGNUASTTypeIdExpression extends IASTTypeIdExpression { public interface IGNUASTTypeIdExpression extends IASTTypeIdExpression {
/** /**

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008, 2009 Wind River Systems, Inc. and others. * Copyright (c) 2008, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -19,8 +19,6 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.core.runtime.Assert;
/** /**
* Handles the ambiguity between a binary- and a cast-expression. (type)+var versus (var)+var. * Handles the ambiguity between a binary- and a cast-expression. (type)+var versus (var)+var.
@ -46,14 +44,10 @@ public abstract class ASTAmbiguousBinaryVsCastExpression extends ASTAmbiguousNod
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public void addExpression(IASTExpression e) { public final void addExpression(IASTExpression e) {
Assert.isLegal(false); throw new UnsupportedOperationException();
} }
public IType getExpressionType() {
return null;
}
@Override @Override
public final IASTNode[] getNodes() { public final IASTNode[] getNodes() {
return getExpressions(); return getExpressions();

View file

@ -23,8 +23,6 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.core.runtime.Assert;
/** /**
* Handles the ambiguity between cast and function-call expressions: (type)(expr) versus (function)(expr); * Handles the ambiguity between cast and function-call expressions: (type)(expr) versus (function)(expr);
@ -56,13 +54,9 @@ public abstract class ASTAmbiguousCastVsFunctionCallExpression extends ASTAmbigu
} }
public void addExpression(IASTExpression e) { public void addExpression(IASTExpression e) {
Assert.isLegal(false); throw new UnsupportedOperationException();
} }
public IType getExpressionType() {
return fCastExpression.getExpressionType();
}
public IASTExpression[] getExpressions() { public IASTExpression[] getExpressions() {
return new IASTExpression[] {fCastExpression, fFunctionCallExpression}; return new IASTExpression[] {fCastExpression, fFunctionCallExpression};
} }

View file

@ -13,11 +13,13 @@ package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
/** /**
@ -139,7 +141,13 @@ public abstract class ASTAmbiguousNode extends ASTNode {
return bestAlternative; return bestAlternative;
} }
public boolean isLValue() { public final IType getExpressionType() {
return false; throw new UnsupportedOperationException();
}
public final ValueCategory getValueCategory() {
throw new UnsupportedOperationException();
}
public final boolean isLValue() {
throw new UnsupportedOperationException();
} }
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -87,7 +87,11 @@ public abstract class ASTTypeIdInitializerExpression extends ASTNode implements
return true; return true;
} }
public boolean isLValue() { public final boolean isLValue() {
return false; return false;
} }
public final ValueCategory getValueCategory() {
return ValueCategory.PRVALUE;
}
} }

View file

@ -1174,6 +1174,10 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
public boolean isLValue() { public boolean isLValue() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public ValueCategory getValueCategory() {
throw new UnsupportedOperationException();
}
} }
protected final IASTExpression castExpression(CastExprCtx ctx) throws EndOfFileException, BacktrackException { protected final IASTExpression castExpression(CastExprCtx ctx) throws EndOfFileException, BacktrackException {

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others. * Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -13,7 +13,6 @@ package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression;
@ -48,10 +47,6 @@ public class CASTAmbiguousExpression extends ASTAmbiguousNode implements IASTAmb
return getExpressions(); return getExpressions();
} }
public IType getExpressionType() {
return null;
}
public IASTExpression copy() { public IASTExpression copy() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }

View file

@ -137,4 +137,8 @@ public class CASTArraySubscriptExpression extends ASTNode implements
public boolean isLValue() { public boolean isLValue() {
return true; return true;
} }
public final ValueCategory getValueCategory() {
return ValueCategory.LVALUE;
}
} }

View file

@ -18,9 +18,9 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.c.ICArrayType; import org.eclipse.cdt.core.dom.ast.c.ICArrayType;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
@ -258,4 +258,8 @@ public class CASTBinaryExpression extends ASTNode implements
} }
return false; return false;
} }
public final ValueCategory getValueCategory() {
return isLValue() ? ValueCategory.LVALUE : ValueCategory.PRVALUE;
}
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -125,4 +125,8 @@ public class CASTCastExpression extends ASTNode implements IASTCastExpression, I
public boolean isLValue() { public boolean isLValue() {
return false; return false;
} }
public final ValueCategory getValueCategory() {
return ValueCategory.PRVALUE;
}
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -96,4 +96,8 @@ public class CASTCompoundStatementExpression extends ASTNode implements IGNUASTC
} }
return false; return false;
} }
public final ValueCategory getValueCategory() {
return isLValue() ? ValueCategory.LVALUE : ValueCategory.PRVALUE;
}
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -148,4 +148,8 @@ public class CASTConditionalExpression extends ASTNode implements
public boolean isLValue() { public boolean isLValue() {
return false; return false;
} }
public final ValueCategory getValueCategory() {
return ValueCategory.PRVALUE;
}
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -111,4 +111,8 @@ public class CASTExpressionList extends ASTNode implements IASTExpressionList,
} }
return false; return false;
} }
public final ValueCategory getValueCategory() {
return isLValue() ? ValueCategory.LVALUE : ValueCategory.PRVALUE;
}
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -152,6 +152,10 @@ public class CASTFieldReference extends ASTNode implements IASTFieldReference, I
return getFieldOwner().isLValue(); return getFieldOwner().isLValue();
} }
public final ValueCategory getValueCategory() {
return isLValue() ? ValueCategory.LVALUE : ValueCategory.PRVALUE;
}
public IBinding[] findBindings(IASTName n, boolean isPrefix) { public IBinding[] findBindings(IASTName n, boolean isPrefix) {
return CVisitor.findBindingsForContentAssist(n, isPrefix); return CVisitor.findBindingsForContentAssist(n, isPrefix);
} }

View file

@ -15,8 +15,8 @@ package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList; import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
@ -140,6 +140,10 @@ public class CASTFunctionCallExpression extends ASTNode implements
return false; return false;
} }
public final ValueCategory getValueCategory() {
return ValueCategory.PRVALUE;
}
@Deprecated @Deprecated
public IASTExpression getParameterExpression() { public IASTExpression getParameterExpression() {
if (fArguments.length == 0) if (fArguments.length == 0)

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -114,6 +114,11 @@ public class CASTIdExpression extends ASTNode implements IASTIdExpression, IASTC
public boolean isLValue() { public boolean isLValue() {
return true; return true;
} }
public final ValueCategory getValueCategory() {
return ValueCategory.LVALUE;
}
public IBinding[] findBindings(IASTName n, boolean isPrefix) { public IBinding[] findBindings(IASTName n, boolean isPrefix) {
IBinding[] bindings = CVisitor.findBindingsForContentAssist(n, isPrefix); IBinding[] bindings = CVisitor.findBindingsForContentAssist(n, isPrefix);

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -15,8 +15,8 @@ package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
@ -104,6 +104,10 @@ public class CASTLiteralExpression extends ASTNode implements IASTLiteralExpress
return getKind() == IASTLiteralExpression.lk_string_literal; return getKind() == IASTLiteralExpression.lk_string_literal;
} }
public final ValueCategory getValueCategory() {
return isLValue() ? ValueCategory.LVALUE : ValueCategory.PRVALUE;
}
private IType classifyTypeOfFloatLiteral() { private IType classifyTypeOfFloatLiteral() {
final char[] lit= getValue(); final char[] lit= getValue();
final int len= lit.length; final int len= lit.length;

View file

@ -1,12 +1,12 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others. * Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM - Initial API and implementation * John Camelon (IBM) - Initial API and implementation
* Yuan Zhang / Beth Tibbitts (IBM Research) * Yuan Zhang / Beth Tibbitts (IBM Research)
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
@ -17,9 +17,6 @@ import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTProblemExpression; import org.eclipse.cdt.core.dom.ast.IASTProblemExpression;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
/**
* @author jcamelon
*/
public class CASTProblemExpression extends CASTProblemOwner implements IASTProblemExpression { public class CASTProblemExpression extends CASTProblemOwner implements IASTProblemExpression {
public CASTProblemExpression() { public CASTProblemExpression() {
@ -63,4 +60,8 @@ public class CASTProblemExpression extends CASTProblemOwner implements IASTProbl
public boolean isLValue() { public boolean isLValue() {
return false; return false;
} }
public ValueCategory getValueCategory() {
return ValueCategory.PRVALUE;
}
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -94,4 +94,8 @@ public class CASTTypeIdExpression extends ASTNode implements IASTTypeIdExpressio
public boolean isLValue() { public boolean isLValue() {
return false; return false;
} }
public ValueCategory getValueCategory() {
return ValueCategory.PRVALUE;
}
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -134,4 +134,8 @@ public class CASTUnaryExpression extends ASTNode implements IASTUnaryExpression,
return false; return false;
} }
} }
public final ValueCategory getValueCategory() {
return isLValue() ? ValueCategory.LVALUE : ValueCategory.PRVALUE;
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009 Wind River Systems, Inc. and others. * Copyright (c) 2009, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -15,7 +15,6 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
@ -53,8 +52,4 @@ public class CPPASTAmbiguousCondition extends ASTAmbiguousNode implements IASTAm
public IASTExpression copy() { public IASTExpression copy() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public IType getExpressionType() {
return null;
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others. * Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -13,7 +13,6 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression;
@ -52,9 +51,4 @@ public class CPPASTAmbiguousExpression extends ASTAmbiguousNode implements
public IASTNode[] getNodes() { public IASTNode[] getNodes() {
return getExpressions(); return getExpressions();
} }
public IType getExpressionType() {
return exp[0].getExpressionType();
}
} }

View file

@ -12,13 +12,17 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName; import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTArraySubscriptExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTArraySubscriptExpression;
@ -27,7 +31,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; 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.ExpressionTypes;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
public class CPPASTArraySubscriptExpression extends ASTNode implements ICPPASTArraySubscriptExpression, IASTAmbiguityParent { public class CPPASTArraySubscriptExpression extends ASTNode implements ICPPASTArraySubscriptExpression, IASTAmbiguityParent {
@ -120,8 +125,8 @@ public class CPPASTArraySubscriptExpression extends ASTNode implements ICPPASTAr
if (overload == UNINITIALIZED_FUNCTION) { if (overload == UNINITIALIZED_FUNCTION) {
overload= null; overload= null;
IType t = getArrayExpression().getExpressionType(); IType t = getArrayExpression().getExpressionType();
t= SemanticUtil.getUltimateTypeUptoPointers(t); t= SemanticUtil.getNestedType(t, TDEF | REF | CVTYPE);
if (t instanceof ICPPClassType && !(t instanceof ICPPUnknownType)) { if (t instanceof ICPPClassType) {
overload= CPPSemantics.findOverloadedOperator(this); overload= CPPSemantics.findOverloadedOperator(this);
} }
} }
@ -177,34 +182,42 @@ public class CPPASTArraySubscriptExpression extends ASTNode implements ICPPASTAr
public IType getExpressionType() { public IType getExpressionType() {
ICPPFunction op = getOverload(); ICPPFunction op = getOverload();
if (op != null) { if (op != null) {
try { return ExpressionTypes.typeFromFunctionCall(op);
return op.getType().getReturnType(); }
} catch (DOMException e) { IType t1 = getArrayExpression().getExpressionType();
return e.getProblem(); t1= Conversions.lvalue_to_rvalue(t1);
if (t1 instanceof IPointerType) {
t1= ((IPointerType) t1).getType();
return glvalueType(t1);
}
IType t2= null;
IASTInitializerClause arg = getArgument();
if (arg instanceof IASTExpression) {
t2= Conversions.lvalue_to_rvalue(t2);
if (t2 instanceof IPointerType) {
t2= ((IPointerType) t2).getType();
return glvalueType(t2);
} }
} }
IType t = getArrayExpression().getExpressionType(); if (t1 instanceof ICPPUnknownType || t2 instanceof ICPPUnknownType) {
t= SemanticUtil.getUltimateTypeUptoPointers(t); // mstodo type of unknown
if (t instanceof ICPPUnknownType) {
return CPPUnknownClass.createUnnamedInstance(); return CPPUnknownClass.createUnnamedInstance();
} }
if (t instanceof IPointerType) {
return ((IPointerType) t).getType(); // mstodo return problem type
}
if (t instanceof IArrayType) {
return ((IArrayType) t).getType();
}
return null; return null;
} }
public boolean isLValue() { public boolean isLValue() {
return getValueCategory() == LVALUE;
}
public ValueCategory getValueCategory() {
ICPPFunction op = getOverload(); ICPPFunction op = getOverload();
if (op != null) { if (op != null) {
try { return ExpressionTypes.valueCategoryFromFunctionCall(op);
return CPPVisitor.isLValueReference(op.getType().getReturnType());
} catch (DOMException e) {
}
} }
return true; return ValueCategory.LVALUE;
} }
} }

View file

@ -12,21 +12,24 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.*;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName; import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner; import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
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.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
@ -34,7 +37,6 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; 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.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpression, IASTAmbiguityParent { public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpression, IASTAmbiguityParent {
@ -252,13 +254,10 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
return overload = CPPSemantics.findOverloadedOperator(this); return overload = CPPSemantics.findOverloadedOperator(this);
} }
public boolean isLValue() { public ValueCategory getValueCategory() {
ICPPFunction op = getOverload(); ICPPFunction op = getOverload();
if (op != null) { if (op != null) {
try { return valueCategoryFromFunctionCall(op);
return CPPVisitor.isLValueReference(op.getType().getReturnType());
} catch (DOMException e) {
}
} }
switch (getOperator()) { switch (getOperator()) {
case op_assign: case op_assign:
@ -272,31 +271,46 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
case op_plusAssign: case op_plusAssign:
case op_shiftLeftAssign: case op_shiftLeftAssign:
case op_shiftRightAssign: case op_shiftRightAssign:
return true; return LVALUE;
}
return false;
}
case op_pmdot:
if (!(getExpressionType() instanceof ICPPFunctionType)) {
return operand1.getValueCategory();
}
return PRVALUE;
case op_pmarrow:
if (!(getExpressionType() instanceof ICPPFunctionType))
return LVALUE;
return PRVALUE;
}
return PRVALUE;
}
public boolean isLValue() {
return getValueCategory() == LVALUE;
}
private IType createExpressionType() { private IType createExpressionType() {
// Check for overloaded operator. // Check for overloaded operator.
ICPPFunction o= getOverload(); ICPPFunction o= getOverload();
if (o != null) { if (o != null) {
try { return typeFromFunctionCall(o);
return o.getType().getReturnType();
} catch (DOMException e) {
e.getProblem();
}
} }
final int op = getOperator(); final int op = getOperator();
IType type1 = SemanticUtil.getUltimateTypeUptoPointers(getOperand1().getExpressionType()); IType type1 = prvalueType(operand1.getExpressionType());
if (type1 instanceof IProblemBinding) { if (type1 instanceof IProblemBinding) {
return type1; return type1;
} }
IType type2 = SemanticUtil.getUltimateTypeUptoPointers(getOperand2().getExpressionType()); IType type2 = null;
if (type2 instanceof IProblemBinding) { if (operand2 instanceof IASTExpression) {
return type2; type2= prvalueType(((IASTExpression) operand2).getExpressionType());
if (type2 instanceof IProblemBinding) {
return type2;
}
} }
IType type= CPPArithmeticConversion.convertCppOperandTypes(op, type1, type2); IType type= CPPArithmeticConversion.convertCppOperandTypes(op, type1, type2);
@ -316,35 +330,38 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
return new CPPBasicType(Kind.eBoolean, 0, this); return new CPPBasicType(Kind.eBoolean, 0, this);
case IASTBinaryExpression.op_plus: case IASTBinaryExpression.op_plus:
if (type1 instanceof IArrayType) { if (type1 instanceof IPointerType) {
return arrayTypeToPointerType((IArrayType) type1); return type1;
} else if (type2 instanceof IPointerType) { }
if (type2 instanceof IPointerType) {
return type2; return type2;
} else if (type2 instanceof IArrayType) { }
return arrayTypeToPointerType((IArrayType) type2); // mstodo problem type
}
break; break;
case IASTBinaryExpression.op_minus: case IASTBinaryExpression.op_minus:
if (type2 instanceof IPointerType || type2 instanceof IArrayType) { if (type1 instanceof IPointerType) {
if (type1 instanceof IPointerType || type1 instanceof IArrayType) { if (type2 instanceof IPointerType) {
return CPPVisitor.getPointerDiffType(this); return CPPVisitor.getPointerDiffType(this);
} }
return type1; return type1;
} }
// mstodo problem type
break; break;
case ICPPASTBinaryExpression.op_pmarrow: case ICPPASTBinaryExpression.op_pmarrow:
case ICPPASTBinaryExpression.op_pmdot: case ICPPASTBinaryExpression.op_pmdot:
if (type2 instanceof ICPPPointerToMemberType) { if (type2 instanceof ICPPPointerToMemberType) {
return ((ICPPPointerToMemberType) type2).getType(); IType t= ((ICPPPointerToMemberType) type2).getType();
if (t instanceof ICPPFunctionType)
return t;
if (op == ICPPASTBinaryExpression.op_pmdot && operand1.getValueCategory() == PRVALUE) {
return prvalueType(t);
}
return glvalueType(t);
} }
return new ProblemBinding(this, IProblemBinding.SEMANTIC_INVALID_TYPE, getRawSignature().toCharArray()); return new ProblemBinding(this, IProblemBinding.SEMANTIC_INVALID_TYPE, getRawSignature().toCharArray());
} }
return type1; return type1;
}
private IType arrayTypeToPointerType(IArrayType type) {
return new CPPPointerType(type.getType());
} }
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others. * Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -11,6 +11,10 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromReturnType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromReturnType;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
@ -29,6 +33,7 @@ public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpressi
private IASTExpression operand; private IASTExpression operand;
private IASTTypeId typeId; private IASTTypeId typeId;
private IType fType; private IType fType;
private ValueCategory fValueCategory;
public CPPASTCastExpression() { public CPPASTCastExpression() {
} }
@ -119,13 +124,22 @@ public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpressi
public IType getExpressionType() { public IType getExpressionType() {
if (fType == null) { if (fType == null) {
fType= CPPVisitor.createType(typeId.getAbstractDeclarator()); IType t= CPPVisitor.createType(typeId.getAbstractDeclarator());
fValueCategory= valueCategoryFromReturnType(t);
fType= typeFromReturnType(t);
} }
return fType; return fType;
} }
public ValueCategory getValueCategory() {
if (fValueCategory == null) {
getExpressionType(); // as a side effect fValueCategory is computed
}
return fValueCategory;
}
public boolean isLValue() { public boolean isLValue() {
return CPPVisitor.isLValueReference(getExpressionType()); return getValueCategory() == LVALUE;
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others. * Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -11,6 +11,9 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement; import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
@ -20,7 +23,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
/** /**
* @author jcamelon * Gnu-extension: ({ ... })
*/ */
public class CPPASTCompoundStatementExpression extends ASTNode implements IGNUASTCompoundStatementExpression { public class CPPASTCompoundStatementExpression extends ASTNode implements IGNUASTCompoundStatementExpression {
@ -82,19 +85,16 @@ public class CPPASTCompoundStatementExpression extends ASTNode implements IGNUAS
if (statements.length > 0) { if (statements.length > 0) {
IASTStatement st = statements[statements.length - 1]; IASTStatement st = statements[statements.length - 1];
if (st instanceof IASTExpressionStatement) if (st instanceof IASTExpressionStatement)
return ((IASTExpressionStatement) st).getExpression().getExpressionType(); return prvalueType(((IASTExpressionStatement) st).getExpression().getExpressionType());
} }
return null; return null;
} }
public boolean isLValue() { public boolean isLValue() {
IASTCompoundStatement compound = getCompoundStatement();
IASTStatement[] statements = compound.getStatements();
if (statements.length > 0) {
IASTStatement st = statements[statements.length - 1];
if (st instanceof IASTExpressionStatement)
return ((IASTExpressionStatement)st).getExpression().isLValue();
}
return false; return false;
} }
public ValueCategory getValueCategory() {
return PRVALUE;
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others. * Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -11,6 +11,9 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
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.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression; import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
@ -20,11 +23,8 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
/** public class CPPASTConditionalExpression extends ASTNode implements IASTConditionalExpression,
* @author jcamelon IASTAmbiguityParent {
*/
public class CPPASTConditionalExpression extends ASTNode implements
IASTConditionalExpression, IASTAmbiguityParent {
private IASTExpression condition; private IASTExpression condition;
private IASTExpression negative; private IASTExpression negative;
@ -134,6 +134,7 @@ public class CPPASTConditionalExpression extends ASTNode implements
} }
} }
// mstodo type of conditional operator
public IType getExpressionType() { public IType getExpressionType() {
IASTExpression positiveExpression = getPositiveResultExpression(); IASTExpression positiveExpression = getPositiveResultExpression();
if (positiveExpression == null) { if (positiveExpression == null) {
@ -146,7 +147,12 @@ public class CPPASTConditionalExpression extends ASTNode implements
return t2; return t2;
} }
// mstodo
public ValueCategory getValueCategory() {
return PRVALUE;
}
public boolean isLValue() { public boolean isLValue() {
return false; return getValueCategory() == LVALUE;
} }
} }

View file

@ -11,6 +11,8 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -20,6 +22,7 @@ import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
@ -155,4 +158,8 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
public boolean isLValue() { public boolean isLValue() {
return false; return false;
} }
public ValueCategory getValueCategory() {
return PRVALUE;
}
} }

View file

@ -12,6 +12,11 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromFunctionCall;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
@ -29,18 +34,18 @@ 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.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionList, IASTAmbiguityParent { public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionList, IASTAmbiguityParent {
private static final ICPPFunction[] NO_FUNCTIONS = new ICPPFunction[0]; private static final ICPPFunction[] NO_FUNCTIONS = new ICPPFunction[0];
private IASTExpression [] expressions = new IASTExpression[2];
/** /**
* Caution: may contain nulls. * Caution: may contain nulls.
* @see CPPASTExpressionList#computeImplicitNames * @see CPPASTExpressionList#computeImplicitNames
*/ */
private IASTImplicitName[] implicitNames; private IASTImplicitName[] implicitNames;
private ICPPFunction[] overloads = null; private ICPPFunction[] overloads = null;
@ -59,15 +64,13 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
public void addExpression(IASTExpression expression) { public void addExpression(IASTExpression expression) {
assertNotFrozen(); assertNotFrozen();
expressions = (IASTExpression [])ArrayUtil.append( IASTExpression.class, expressions, expression ); expressions = ArrayUtil.append(expressions, expression);
if (expression != null) { if (expression != null) {
expression.setParent(this); expression.setParent(this);
expression.setPropertyInParent(NESTED_EXPRESSION); expression.setPropertyInParent(NESTED_EXPRESSION);
} }
} }
private IASTExpression [] expressions = new IASTExpression[2];
@Override @Override
public boolean accept( ASTVisitor action ){ public boolean accept( ASTVisitor action ){
if( action.shouldVisitExpressions ){ if( action.shouldVisitExpressions ){
@ -190,10 +193,7 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
if (overloads.length > 0) { if (overloads.length > 0) {
ICPPFunction last = overloads[overloads.length - 1]; ICPPFunction last = overloads[overloads.length - 1];
if (last != null) { if (last != null) {
try { return typeFromFunctionCall(last);
return last.getType().getReturnType();
} catch (DOMException e) {
}
} }
} }
@ -205,24 +205,24 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
return null; return null;
} }
public boolean isLValue() { public ValueCategory getValueCategory() {
ICPPFunction[] overloads = getOverloads(); ICPPFunction[] overloads = getOverloads();
if (overloads.length > 0) { if (overloads.length > 0) {
ICPPFunction last = overloads[overloads.length - 1]; ICPPFunction last = overloads[overloads.length - 1];
if (last != null) { if (last != null) {
try { return valueCategoryFromFunctionCall(last);
return CPPVisitor.isLValueReference(last.getType().getReturnType());
} catch (DOMException e) {
return false;
}
} }
} }
for (int i = expressions.length-1; i >= 0; i--) { for (int i = expressions.length-1; i >= 0; i--) {
IASTExpression expr= expressions[i]; IASTExpression expr= expressions[i];
if (expr != null) if (expr != null)
return expr.isLValue(); return expr.getValueCategory();
} }
return false; return PRVALUE;
}
public boolean isLValue() {
return getValueCategory() == LVALUE;
} }
} }

View file

@ -13,6 +13,10 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
import java.util.ArrayList; import java.util.ArrayList;
@ -35,7 +39,6 @@ import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
@ -202,7 +205,10 @@ public class CPPASTFieldReference extends ASTNode implements ICPPASTFieldReferen
try { try {
if (binding instanceof IVariable) { if (binding instanceof IVariable) {
IType e2= ((IVariable) binding).getType(); IType e2= ((IVariable) binding).getType();
if (binding instanceof ICPPField && !((ICPPField) binding).isStatic()) { e2= SemanticUtil.getNestedType(e2, TDEF);
if (e2 instanceof ICPPReferenceType) {
e2= glvalueType(e2);
} else if (binding instanceof ICPPField && !((ICPPField) binding).isStatic()) {
IType e1= getFieldOwner().getExpressionType(); IType e1= getFieldOwner().getExpressionType();
if (isPointerDereference()) { if (isPointerDereference()) {
e1= SemanticUtil.getNestedType(e1, TDEF | REF | CVTYPE); e1= SemanticUtil.getNestedType(e1, TDEF | REF | CVTYPE);
@ -211,23 +217,34 @@ public class CPPASTFieldReference extends ASTNode implements ICPPASTFieldReferen
} }
} }
e2 = addQualifiersForAccess((ICPPField) binding, e2, e1); e2 = addQualifiersForAccess((ICPPField) binding, e2, e1);
} if (!isPointerDereference() && owner.getValueCategory() == PRVALUE) {
e2= prvalueType(e2);
} else {
e2= glvalueType(e2);
}
}
return SemanticUtil.mapToAST(e2, this); return SemanticUtil.mapToAST(e2, this);
} else if (binding instanceof IEnumerator) { }
if (binding instanceof IEnumerator) {
return ((IEnumerator) binding).getType(); return ((IEnumerator) binding).getType();
} else if (binding instanceof IFunction) { }
if (binding instanceof IFunction) {
return SemanticUtil.mapToAST(((IFunction) binding).getType(), this); return SemanticUtil.mapToAST(((IFunction) binding).getType(), this);
} else if (binding instanceof ICPPUnknownBinding) { }
if (binding instanceof ICPPUnknownBinding) {
// mstodo type of unknown.
return CPPUnknownClass.createUnnamedInstance(); return CPPUnknownClass.createUnnamedInstance();
} else if (binding instanceof IProblemBinding) { }
if (binding instanceof IProblemBinding) {
return (IType) binding; return (IType) binding;
} }
// mstodo problem type.
return null;
} catch (DOMException e) { } catch (DOMException e) {
return e.getProblem(); return e.getProblem();
} }
return null;
} }
public static IType addQualifiersForAccess(ICPPField field, IType fieldType, IType ownerType) throws DOMException { public static IType addQualifiersForAccess(ICPPField field, IType fieldType, IType ownerType) throws DOMException {
CVQualifier cvq1 = SemanticUtil.getCVQualifier(ownerType); CVQualifier cvq1 = SemanticUtil.getCVQualifier(ownerType);
if (field.isMutable()) { if (field.isMutable()) {
@ -244,23 +261,34 @@ public class CPPASTFieldReference extends ASTNode implements ICPPASTFieldReferen
} }
public boolean isLValue() { public ValueCategory getValueCategory() {
if (isPointerDereference()) IASTName name= getFieldName();
return true; IBinding binding = name.resolvePreBinding();
IBinding b= getFieldName().resolveBinding();
try { try {
if (b instanceof ICPPMember && ((ICPPMember) b).isStatic()) if (binding instanceof IVariable) {
return true; IType e2= ((IVariable) binding).getType();
if (b instanceof IVariable) { e2= SemanticUtil.getNestedType(e2, TDEF);
if (SemanticUtil.getNestedType(((IVariable) b).getType(), TDEF) instanceof ICPPReferenceType) { if (e2 instanceof ICPPReferenceType) {
return true; return LVALUE;
}
if (binding instanceof ICPPField && !((ICPPField) binding).isStatic()) {
if (isPointerDereference())
return LVALUE;
return owner.getValueCategory();
} }
return getFieldOwner().isLValue(); return LVALUE;
} }
} catch (DOMException e) { if (binding instanceof IFunction) {
} return LVALUE;
return false; }
} catch (DOMException e) {
}
return PRVALUE;
}
public boolean isLValue() {
return getValueCategory() == LVALUE;
} }
public IBinding[] findBindings(IASTName n, boolean isPrefix, String[] namespaces) { public IBinding[] findBindings(IASTName n, boolean isPrefix, String[] namespaces) {

View file

@ -12,8 +12,13 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.*;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.ExpansionOverlapsBoundaryException; import org.eclipse.cdt.core.dom.ast.ExpansionOverlapsBoundaryException;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
@ -21,12 +26,10 @@ import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression; 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.ICPPClassType;
@ -38,7 +41,6 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; 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.SemanticUtil; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
@ -49,7 +51,6 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
private IASTInitializerClause[] fArguments; private IASTInitializerClause[] fArguments;
private IASTImplicitName[] implicitNames; private IASTImplicitName[] implicitNames;
private IType type; // cached type of expression
private ICPPFunction overload= UNINITIALIZED_FUNCTION; private ICPPFunction overload= UNINITIALIZED_FUNCTION;
@ -203,67 +204,79 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
public ICPPFunction getOperator() { public ICPPFunction getOperator() {
if (overload == UNINITIALIZED_FUNCTION) { if (overload == UNINITIALIZED_FUNCTION) {
overload= null; overload= null;
// as a side effect this computes the overload IType t= functionName.getExpressionType();
getExpressionType(); t= SemanticUtil.getNestedType(t, TDEF | REF | CVTYPE);
} if (t instanceof ICPPClassType) {
overload = CPPSemantics.findOverloadedOperator(this, (ICPPClassType)t);
}
}
return overload; return overload;
} }
public IType getExpressionType() { public IType getExpressionType() {
if (type == null) { if (functionName instanceof IASTIdExpression) {
type= computeExpressionType(); // Handle misused id-expression in functional type conversions or simple type initializers.
} final IBinding binding= ((IASTIdExpression) functionName).getName().resolvePreBinding();
return type; if (binding instanceof ICPPConstructor) {
IBinding owner= binding.getOwner();
if (owner instanceof ICPPClassType) {
return (ICPPClassType) owner;
}
return new ProblemBinding(this, IProblemBinding.SEMANTIC_BAD_SCOPE, binding.getNameCharArray());
}
if (binding instanceof IProblemBinding) {
return (IProblemBinding) binding;
}
if (binding instanceof IType) {
return prvalueType((IType) binding);
}
}
IType t= SemanticUtil.getNestedType(functionName.getExpressionType(), TDEF|REF|CVTYPE);
if (t instanceof ICPPClassType) {
if (overload == UNINITIALIZED_FUNCTION) {
overload = CPPSemantics.findOverloadedOperator(this, (ICPPClassType)t);
}
if (overload != null) {
return typeFromFunctionCall(overload);
}
// mstodo problem type
return null;
}
if (t instanceof IPointerType) {
t= SemanticUtil.getNestedType(((IPointerType) t).getType(), TDEF | REF | CVTYPE);
}
if (t instanceof IFunctionType) {
return typeFromReturnType(((IFunctionType) t).getReturnType());
}
// mstodo problem type
return null;
} }
public boolean isLValue() { public boolean isLValue() {
return CPPVisitor.isLValueReference(getExpressionType()); return getValueCategory() == LVALUE;
} }
private IType computeExpressionType() { public ValueCategory getValueCategory() {
overload= null; IType t= functionName.getExpressionType();
try { if (t instanceof ICPPClassType) {
IType t= null; if (overload == UNINITIALIZED_FUNCTION) {
if (functionName instanceof IASTIdExpression) { overload = CPPSemantics.findOverloadedOperator(this, (ICPPClassType)t);
final IBinding binding= ((IASTIdExpression) functionName).getName().resolvePreBinding(); }
if (binding instanceof ICPPConstructor) { if (overload != null) {
IBinding owner= binding.getOwner(); return valueCategoryFromFunctionCall(overload);
if (owner instanceof ICPPClassType) { }
return (ICPPClassType) owner; } else {
} if (t instanceof IPointerType) {
return new ProblemBinding(this, IProblemBinding.SEMANTIC_BAD_SCOPE, t= SemanticUtil.getNestedType(((IPointerType) t).getType(), TDEF | REF | CVTYPE);
binding.getName().toCharArray()); }
} else if (binding instanceof IFunction) { if (t instanceof IFunctionType) {
t = SemanticUtil.mapToAST(((IFunction) binding).getType(), this); return valueCategoryFromReturnType(((IFunctionType) t).getReturnType());
} else if (binding instanceof IVariable) { }
t = SemanticUtil.mapToAST(((IVariable) binding).getType(), this); }
} else if (binding instanceof IType) { return ValueCategory.PRVALUE;
return (IType) binding; // constructor or simple type initializer
} else if (binding instanceof IProblemBinding) {
return (IProblemBinding) binding;
}
} else {
t= functionName.getExpressionType();
}
t= SemanticUtil.getUltimateTypeUptoPointers(t);
if (t instanceof IFunctionType) {
return ((IFunctionType) t).getReturnType();
} else if (t instanceof ICPPClassType) {
overload = CPPSemantics.findOverloadedOperator(this, (ICPPClassType)t);
if (overload != null) {
return overload.getType().getReturnType();
}
} else if (t instanceof IPointerType) {
t= SemanticUtil.getUltimateTypeUptoPointers(((IPointerType) t).getType());
if (t instanceof IFunctionType) {
return ((IFunctionType) t).getReturnType();
}
}
} catch (DOMException e) {
return e.getProblem();
}
return null;
} }
@Deprecated @Deprecated

View file

@ -12,22 +12,35 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICPPASTCompletionContext; import org.eclipse.cdt.core.dom.ast.ICPPASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; 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.CPPVisitor;
@ -35,7 +48,10 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, ICPPASTCompletionContext { public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, ICPPASTCompletionContext {
private static final ICPPASTFieldReference NOT_INITIALIZED = new CPPASTFieldReference();
private IASTName name; private IASTName name;
private ICPPASTFieldReference fTransformedExpression= NOT_INITIALIZED;
public CPPASTIdExpression() { public CPPASTIdExpression() {
} }
@ -92,21 +108,18 @@ public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, ICP
public IType getExpressionType() { public IType getExpressionType() {
IBinding binding = name.resolvePreBinding(); IBinding binding = name.resolvePreBinding();
if (checkForTransformation(binding)) {
return fTransformedExpression.getExpressionType();
}
try { try {
if (binding instanceof IVariable) { if (binding instanceof IProblemBinding) {
final IVariable var = (IVariable) binding; return (IProblemBinding) binding;
IType type= SemanticUtil.mapToAST(var.getType(), this); }
if (var instanceof ICPPField && !var.isStatic()) { if (binding instanceof IType || binding instanceof ICPPConstructor) {
IScope scope= CPPVisitor.getContainingScope(name); // mstodo return problem type
if (scope != null) { return null;
IType containerType= CPPVisitor.getImpliedObjectType(scope); }
if (containerType != null) { if (binding instanceof IEnumerator) {
type= CPPASTFieldReference.addQualifiersForAccess((ICPPField) var, type, containerType);
}
}
}
return type;
} else if (binding instanceof IEnumerator) {
IType type= ((IEnumerator) binding).getType(); IType type= ((IEnumerator) binding).getType();
if (type instanceof ICPPEnumeration) { if (type instanceof ICPPEnumeration) {
ICPPEnumeration enumType= (ICPPEnumeration) type; ICPPEnumeration enumType= (ICPPEnumeration) type;
@ -122,29 +135,84 @@ public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, ICP
} }
} }
return type; return type;
} else if (binding instanceof IProblemBinding) { }
return (IType) binding; if (binding instanceof IVariable) {
} else if (binding instanceof IFunction) { final IType t = glvalueType(((IVariable) binding).getType());
return SemanticUtil.mapToAST(t, this);
}
if (binding instanceof IFunction) {
return SemanticUtil.mapToAST(((IFunction) binding).getType(), this); return SemanticUtil.mapToAST(((IFunction) binding).getType(), this);
} else if (binding instanceof ICPPTemplateNonTypeParameter) { }
return ((ICPPTemplateNonTypeParameter) binding).getType(); if (binding instanceof ICPPTemplateNonTypeParameter) {
} else if (binding instanceof ICPPClassType) { return prvalueType(((ICPPTemplateNonTypeParameter) binding).getType());
return ((ICPPClassType) binding); }
} else if (binding instanceof ICPPUnknownBinding) { if (binding instanceof ICPPUnknownBinding) {
// mstodo typeof unknown binding
return CPPUnknownClass.createUnnamedInstance(); return CPPUnknownClass.createUnnamedInstance();
} }
} catch (DOMException e) { } catch (DOMException e) {
return e.getProblem(); return e.getProblem();
} }
// mstodo return problem type
return null; return null;
} }
public boolean isLValue() { /**
IBinding b= getName().resolveBinding(); * 9.3.1-3 Transformation to class member access within the definition of a non-static
if (b instanceof IVariable || b instanceof IFunction) { * member function.
return true; */
public boolean checkForTransformation(IBinding binding) {
if (fTransformedExpression == NOT_INITIALIZED) {
fTransformedExpression= null;
if (name instanceof ICPPASTQualifiedName) {
IASTNode parent= name.getParent();
if (parent instanceof ICPPASTUnaryExpression) {
if (((ICPPASTUnaryExpression) parent).getOperator() == IASTUnaryExpression.op_amper) {
return false;
}
}
}
if (binding instanceof ICPPMember && !(binding instanceof IType) && !(binding instanceof ICPPConstructor)
&&!((ICPPMember) binding).isStatic()) {
IASTNode parent= getParent();
while (parent != null && !(parent instanceof ICPPASTFunctionDefinition)) {
parent= parent.getParent();
}
if (parent instanceof ICPPASTFunctionDefinition) {
ICPPASTFunctionDefinition fdef= (ICPPASTFunctionDefinition) parent;
final IBinding methodBinding = fdef.getDeclarator().getName().resolvePreBinding();
if (methodBinding instanceof ICPPMethod && !((ICPPMethod) methodBinding).isStatic()) {
IASTName nameDummy= new CPPASTName();
nameDummy.setBinding(binding);
IASTExpression owner= new CPPASTLiteralExpression(IASTLiteralExpression.lk_this, CharArrayUtils.EMPTY);
owner= new CPPASTUnaryExpression(IASTUnaryExpression.op_star, owner);
fTransformedExpression= new CPPASTFieldReference(nameDummy, owner);
fTransformedExpression.setParent(getParent());
fTransformedExpression.setPropertyInParent(getPropertyInParent());
}
}
}
} }
return false;
return fTransformedExpression != null;
}
public boolean isLValue() {
return getValueCategory() == LVALUE;
}
public ValueCategory getValueCategory() {
IBinding binding = name.resolvePreBinding();
if (checkForTransformation(binding)) {
return fTransformedExpression.getValueCategory();
}
if (binding instanceof ICPPTemplateNonTypeParameter)
return ValueCategory.PRVALUE;
if (binding instanceof IVariable || binding instanceof IFunction) {
return ValueCategory.LVALUE;
}
return ValueCategory.PRVALUE;
} }
public IBinding[] findBindings(IASTName n, boolean isPrefix, String[] namespaces) { public IBinding[] findBindings(IASTName n, boolean isPrefix, String[] namespaces) {

View file

@ -12,12 +12,12 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; 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.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture; 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.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.parser.util.ArrayUtil; 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.ASTNode;
@ -44,7 +44,7 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTExpression#copy() * @see org.eclipse.cdt.core.dom.ast.IASTExpression#copy()
*/ */
public IASTExpression copy() { public CPPASTLambdaExpression copy() {
CPPASTLambdaExpression result= new CPPASTLambdaExpression(); CPPASTLambdaExpression result= new CPPASTLambdaExpression();
result.fCaptureDefault= fCaptureDefault; result.fCaptureDefault= fCaptureDefault;
if (fCaptures != null) { if (fCaptures != null) {
@ -191,4 +191,8 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr
public boolean isLValue() { public boolean isLValue() {
return false; return false;
} }
public ValueCategory getValueCategory() {
return ValueCategory.PRVALUE;
}
} }

View file

@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
@ -122,6 +123,10 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
public boolean isLValue() { public boolean isLValue() {
return getKind() == IASTLiteralExpression.lk_string_literal; return getKind() == IASTLiteralExpression.lk_string_literal;
} }
public ValueCategory getValueCategory() {
return isLValue() ? ValueCategory.LVALUE : ValueCategory.PRVALUE;
}
private IValue getStringLiteralSize() { private IValue getStringLiteralSize() {
char[] value= getValue(); char[] value= getValue();

View file

@ -12,6 +12,8 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; 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.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator; import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier; import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
@ -29,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
@ -224,7 +227,11 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression
return false; return false;
} }
@Deprecated public ValueCategory getValueCategory() {
return PRVALUE;
}
@Deprecated
public IASTExpression[] getNewTypeIdArrayExpressions() { public IASTExpression[] getNewTypeIdArrayExpressions() {
if (cachedArraySizes == null) { if (cachedArraySizes == null) {
if (typeId != null) { if (typeId != null) {

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009 Wind River Systems, Inc. and others. * Copyright (c) 2009, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -41,12 +41,11 @@ public class CPPASTPackExpansionExpression extends ASTNode implements ICPPASTPac
} }
} }
public IASTExpression getPattern() { public IASTExpression getPattern() {
return fPattern; return fPattern;
} }
public IASTExpression copy() { public CPPASTPackExpansionExpression copy() {
CPPASTPackExpansionExpression copy = new CPPASTPackExpansionExpression(fPattern.copy()); CPPASTPackExpansionExpression copy = new CPPASTPackExpansionExpression(fPattern.copy());
copy.setOffsetAndLength(this); copy.setOffsetAndLength(this);
return copy; return copy;
@ -63,6 +62,10 @@ public class CPPASTPackExpansionExpression extends ASTNode implements ICPPASTPac
public boolean isLValue() { public boolean isLValue() {
return fPattern.isLValue(); return fPattern.isLValue();
} }
public ValueCategory getValueCategory() {
return fPattern.getValueCategory();
}
@Override @Override
public boolean accept(ASTVisitor visitor) { public boolean accept(ASTVisitor visitor) {

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others. * Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -59,4 +59,8 @@ public class CPPASTProblemExpression extends CPPASTProblemOwner implements IASTP
public boolean isLValue() { public boolean isLValue() {
return false; return false;
} }
public ValueCategory getValueCategory() {
return ValueCategory.PRVALUE;
}
} }

View file

@ -11,15 +11,19 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
@ -73,7 +77,7 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode implements
public IType getExpressionType() { public IType getExpressionType() {
if (fType == null) { if (fType == null) {
fType= CPPVisitor.createType(fDeclSpec); fType= prvalueType(CPPVisitor.createType(fDeclSpec));
} }
return fType; return fType;
} }
@ -82,7 +86,11 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode implements
return false; return false;
} }
@Override public ValueCategory getValueCategory() {
return PRVALUE;
}
@Override
public boolean accept(ASTVisitor action) { public boolean accept(ASTVisitor action) {
if (action.shouldVisitExpressions) { if (action.shouldVisitExpressions) {
switch (action.visit(this)) { switch (action.visit(this)) {

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others. * Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -11,6 +11,9 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
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.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
@ -84,6 +87,7 @@ public class CPPASTTypeIdExpression extends ASTNode implements ICPPASTTypeIdExpr
public IType getExpressionType() { public IType getExpressionType() {
switch (getOperator()) { switch (getOperator()) {
case op_sizeof: case op_sizeof:
case op_alignof:
return CPPVisitor.get_SIZE_T(this); return CPPVisitor.get_SIZE_T(this);
case op_typeid: case op_typeid:
return CPPVisitor.get_type_info(this); return CPPVisitor.get_type_info(this);
@ -98,6 +102,8 @@ public class CPPASTTypeIdExpression extends ASTNode implements ICPPASTTypeIdExpr
} }
return false; return false;
} }
public ValueCategory getValueCategory() {
return isLValue() ? LVALUE : PRVALUE;
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009 Wind River Systems, Inc. and others. * Copyright (c) 2009, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -10,6 +10,8 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdInitializerExpression; import org.eclipse.cdt.core.dom.ast.IASTTypeIdInitializerExpression;
@ -18,7 +20,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTTypeIdInitializerExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
/** /**
* C++ variant of type id initializer expression. * C++ variant of type id initializer expression. type-id { initializer }
*/ */
public class CPPASTTypeIdInitializerExpression extends ASTTypeIdInitializerExpression { public class CPPASTTypeIdInitializerExpression extends ASTTypeIdInitializerExpression {
@ -37,6 +39,6 @@ public class CPPASTTypeIdInitializerExpression extends ASTTypeIdInitializerExpre
public IType getExpressionType() { public IType getExpressionType() {
final IASTTypeId typeId = getTypeId(); final IASTTypeId typeId = getTypeId();
return CPPVisitor.createType(typeId.getAbstractDeclarator()); return prvalueType(CPPVisitor.createType(typeId.getAbstractDeclarator()));
} }
} }

View file

@ -13,6 +13,9 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.*;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
@ -48,7 +51,9 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
* Unary expression in c++ * Unary expression in c++
*/ */
public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpression, IASTAmbiguityParent { public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpression, IASTAmbiguityParent {
private int op; private static final CPPBasicType BOOLEAN_TYPE = new CPPBasicType(Kind.eBoolean, 0);
private int op;
private IASTExpression operand; private IASTExpression operand;
private ICPPFunction overload = UNINITIALIZED_FUNCTION; private ICPPFunction overload = UNINITIALIZED_FUNCTION;
@ -187,6 +192,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
try { try {
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
if (!member.isStatic()) { // so if the member is static it will fall through if (!member.isStatic()) { // so if the member is static it will fall through
overload= null;
if (!inParenthesis) { if (!inParenthesis) {
return new CPPPointerToMemberType(member.getType(), member.getClassOwner(), false, false); return new CPPPointerToMemberType(member.getType(), member.getClassOwner(), false, false);
} else if (member instanceof IFunction) { } else if (member instanceof IFunction) {
@ -210,6 +216,8 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
return CPPVisitor.get_SIZE_T(this); return CPPVisitor.get_SIZE_T(this);
case op_typeid: case op_typeid:
return CPPVisitor.get_type_info(this); return CPPVisitor.get_type_info(this);
case op_bracketedPrimary:
return getOperand().getExpressionType();
} }
final IASTExpression operand = getOperand(); final IASTExpression operand = getOperand();
@ -219,88 +227,90 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
if (ptm != null) if (ptm != null)
return ptm; return ptm;
IType operator = findOperatorReturnType(); ICPPFunction overload = getOverload();
if (operator != null) if (overload != null)
return operator; return typeFromFunctionCall(overload);
IType type= operand.getExpressionType(); return new CPPPointerType(operand.getExpressionType());
type = SemanticUtil.getNestedType(type, TDEF | REF);
return new CPPPointerType(type);
} }
ICPPFunction overload = getOverload();
if (overload != null)
return typeFromFunctionCall(overload);
if (op == op_star) { if (op == op_star) {
IType type= operand.getExpressionType(); IType type= operand.getExpressionType();
type = SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE); type = SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE);
if (type instanceof IProblemBinding) { if (type instanceof IProblemBinding) {
return type; return type;
} }
IType operator = findOperatorReturnType();
if (operator != null) { if (type instanceof IPointerType || type instanceof IArrayType) {
return operator; type= ((ITypeContainer) type).getType();
} else if (type instanceof IPointerType || type instanceof IArrayType) { return glvalueType(type);
return ((ITypeContainer) type).getType(); }
} else if (type instanceof ICPPUnknownType) { if (type instanceof ICPPUnknownType) {
// mstodo Type of unknown
return CPPUnknownClass.createUnnamedInstance(); return CPPUnknownClass.createUnnamedInstance();
} }
return new ProblemBinding(this, IProblemBinding.SEMANTIC_INVALID_TYPE, this.getRawSignature().toCharArray()); return new ProblemBinding(this, IProblemBinding.SEMANTIC_INVALID_TYPE, this.getRawSignature().toCharArray());
} }
IType origType= operand.getExpressionType(); IType typeOfOperand= operand.getExpressionType();
IType type = SemanticUtil.getUltimateTypeUptoPointers(origType);
IType operator = findOperatorReturnType();
if (operator != null) {
return operator;
}
switch (op) { switch (op) {
case op_not: case op_not:
return new CPPBasicType(Kind.eBoolean, 0); return BOOLEAN_TYPE;
case op_postFixDecr:
case op_postFixIncr:
typeOfOperand= prvalueType(typeOfOperand);
break;
case op_minus: case op_minus:
case op_plus: case op_plus:
case op_tilde: case op_tilde:
IType t= CPPArithmeticConversion.promoteCppType(type); IType t= CPPArithmeticConversion.promoteCppType(prvalueType(typeOfOperand));
if (t != null) { if (t != null) {
return t; return t;
} }
break; break;
} }
if (origType instanceof CPPBasicType) { if (typeOfOperand instanceof CPPBasicType) {
((CPPBasicType) origType).setFromExpression(this); ((CPPBasicType) typeOfOperand).setFromExpression(this);
} }
return origType; return typeOfOperand;
} }
public boolean isLValue() { public ValueCategory getValueCategory() {
ICPPFunction op = getOverload(); final int op= getOperator();
if (op != null) { switch (op) {
try { case op_typeid:
return CPPVisitor.isLValueReference(op.getType().getReturnType()); return LVALUE;
} catch (DOMException e) { case op_sizeof:
} case op_sizeofParameterPack:
} return PRVALUE;
switch (getOperator()) {
case op_bracketedPrimary: case op_bracketedPrimary:
return getOperand().isLValue(); return (operand).getValueCategory();
case op_star: }
case op_prefixDecr:
case op_prefixIncr: if (op == op_amper && computePointerToMemberType() != null) {
return true; return PRVALUE;
default:
return false;
} }
}
private IType findOperatorReturnType() { ICPPFunction overload = getOverload();
ICPPFunction operatorFunction = getOverload(); if (overload != null)
if (operatorFunction != null) { return valueCategoryFromFunctionCall(overload);
try {
return operatorFunction.getType().getReturnType(); switch(op) {
} catch (DOMException e) { case op_star:
return e.getProblem(); case op_prefixDecr:
} case op_prefixIncr:
return LVALUE;
} }
return null; return PRVALUE;
} }
public boolean isLValue() {
return getValueCategory() == LVALUE;
}
} }

View file

@ -153,8 +153,6 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
if (expr != null) { if (expr != null) {
IType type= expr.getExpressionType(); IType type= expr.getExpressionType();
type= Conversions.lvalue_to_rvalue(type); type= Conversions.lvalue_to_rvalue(type);
type= Conversions.array_to_pointer(type);
type= Conversions.function_to_pointer(type);
if (type != null) { if (type != null) {
return type; return type;
} }

View file

@ -338,7 +338,7 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
} }
} }
public boolean isStatic() { public final boolean isStatic() {
return isStatic(true); return isStatic(true);
} }

View file

@ -273,8 +273,8 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
return ASTQueries.findInnermostDeclarator(paramDecl.getDeclarator()).getName(); return ASTQueries.findInnermostDeclarator(paramDecl.getDeclarator()).getName();
} }
public boolean isStatic() { public final boolean isStatic() {
return hasStorageClass(IASTDeclSpecifier.sc_static); return isStatic(true);
} }
public boolean isMutable() { public boolean isMutable() {

View file

@ -208,6 +208,18 @@ public class CPPMethod extends CPPFunction implements ICPPMethod {
public boolean isMutable() { public boolean isMutable() {
return hasStorageClass( this, IASTDeclSpecifier.sc_mutable ); return hasStorageClass( this, IASTDeclSpecifier.sc_mutable );
} }
@Override
public boolean isStatic(boolean resolveAll) {
IASTDeclaration decl = getPrimaryDeclaration();
if (decl != null) {
ICPPASTDeclSpecifier declSpec = getDeclSpec(decl);
if (declSpec != null) {
return declSpec.getStorageClass() == IASTDeclSpecifier.sc_static;
}
}
return false;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod#isDestructor() * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod#isDestructor()

View file

@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
@ -151,6 +152,18 @@ public class CPPMethodTemplate extends CPPFunctionTemplate implements ICPPMethod
return false; return false;
} }
@Override
public boolean isStatic(boolean resolveAll) {
IASTDeclaration decl = getPrimaryDeclaration();
if (decl instanceof ICPPASTTemplateDeclaration) {
ICPPASTDeclSpecifier declSpec= getDeclSpecifier(((ICPPASTTemplateDeclaration) decl).getDeclaration());
if (declSpec != null) {
return declSpec.getStorageClass() == IASTDeclSpecifier.sc_static;
}
}
return false;
}
@Override @Override
public boolean isInline() { public boolean isInline() {
IASTDeclaration decl = getPrimaryDeclaration(); IASTDeclaration decl = getPrimaryDeclaration();

View file

@ -15,6 +15,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.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
@ -38,7 +39,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
/** /**
* A template template parameter. * A template template parameter.
@ -107,8 +107,13 @@ public class CPPTemplateTemplateParameter extends CPPTemplateParameter implement
if (parent instanceof ICPPASTTemplatedTypeTemplateParameter) { if (parent instanceof ICPPASTTemplatedTypeTemplateParameter) {
ICPPASTTemplatedTypeTemplateParameter param = (ICPPASTTemplatedTypeTemplateParameter) parent; ICPPASTTemplatedTypeTemplateParameter param = (ICPPASTTemplatedTypeTemplateParameter) parent;
IASTExpression value = param.getDefaultValue(); IASTExpression value = param.getDefaultValue();
if (value != null) if (value instanceof IASTIdExpression) {
return CPPVisitor.createType(value); IASTName name= ((IASTIdExpression) value).getName();
IBinding b= name.resolveBinding();
if (b instanceof IType) {
return (IType) b;
}
}
} }
} }
} }

View file

@ -115,7 +115,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointerToMember; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointerToMember;
import org.eclipse.cdt.core.dom.parser.IExtensionToken; import org.eclipse.cdt.core.dom.parser.IExtensionToken;
@ -2576,7 +2575,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
simpleType= IASTSimpleDeclSpecifier.t_typeof; simpleType= IASTSimpleDeclSpecifier.t_typeof;
consume(IGCCToken.t_typeof); consume(IGCCToken.t_typeof);
typeofExpression= parseTypeidInParenthesisOrUnaryExpression(false, LA(1).getOffset(), typeofExpression= parseTypeidInParenthesisOrUnaryExpression(false, LA(1).getOffset(),
IGNUASTTypeIdExpression.op_typeof, -1, CastExprCtx.eNotBExpr); IASTTypeIdExpression.op_typeof, -1, CastExprCtx.eNotBExpr);
encounteredTypename= true; encounteredTypename= true;
endOffset= calculateEndOffset(typeofExpression); endOffset= calculateEndOffset(typeofExpression);

View file

@ -1958,18 +1958,17 @@ public class CPPVisitor extends ASTQueries {
} }
IType type = expr.getExpressionType(); IType type = expr.getExpressionType();
if (spec.getType() == IASTSimpleDeclSpecifier.t_decltype) { if (spec.getType() == IASTSimpleDeclSpecifier.t_decltype) {
while (expr instanceof IASTUnaryExpression switch((expr).getValueCategory()) {
&& ((IASTUnaryExpression) expr).getOperator() == IASTUnaryExpression.op_bracketedPrimary) { case XVALUE:
expr = ((IASTUnaryExpression) expr).getOperand(); type= new CPPReferenceType(type, true);
break;
case LVALUE:
type= new CPPReferenceType(type, false);
break;
case PRVALUE:
break;
} }
if (!(expr instanceof IASTFunctionCallExpression)) { }
type= SemanticUtil.getNestedType(type, TDEF | REF);
if (expr.isLValue())
type= new CPPReferenceType(type, false);
}
} else {
type= SemanticUtil.getNestedType(type, TDEF | REF);
}
return type; return type;
} }
@ -2208,7 +2207,8 @@ public class CPPVisitor extends ASTQueries {
} }
return false; return false;
} }
@Deprecated
public static boolean isLValueReference(IType t) { public static boolean isLValueReference(IType t) {
t= SemanticUtil.getNestedType(t, TDEF); t= SemanticUtil.getNestedType(t, TDEF);
return t instanceof ICPPReferenceType && !((ICPPReferenceType) t).isRValueReference(); return t instanceof ICPPReferenceType && !((ICPPReferenceType) t).isRValueReference();

View file

@ -192,7 +192,7 @@ public class Conversions {
} }
} }
// Otherwise, a temporary of type cv1 T1 is created and initialized from the initializer // Otherwise, a temporary of type 'cv1 T1' is created and initialized from the initializer
// expression using the rules for a non-reference copy initialization (8.5). The reference is then // expression using the rules for a non-reference copy initialization (8.5). The reference is then
// bound to the temporary. If T1 is reference-related to T2, cv1 must be the same cv-qualification // bound to the temporary. If T1 is reference-related to T2, cv1 must be the same cv-qualification
// as, or greater cv-qualification than, cv2; otherwise, the program is ill-formed. // as, or greater cv-qualification than, cv2; otherwise, the program is ill-formed.
@ -271,6 +271,7 @@ public class Conversions {
} }
private static Cost nonReferenceConversion(boolean sourceIsLValue, IType source, IType target, UDCMode udc, boolean isImpliedObject) throws DOMException { private static Cost nonReferenceConversion(boolean sourceIsLValue, IType source, IType target, UDCMode udc, boolean isImpliedObject) throws DOMException {
// mstodo fix this to better match the specification
if (source instanceof InitializerListType) { if (source instanceof InitializerListType) {
return listInitializationSequence(((InitializerListType) source), target, udc, false); return listInitializationSequence(((InitializerListType) source), target, udc, false);
} }
@ -756,6 +757,7 @@ public class Conversions {
* [4.3] function-to-ptr * [4.3] function-to-ptr
*/ */
private static final boolean lvalue_to_rvalue(final Cost cost, boolean isLValue) { private static final boolean lvalue_to_rvalue(final Cost cost, boolean isLValue) {
// mstodo request value category
// target should not be a reference here. // target should not be a reference here.
boolean isConverted= false; boolean isConverted= false;
IType target = getNestedType(cost.target, REF | TDEF); IType target = getNestedType(cost.target, REF | TDEF);
@ -1095,39 +1097,20 @@ public class Conversions {
} }
/** /**
* 4.1 * 4.1, 4.2, 4.3
*/ */
public static IType lvalue_to_rvalue(IType type) { public static IType lvalue_to_rvalue(IType type) {
IType nested= SemanticUtil.getNestedType(type, TDEF | REF); type= SemanticUtil.getNestedType(type, TDEF | REF);
if (nested == null || nested == type || nested instanceof IArrayType || nested instanceof ICPPFunctionType) { if (type instanceof IArrayType) {
return new CPPPointerType(((IArrayType) type).getType());
}
if (type instanceof IFunctionType) {
return new CPPPointerType(type);
}
IType uqType= SemanticUtil.getNestedType(type, TDEF | REF | ALLCVQ);
if (uqType instanceof ICPPClassType) {
return type; return type;
} }
IType unqualified= SemanticUtil.getNestedType(nested, TDEF | ALLCVQ); return uqType;
if (unqualified instanceof ICPPClassType)
return nested;
return unqualified;
}
/**
* 4.2
*/
public static IType array_to_pointer(IType type) {
IType nested= SemanticUtil.getNestedType(type, TDEF);
if (nested instanceof IArrayType) {
return new CPPPointerType(((IArrayType) nested).getType());
}
return type;
}
/**
* 4.3
*/
public static IType function_to_pointer(IType type) {
IType nested= SemanticUtil.getNestedType(type, TDEF);
if (nested instanceof IFunctionType) {
return new CPPPointerType(nested);
}
return type;
} }
} }

View file

@ -0,0 +1,81 @@
/*******************************************************************************
* 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 - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
/**
* Methods for computing the type of an expression
*/
public class ExpressionTypes {
public static IType glvalueType(IType type) {
// Reference types are removed.
return SemanticUtil.getNestedType(type, TDEF | REF);
}
public static IType prvalueType(IType type) {
return Conversions.lvalue_to_rvalue(type);
}
public static ValueCategory valueCategoryFromFunctionCall(ICPPFunction function) {
try {
final ICPPFunctionType ft = function.getType();
return valueCategoryFromReturnType(ft.getReturnType());
} catch (DOMException e) {
return ValueCategory.PRVALUE;
}
}
public static ValueCategory valueCategoryFromReturnType(IType r) {
r= SemanticUtil.getNestedType(r, TDEF);
if (r instanceof ICPPReferenceType) {
ICPPReferenceType refType= (ICPPReferenceType) r;
if (!refType.isRValueReference()) {
return ValueCategory.LVALUE;
}
if (SemanticUtil.getNestedType(refType.getType(), TDEF | REF | CVTYPE) instanceof IFunctionType) {
return ValueCategory.LVALUE;
}
return ValueCategory.XVALUE;
}
return ValueCategory.PRVALUE;
}
public static IType typeFromFunctionCall(ICPPFunction function) {
try {
final ICPPFunctionType ft = function.getType();
return typeFromReturnType(ft.getReturnType());
} catch (DOMException e) {
return e.getProblem();
}
}
public static IType typeFromReturnType(IType r) {
r= SemanticUtil.getNestedType(r, TDEF);
if (r instanceof ICPPReferenceType) {
return glvalueType(r);
}
return prvalueType(r);
}
}

View file

@ -14,13 +14,16 @@
package org.eclipse.cdt.internal.core.pdom.dom.cpp; package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
@ -197,8 +200,24 @@ class PDOMCPPMethod extends PDOMCPPFunction implements ICPPMethod {
return PDOMName.COULD_BE_POLYMORPHIC_METHOD_CALL; return PDOMName.COULD_BE_POLYMORPHIC_METHOD_CALL;
} }
// v.member() // v.member()
IType type= fr.getFieldOwner().getExpressionType(); IASTExpression fieldOwner = fr.getFieldOwner();
if (type instanceof ICPPReferenceType) { if (fieldOwner.getValueCategory().isGLValue()) {
while (fieldOwner instanceof IASTUnaryExpression
&& ((IASTUnaryExpression) fieldOwner).getOperator() == IASTUnaryExpression.op_bracketedPrimary)
fieldOwner = ((IASTUnaryExpression) fieldOwner).getOperand();
if (fieldOwner instanceof IASTIdExpression) {
IBinding b= ((IASTIdExpression) fieldOwner).getName().resolveBinding();
if (b instanceof IVariable) {
try {
IType t = ((IVariable) b).getType();
if (!(t instanceof ICPPReferenceType)) {
return 0;
}
} catch (DOMException e) {
return 0;
}
}
}
return PDOMName.COULD_BE_POLYMORPHIC_METHOD_CALL; return PDOMName.COULD_BE_POLYMORPHIC_METHOD_CALL;
} }
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2006, 2009 IBM Corporation and others. * Copyright (c) 2006, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -11,8 +11,8 @@
package org.eclipse.cdt.internal.core.dom.parser.upc.ast; package org.eclipse.cdt.internal.core.dom.parser.upc.ast;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.upc.ast.IUPCASTKeywordExpression; import org.eclipse.cdt.core.dom.upc.ast.IUPCASTKeywordExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.c.CBasicType; import org.eclipse.cdt.internal.core.dom.parser.c.CBasicType;
@ -53,6 +53,10 @@ public class UPCASTKeywordExpression extends ASTNode implements IUPCASTKeywordEx
return false; return false;
} }
public ValueCategory getValueCategory() {
return ValueCategory.PRVALUE;
}
@Override @Override
public boolean accept(ASTVisitor visitor) { public boolean accept(ASTVisitor visitor) {
if(visitor.shouldVisitExpressions) { if(visitor.shouldVisitExpressions) {