mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 09:25:31 +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 {
|
||||
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||
ba.assertImplicitName("+= 5", 2, ICPPMethod.class);
|
||||
ba.assertImplicitName("+ p", 1, ICPPMethod.class);
|
||||
ba.assertImplicitName("- p", 1, ICPPMethod.class);
|
||||
ba.assertImplicitName("* p", 1, ICPPFunction.class);
|
||||
ba.assertImplicitName("/ p", 1, ICPPFunction.class);
|
||||
IASTTranslationUnit tu = ba.getTranslationUnit();
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
tu.accept(col);
|
||||
IASTImplicitName n;
|
||||
|
||||
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.assertImplicitName("-p;", 1, ICPPMethod.class);
|
||||
ba.assertNoImplicitName("+p;", 1);
|
||||
}
|
||||
|
||||
|
@ -114,8 +131,14 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
|||
// }
|
||||
public void testPointerToMember() throws Exception {
|
||||
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||
IASTTranslationUnit tu = ba.getTranslationUnit();
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
tu.accept(col);
|
||||
|
||||
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;
|
||||
// test(a , b , c , d); // func
|
||||
// }
|
||||
public void _testCommaOperator() throws Exception {
|
||||
public void testCommaOperator1() throws Exception {
|
||||
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||
// expression lists are used in function calls but they should not resolve to the comma operator
|
||||
ba.assertNoImplicitName(", b , c , d); // func", 1);
|
||||
|
@ -213,22 +236,65 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
|||
tu.accept(col);
|
||||
|
||||
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 {
|
||||
// int operator()(bool);
|
||||
// int operator()();
|
||||
// int operator()(int,int);
|
||||
// };
|
||||
//
|
||||
// int test(X x) {
|
||||
// bool b = true;
|
||||
// x(b); // 1
|
||||
// x(); // 2
|
||||
// x(1,2); // 3
|
||||
// }
|
||||
public void testFunctionCallOperator() throws Exception {
|
||||
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 n2 = ba.assertImplicitName("); // 1", 1, ICPPMethod.class);
|
||||
|
@ -237,12 +303,21 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
|||
assertTrue(n2.isAlternate());
|
||||
// there should be no overlap
|
||||
ba.assertNoImplicitName("b); // 1", 1);
|
||||
assertSame(col.getName(1).resolveBinding(), n1.resolveBinding());
|
||||
|
||||
n1 = ba.assertImplicitName("(); // 2", 1, ICPPMethod.class);
|
||||
n2 = ba.assertImplicitName("); // 2", 1, ICPPMethod.class);
|
||||
assertSame(n1.resolveBinding(), n2.resolveBinding());
|
||||
assertFalse(n1.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 {
|
||||
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);
|
||||
ba.assertNoImplicitName("0]); //1", 1);
|
||||
IASTImplicitName n2 = ba.assertImplicitName("]); //1", 1, ICPPMethod.class);
|
||||
assertSame(n1.resolveBinding(), n2.resolveBinding());
|
||||
assertFalse(n1.isAlternate());
|
||||
assertTrue(n2.isAlternate());
|
||||
assertSame(col.getName(1).resolveBinding(), n1.resolveBinding());
|
||||
|
||||
n1 = ba.assertImplicitName("[q]); //2", 1, ICPPMethod.class);
|
||||
ba.assertNoImplicitName("q]); //2", 1);
|
||||
|
@ -291,6 +371,7 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
|||
assertSame(n1.resolveBinding(), n2.resolveBinding());
|
||||
assertFalse(n1.isAlternate());
|
||||
assertTrue(n2.isAlternate());
|
||||
assertSame(col.getName(3).resolveBinding(), n1.resolveBinding());
|
||||
}
|
||||
|
||||
|
||||
|
@ -304,6 +385,7 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
|||
// delete x;
|
||||
// X* xs = new X[5];
|
||||
// delete[] x;
|
||||
// delete 1;
|
||||
// }
|
||||
public void testDelete() throws Exception {
|
||||
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||
|
@ -322,6 +404,8 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
|||
names = ba.getImplicitNames("delete[] x;", 6);
|
||||
assertEquals(1, names.length);
|
||||
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 {
|
||||
BindingAssertionHelper ba = new BindingAssertionHelper(getAboveComment(), true);
|
||||
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);
|
||||
ba.assertNoImplicitName("throw;", 5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -6187,7 +6187,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// };
|
||||
// A a;
|
||||
// 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+
|
||||
// }
|
||||
public void test13_3_1_2s10() throws Exception {
|
||||
|
|
|
@ -7029,4 +7029,52 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
final String code = getAboveComment();
|
||||
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(LanguageExtensionsTest.suite());
|
||||
suite.addTest(ASTInactiveCodeTests.suite());
|
||||
suite.addTest(AST2CPPImplicitNameTests.suite());
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
* Andrew Niefer (IBM Corporation) - initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Andrew Ferguson (Symbian)
|
||||
* Mike Kucera (IBM)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.parser.util;
|
||||
|
||||
|
@ -386,4 +387,26 @@ public class ArrayUtil {
|
|||
}
|
||||
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.IArrayType;
|
||||
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.cpp.ICPPASTArraySubscriptExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
|
@ -105,15 +104,7 @@ public class CPPASTArraySubscriptExpression extends ASTNode implements ICPPASTAr
|
|||
|
||||
|
||||
public ICPPFunction getOverload() {
|
||||
IType type1 = arrayExpression.getExpressionType();
|
||||
IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
|
||||
if (ultimateType1 instanceof IProblemBinding) {
|
||||
return null;
|
||||
}
|
||||
if (ultimateType1 instanceof ICPPClassType) {
|
||||
return CPPSemantics.findOperator(this, (ICPPClassType) ultimateType1);
|
||||
}
|
||||
return null;
|
||||
return CPPSemantics.findOverloadedOperator(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -172,7 +163,7 @@ public class CPPASTArraySubscriptExpression extends ASTNode implements ICPPASTAr
|
|||
return CPPUnknownClass.createUnnamedInstance();
|
||||
}
|
||||
if (t instanceof ICPPClassType) {
|
||||
ICPPFunction op = CPPSemantics.findOperator(this, (ICPPClassType) t);
|
||||
ICPPFunction op = getOverload();
|
||||
if (op != null) {
|
||||
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.IASTImplicitName;
|
||||
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.IProblemBinding;
|
||||
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.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.ICPPPointerToMemberType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
|
@ -171,35 +169,9 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
|
|||
if (overload != UNINITIALIZED)
|
||||
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() {
|
||||
// Check for overloaded operator.
|
||||
ICPPFunction o= getOverload();
|
||||
|
@ -262,10 +234,5 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
|
|||
}
|
||||
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 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.IASTImplicitName;
|
||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||
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.ICPPClassType;
|
||||
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.cpp.semantics.CPPSemantics;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||
|
||||
|
||||
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() {
|
||||
if(implicitNames == null) {
|
||||
ICPPClassType nestedType = getNestedClassType();
|
||||
if(nestedType == null)
|
||||
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||
|
||||
List<IASTImplicitName> names = new ArrayList<IASTImplicitName>();
|
||||
|
||||
if(!isVectored) {
|
||||
ICPPFunction destructor = CPPSemantics.findDestructor(this, nestedType);
|
||||
ICPPFunction destructor = CPPSemantics.findDestructor(this);
|
||||
if(destructor != null) {
|
||||
CPPASTImplicitName destructorName = new CPPASTImplicitName(destructor.getNameCharArray(), this);
|
||||
destructorName.setBinding(destructor);
|
||||
|
@ -108,7 +100,7 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
|
|||
}
|
||||
|
||||
if(!isGlobal) {
|
||||
ICPPFunction deleteOperator = findOperatorFunction(nestedType);
|
||||
ICPPFunction deleteOperator = CPPSemantics.findOverloadedOperator(this);
|
||||
if(deleteOperator != null) {
|
||||
CPPASTImplicitName deleteName = new CPPASTImplicitName(deleteOperator.getNameCharArray(), this);
|
||||
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
|
||||
public boolean accept( ASTVisitor action ){
|
||||
if( action.shouldVisitExpressions ){
|
||||
|
|
|
@ -12,21 +12,18 @@
|
|||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
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.IASTFunctionCallExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||
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.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.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.SemanticUtil;
|
||||
|
||||
|
||||
public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionList, IASTAmbiguityParent {
|
||||
|
@ -38,6 +35,8 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
|
|||
*/
|
||||
private IASTImplicitName[] implicitNames;
|
||||
|
||||
private ICPPFunction[] overloads = null;
|
||||
|
||||
|
||||
public CPPASTExpressionList copy() {
|
||||
CPPASTExpressionList copy = new CPPASTExpressionList();
|
||||
|
@ -112,11 +111,9 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
|
|||
|
||||
implicitNames = new IASTImplicitName[exprs.length-1];
|
||||
|
||||
if(getPropertyInParent() == IASTFunctionCallExpression.PARAMETERS)
|
||||
return implicitNames;
|
||||
|
||||
for(int i = 0, n = exprs.length-1; i < n; i++) {
|
||||
ICPPFunction overload = getOverload(i);
|
||||
ICPPFunction[] overloads = getOverloads();
|
||||
for(int i = 0; i < overloads.length; i++) {
|
||||
ICPPFunction overload = overloads[i];
|
||||
if(overload != null) {
|
||||
CPPASTImplicitName operatorName = new CPPASTImplicitName(OverloadableOperator.COMMA, this);
|
||||
operatorName.setBinding(overload);
|
||||
|
@ -135,39 +132,35 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param index the index of the first argument
|
||||
*/
|
||||
private ICPPFunction getOverload(int index) {
|
||||
// try to find a method
|
||||
IASTExpression[] exprs = getExpressions();
|
||||
private ICPPFunction[] getOverloads() {
|
||||
if(overloads == null) {
|
||||
IASTExpression[] exprs = getExpressions();
|
||||
if(exprs.length < 2 || getPropertyInParent() == IASTFunctionCallExpression.PARAMETERS)
|
||||
return overloads = new ICPPFunction[0];
|
||||
|
||||
overloads = new ICPPFunction[exprs.length-1];
|
||||
IType lookupType = exprs[0].getExpressionType();
|
||||
|
||||
for(int i = 1; i < exprs.length; i++) {
|
||||
IASTExpression e1 = exprs[i-1], e2 = exprs[i];
|
||||
ICPPFunction overload = CPPSemantics.findOverloadedOperatorComma(e1, e2, lookupType);
|
||||
if(overload == null) {
|
||||
lookupType = e2.getExpressionType();
|
||||
}
|
||||
else {
|
||||
overloads[i-1] = overload;
|
||||
try {
|
||||
lookupType = overload.getType().getReturnType();
|
||||
} catch (DOMException e) {
|
||||
lookupType = e2.getExpressionType();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IType type1 = exprs[index].getExpressionType();
|
||||
IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
|
||||
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
|
||||
IType type2 = exprs[index+1].getExpressionType();
|
||||
IType ultimateType2 = SemanticUtil.getUltimateTypeUptoPointers(type2);
|
||||
if (ultimateType2 instanceof IProblemBinding)
|
||||
return null;
|
||||
if (isUserDefined(ultimateType1) || isUserDefined(ultimateType2))
|
||||
return CPPSemantics.findOverloadedOperator(this, index);
|
||||
|
||||
return null;
|
||||
return overloads;
|
||||
}
|
||||
|
||||
private static boolean isUserDefined(IType type) {
|
||||
return type instanceof ICPPClassType || type instanceof IEnumeration;
|
||||
}
|
||||
|
||||
|
||||
public void replace(IASTNode child, IASTNode other) {
|
||||
if( expressions == null ) return;
|
||||
for (int i = 0; i < expressions.length; ++i) {
|
||||
|
@ -180,6 +173,16 @@ 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 {
|
||||
return last.getType().getReturnType();
|
||||
} catch (DOMException e) { }
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = expressions.length-1; i >= 0 ; i--) {
|
||||
IASTExpression expr= expressions[i];
|
||||
if (expr != null)
|
||||
|
|
|
@ -219,7 +219,7 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
|||
if (t instanceof IFunctionType) {
|
||||
return ((IFunctionType) t).getReturnType();
|
||||
} else if (t instanceof ICPPClassType) {
|
||||
ICPPFunction op = CPPSemantics.findOperator(this, (ICPPClassType) t);
|
||||
ICPPFunction op = CPPSemantics.findOverloadedOperator(this, (ICPPClassType)t);
|
||||
if (op != null) {
|
||||
if(overload != null)
|
||||
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.IASTTypeId;
|
||||
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.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.parser.IProblem;
|
||||
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.IASTAmbiguityParent;
|
||||
|
@ -180,17 +177,7 @@ public class CPPASTNewExpression extends ASTNode implements
|
|||
|
||||
public IASTImplicitName[] getImplicitNames() {
|
||||
if(implicitNames == null) {
|
||||
IType type = getExpressionType();
|
||||
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);
|
||||
ICPPFunction operatorFunction = CPPSemantics.findOverloadedOperator(this);
|
||||
if(operatorFunction == null) {
|
||||
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||
}
|
||||
|
@ -205,17 +192,6 @@ public class CPPASTNewExpression extends ASTNode implements
|
|||
|
||||
return implicitNames;
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -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.ICPPASTUnaryExpression;
|
||||
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.ICPPMember;
|
||||
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++
|
||||
*/
|
||||
public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpression, IASTAmbiguityParent {
|
||||
private static final ICPPFunction UNINITIALIZED = new CPPFunction(null);
|
||||
private int op;
|
||||
private IASTExpression operand;
|
||||
|
||||
private ICPPFunction overload = UNINITIALIZED;
|
||||
private IASTImplicitName[] implicitNames = null;
|
||||
|
||||
public CPPASTUnaryExpression() {
|
||||
|
@ -155,13 +156,46 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
|||
|
||||
|
||||
public ICPPFunction getOverload() {
|
||||
if(operand == null)
|
||||
return null;
|
||||
if(getExpressionType() instanceof CPPPointerToMemberType) // then it must be the builtin &
|
||||
return null;
|
||||
IType type = operand.getExpressionType();
|
||||
type = SemanticUtil.getNestedType(type, TDEF | REF);
|
||||
return findOperatorFunction(type);
|
||||
if (overload != UNINITIALIZED)
|
||||
return overload;
|
||||
|
||||
overload = CPPSemantics.findOverloadedOperator(this);
|
||||
if(operand != null && op == op_amper && computePointerToMemberType() instanceof CPPPointerToMemberType)
|
||||
overload = null;
|
||||
|
||||
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();
|
||||
|
||||
if (op == op_amper) { // check for pointer to member
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
IType ptm = computePointerToMemberType();
|
||||
if(ptm != null)
|
||||
return ptm;
|
||||
|
||||
IType type= operand.getExpressionType();
|
||||
type = SemanticUtil.getNestedType(type, TDEF | REF);
|
||||
|
||||
IType operator = findOperatorReturnType(type);
|
||||
IType operator = findOperatorReturnType();
|
||||
if(operator != null)
|
||||
return operator;
|
||||
|
||||
IType type= operand.getExpressionType();
|
||||
type = SemanticUtil.getNestedType(type, TDEF | REF);
|
||||
return new CPPPointerType(type);
|
||||
}
|
||||
|
||||
|
@ -222,7 +232,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
|||
return type;
|
||||
}
|
||||
try {
|
||||
IType operator = findOperatorReturnType(type);
|
||||
IType operator = findOperatorReturnType();
|
||||
if(operator != null) {
|
||||
return operator;
|
||||
} else if (type instanceof IPointerType || type instanceof IArrayType) {
|
||||
|
@ -239,7 +249,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
|||
|
||||
IType type= operand.getExpressionType();
|
||||
type = SemanticUtil.getNestedType(type, TDEF | REF);
|
||||
IType operator = findOperatorReturnType(type);
|
||||
IType operator = findOperatorReturnType();
|
||||
if(operator != null) {
|
||||
return operator;
|
||||
}
|
||||
|
@ -254,8 +264,8 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
|||
}
|
||||
|
||||
|
||||
private IType findOperatorReturnType(IType type) {
|
||||
ICPPFunction operatorFunction = findOperatorFunction(type);
|
||||
private IType findOperatorReturnType() {
|
||||
ICPPFunction operatorFunction = getOverload();
|
||||
if(operatorFunction != null) {
|
||||
try {
|
||||
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.ICPPASTDeclSpecifier;
|
||||
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.ICPPASTForStatement;
|
||||
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.index.IIndexBinding;
|
||||
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.CharArrayObjectMap;
|
||||
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.CPPASTTranslationUnit;
|
||||
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.CPPCompositeBinding;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNamespace;
|
||||
|
@ -248,8 +249,10 @@ public class CPPSemantics {
|
|||
return postResolution(binding, 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
|
||||
try {
|
||||
boolean doKoenig= true;
|
||||
|
@ -753,13 +756,14 @@ public class CPPSemantics {
|
|||
scope= (ICPPScope) data.tu.mapToASTScope(((IIndexScope) scope));
|
||||
}
|
||||
|
||||
if (!data.usingDirectivesOnly) {
|
||||
if (!data.usingDirectivesOnly && !(data.ignoreMembers && scope instanceof ICPPClassScope)) {
|
||||
IBinding[] bindings= getBindingsFromScope(scope, fileSet, data);
|
||||
if (data.typesOnly) {
|
||||
removeObjects(bindings);
|
||||
}
|
||||
mergeResults(data, bindings, true);
|
||||
|
||||
|
||||
// store using-directives found in this block or namespace for later use.
|
||||
if ((!data.hasResults() || !data.qualified() || data.contentAssist) && scope instanceof ICPPNamespaceScope) {
|
||||
final ICPPNamespaceScope blockScope= (ICPPNamespaceScope) scope;
|
||||
|
@ -1928,14 +1932,15 @@ public class CPPSemantics {
|
|||
return;
|
||||
|
||||
final boolean def = data.forFunctionDeclaration();
|
||||
int numArgs= data.getFunctionArgumentCount();
|
||||
if (def && numArgs == 1) {
|
||||
int argumentCount = data.getFunctionArgumentCount();
|
||||
|
||||
if (def && argumentCount == 1) {
|
||||
// check for parameter of type void
|
||||
final IType[] argTypes = data.getFunctionArgumentTypes();
|
||||
if (argTypes.length == 1) {
|
||||
IType t= getNestedType(argTypes[0], TDEF);
|
||||
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.
|
||||
final IType[] parameterTypes = function.getType().getParameterTypes();
|
||||
int numPars = parameterTypes.length;
|
||||
|
||||
int numArgs = argumentCount;
|
||||
if(function instanceof ICPPMethod && data.firstArgIsImpliedMethodArg)
|
||||
numArgs--;
|
||||
|
||||
if (numArgs < 2 && numPars == 1) {
|
||||
// check for void
|
||||
IType t = getNestedType(parameterTypes[0], TDEF);
|
||||
|
@ -2059,15 +2069,13 @@ public class CPPSemantics {
|
|||
IFunction bestFn = null; // the best function
|
||||
Cost[] bestFnCost = null; // the cost of the best function
|
||||
boolean bestHasAmbiguousParam = false; // bestFn has an ambiguous parameter conversion (not ok, ambiguous)
|
||||
|
||||
final IType thisType = data.getImpliedObjectArgument();
|
||||
|
||||
|
||||
// Loop over all functions
|
||||
for (IFunction fn : fns) {
|
||||
if (fn == null || bestFn == fn)
|
||||
continue;
|
||||
|
||||
final Cost[] fnCost= costForFunctionCall(fn, thisType, argTypes, args, allowUDC);
|
||||
final Cost[] fnCost= costForFunctionCall(fn, argTypes, args, allowUDC, data);
|
||||
if (fnCost == null)
|
||||
continue;
|
||||
|
||||
|
@ -2166,8 +2174,7 @@ public class CPPSemantics {
|
|||
return bestFn;
|
||||
}
|
||||
|
||||
private static Cost[] costForFunctionCall(IFunction fn, IType thisType, IType[] argTypes, IASTExpression[] args,
|
||||
boolean allowUDC) throws DOMException {
|
||||
private static Cost[] costForFunctionCall(IFunction fn, IType[] argTypes, IASTExpression[] args, boolean allowUDC, LookupData data) throws DOMException {
|
||||
final ICPPFunctionType ftype= (ICPPFunctionType) fn.getType();
|
||||
if (ftype == null)
|
||||
return null;
|
||||
|
@ -2176,8 +2183,12 @@ public class CPPSemantics {
|
|||
final IType[] paramTypes= ftype.getParameterTypes();
|
||||
if (fn instanceof ICPPMethod && !(fn instanceof ICPPConstructor)) {
|
||||
implicitType = getImplicitType((ICPPMethod) fn, ftype.isConst(), ftype.isVolatile());
|
||||
if(data.firstArgIsImpliedMethodArg) {
|
||||
argTypes = ArrayUtil.removeFirst(argTypes);
|
||||
args = ArrayUtil.removeFirst(args);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int k= 0;
|
||||
Cost cost;
|
||||
final int sourceLen= argTypes.length;
|
||||
|
@ -2186,6 +2197,9 @@ public class CPPSemantics {
|
|||
result= new Cost[sourceLen];
|
||||
} else {
|
||||
result= new Cost[sourceLen+1];
|
||||
|
||||
final IType thisType = data.getImpliedObjectArgument();
|
||||
|
||||
if (ASTInternal.isStatic(fn, false)) {
|
||||
// 13.3.1-4 for static member functions, the implicit object parameter always matches, no cost
|
||||
cost = new Cost(thisType, implicitType, Rank.IDENTITY);
|
||||
|
@ -2559,6 +2573,9 @@ public class CPPSemantics {
|
|||
if (!fieldReference.isPointerDereference())
|
||||
return type;
|
||||
|
||||
char[] operatorName = OverloadableOperator.ARROW.toCharArray();
|
||||
IASTExpression[] args = {null};
|
||||
|
||||
// bug 205964: as long as the type is a class type, recurse.
|
||||
// Be defensive and allow a max of 10 levels.
|
||||
boolean foundOperator= false;
|
||||
|
@ -2594,7 +2611,7 @@ public class CPPSemantics {
|
|||
IASTFieldReference innerFR= new CPPASTFieldReference(arw, new CPPASTIdExpression(x));
|
||||
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)
|
||||
break;
|
||||
|
||||
|
@ -2615,112 +2632,99 @@ 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;
|
||||
public static ICPPFunction findOverloadedOperator(IASTArraySubscriptExpression exp) {
|
||||
char[] name = OverloadableOperator.BRACKET.toCharArray();
|
||||
IASTExpression[] args = { null, exp.getSubscriptExpression() };
|
||||
IType type1 = exp.getArrayExpression().getExpressionType();
|
||||
IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
|
||||
return findOverloadedOperator(exp, args, ultimateType1, name, false);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
CPPASTName astName = new CPPASTName();
|
||||
astName.setParent(exp);
|
||||
astName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
|
||||
LookupData data = new LookupData(astName);
|
||||
data.forceQualified = true;
|
||||
|
||||
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 {
|
||||
IType type = exp.getExpressionType();
|
||||
if(type instanceof IProblem)
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
lookup(data, scope);
|
||||
IBinding binding = resolveAmbiguities(data, astName);
|
||||
if (binding instanceof ICPPFunction)
|
||||
return (ICPPFunction) binding;
|
||||
type = ((IPointerType)type).getType();
|
||||
} 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) {
|
||||
}
|
||||
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) {
|
||||
public static ICPPFunction findDestructor(ICPPASTDeleteExpression expr) {
|
||||
ICPPClassType cls = getNestedClassType(expr);
|
||||
if(cls == null)
|
||||
return null;
|
||||
|
||||
IScope scope = null;
|
||||
try {
|
||||
scope = cls.getCompositeScope();
|
||||
|
@ -2749,120 +2753,145 @@ public class CPPSemantics {
|
|||
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) {
|
||||
OverloadableOperator operator = OverloadableOperator.fromUnaryExpression(exp);
|
||||
|
||||
IASTExpression[] args = null;
|
||||
int op = exp.getOperator();
|
||||
if(op == IASTUnaryExpression.op_postFixDecr || op == IASTUnaryExpression.op_postFixIncr)
|
||||
if(exp.getOperand() == null)
|
||||
return null;
|
||||
|
||||
OverloadableOperator op = OverloadableOperator.fromUnaryExpression(exp);
|
||||
if(op == null)
|
||||
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 };
|
||||
else
|
||||
args = new IASTExpression[] { exp.getOperand() };
|
||||
|
||||
return findOverloadedOperator(exp, operator, args);
|
||||
}
|
||||
IType type = exp.getOperand().getExpressionType();
|
||||
type = SemanticUtil.getNestedType(type, TDEF | REF | CVQ);
|
||||
|
||||
|
||||
/**
|
||||
* 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()]));
|
||||
return findOverloadedOperator(exp, args, type, op.toCharArray(), true);
|
||||
}
|
||||
|
||||
|
||||
private static ICPPFunction findOverloadedOperator(IASTExpression exp, OverloadableOperator operator, IASTExpression[] args) {
|
||||
if (operator == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
IScope scope = CPPVisitor.getContainingScope(exp);
|
||||
if (scope == null)
|
||||
public static ICPPFunction findOverloadedOperator(IASTBinaryExpression exp) {
|
||||
OverloadableOperator op = OverloadableOperator.fromBinaryExpression(exp);
|
||||
if(op == null)
|
||||
return null;
|
||||
|
||||
CPPASTName astName = new CPPASTName();
|
||||
astName.setParent(exp);
|
||||
astName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
|
||||
astName.setName(operator.toCharArray());
|
||||
LookupData data = new LookupData(astName);
|
||||
data.setFunctionArguments(args);
|
||||
|
||||
try {
|
||||
lookup(data, scope);
|
||||
IBinding binding = resolveAmbiguities(data, astName);
|
||||
|
||||
IType op1type = SemanticUtil.getUltimateTypeUptoPointers(exp.getOperand1().getExpressionType());
|
||||
IASTExpression[] args = new IASTExpression[] { exp.getOperand1(), exp.getOperand2() } ;
|
||||
|
||||
boolean lookupNonMember = false;
|
||||
if(exp.getOperator() != IASTBinaryExpression.op_assign) {
|
||||
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);
|
||||
}
|
||||
|
||||
if (binding instanceof ICPPFunction)
|
||||
return (ICPPFunction) binding;
|
||||
} catch (DOMException e) {}
|
||||
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
|
||||
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 {
|
||||
return findBindings(scope, name.toCharArray(), qualified, null);
|
||||
|
|
|
@ -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.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.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
||||
|
@ -104,7 +105,9 @@ public class LookupData {
|
|||
public boolean considerConstructors = false;
|
||||
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 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 Object foundItems = null;
|
||||
private Object[] functionArgs;
|
||||
|
@ -370,6 +373,19 @@ public class LookupData {
|
|||
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
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue