Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ASTComparer.java3
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java153
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java45
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOMManager.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java48
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTExpression.java8
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTLiteralExpression.java12
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTReferenceOperator.java7
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java24
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPReferenceType.java9
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousNode.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTypeIdInitializerExpression.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTArraySubscriptExpression.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java18
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTCastExpression.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTCompoundStatementExpression.java12
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTConditionalExpression.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTExpressionList.java9
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFieldReference.java8
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFunctionCallExpression.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIdExpression.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTLiteralExpression.java6
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTProblemExpression.java7
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypeIdExpression.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTUnaryExpression.java14
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java62
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java25
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java12
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java14
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java7
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java5
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java52
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java25
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java8
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java16
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java5
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTProblemExpression.java11
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTReferenceOperator.java11
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java7
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java21
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypenameExpression.java10
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java20
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java6
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPReferenceType.java60
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java17
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java29
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java38
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVariableReadWriteFlags.java2
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java38
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java381
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java25
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java6
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java33
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java36
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java2
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/NodeContainer.java2
-rw-r--r--upc/org.eclipse.cdt.core.parser.upc/src/org/eclipse/cdt/internal/core/dom/parser/upc/ast/UPCASTKeywordExpression.java8
60 files changed, 1058 insertions, 367 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ASTComparer.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ASTComparer.java
index 6110daeb3cd..6c329290f07 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ASTComparer.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ASTComparer.java
@@ -51,7 +51,8 @@ public class ASTComparer extends Assert {
"isReference",
"isAssociatedWithLastName",
"getNestingLevel",
- "getImplicitNames"
+ "getImplicitNames",
+ "isLValue"
));
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
index cfdd619ff64..82bf53d2ca3 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
@@ -23,6 +23,7 @@ import java.util.Iterator;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.dom.ast.ASTSignatureUtil;
+import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.EScopeKind;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
@@ -7750,5 +7751,157 @@ public class AST2CPPTests extends AST2BaseTest {
final String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
}
+
+ // struct A {};
+ //
+ // void foo(const A&); // #1
+ // void foo(A&&); // #2
+ //
+ // A source_rvalue();
+ // A& source_ref();
+ // A&& source_rvalue_ref();
+ //
+ // const A source_const_rvalue();
+ // const A& source_const_ref();
+ // const A&& source_const_rvalue_ref();
+ //
+ // int main() {
+ // A a;
+ // A& ra = a;
+ // A&& rra = a;
+ // const A ca;
+ // const A& rca = ca;
+ // const A&& rrca = ca;
+ //
+ // foo(a); // #1
+ // foo(ra); // #1
+ // foo(rra); // #1
+ // foo(ca); // #1
+ // foo(rca); // #1
+ // foo(rrca); // #1
+ // foo(source_rvalue()); // #2
+ // foo(source_ref()); // #1
+ // foo(source_rvalue_ref()); // #2
+ // foo(source_const_rvalue()); // #1
+ // foo(source_const_ref()); // #1
+ // foo(source_const_rvalue_ref()); // #1
+ // }
+ public void testRValueReference_294730() throws Exception {
+ final String code= getAboveComment();
+ BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
+ IBinding foo1= bh.assertNonProblem("foo(const A&)", 3);
+ IBinding foo2= bh.assertNonProblem("foo(A&&)", 3);
+ IBinding b;
+ b= bh.assertNonProblem("foo(a)", 3);
+ assertSame(b, foo1);
+ b= bh.assertNonProblem("foo(ra)", 3);
+ assertSame(b, foo1);
+ b= bh.assertNonProblem("foo(rra)", 3);
+ assertSame(b, foo1);
+ b= bh.assertNonProblem("foo(ca)", 3);
+ assertSame(b, foo1);
+ b= bh.assertNonProblem("foo(rca)", 3);
+ assertSame(b, foo1);
+ b= bh.assertNonProblem("foo(rrca)", 3);
+ assertSame(b, foo1);
+ b= bh.assertNonProblem("foo(source_rvalue())", 3);
+ assertSame(b, foo2);
+ b= bh.assertNonProblem("foo(source_ref())", 3);
+ assertSame(b, foo1);
+ b= bh.assertNonProblem("foo(source_rvalue_ref())", 3);
+ assertSame(b, foo2);
+ b= bh.assertNonProblem("foo(source_const_rvalue())", 3);
+ assertSame(b, foo1);
+ b= bh.assertNonProblem("foo(source_const_ref())", 3);
+ assertSame(b, foo1);
+ b= bh.assertNonProblem("foo(source_const_rvalue_ref())", 3);
+ assertSame(b, foo1);
+ }
+
+
+ // int i;
+ // typedef int& LRI;
+ // typedef int&& RRI;
+ // LRI& r1 = i; // r1 has the type int&
+ // const LRI& r2 = i; // r2 has the type int&
+ // const LRI&& r3 = i; // r3 has the type int&
+ // RRI& r4 = i; // r4 has the type int&
+ // RRI&& r5 = i; // r5 has the type int&&
+ public void testRValueReferenceTypedefs_294730() throws Exception {
+ final String code= getAboveComment();
+ BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
+ IVariable v;
+ v= bh.assertNonProblem("r1", 2);
+ assertEquals("int &", ASTTypeUtil.getType(v.getType()));
+ v= bh.assertNonProblem("r2", 2);
+ assertEquals("int &", ASTTypeUtil.getType(v.getType()));
+ v= bh.assertNonProblem("r3", 2);
+ assertEquals("int &", ASTTypeUtil.getType(v.getType()));
+ v= bh.assertNonProblem("r4", 2);
+ assertEquals("int &", ASTTypeUtil.getType(v.getType()));
+ v= bh.assertNonProblem("r5", 2);
+ assertEquals("int &&", ASTTypeUtil.getType(v.getType()));
+ }
+
+ // void dref(double&);
+ // void drref(double&&);
+ // void cdref(const double&);
+ // struct A { };
+ // struct B : A { };
+ // extern B f();
+ // struct X {
+ // operator B();
+ // } x;
+ // void aref(A&);
+ // void caref(const A&);
+ // void carref(const A&&);
+ // void test() {
+ // B b;
+ // double d = 2.0;
+ // const volatile double cvd = 1;
+ // int i = 2;
+ // dref(d);
+ // cdref(d);
+ // aref(b);
+ // caref(b);
+ // dref(2.0); // error: not an lvalue and reference not const
+ // dref(i); // error: type mismatch and reference not const
+ // drref(i); // error: rvalue reference cannot bind to lvalue
+ // caref(f()); // bound to the A subobject of the B rvalue.
+ // carref(f()); // same as above
+ // caref(x); // bound to the A subobject of the result of the conversion
+ // cdref(2); // rcd2 refers to temporary with value 2.0
+ // drref(2); // rcd3 refers to temporary with value 2.0
+ // cdref(cvd); // error: type qualifiers dropped
+ // }
+ public void testDirectBinding_294730() throws Exception {
+ final String code= getAboveComment();
+ BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
+ bh.assertNonProblem("dref(d)", 4);
+ bh.assertNonProblem("cdref(d)", 5);
+ bh.assertNonProblem("aref(b)", 4);
+ bh.assertNonProblem("caref(b)", 5);
+ bh.assertProblem("dref(2.0)", 4);
+ bh.assertProblem("dref(i)", 4);
+ bh.assertProblem("drref(i)", 5);
+ bh.assertNonProblem("caref(f())", 5);
+ bh.assertNonProblem("carref(f())", 6);
+ bh.assertNonProblem("caref(x)", 5);
+ bh.assertNonProblem("cdref(2)", 5);
+ bh.assertNonProblem("drref(2)", 5);
+ bh.assertProblem("cdref(cvd)", 5);
+ }
+
+ // struct S {
+ // operator int() {return 0;}
+ // };
+ // S s(){return *new S();}
+ // void test(int) {
+ // test(s());
+ // }
+ public void testSpecialRuleForImplicitObjectType_294730() throws Exception {
+ final String code= getAboveComment();
+ parseAndCheckBindings(code, ParserLanguage.CPP);
+ }
}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
index fba9cb3f342..1daabe62459 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
@@ -4296,8 +4296,51 @@ public class AST2TemplateTests extends AST2BaseTest {
// int a=1;
// a OPASSIGN(>>) 1;
// }
- public void testTokenPasteShiftROperaotr_261268() throws Exception {
+ public void testTokenPasteShiftROperator_261268() throws Exception {
final String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
}
+
+ // template <class T> class X {
+ // void f(const T&);
+ // void g(T&&);
+ // };
+ // X<int&> x1; // X<int&>::f has the parameter type int&
+ // // X<int&>::g has the parameter type int&
+ // X<const int&&> x2; // X<const int&&>::f has the parameter type const int&
+ // // X<const int&&>::g has the parameter type const int&&
+ public void testRValueReferences_1_294730() throws Exception {
+ final String code= getAboveComment();
+ parseAndCheckBindings(code, ParserLanguage.CPP);
+ BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
+
+ ICPPClassType type= bh.assertNonProblem("X<int&>", 7);
+ ICPPMethod[] ms= type.getMethods();
+ int i= ms[0].getName().equals("f") ? 0 : 1;
+ ICPPMethod m= ms[i];
+ assertEquals("int &", ASTTypeUtil.getType(m.getType().getParameterTypes()[0]));
+ m= ms[1-i];
+ assertEquals("int &", ASTTypeUtil.getType(m.getType().getParameterTypes()[0]));
+
+ type= bh.assertNonProblem("X<const int&&>", 14);
+ ms= type.getMethods();
+ i= ms[0].getName().equals("f") ? 0 : 1;
+ m= ms[i];
+ assertEquals("const int &", ASTTypeUtil.getType(m.getType().getParameterTypes()[0]));
+ m= ms[1-i];
+ assertEquals("const int &&", ASTTypeUtil.getType(m.getType().getParameterTypes()[0]));
+ }
+
+ // template<typename T> int f(T&&);
+ // void test() {
+ // int i;
+ // int j = f(i); // calls f<int&>(i)
+ // }
+ public void testRValueReferences_2_294730() throws Exception {
+ final String code= getAboveComment();
+ parseAndCheckBindings(code, ParserLanguage.CPP);
+ BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
+ ICPPTemplateInstance inst= bh.assertNonProblem("f(i)", 1);
+ assertEquals("<int &>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true));
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOMManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOMManager.java
index 4faa8648790..874147d85d0 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOMManager.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOMManager.java
@@ -9,7 +9,6 @@
* Doug Schaefer (QNX) - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
-
package org.eclipse.cdt.core.dom;
import org.eclipse.cdt.core.model.ICProject;
@@ -23,8 +22,9 @@ public interface IPDOMManager {
public static final String ID_NO_INDEXER= "org.eclipse.cdt.core.nullindexer"; //$NON-NLS-1$
public static final String ID_FAST_INDEXER= "org.eclipse.cdt.core.fastIndexer"; //$NON-NLS-1$
/**
- * @deprecated, the full indexer has been removed.
+ * @deprecated The full indexer has been removed.
*/
+ @Deprecated
public static final String ID_FULL_INDEXER= "org.eclipse.cdt.core.domsourceindexer"; //$NON-NLS-1$
// Getting and setting indexer Ids
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java
index 8083c669eb7..d2bfdbf569f 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java
@@ -350,7 +350,11 @@ public class ASTTypeUtil {
result.append(getArgumentListString(inst.getTemplateArguments(), normalize));
}
} else if (type instanceof ICPPReferenceType) {
- result.append(Keywords.cpAMPER);
+ if (((ICPPReferenceType) type).isRValueReference()) {
+ result.append(Keywords.cpAND);
+ } else {
+ result.append(Keywords.cpAMPER);
+ }
} else if (type instanceof IEnumeration) {
result.append(Keywords.ENUM);
result.append(SPACE);
@@ -451,6 +455,7 @@ public class ASTTypeUtil {
// push all of the types onto the stack
int i = 0;
IQualifierType cvq= null;
+ ICPPReferenceType ref= null;
while (type != null && ++i < 100) {
if (!normalize) {
types = (IType[]) ArrayUtil.append(IType.class, types, type);
@@ -461,19 +466,38 @@ public class ASTTypeUtil {
if (type instanceof ITypedef) {
// skip it
} else {
- if (cvq != null) {
- if (type instanceof IQualifierType || type instanceof IPointerType) {
- type= SemanticUtil.addQualifiers(type, cvq.isConst(), cvq.isVolatile());
- cvq= null;
- } else {
- types = (IType[]) ArrayUtil.append(IType.class, types, cvq);
+ if (type instanceof ICPPReferenceType) {
+ // reference types ignore cv-qualifiers
+ cvq=null;
+ // lvalue references win over rvalue references
+ if (ref == null || ref.isRValueReference()) {
+ // delay reference to see if there are more
+ ref= (ICPPReferenceType) type;
}
- }
- if (type instanceof IQualifierType) {
- cvq= (IQualifierType) type;
} else {
- types = (IType[]) ArrayUtil.append(IType.class, types, type);
- }
+ if (cvq != null) {
+ // merge cv qualifiers
+ if (type instanceof IQualifierType || type instanceof IPointerType) {
+ type= SemanticUtil.addQualifiers(type, cvq.isConst(), cvq.isVolatile());
+ cvq= null;
+ }
+ }
+ if (type instanceof IQualifierType) {
+ // delay cv qualifier to merge it with others
+ cvq= (IQualifierType) type;
+ } else {
+ // no reference, no cv qualifier: output reference and cv-qualifier
+ if (ref != null) {
+ types = (IType[]) ArrayUtil.append(IType.class, types, ref);
+ ref= null;
+ }
+ if (cvq != null) {
+ types = (IType[]) ArrayUtil.append(IType.class, types, cvq);
+ cvq= null;
+ }
+ types = (IType[]) ArrayUtil.append(IType.class, types, type);
+ }
+ }
}
}
if (type instanceof ITypeContainer) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTExpression.java
index 6939a0d6207..973e23d65ef 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTExpression.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Doug Schaefer (IBM) - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
@@ -25,6 +26,13 @@ public interface IASTExpression extends IASTNode {
public IType getExpressionType();
/**
+ * Returns whether this expression is an lvalue. LValues are for instance required on the
+ * left hand side of an assignment expression.
+ * @since 5.2
+ */
+ public boolean isLValue();
+
+ /**
* @since 5.1
*/
public IASTExpression copy();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTLiteralExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTLiteralExpression.java
index 9e74aba10b0..3d40d9391d6 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTLiteralExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTLiteralExpression.java
@@ -91,15 +91,15 @@ public interface IASTLiteralExpression extends IASTExpression {
* @since 5.1
*/
public void setValue(char[] value);
-
+
/**
- * @deprecated, use {@link #setValue(char[])}, instead.
+ * @since 5.1
*/
- public void setValue(String value);
+ public IASTLiteralExpression copy();
/**
- * @since 5.1
+ * @deprecated Replaced by {@link #setValue(char[])}.
*/
- public IASTLiteralExpression copy();
-
+ @Deprecated
+ public void setValue(String value);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTReferenceOperator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTReferenceOperator.java
index cc888c778a3..04e1b73eeb3 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTReferenceOperator.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTReferenceOperator.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Doug Schaefer (IBM) - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
@@ -21,6 +22,12 @@ import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
public interface ICPPASTReferenceOperator extends IASTPointerOperator {
/**
+ * Returns whether the operator denotes a rvalue reference (e.g. <code>int &&</code>).
+ * @since 5.2
+ */
+ public boolean isRValueReference();
+
+ /**
* @since 5.1
*/
public ICPPASTReferenceOperator copy();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java
index 694ec43a854..c5156e87e45 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java
@@ -40,12 +40,6 @@ import org.eclipse.cdt.core.parser.IScanner;
public interface ICPPNodeFactory extends INodeFactory {
/**
- * @deprecated use {@link #newTranslationUnit(IScanner)}, instead.
- */
- @Deprecated
- public ICPPASTTranslationUnit newTranslationUnit();
-
- /**
* Creates a new translation unit that cooperates with the given scanner in order
* to track macro-expansions and location information.
* @scanner the preprocessor the translation unit interacts with.
@@ -152,8 +146,12 @@ public interface ICPPNodeFactory extends INodeFactory {
public IGPPASTPointer newPointerGPP();
- public ICPPASTReferenceOperator newReferenceOperator();
-
+ /**
+ * Creates an lvalue or rvalue reference operator.
+ * @since 5.2
+ */
+ public ICPPASTReferenceOperator newReferenceOperator(boolean isRValueReference);
+
public ICPPASTPointerToMember newPointerToMember(IASTName name);
public IGPPASTPointerToMember newPointerToMemberGPP(IASTName name);
@@ -183,4 +181,14 @@ public interface ICPPNodeFactory extends INodeFactory {
*/
public ICPPASTStaticAssertDeclaration newStaticAssertion(IASTExpression condition, ICPPASTLiteralExpression message);
+
+ /**
+ * @deprecated Replaced by {@link #newReferenceOperator(boolean)}.
+ */
+ @Deprecated public ICPPASTReferenceOperator newReferenceOperator();
+ /**
+ * @deprecated Replaced by {@link #newTranslationUnit(IScanner)}.
+ */
+ @Deprecated
+ public ICPPASTTranslationUnit newTranslationUnit();
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPReferenceType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPReferenceType.java
index 195d32317db..5d4d7b4f06f 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPReferenceType.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPReferenceType.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Andrew Niefer (IBM Corporation) - initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
@@ -19,7 +20,13 @@ import org.eclipse.cdt.core.dom.ast.IType;
public interface ICPPReferenceType extends IType {
/**
- * get the type that this is a reference of
+ * Returns the type that this is a reference of
*/
public IType getType();
+
+ /**
+ * Returns whether this is an rvalue reference (e.g: int&&)
+ * @since 5.2
+ */
+ public boolean isRValueReference();
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousNode.java
index 33dc8795757..c464d37cac5 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousNode.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousNode.java
@@ -133,4 +133,8 @@ public abstract class ASTAmbiguousNode extends ASTNode {
afterResolution(resolver, bestAlternative);
return bestAlternative;
}
+
+ public boolean isLValue() {
+ return false;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTypeIdInitializerExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTypeIdInitializerExpression.java
index 22f19c5f277..8d3141854ca 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTypeIdInitializerExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTypeIdInitializerExpression.java
@@ -86,4 +86,8 @@ public abstract class ASTTypeIdInitializerExpression extends ASTNode implements
}
return true;
}
+
+ public boolean isLValue() {
+ return false;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
index 0211c0fe93c..2b725d9a2bf 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
@@ -1152,6 +1152,10 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
public IType getExpressionType() {
throw new UnsupportedOperationException();
}
+
+ public boolean isLValue() {
+ throw new UnsupportedOperationException();
+ }
}
protected final IASTExpression castExpression(CastExprCtx ctx) throws EndOfFileException, BacktrackException {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTArraySubscriptExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTArraySubscriptExpression.java
index 83bdceacf17..420e0188cb8 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTArraySubscriptExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTArraySubscriptExpression.java
@@ -120,4 +120,8 @@ public class CASTArraySubscriptExpression extends ASTNode implements
return ((IArrayType)t).getType();
return t;
}
+
+ public boolean isLValue() {
+ return true;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java
index 631430e0466..8d926304649 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java
@@ -161,4 +161,22 @@ public class CASTBinaryExpression extends ASTNode implements
}
return t1;
}
+
+ public boolean isLValue() {
+ switch (getOperator()) {
+ case op_assign:
+ case op_binaryAndAssign:
+ case op_binaryOrAssign:
+ case op_binaryXorAssign:
+ case op_divideAssign:
+ case op_minusAssign:
+ case op_moduloAssign:
+ case op_multiplyAssign:
+ case op_plusAssign:
+ case op_shiftLeftAssign:
+ case op_shiftRightAssign:
+ return true;
+ }
+ return false;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTCastExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTCastExpression.java
index 703c4581c7d..a75801117ec 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTCastExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTCastExpression.java
@@ -121,4 +121,8 @@ public class CASTCastExpression extends ASTNode implements IASTCastExpression, I
IASTTypeId id= getTypeId();
return CVisitor.createType(id.getAbstractDeclarator());
}
+
+ public boolean isLValue() {
+ return false;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTCompoundStatementExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTCompoundStatementExpression.java
index 40d571db67c..77101763296 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTCompoundStatementExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTCompoundStatementExpression.java
@@ -85,5 +85,15 @@ public class CASTCompoundStatementExpression extends ASTNode implements IGNUASTC
}
return null;
}
-
+
+ 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;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTConditionalExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTConditionalExpression.java
index 947c2760b1d..2851a25c383 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTConditionalExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTConditionalExpression.java
@@ -144,4 +144,8 @@ public class CASTConditionalExpression extends ASTNode implements
return t3;
return t2;
}
+
+ public boolean isLValue() {
+ return false;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTExpressionList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTExpressionList.java
index 12b74310527..7e49e7f6f0a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTExpressionList.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTExpressionList.java
@@ -102,4 +102,13 @@ public class CASTExpressionList extends ASTNode implements IASTExpressionList,
}
return null;
}
+
+ public boolean isLValue() {
+ for (int i = expressions.length-1; i >= 0; i--) {
+ IASTExpression expr= expressions[i];
+ if (expr != null)
+ return expr.isLValue();
+ }
+ return false;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFieldReference.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFieldReference.java
index 6bdc76298a9..cc33582510e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFieldReference.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFieldReference.java
@@ -144,6 +144,14 @@ public class CASTFieldReference extends ASTNode implements IASTFieldReference, I
return null;
}
+
+ public boolean isLValue() {
+ if (isPointerDereference())
+ return true;
+
+ return getFieldOwner().isLValue();
+ }
+
public IBinding[] findBindings(IASTName n, boolean isPrefix) {
return CVisitor.findBindingsForContentAssist(n, isPrefix);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFunctionCallExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFunctionCallExpression.java
index 95a8586e1a4..dc94acc2313 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFunctionCallExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFunctionCallExpression.java
@@ -120,4 +120,8 @@ public class CASTFunctionCallExpression extends ASTNode implements
return ((IFunctionType) type).getReturnType();
return null;
}
+
+ public boolean isLValue() {
+ return false;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIdExpression.java
index 35de0e98c54..67927aad6e7 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIdExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIdExpression.java
@@ -111,6 +111,10 @@ public class CASTIdExpression extends ASTNode implements IASTIdExpression, IASTC
return null;
}
+ public boolean isLValue() {
+ return true;
+ }
+
public IBinding[] findBindings(IASTName n, boolean isPrefix) {
IBinding[] bindings = CVisitor.findBindingsForContentAssist(n, isPrefix);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTLiteralExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTLiteralExpression.java
index e7f275d33b5..039be3d0497 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTLiteralExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTLiteralExpression.java
@@ -99,7 +99,11 @@ public class CASTLiteralExpression extends ASTNode implements IASTLiteralExpress
}
return null;
}
-
+
+ public boolean isLValue() {
+ return getKind() == IASTLiteralExpression.lk_string_literal;
+ }
+
private IType classifyTypeOfFloatLiteral() {
final char[] lit= getValue();
final int len= lit.length;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTProblemExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTProblemExpression.java
index ec1ba3a1b9b..de5442d8015 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTProblemExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTProblemExpression.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -59,5 +59,8 @@ public class CASTProblemExpression extends CASTProblemOwner implements IASTProbl
public IType getExpressionType() {
return null;
}
-
+
+ public boolean isLValue() {
+ return false;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypeIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypeIdExpression.java
index f1791d88cb2..4f8279e42c8 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypeIdExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypeIdExpression.java
@@ -90,4 +90,8 @@ public class CASTTypeIdExpression extends ASTNode implements IASTTypeIdExpressio
}
return CVisitor.createType(typeId.getAbstractDeclarator());
}
+
+ public boolean isLValue() {
+ return false;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTUnaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTUnaryExpression.java
index ad91cb843fd..a4dc96ef3f8 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTUnaryExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTUnaryExpression.java
@@ -121,5 +121,17 @@ public class CASTUnaryExpression extends ASTNode implements IASTUnaryExpression,
}
return exprType; // return the original
}
-
+
+ public boolean isLValue() {
+ switch (getOperator()) {
+ case op_bracketedPrimary:
+ return getOperand().isLValue();
+ case op_star:
+ case op_prefixDecr:
+ case op_prefixIncr:
+ return true;
+ default:
+ return false;
+ }
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java
index 312d2ef238f..3ba0cd9bc45 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java
@@ -8,6 +8,7 @@
* Contributors:
* John Camelon (IBM) - Initial API and implementation
* Mike Kucera (IBM)
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@@ -25,15 +26,14 @@ 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.IASTAmbiguityParent;
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;
-/**
- * @author jcamelon
- */
public class CPPASTArraySubscriptExpression extends ASTNode implements ICPPASTArraySubscriptExpression, IASTAmbiguityParent {
private IASTExpression subscriptExp;
private IASTExpression arrayExpression;
+ private ICPPFunction overload= UNINITIALIZED_FUNCTION;
private IASTImplicitName[] implicitNames = null;
@@ -104,7 +104,15 @@ public class CPPASTArraySubscriptExpression extends ASTNode implements ICPPASTAr
public ICPPFunction getOverload() {
- return CPPSemantics.findOverloadedOperator(this);
+ if (overload == UNINITIALIZED_FUNCTION) {
+ overload= null;
+ IType t = getArrayExpression().getExpressionType();
+ t= SemanticUtil.getUltimateTypeUptoPointers(t);
+ if (t instanceof ICPPClassType && !(t instanceof ICPPUnknownType)) {
+ overload= CPPSemantics.findOverloadedOperator(this);
+ }
+ }
+ return overload;
}
@Override
@@ -156,28 +164,36 @@ public class CPPASTArraySubscriptExpression extends ASTNode implements ICPPASTAr
}
public IType getExpressionType() {
+ ICPPFunction op = getOverload();
+ if (op != null) {
+ try {
+ return op.getType().getReturnType();
+ } catch (DOMException e) {
+ return e.getProblem();
+ }
+ }
IType t = getArrayExpression().getExpressionType();
t= SemanticUtil.getUltimateTypeUptoPointers(t);
- try {
- if (t instanceof ICPPUnknownType) {
- return CPPUnknownClass.createUnnamedInstance();
- }
- if (t instanceof ICPPClassType) {
- ICPPFunction op = getOverload();
- if (op != null) {
- return op.getType().getReturnType();
- }
- }
- if (t instanceof IPointerType) {
- return ((IPointerType) t).getType();
- }
- if (t instanceof IArrayType) {
- return ((IArrayType) t).getType();
- }
- } catch (DOMException e) {
- return e.getProblem();
+ if (t instanceof ICPPUnknownType) {
+ return CPPUnknownClass.createUnnamedInstance();
+ }
+ if (t instanceof IPointerType) {
+ return ((IPointerType) t).getType();
+ }
+ if (t instanceof IArrayType) {
+ return ((IArrayType) t).getType();
}
return null;
}
-
+
+ public boolean isLValue() {
+ ICPPFunction op = getOverload();
+ if (op != null) {
+ try {
+ return CPPVisitor.isLValueReference(op.getType().getReturnType());
+ } catch (DOMException e) {
+ }
+ }
+ return true;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java
index 2b511f24fa5..19ae917afc9 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java
@@ -172,6 +172,31 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
return overload = CPPSemantics.findOverloadedOperator(this);
}
+ public boolean isLValue() {
+ ICPPFunction op = getOverload();
+ if (op != null) {
+ try {
+ return CPPVisitor.isLValueReference(op.getType().getReturnType());
+ } catch (DOMException e) {
+ }
+ }
+ switch (getOperator()) {
+ case op_assign:
+ case op_binaryAndAssign:
+ case op_binaryOrAssign:
+ case op_binaryXorAssign:
+ case op_divideAssign:
+ case op_minusAssign:
+ case op_moduloAssign:
+ case op_multiplyAssign:
+ case op_plusAssign:
+ case op_shiftLeftAssign:
+ case op_shiftRightAssign:
+ return true;
+ }
+ return false;
+ }
+
private IType createExpressionType() {
// Check for overloaded operator.
ICPPFunction o= getOverload();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java
index 8800f173483..f6224debc3b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java
@@ -28,6 +28,7 @@ public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpressi
private int op;
private IASTExpression operand;
private IASTTypeId typeId;
+ private IType fType;
public CPPASTCastExpression() {
}
@@ -117,6 +118,15 @@ public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpressi
}
public IType getExpressionType() {
- return CPPVisitor.createType(typeId.getAbstractDeclarator());
+ if (fType == null) {
+ fType= CPPVisitor.createType(typeId.getAbstractDeclarator());
+ }
+ return fType;
+ }
+
+ public boolean isLValue() {
+ return CPPVisitor.isLValueReference(getExpressionType());
}
+
+
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java
index 50837be602e..bd4be362270 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java
@@ -6,7 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * IBM - Initial API and implementation
+ * John Camelon (IBM) - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@@ -85,4 +86,15 @@ public class CPPASTCompoundStatementExpression extends ASTNode implements IGNUAS
}
return null;
}
+
+ 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;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java
index 0710164d351..59c90b28eb5 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java
@@ -6,7 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * IBM - Initial API and implementation
+ * John Camelon (IBM) - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@@ -144,4 +145,8 @@ public class CPPASTConditionalExpression extends ASTNode implements
return t3;
return t2;
}
+
+ public boolean isLValue() {
+ return false;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java
index 94cba9f2f75..c9f17b798ac 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java
@@ -7,6 +7,7 @@
*
* Contributors:
* John Camelon (IBM) - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@@ -151,4 +152,8 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
public IType getExpressionType() {
return CPPSemantics.VOID_TYPE;
}
+
+ public boolean isLValue() {
+ return false;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java
index c4a4d8752f0..af63b2b445d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java
@@ -8,6 +8,7 @@
* Contributors:
* John Camelon (IBM) - Initial API and implementation
* Mike Kucera (IBM) - implicit names
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@@ -24,6 +25,7 @@ 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.IASTAmbiguityParent;
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 {
@@ -172,22 +174,44 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
}
}
- public IType getExpressionType() {
- ICPPFunction[] overloads = getOverloads();
- if(overloads.length > 0) {
- ICPPFunction last = overloads[overloads.length-1];
- if(last != null) {
- try {
+ public IType getExpressionType() {
+ ICPPFunction[] overloads = getOverloads();
+ if (overloads.length > 0) {
+ ICPPFunction last = overloads[overloads.length - 1];
+ if (last != null) {
+ try {
return last.getType().getReturnType();
- } catch (DOMException e) { }
- }
- }
-
- for (int i = expressions.length-1; i >= 0 ; i--) {
- IASTExpression expr= expressions[i];
+ } catch (DOMException e) {
+ }
+ }
+ }
+
+ for (int i = expressions.length - 1; i >= 0; i--) {
+ IASTExpression expr = expressions[i];
if (expr != null)
return expr.getExpressionType();
}
- return null;
- }
+ return null;
+ }
+
+ public boolean isLValue() {
+ ICPPFunction[] overloads = getOverloads();
+ if (overloads.length > 0) {
+ ICPPFunction last = overloads[overloads.length - 1];
+ if (last != null) {
+ try {
+ return CPPVisitor.isLValueReference(last.getType().getReturnType());
+ } catch (DOMException e) {
+ return false;
+ }
+ }
+ }
+
+ for (int i = expressions.length-1; i >= 0; i--) {
+ IASTExpression expr= expressions[i];
+ if (expr != null)
+ return expr.isLValue();
+ }
+ return false;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java
index 745f878ac91..de83bb6eebb 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java
@@ -9,9 +9,12 @@
* John Camelon (IBM) - Initial API and implementation
* Bryan Wilkinson (QNX)
* Mike Kucera (IBM)
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
+import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
+
import java.util.ArrayList;
import java.util.List;
@@ -31,7 +34,9 @@ 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.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.ICPPReferenceType;
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.cpp.semantics.CPPSemantics;
@@ -205,6 +210,26 @@ public class CPPASTFieldReference extends ASTNode implements
return null;
}
+
+ public boolean isLValue() {
+ if (isPointerDereference())
+ return true;
+
+ IBinding b= getFieldName().resolveBinding();
+ try {
+ if (b instanceof ICPPMember && ((ICPPMember) b).isStatic())
+ return true;
+ if (b instanceof IVariable) {
+ if (SemanticUtil.getNestedType(((IVariable) b).getType(), TDEF) instanceof ICPPReferenceType) {
+ return true;
+ }
+ return getFieldOwner().isLValue();
+ }
+ } catch (DOMException e) {
+ }
+ return false;
+ }
+
public IBinding[] findBindings(IASTName n, boolean isPrefix) {
IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix);
List<IBinding> filtered = new ArrayList<IBinding>();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java
index f2363a81124..1fc061ced49 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java
@@ -8,6 +8,7 @@
* Contributors:
* John Camelon (IBM) - Initial API and implementation
* Mike Kucera (IBM) - implicit names
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@@ -34,6 +35,7 @@ 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.ProblemBinding;
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;
@@ -199,7 +201,11 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
return type;
}
- private IType computeExpressionType() {
+ public boolean isLValue() {
+ return CPPVisitor.isLValueReference(getExpressionType());
+ }
+
+ private IType computeExpressionType() {
overload= null;
try {
IType t= null;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java
index e1fd753713b..3eb92576c84 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java
@@ -6,8 +6,9 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * IBM - Initial API and implementation
- * Bryan Wilkinson (QNX)
+ * John Camelon (IBM) - Initial API and implementation
+ * Bryan Wilkinson (QNX)
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@@ -28,9 +29,6 @@ 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.SemanticUtil;
-/**
- * @author jcamelon
- */
public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, IASTCompletionContext {
private IASTName name;
@@ -112,6 +110,14 @@ public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, IAS
return null;
}
+ public boolean isLValue() {
+ IBinding b= getName().resolveBinding();
+ if (b instanceof IVariable || b instanceof IFunction) {
+ return true;
+ }
+ return false;
+ }
+
public IBinding[] findBindings(IASTName n, boolean isPrefix) {
return CPPSemantics.findBindingsForContentAssist(n, isPrefix);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java
index 976a55254fe..009be14f7ac 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java
@@ -12,6 +12,7 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
+import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
@@ -113,6 +114,10 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
return null;
}
+ public boolean isLValue() {
+ return getKind() == IASTLiteralExpression.lk_string_literal;
+ }
+
private IValue getStringLiteralSize() {
char[] value= getValue();
int length= value.length-1;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java
index dedb270d20c..5d8d2493a7b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java
@@ -256,4 +256,8 @@ public class CPPASTNewExpression extends ASTNode implements
}
return new CPPPointerType(t);
}
+
+ public boolean isLValue() {
+ return false;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTProblemExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTProblemExpression.java
index 774c09744a8..a0e061e4eb5 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTProblemExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTProblemExpression.java
@@ -1,12 +1,12 @@
/*******************************************************************************
- * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * IBM - Initial API and implementation
+ * John Camelon (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@@ -16,9 +16,6 @@ import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTProblemExpression;
import org.eclipse.cdt.core.dom.ast.IType;
-/**
- * @author jcamelon
- */
public class CPPASTProblemExpression extends CPPASTProblemOwner implements IASTProblemExpression {
public CPPASTProblemExpression() {
@@ -58,4 +55,8 @@ public class CPPASTProblemExpression extends CPPASTProblemOwner implements IASTP
public IType getExpressionType() {
return null;
}
+
+ public boolean isLValue() {
+ return false;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTReferenceOperator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTReferenceOperator.java
index 99676400df9..3eb09471a76 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTReferenceOperator.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTReferenceOperator.java
@@ -20,11 +20,18 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
*/
public class CPPASTReferenceOperator extends ASTNode implements ICPPASTReferenceOperator {
- public CPPASTReferenceOperator() {
+ private final boolean fIsRValue;
+
+ public CPPASTReferenceOperator(boolean isRValueReference) {
+ fIsRValue= isRValueReference;
}
+ public boolean isRValueReference() {
+ return fIsRValue;
+ }
+
public CPPASTReferenceOperator copy() {
- CPPASTReferenceOperator copy = new CPPASTReferenceOperator();
+ CPPASTReferenceOperator copy = new CPPASTReferenceOperator(fIsRValue);
copy.setOffsetAndLength(this);
return copy;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java
index 66cf4207f70..611ed09ce1a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java
@@ -19,9 +19,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
-/**
- * @author jcamelon
- */
public class CPPASTSimpleTypeConstructorExpression extends ASTNode implements
ICPPASTSimpleTypeConstructorExpression, IASTAmbiguityParent {
@@ -100,4 +97,8 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode implements
public IType getExpressionType() {
return new CPPBasicType(CPPBasicType.getKind(st), 0);
}
+
+ public boolean isLValue() {
+ return false;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java
index 6e8a6aca413..c9e661699f3 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java
@@ -6,21 +6,18 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * IBM - Initial API and implementation
+ * John Camelon (IBM) - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
-import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
-/**
- * @author jcamelon
- */
public class CPPASTTypeIdExpression extends ASTNode implements ICPPASTTypeIdExpression {
private int op;
@@ -86,11 +83,21 @@ public class CPPASTTypeIdExpression extends ASTNode implements ICPPASTTypeIdExpr
public IType getExpressionType() {
switch (getOperator()) {
- case IASTTypeIdExpression.op_sizeof:
+ case op_sizeof:
return CPPVisitor.get_SIZE_T(this);
- case IASTTypeIdExpression.op_typeid:
+ case op_typeid:
return CPPVisitor.get_type_info(this);
}
return CPPVisitor.createType(getTypeId());
}
+
+ public boolean isLValue() {
+ switch(getOperator()) {
+ case op_typeid:
+ return true;
+ }
+ return false;
+ }
+
+
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypenameExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypenameExpression.java
index c9928d34731..625464d0de3 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypenameExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypenameExpression.java
@@ -6,7 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * IBM - Initial API and implementation
+ * John Camelon (IBM) - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@@ -20,9 +21,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
-/**
- * @author jcamelon
- */
public class CPPASTTypenameExpression extends ASTNode implements
ICPPASTTypenameExpression, IASTAmbiguityParent {
@@ -135,4 +133,8 @@ public class CPPASTTypenameExpression extends ASTNode implements
}
return null;
}
+
+ public boolean isLValue() {
+ return false;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java
index e31734b02e6..0ce2d33aa31 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java
@@ -271,6 +271,26 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
return origType;
}
+ public boolean isLValue() {
+ ICPPFunction op = getOverload();
+ if (op != null) {
+ try {
+ return CPPVisitor.isLValueReference(op.getType().getReturnType());
+ } catch (DOMException e) {
+ }
+ }
+
+ switch (getOperator()) {
+ case op_bracketedPrimary:
+ return getOperand().isLValue();
+ case op_star:
+ case op_prefixDecr:
+ case op_prefixIncr:
+ return true;
+ default:
+ return false;
+ }
+ }
private IType findOperatorReturnType() {
ICPPFunction operatorFunction = getOverload();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java
index 23cc2752389..1ae7fc756a0 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java
@@ -100,7 +100,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
char[] className = name.getLookupKey();
IParameter[] voidPs = new IParameter[] { new CPPParameter(CPPSemantics.VOID_TYPE, 0) };
- IType pType = new CPPReferenceType(SemanticUtil.addQualifiers(clsType, true, false));
+ IType pType = new CPPReferenceType(SemanticUtil.addQualifiers(clsType, true, false), false);
IParameter[] ps = new IParameter[] { new CPPParameter(pType, 0) };
int i= 0;
@@ -124,7 +124,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
if (!ia.hasUserDeclaredCopyAssignmentOperator()) {
//copy assignment operator: A& operator = (const A &)
- IType refType = new CPPReferenceType(clsType);
+ IType refType = new CPPReferenceType(clsType, false);
ICPPFunctionType ft= CPPVisitor.createImplicitFunctionType(refType, ps, false, false);
ICPPMethod m = new CPPImplicitMethod(this, OverloadableOperator.ASSIGN.toCharArray(), ft, ps);
implicits[i++] = m;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java
index 71990c1ecab..fd14a698f56 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java
@@ -454,7 +454,11 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
}
public ICPPASTReferenceOperator newReferenceOperator() {
- return new CPPASTReferenceOperator();
+ return new CPPASTReferenceOperator(false);
+ }
+
+ public ICPPASTReferenceOperator newReferenceOperator(boolean isRValueReference) {
+ return new CPPASTReferenceOperator(isRValueReference);
}
public ICPPASTPointerToMember newPointerToMember(IASTName name) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPReferenceType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPReferenceType.java
index 783327f5787..b9463a2fb54 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPReferenceType.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPReferenceType.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Andrew Niefer (IBM Corporation) - initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@@ -20,18 +21,29 @@ import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.core.runtime.CoreException;
public class CPPReferenceType implements ICPPReferenceType, ITypeContainer, ISerializableType {
- IType type = null;
+ private IType fType = null;
+ private boolean fIsRValue;
- public CPPReferenceType(IType type) {
- this.type = type;
+ public CPPReferenceType(IType type, boolean isRValue) {
+ fIsRValue= isRValue;
+ setType(type);
}
public IType getType() {
- return type;
+ return fType;
}
+ public boolean isRValueReference() {
+ return fIsRValue;
+ }
+
public void setType(IType t) {
- type = t;
+ if (t instanceof ICPPReferenceType) {
+ final ICPPReferenceType rt = (ICPPReferenceType) t;
+ fIsRValue = fIsRValue && rt.isRValueReference();
+ t= rt.getType();
+ }
+ fType= t;
}
public boolean isSameType(IType obj) {
@@ -40,11 +52,36 @@ public class CPPReferenceType implements ICPPReferenceType, ITypeContainer, ISer
if (obj instanceof ITypedef)
return ((ITypedef)obj).isSameType(this);
- if (type == null)
- return false;
-
if (obj instanceof ICPPReferenceType) {
- return type.isSameType(((ICPPReferenceType) obj).getType());
+ final ICPPReferenceType rhs = (ICPPReferenceType) obj;
+ IType t1= getType();
+ IType t2= rhs.getType();
+ boolean rv1= isRValueReference();
+ boolean rv2= rhs.isRValueReference();
+ for(;;) {
+ if (t1 instanceof ITypedef) {
+ t1= ((ITypedef) t1).getType();
+ } else if (t1 instanceof ICPPReferenceType) {
+ rv1= rv1 && ((ICPPReferenceType) t1).isRValueReference();
+ t1= ((ICPPReferenceType) t1).getType();
+ } else {
+ break;
+ }
+ }
+ for(;;) {
+ if (t2 instanceof ITypedef) {
+ t2= ((ITypedef) t2).getType();
+ } else if (t2 instanceof ICPPReferenceType) {
+ rv2= rv2 && ((ICPPReferenceType) t2).isRValueReference();
+ t2= ((ICPPReferenceType) t2).getType();
+ } else {
+ break;
+ }
+ }
+ if (t1 == null)
+ return false;
+
+ return rv1 == rv2 && t1.isSameType(t2);
}
return false;
}
@@ -67,12 +104,15 @@ public class CPPReferenceType implements ICPPReferenceType, ITypeContainer, ISer
public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
int firstByte= ITypeMarshalBuffer.REFERENCE;
+ if (isRValueReference()) {
+ firstByte |= ITypeMarshalBuffer.FLAG1;
+ }
buffer.putByte((byte) firstByte);
buffer.marshalType(getType());
}
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
IType nested= buffer.unmarshalType();
- return new CPPReferenceType(nested);
+ return new CPPReferenceType(nested, (firstByte & ITypeMarshalBuffer.FLAG1) != 0);
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
index ff50c2c4dab..e05a14bc0bc 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
@@ -2947,17 +2947,16 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
// __attribute__ in-between pointers
__attribute_decl_seq(supportAttributeSpecifiers, false);
- if (LT(1) == IToken.tAMPER) {
-// boolean isRestrict= false;
- IToken lastToken= consume();
- final int from= lastToken.getOffset();
+ final int lt1 = LT(1);
+ if (lt1 == IToken.tAMPER || lt1 == IToken.tAND) {
+ IToken endToken= consume();
+ final int offset= endToken.getOffset();
+
if (allowCPPRestrict && LT(1) == IToken.t_restrict) {
-// isRestrict= true;
- lastToken= consume();
+ endToken= consume();
}
- ICPPASTReferenceOperator refOp = nodeFactory.newReferenceOperator();
- ((ASTNode) refOp).setOffsetAndLength(from, lastToken.getEndOffset()-from);
- collection.add(refOp);
+ ICPPASTReferenceOperator refOp = nodeFactory.newReferenceOperator(lt1 == IToken.tAND);
+ collection.add(setRange(refOp, offset, endToken.getEndOffset()));
return;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
index d0a9b9561da..5135dfbae12 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
@@ -18,6 +18,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
import java.util.ArrayList;
+import java.util.BitSet;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@@ -1799,7 +1800,7 @@ public class CPPSemantics {
return !b1FromIndex ? 1 : -1;
} else if (b1FromIndex) {
// Both are from index.
- if (data.tu != null) {
+ if (data != null && data.tu != null) {
boolean b1Reachable= isReachableFromAst(data.tu, b1);
boolean b2Reachable= isReachableFromAst(data.tu, b2);
if (b1Reachable != b2Reachable) {
@@ -2047,7 +2048,7 @@ public class CPPSemantics {
}
if (!data.forFunctionDeclaration() || data.forExplicitFunctionSpecialization()) {
- CPPTemplates.instantiateFunctionTemplates(fns, data.getFunctionArgumentTypes(), data.astName);
+ CPPTemplates.instantiateFunctionTemplates(fns, data.getFunctionArgumentTypes(), data.getFunctionArgumentLValues(), data.astName);
}
// Reduce our set of candidate functions to only those who have the right number of parameters
@@ -2069,7 +2070,6 @@ public class CPPSemantics {
return firstViable;
// The arguments the function is being called with
- final IASTExpression[] args= data.getFunctionArguments();
IType[] argTypes = data.getFunctionArgumentTypes();
if (CPPTemplates.containsDependentType(argTypes)) {
if (viableCount == 1)
@@ -2086,7 +2086,7 @@ public class CPPSemantics {
if (fn == null)
continue;
- final FunctionCost fnCost= costForFunctionCall(fn, argTypes, args, allowUDC, data);
+ final FunctionCost fnCost= costForFunctionCall(fn, allowUDC, data);
if (fnCost == null)
continue;
@@ -2137,8 +2137,10 @@ public class CPPSemantics {
return bestFnCost.getFunction();
}
- private static FunctionCost costForFunctionCall(IFunction fn, IType[] argTypes, IASTExpression[] args,
- boolean allowUDC, LookupData data) throws DOMException {
+ private static FunctionCost costForFunctionCall(IFunction fn, boolean allowUDC, LookupData data)
+ throws DOMException {
+ IType[] argTypes = data.getFunctionArgumentTypes();
+ BitSet isLValue= data.getFunctionArgumentLValues();
final ICPPFunctionType ftype= (ICPPFunctionType) fn.getType();
if (ftype == null)
return null;
@@ -2149,9 +2151,7 @@ public class CPPSemantics {
implicitType = getImplicitType((ICPPMethod) fn, ftype.isConst(), ftype.isVolatile());
if (data.firstArgIsImpliedMethodArg) {
argTypes = ArrayUtil.removeFirst(argTypes);
- if (args != null) {
- args = ArrayUtil.removeFirst(args);
- }
+ isLValue = isLValue.get(1, isLValue.size());
}
}
@@ -2175,7 +2175,7 @@ public class CPPSemantics {
} else if (thisType.isSameType(implicitType)) {
cost = new Cost(thisType, implicitType, Rank.IDENTITY);
} else {
- cost = Conversions.checkImplicitConversionSequence(sourceIsLValue, thisType, implicitType, UDCMode.noUDC, true);
+ cost = Conversions.checkImplicitConversionSequence(implicitType, thisType, sourceIsLValue, UDCMode.noUDC, true);
if (cost.getRank() == Rank.NO_MATCH) {
if (CPPTemplates.isDependentType(implicitType) || CPPTemplates.isDependentType(thisType)) {
IType s= getNestedType(thisType, TDEF|REF|CVTYPE);
@@ -2195,12 +2195,11 @@ public class CPPSemantics {
final UDCMode udc = allowUDC ? UDCMode.deferUDC : UDCMode.noUDC;
for (int j = 0; j < sourceLen; j++) {
- final IType argType= argTypes[j];
+ final IType argType= SemanticUtil.getNestedType(argTypes[j], TDEF | REF);
if (argType == null)
return null;
- final IASTExpression arg= args != null && j < args.length ? args[j] : null;
- final boolean sourceIsLValue = arg != null && !CPPVisitor.isRValue(arg);
+ final boolean sourceIsLValue = isLValue.get(j);
IType paramType;
if (j < paramTypes.length) {
@@ -2218,7 +2217,7 @@ public class CPPSemantics {
} else {
if (CPPTemplates.isDependentType(paramType))
return CONTAINS_DEPENDENT_TYPES;
- cost = Conversions.checkImplicitConversionSequence(sourceIsLValue, argType, paramType, udc, false);
+ cost = Conversions.checkImplicitConversionSequence(paramType, argType, sourceIsLValue, udc, false);
}
if (cost.getRank() == Rank.NO_MATCH)
return null;
@@ -2236,7 +2235,7 @@ public class CPPSemantics {
owner= CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) owner);
}
implicitType= SemanticUtil.addQualifiers(owner, isConst, isVolatile);
- implicitType= new CPPReferenceType(implicitType);
+ implicitType= new CPPReferenceType(implicitType, false);
return implicitType;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
index d659b80e527..dd0bd9c3224 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
@@ -13,11 +13,10 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
-import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ALLCVQ;
-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.TDEF;
+import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
import java.util.ArrayList;
+import java.util.BitSet;
import java.util.Collections;
import java.util.List;
@@ -122,6 +121,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodTemplateSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateDefinition;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeParameter;
@@ -634,7 +634,7 @@ public class CPPTemplates {
* 14.8.2.1
*/
static private ICPPTemplateArgument[] deduceTemplateFunctionArguments(ICPPFunctionTemplate template,
- ICPPTemplateArgument[] tmplArgs, IType[] fnArgs, CPPTemplateParameterMap map) throws DOMException {
+ ICPPTemplateArgument[] tmplArgs, IType[] fnArgs, BitSet argIsLValue, CPPTemplateParameterMap map) throws DOMException {
final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters();
final int length = tmplParams.length;
if (tmplArgs.length > length)
@@ -654,7 +654,7 @@ public class CPPTemplates {
result[i]= tmplArg;
}
- if (!deduceTemplateParameterMapFromFunctionParameters(template, fnArgs, map, false))
+ if (!deduceTemplateParameterMapFromFunctionParameters(template, fnArgs, argIsLValue, map, false))
return null;
for (int i = 0; i < length; i++) {
@@ -1360,7 +1360,7 @@ public class CPPTemplates {
return result;
}
- static protected void instantiateFunctionTemplates(IFunction[] functions, IType[] fnArgs, IASTName name) {
+ static protected void instantiateFunctionTemplates(IFunction[] functions, IType[] fnArgs, BitSet argIsLValue, IASTName name) {
boolean requireTemplate= false;
if (name != null) {
if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) {
@@ -1399,7 +1399,7 @@ public class CPPTemplates {
}
CPPTemplateParameterMap map= new CPPTemplateParameterMap(fnArgs.length);
try {
- ICPPTemplateArgument[] args= deduceTemplateFunctionArguments(template, templateArguments, fnArgs, map);
+ ICPPTemplateArgument[] args= deduceTemplateFunctionArguments(template, templateArguments, fnArgs, argIsLValue, map);
if (args != null) {
IBinding instance= instantiateFunctionTemplate(template, args);
if (instance instanceof IFunction) {
@@ -1458,7 +1458,7 @@ public class CPPTemplates {
* returns <code>false</code> if there is no mapping.
*/
private static boolean deduceTemplateParameterMapFromFunctionParameters(ICPPFunctionTemplate template,
- IType[] fnArgs, CPPTemplateParameterMap map, boolean checkExactMatch) throws DOMException {
+ IType[] fnArgs, BitSet argIsLValue, CPPTemplateParameterMap map, boolean checkExactMatch) throws DOMException {
try {
IType[] fnPars = template.getType().getParameterTypes();
if (fnPars.length == 0)
@@ -1478,12 +1478,24 @@ public class CPPTemplates {
IType par= instPars[j];
boolean isDependentPar= isDependentType(par);
if (checkExactMatch || isDependentPar) {
+ boolean isReferenceTypeParameter= false;
+ IType arg = fnArgs[j];
par= SemanticUtil.getNestedType(par, SemanticUtil.TDEF); // adjustParameterType preserves typedefs
// 14.8.2.1-2
- final boolean isReferenceTypeParameter = par instanceof ICPPReferenceType;
- IType arg= getArgumentTypeForDeduction(fnArgs[j], isReferenceTypeParameter);
- if (isReferenceTypeParameter)
+ if (par instanceof ICPPReferenceType) {
+ // If P is an rvalue reference to a cv-unqualified template parameter and the argument is an
+ // lvalue, the type A& “lvalue reference to A” is used in place of A for type deduction.
+ isReferenceTypeParameter= true;
+ final ICPPReferenceType refPar = (ICPPReferenceType) par;
+ if (refPar.isRValueReference() && refPar.getType() instanceof ICPPTemplateParameter && argIsLValue.get(j)) {
+ arg= new CPPReferenceType(getSimplifiedType(arg), false);
+ } else {
+ arg= getArgumentTypeForDeduction(arg, true);
+ }
par= SemanticUtil.getNestedType(par, SemanticUtil.REF | SemanticUtil.TDEF);
+ } else {
+ arg= getArgumentTypeForDeduction(arg, false);
+ }
if (!checkExactMatch) {
// 14.8.2.1-3
@@ -1841,7 +1853,7 @@ public class CPPTemplates {
CPPTemplateParameterMap map= new CPPTemplateParameterMap(2);
final IType[] transferredParameterTypes = ((ICPPFunction) transferredTemplate).getType().getParameterTypes();
- if (!deduceTemplateParameterMapFromFunctionParameters(f2, transferredParameterTypes, map, true))
+ if (!deduceTemplateParameterMapFromFunctionParameters(f2, transferredParameterTypes, new BitSet(), map, true))
return false;
final ICPPTemplateParameter[] tmplParams = f2.getTemplateParameters();
@@ -2078,7 +2090,7 @@ public class CPPTemplates {
} else if (paramType instanceof IArrayType) {
paramType = new CPPPointerType(((IArrayType) paramType).getType());
}
- Cost cost = Conversions.checkImplicitConversionSequence(true, arg, paramType, UDCMode.noUDC, false);
+ Cost cost = Conversions.checkImplicitConversionSequence(paramType, arg, true, UDCMode.noUDC, false);
return cost != null && cost.getRank() != Rank.NO_MATCH;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVariableReadWriteFlags.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVariableReadWriteFlags.java
index 40639690116..d5425756a40 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVariableReadWriteFlags.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVariableReadWriteFlags.java
@@ -46,7 +46,7 @@ public final class CPPVariableReadWriteFlags extends VariableReadWriteFlags {
@Override
protected int rwAssignmentToType(IType type, int indirection) {
if (indirection == 0) {
- if (!(type instanceof ICPPReferenceType)) {
+ if (!(type instanceof ICPPReferenceType) || ((ICPPReferenceType) type).isRValueReference()) {
return READ;
}
type= ((ICPPReferenceType) type).getType();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
index 4274d0a8d2c..a0f33b20967 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
@@ -44,7 +44,6 @@ import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializerList;
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
-import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTNode;
@@ -1617,7 +1616,8 @@ public class CPPVisitor extends ASTQueries {
} else if (ptrOp instanceof IASTPointer) {
type = new CPPPointerType(type, (IASTPointer) ptrOp);
} else if (ptrOp instanceof ICPPASTReferenceOperator) {
- type = new CPPReferenceType(type);
+ final ICPPASTReferenceOperator refOp = (ICPPASTReferenceOperator) ptrOp;
+ type = new CPPReferenceType(type, refOp.isRValueReference());
}
}
return type;
@@ -1976,37 +1976,9 @@ public class CPPVisitor extends ASTQueries {
return false;
}
- /**
- * [3.10] Lvalues and Rvalues
- * @param exp
- * @return whether the specified expression is an rvalue
- */
- static boolean isRValue(IASTExpression exp) {
- if (exp instanceof IASTUnaryExpression) {
- IASTUnaryExpression ue= (IASTUnaryExpression) exp;
- if (ue.getOperator() == IASTUnaryExpression.op_amper) {
- return true;
- }
- }
- if (exp instanceof IASTLiteralExpression)
- return true;
- if (exp instanceof IASTFunctionCallExpression) {
- try {
- IASTFunctionCallExpression fc= (IASTFunctionCallExpression) exp;
- IASTExpression fne= fc.getFunctionNameExpression();
- if (fne instanceof IASTIdExpression) {
- IASTIdExpression ide= (IASTIdExpression) fne;
- IBinding b= ide.getName().resolveBinding();
- if (b instanceof IFunction) {
- IFunctionType tp= ((IFunction) b).getType();
- return !(tp.getReturnType() instanceof ICPPReferenceType);
- }
- }
- } catch (DOMException de) {
- // fall-through
- }
- }
- return false;
+ public static boolean isLValueReference(IType t) {
+ t= SemanticUtil.getNestedType(t, TDEF);
+ return t instanceof ICPPReferenceType && !((ICPPReferenceType) t).isRValueReference();
}
/**
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java
index 492290acb1c..f84916440a5 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java
@@ -17,7 +17,8 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CVQualifier._;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
-import org.eclipse.cdt.core.CCorePlugin;
+import java.util.BitSet;
+
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
@@ -43,7 +44,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
-import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.internal.core.dom.parser.ArithmeticConversion;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
@@ -51,126 +51,166 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank;
-import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
-import org.eclipse.core.runtime.CoreException;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.ReferenceBinding;
/**
* Routines for calculating the cost of conversions.
*/
public class Conversions {
enum UDCMode {allowUDC, noUDC, deferUDC}
-
+
+ private static final BitSet RVBITSET = new BitSet();
+ private static final BitSet LVBITSET = new BitSet();
+ static {
+ LVBITSET.set(0, true);
+ }
/**
* Computes the cost of an implicit conversion sequence
* [over.best.ics] 13.3.3.1
- * @param sourceIsLValue whether the source type is an lvalue
- * @param source the source (argument) type
* @param target the target (parameter) type
- * @param isImpliedObject
- *
+ * @param exprType the source (argument) type
+ * @param exprIsLValue whether the source type is an lvalue
+ * @param isImpliedObjectType
* @return the cost of converting from source to target
* @throws DOMException
*/
- public static Cost checkImplicitConversionSequence(boolean sourceIsLValue, IType source,
- IType target, UDCMode udc, boolean isImpliedObject) throws DOMException {
- if (isImpliedObject) {
+ public static Cost checkImplicitConversionSequence(IType target, IType exprType,
+ boolean exprIsLValue, UDCMode udc, boolean isImpliedObjectType) throws DOMException {
+ if (isImpliedObjectType) {
udc= UDCMode.noUDC;
}
target= getNestedType(target, TDEF);
- source= getNestedType(source, TDEF);
+ exprType= getNestedType(exprType, TDEF | REF);
if (target instanceof ICPPReferenceType) {
// [8.5.3-5] initialization of a reference
- IType cv1T1= getNestedType(target, TDEF | REF);
-
- if (source instanceof ICPPReferenceType) {
- sourceIsLValue= true;
- source= getNestedType(source, TDEF | REF);
+ final boolean isLValueRef= !((ICPPReferenceType) target).isRValueReference();
+ final IType cv1T1= getNestedType(target, TDEF | REF);
+ final IType T1= getNestedType(cv1T1, TDEF | REF | ALLCVQ);
+ final IType cv2T2= exprType;
+ final IType T2= getNestedType(cv2T2, TDEF | REF | ALLCVQ);
+
+ final boolean isImplicitWithoutRefQualifier = isImpliedObjectType; // mstodo need to pass this information to here
+ ReferenceBinding refBindingType= ReferenceBinding.OTHER;
+ if (!isImplicitWithoutRefQualifier) {
+ if (isLValueRef) {
+ refBindingType= ReferenceBinding.LVALUE_REF;
+ } else if (exprIsLValue) {
+ refBindingType= ReferenceBinding.RVALUE_REF_BINDS_RVALUE;
+ }
}
-
- IType T2= getNestedType(source, TDEF | REF | ALLCVQ);
- // [8.5.3-5] Is an lvalue (but is not a bit-field), and "cv1 T1" is reference-compatible with "cv2 T2,"
- if (sourceIsLValue) {
- Cost cost= isReferenceCompatible(cv1T1, source, isImpliedObject);
- if (cost != null) {
- // [8.5.3-5] this is a direct reference binding
- // [13.3.3.1.4-1] direct binding has either identity or conversion rank.
- if (cost.getInheritanceDistance() > 0) {
- cost.setRank(Rank.CONVERSION);
- }
- return cost;
- }
- }
- if (T2 instanceof ICPPClassType && udc != UDCMode.noUDC) {
- // Or has a class type (i.e., T2 is a class type) and can be implicitly converted to
- // an lvalue of type "cv3 T3," where "cv1 T1" is reference-compatible with "cv3 T3" 92)
- // (this conversion is selected by enumerating the applicable conversion functions
- // (13.3.1.6) and choosing the best one through overload resolution (13.3)).
- ICPPMethod[] fcns= SemanticUtil.getConversionOperators((ICPPClassType) T2);
- Cost operatorCost= null;
- boolean ambiguousConversionOperator= false;
- if (fcns.length > 0 && !(fcns[0] instanceof IProblemBinding)) {
- for (final ICPPMethod op : fcns) {
- IType newSource= op.getType().getReturnType();
- if (newSource instanceof ICPPReferenceType) { // require an lvalue
- IType cvT2= getNestedType(newSource, TDEF | REF);
- Cost cost2= isReferenceCompatible(cv1T1, cvT2, false);
- if (cost2 != null) {
- int cmp= cost2.compareTo(operatorCost);
- if (cmp <= 0) {
- ambiguousConversionOperator= cmp == 0;
- operatorCost= cost2;
- operatorCost.setUserDefinedConversion(op);
- }
- }
- }
- }
+ // If the reference is an lvalue reference and ...
+ if (isLValueRef) {
+ // ... the initializer expression is an lvalue (but is not a bit field)
+ // [for overload resolution bit-fields are treated the same, error if selected as best match]
+ if (exprIsLValue) {
+ // ... and "cv1 T1" is reference-compatible with "cv2 T2"
+ Cost cost= isReferenceCompatible(cv1T1, cv2T2, isImpliedObjectType);
+ if (cost != null) {
+ // [13.3.3.1.4-1] direct binding has either identity or conversion rank.
+ if (cost.getInheritanceDistance() > 0) {
+ cost.setRank(Rank.CONVERSION);
+ }
+ cost.setReferenceBinding(refBindingType);
+ return cost;
+ }
}
-
- if (operatorCost != null && !ambiguousConversionOperator) {
- if (isImpliedObject) {
- operatorCost.setInheritanceDistance(0);
+ // ... or has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can be
+ // implicitly converted to an lvalue of type “cv3 T3,” where “cv1 T1” is reference-compatible with
+ // “cv3 T3” (this conversion is selected by enumerating the applicable conversion functions (13.3.1.6)
+ // and choosing the best one through overload resolution (13.3)),
+ if (T2 instanceof ICPPClassType && udc != UDCMode.noUDC && isReferenceRelated(T1, T2) < 0) {
+ Cost cost= conversionFuncForDirectReference(cv1T1, cv2T2, T2, true);
+ if (cost != null) {
+ cost.setReferenceBinding(refBindingType);
+ return cost;
}
- return operatorCost;
}
}
+
+ // Otherwise, the reference shall be an lvalue reference to a non-volatile const type (i.e., cv1
+ // shall be const), or the reference shall be an rvalue reference and the initializer expression
+ // shall be an rvalue.
+ boolean ok;
+ if (isLValueRef) {
+ // mstodo
+ // Special rule for implicit object type, 13.3.1-5:
+ // Even if the implicit object type is not const-qualified, an rvalue temporary can
+ // be bound to the parameter as long as in all other respects ....
+ //
+ final CVQualifier cvq = getCVQualifier(cv1T1);
+ ok = cvq == CVQualifier.c;
+ } else {
+ ok= !exprIsLValue;
+ }
+ if (!ok) {
+ return new Cost(exprType, cv1T1, Rank.NO_MATCH);
+ }
+
+ // If T1 and T2 are class types and ...
+ if (T1 instanceof ICPPClassType && T2 instanceof ICPPClassType) {
+ // ... the initializer expression is an rvalue and “cv1 T1” is reference-compatible with “cv2 T2”
+ if (!exprIsLValue) {
+ Cost cost= isReferenceCompatible(cv1T1, cv2T2, isImpliedObjectType);
+ if (cost != null) {
+ // [13.3.3.1.4-1] direct binding has either identity or conversion rank.
+ if (cost.getInheritanceDistance() > 0) {
+ cost.setRank(Rank.CONVERSION);
+ }
+ cost.setReferenceBinding(refBindingType);
+ return cost;
+ }
+ }
- // [8.5.3-5] Direct binding failed - Otherwise
- boolean cv1isConst= getCVQualifier(cv1T1) == CVQualifier.c;
- if (cv1isConst) {
- if (!sourceIsLValue && T2 instanceof ICPPClassType) {
- Cost cost= isReferenceCompatible(cv1T1, source, isImpliedObject);
- if (cost != null)
+ // or T1 is not reference-related to T2 and the initializer expression can be implicitly
+ // converted to an rvalue of type “cv3 T3” (this conversion is selected by enumerating the
+ // applicable conversion functions (13.3.1.6) and choosing the best one through overload
+ // resolution (13.3)), then the reference is bound to the initializer expression rvalue in the
+ // first case and to the object that is the result of the conversion in the second case (or,
+ // in either case, to the appropriate base class subobject of the object).
+ if (udc != UDCMode.noUDC && isReferenceRelated(T1, T2) < 0) {
+ Cost cost= conversionFuncForDirectReference(cv1T1, cv2T2, T2, false);
+ if (cost != null) {
+ cost.setReferenceBinding(refBindingType);
return cost;
+ }
}
+ }
- // 5 - Otherwise
- // 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 bound to the temporary.
+ // If the initializer expression is an rvalue, with T2 an array type, and “cv1 T1” is
+ // reference-compatible with “cv2 T2,” the reference is bound to the object represented by the
+ // rvalue (see 3.10).
+ if (!exprIsLValue && T2 instanceof IArrayType) {
+ Cost cost= isReferenceCompatible(cv1T1, cv2T2, isImpliedObjectType);
+ if (cost != null) {
+ cost.setReferenceBinding(refBindingType);
+ return cost;
+ }
+ }
- // 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.
+ // — 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
+ // 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.
- // 13.3.3.1.7 no temporary object when converting the implicit object parameter
- if (!isImpliedObject) {
- IType T1= getNestedType(cv1T1, TDEF | REF | ALLCVQ);
- boolean illformed= isReferenceRelated(T1, T2) >= 0 && compareQualifications(cv1T1, source) < 0;
-
- // We must do a non-reference initialization
- if (!illformed) {
- return nonReferenceConversion(sourceIsLValue, source, T1, udc, isImpliedObject);
+ // 13.3.3.1.7 no temporary object when converting the implicit object parameter
+ if (!isImpliedObjectType) {
+ if (isReferenceRelated(T1, T2) < 0 || compareQualifications(cv1T1, cv2T2) >= 0) {
+ Cost cost= nonReferenceConversion(exprIsLValue, cv2T2, T1, udc, false);
+ if (!isImplicitWithoutRefQualifier) {
+ cost.setReferenceBinding(isLValueRef ? ReferenceBinding.LVALUE_REF : ReferenceBinding.RVALUE_REF_BINDS_RVALUE);
}
+ return cost;
}
}
- return new Cost(source, cv1T1, Rank.NO_MATCH);
+ return new Cost(exprType, cv1T1, Rank.NO_MATCH);
}
// Non-reference binding
- IType uqsource= getNestedType(source, TDEF | REF | ALLCVQ);
+ IType uqsource= getNestedType(exprType, TDEF | REF | ALLCVQ);
IType uqtarget= getNestedType(target, TDEF | REF | ALLCVQ);
// [13.3.3.1-6] Derived to base conversion
@@ -186,13 +226,53 @@ public class Conversions {
}
}
- return nonReferenceConversion(sourceIsLValue, source, uqtarget, udc, isImpliedObject);
+ return nonReferenceConversion(exprIsLValue, exprType, uqtarget, udc, isImpliedObjectType);
+ }
+
+ /**
+ * 0x: 13.3.1.6 Initialization by conversion function for direct reference binding
+ */
+ private static Cost conversionFuncForDirectReference(final IType cv1T1, final IType cv2T2, final IType T2, boolean forLValue)
+ throws DOMException {
+ ICPPMethod[] fcns= SemanticUtil.getConversionOperators((ICPPClassType) T2);
+ Cost operatorCost= null;
+ FunctionCost bestUdcCost= null;
+ boolean ambiguousConversionOperator= false;
+ if (fcns.length > 0 && !(fcns[0] instanceof IProblemBinding)) {
+ for (final ICPPMethod op : fcns) {
+ final ICPPFunctionType ft = op.getType();
+ IType convertedType= ft.getReturnType();
+ final boolean isLValue = CPPVisitor.isLValueReference(convertedType);
+ if (isLValue == forLValue) { // require an lvalue or rvalue
+ IType implicitObjectType= CPPSemantics.getImplicitType(op, ft.isConst(), ft.isVolatile());
+ Cost udcCost= isReferenceCompatible(getNestedType(implicitObjectType, TDEF | REF), cv2T2, true); // expression type to implicit object type
+ if (udcCost != null) {
+ FunctionCost udcFuncCost= new FunctionCost(op, udcCost);
+ int cmp= udcFuncCost.compareTo(null, bestUdcCost);
+ if (cmp <= 0) {
+ Cost cost= isReferenceCompatible(cv1T1, getNestedType(convertedType, TDEF | REF), false); // converted to target
+ if (cost != null) {
+ bestUdcCost= udcFuncCost;
+ ambiguousConversionOperator= cmp == 0;
+ operatorCost= cost;
+ operatorCost.setUserDefinedConversion(op);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (operatorCost != null && !ambiguousConversionOperator) {
+ return operatorCost;
+ }
+ return null;
}
private static Cost nonReferenceConversion(boolean sourceIsLValue, IType source, IType target, UDCMode udc, boolean isImpliedObject) throws DOMException {
// [13.3.3.1-6] Subsume cv-qualifications
IType uqSource= SemanticUtil.getNestedType(source, TDEF | ALLCVQ);
- Cost cost= checkStandardConversionSequence(uqSource, target, isImpliedObject);
+ Cost cost= checkStandardConversionSequence(uqSource, sourceIsLValue, target, isImpliedObject);
if (cost.getRank() != Rank.NO_MATCH || udc == UDCMode.noUDC)
return cost;
@@ -327,10 +407,10 @@ public class Conversions {
* base conversion does not cause any costs.
* @throws DOMException
*/
- private static final Cost checkStandardConversionSequence(IType source, IType target,
+ private static final Cost checkStandardConversionSequence(IType source, boolean isLValue, IType target,
boolean isImplicitThis) throws DOMException {
final Cost cost= new Cost(source, target, Rank.IDENTITY);
- if (lvalue_to_rvalue(cost))
+ if (lvalue_to_rvalue(cost, isLValue))
return cost;
if (promotion(cost))
@@ -370,25 +450,25 @@ public class Conversions {
// 13.3.1.4 Copy initialization of class by user-defined conversion
if (t instanceof ICPPClassType) {
- Cost cost1= null;
+ FunctionCost cost1= null;
Cost cost2= null;
ICPPConstructor[] ctors= ((ICPPClassType) t).getConstructors();
- CPPTemplates.instantiateFunctionTemplates(ctors, new IType[]{source}, null);
+ CPPTemplates.instantiateFunctionTemplates(ctors, new IType[]{source}, sourceIsLValue ? LVBITSET : RVBITSET, null);
for (ICPPConstructor ctor : ctors) {
if (ctor != null && !(ctor instanceof IProblemBinding) && !ctor.isExplicit()) {
final ICPPFunctionType ft = ctor.getType();
final IType[] ptypes = ft.getParameterTypes();
- Cost c1;
+ FunctionCost c1;
if (ptypes.length == 0) {
if (ctor.takesVarArgs()) {
- c1= new Cost(source, null, Rank.ELLIPSIS_CONVERSION);
+ c1= new FunctionCost(ctor, new Cost(source, null, Rank.ELLIPSIS_CONVERSION));
} else {
continue;
}
} else {
IType ptype= ptypes[0];
- // We don't need to check the implicit conversion sequence it the type is void
+ // We don't need to check the implicit conversion sequence if the type is void
if (ptype instanceof ICPPBasicType && ((ICPPBasicType) ptype).getKind() == Kind.eVoid)
continue;
if (ptypes.length > 1) {
@@ -397,9 +477,9 @@ public class Conversions {
continue;
}
- c1= checkImplicitConversionSequence(sourceIsLValue, source, ptype, UDCMode.noUDC, false);
+ c1= new FunctionCost(ctor, checkImplicitConversionSequence(ptype, source, sourceIsLValue, UDCMode.noUDC, false));
}
- int cmp= c1.compareTo(cost1);
+ int cmp= c1.compareTo(null, cost1);
if (cmp <= 0) {
cost1= c1;
cost2= new Cost(t, t, Rank.IDENTITY);
@@ -421,25 +501,28 @@ public class Conversions {
if (dist >= 0) {
final ICPPFunctionType ft = op.getType();
IType implicitType= CPPSemantics.getImplicitType(op, ft.isConst(), ft.isVolatile());
- Cost c1= checkImplicitConversionSequence(sourceIsLValue, source, implicitType, UDCMode.noUDC, false);
- int cmp= c1.compareTo(cost1);
- if (cmp <= 0) {
- cost1= c1;
- cost2= new Cost(t, t, Rank.IDENTITY);
- if (dist > 0) {
- cost2.setInheritanceDistance(dist);
- cost2.setRank(Rank.CONVERSION);
- }
- cost2.setUserDefinedConversion(op);
- if (cmp == 0) {
- cost2.setAmbiguousUDC(true);
+ final Cost udcCost = isReferenceCompatible(getNestedType(implicitType, TDEF | REF), source, true);
+ if (udcCost != null) {
+ FunctionCost c1= new FunctionCost(op, udcCost);
+ int cmp= c1.compareTo(null, cost1);
+ if (cmp <= 0) {
+ cost1= c1;
+ cost2= new Cost(t, t, Rank.IDENTITY);
+ if (dist > 0) {
+ cost2.setInheritanceDistance(dist);
+ cost2.setRank(Rank.CONVERSION);
+ }
+ cost2.setUserDefinedConversion(op);
+ if (cmp == 0) {
+ cost2.setAmbiguousUDC(true);
+ }
}
}
}
}
}
}
- if (cost1 == null || cost1.getRank() == Rank.NO_MATCH)
+ if (cost1 == null || cost1.getCost(0).getRank() == Rank.NO_MATCH)
return null;
return cost2;
@@ -449,30 +532,35 @@ public class Conversions {
if (s instanceof ICPPClassType) {
ICPPMethod[] ops = SemanticUtil.getConversionOperators((ICPPClassType) s);
CPPTemplates.instantiateConversionTemplates(ops, target);
- Cost cost1= null;
+ FunctionCost cost1= null;
Cost cost2= null;
for (final ICPPMethod op : ops) {
if (op != null && !(op instanceof IProblemBinding)) {
final IType returnType = op.getType().getReturnType();
IType uqReturnType= getNestedType(returnType, TDEF | ALLCVQ);
- Cost c2= checkImplicitConversionSequence(false, uqReturnType, target, UDCMode.noUDC, false);
+ boolean isLValue = uqReturnType instanceof ICPPReferenceType
+ && !((ICPPReferenceType) uqReturnType).isRValueReference();
+ Cost c2= checkImplicitConversionSequence(target, uqReturnType, isLValue, UDCMode.noUDC, false);
if (c2.getRank() != Rank.NO_MATCH) {
ICPPFunctionType ftype = op.getType();
IType implicitType= CPPSemantics.getImplicitType(op, ftype.isConst(), ftype.isVolatile());
- Cost c1= checkImplicitConversionSequence(sourceIsLValue, source, implicitType, UDCMode.noUDC, false);
- int cmp= c1.compareTo(cost1);
- if (cmp <= 0) {
- cost1= c1;
- cost2= c2;
- cost2.setUserDefinedConversion(op);
- if (cmp == 0) {
- cost2.setAmbiguousUDC(true);
+ final Cost udcCost = isReferenceCompatible(getNestedType(implicitType, TDEF | REF), source, true);
+ if (udcCost != null) {
+ FunctionCost c1= new FunctionCost(op, udcCost);
+ int cmp= c1.compareTo(null, cost1);
+ if (cmp <= 0) {
+ cost1= c1;
+ cost2= c2;
+ cost2.setUserDefinedConversion(op);
+ if (cmp == 0) {
+ cost2.setAmbiguousUDC(true);
+ }
}
}
}
}
}
- if (cost1 == null || cost1.getRank() == Rank.NO_MATCH)
+ if (cost1 == null || cost1.getCost(0).getRank() == Rank.NO_MATCH)
return null;
return cost2;
@@ -511,7 +599,6 @@ public class Conversions {
return 1;
}
- tbase= getNestedType(tbase, TDEF);
if (tbase instanceof ICPPClassType) {
int n= calculateInheritanceDepth(maxdepth - 1, tbase, ancestorToFind);
if (n > 0)
@@ -531,38 +618,31 @@ public class Conversions {
* [4.2] array-to-ptr
* [4.3] function-to-ptr
*/
- private static final boolean lvalue_to_rvalue(final Cost cost) throws DOMException {
+ private static final boolean lvalue_to_rvalue(final Cost cost, boolean isLValue) throws DOMException {
// target should not be a reference here.
boolean isConverted= false;
IType target = getNestedType(cost.target, REF | TDEF);
- IType source= getNestedType(cost.source, TDEF);
+ IType source= getNestedType(cost.source, REF | TDEF);
// 4.1 lvalue to rvalue
- IType srcRValue= getNestedType(source, REF | TDEF);
- if (source instanceof ICPPReferenceType) {
+ if (isLValue) {
// 4.1 lvalue of non-function and non-array
- if (!(srcRValue instanceof IFunctionType) && !(srcRValue instanceof IArrayType)) {
+ if (!(source instanceof IFunctionType) && !(source instanceof IArrayType)) {
// 4.1 if T is a non-class type, the type of the rvalue is the cv-unqualified version of T
- IType unqualifiedSrcRValue= getNestedType(srcRValue, ALLCVQ | TDEF | REF);
+ IType unqualifiedSrcRValue= getNestedType(source, ALLCVQ | TDEF | REF);
if (unqualifiedSrcRValue instanceof ICPPClassType) {
- if (isCompleteType(unqualifiedSrcRValue)) {
- source= srcRValue;
- } else {
- // ill-formed
- cost.setRank(Rank.NO_MATCH);
- return true;
- }
+ cost.setRank(Rank.NO_MATCH);
+ return true;
} else {
source= unqualifiedSrcRValue;
}
- cost.setRank(Rank.LVALUE_TRANSFORMATION);
isConverted= true;
}
}
// 4.2 array to pointer conversion
- if (!isConverted && srcRValue instanceof IArrayType) {
- final IArrayType arrayType= (IArrayType) srcRValue;
+ if (!isConverted && source instanceof IArrayType) {
+ final IArrayType arrayType= (IArrayType) source;
if (target instanceof IPointerType) {
final IType targetPtrTgt= getNestedType(((IPointerType) target).getType(), TDEF);
@@ -579,7 +659,6 @@ public class Conversions {
if (lit.getKind() == IASTLiteralExpression.lk_string_literal) {
source= new CPPPointerType(tmp, false, false);
cost.setQualificationAdjustment(getCVQualifier(targetPtrTgt).isVolatile() ? 2 : 1);
- cost.setRank(Rank.LVALUE_TRANSFORMATION);
isConverted= true;
}
}
@@ -589,7 +668,6 @@ public class Conversions {
}
if (!isConverted && (target instanceof IPointerType || target instanceof IBasicType)) {
source = new CPPPointerType(getNestedType(arrayType.getType(), TDEF));
- cost.setRank(Rank.LVALUE_TRANSFORMATION);
isConverted= true;
}
}
@@ -597,9 +675,8 @@ public class Conversions {
// 4.3 function to pointer conversion
if (!isConverted && target instanceof IPointerType) {
final IType targetPtrTgt= getNestedType(((IPointerType) target).getType(), TDEF);
- if (targetPtrTgt instanceof IFunctionType && srcRValue instanceof IFunctionType) {
+ if (targetPtrTgt instanceof IFunctionType && source instanceof IFunctionType) {
source = new CPPPointerType(source);
- cost.setRank(Rank.LVALUE_TRANSFORMATION);
isConverted= true;
}
}
@@ -849,30 +926,4 @@ public class Conversions {
}
return false;
}
-
- /**
- * @param type
- * @return whether the specified type has an associated definition
- */
- private static final boolean isCompleteType(IType type) {
- type= getUltimateType(type, false);
- if (type instanceof ICPPTemplateInstance)
- return true;
- if (type instanceof ICPPClassType) {
- if (type instanceof IIndexFragmentBinding) {
- try {
- return ((IIndexFragmentBinding) type).hasDefinition();
- } catch (CoreException e) {
- CCorePlugin.log(e);
- }
- }
- try {
- return ((ICPPClassType) type).getCompositeScope() != null;
- } catch (DOMException e) {
- return false;
- }
- }
-
- return true;
- }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java
index e87bcaf6eb9..52b7ad002cb 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java
@@ -24,9 +24,12 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
*/
final class Cost {
enum Rank {
- IDENTITY, LVALUE_TRANSFORMATION, PROMOTION, CONVERSION, CONVERSION_PTR_BOOL,
+ IDENTITY, PROMOTION, CONVERSION, CONVERSION_PTR_BOOL,
USER_DEFINED_CONVERSION, ELLIPSIS_CONVERSION, NO_MATCH
}
+ enum ReferenceBinding {
+ RVALUE_REF_BINDS_RVALUE, LVALUE_REF, OTHER
+ }
IType source;
IType target;
@@ -38,11 +41,13 @@ final class Cost {
private int fQualificationAdjustments;
private int fInheritanceDistance;
private ICPPFunction fUserDefinedConversion;
+ private ReferenceBinding fReferenceBinding;
public Cost(IType s, IType t, Rank rank) {
source = s;
target = t;
fRank= rank;
+ fReferenceBinding= ReferenceBinding.OTHER;
}
public Rank getRank() {
@@ -53,6 +58,11 @@ final class Cost {
fRank= rank;
}
+ public void setReferenceBinding(ReferenceBinding binding) {
+ fReferenceBinding= binding;
+ }
+
+
public boolean isAmbiguousUDC() {
return fAmbiguousUDC;
}
@@ -79,9 +89,6 @@ final class Cost {
public void setQualificationAdjustment(int adjustment) {
fQualificationAdjustments= adjustment;
- if (adjustment != 0 && fRank == Rank.IDENTITY) {
- fRank= Rank.LVALUE_TRANSFORMATION;
- }
}
/**
@@ -130,13 +137,21 @@ final class Cost {
if (cmp != 0)
return cmp;
+ if (fReferenceBinding == ReferenceBinding.LVALUE_REF) {
+ if (other.fReferenceBinding == ReferenceBinding.RVALUE_REF_BINDS_RVALUE)
+ return 1;
+ } else if (fReferenceBinding == ReferenceBinding.RVALUE_REF_BINDS_RVALUE) {
+ if (other.fReferenceBinding == ReferenceBinding.LVALUE_REF)
+ return -1;
+ }
+
int qdiff= fQualificationAdjustments ^ other.fQualificationAdjustments;
if (qdiff != 0) {
if ((fQualificationAdjustments & qdiff) == 0)
return -1;
if ((other.fQualificationAdjustments & qdiff) == 0)
return 1;
- }
+ }
return 0;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java
index f789cd476ed..0121ab087a6 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java
@@ -33,6 +33,12 @@ class FunctionCost {
fSourceIsLValue= new BitSet(paramCount);
}
+ public FunctionCost(IFunction fn, Cost cost) {
+ fFunction= fn;
+ fCosts= new Cost[] {cost};
+ fSourceIsLValue= null; // no udc will be performed
+ }
+
public int getLength() {
return fCosts.length;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java
index fb802d5b36c..f5a54084b94 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java
@@ -14,6 +14,7 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
+import java.util.BitSet;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -66,6 +67,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
@@ -108,6 +110,7 @@ public class LookupData {
private Object[] functionArgs;
private IType[] functionArgTypes;
public ProblemBinding problem;
+ private BitSet functionArgLValues;
public LookupData(IASTName n) {
astName = n;
@@ -600,7 +603,7 @@ public class LookupData {
functionArgTypes= new IType[pdecls.length];
for (int i = 0; i < pdecls.length; i++) {
IASTParameterDeclaration p = pdecls[i];
- functionArgTypes[i]= CPPVisitor.createType(p.getDeclarator());
+ functionArgTypes[i]= SemanticUtil.getSimplifiedType(CPPVisitor.createType(p.getDeclarator()));
}
} else if (functionArgs instanceof IASTExpression[]) {
IASTExpression[] exprs= (IASTExpression[]) functionArgs;
@@ -608,13 +611,37 @@ public class LookupData {
for (int i = 0; i < exprs.length; i++) {
IASTExpression e = exprs[i];
IType etype= e.getExpressionType();
- functionArgTypes[i]= etype;
+ functionArgTypes[i]= SemanticUtil.getSimplifiedType(etype);
}
-
}
}
return functionArgTypes;
}
+
+ public BitSet getFunctionArgumentLValues() {
+ if (functionArgLValues == null) {
+ functionArgLValues= new BitSet();
+ IASTExpression[] args= getFunctionArguments();
+ if (args != null) {
+ for (int i = 0; i < args.length; i++) {
+ final IASTExpression arg = args[i];
+ if (arg != null) {
+ functionArgLValues.set(i, arg.isLValue());
+ }
+ }
+ } else {
+ IType[] argTypes= getFunctionArgumentTypes();
+ if (argTypes != null) {
+ for (int i = 0; i < argTypes.length; i++) {
+ IType t= argTypes[i];
+ functionArgLValues.set(i, t instanceof ICPPReferenceType && !((ICPPReferenceType) t).isRValueReference());
+ }
+ }
+ }
+ }
+ return functionArgLValues;
+ }
+
public void setFunctionArgumentTypes(IType[] paramTypes) {
functionArgTypes= paramTypes;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java
index 23b08505d01..7fbb368181e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java
@@ -275,8 +275,18 @@ public class SemanticUtil {
return type;
return replaceNestedType((ITypeContainer) atype, newNested);
}
- } else if ((options & REF) != 0 && type instanceof ICPPReferenceType) {
- t= ((ICPPReferenceType) type).getType();
+ } else if (type instanceof ICPPReferenceType) {
+ final ICPPReferenceType rt = (ICPPReferenceType) type;
+ if ((options & REF) != 0) {
+ t= rt.getType();
+ } else if (tdef) {
+ // a typedef within the reference type can influence whether the reference is lvalue or rvalue
+ IType nested= rt.getType();
+ IType newNested = getNestedType(nested, TDEF);
+ if (nested == newNested)
+ return type;
+ return replaceNestedType((ITypeContainer) rt, newNested);
+ }
}
if (t == null)
return type;
@@ -323,6 +333,28 @@ public class SemanticUtil {
}
return type;
}
+
+ static boolean isSimplified(IType type) {
+ if (type instanceof ICPPFunctionType) {
+ final ICPPFunctionType ft = (ICPPFunctionType) type;
+ if (!isSimplified(ft.getReturnType()))
+ return false;
+
+ IType[] ps = ft.getParameterTypes();
+ for (IType p : ps) {
+ if (!isSimplified(p))
+ return false;
+ }
+ return true;
+ }
+ if (type instanceof ITypedef) {
+ return false;
+ }
+ if (type instanceof ITypeContainer) {
+ return isSimplified(((ITypeContainer) type).getType());
+ }
+ return true;
+ }
public static IType replaceNestedType(ITypeContainer type, IType newNestedType) {
if (newNestedType == null)
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java
index f7cf8f1b927..55a42dee834 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java
@@ -161,7 +161,7 @@ public class CPPCompositesFactory extends AbstractCompositeFactory {
IType r= rt.getType();
IType r2= getCompositeType(r);
if (r != r2) {
- return new CPPReferenceType(r2);
+ return new CPPReferenceType(r2, rt.isRValueReference());
}
return rt;
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/NodeContainer.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/NodeContainer.java
index 7e6362201fe..01aa60e9d99 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/NodeContainer.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/NodeContainer.java
@@ -172,7 +172,7 @@ public class NodeContainer {
declarator.addPointerOperator(new CASTPointer());
break;
case CPP:
- declarator.addPointerOperator(new CPPASTReferenceOperator());
+ declarator.addPointerOperator(new CPPASTReferenceOperator(false));
break;
}
}
diff --git a/upc/org.eclipse.cdt.core.parser.upc/src/org/eclipse/cdt/internal/core/dom/parser/upc/ast/UPCASTKeywordExpression.java b/upc/org.eclipse.cdt.core.parser.upc/src/org/eclipse/cdt/internal/core/dom/parser/upc/ast/UPCASTKeywordExpression.java
index 1e3b45d7ee1..1e9a566f46a 100644
--- a/upc/org.eclipse.cdt.core.parser.upc/src/org/eclipse/cdt/internal/core/dom/parser/upc/ast/UPCASTKeywordExpression.java
+++ b/upc/org.eclipse.cdt.core.parser.upc/src/org/eclipse/cdt/internal/core/dom/parser/upc/ast/UPCASTKeywordExpression.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2008 IBM Corporation and others.
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -11,7 +11,6 @@
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.IBasicType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.upc.ast.IUPCASTKeywordExpression;
@@ -50,7 +49,10 @@ public class UPCASTKeywordExpression extends ASTNode implements IUPCASTKeywordEx
return new CBasicType(Kind.eInt, 0, this);
}
-
+ public boolean isLValue() {
+ return false;
+ }
+
@Override
public boolean accept(ASTVisitor visitor) {
if(visitor.shouldVisitExpressions) {

Back to the top