From 2f68844e687994b43346f9110d1613009efc3e94 Mon Sep 17 00:00:00 2001 From: Andrew Niefer Date: Thu, 7 Apr 2005 20:00:54 +0000 Subject: [PATCH] fixing bugs: 90616 - Type of an expression list is the type of last item in list 90603 - array out of bounds in CPPMethod.getScope 90662 - handle invalid redefinition of class 90608 - Don't add simpleDeclarations as function definitions 90633 - only use parameters for nodes with property IASTFunctionCallExpression.FUNCTION_NAME --- .../tests/ast2/AST2CPPSpecFailingTest.java | 80 +------------------ .../parser/tests/ast2/AST2CPPSpecTest.java | 80 +++++++++++++++++++ .../core/parser/tests/ast2/AST2CPPTests.java | 54 +++++++++++++ .../core/dom/parser/cpp/CPPMethod.java | 3 +- .../core/dom/parser/cpp/CPPSemantics.java | 9 ++- .../core/dom/parser/cpp/CPPVisitor.java | 13 ++- 6 files changed, 154 insertions(+), 85 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java index 0cb3c11f954..94e3ca4eb51 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java @@ -270,29 +270,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest { } } - /** - [--Start Example(CPP 5.18-2): - int f(int, int, int) {} - int foo() { - int a=0, t=1, c=2; - f(a, (t=3, t+2), c); - } - --End Example] - */ - public void test5_18s2() { // TODO Devin raised bug 90616 - StringBuffer buffer = new StringBuffer(); - buffer.append("int f(int, int, int) {}\n"); //$NON-NLS-1$ - buffer.append("int foo() {\n"); //$NON-NLS-1$ - buffer.append("int a=0, t=1, c=2;\n"); //$NON-NLS-1$ - buffer.append("f(a, (t=3, t+2), c);\n"); //$NON-NLS-1$ - buffer.append("}\n"); //$NON-NLS-1$ - try { - parse(buffer.toString(), ParserLanguage.CPP, true, true); - assertTrue(false); - } catch (Exception e) { - } - } - /** [--Start Example(CPP 6.4-3): int foo() { @@ -515,7 +492,7 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest { } --End Example] */ - public void _test8_2s7a() { // TODO Devin raised bug 90633 + public void test8_2s7a() { // TODO Devin raised bug 90633 StringBuffer buffer = new StringBuffer(); buffer.append("class C { };\n"); //$NON-NLS-1$ buffer.append("void f(int(C)) { } // void f(int (*fp)(C c)) { }\n"); //$NON-NLS-1$ @@ -737,61 +714,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest { } } - /** - [--Start Example(CPP 12.7-1): - struct X { int i; }; - struct Y : X { }; - struct A { int a; }; - struct B : public A { int j; Y y; }; - extern B bobj; - B* pb = &bobj; // OK - int* p1 = &bobj.a; // undefined, refers to base class member - int* p2 = &bobj.y.i; // undefined, refers to member’s member - A* pa = &bobj; // undefined, upcast to a base class type - B bobj; // definition of bobj - extern X xobj; - int* p3 = &xobj.i; // OK, X is a POD class - X xobj; - struct W { int j; }; - struct X : public virtual W { }; - struct Y { - int *p; - X x; - Y() : p(&x.j) // undefined, x is not yet constructed - { } - }; - --End Example] - */ - public void test12_7s1() { // TODO Devin raised bug 90662 - StringBuffer buffer = new StringBuffer(); - buffer.append("struct X { int i; };\n"); //$NON-NLS-1$ - buffer.append("struct Y : X { };\n"); //$NON-NLS-1$ - buffer.append("struct A { int a; };\n"); //$NON-NLS-1$ - buffer.append("struct B : public A { int j; Y y; };\n"); //$NON-NLS-1$ - buffer.append("extern B bobj;\n"); //$NON-NLS-1$ - buffer.append("B* pb = &bobj; // OK\n"); //$NON-NLS-1$ - buffer.append("int* p1 = &bobj.a; // undefined, refers to base class member\n"); //$NON-NLS-1$ - buffer.append("int* p2 = &bobj.y.i; // undefined, refers to member’s member\n"); //$NON-NLS-1$ - buffer.append("A* pa = &bobj; // undefined, upcast to a base class type\n"); //$NON-NLS-1$ - buffer.append("B bobj; // definition of bobj\n"); //$NON-NLS-1$ - buffer.append("extern X xobj;\n"); //$NON-NLS-1$ - buffer.append("int* p3 = &xobj.i; // OK, X is a POD class\n"); //$NON-NLS-1$ - buffer.append("X xobj;\n"); //$NON-NLS-1$ - buffer.append("struct W { int j; };\n"); //$NON-NLS-1$ - buffer.append("struct X : public virtual W { };\n"); //$NON-NLS-1$ - buffer.append("struct Y {\n"); //$NON-NLS-1$ - buffer.append("int *p;\n"); //$NON-NLS-1$ - buffer.append("X x;\n"); //$NON-NLS-1$ - buffer.append("Y() : p(&x.j) // undefined, x is not yet constructed\n"); //$NON-NLS-1$ - buffer.append("{ }\n"); //$NON-NLS-1$ - buffer.append("};\n"); //$NON-NLS-1$ - try { - parse(buffer.toString(), ParserLanguage.CPP, true, true); - assertTrue(false); - } catch (Exception e) { - } - } - /** [--Start Example(CPP 12.7-2): struct A { }; diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java index 4e12cc1f7c0..e640ccd732c 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java @@ -1455,6 +1455,25 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest { parse(buffer.toString(), ParserLanguage.CPP, true, true); } + /** + [--Start Example(CPP 5.18-2): + int f(int, int, int) {} + int foo() { + int a=0, t=1, c=2; + f(a, (t=3, t+2), c); + } + --End Example] + */ + public void test5_18s2() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("int f(int, int, int) {}\n"); //$NON-NLS-1$ + buffer.append("int foo() {\n"); //$NON-NLS-1$ + buffer.append("int a=0, t=1, c=2;\n"); //$NON-NLS-1$ + buffer.append("f(a, (t=3, t+2), c);\n"); //$NON-NLS-1$ + buffer.append("}\n"); //$NON-NLS-1$ + parse(buffer.toString(), ParserLanguage.CPP, true, true); + } + /** [--Start Example(CPP 6.4-1): int foo() { @@ -7037,6 +7056,67 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest { parse(buffer.toString(), ParserLanguage.CPP, true, true); } + /** + [--Start Example(CPP 12.7-1 a): + struct X { int i; }; + struct Y : X { }; + struct A { int a; }; + struct B : public A { int j; Y y; }; + extern B bobj; + B* pb = &bobj; // OK + int* p1 = &bobj.a; // undefined, refers to base class member + int* p2 = &bobj.y.i; // undefined, refers to member’s member + A* pa = &bobj; // undefined, upcast to a base class type + B bobj; // definition of bobj + extern X xobj; + int* p3 = &xobj.i; // OK, X is a POD class + X xobj; + --End Example] + */ + public void test12_7s1_a() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("struct X { int i; };\n"); //$NON-NLS-1$ + buffer.append("struct Y : X { };\n"); //$NON-NLS-1$ + buffer.append("struct A { int a; };\n"); //$NON-NLS-1$ + buffer.append("struct B : public A { int j; Y y; };\n"); //$NON-NLS-1$ + buffer.append("extern B bobj;\n"); //$NON-NLS-1$ + buffer.append("B* pb = &bobj; // OK\n"); //$NON-NLS-1$ + buffer.append("int* p1 = &bobj.a; // undefined, refers to base class member\n"); //$NON-NLS-1$ + buffer.append("int* p2 = &bobj.y.i; // undefined, refers to member’s member\n"); //$NON-NLS-1$ + buffer.append("A* pa = &bobj; // undefined, upcast to a base class type\n"); //$NON-NLS-1$ + buffer.append("B bobj; // definition of bobj\n"); //$NON-NLS-1$ + buffer.append("extern X xobj;\n"); //$NON-NLS-1$ + buffer.append("int* p3 = &xobj.i; // OK, X is a POD class\n"); //$NON-NLS-1$ + buffer.append("X xobj;\n"); //$NON-NLS-1$ + parse(buffer.toString(), ParserLanguage.CPP, true, true); + } + + /** + [--Start Example(CPP 12.7-1 b): + struct W { int j; }; + struct X : public virtual W { }; + struct Y { + int *p; + X x; + Y() : p(&x.j) // undefined, x is not yet constructed + { } + }; + --End Example] + */ + public void test12_7s1_b() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("struct W { int j; };\n"); //$NON-NLS-1$ + buffer.append("struct X : public virtual W { };\n"); //$NON-NLS-1$ + buffer.append("struct Y {\n"); //$NON-NLS-1$ + buffer.append("int *p;\n"); //$NON-NLS-1$ + buffer.append("X x;\n"); //$NON-NLS-1$ + buffer.append("Y() : p(&x.j) // undefined, x is not yet constructed\n"); //$NON-NLS-1$ + buffer.append("{ }\n"); //$NON-NLS-1$ + buffer.append("};\n"); //$NON-NLS-1$ + + parse(buffer.toString(), ParserLanguage.CPP, true, true); + } + /** [--Start Example(CPP 12.7-3): class V { diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index df79bf45fb0..b8a4c867934 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -70,6 +70,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias; @@ -3359,5 +3360,58 @@ public class AST2CPPTests extends AST2BaseTest { assertTrue( binding instanceof ITypedef ); assertTrue( ((ITypedef)binding).getType() instanceof IFunctionType ); } + + public void testBug90616() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append( "void f( int ); \n"); //$NON-NLS-1$ + buffer.append( "void foo(){ \n"); //$NON-NLS-1$ + buffer.append( " f( ( 1, 2 ) ); \n"); //$NON-NLS-1$ + buffer.append( "} \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); //$NON-NLS-1$ + CPPNameCollector col = new CPPNameCollector(); + tu.accept( col ); + + IFunction f1 = (IFunction) col.getName(0).resolveBinding(); + IFunction f2 = (IFunction) col.getName(3).resolveBinding(); + assertSame( f1, f2 ); + } + + public void testBug90603() throws Exception { + IASTTranslationUnit tu = parse( "class X { void f(){} };", ParserLanguage.CPP ); //$NON-NLS-1$ + CPPNameCollector col = new CPPNameCollector(); + tu.accept( col ); + + ICPPClassType X = (ICPPClassType) col.getName(0).resolveBinding(); + ICPPMethod f1 = (ICPPMethod) col.getName(1).resolveBinding(); + + assertFalse( f1.isStatic() ); + + String[] qns = f1.getQualifiedName(); + assertEquals( qns.length, 2 ); + assertEquals( qns[0], "X" ); //$NON-NLS-1$ + assertEquals( qns[1], "f" ); //$NON-NLS-1$ + assertTrue( f1.isGloballyQualified() ); + assertEquals( f1.getVisibility(), ICPPMember.v_private ); + + assertSame( f1.getScope(), X.getCompositeScope() ); + } + + public void testBug90662() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("class X { }; \n"); //$NON-NLS-1$ + buffer.append("X x; \n"); //$NON-NLS-1$ + buffer.append("class X { }; \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); //$NON-NLS-1$ + CPPNameCollector col = new CPPNameCollector(); + tu.accept( col ); + + ICPPClassType X = (ICPPClassType) col.getName(0).resolveBinding(); + IVariable x = (IVariable) col.getName(2).resolveBinding(); + IProblemBinding problem = (IProblemBinding) col.getName(3).resolveBinding(); + assertSame( x.getType(), X ); + assertEquals( problem.getID(), IProblemBinding.SEMANTIC_INVALID_REDEFINITION ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethod.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethod.java index 0f9d00564ce..c59f768df60 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethod.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethod.java @@ -125,7 +125,8 @@ public class CPPMethod extends CPPFunction implements ICPPMethod { } public IScope getScope() { - return CPPVisitor.getContainingScope( declarations != null ? declarations[0] : definition ); + IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : definition; + return CPPVisitor.getContainingScope( node ); } public String getName() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java index 9630acfaf1f..13388eee04c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java @@ -493,8 +493,9 @@ public class CPPSemantics { if( parent instanceof ICPPASTFunctionDeclarator ){ data.functionParameters = ((ICPPASTFunctionDeclarator)parent).getParameters(); } else if( parent instanceof IASTIdExpression ){ - parent = parent.getParent(); - if( parent instanceof IASTFunctionCallExpression ){ + ASTNodeProperty prop = parent.getPropertyInParent(); + if( prop == IASTFunctionCallExpression.FUNCTION_NAME ){ + parent = parent.getParent(); IASTExpression exp = ((IASTFunctionCallExpression)parent).getParameterExpression(); if( exp instanceof IASTExpressionList ) data.functionParameters = ((IASTExpressionList) exp ).getExpressions(); @@ -503,7 +504,7 @@ public class CPPSemantics { else data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY; } - } else if( parent instanceof ICPPASTFieldReference && parent.getParent() instanceof IASTFunctionCallExpression ){ + } else if( parent instanceof ICPPASTFieldReference && parent.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME ){ IASTExpression exp = ((IASTFunctionCallExpression)parent.getParent()).getParameterExpression(); if( exp instanceof IASTExpressionList ) data.functionParameters = ((IASTExpressionList) exp ).getExpressions(); @@ -1291,7 +1292,7 @@ public class CPPSemantics { IASTNode node = name.getParent(); if( node instanceof ICPPASTQualifiedName ) node = node.getParent(); - if( node instanceof ICPPASTFunctionDeclarator ){ + if( node instanceof ICPPASTFunctionDeclarator && node.getParent() instanceof IASTFunctionDefinition ){ if( binding instanceof ICPPInternalBinding ) ((ICPPInternalBinding)binding).addDefinition( node ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index 10ecf5ece85..13ac731caf0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -29,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier; import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IASTExpressionList; import org.eclipse.cdt.core.dom.ast.IASTFieldReference; import org.eclipse.cdt.core.dom.ast.IASTForStatement; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; @@ -349,7 +350,14 @@ public class CPPVisitor { binding = new CPPClassType( name ); scope.addName( compType.getName() ); } else { - ((CPPClassType)binding).addDefinition( compType ); + if( binding instanceof ICPPInternalBinding ){ + ICPPInternalBinding internal = (ICPPInternalBinding) binding; + if( internal.getDefinition() == null ) + internal.addDefinition( compType ); + else + binding = new ProblemBinding( name, IProblemBinding.SEMANTIC_INVALID_REDEFINITION, name.toCharArray() ); + } + } } catch ( DOMException e ) { binding = e.getProblem(); @@ -1542,6 +1550,9 @@ public class CPPVisitor { } catch ( DOMException e ) { return e.getProblem(); } + } else if( expression instanceof IASTExpressionList ){ + IASTExpression [] exps = ((IASTExpressionList)expression).getExpressions(); + return getExpressionType( exps[ exps.length - 1 ] ); } return null; }