/******************************************************************************* * Copyright (c) 2007, 2008 Symbian Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Andrew Ferguson (Symbian) - Initial implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.index.tests; import java.io.IOException; import junit.framework.TestSuite; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IVariable; /** * For testing PDOM binding C language resolution */ /* * aftodo - once we have non-problem bindings working, each test should * additionally check that the binding obtained has characteristics as * expected (type,name,etc..) */ public class IndexCBindingResolutionTest extends IndexBindingResolutionTestBase { public static class SingleProject extends IndexCBindingResolutionTest { public SingleProject() {setStrategy(new SinglePDOMTestStrategy(false));} public static TestSuite suite() {return suite(SingleProject.class);} } public static class ProjectWithDepProj extends IndexCBindingResolutionTest { public ProjectWithDepProj() {setStrategy(new ReferencedProject(false));} public static TestSuite suite() {return suite(ProjectWithDepProj.class);} } public static void addTests(TestSuite suite) { suite.addTest(SingleProject.suite()); suite.addTest(ProjectWithDepProj.suite()); } public IndexCBindingResolutionTest() { setStrategy(new SinglePDOMTestStrategy(false)); } // int (*f)(int); // int g(int n){return n;} // void foo() { // f= g; // } public void testPointerToFunction() throws Exception { IBinding b0 = getBindingFromASTName("f= g;", 1); IBinding b1 = getBindingFromASTName("g;", 1); assertInstance(b0, IVariable.class); IVariable v0= (IVariable) b0; assertInstance(v0.getType(), IPointerType.class); IPointerType p0= (IPointerType) v0.getType(); assertInstance(p0.getType(), IFunctionType.class); IFunctionType f0= (IFunctionType) p0.getType(); assertInstance(f0.getReturnType(), IBasicType.class); assertEquals(1, f0.getParameterTypes().length); assertInstance(f0.getParameterTypes()[0], IBasicType.class); assertInstance(b1, IFunction.class); IFunctionType f1= ((IFunction)b1).getType(); assertInstance(f1.getReturnType(), IBasicType.class); assertEquals(1, f1.getParameterTypes().length); assertInstance(f1.getParameterTypes()[0], IBasicType.class); } // // header file // struct S {int x;}; // union U {int x;}; // enum E {ER1,ER2,ER3}; // void func1(enum E e) {} // void func2(struct S s) {} // void func3(int** ppi) {} // void func4(int n) {} // // int var1; // struct S var2; // struct S *var3; // typedef int Int; // typedef int *IntPtr; // // referencing file // void references() { // struct S s; /*s*/ // union U u; /*u*/ // enum E e; /*e*/ // Int a; /*a*/ // IntPtr b = &a; /*b*/ // func3(&b); /*func4*/ // func4(a); /*func5*/ // // var1 = 1; /*var1*/ // var2 = s; /*var2*/ // var3 = &s; /*var3*/ // func1(e); /*func1*/ // func1(var1); /*func2*/ // func2(s); /*func3*/ // } public void testSimpleGlobalBindings() throws IOException { IBinding b2 = getBindingFromASTName("S s;", 1); IBinding b3 = getBindingFromASTName("s;", 1); IBinding b4 = getBindingFromASTName("U u;", 1); IBinding b5 = getBindingFromASTName("u; ", 1); IBinding b6 = getBindingFromASTName("E e; ", 1); IBinding b7 = getBindingFromASTName("e; ", 1); IBinding b8 = getBindingFromASTName("var1 = 1;", 4); IBinding b9 = getBindingFromASTName("var2 = s;", 4); IBinding b10 = getBindingFromASTName("var3 = &s;", 4); IBinding b11 = getBindingFromASTName("func1(e);", 5); IBinding b12 = getBindingFromASTName("func1(var1);", 5); IBinding b13 = getBindingFromASTName("func2(s);", 5); IBinding b14 = getBindingFromASTName("Int a; ", 3); IBinding b15 = getBindingFromASTName("a; ", 1); IBinding b16 = getBindingFromASTName("IntPtr b = &a; ", 6); IBinding b17 = getBindingFromASTName("b = &a; /*b*/", 1); IBinding b18 = getBindingFromASTName("func3(&b);", 5); IBinding b19 = getBindingFromASTName("b); /*func4*/", 1); IBinding b20 = getBindingFromASTName("func4(a);", 5); IBinding b21 = getBindingFromASTName("a); /*func5*/", 1); } // // empty // typedef struct S {int a;} S; // typedef enum E {A,B} E; // struct A { // S *s; // E *e; // }; public void testTypedefA() throws Exception { IBinding b1 = getBindingFromASTName("S {", 1); IBinding b2 = getBindingFromASTName("S;", 1); IBinding b3 = getBindingFromASTName("E {", 1); IBinding b4 = getBindingFromASTName("E;", 1); IBinding b5 = getBindingFromASTName("S *s", 1); IBinding b6 = getBindingFromASTName("E *e", 1); assertInstance(b1, ICompositeType.class); assertInstance(b2, ITypedef.class); assertInstance(b3, IEnumeration.class); assertInstance(b4, ITypedef.class); assertInstance(b5, ITypedef.class); ITypedef t5= (ITypedef) b5; assertInstance(t5.getType(), ICompositeType.class); assertEquals(ICompositeType.k_struct, ((ICompositeType)t5.getType()).getKey()); assertInstance(b6, ITypedef.class); ITypedef t6= (ITypedef) b6; assertInstance(t6.getType(), IEnumeration.class); } // typedef struct S {int a;} S; // typedef enum E {A,B} E; // struct A { // S *s; // E *e; // }; public void testTypedefB() throws Exception { IBinding b1 = getBindingFromASTName("S *s", 1); IBinding b2 = getBindingFromASTName("E *e", 1); assertInstance(b1, ITypedef.class); ITypedef t1= (ITypedef) b1; assertInstance(t1.getType(), ICompositeType.class); assertEquals(ICompositeType.k_struct, ((ICompositeType)t1.getType()).getKey()); assertInstance(b2, ITypedef.class); ITypedef t2= (ITypedef) b2; assertInstance(t2.getType(), IEnumeration.class); } // union U { // int x; // int y; // }; // struct S { // union U u; // int z; // }; // typedef struct S TS; // void refs() { // union U b1; // struct S b2; // union U *b3 = &b1; // struct S *b4 = &b2; // TS b5; // TS *b6 = &b5; // // b1.x = 0; // b1.y = 1; // b2.u.x = 2; // b2.u.y = 3; // b3->x = 4; // b3->y = 5; // b4->u.x = 6; // b4->u.y = 7; // b4->z = 8; // b5.u.x = 9; // b5.u.y = 10; // b6->u.x = 11; // b6->u.y = 12; // b6->z = 13; // } public void testFieldReference() throws Exception { IBinding b01 = getBindingFromASTName("b1;",2); assertVariable(b01, "b1", ICompositeType.class, "U"); IBinding b02 = getBindingFromASTName("b2;",2); assertVariable(b02, "b2", ICompositeType.class, "S"); IBinding b03 = getBindingFromASTName("b3 =",2); assertVariable(b03, "b3", IPointerType.class, null); assertTypeContainer(((IVariable)b03).getType(), null, IPointerType.class, ICompositeType.class, "U"); IBinding b04 = getBindingFromASTName("b4 =",2); assertVariable(b04, "b4", IPointerType.class, null); assertTypeContainer(((IVariable)b04).getType(), null, IPointerType.class, ICompositeType.class, "S"); IBinding b05 = getBindingFromASTName("b5;",2); assertVariable(b05, "b5", ITypedef.class, null); assertTypeContainer(((IVariable)b05).getType(), null, ITypedef.class, ICompositeType.class, "S"); IBinding b06 = getBindingFromASTName("b6 =",2); assertVariable(b06, "b6", IPointerType.class, null); assertTypeContainer(((IVariable)b06).getType(), null, IPointerType.class, ITypedef.class, "TS"); assertTypeContainer(((IPointerType)((IVariable)b06).getType()).getType(), null, ITypedef.class, ICompositeType.class, "S"); IBinding b07 = getBindingFromASTName("x = 0",1); assertVariable(b07, "x", IBasicType.class, null); IBinding b08 = getBindingFromASTName("y = 1",1); assertVariable(b08, "y", IBasicType.class, null); IBinding b09 = getBindingFromASTName("x = 0",1); assertVariable(b09, "x", IBasicType.class, null); IBinding b10 = getBindingFromASTName("y = 1",1); assertVariable(b08, "y", IBasicType.class, null); IBinding b11 = getBindingFromASTName("u.x = 2",1); assertVariable(b11, "u", ICompositeType.class, "U"); IBinding b12 = getBindingFromASTName("x = 2",1); assertVariable(b12, "x", IBasicType.class, null); IBinding b13 = getBindingFromASTName("u.y = 3",1); assertVariable(b13, "u", ICompositeType.class, "U"); IBinding b14 = getBindingFromASTName("y = 3",1); assertVariable(b08, "y", IBasicType.class, null); IBinding b15 = getBindingFromASTName("x = 4",1); assertVariable(b15, "x", IBasicType.class, null); IBinding b16 = getBindingFromASTName("y = 5",1); assertVariable(b16, "y", IBasicType.class, null); IBinding b17 = getBindingFromASTName("u.x = 6",1); assertVariable(b17, "u", ICompositeType.class, "U"); IBinding b18 = getBindingFromASTName("x = 6",1); assertVariable(b18, "x", IBasicType.class, null); IBinding b19 = getBindingFromASTName("u.y = 7",1); assertVariable(b19, "u", ICompositeType.class, "U"); IBinding b20 = getBindingFromASTName("y = 7",1); assertVariable(b20, "y", IBasicType.class, null); IBinding b21 = getBindingFromASTName("z = 8",1); assertVariable(b21, "z", IBasicType.class, null); IBinding b22 = getBindingFromASTName("x = 9",1); assertVariable(b22, "x", IBasicType.class, null); IBinding b23 = getBindingFromASTName("y = 10",1); assertVariable(b23, "y", IBasicType.class, null); IBinding b24 = getBindingFromASTName("u.x = 11",1); assertVariable(b24, "u", ICompositeType.class, "U"); IBinding b25 = getBindingFromASTName("x = 11",1); assertVariable(b25, "x", IBasicType.class, null); IBinding b26 = getBindingFromASTName("u.y = 12",1); assertVariable(b26, "u", ICompositeType.class, "U"); IBinding b27 = getBindingFromASTName("y = 12",1); assertVariable(b27, "y", IBasicType.class, null); IBinding b28 = getBindingFromASTName("z = 13",1); assertVariable(b28, "z", IBasicType.class, null); } // // header file // struct S {struct S* sp;}; // struct S foo1(struct S s); // struct S* foo2(struct S* s); // int foo3(int i); // int foo4(int i, struct S s); // // referencing content // void references() { // struct S s, *sp; // foo1/*a*/(sp[1]); // IASTArraySubscriptExpression // foo2/*b*/(sp+1); // IASTBinaryExpression // foo2/*c*/((struct S*) sp);/*1*/ // IASTCastExpression // foo1/*d*/(1==1 ? s : s);/*2*/ // IASTConditionalExpression // foo4/*e*/(5, s);/*3*/ // IASTExpressionList // foo2/*f*/(s.sp);/*4*/ foo2(sp->sp);/*5*/// IASTFieldReference // foo1/*g*/(foo1(s));/*6*/ // IASTFunctionCallExpression // foo1/*h*/(s);/*7*/ // IASTIdExpression // foo3/*i*/(23489); // IASTLiteralExpression // foo3/*j*/(sizeof(struct S));/*8*/ // IASTTypeIdExpression // foo1/*k*/(*sp);/*9*/ // IASTUnaryExpression // } public void testExpressionKindForFunctionCalls() { IBinding b0 = getBindingFromASTName("foo1/*a*/", 4); IBinding b0a = getBindingFromASTName("sp[1]", 2); IBinding b1 = getBindingFromASTName("foo2/*b*/", 4); IBinding b1a = getBindingFromASTName("sp+1);", 2); IBinding b2 = getBindingFromASTName("foo2/*c*/", 4); IBinding b2a = getBindingFromASTName("sp);/*1*/", 2); IBinding b3 = getBindingFromASTName("foo1/*d*/", 4); IBinding b3a = getBindingFromASTName("s : s);/*2*/", 1); IBinding b3b = getBindingFromASTName("s);/*2*/", 1); IBinding b4 = getBindingFromASTName("foo4/*e*/", 4); IBinding b4a = getBindingFromASTName("s);/*3*/", 1); IBinding b5 = getBindingFromASTName("foo2/*f*/", 4); IBinding b5a = getBindingFromASTName("s.sp);/*4*/", 1); IBinding b5b = getBindingFromASTName("sp);/*4*/", 2); IBinding b5c = getBindingFromASTName("sp->sp);/*5*/", 2); IBinding b5d = getBindingFromASTName("sp);/*5*/", 2); IBinding b6 = getBindingFromASTName("foo1/*g*/", 4); IBinding b6a = getBindingFromASTName("foo1(s));/*6*/", 4); IBinding b6b = getBindingFromASTName("s));/*6*/", 1); IBinding b7 = getBindingFromASTName("foo1/*h*/", 4); IBinding b7a = getBindingFromASTName("s);/*7*/", 1); IBinding b8 = getBindingFromASTName("foo3/*i*/", 4); IBinding b9 = getBindingFromASTName("foo3/*j*/", 4); IBinding b9a = getBindingFromASTName("S));/*8*/", 1); IBinding b10 = getBindingFromASTName("foo1/*k*/", 4); IBinding b10a = getBindingFromASTName("sp);/*9*/ ", 2); } // // header file // struct myStruct { // int a; // }; // union myUnion { // int b; // }; // // referencing content // struct myStruct; // union myUnion; // void test() { // struct myStruct* u; // union myUnion* v; // u->a= 1; // since we include the definition, we may use the type. // v->b= 1; // since we include the definition, we may use the type. // } public void testTypeDefinitionWithFwdDeclaration() { getBindingFromASTName("a= 1", 1); getBindingFromASTName("b= 1", 1); } // int a= 1+2-3*4+10/2; // -4 // int b= a+4; // int* c= &b; // enum X {e0, e4=4, e5, e2=2, e3}; // void ref() { // a; b; c; e0; e2; e3; e4; e5; // } public void testValues() throws Exception { IVariable v= (IVariable) getBindingFromASTName("a;", 1); checkValue(v.getInitialValue(), -4); v= (IVariable) getBindingFromASTName("b;", 1); checkValue(v.getInitialValue(), 0); v= (IVariable) getBindingFromASTName("c;", 1); assertNull(v.getInitialValue().numericalValue()); IEnumerator e= (IEnumerator) getBindingFromASTName("e0", 2); checkValue(e.getValue(), 0); e= (IEnumerator) getBindingFromASTName("e2", 2); checkValue(e.getValue(), 2); e= (IEnumerator) getBindingFromASTName("e3", 2); checkValue(e.getValue(), 3); e= (IEnumerator) getBindingFromASTName("e4", 2); checkValue(e.getValue(), 4); e= (IEnumerator) getBindingFromASTName("e5", 2); checkValue(e.getValue(), 5); } private void checkValue(IValue initialValue, int i) { assertNotNull(initialValue); final Long numericalValue = initialValue.numericalValue(); assertNotNull(numericalValue); assertEquals(i, numericalValue.intValue()); } }