diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index 5d0a949972a..2634bdb12ab 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -13,6 +13,7 @@ package org.eclipse.cdt.core.parser.tests.ast2; import java.util.List; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; +import org.eclipse.cdt.core.dom.ast.IASTCastExpression; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; @@ -26,6 +27,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; +import org.eclipse.cdt.core.dom.ast.IASTIfStatement; import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression; import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.IASTName; @@ -36,8 +38,9 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; -import org.eclipse.cdt.core.dom.ast.IASTCastExpression; 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.IField; import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.ILabel; @@ -45,7 +48,9 @@ import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.IVariable; +import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.c.ICASTEnumerationSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTPointer; import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.internal.core.parser.ParserException; @@ -723,5 +728,92 @@ public class AST2Tests extends AST2BaseTest { { parse( "long long x;\n", ParserLanguage.C ); //$NON-NLS-1$ } + + public void testEnumerations() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append( "enum hue { red, blue, green }; \n" ); //$NON-NLS-1$ + buffer.append( "enum hue col, *cp; \n" ); //$NON-NLS-1$ + buffer.append( "void f() { \n" ); //$NON-NLS-1$ + buffer.append( " col = blue; \n" ); //$NON-NLS-1$ + buffer.append( " cp = &col; \n" ); //$NON-NLS-1$ + buffer.append( " if( *cp != red ) \n" ); //$NON-NLS-1$ + buffer.append( " return; \n" ); //$NON-NLS-1$ + buffer.append( "} \n" ); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C ); + + IASTSimpleDeclaration decl = (IASTSimpleDeclaration) tu.getDeclarations().get( 0 ); + assertEquals( decl.getDeclarators().size(), 0 ); + ICASTEnumerationSpecifier enumSpec = (ICASTEnumerationSpecifier) decl.getDeclSpecifier(); + IASTEnumerator e1 = (IASTEnumerator) enumSpec.getEnumerators().get(0); + IASTEnumerator e2 = (IASTEnumerator) enumSpec.getEnumerators().get(1); + IASTEnumerator e3 = (IASTEnumerator) enumSpec.getEnumerators().get(2); + IASTName name_hue = enumSpec.getName(); + + decl = (IASTSimpleDeclaration) tu.getDeclarations().get(1); + IASTDeclarator dtor = (IASTDeclarator) decl.getDeclarators().get(0); + IASTName name_col = dtor.getName(); + dtor = (IASTDeclarator) decl.getDeclarators().get(1); + IASTName name_cp = dtor.getName(); + IASTElaboratedTypeSpecifier spec = (IASTElaboratedTypeSpecifier) decl.getDeclSpecifier(); + assertEquals( spec.getKind(), IASTElaboratedTypeSpecifier.k_enum ); + IASTName name_hue2 = spec.getName(); + + IASTFunctionDefinition fn = (IASTFunctionDefinition) tu.getDeclarations().get(2); + IASTCompoundStatement compound = (IASTCompoundStatement) fn.getBody(); + IASTExpressionStatement expStatement = (IASTExpressionStatement) compound.getStatements().get(0); + IASTBinaryExpression exp = (IASTBinaryExpression) expStatement.getExpression(); + assertEquals( exp.getOperator(), IASTBinaryExpression.op_assign ); + IASTIdExpression id1 = (IASTIdExpression) exp.getOperand1(); + IASTIdExpression id2 = (IASTIdExpression) exp.getOperand2(); + IASTName r_col = id1.getName(); + IASTName r_blue = id2.getName(); + + expStatement = (IASTExpressionStatement) compound.getStatements().get(1); + exp = (IASTBinaryExpression) expStatement.getExpression(); + assertEquals( exp.getOperator(), IASTBinaryExpression.op_assign ); + id1 = (IASTIdExpression) exp.getOperand1(); + IASTUnaryExpression ue = (IASTUnaryExpression) exp.getOperand2(); + id2 = (IASTIdExpression) ue.getOperand(); + IASTName r_cp = id1.getName(); + IASTName r_col2 = id2.getName(); + + IASTIfStatement ifStatement = (IASTIfStatement) compound.getStatements().get(2); + exp = (IASTBinaryExpression) ifStatement.getCondition(); + ue = (IASTUnaryExpression) exp.getOperand1(); + id1 = (IASTIdExpression) ue.getOperand(); + id2 = (IASTIdExpression) exp.getOperand2(); + + IASTName r_cp2 = id1.getName(); + IASTName r_red = id2.getName(); + + IEnumeration hue = (IEnumeration) name_hue.resolveBinding(); + IEnumerator red = (IEnumerator) e1.getName().resolveBinding(); + IEnumerator blue = (IEnumerator) e2.getName().resolveBinding(); + IEnumerator green = (IEnumerator) e3.getName().resolveBinding(); + IVariable col = (IVariable) name_col.resolveBinding(); + IVariable cp = (IVariable) name_cp.resolveBinding(); + IEnumeration hue_2 = (IEnumeration) name_hue2.resolveBinding(); + IVariable col2 = (IVariable) r_col.resolveBinding(); + IEnumerator blue2 = (IEnumerator) r_blue.resolveBinding(); + IVariable cp2 = (IVariable) r_cp.resolveBinding(); + IVariable col3 = (IVariable) r_col2.resolveBinding(); + IVariable cp3 = (IVariable) r_cp2.resolveBinding(); + IEnumerator red2 = (IEnumerator) r_red.resolveBinding(); + + assertNotNull( hue ); + assertSame( hue, hue_2 ); + assertNotNull( red ); + assertNotNull( green ); + assertNotNull( blue ); + assertNotNull( col ); + assertNotNull( cp ); + assertSame( col, col2 ); + assertSame( blue, blue2); + assertSame( cp, cp2 ); + assertSame( col, col3 ); + assertSame( cp, cp3 ); + assertSame( red, red2 ); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCTests.java index 10354fd0928..153ac5afa90 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCTests.java @@ -16,8 +16,11 @@ package org.eclipse.cdt.core.parser.tests.ast2; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; 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.IField; import org.eclipse.cdt.core.dom.ast.IFunction; +import org.eclipse.cdt.core.dom.ast.ILabel; import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.IVariable; @@ -284,7 +287,7 @@ public class GCCTests extends AST2BaseTest { NameCollector collector = new NameCollector(); CVisitor.visitTranslationUnit( tu, collector ); - assertEquals( collector.size(), 7 ); + assertEquals( collector.size(), 9 ); IVariable winds = (IVariable) collector.getName( 1 ).resolveBinding(); assertInstances( collector, winds, 6 ); @@ -348,7 +351,7 @@ public class GCCTests extends AST2BaseTest { NameCollector collector = new NameCollector(); CVisitor.visitTranslationUnit( tu, collector ); - assertEquals( collector.size(), 36 ); + assertEquals( collector.size(), 37 ); IVariable aa = (IVariable) collector.getName( 0 ).resolveBinding(); IVariable bb = (IVariable) collector.getName( 1 ).resolveBinding(); IFunction seqgt = (IFunction) collector.getName( 2 ).resolveBinding(); @@ -419,7 +422,7 @@ public class GCCTests extends AST2BaseTest { NameCollector collector = new NameCollector(); CVisitor.visitTranslationUnit( tu, collector ); - assertEquals( collector.size(), 14 ); + assertEquals( collector.size(), 15 ); IFunction f = (IFunction) collector.getName( 0 ).resolveBinding(); IParameter a = (IParameter) collector.getName( 1 ).resolveBinding(); IParameter y = (IParameter) collector.getName( 2 ).resolveBinding(); @@ -533,4 +536,292 @@ public class GCCTests extends AST2BaseTest { assertInstances( collector, N2, 2 ); assertInstances( collector, i2, 5 ); } + + public void testGCC20000412_5() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append( "int main( void ) { \n"); //$NON-NLS-1$ + buffer.append( " struct { \n"); //$NON-NLS-1$ + buffer.append( " int node; \n"); //$NON-NLS-1$ + buffer.append( " int type; \n"); //$NON-NLS-1$ + buffer.append( " } lastglob[1] = { { 0, 1 } }; \n"); //$NON-NLS-1$ + buffer.append( " if( lastglob[0].node != 0 || lastglob[0].type != 1 ) \n"); //$NON-NLS-1$ + buffer.append( " return -1; \n"); //$NON-NLS-1$ + buffer.append( " return 0; \n"); //$NON-NLS-1$ + buffer.append( "} \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C ); + NameCollector collector = new NameCollector(); + CVisitor.visitTranslationUnit( tu, collector ); + + assertEquals( collector.size(), 10 ); + IField node = (IField) collector.getName( 3 ).resolveBinding(); + IField type = (IField) collector.getName( 4 ).resolveBinding(); + IVariable lastglob = (IVariable) collector.getName( 5 ).resolveBinding(); + + assertInstances( collector, node, 2 ); + assertInstances( collector, type, 2 ); + assertInstances( collector, lastglob, 3 ); + } + + public void testGCC20000419() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append( "struct foo { int a, b, c; }; \n"); //$NON-NLS-1$ + buffer.append( "void brother( int a, int b, int c ) { \n"); //$NON-NLS-1$ + buffer.append( " if( a ) return; \n"); //$NON-NLS-1$ + buffer.append( "} \n"); //$NON-NLS-1$ + buffer.append( "void sister( struct foo f, int b, int c ) { \n"); //$NON-NLS-1$ + buffer.append( " brother( (f.b == b), b, c ); \n"); //$NON-NLS-1$ + buffer.append( "} \n"); //$NON-NLS-1$ + buffer.append( "int main() { \n"); //$NON-NLS-1$ + buffer.append( " struct foo f = { 7, 8, 9 }; \n"); //$NON-NLS-1$ + buffer.append( " sister( f, 1, 2 ); \n"); //$NON-NLS-1$ + buffer.append( " return 0; \n"); //$NON-NLS-1$ + buffer.append( "} \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C ); + NameCollector collector = new NameCollector(); + CVisitor.visitTranslationUnit( tu, collector ); + + assertEquals( collector.size(), 25 ); + ICompositeType foo = (ICompositeType) collector.getName( 0 ).resolveBinding(); + IField fa = (IField) collector.getName( 1 ).resolveBinding(); + IField fb = (IField) collector.getName( 2 ).resolveBinding(); + IField fc = (IField) collector.getName( 3 ).resolveBinding(); + IFunction brother = (IFunction) collector.getName( 4 ).resolveBinding(); + IParameter pa = (IParameter) collector.getName( 5 ).resolveBinding(); + IParameter pb = (IParameter) collector.getName( 6 ).resolveBinding(); + IParameter pc = (IParameter) collector.getName( 7 ).resolveBinding(); + IFunction sister = (IFunction) collector.getName( 9 ).resolveBinding(); + IParameter sf = (IParameter) collector.getName( 11 ).resolveBinding(); + IParameter sb = (IParameter) collector.getName( 12 ).resolveBinding(); + IParameter sc = (IParameter) collector.getName( 13 ).resolveBinding(); + IVariable f = (IVariable) collector.getName( 22 ).resolveBinding(); + + assertInstances( collector, foo, 3 ); + assertInstances( collector, fa, 1 ); + assertInstances( collector, fb, 2 ); + assertInstances( collector, fc, 1 ); + assertInstances( collector, brother, 2 ); + assertInstances( collector, pa, 2 ); + assertInstances( collector, pb, 1 ); + assertInstances( collector, pc, 1 ); + assertInstances( collector, sister, 2 ); + assertInstances( collector, sf, 2 ); + assertInstances( collector, sb, 3 ); + assertInstances( collector, sc, 2 ); + assertInstances( collector, f, 2 ); + } + public void testGCC20000503() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("unsigned long sub( int a ) { \n"); //$NON-NLS-1$ + buffer.append(" return ((0 > a - 2) ? 0 : a - 2) * sizeof(long); \n"); //$NON-NLS-1$ + buffer.append("} \n"); //$NON-NLS-1$ + buffer.append("main(){ \n"); //$NON-NLS-1$ + buffer.append(" return ( sub(0) != 0 ); \n"); //$NON-NLS-1$ + buffer.append("} \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C ); + NameCollector collector = new NameCollector(); + CVisitor.visitTranslationUnit( tu, collector ); + + assertEquals( collector.size(), 7 ); + IFunction sub = (IFunction) collector.getName( 0 ).resolveBinding(); + IParameter a = (IParameter) collector.getName( 1 ).resolveBinding(); + + assertInstances( collector, sub, 2 ); + assertInstances( collector, a, 3 ); + } + + public void testGCC20000511() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("int f( int value, int expect ) { \n"); //$NON-NLS-1$ + buffer.append(" return ( value == expect ); \n"); //$NON-NLS-1$ + buffer.append("} \n"); //$NON-NLS-1$ + buffer.append("main(){ \n"); //$NON-NLS-1$ + buffer.append(" int a = 7, b = 6, c = 4, d = 7, e = 2; \n"); //$NON-NLS-1$ + buffer.append(" f( a || b % c, 1 ); \n"); //$NON-NLS-1$ + buffer.append(" f( a ? b % c : 0, 2 ); \n"); //$NON-NLS-1$ + buffer.append(" f( a = b % c, 2); \n"); //$NON-NLS-1$ + buffer.append(" f( a *= b % c, 4 ); \n"); //$NON-NLS-1$ + buffer.append(" f( a /= b % c, 2 ); \n"); //$NON-NLS-1$ + buffer.append(" f( a %= b % c, 0 ); \n"); //$NON-NLS-1$ + buffer.append(" f( a += b % c, 2 ); \n"); //$NON-NLS-1$ + buffer.append(" f( d || c && e, 1 ); \n"); //$NON-NLS-1$ + buffer.append(" f( d ? c && e : 0, 1 ); \n"); //$NON-NLS-1$ + buffer.append(" f( d = c && e, 1 ); \n"); //$NON-NLS-1$ + buffer.append(" f( d *= c && e, 1 ); \n"); //$NON-NLS-1$ + buffer.append(" f( d %= c && e, 0); \n"); //$NON-NLS-1$ + buffer.append(" f( d += c && e, 1); \n"); //$NON-NLS-1$ + buffer.append(" f( d -= c && e, 0); \n"); //$NON-NLS-1$ + buffer.append(" f( d || c || e, 1); \n"); //$NON-NLS-1$ + buffer.append(" f( d ? c || e : 0, 0); \n"); //$NON-NLS-1$ + buffer.append(" f( d = c || e, 1 ); \n"); //$NON-NLS-1$ + buffer.append(" f( d *= c || e, 1); \n"); //$NON-NLS-1$ + buffer.append(" f( d %= c || e, 0); \n"); //$NON-NLS-1$ + buffer.append(" f( d += c || e, 1); \n"); //$NON-NLS-1$ + buffer.append(" f( d -= c || e, 0 ); \n"); //$NON-NLS-1$ + buffer.append("} \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C ); + NameCollector collector = new NameCollector(); + CVisitor.visitTranslationUnit( tu, collector ); + + assertEquals( collector.size(), 95 ); + IFunction f = (IFunction) collector.getName( 0 ).resolveBinding(); + IParameter v = (IParameter) collector.getName( 1 ).resolveBinding(); + IParameter ex = (IParameter) collector.getName( 2 ).resolveBinding(); + IVariable a = (IVariable) collector.getName( 6 ).resolveBinding(); + IVariable b = (IVariable) collector.getName( 7 ).resolveBinding(); + IVariable c = (IVariable) collector.getName( 8 ).resolveBinding(); + IVariable d = (IVariable) collector.getName( 9 ).resolveBinding(); + IVariable e = (IVariable) collector.getName( 10).resolveBinding(); + + + assertInstances( collector, f, 22 ); + assertInstances( collector, v, 2 ); + assertInstances( collector, ex, 2 ); + assertInstances( collector, a, 8 ); + assertInstances( collector, b, 8 ); + assertInstances( collector, c, 22 ); + assertInstances( collector, d, 15 ); + assertInstances( collector, e, 15 ); + } + public void testGCC20000603() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append( "struct s1 { double d; }; \n"); //$NON-NLS-1$ + buffer.append( "struct s2 { double d; }; \n"); //$NON-NLS-1$ + buffer.append( "double f( struct s1 * a, struct s2 *b) { \n"); //$NON-NLS-1$ + buffer.append( " a->d = 1.0; \n"); //$NON-NLS-1$ + buffer.append( " return b->d + 1.0; \n"); //$NON-NLS-1$ + buffer.append( "} \n"); //$NON-NLS-1$ + buffer.append( "int main() { \n"); //$NON-NLS-1$ + buffer.append( " struct s1 a; \n"); //$NON-NLS-1$ + buffer.append( " a.d = 0.0; \n"); //$NON-NLS-1$ + buffer.append( " if( f( &a, (struct s2 *)&a ) != 2.0 ) \n"); //$NON-NLS-1$ + buffer.append( " return -1; \n"); //$NON-NLS-1$ + buffer.append( " return 0; \n"); //$NON-NLS-1$ + buffer.append( "} \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C ); + NameCollector collector = new NameCollector(); + CVisitor.visitTranslationUnit( tu, collector ); + + assertEquals( collector.size(), 23 ); + ICompositeType s1 = (ICompositeType) collector.getName( 0 ).resolveBinding(); + IField d1 = (IField) collector.getName( 1 ).resolveBinding(); + ICompositeType s2 = (ICompositeType) collector.getName( 2 ).resolveBinding(); + IField d2 = (IField) collector.getName( 3 ).resolveBinding(); + IFunction f = (IFunction) collector.getName( 4 ).resolveBinding(); + IParameter pa = (IParameter) collector.getName( 6 ).resolveBinding(); + IParameter pb = (IParameter) collector.getName( 8 ).resolveBinding(); + IVariable a = (IVariable) collector.getName( 15 ).resolveBinding(); + + assertInstances( collector, s1, 3 ); + assertInstances( collector, s2, 3 ); + assertInstances( collector, d1, 3 ); + assertInstances( collector, d2, 2 ); + assertInstances( collector, f, 2 ); + assertInstances( collector, pa, 2 ); + assertInstances( collector, pb, 2 ); + assertInstances( collector, a, 4 ); + } + public void testGCC20000605_2() throws Exception{ + StringBuffer buffer = new StringBuffer(); + buffer.append( "struct F { int i; }; \n"); //$NON-NLS-1$ + buffer.append( "void f1( struct F *x, struct F * y ) { \n"); //$NON-NLS-1$ + buffer.append( " int timeout = 0; \n"); //$NON-NLS-1$ + buffer.append( " for( ; ((const struct F*)x)->i < y->i; x->i++ ) \n"); //$NON-NLS-1$ + buffer.append( " if( ++timeout > 5 ) \n"); //$NON-NLS-1$ + buffer.append( " return; \n"); //$NON-NLS-1$ + buffer.append( "} \n"); //$NON-NLS-1$ + buffer.append( "main() { \n"); //$NON-NLS-1$ + buffer.append( " struct F x, y; \n"); //$NON-NLS-1$ + buffer.append( " x.i = 0; y.i = 1; \n"); //$NON-NLS-1$ + buffer.append( " f1( &x, &y ); \n"); //$NON-NLS-1$ + buffer.append( "} \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C ); + NameCollector collector = new NameCollector(); + CVisitor.visitTranslationUnit( tu, collector ); + + assertEquals( collector.size(), 28 ); + ICompositeType F = (ICompositeType) collector.getName( 0 ).resolveBinding(); + IField i = (IField) collector.getName( 1 ).resolveBinding(); + IFunction f1 = (IFunction) collector.getName( 2 ).resolveBinding(); + IParameter px = (IParameter) collector.getName( 4 ).resolveBinding(); + IParameter py = (IParameter) collector.getName( 6 ).resolveBinding(); + IVariable timeout = (IVariable) collector.getName( 7 ).resolveBinding(); + IVariable x = (IVariable) collector.getName( 20 ).resolveBinding(); + IVariable y = (IVariable) collector.getName( 21 ).resolveBinding(); + + assertInstances( collector, F, 5 ); + assertInstances( collector, i, 6 ); + assertInstances( collector, f1, 2 ); + assertInstances( collector, px, 3 ); + assertInstances( collector, py, 2 ); + assertInstances( collector, timeout, 2 ); + assertInstances( collector, x, 3 ); + assertInstances( collector, y, 3 ); + } + public void testGCC20000605_3() throws Exception{ + StringBuffer buffer = new StringBuffer(); + buffer.append( "struct F { int x; int y; }; \n"); //$NON-NLS-1$ + buffer.append( "int main() { \n"); //$NON-NLS-1$ + buffer.append( " int timeout = 0, x = 0; \n"); //$NON-NLS-1$ + buffer.append( " while( 1 ) { \n"); //$NON-NLS-1$ + buffer.append( " const struct F i = { x++, }; \n"); //$NON-NLS-1$ + buffer.append( " if( i.x > 0 ) \n"); //$NON-NLS-1$ + buffer.append( " break; \n"); //$NON-NLS-1$ + buffer.append( " if( ++timeout > 5 ) \n"); //$NON-NLS-1$ + buffer.append( " goto die; \n"); //$NON-NLS-1$ + buffer.append( " } \n"); //$NON-NLS-1$ + buffer.append( " die: return 0; \n"); //$NON-NLS-1$ + buffer.append( "} \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C ); + NameCollector collector = new NameCollector(); + CVisitor.visitTranslationUnit( tu, collector ); + + assertEquals( collector.size(), 14 ); + ICompositeType F = (ICompositeType) collector.getName( 0 ).resolveBinding(); + IField fx = (IField) collector.getName( 1 ).resolveBinding(); + IField fy = (IField) collector.getName( 2 ).resolveBinding(); + IVariable timeout = (IVariable) collector.getName( 4 ).resolveBinding(); + IVariable x = (IVariable) collector.getName( 5 ).resolveBinding(); + IVariable i = (IVariable) collector.getName( 7 ).resolveBinding(); + ILabel die = (ILabel) collector.getName( 13 ).resolveBinding(); + + assertInstances( collector, F, 2 ); + assertInstances( collector, fx, 2 ); + assertInstances( collector, fy, 1 ); + assertInstances( collector, timeout, 2 ); + assertInstances( collector, x, 2 ); + assertInstances( collector, i, 2 ); + assertInstances( collector, die, 2 ); + } + public void testGCCenum_2() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append( "enum foo { FOO, BAR }; \n"); //$NON-NLS-1$ + buffer.append( "int main() { \n"); //$NON-NLS-1$ + buffer.append( " int i; \n"); //$NON-NLS-1$ + buffer.append( " for( i = BAR; i >= FOO; --i ) \n"); //$NON-NLS-1$ + buffer.append( " if( i == -1 ) return -1; \n"); //$NON-NLS-1$ + buffer.append( " return 0; \n"); //$NON-NLS-1$ + buffer.append( "} \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C ); + NameCollector collector = new NameCollector(); + CVisitor.visitTranslationUnit( tu, collector ); + + assertEquals( collector.size(), 11 ); + IEnumeration foo = (IEnumeration) collector.getName( 0 ).resolveBinding(); + IEnumerator FOO = (IEnumerator) collector.getName( 1 ).resolveBinding(); + IEnumerator BAR = (IEnumerator) collector.getName( 2 ).resolveBinding(); + IVariable i = (IVariable) collector.getName( 4 ).resolveBinding(); + + assertInstances( collector, foo, 1 ); + assertInstances( collector, FOO, 2 ); + assertInstances( collector, BAR, 2 ); + assertInstances( collector, i, 5 ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IEnumeration.java new file mode 100644 index 00000000000..9ce6b24949a --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IEnumeration.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +/* + * Created on Nov 23, 2004 + */ +package org.eclipse.cdt.core.dom.ast; + +/** + * @author aniefer + */ +public interface IEnumeration extends IType { + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IEnumerator.java new file mode 100644 index 00000000000..ad6bb68b51c --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IEnumerator.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +/* + * Created on Nov 23, 2004 + */ +package org.eclipse.cdt.core.dom.ast; + +/** + * @author aniefer + */ +public interface IEnumerator extends IBinding { + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CEnumeration.java new file mode 100644 index 00000000000..a4698176c72 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CEnumeration.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +/* + * Created on Nov 23, 2004 + */ +package org.eclipse.cdt.internal.core.parser2.c; + +import org.eclipse.cdt.core.dom.ast.IEnumeration; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.c.ICASTEnumerationSpecifier; + +/** + * @author aniefer + */ +public class CEnumeration implements IEnumeration { + + private final ICASTEnumerationSpecifier enumSpec; + public CEnumeration( ICASTEnumerationSpecifier spec ){ + spec = checkForDefinition( spec ); + this.enumSpec = spec; + } + + private ICASTEnumerationSpecifier checkForDefinition( ICASTEnumerationSpecifier spec ){ + return spec; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getName() + */ + public String getName() { + return enumSpec.getName().toString(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() + */ + public IScope getScope() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CEnumerator.java new file mode 100644 index 00000000000..1e0baf66205 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CEnumerator.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +/* + * Created on Nov 23, 2004 + */ +package org.eclipse.cdt.internal.core.parser2.c; + +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; + +/** + * @author aniefer + */ +public class CEnumerator implements IEnumerator { + + private final IASTEnumerator enumerator; + public CEnumerator( IASTEnumerator enumtor ){ + this.enumerator= enumtor; + } + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getName() + */ + public String getName() { + return enumerator.getName().toString(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() + */ + public IScope getScope() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CVariable.java index ec2bdbced82..02e9344da36 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CVariable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CVariable.java @@ -11,6 +11,7 @@ **********************************************************************/ package org.eclipse.cdt.internal.core.parser2.c; +import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; @@ -67,6 +68,9 @@ public class CVariable implements IVariable { } else if( declSpec instanceof IASTElaboratedTypeSpecifier ){ IASTElaboratedTypeSpecifier elabTypeSpec = (IASTElaboratedTypeSpecifier) declSpec; return (IType) elabTypeSpec.getName().resolveBinding(); + } else if( declSpec instanceof IASTCompositeTypeSpecifier ){ + IASTCompositeTypeSpecifier compTypeSpec = (IASTCompositeTypeSpecifier) declSpec; + return (IType) compTypeSpec.getName().resolveBinding(); } return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CVisitor.java index 08d21551725..2919150ab6b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/CVisitor.java @@ -16,6 +16,7 @@ import java.util.List; import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.IASTCaseStatement; +import org.eclipse.cdt.core.dom.ast.IASTCastExpression; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; @@ -49,17 +50,20 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; -import org.eclipse.cdt.core.dom.ast.IASTCastExpression; import org.eclipse.cdt.core.dom.ast.IASTWhileStatement; 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.IFunction; import org.eclipse.cdt.core.dom.ast.ILabel; import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.IVariable; +import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTElaboratedTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.c.ICASTEnumerationSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTTypeIdInitializerExpression; import org.eclipse.cdt.core.dom.ast.c.ICASTTypedefNameSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICFunctionScope; @@ -81,6 +85,7 @@ public class CVisitor { public boolean processExpressions = false; public boolean processStatements = false; public boolean processTypeIds = false; + public boolean processEnumerators = false; /** * @return true to continue visiting, return false to stop @@ -94,6 +99,7 @@ public class CVisitor { public boolean processExpression( IASTExpression expression ) { return true; } public boolean processStatement( IASTStatement statement ) { return true; } public boolean processTypeId( IASTTypeId typeId ) { return true; } + public boolean processEnumerator( IASTEnumerator enumerator ) { return true; } } public static class ClearBindingAction extends BaseVisitorAction { @@ -133,10 +139,20 @@ public class CVisitor { binding = createBinding( (ICASTElaboratedTypeSpecifier) parent ); } else if( parent instanceof IASTStatement ){ binding = createBinding ( (IASTStatement) parent ); + } else if( parent instanceof ICASTEnumerationSpecifier ){ + binding = createBinding( (ICASTEnumerationSpecifier) parent ); + } else if( parent instanceof IASTEnumerator ) { + binding = createBinding( (IASTEnumerator) parent ); } name.setBinding( binding ); } + private static IBinding createBinding( ICASTEnumerationSpecifier enumeration ){ + return new CEnumeration( enumeration ); + } + private static IBinding createBinding( IASTEnumerator enumerator ){ + return new CEnumerator( enumerator ); + } private static IBinding createBinding( IASTStatement statement ){ if( statement instanceof IASTGotoStatement ){ IScope scope = getContainingScope( statement ); @@ -170,7 +186,7 @@ public class CVisitor { return binding; } return resolveBinding( elabTypeSpec, COMPLETE | TAGS ); - } else if( parent instanceof IASTTypeId ){ + } else if( parent instanceof IASTTypeId || parent instanceof IASTParameterDeclaration ){ IASTNode blockItem = getContainingBlockItem( parent ); return findBinding( blockItem, (CASTName) elabTypeSpec.getName(), COMPLETE | TAGS ); } @@ -178,31 +194,36 @@ public class CVisitor { } private static IBinding findBinding( IASTFieldReference fieldReference ){ IASTExpression fieldOwner = fieldReference.getFieldOwner(); - ICompositeType compositeType = null; - if( fieldOwner instanceof IASTIdExpression ){ - IBinding binding = resolveBinding( fieldOwner ); - if( binding instanceof IVariable ){ - binding = ((IVariable)binding).getType(); - while( binding != null && binding instanceof ITypedef ) - binding = ((ITypedef)binding).getType(); - } - if( binding instanceof ICompositeType ) - compositeType = (ICompositeType) binding; - } else if( fieldOwner instanceof IASTCastExpression ){ - IASTTypeId id = ((IASTCastExpression)fieldOwner).getTypeId(); - IBinding binding = resolveBinding( id ); - if( binding != null && binding instanceof ICompositeType ){ - compositeType = (ICompositeType) binding; - } + IType type = null; + if( fieldOwner instanceof IASTArraySubscriptExpression ){ + type = getExpressionType( ((IASTArraySubscriptExpression) fieldOwner).getArrayExpression() ); + } else { + type = getExpressionType( fieldOwner ); } - - IBinding binding = null; - if( compositeType != null ){ - binding = compositeType.findField( fieldReference.getFieldName().toString() ); + while( type != null && type instanceof ITypedef ) + type = ((ITypedef)type).getType(); + + if( type != null && type instanceof ICompositeType ){ + return ((ICompositeType) type).findField( fieldReference.getFieldName().toString() ); } - return binding; + return null; } + private static IType getExpressionType( IASTExpression expression ) { + if( expression instanceof IASTIdExpression ){ + IBinding binding = resolveBinding( expression ); + if( binding instanceof IVariable ){ + return ((IVariable)binding).getType(); + } + } else if( expression instanceof IASTCastExpression ){ + IASTTypeId id = ((IASTCastExpression)expression).getTypeId(); + IBinding binding = resolveBinding( id ); + if( binding != null && binding instanceof IType ){ + return (IType) binding; + } + } + return null; + } /** * @param parent * @return @@ -397,8 +418,8 @@ public class CVisitor { binding = checkForBinding( (IASTDeclaration) node, name ); } if( binding != null ){ - if( (bits & TAGS) != 0 && !(binding instanceof ICompositeType) || - (bits & TAGS) == 0 && (binding instanceof ICompositeType) ) + if( (bits & TAGS) != 0 && !(binding instanceof ICompositeType || binding instanceof IEnumeration) || + (bits & TAGS) == 0 && (binding instanceof ICompositeType || binding instanceof IEnumeration) ) { binding = null; } else { @@ -458,6 +479,22 @@ public class CVisitor { if( CharArrayUtils.equals( compName.toCharArray(), name.toCharArray() ) ){ return compName.resolveBinding(); } + } else if( declSpec instanceof ICASTEnumerationSpecifier ){ + ICASTEnumerationSpecifier enumeration = (ICASTEnumerationSpecifier) declSpec; + CASTName eName = (CASTName) enumeration.getName(); + if( CharArrayUtils.equals( eName.toCharArray(), name.toCharArray() ) ){ + return eName.resolveBinding(); + } + //check enumerators too + List list = enumeration.getEnumerators(); + for( int i = 0; i < list.size(); i++ ) { + IASTEnumerator enumerator = (IASTEnumerator) list.get(i); + eName = (CASTName) enumerator.getName(); + if( CharArrayUtils.equals( eName.toCharArray(), name.toCharArray() ) ){ + return eName.resolveBinding(); + } + } + } } else if( declaration instanceof IASTFunctionDefinition ){ IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration; @@ -658,9 +695,26 @@ public class CVisitor { if( !visitName( ((ICASTElaboratedTypeSpecifier) declSpec).getName(), action ) ) return false; } else if( declSpec instanceof ICASTTypedefNameSpecifier ){ if( !visitName( ((ICASTTypedefNameSpecifier) declSpec).getName(), action ) ) return false; + } else if( declSpec instanceof ICASTEnumerationSpecifier ){ + ICASTEnumerationSpecifier enumSpec = (ICASTEnumerationSpecifier) declSpec; + if( !visitName( enumSpec.getName(), action ) ) return false; + List list = enumSpec.getEnumerators(); + for( int i = 0; i < list.size(); i++ ){ + if( !visitEnumerator( (IASTEnumerator) list.get(i), action ) ) return false; + } + } return true; } + public static boolean visitEnumerator( IASTEnumerator enumerator, BaseVisitorAction action ){ + if( action.processEnumerators ) + if( !action.processEnumerator( enumerator ) ) return false; + + if( !visitName( enumerator.getName(), action ) ) return false; + if( enumerator.getValue() != null ) + if( !visitExpression( enumerator.getValue(), action ) ) return false; + return true; + } public static boolean visitStatement( IASTStatement statement, BaseVisitorAction action ){ if( action.processStatements ) if( !action.processStatement( statement ) ) return false; @@ -744,11 +798,11 @@ public class CVisitor { if( !visitName( ((IASTIdExpression)expression).getName(), action ) ) return false; } else if( expression instanceof IASTTypeIdExpression ){ if( !visitTypeId( ((IASTTypeIdExpression)expression).getTypeId(), action ) ) return false; + } else if( expression instanceof IASTCastExpression ){ + if( !visitTypeId( ((IASTCastExpression)expression).getTypeId(), action ) ) return false; + if( !visitExpression( ((IASTCastExpression)expression).getOperand(), action ) ) return false; } else if( expression instanceof IASTUnaryExpression ){ if( !visitExpression( ((IASTUnaryExpression)expression).getOperand(), action ) ) return false; - } else if( expression instanceof IASTCastExpression ){ - if( !visitExpression( ((IASTCastExpression)expression).getOperand(), action ) ) return false; - if( !visitTypeId( ((IASTCastExpression)expression).getTypeId(), action ) ) return false; } else if( expression instanceof ICASTTypeIdInitializerExpression ){ if( !visitTypeId( ((ICASTTypeIdInitializerExpression)expression).getTypeId(), action ) ) return false; if( !visitInitializer( ((ICASTTypeIdInitializerExpression)expression).getInitializer(), action ) ) return false;