1
/*******************************************************************************
2
* Copyright (c) 2010 Wind River Systems, Inc. and others.
3
* All rights reserved. This program and the accompanying materials
4
* are made available under the terms of the Eclipse Public License v1.0
5
* which accompanies this distribution, and is available at
6
* http://www.eclipse.org/legal/epl-v10.html
9
* Markus Schorn - initial API and implementation
10
*******************************************************************************/
11
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
13
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
14
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
15
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
17
import org.eclipse.cdt.core.dom.ast.IASTExpression;
18
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
19
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
20
import org.eclipse.cdt.core.dom.ast.IASTName;
21
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
22
import org.eclipse.cdt.core.dom.ast.IBinding;
23
import org.eclipse.cdt.core.dom.ast.IFunctionType;
24
import org.eclipse.cdt.core.dom.ast.IType;
25
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
26
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
27
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
31
* Methods for computing the type of an expression
33
public class ExpressionTypes {
35
public static IType glvalueType(IType type) {
36
// Reference types are removed.
37
return SemanticUtil.getNestedType(type, TDEF | REF);
40
public static IType prvalueType(IType type) {
41
return Conversions.lvalue_to_rvalue(type);
45
public static ValueCategory valueCategoryFromFunctionCall(ICPPFunction function) {
46
final ICPPFunctionType ft = function.getType();
47
return valueCategoryFromReturnType(ft.getReturnType());
50
public static ValueCategory valueCategoryFromReturnType(IType r) {
51
r= SemanticUtil.getNestedType(r, TDEF);
52
if (r instanceof ICPPReferenceType) {
53
ICPPReferenceType refType= (ICPPReferenceType) r;
54
if (!refType.isRValueReference()) {
55
return ValueCategory.LVALUE;
57
if (SemanticUtil.getNestedType(refType.getType(), TDEF | REF | CVTYPE) instanceof IFunctionType) {
58
return ValueCategory.LVALUE;
60
return ValueCategory.XVALUE;
62
return ValueCategory.PRVALUE;
65
public static IType typeFromFunctionCall(ICPPFunction function) {
66
final ICPPFunctionType ft = function.getType();
67
return typeFromReturnType(ft.getReturnType());
70
public static IType typeFromReturnType(IType r) {
71
r= SemanticUtil.getNestedType(r, TDEF);
72
if (r instanceof ICPPReferenceType) {
73
return glvalueType(r);
75
return prvalueType(r);
78
public static IType typeOrFunctionSet(IASTExpression e) {
79
FunctionSetType fs= getFunctionSetType(e);
83
return e.getExpressionType();
86
public static ValueCategory valueCat(IASTExpression e) {
87
FunctionSetType fs= getFunctionSetType(e);
89
return fs.getValueCategory();
90
return e.getValueCategory();
93
private static FunctionSetType getFunctionSetType(IASTExpression e) {
94
boolean addressOf= false;
95
while (e instanceof IASTUnaryExpression) {
96
final IASTUnaryExpression unary = (IASTUnaryExpression) e;
97
final int op= unary.getOperator();
98
if (op == IASTUnaryExpression.op_bracketedPrimary) {
99
e= unary.getOperand();
100
} else if (!addressOf && op == IASTUnaryExpression.op_amper) {
102
e= unary.getOperand();
108
if (e instanceof IASTIdExpression) {
109
IASTIdExpression idexpr= (IASTIdExpression) e;
110
final IASTName name = idexpr.getName();
111
IBinding b= name.resolvePreBinding();
112
if (b instanceof CPPFunctionSet) {
113
return new FunctionSetType(((CPPFunctionSet) b).getBindings(), name, addressOf);