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 be7905597ef..f48f742fc2d 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 @@ -91,7 +91,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; @@ -1535,6 +1534,43 @@ public class AST2CPPTests extends AST2BaseTest { } } + // struct A { + // A(int x); + // A(char x); + // }; + // + // A a = A(1); + public void testConstructorCall() throws Exception { + BindingAssertionHelper bh = new BindingAssertionHelper(getAboveComment(), CPP); + ICPPConstructor ctor = bh.assertNonProblem("A(int x)", "A", ICPPConstructor.class); + ICPPClassType classType = bh.assertNonProblem("A(1)", "A", ICPPClassType.class); + assertSame(ctor.getOwner(), classType); + IASTName name = bh.findName("A(1)", "A"); + IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) name.getParent().getParent()).getImplicitNames(); + assertEquals(1, implicitNames.length); + IBinding ctor2 = implicitNames[0].getBinding(); + assertSame(ctor, ctor2); + } + + // struct A { + // A(int x); + // }; + // struct B { + // operator A(); + // }; + // + // void test() { + // B b; + // A a = A(b); + // } + public void _testConversionOperator() throws Exception { + BindingAssertionHelper bh = new BindingAssertionHelper(getAboveComment(), CPP); + ICPPMethod oper = bh.assertNonProblem("operator A", "operator A", ICPPMethod.class); + ICPPMethod conv = bh.assertNonProblem("A(b)", "A", ICPPMethod.class); + // This assertion fails because conv is the copy ctor A(const A&), not the conversion operator B::operator A() + assertSame(oper, conv); + } + // namespace A { int x; } // namespace B = A; // int f(){ B::x; } @@ -2581,25 +2617,25 @@ public class AST2CPPTests extends AST2BaseTest { assertTrue(d.getNestedDeclarator().getPointerOperators()[0] instanceof ICPPASTPointerToMember); } - // struct T1 { - // T1 operator() (int x) { - // return T1(x); + // struct A { + // A operator()(int x) { + // return A(x); // } - // T1(int) {} + // A(int) {} // }; public void testBug86336() throws Exception { - IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP); - CPPNameCollector col = new CPPNameCollector(); - tu.accept(col); - - ICPPConstructor T1_ctor = (ICPPConstructor) col.getName(6).resolveBinding(); - ICPPClassType T1 = (ICPPClassType) col.getName(0).resolveBinding(); - assertInstances(col, T1_ctor, 1); - assertInstances(col, T1, 3); - - ICPPASTFunctionCallExpression fc= (ICPPASTFunctionCallExpression) col.getName(4).getParent().getParent(); - IBinding ctor2 = fc.getImplicitNames()[0].resolveBinding(); - assertSame(T1_ctor, ctor2); + BindingAssertionHelper bh = getAssertionHelper(); + ICPPClassType clazz = bh.assertNonProblem("A {", "A", ICPPClassType.class); + ICPPConstructor ctor = bh.assertNonProblem("A(int)", "A", ICPPConstructor.class); + ICPPClassType clazz2 = bh.assertNonProblem("A(x)", "A", ICPPClassType.class); + assertSame(clazz, clazz2); + clazz2 = bh.assertNonProblem("A operator", "A", ICPPClassType.class); + assertSame(clazz, clazz2); + IASTName name = bh.findName("A(x)", "A"); + IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) name.getParent().getParent()).getImplicitNames(); + assertEquals(1, implicitNames.length); + IBinding ctor2 = implicitNames[0].getBinding(); + assertSame(ctor, ctor2); } // struct S { int i; }; @@ -3783,6 +3819,24 @@ public class AST2CPPTests extends AST2BaseTest { assertTrue(((ITypedef) binding).getType() instanceof IFunctionType); } + // struct A { + // A(int x); + // }; + // typedef A B; + // + // B a = B(1); + public void testTypedefConstructorCall() throws Exception { + BindingAssertionHelper bh = new BindingAssertionHelper(getAboveComment(), CPP); + ICPPConstructor ctor = bh.assertNonProblem("A(int x)", "A", ICPPConstructor.class); + ITypedef typedef = bh.assertNonProblem("B(1)", "B", ITypedef.class); + assertSame(ctor.getOwner(), typedef.getType()); + IASTName name = bh.findName("B(1)", "B"); + IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) name.getParent().getParent()).getImplicitNames(); + assertEquals(1, implicitNames.length); + IBinding ctor2 = implicitNames[0].getBinding(); + assertSame(ctor, ctor2); + } + // void f(int); // void foo(){ // f((1, 2)); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 2f54ed2d440..697bb86045b 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -18,6 +18,9 @@ import static org.eclipse.cdt.core.parser.ParserLanguage.CPP; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateType; + +import java.io.IOException; + import junit.framework.TestSuite; import org.eclipse.cdt.core.dom.IName; @@ -29,6 +32,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTImplicitName; +import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNodeSelector; @@ -50,7 +54,6 @@ 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.cpp.ICPPASTExplicitTemplateInstantiation; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; @@ -90,6 +93,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; +import org.eclipse.cdt.internal.core.parser.ParserException; public class AST2TemplateTests extends AST2BaseTest { @@ -112,6 +116,11 @@ public class AST2TemplateTests extends AST2BaseTest { return parseAndCheckBindings(code, CPP); } + protected BindingAssertionHelper getAssertionHelper() throws ParserException, IOException { + String code= getAboveComment(); + return new BindingAssertionHelper(code, true); + } + public void testBasicClassTemplate() throws Exception { IASTTranslationUnit tu = parse("template class A{ T t; };", CPP); //$NON-NLS-1$ CPPNameCollector col = new CPPNameCollector(); @@ -1720,23 +1729,19 @@ public class AST2TemplateTests extends AST2BaseTest { // void m(){ // f(A(1)); // } - public void testBug99254() throws Exception{ - IASTTranslationUnit tu = parse(getAboveComment(), CPP); - CPPNameCollector col = new CPPNameCollector(); - tu.accept(col); - - ICPPConstructor ctor = (ICPPConstructor) col.getName(2).resolveBinding(); - ICPPFunction f = (ICPPFunction) col.getName(5).resolveBinding(); - - final IASTName typeConversion = col.getName(11); - ICPPSpecialization spec = (ICPPSpecialization) typeConversion.resolveBinding(); + public void testBug99254_1() throws Exception { + BindingAssertionHelper bh= getAssertionHelper(); + ICPPConstructor ctor = bh.assertNonProblem("A(T t)", "A", ICPPConstructor.class); + ICPPSpecialization spec = bh.assertNonProblem("A(1)", "A", ICPPSpecialization.class); assertSame(ctor.getOwner(), spec.getSpecializedBinding()); - - final ICPPASTFunctionCallExpression fcall = (ICPPASTFunctionCallExpression) typeConversion.getParent().getParent(); - final IBinding ctorSpec = fcall.getImplicitNames()[0].resolveBinding(); - assertSame(ctor, (((ICPPSpecialization) ctorSpec).getSpecializedBinding())); - - assertSame(f, col.getName(10).resolveBinding()); + IASTName name = bh.findName("A(1)", "A"); + IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) name.getParent().getParent()).getImplicitNames(); + assertEquals(1, implicitNames.length); + ICPPSpecialization ctor2 = (ICPPSpecialization) implicitNames[0].getBinding(); + assertSame(ctor, ctor2.getSpecializedBinding()); + ICPPFunction f = bh.assertNonProblem("f(A a)", "f", ICPPFunction.class); + ICPPFunction f2 = bh.assertNonProblem("f(A(1))", "f", ICPPFunction.class); + assertSame(f, f2); } // namespace core { @@ -1745,67 +1750,59 @@ public class AST2TemplateTests extends AST2BaseTest { // }; // } // class B { - // int add(const core::A &rect); + // int add(const core::A& rect); // }; // void f(B* b){ // b->add(core::A(10, 2)); // } public void testBug99254_2() throws Exception { - IASTTranslationUnit tu = parse(getAboveComment(), CPP); - CPPNameCollector col = new CPPNameCollector(); - tu.accept(col); - - ICPPConstructor ctor = (ICPPConstructor) col.getName(3).resolveBinding(); - ICPPMethod add = (ICPPMethod) col.getName(9).resolveBinding(); - - final IASTName typeConversion = col.getName(20); - ICPPSpecialization spec = (ICPPSpecialization) typeConversion.resolveBinding(); + BindingAssertionHelper bh= getAssertionHelper(); + ICPPConstructor ctor = bh.assertNonProblem("A(T x, T y)", "A", ICPPConstructor.class); + ICPPSpecialization spec = bh.assertNonProblem("A(10, 2)", "A", ICPPSpecialization.class); assertSame(ctor.getOwner(), spec.getSpecializedBinding()); - - final ICPPASTFunctionCallExpression fcall = (ICPPASTFunctionCallExpression) typeConversion.getParent().getParent(); - final IBinding ctorSpec = fcall.getImplicitNames()[0].resolveBinding(); - assertSame(ctor, (((ICPPSpecialization) ctorSpec).getSpecializedBinding())); - - assertSame(add, col.getName(19).resolveBinding()); + IASTName name = bh.findName("A(10, 2)", "A"); + IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) name.getParent().getParent().getParent()).getImplicitNames(); + assertEquals(1, implicitNames.length); + ICPPSpecialization ctor2 = (ICPPSpecialization) implicitNames[0].getBinding(); + assertSame(ctor, ctor2.getSpecializedBinding()); + ICPPMethod add = bh.assertNonProblem("add(const core::A& rect)", "add", ICPPMethod.class); + ICPPMethod add2 = bh.assertNonProblem("b->add(core::A(10, 2))", "add", ICPPMethod.class); + assertSame(add, add2); } // template class A { A(T); }; // typedef signed int s32; // class B { - // int add(const A &rect); + // int add(const A& rect); // }; // void f(B* b){ // b->add(A(10)); // } public void testBug99254_3() throws Exception { - IASTTranslationUnit tu = parse(getAboveComment(), CPP); - CPPNameCollector col = new CPPNameCollector(); - tu.accept(col); - - ICPPConstructor ctor = (ICPPConstructor) col.getName(2).resolveBinding(); - ICPPMethod add = (ICPPMethod) col.getName(7).resolveBinding(); - - final IASTName typeConversion = col.getName(17); - ICPPSpecialization spec = (ICPPSpecialization) typeConversion.resolveBinding(); + BindingAssertionHelper bh= getAssertionHelper(); + ICPPConstructor ctor = bh.assertNonProblem("A(T)", "A", ICPPConstructor.class); + ICPPSpecialization spec = bh.assertNonProblem("A(10)", "A", ICPPSpecialization.class); assertSame(ctor.getOwner(), spec.getSpecializedBinding()); - - final ICPPASTFunctionCallExpression fcall = (ICPPASTFunctionCallExpression) typeConversion.getParent().getParent(); - final IBinding ctorSpec = fcall.getImplicitNames()[0].resolveBinding(); - assertSame(ctor, (((ICPPSpecialization) ctorSpec).getSpecializedBinding())); - - assertSame(add, col.getName(16).resolveBinding()); + IASTName name = bh.findName("A(10)", "A"); + IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) name.getParent().getParent()).getImplicitNames(); + assertEquals(1, implicitNames.length); + ICPPSpecialization ctor2 = (ICPPSpecialization) implicitNames[0].getBinding(); + assertSame(ctor, ctor2.getSpecializedBinding()); + ICPPMethod add = bh.assertNonProblem("add(const A& rect)", "add", ICPPMethod.class); + ICPPMethod add2 = bh.assertNonProblem("b->add(A(10))", "add", ICPPMethod.class); + assertSame(add, add2); } public void testBug98666() throws Exception { CPPASTNameBase.sAllowNameComputation= true; - IASTTranslationUnit tu = parse("A::template B b;", CPP); //$NON-NLS-1$ + IASTTranslationUnit tu = parse("A::template B b;", CPP); CPPNameCollector col = new CPPNameCollector(); tu.accept(col); ICPPASTQualifiedName qn = (ICPPASTQualifiedName) col.getName(0); IASTName[] ns = qn.getNames(); assertTrue(ns[1] instanceof ICPPASTTemplateId); - assertEquals(ns[1].toString(), "B"); //$NON-NLS-1$ + assertEquals(ns[1].toString(), "B"); } // template struct A{ diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/VariableReadWriteFlagsTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/VariableReadWriteFlagsTest.java index c0ef5db339e..694a90a7186 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/VariableReadWriteFlagsTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/VariableReadWriteFlagsTest.java @@ -159,6 +159,32 @@ public class VariableReadWriteFlagsTest extends AST2BaseTest { a.assertReadWriteFlags("g(&a, b, c)", "c", READ); } + // struct A { + // A(int* x, int& y); + // A(const int* x, const int& y, int z); + // }; + // + // void test(int a, int b, int c) { + // A(&a, b); + // A x(&a, b); + // A(&a, b, c); + // A y(&a, b, c); + // }; + public void testConstructorCall_393068() throws Exception { + AssertionHelper a = getCPPAssertionHelper(); +// a.assertReadWriteFlags("A(&a, b)", "a", READ | WRITE); +// a.assertReadWriteFlags("A(&a, b)", "b", READ | WRITE); +// a.assertReadWriteFlags("x(&a, b)", "a", READ | WRITE); +// a.assertReadWriteFlags("x(&a, b)", "b", READ | WRITE); +// a.assertReadWriteFlags("x(&a, b)", "x", WRITE); + a.assertReadWriteFlags("A(&a, b, c)", "a", READ); + a.assertReadWriteFlags("A(&a, b, c)", "b", READ); + a.assertReadWriteFlags("A(&a, b, c)", "c", READ); + a.assertReadWriteFlags("y(&a, b, c)", "a", READ); + a.assertReadWriteFlags("y(&a, b, c)", "b", READ); + a.assertReadWriteFlags("y(&a, b, c)", "c", READ); + } + // struct A { // void m(); // void mc() const; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java index 0b48e9065fb..a800794bc05 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java @@ -28,6 +28,8 @@ import org.eclipse.cdt.core.dom.ast.IASTForStatement; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIfStatement; +import org.eclipse.cdt.core.dom.ast.IASTImplicitName; +import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner; import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTInitializerList; import org.eclipse.cdt.core.dom.ast.IASTNode; @@ -41,6 +43,7 @@ import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IASTWhileStatement; import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IVariable; @@ -188,6 +191,15 @@ public abstract class VariableReadWriteFlags { final IType type= functionNameExpression.getExpressionType(); if (type instanceof IFunctionType) { return rwArgumentForFunctionCall((IFunctionType) type, i, indirection); + } else { + IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) funcCall).getImplicitNames(); + if (implicitNames.length == 1) { + IASTImplicitName name = implicitNames[0]; + IBinding binding = name.resolveBinding(); + if (binding instanceof IFunction) { + return rwArgumentForFunctionCall(((IFunction) binding).getType(), i, indirection); + } + } } } break;