mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-09-10 12:03:16 +02:00
Fixes bugs 269365, 268534, and 266211. Fixed overload resolution for operator functions and also fixed expression lists.
This commit is contained in:
parent
2d935d7b6e
commit
6045ee4478
14 changed files with 522 additions and 430 deletions
|
@ -67,13 +67,30 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
||||||
// }
|
// }
|
||||||
public void testBinaryExpressions() throws Exception {
|
public void testBinaryExpressions() throws Exception {
|
||||||
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
ba.assertImplicitName("+= 5", 2, ICPPMethod.class);
|
IASTTranslationUnit tu = ba.getTranslationUnit();
|
||||||
ba.assertImplicitName("+ p", 1, ICPPMethod.class);
|
CPPNameCollector col = new CPPNameCollector();
|
||||||
ba.assertImplicitName("- p", 1, ICPPMethod.class);
|
tu.accept(col);
|
||||||
ba.assertImplicitName("* p", 1, ICPPFunction.class);
|
IASTImplicitName n;
|
||||||
ba.assertImplicitName("/ p", 1, ICPPFunction.class);
|
|
||||||
|
n = ba.assertImplicitName("+= 5", 2, ICPPMethod.class);
|
||||||
|
assertSame(n.resolveBinding(), col.getName(14).resolveBinding());
|
||||||
|
|
||||||
|
n = ba.assertImplicitName("+ p", 1, ICPPMethod.class);
|
||||||
|
assertSame(n.resolveBinding(), col.getName(4).resolveBinding());
|
||||||
|
|
||||||
|
n = ba.assertImplicitName("- p", 1, ICPPMethod.class);
|
||||||
|
assertSame(n.resolveBinding(), col.getName(8).resolveBinding());
|
||||||
|
|
||||||
|
n = ba.assertImplicitName("* p", 1, ICPPFunction.class);
|
||||||
|
assertSame(n.resolveBinding(), col.getName(17).resolveBinding());
|
||||||
|
|
||||||
|
n = ba.assertImplicitName("/ p", 1, ICPPFunction.class);
|
||||||
|
assertSame(n.resolveBinding(), col.getName(23).resolveBinding());
|
||||||
|
|
||||||
|
n = ba.assertImplicitName("-p;", 1, ICPPMethod.class);
|
||||||
|
assertSame(n.resolveBinding(), col.getName(12).resolveBinding());
|
||||||
|
|
||||||
ba.assertNoImplicitName("<< 6", 2);
|
ba.assertNoImplicitName("<< 6", 2);
|
||||||
ba.assertImplicitName("-p;", 1, ICPPMethod.class);
|
|
||||||
ba.assertNoImplicitName("+p;", 1);
|
ba.assertNoImplicitName("+p;", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,8 +131,14 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
||||||
// }
|
// }
|
||||||
public void testPointerToMember() throws Exception {
|
public void testPointerToMember() throws Exception {
|
||||||
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
IASTTranslationUnit tu = ba.getTranslationUnit();
|
||||||
|
CPPNameCollector col = new CPPNameCollector();
|
||||||
|
tu.accept(col);
|
||||||
|
|
||||||
ba.assertNoImplicitName("&Y::x;", 1);
|
ba.assertNoImplicitName("&Y::x;", 1);
|
||||||
ba.assertImplicitName("&y;", 1, ICPPFunction.class);
|
|
||||||
|
IASTImplicitName n = ba.assertImplicitName("&y;", 1, ICPPFunction.class);
|
||||||
|
assertSame(n.resolveBinding(), col.getName(9).resolveBinding());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -197,7 +220,7 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
||||||
// D d;
|
// D d;
|
||||||
// test(a , b , c , d); // func
|
// test(a , b , c , d); // func
|
||||||
// }
|
// }
|
||||||
public void _testCommaOperator() throws Exception {
|
public void testCommaOperator1() throws Exception {
|
||||||
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
// expression lists are used in function calls but they should not resolve to the comma operator
|
// expression lists are used in function calls but they should not resolve to the comma operator
|
||||||
ba.assertNoImplicitName(", b , c , d); // func", 1);
|
ba.assertNoImplicitName(", b , c , d); // func", 1);
|
||||||
|
@ -213,22 +236,65 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
||||||
tu.accept(col);
|
tu.accept(col);
|
||||||
|
|
||||||
assertSame(opAB.resolveBinding(), col.getName(5).resolveBinding());
|
assertSame(opAB.resolveBinding(), col.getName(5).resolveBinding());
|
||||||
assertSame(opCC.resolveBinding(), col.getName(9).resolveBinding());
|
assertSame(opCC.resolveBinding(), col.getName(11).resolveBinding());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// struct B {};
|
||||||
|
// struct C {};
|
||||||
|
// struct E {
|
||||||
|
// int ee;
|
||||||
|
// };
|
||||||
|
// struct A {
|
||||||
|
// C operator,(B);
|
||||||
|
// };
|
||||||
|
// struct D {
|
||||||
|
// E operator,(D);
|
||||||
|
// };
|
||||||
|
// D operator,(C,C);
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// int test(A a, B b, C c, D d) {
|
||||||
|
// (a , b , c , d).ee; // expr
|
||||||
|
// }
|
||||||
|
public void testCommaOperator2() throws Exception {
|
||||||
|
BindingAssertionHelper ba = new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
|
||||||
|
IASTImplicitName opAB = ba.assertImplicitName(", b , c , d", 1, ICPPMethod.class);
|
||||||
|
IASTImplicitName opCC = ba.assertImplicitName(", c , d", 1, ICPPFunction.class);
|
||||||
|
IASTImplicitName opDD = ba.assertImplicitName(", d", 1, ICPPMethod.class);
|
||||||
|
|
||||||
|
IASTTranslationUnit tu = ba.getTranslationUnit();
|
||||||
|
CPPNameCollector col = new CPPNameCollector();
|
||||||
|
tu.accept(col);
|
||||||
|
|
||||||
|
// 6, 11, 15
|
||||||
|
assertSame(opAB.resolveBinding(), col.getName(6).resolveBinding());
|
||||||
|
assertSame(opCC.resolveBinding(), col.getName(15).resolveBinding());
|
||||||
|
assertSame(opDD.resolveBinding(), col.getName(11).resolveBinding());
|
||||||
|
|
||||||
|
ba.assertNonProblem("ee;", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// struct X {
|
// struct X {
|
||||||
// int operator()(bool);
|
// int operator()(bool);
|
||||||
// int operator()();
|
// int operator()();
|
||||||
|
// int operator()(int,int);
|
||||||
// };
|
// };
|
||||||
//
|
//
|
||||||
// int test(X x) {
|
// int test(X x) {
|
||||||
// bool b = true;
|
// bool b = true;
|
||||||
// x(b); // 1
|
// x(b); // 1
|
||||||
// x(); // 2
|
// x(); // 2
|
||||||
|
// x(1,2); // 3
|
||||||
// }
|
// }
|
||||||
public void testFunctionCallOperator() throws Exception {
|
public void testFunctionCallOperator() throws Exception {
|
||||||
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
IASTTranslationUnit tu = ba.getTranslationUnit();
|
||||||
|
CPPNameCollector col = new CPPNameCollector();
|
||||||
|
tu.accept(col);
|
||||||
|
|
||||||
IASTImplicitName n1 = ba.assertImplicitName("(b); // 1", 1, ICPPMethod.class);
|
IASTImplicitName n1 = ba.assertImplicitName("(b); // 1", 1, ICPPMethod.class);
|
||||||
IASTImplicitName n2 = ba.assertImplicitName("); // 1", 1, ICPPMethod.class);
|
IASTImplicitName n2 = ba.assertImplicitName("); // 1", 1, ICPPMethod.class);
|
||||||
|
@ -237,12 +303,21 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
||||||
assertTrue(n2.isAlternate());
|
assertTrue(n2.isAlternate());
|
||||||
// there should be no overlap
|
// there should be no overlap
|
||||||
ba.assertNoImplicitName("b); // 1", 1);
|
ba.assertNoImplicitName("b); // 1", 1);
|
||||||
|
assertSame(col.getName(1).resolveBinding(), n1.resolveBinding());
|
||||||
|
|
||||||
n1 = ba.assertImplicitName("(); // 2", 1, ICPPMethod.class);
|
n1 = ba.assertImplicitName("(); // 2", 1, ICPPMethod.class);
|
||||||
n2 = ba.assertImplicitName("); // 2", 1, ICPPMethod.class);
|
n2 = ba.assertImplicitName("); // 2", 1, ICPPMethod.class);
|
||||||
assertSame(n1.resolveBinding(), n2.resolveBinding());
|
assertSame(n1.resolveBinding(), n2.resolveBinding());
|
||||||
assertFalse(n1.isAlternate());
|
assertFalse(n1.isAlternate());
|
||||||
assertTrue(n2.isAlternate());
|
assertTrue(n2.isAlternate());
|
||||||
|
assertSame(col.getName(3).resolveBinding(), n1.resolveBinding());
|
||||||
|
|
||||||
|
n1 = ba.assertImplicitName("(1,2); // 3", 1, ICPPMethod.class);
|
||||||
|
n2 = ba.assertImplicitName("); // 3", 1, ICPPMethod.class);
|
||||||
|
assertSame(n1.resolveBinding(), n2.resolveBinding());
|
||||||
|
assertFalse(n1.isAlternate());
|
||||||
|
assertTrue(n2.isAlternate());
|
||||||
|
assertSame(col.getName(4).resolveBinding(), n1.resolveBinding());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -278,12 +353,17 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
||||||
// }
|
// }
|
||||||
public void testArraySubscript() throws Exception {
|
public void testArraySubscript() throws Exception {
|
||||||
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
IASTTranslationUnit tu = ba.getTranslationUnit();
|
||||||
|
CPPNameCollector col = new CPPNameCollector();
|
||||||
|
tu.accept(col);
|
||||||
|
|
||||||
IASTImplicitName n1 = ba.assertImplicitName("[0]); //1", 1, ICPPMethod.class);
|
IASTImplicitName n1 = ba.assertImplicitName("[0]); //1", 1, ICPPMethod.class);
|
||||||
ba.assertNoImplicitName("0]); //1", 1);
|
ba.assertNoImplicitName("0]); //1", 1);
|
||||||
IASTImplicitName n2 = ba.assertImplicitName("]); //1", 1, ICPPMethod.class);
|
IASTImplicitName n2 = ba.assertImplicitName("]); //1", 1, ICPPMethod.class);
|
||||||
assertSame(n1.resolveBinding(), n2.resolveBinding());
|
assertSame(n1.resolveBinding(), n2.resolveBinding());
|
||||||
assertFalse(n1.isAlternate());
|
assertFalse(n1.isAlternate());
|
||||||
assertTrue(n2.isAlternate());
|
assertTrue(n2.isAlternate());
|
||||||
|
assertSame(col.getName(1).resolveBinding(), n1.resolveBinding());
|
||||||
|
|
||||||
n1 = ba.assertImplicitName("[q]); //2", 1, ICPPMethod.class);
|
n1 = ba.assertImplicitName("[q]); //2", 1, ICPPMethod.class);
|
||||||
ba.assertNoImplicitName("q]); //2", 1);
|
ba.assertNoImplicitName("q]); //2", 1);
|
||||||
|
@ -291,6 +371,7 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
||||||
assertSame(n1.resolveBinding(), n2.resolveBinding());
|
assertSame(n1.resolveBinding(), n2.resolveBinding());
|
||||||
assertFalse(n1.isAlternate());
|
assertFalse(n1.isAlternate());
|
||||||
assertTrue(n2.isAlternate());
|
assertTrue(n2.isAlternate());
|
||||||
|
assertSame(col.getName(3).resolveBinding(), n1.resolveBinding());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -304,6 +385,7 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
||||||
// delete x;
|
// delete x;
|
||||||
// X* xs = new X[5];
|
// X* xs = new X[5];
|
||||||
// delete[] x;
|
// delete[] x;
|
||||||
|
// delete 1;
|
||||||
// }
|
// }
|
||||||
public void testDelete() throws Exception {
|
public void testDelete() throws Exception {
|
||||||
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
@ -322,6 +404,8 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
||||||
names = ba.getImplicitNames("delete[] x;", 6);
|
names = ba.getImplicitNames("delete[] x;", 6);
|
||||||
assertEquals(1, names.length);
|
assertEquals(1, names.length);
|
||||||
assertSame(col.getName(3).resolveBinding(), names[0].resolveBinding());
|
assertSame(col.getName(3).resolveBinding(), names[0].resolveBinding());
|
||||||
|
|
||||||
|
ba.assertNoImplicitName("delete 1;", 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -333,7 +417,7 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
||||||
public void _testImplicitNewAndDelete() throws Exception {
|
public void _testImplicitNewAndDelete() throws Exception {
|
||||||
BindingAssertionHelper ba = new BindingAssertionHelper(getAboveComment(), true);
|
BindingAssertionHelper ba = new BindingAssertionHelper(getAboveComment(), true);
|
||||||
ba.assertNoImplicitName("new X", 3);
|
ba.assertNoImplicitName("new X", 3);
|
||||||
ba.assertNoImplicitName("delete[]", 6);
|
ba.assertNoImplicitName("delete[]", 6); // fails because its picking up the implicit global delete[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -373,13 +457,4 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
||||||
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
ba.assertNoImplicitName("throw;", 5);
|
ba.assertNoImplicitName("throw;", 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6187,7 +6187,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
||||||
// };
|
// };
|
||||||
// A a;
|
// A a;
|
||||||
// void B::f() {
|
// void B::f() {
|
||||||
// operator+ (a,a); // ERROR - global operator hidden by member
|
// //operator+ (a,a); // ERROR - global operator hidden by member
|
||||||
// a + a; // OK - calls global operator+
|
// a + a; // OK - calls global operator+
|
||||||
// }
|
// }
|
||||||
public void test13_3_1_2s10() throws Exception {
|
public void test13_3_1_2s10() throws Exception {
|
||||||
|
|
|
@ -7029,4 +7029,52 @@ public class AST2CPPTests extends AST2BaseTest {
|
||||||
final String code = getAboveComment();
|
final String code = getAboveComment();
|
||||||
parseAndCheckBindings(code, ParserLanguage.CPP);
|
parseAndCheckBindings(code, ParserLanguage.CPP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// struct A { int a; };
|
||||||
|
// struct B { int b; };
|
||||||
|
//
|
||||||
|
// struct X {
|
||||||
|
// A operator+(int);
|
||||||
|
// X(int);
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// A operator+(X,X);
|
||||||
|
// B operator+(X,double);
|
||||||
|
//
|
||||||
|
// void test(X x) {
|
||||||
|
// (x + 1).a; //1
|
||||||
|
// (1 + x).a; //2
|
||||||
|
// (x + 1.0).b; //3
|
||||||
|
// }
|
||||||
|
public void testOverloadResolutionForOperators_Bug266211() throws Exception {
|
||||||
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
ba.assertNonProblem("a; //1", 1, ICPPField.class);
|
||||||
|
ba.assertNonProblem("a; //2", 1, ICPPField.class);
|
||||||
|
ba.assertNonProblem("b; //3", 1, ICPPField.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// struct A { int a; };
|
||||||
|
// struct X {
|
||||||
|
// A operator+(X);
|
||||||
|
// void m();
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// A operator+(X,double);
|
||||||
|
//
|
||||||
|
// void X::m() {
|
||||||
|
// X x;
|
||||||
|
// (x + x).a; //1
|
||||||
|
// (x + 1.0).a; //2
|
||||||
|
// }
|
||||||
|
public void testOverloadResolutionForOperators_Bug268534() throws Exception {
|
||||||
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
ba.assertNonProblem("a; //1", 1, ICPPField.class);
|
||||||
|
ba.assertNonProblem("a; //2", 1, ICPPField.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,6 @@ public class DOMParserTestSuite extends TestCase {
|
||||||
suite.addTest(FaultToleranceTests.suite());
|
suite.addTest(FaultToleranceTests.suite());
|
||||||
suite.addTest(LanguageExtensionsTest.suite());
|
suite.addTest(LanguageExtensionsTest.suite());
|
||||||
suite.addTest(ASTInactiveCodeTests.suite());
|
suite.addTest(ASTInactiveCodeTests.suite());
|
||||||
suite.addTest(AST2CPPImplicitNameTests.suite());
|
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
* Andrew Niefer (IBM Corporation) - initial API and implementation
|
* Andrew Niefer (IBM Corporation) - initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
* Andrew Ferguson (Symbian)
|
* Andrew Ferguson (Symbian)
|
||||||
|
* Mike Kucera (IBM)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.parser.util;
|
package org.eclipse.cdt.core.parser.util;
|
||||||
|
|
||||||
|
@ -386,4 +387,26 @@ public class ArrayUtil {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new array that contains all of the elements of the
|
||||||
|
* given array except the first one.
|
||||||
|
*
|
||||||
|
* @since 5.1
|
||||||
|
* @throws NullPointerException if args is null
|
||||||
|
* @throws IllegalArgumentException if args.length <= 0
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> T[] removeFirst(T[] args) {
|
||||||
|
int n = args.length;
|
||||||
|
if(n <= 0)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
|
||||||
|
T[] newArgs = (T[]) Array.newInstance(args.getClass().getComponentType(), n-1);
|
||||||
|
for(int i = 1; i < n; i++) {
|
||||||
|
newArgs[i-1] = args[i];
|
||||||
|
}
|
||||||
|
return newArgs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTArraySubscriptExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTArraySubscriptExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
|
@ -105,15 +104,7 @@ public class CPPASTArraySubscriptExpression extends ASTNode implements ICPPASTAr
|
||||||
|
|
||||||
|
|
||||||
public ICPPFunction getOverload() {
|
public ICPPFunction getOverload() {
|
||||||
IType type1 = arrayExpression.getExpressionType();
|
return CPPSemantics.findOverloadedOperator(this);
|
||||||
IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
|
|
||||||
if (ultimateType1 instanceof IProblemBinding) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (ultimateType1 instanceof ICPPClassType) {
|
|
||||||
return CPPSemantics.findOperator(this, (ICPPClassType) ultimateType1);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -172,7 +163,7 @@ public class CPPASTArraySubscriptExpression extends ASTNode implements ICPPASTAr
|
||||||
return CPPUnknownClass.createUnnamedInstance();
|
return CPPUnknownClass.createUnnamedInstance();
|
||||||
}
|
}
|
||||||
if (t instanceof ICPPClassType) {
|
if (t instanceof ICPPClassType) {
|
||||||
ICPPFunction op = CPPSemantics.findOperator(this, (ICPPClassType) t);
|
ICPPFunction op = getOverload();
|
||||||
if (op != null) {
|
if (op != null) {
|
||||||
return op.getType().getReturnType();
|
return op.getType().getReturnType();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,13 +17,11 @@ import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IEnumeration;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
|
@ -171,35 +169,9 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
|
||||||
if (overload != UNINITIALIZED)
|
if (overload != UNINITIALIZED)
|
||||||
return overload;
|
return overload;
|
||||||
|
|
||||||
return overload= computeOverload();
|
return overload = CPPSemantics.findOverloadedOperator(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ICPPFunction computeOverload() {
|
|
||||||
IType type1 = getOperand1().getExpressionType();
|
|
||||||
IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
|
|
||||||
if (ultimateType1 instanceof IProblemBinding) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (ultimateType1 instanceof ICPPClassType) {
|
|
||||||
ICPPFunction operator = CPPSemantics.findOperator(this, (ICPPClassType) ultimateType1);
|
|
||||||
if (operator != null)
|
|
||||||
return operator;
|
|
||||||
}
|
|
||||||
|
|
||||||
// try to find a function
|
|
||||||
if(op != op_assign) {
|
|
||||||
IType type2 = getOperand2().getExpressionType();
|
|
||||||
IType ultimateType2 = SemanticUtil.getUltimateTypeUptoPointers(type2);
|
|
||||||
if (ultimateType2 instanceof IProblemBinding)
|
|
||||||
return null;
|
|
||||||
if (isUserDefined(ultimateType1) || isUserDefined(ultimateType2))
|
|
||||||
return CPPSemantics.findOverloadedOperator(this);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private IType createExpressionType() {
|
private IType createExpressionType() {
|
||||||
// Check for overloaded operator.
|
// Check for overloaded operator.
|
||||||
ICPPFunction o= getOverload();
|
ICPPFunction o= getOverload();
|
||||||
|
@ -263,9 +235,4 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
|
||||||
return type1;
|
return type1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static boolean isUserDefined(IType type) {
|
|
||||||
return type instanceof ICPPClassType || type instanceof IEnumeration;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,17 +14,13 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
|
||||||
|
|
||||||
|
|
||||||
public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpression {
|
public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpression {
|
||||||
|
@ -87,18 +83,14 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to resolve both the destructor and the operator delete.
|
* Try to resolve both the destructor and operator delete.
|
||||||
*/
|
*/
|
||||||
public IASTImplicitName[] getImplicitNames() {
|
public IASTImplicitName[] getImplicitNames() {
|
||||||
if(implicitNames == null) {
|
if(implicitNames == null) {
|
||||||
ICPPClassType nestedType = getNestedClassType();
|
|
||||||
if(nestedType == null)
|
|
||||||
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
|
||||||
|
|
||||||
List<IASTImplicitName> names = new ArrayList<IASTImplicitName>();
|
List<IASTImplicitName> names = new ArrayList<IASTImplicitName>();
|
||||||
|
|
||||||
if(!isVectored) {
|
if(!isVectored) {
|
||||||
ICPPFunction destructor = CPPSemantics.findDestructor(this, nestedType);
|
ICPPFunction destructor = CPPSemantics.findDestructor(this);
|
||||||
if(destructor != null) {
|
if(destructor != null) {
|
||||||
CPPASTImplicitName destructorName = new CPPASTImplicitName(destructor.getNameCharArray(), this);
|
CPPASTImplicitName destructorName = new CPPASTImplicitName(destructor.getNameCharArray(), this);
|
||||||
destructorName.setBinding(destructor);
|
destructorName.setBinding(destructor);
|
||||||
|
@ -108,7 +100,7 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isGlobal) {
|
if(!isGlobal) {
|
||||||
ICPPFunction deleteOperator = findOperatorFunction(nestedType);
|
ICPPFunction deleteOperator = CPPSemantics.findOverloadedOperator(this);
|
||||||
if(deleteOperator != null) {
|
if(deleteOperator != null) {
|
||||||
CPPASTImplicitName deleteName = new CPPASTImplicitName(deleteOperator.getNameCharArray(), this);
|
CPPASTImplicitName deleteName = new CPPASTImplicitName(deleteOperator.getNameCharArray(), this);
|
||||||
deleteName.setOperator(true);
|
deleteName.setOperator(true);
|
||||||
|
@ -128,33 +120,6 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private ICPPClassType getNestedClassType() {
|
|
||||||
IType type1 = operand.getExpressionType();
|
|
||||||
IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
|
|
||||||
if(ultimateType1 instanceof IPointerType) {
|
|
||||||
try {
|
|
||||||
IType classType = ((IPointerType)ultimateType1).getType();
|
|
||||||
if(classType instanceof ICPPClassType)
|
|
||||||
return (ICPPClassType) classType;
|
|
||||||
} catch (DOMException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO this code is repeated in too many places
|
|
||||||
private ICPPFunction findOperatorFunction(IType type) {
|
|
||||||
if(type instanceof ICPPClassType) {
|
|
||||||
ICPPFunction operator = CPPSemantics.findOperator(this, (ICPPClassType) type);
|
|
||||||
if(operator != null)
|
|
||||||
return operator;
|
|
||||||
return CPPSemantics.findOverloadedOperator(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept( ASTVisitor action ){
|
public boolean accept( ASTVisitor action ){
|
||||||
if( action.shouldVisitExpressions ){
|
if( action.shouldVisitExpressions ){
|
||||||
|
|
|
@ -12,21 +12,18 @@
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IEnumeration;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
|
||||||
|
|
||||||
|
|
||||||
public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionList, IASTAmbiguityParent {
|
public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionList, IASTAmbiguityParent {
|
||||||
|
@ -38,6 +35,8 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
|
||||||
*/
|
*/
|
||||||
private IASTImplicitName[] implicitNames;
|
private IASTImplicitName[] implicitNames;
|
||||||
|
|
||||||
|
private ICPPFunction[] overloads = null;
|
||||||
|
|
||||||
|
|
||||||
public CPPASTExpressionList copy() {
|
public CPPASTExpressionList copy() {
|
||||||
CPPASTExpressionList copy = new CPPASTExpressionList();
|
CPPASTExpressionList copy = new CPPASTExpressionList();
|
||||||
|
@ -112,11 +111,9 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
|
||||||
|
|
||||||
implicitNames = new IASTImplicitName[exprs.length-1];
|
implicitNames = new IASTImplicitName[exprs.length-1];
|
||||||
|
|
||||||
if(getPropertyInParent() == IASTFunctionCallExpression.PARAMETERS)
|
ICPPFunction[] overloads = getOverloads();
|
||||||
return implicitNames;
|
for(int i = 0; i < overloads.length; i++) {
|
||||||
|
ICPPFunction overload = overloads[i];
|
||||||
for(int i = 0, n = exprs.length-1; i < n; i++) {
|
|
||||||
ICPPFunction overload = getOverload(i);
|
|
||||||
if(overload != null) {
|
if(overload != null) {
|
||||||
CPPASTImplicitName operatorName = new CPPASTImplicitName(OverloadableOperator.COMMA, this);
|
CPPASTImplicitName operatorName = new CPPASTImplicitName(OverloadableOperator.COMMA, this);
|
||||||
operatorName.setBinding(overload);
|
operatorName.setBinding(overload);
|
||||||
|
@ -135,37 +132,33 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
private ICPPFunction[] getOverloads() {
|
||||||
* @param index the index of the first argument
|
if(overloads == null) {
|
||||||
*/
|
IASTExpression[] exprs = getExpressions();
|
||||||
private ICPPFunction getOverload(int index) {
|
if(exprs.length < 2 || getPropertyInParent() == IASTFunctionCallExpression.PARAMETERS)
|
||||||
// try to find a method
|
return overloads = new ICPPFunction[0];
|
||||||
IASTExpression[] exprs = getExpressions();
|
|
||||||
|
|
||||||
IType type1 = exprs[index].getExpressionType();
|
overloads = new ICPPFunction[exprs.length-1];
|
||||||
IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
|
IType lookupType = exprs[0].getExpressionType();
|
||||||
if (ultimateType1 instanceof IProblemBinding) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (ultimateType1 instanceof ICPPClassType) {
|
|
||||||
ICPPFunction operator = CPPSemantics.findOperatorComma(this, index, (ICPPClassType) ultimateType1);
|
|
||||||
if (operator != null)
|
|
||||||
return operator;
|
|
||||||
}
|
|
||||||
|
|
||||||
// try to find a function
|
for(int i = 1; i < exprs.length; i++) {
|
||||||
IType type2 = exprs[index+1].getExpressionType();
|
IASTExpression e1 = exprs[i-1], e2 = exprs[i];
|
||||||
IType ultimateType2 = SemanticUtil.getUltimateTypeUptoPointers(type2);
|
ICPPFunction overload = CPPSemantics.findOverloadedOperatorComma(e1, e2, lookupType);
|
||||||
if (ultimateType2 instanceof IProblemBinding)
|
if(overload == null) {
|
||||||
return null;
|
lookupType = e2.getExpressionType();
|
||||||
if (isUserDefined(ultimateType1) || isUserDefined(ultimateType2))
|
}
|
||||||
return CPPSemantics.findOverloadedOperator(this, index);
|
else {
|
||||||
|
overloads[i-1] = overload;
|
||||||
|
try {
|
||||||
|
lookupType = overload.getType().getReturnType();
|
||||||
|
} catch (DOMException e) {
|
||||||
|
lookupType = e2.getExpressionType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return overloads;
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isUserDefined(IType type) {
|
|
||||||
return type instanceof ICPPClassType || type instanceof IEnumeration;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void replace(IASTNode child, IASTNode other) {
|
public void replace(IASTNode child, IASTNode other) {
|
||||||
|
@ -180,6 +173,16 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
|
||||||
}
|
}
|
||||||
|
|
||||||
public IType getExpressionType() {
|
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--) {
|
for (int i = expressions.length-1; i >= 0 ; i--) {
|
||||||
IASTExpression expr= expressions[i];
|
IASTExpression expr= expressions[i];
|
||||||
if (expr != null)
|
if (expr != null)
|
||||||
|
|
|
@ -219,7 +219,7 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
||||||
if (t instanceof IFunctionType) {
|
if (t instanceof IFunctionType) {
|
||||||
return ((IFunctionType) t).getReturnType();
|
return ((IFunctionType) t).getReturnType();
|
||||||
} else if (t instanceof ICPPClassType) {
|
} else if (t instanceof ICPPClassType) {
|
||||||
ICPPFunction op = CPPSemantics.findOperator(this, (ICPPClassType) t);
|
ICPPFunction op = CPPSemantics.findOverloadedOperator(this, (ICPPClassType)t);
|
||||||
if (op != null) {
|
if (op != null) {
|
||||||
if(overload != null)
|
if(overload != null)
|
||||||
overload[0] = op;
|
overload[0] = op;
|
||||||
|
|
|
@ -23,12 +23,9 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||||
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
import org.eclipse.cdt.core.parser.IProblem;
|
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
||||||
|
@ -180,17 +177,7 @@ public class CPPASTNewExpression extends ASTNode implements
|
||||||
|
|
||||||
public IASTImplicitName[] getImplicitNames() {
|
public IASTImplicitName[] getImplicitNames() {
|
||||||
if(implicitNames == null) {
|
if(implicitNames == null) {
|
||||||
IType type = getExpressionType();
|
ICPPFunction operatorFunction = CPPSemantics.findOverloadedOperator(this);
|
||||||
if(type instanceof IProblem)
|
|
||||||
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
|
||||||
|
|
||||||
try {
|
|
||||||
type = ((IPointerType)type).getType();
|
|
||||||
} catch (DOMException e) {
|
|
||||||
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
ICPPFunction operatorFunction = findOperatorFunction(type);
|
|
||||||
if(operatorFunction == null) {
|
if(operatorFunction == null) {
|
||||||
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
}
|
}
|
||||||
|
@ -207,17 +194,6 @@ public class CPPASTNewExpression extends ASTNode implements
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO this code is repeated in too many places
|
|
||||||
private ICPPFunction findOperatorFunction(IType type) {
|
|
||||||
if(type instanceof ICPPClassType) {
|
|
||||||
ICPPFunction operator = CPPSemantics.findOperator(this, (ICPPClassType) type);
|
|
||||||
if(operator != null)
|
|
||||||
return operator;
|
|
||||||
}
|
|
||||||
return CPPSemantics.findOverloadedOperator(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this expression is allocating an array.
|
* Returns true if this expression is allocating an array.
|
||||||
* @since 5.1
|
* @since 5.1
|
||||||
|
|
|
@ -31,7 +31,6 @@ import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
|
@ -46,9 +45,11 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
* Unary expression in c++
|
* Unary expression in c++
|
||||||
*/
|
*/
|
||||||
public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpression, IASTAmbiguityParent {
|
public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpression, IASTAmbiguityParent {
|
||||||
|
private static final ICPPFunction UNINITIALIZED = new CPPFunction(null);
|
||||||
private int op;
|
private int op;
|
||||||
private IASTExpression operand;
|
private IASTExpression operand;
|
||||||
|
|
||||||
|
private ICPPFunction overload = UNINITIALIZED;
|
||||||
private IASTImplicitName[] implicitNames = null;
|
private IASTImplicitName[] implicitNames = null;
|
||||||
|
|
||||||
public CPPASTUnaryExpression() {
|
public CPPASTUnaryExpression() {
|
||||||
|
@ -155,13 +156,46 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
||||||
|
|
||||||
|
|
||||||
public ICPPFunction getOverload() {
|
public ICPPFunction getOverload() {
|
||||||
if(operand == null)
|
if (overload != UNINITIALIZED)
|
||||||
return null;
|
return overload;
|
||||||
if(getExpressionType() instanceof CPPPointerToMemberType) // then it must be the builtin &
|
|
||||||
return null;
|
overload = CPPSemantics.findOverloadedOperator(this);
|
||||||
IType type = operand.getExpressionType();
|
if(operand != null && op == op_amper && computePointerToMemberType() instanceof CPPPointerToMemberType)
|
||||||
type = SemanticUtil.getNestedType(type, TDEF | REF);
|
overload = null;
|
||||||
return findOperatorFunction(type);
|
|
||||||
|
return overload;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private IType computePointerToMemberType() {
|
||||||
|
IASTNode child= operand;
|
||||||
|
boolean inParenthesis= false;
|
||||||
|
while (child instanceof IASTUnaryExpression && ((IASTUnaryExpression) child).getOperator() == IASTUnaryExpression.op_bracketedPrimary) {
|
||||||
|
child= ((IASTUnaryExpression) child).getOperand();
|
||||||
|
inParenthesis= true;
|
||||||
|
}
|
||||||
|
if (child instanceof IASTIdExpression) {
|
||||||
|
IASTName name= ((IASTIdExpression) child).getName();
|
||||||
|
IBinding b= name.resolveBinding();
|
||||||
|
if (b instanceof ICPPMember) {
|
||||||
|
ICPPMember member= (ICPPMember) b;
|
||||||
|
try {
|
||||||
|
if (name instanceof ICPPASTQualifiedName) {
|
||||||
|
if (!member.isStatic()) { // so if the member is static it will fall through
|
||||||
|
if (!inParenthesis) {
|
||||||
|
return new CPPPointerToMemberType(member.getType(), member.getClassOwner(), false, false);
|
||||||
|
} else if (member instanceof IFunction) {
|
||||||
|
return new ProblemBinding(operand, IProblemBinding.SEMANTIC_INVALID_TYPE, operand.getRawSignature().toCharArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (DOMException e) {
|
||||||
|
return e.getProblem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -177,40 +211,16 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
||||||
final IASTExpression operand = getOperand();
|
final IASTExpression operand = getOperand();
|
||||||
|
|
||||||
if (op == op_amper) { // check for pointer to member
|
if (op == op_amper) { // check for pointer to member
|
||||||
IASTNode child= operand;
|
IType ptm = computePointerToMemberType();
|
||||||
boolean inParenthesis= false;
|
if(ptm != null)
|
||||||
while (child instanceof IASTUnaryExpression && ((IASTUnaryExpression) child).getOperator() == IASTUnaryExpression.op_bracketedPrimary) {
|
return ptm;
|
||||||
child= ((IASTUnaryExpression) child).getOperand();
|
|
||||||
inParenthesis= true;
|
|
||||||
}
|
|
||||||
if (child instanceof IASTIdExpression) {
|
|
||||||
IASTName name= ((IASTIdExpression) child).getName();
|
|
||||||
IBinding b= name.resolveBinding();
|
|
||||||
if (b instanceof ICPPMember) {
|
|
||||||
ICPPMember member= (ICPPMember) b;
|
|
||||||
try {
|
|
||||||
if (name instanceof ICPPASTQualifiedName) {
|
|
||||||
if (!member.isStatic()) { // so if the member is static it will fall through
|
|
||||||
if (!inParenthesis) {
|
|
||||||
return new CPPPointerToMemberType(member.getType(), member.getClassOwner(), false, false);
|
|
||||||
} else if (member instanceof IFunction) {
|
|
||||||
return new ProblemBinding(operand, IProblemBinding.SEMANTIC_INVALID_TYPE, operand.getRawSignature().toCharArray());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (DOMException e) {
|
|
||||||
return e.getProblem();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IType type= operand.getExpressionType();
|
IType operator = findOperatorReturnType();
|
||||||
type = SemanticUtil.getNestedType(type, TDEF | REF);
|
|
||||||
|
|
||||||
IType operator = findOperatorReturnType(type);
|
|
||||||
if(operator != null)
|
if(operator != null)
|
||||||
return operator;
|
return operator;
|
||||||
|
|
||||||
|
IType type= operand.getExpressionType();
|
||||||
|
type = SemanticUtil.getNestedType(type, TDEF | REF);
|
||||||
return new CPPPointerType(type);
|
return new CPPPointerType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +232,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
IType operator = findOperatorReturnType(type);
|
IType operator = findOperatorReturnType();
|
||||||
if(operator != null) {
|
if(operator != null) {
|
||||||
return operator;
|
return operator;
|
||||||
} else if (type instanceof IPointerType || type instanceof IArrayType) {
|
} else if (type instanceof IPointerType || type instanceof IArrayType) {
|
||||||
|
@ -239,7 +249,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
||||||
|
|
||||||
IType type= operand.getExpressionType();
|
IType type= operand.getExpressionType();
|
||||||
type = SemanticUtil.getNestedType(type, TDEF | REF);
|
type = SemanticUtil.getNestedType(type, TDEF | REF);
|
||||||
IType operator = findOperatorReturnType(type);
|
IType operator = findOperatorReturnType();
|
||||||
if(operator != null) {
|
if(operator != null) {
|
||||||
return operator;
|
return operator;
|
||||||
}
|
}
|
||||||
|
@ -254,8 +264,8 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private IType findOperatorReturnType(IType type) {
|
private IType findOperatorReturnType() {
|
||||||
ICPPFunction operatorFunction = findOperatorFunction(type);
|
ICPPFunction operatorFunction = getOverload();
|
||||||
if(operatorFunction != null) {
|
if(operatorFunction != null) {
|
||||||
try {
|
try {
|
||||||
return operatorFunction.getType().getReturnType();
|
return operatorFunction.getType().getReturnType();
|
||||||
|
@ -267,14 +277,4 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private ICPPFunction findOperatorFunction(IType type) {
|
|
||||||
if(type instanceof ICPPClassType) {
|
|
||||||
ICPPFunction operator = CPPSemantics.findOperator(this, (ICPPClassType) type);
|
|
||||||
if(operator != null)
|
|
||||||
return operator;
|
|
||||||
return CPPSemantics.findOverloadedOperator(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||||
|
@ -136,6 +135,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||||
import org.eclipse.cdt.core.index.IIndexBinding;
|
import org.eclipse.cdt.core.index.IIndexBinding;
|
||||||
import org.eclipse.cdt.core.index.IIndexFileSet;
|
import org.eclipse.cdt.core.index.IIndexFileSet;
|
||||||
|
import org.eclipse.cdt.core.parser.IProblem;
|
||||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
|
@ -154,6 +154,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypeIdExpression;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypeIdExpression;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTUnaryExpression;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPCompositeBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPCompositeBinding;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNamespace;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNamespace;
|
||||||
|
@ -248,8 +249,10 @@ public class CPPSemantics {
|
||||||
return postResolution(binding, data);
|
return postResolution(binding, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static IBinding postResolution(IBinding binding, LookupData data) {
|
private static IBinding postResolution(IBinding binding, LookupData data) {
|
||||||
if (data.checkAssociatedScopes()) {
|
// If the normal lookup of the unqualified name finds a class member function, then ADL does not occur
|
||||||
|
if (data.checkAssociatedScopes() && !data.hasMemberFunctionResult()) {
|
||||||
// 3.4.2 argument dependent name lookup, aka Koenig lookup
|
// 3.4.2 argument dependent name lookup, aka Koenig lookup
|
||||||
try {
|
try {
|
||||||
boolean doKoenig= true;
|
boolean doKoenig= true;
|
||||||
|
@ -753,13 +756,14 @@ public class CPPSemantics {
|
||||||
scope= (ICPPScope) data.tu.mapToASTScope(((IIndexScope) scope));
|
scope= (ICPPScope) data.tu.mapToASTScope(((IIndexScope) scope));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.usingDirectivesOnly) {
|
if (!data.usingDirectivesOnly && !(data.ignoreMembers && scope instanceof ICPPClassScope)) {
|
||||||
IBinding[] bindings= getBindingsFromScope(scope, fileSet, data);
|
IBinding[] bindings= getBindingsFromScope(scope, fileSet, data);
|
||||||
if (data.typesOnly) {
|
if (data.typesOnly) {
|
||||||
removeObjects(bindings);
|
removeObjects(bindings);
|
||||||
}
|
}
|
||||||
mergeResults(data, bindings, true);
|
mergeResults(data, bindings, true);
|
||||||
|
|
||||||
|
|
||||||
// store using-directives found in this block or namespace for later use.
|
// store using-directives found in this block or namespace for later use.
|
||||||
if ((!data.hasResults() || !data.qualified() || data.contentAssist) && scope instanceof ICPPNamespaceScope) {
|
if ((!data.hasResults() || !data.qualified() || data.contentAssist) && scope instanceof ICPPNamespaceScope) {
|
||||||
final ICPPNamespaceScope blockScope= (ICPPNamespaceScope) scope;
|
final ICPPNamespaceScope blockScope= (ICPPNamespaceScope) scope;
|
||||||
|
@ -1928,14 +1932,15 @@ public class CPPSemantics {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
final boolean def = data.forFunctionDeclaration();
|
final boolean def = data.forFunctionDeclaration();
|
||||||
int numArgs= data.getFunctionArgumentCount();
|
int argumentCount = data.getFunctionArgumentCount();
|
||||||
if (def && numArgs == 1) {
|
|
||||||
|
if (def && argumentCount == 1) {
|
||||||
// check for parameter of type void
|
// check for parameter of type void
|
||||||
final IType[] argTypes = data.getFunctionArgumentTypes();
|
final IType[] argTypes = data.getFunctionArgumentTypes();
|
||||||
if (argTypes.length == 1) {
|
if (argTypes.length == 1) {
|
||||||
IType t= getNestedType(argTypes[0], TDEF);
|
IType t= getNestedType(argTypes[0], TDEF);
|
||||||
if (t instanceof IBasicType && ((IBasicType)t).getType() == IBasicType.t_void) {
|
if (t instanceof IBasicType && ((IBasicType)t).getType() == IBasicType.t_void) {
|
||||||
numArgs= 0;
|
argumentCount= 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1962,6 +1967,11 @@ public class CPPSemantics {
|
||||||
// as long as possible.
|
// as long as possible.
|
||||||
final IType[] parameterTypes = function.getType().getParameterTypes();
|
final IType[] parameterTypes = function.getType().getParameterTypes();
|
||||||
int numPars = parameterTypes.length;
|
int numPars = parameterTypes.length;
|
||||||
|
|
||||||
|
int numArgs = argumentCount;
|
||||||
|
if(function instanceof ICPPMethod && data.firstArgIsImpliedMethodArg)
|
||||||
|
numArgs--;
|
||||||
|
|
||||||
if (numArgs < 2 && numPars == 1) {
|
if (numArgs < 2 && numPars == 1) {
|
||||||
// check for void
|
// check for void
|
||||||
IType t = getNestedType(parameterTypes[0], TDEF);
|
IType t = getNestedType(parameterTypes[0], TDEF);
|
||||||
|
@ -2060,14 +2070,12 @@ public class CPPSemantics {
|
||||||
Cost[] bestFnCost = null; // the cost of the best function
|
Cost[] bestFnCost = null; // the cost of the best function
|
||||||
boolean bestHasAmbiguousParam = false; // bestFn has an ambiguous parameter conversion (not ok, ambiguous)
|
boolean bestHasAmbiguousParam = false; // bestFn has an ambiguous parameter conversion (not ok, ambiguous)
|
||||||
|
|
||||||
final IType thisType = data.getImpliedObjectArgument();
|
|
||||||
|
|
||||||
// Loop over all functions
|
// Loop over all functions
|
||||||
for (IFunction fn : fns) {
|
for (IFunction fn : fns) {
|
||||||
if (fn == null || bestFn == fn)
|
if (fn == null || bestFn == fn)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
final Cost[] fnCost= costForFunctionCall(fn, thisType, argTypes, args, allowUDC);
|
final Cost[] fnCost= costForFunctionCall(fn, argTypes, args, allowUDC, data);
|
||||||
if (fnCost == null)
|
if (fnCost == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -2166,8 +2174,7 @@ public class CPPSemantics {
|
||||||
return bestFn;
|
return bestFn;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Cost[] costForFunctionCall(IFunction fn, IType thisType, IType[] argTypes, IASTExpression[] args,
|
private static Cost[] costForFunctionCall(IFunction fn, IType[] argTypes, IASTExpression[] args, boolean allowUDC, LookupData data) throws DOMException {
|
||||||
boolean allowUDC) throws DOMException {
|
|
||||||
final ICPPFunctionType ftype= (ICPPFunctionType) fn.getType();
|
final ICPPFunctionType ftype= (ICPPFunctionType) fn.getType();
|
||||||
if (ftype == null)
|
if (ftype == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -2176,6 +2183,10 @@ public class CPPSemantics {
|
||||||
final IType[] paramTypes= ftype.getParameterTypes();
|
final IType[] paramTypes= ftype.getParameterTypes();
|
||||||
if (fn instanceof ICPPMethod && !(fn instanceof ICPPConstructor)) {
|
if (fn instanceof ICPPMethod && !(fn instanceof ICPPConstructor)) {
|
||||||
implicitType = getImplicitType((ICPPMethod) fn, ftype.isConst(), ftype.isVolatile());
|
implicitType = getImplicitType((ICPPMethod) fn, ftype.isConst(), ftype.isVolatile());
|
||||||
|
if(data.firstArgIsImpliedMethodArg) {
|
||||||
|
argTypes = ArrayUtil.removeFirst(argTypes);
|
||||||
|
args = ArrayUtil.removeFirst(args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int k= 0;
|
int k= 0;
|
||||||
|
@ -2186,6 +2197,9 @@ public class CPPSemantics {
|
||||||
result= new Cost[sourceLen];
|
result= new Cost[sourceLen];
|
||||||
} else {
|
} else {
|
||||||
result= new Cost[sourceLen+1];
|
result= new Cost[sourceLen+1];
|
||||||
|
|
||||||
|
final IType thisType = data.getImpliedObjectArgument();
|
||||||
|
|
||||||
if (ASTInternal.isStatic(fn, false)) {
|
if (ASTInternal.isStatic(fn, false)) {
|
||||||
// 13.3.1-4 for static member functions, the implicit object parameter always matches, no cost
|
// 13.3.1-4 for static member functions, the implicit object parameter always matches, no cost
|
||||||
cost = new Cost(thisType, implicitType, Rank.IDENTITY);
|
cost = new Cost(thisType, implicitType, Rank.IDENTITY);
|
||||||
|
@ -2559,6 +2573,9 @@ public class CPPSemantics {
|
||||||
if (!fieldReference.isPointerDereference())
|
if (!fieldReference.isPointerDereference())
|
||||||
return type;
|
return type;
|
||||||
|
|
||||||
|
char[] operatorName = OverloadableOperator.ARROW.toCharArray();
|
||||||
|
IASTExpression[] args = {null};
|
||||||
|
|
||||||
// bug 205964: as long as the type is a class type, recurse.
|
// bug 205964: as long as the type is a class type, recurse.
|
||||||
// Be defensive and allow a max of 10 levels.
|
// Be defensive and allow a max of 10 levels.
|
||||||
boolean foundOperator= false;
|
boolean foundOperator= false;
|
||||||
|
@ -2594,7 +2611,7 @@ public class CPPSemantics {
|
||||||
IASTFieldReference innerFR= new CPPASTFieldReference(arw, new CPPASTIdExpression(x));
|
IASTFieldReference innerFR= new CPPASTFieldReference(arw, new CPPASTIdExpression(x));
|
||||||
innerFR.setParent(fieldReference); // connect to the AST
|
innerFR.setParent(fieldReference); // connect to the AST
|
||||||
|
|
||||||
ICPPFunction op = CPPSemantics.findOperator(innerFR, (ICPPClassType) uTemp);
|
ICPPFunction op = findOverloadedOperator(innerFR, args, uTemp, operatorName, false);
|
||||||
if (op == null)
|
if (op == null)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2616,111 +2633,98 @@ public class CPPSemantics {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ICPPFunction findOperator(IASTExpression exp, ICPPClassType cls) {
|
|
||||||
IScope scope = null;
|
|
||||||
try {
|
|
||||||
scope = cls.getCompositeScope();
|
|
||||||
} catch (DOMException e1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (scope == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
CPPASTName astName = new CPPASTName();
|
public static ICPPFunction findOverloadedOperator(IASTArraySubscriptExpression exp) {
|
||||||
astName.setParent(exp);
|
char[] name = OverloadableOperator.BRACKET.toCharArray();
|
||||||
astName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
|
IASTExpression[] args = { null, exp.getSubscriptExpression() };
|
||||||
LookupData data = new LookupData(astName);
|
IType type1 = exp.getArrayExpression().getExpressionType();
|
||||||
data.forceQualified = true;
|
IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
|
||||||
|
return findOverloadedOperator(exp, args, ultimateType1, name, false);
|
||||||
if (exp instanceof IASTArraySubscriptExpression) {
|
|
||||||
astName.setName(OverloadableOperator.BRACKET.toCharArray());
|
|
||||||
data.setFunctionArguments(((IASTArraySubscriptExpression) exp).getSubscriptExpression());
|
|
||||||
} else if (exp instanceof IASTFieldReference) {
|
|
||||||
astName.setName(OverloadableOperator.ARROW.toCharArray());
|
|
||||||
data.setFunctionArguments(IASTExpression.EMPTY_EXPRESSION_ARRAY);
|
|
||||||
} else if (exp instanceof IASTFunctionCallExpression) {
|
|
||||||
astName.setName(OverloadableOperator.PAREN.toCharArray());
|
|
||||||
data.setFunctionArguments(((IASTFunctionCallExpression) exp).getParameterExpression());
|
|
||||||
} else if (exp instanceof ICPPASTDeleteExpression) {
|
|
||||||
OverloadableOperator oo = OverloadableOperator.fromDeleteExpression((ICPPASTDeleteExpression)exp);
|
|
||||||
astName.setName(oo.toCharArray());
|
|
||||||
data.setFunctionArguments(IASTExpression.EMPTY_EXPRESSION_ARRAY);
|
|
||||||
} else if (exp instanceof ICPPASTNewExpression) {
|
|
||||||
ICPPASTNewExpression newExpression = (ICPPASTNewExpression) exp;
|
|
||||||
OverloadableOperator operator = OverloadableOperator.fromNewExpression(newExpression);
|
|
||||||
astName.setName(operator.toCharArray());
|
|
||||||
data.setFunctionArguments(newExpression.getNewPlacement());
|
|
||||||
} else if (exp instanceof IASTBinaryExpression) {
|
|
||||||
final IASTBinaryExpression binary = (IASTBinaryExpression) exp;
|
|
||||||
OverloadableOperator operator = OverloadableOperator.fromBinaryExpression(binary);
|
|
||||||
if (operator == null)
|
|
||||||
return null;
|
|
||||||
astName.setName(operator.toCharArray());
|
|
||||||
data.setFunctionArguments(new IASTExpression[] { binary.getOperand2() });
|
|
||||||
} else if (exp instanceof IASTUnaryExpression) {
|
|
||||||
IASTUnaryExpression unary = (IASTUnaryExpression) exp;
|
|
||||||
OverloadableOperator operator = OverloadableOperator.fromUnaryExpression(unary);
|
|
||||||
if(operator == null)
|
|
||||||
return null;
|
|
||||||
astName.setName(operator.toCharArray());
|
|
||||||
int op = unary.getOperator();
|
|
||||||
if(op == IASTUnaryExpression.op_postFixDecr || op == IASTUnaryExpression.op_postFixIncr)
|
|
||||||
data.setFunctionArguments(new IASTExpression[] { CPPASTLiteralExpression.INT_ZERO });
|
|
||||||
else
|
|
||||||
data.setFunctionArguments(IASTExpression.EMPTY_EXPRESSION_ARRAY);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
lookup(data, scope);
|
|
||||||
IBinding binding = resolveAmbiguities(data, astName);
|
|
||||||
if (binding instanceof ICPPFunction)
|
|
||||||
return (ICPPFunction) binding;
|
|
||||||
} catch (DOMException e) {
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param expressionList
|
|
||||||
* @param index the index of the first parameter
|
|
||||||
*/
|
|
||||||
public static ICPPFunction findOperatorComma(ICPPASTExpressionList expressionList, int index, ICPPClassType cls) {
|
|
||||||
IScope scope = null;
|
|
||||||
try {
|
|
||||||
scope = cls.getCompositeScope();
|
|
||||||
} catch (DOMException e1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (scope == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
CPPASTName astName = new CPPASTName();
|
|
||||||
astName.setParent(expressionList);
|
|
||||||
astName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
|
|
||||||
astName.setName(OverloadableOperator.COMMA.toCharArray());
|
|
||||||
|
|
||||||
LookupData data = new LookupData(astName);
|
|
||||||
data.forceQualified = true;
|
|
||||||
IASTExpression[] exprs = expressionList.getExpressions();
|
|
||||||
data.setFunctionArguments(new IASTExpression[] { exprs[index], exprs[index+1] });
|
|
||||||
|
|
||||||
try {
|
|
||||||
lookup(data, scope);
|
|
||||||
IBinding binding = resolveAmbiguities(data, astName);
|
|
||||||
if (binding instanceof ICPPFunction)
|
|
||||||
return (ICPPFunction) binding;
|
|
||||||
} catch (DOMException e) {
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static ICPPFunction findOverloadedOperator(IASTFunctionCallExpression exp, ICPPClassType type) {
|
||||||
|
char[] name = OverloadableOperator.PAREN.toCharArray();
|
||||||
|
IASTExpression param = exp.getParameterExpression();
|
||||||
|
IASTExpression[] args;
|
||||||
|
if(param instanceof IASTExpressionList) {
|
||||||
|
IASTExpression[] actualArgs = ((IASTExpressionList)param).getExpressions();
|
||||||
|
ArrayList<IASTExpression> argsToPass = new ArrayList<IASTExpression>(actualArgs.length + 1);
|
||||||
|
argsToPass.add(null);
|
||||||
|
for(IASTExpression e : actualArgs) {
|
||||||
|
argsToPass.add(e);
|
||||||
|
}
|
||||||
|
args = argsToPass.toArray(new IASTExpression[argsToPass.size()]);
|
||||||
|
}
|
||||||
|
else if(param != null) {
|
||||||
|
args = new IASTExpression[] { null, param };
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
args = new IASTExpression[] { null };
|
||||||
|
}
|
||||||
|
|
||||||
|
return findOverloadedOperator(exp, args, type, name, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ICPPFunction findOverloadedOperator(ICPPASTNewExpression exp) {
|
||||||
|
OverloadableOperator op = OverloadableOperator.fromNewExpression(exp);
|
||||||
|
|
||||||
|
IType type = exp.getExpressionType();
|
||||||
|
if(type instanceof IProblem)
|
||||||
|
return null;
|
||||||
|
try {
|
||||||
|
type = ((IPointerType)type).getType();
|
||||||
|
} catch (DOMException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
IASTTypeId typeId = exp.getTypeId().copy();
|
||||||
|
IASTExpression sizeExpression = new CPPASTTypeIdExpression(IASTTypeIdExpression.op_sizeof, typeId);
|
||||||
|
sizeExpression.setParent(exp);
|
||||||
|
|
||||||
|
IASTExpression placement = exp.getNewPlacement();
|
||||||
|
List<IASTExpression> args = new ArrayList<IASTExpression>();
|
||||||
|
args.add(sizeExpression);
|
||||||
|
if(placement instanceof IASTExpressionList) {
|
||||||
|
for(IASTExpression p : ((IASTExpressionList)placement).getExpressions())
|
||||||
|
args.add(p);
|
||||||
|
}
|
||||||
|
else if(placement != null) {
|
||||||
|
args.add(placement);
|
||||||
|
}
|
||||||
|
|
||||||
|
IASTExpression[] argArray = args.toArray(new IASTExpression[args.size()]);
|
||||||
|
return findOverloadedOperator(exp, argArray, type, op.toCharArray(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static ICPPFunction findOverloadedOperator(ICPPASTDeleteExpression exp) {
|
||||||
|
OverloadableOperator op = OverloadableOperator.fromDeleteExpression(exp);
|
||||||
|
IASTExpression[] args = { exp.getOperand() };
|
||||||
|
IType classType = getNestedClassType(exp);
|
||||||
|
return findOverloadedOperator(exp, args, classType, op.toCharArray(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ICPPClassType getNestedClassType(ICPPASTDeleteExpression exp) {
|
||||||
|
IType type1 = exp.getOperand().getExpressionType();
|
||||||
|
IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
|
||||||
|
if(ultimateType1 instanceof IPointerType) {
|
||||||
|
try {
|
||||||
|
IType classType = ((IPointerType)ultimateType1).getType();
|
||||||
|
if(classType instanceof ICPPClassType)
|
||||||
|
return (ICPPClassType) classType;
|
||||||
|
} catch (DOMException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ICPPFunction findDestructor(ICPPASTDeleteExpression expr) {
|
||||||
|
ICPPClassType cls = getNestedClassType(expr);
|
||||||
|
if(cls == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
public static ICPPFunction findDestructor(ICPPASTDeleteExpression expr, ICPPClassType cls) {
|
|
||||||
IScope scope = null;
|
IScope scope = null;
|
||||||
try {
|
try {
|
||||||
scope = cls.getCompositeScope();
|
scope = cls.getCompositeScope();
|
||||||
|
@ -2749,119 +2753,144 @@ public class CPPSemantics {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the overloaded operator corresponding to a binary expression, or {@code null}
|
|
||||||
* if no such operator is found.
|
|
||||||
* @param exp a binary expression
|
|
||||||
* @return the overloaded operator, or {@code null}.
|
|
||||||
*/
|
|
||||||
public static ICPPFunction findOverloadedOperator(IASTBinaryExpression exp) {
|
|
||||||
OverloadableOperator operator = OverloadableOperator.fromBinaryExpression(exp);
|
|
||||||
IASTExpression[] args = { exp.getOperand1(), exp.getOperand2() };
|
|
||||||
return findOverloadedOperator(exp, operator, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the overloaded operator corresponding to a binary expression, or {@code null}
|
|
||||||
* if no such operator is found.
|
|
||||||
* @param exp a binary expression
|
|
||||||
* @return the overloaded operator, or {@code null}.
|
|
||||||
*/
|
|
||||||
public static ICPPFunction findOverloadedOperator(ICPPASTDeleteExpression exp) {
|
|
||||||
OverloadableOperator operator = OverloadableOperator.fromDeleteExpression(exp);
|
|
||||||
IASTExpression[] args = { exp.getOperand() };
|
|
||||||
return findOverloadedOperator(exp, operator, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the overloaded operator corresponding to a unary expression, or {@code null}
|
|
||||||
* if no such operator is found.
|
|
||||||
*/
|
|
||||||
public static ICPPFunction findOverloadedOperator(IASTUnaryExpression exp) {
|
public static ICPPFunction findOverloadedOperator(IASTUnaryExpression exp) {
|
||||||
OverloadableOperator operator = OverloadableOperator.fromUnaryExpression(exp);
|
if(exp.getOperand() == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
IASTExpression[] args = null;
|
OverloadableOperator op = OverloadableOperator.fromUnaryExpression(exp);
|
||||||
int op = exp.getOperator();
|
if(op == null)
|
||||||
if(op == IASTUnaryExpression.op_postFixDecr || op == IASTUnaryExpression.op_postFixIncr)
|
return null;
|
||||||
|
|
||||||
|
IASTExpression[] args;
|
||||||
|
int operator = exp.getOperator();
|
||||||
|
if(operator == IASTUnaryExpression.op_postFixDecr || operator == IASTUnaryExpression.op_postFixIncr)
|
||||||
args = new IASTExpression[] { exp.getOperand(), CPPASTLiteralExpression.INT_ZERO };
|
args = new IASTExpression[] { exp.getOperand(), CPPASTLiteralExpression.INT_ZERO };
|
||||||
else
|
else
|
||||||
args = new IASTExpression[] { exp.getOperand() };
|
args = new IASTExpression[] { exp.getOperand() };
|
||||||
|
|
||||||
return findOverloadedOperator(exp, operator, args);
|
IType type = exp.getOperand().getExpressionType();
|
||||||
}
|
type = SemanticUtil.getNestedType(type, TDEF | REF | CVQ);
|
||||||
|
|
||||||
|
return findOverloadedOperator(exp, args, type, op.toCharArray(), true);
|
||||||
/**
|
|
||||||
* Returns the overloaded operator corresponding to a comma in an expression list,
|
|
||||||
* or {@code null} if no such operator is found.
|
|
||||||
* @param index the index of the left argument to the comma operator
|
|
||||||
* @throws IndexOutOfBoundsException if index is invalid
|
|
||||||
*/
|
|
||||||
public static ICPPFunction findOverloadedOperator(ICPPASTExpressionList exp, int index) {
|
|
||||||
OverloadableOperator operator = OverloadableOperator.COMMA;
|
|
||||||
IASTExpression[] exprs = exp.getExpressions();
|
|
||||||
IASTExpression[] args = { exprs[index], exprs[index+1] };
|
|
||||||
return findOverloadedOperator(exp, operator, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the overloaded operator corresponding to a comma in an expression list,
|
|
||||||
* or {@code null} if no such operator is found.
|
|
||||||
* @throws IndexOutOfBoundsException if index is invalid
|
|
||||||
*/
|
|
||||||
public static ICPPFunction findOverloadedOperator(ICPPASTNewExpression exp) {
|
|
||||||
OverloadableOperator operator = OverloadableOperator.fromNewExpression(exp);
|
|
||||||
|
|
||||||
IASTTypeId typeId = exp.getTypeId().copy();
|
|
||||||
IASTExpression sizeExpression = new CPPASTTypeIdExpression(IASTTypeIdExpression.op_sizeof, typeId);
|
|
||||||
sizeExpression.setParent(exp);
|
|
||||||
|
|
||||||
IASTExpression placement = exp.getNewPlacement();
|
|
||||||
|
|
||||||
List<IASTExpression> args = new ArrayList<IASTExpression>();
|
|
||||||
args.add(sizeExpression);
|
|
||||||
|
|
||||||
if(placement instanceof IASTExpressionList) {
|
|
||||||
for(IASTExpression p : ((IASTExpressionList)placement).getExpressions())
|
|
||||||
args.add(p);
|
|
||||||
}
|
|
||||||
else if(placement != null) {
|
|
||||||
args.add(placement);
|
|
||||||
}
|
|
||||||
|
|
||||||
return findOverloadedOperator(exp, operator, args.toArray(new IASTExpression[args.size()]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static ICPPFunction findOverloadedOperator(IASTExpression exp, OverloadableOperator operator, IASTExpression[] args) {
|
public static ICPPFunction findOverloadedOperator(IASTBinaryExpression exp) {
|
||||||
if (operator == null) {
|
OverloadableOperator op = OverloadableOperator.fromBinaryExpression(exp);
|
||||||
return null;
|
if(op == null)
|
||||||
}
|
|
||||||
|
|
||||||
IScope scope = CPPVisitor.getContainingScope(exp);
|
|
||||||
if (scope == null)
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
CPPASTName astName = new CPPASTName();
|
IType op1type = SemanticUtil.getUltimateTypeUptoPointers(exp.getOperand1().getExpressionType());
|
||||||
astName.setParent(exp);
|
IASTExpression[] args = new IASTExpression[] { exp.getOperand1(), exp.getOperand2() } ;
|
||||||
astName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
|
|
||||||
astName.setName(operator.toCharArray());
|
boolean lookupNonMember = false;
|
||||||
LookupData data = new LookupData(astName);
|
if(exp.getOperator() != IASTBinaryExpression.op_assign) {
|
||||||
data.setFunctionArguments(args);
|
IType op2type = SemanticUtil.getUltimateTypeUptoPointers(exp.getOperand2().getExpressionType());
|
||||||
|
if(op2type instanceof IProblemBinding)
|
||||||
|
return null;
|
||||||
|
if(isUserDefined(op1type) || isUserDefined(op2type))
|
||||||
|
lookupNonMember = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return findOverloadedOperator(exp, args, op1type, op.toCharArray(), lookupNonMember);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the operator,() function that would apply to the two given arguments.
|
||||||
|
* The lookup type of the class where the operator,() might be found must also be provided.
|
||||||
|
*/
|
||||||
|
public static ICPPFunction findOverloadedOperatorComma(IASTExpression first, IASTExpression second, final IType lookupType) {
|
||||||
|
IASTUnaryExpression dummy = new CPPASTUnaryExpression() {
|
||||||
|
@Override public IType getExpressionType() { return lookupType; }
|
||||||
|
@Override public IASTExpression getOperand() {
|
||||||
|
return new CPPASTUnaryExpression() {
|
||||||
|
@Override public IType getExpressionType() { return lookupType; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dummy.setParent(first);
|
||||||
|
|
||||||
|
char[] name = OverloadableOperator.COMMA.toCharArray();
|
||||||
|
IASTExpression[] args = new IASTExpression[] { dummy , second };
|
||||||
|
return findOverloadedOperator(dummy, args, lookupType, name, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static ICPPFunction findOverloadedOperator(IASTExpression parent, IASTExpression[] args, IType methodLookupType, char[] operatorName, boolean lookupNonMember) {
|
||||||
|
// find a method
|
||||||
|
LookupData methodData = null;
|
||||||
|
CPPASTName methodName = null;
|
||||||
|
if(methodLookupType instanceof IProblemBinding)
|
||||||
|
return null;
|
||||||
|
if(methodLookupType instanceof ICPPClassType) {
|
||||||
|
methodName = new CPPASTName(operatorName);
|
||||||
|
methodName.setParent(parent);
|
||||||
|
methodName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
|
||||||
|
methodData = new LookupData(methodName);
|
||||||
|
methodData.setFunctionArguments(ArrayUtil.removeFirst(args));
|
||||||
|
methodData.forceQualified = true; // (13.3.1.2.3)
|
||||||
|
|
||||||
|
try {
|
||||||
|
IScope scope = ((ICPPClassType)methodLookupType).getCompositeScope();
|
||||||
|
if (scope == null)
|
||||||
|
return null;
|
||||||
|
lookup(methodData, scope);
|
||||||
|
} catch (DOMException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find a function
|
||||||
|
LookupData funcData = null;
|
||||||
|
CPPASTName funcName = null;
|
||||||
|
if(lookupNonMember) {
|
||||||
|
funcName = new CPPASTName(operatorName);
|
||||||
|
funcName.setParent(parent);
|
||||||
|
funcName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
|
||||||
|
funcData = new LookupData(funcName);
|
||||||
|
funcData.setFunctionArguments(args);
|
||||||
|
funcData.ignoreMembers = true; // (13.3.1.2.3)
|
||||||
|
|
||||||
|
try {
|
||||||
|
IScope scope = CPPVisitor.getContainingScope(parent);
|
||||||
|
if (scope == null)
|
||||||
|
return null;
|
||||||
|
lookup(funcData, scope);
|
||||||
|
} catch (DOMException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// resolve ambiguities
|
||||||
|
try {
|
||||||
|
IBinding binding = null;
|
||||||
|
if(methodData != null && funcData != null) {
|
||||||
|
// if there was two lookups then merge the results
|
||||||
|
mergeResults(funcData, methodData.foundItems, false);
|
||||||
|
funcData.firstArgIsImpliedMethodArg = true;
|
||||||
|
binding = resolveAmbiguities(funcData, funcName);
|
||||||
|
}
|
||||||
|
else if(funcData != null) {
|
||||||
|
binding = resolveAmbiguities(funcData, funcName);
|
||||||
|
}
|
||||||
|
else if(methodData != null) {
|
||||||
|
binding = resolveAmbiguities(methodData, methodName);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
lookup(data, scope);
|
|
||||||
IBinding binding = resolveAmbiguities(data, astName);
|
|
||||||
if (binding instanceof ICPPFunction)
|
if (binding instanceof ICPPFunction)
|
||||||
return (ICPPFunction) binding;
|
return (ICPPFunction) binding;
|
||||||
} catch (DOMException e) {}
|
|
||||||
|
} catch (DOMException e) {
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static boolean isUserDefined(IType type) {
|
||||||
|
return type instanceof ICPPClassType || type instanceof IEnumeration;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static IBinding[] findBindings(IScope scope, String name, boolean qualified) throws DOMException {
|
public static IBinding[] findBindings(IScope scope, String name, boolean qualified) throws DOMException {
|
||||||
|
|
|
@ -63,6 +63,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
|
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.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.ICPPNamespaceScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
||||||
|
@ -104,6 +105,8 @@ public class LookupData {
|
||||||
public boolean considerConstructors = false;
|
public boolean considerConstructors = false;
|
||||||
public boolean checkPointOfDecl= true; // for lookup of unknown bindings the point of declaration can be reversed.
|
public boolean checkPointOfDecl= true; // for lookup of unknown bindings the point of declaration can be reversed.
|
||||||
public boolean usesEnclosingScope= true; // for field references or qualified names, enclosing template declarations are ignored.
|
public boolean usesEnclosingScope= true; // for field references or qualified names, enclosing template declarations are ignored.
|
||||||
|
public boolean firstArgIsImpliedMethodArg = false; // when computing the cost of a method call treat the first argument as the implied method argument
|
||||||
|
public boolean ignoreMembers = false;
|
||||||
|
|
||||||
public ICPPClassType skippedScope;
|
public ICPPClassType skippedScope;
|
||||||
public Object foundItems = null;
|
public Object foundItems = null;
|
||||||
|
@ -370,6 +373,19 @@ public class LookupData {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasMemberFunctionResult() {
|
||||||
|
if(foundItems == null)
|
||||||
|
return false;
|
||||||
|
if(foundItems instanceof Object[]) {
|
||||||
|
for(Object item : (Object[])foundItems) {
|
||||||
|
if(item instanceof ICPPMethod) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* an IType[] of function arguments, including the implied object argument
|
* an IType[] of function arguments, including the implied object argument
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Reference in a new issue