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 f33983ef204..00cb7c33a1d 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 @@ -1276,7 +1276,7 @@ public class AST2CPPTests extends AST2TestBase { assertInstances(collector, x2, 1); } - // class A { }; + // class A {}; public void testImplicitConstructors() throws Exception { IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP); @@ -1561,6 +1561,18 @@ public class AST2CPPTests extends AST2TestBase { assertSame(ctor, ctor2); } + // struct A { + // A(int x, int y); + // }; + // + // void test() { + // A a("hi", 5, 10); + // } + public void testInvalidImplicitConstructorCall() throws Exception { + BindingAssertionHelper bh = getAssertionHelper(); + bh.assertImplicitName("a", 1, IProblemBinding.class); + } + // struct A { // A(int x); // }; @@ -8391,9 +8403,7 @@ public class AST2CPPTests extends AST2TestBase { // fH({1}); // H(G(1)) // } public void testListInitialization_302412f() throws Exception { - IProblemBinding problem; - String code= getAboveComment(); - BindingAssertionHelper bh= new BindingAssertionHelper(code, true); + BindingAssertionHelper bh= getAssertionHelper(); bh.assertProblem("f({1,1})", 1); bh.assertImplicitName("F({1,1})", 1, ICPPConstructor.class); bh.assertNonProblem("fF({1,1})", 2); @@ -8402,13 +8412,9 @@ public class AST2CPPTests extends AST2TestBase { bh.assertNonProblem("fG({1})", 2); bh.assertImplicitName("H(1)", 1, ICPPConstructor.class); - bh.assertNoImplicitName("H({1})", 1); - // TODO(nathanridge): Perhaps we should store implicit names even if they - // resolve to ProblemBindings. Then we can do the stronger check in the - // 3 commented lines below. - //IASTImplicitName n= bh.assertImplicitName("H({1})", 1, IProblemBinding.class); - //problem= (IProblemBinding) n.resolveBinding(); - //assertEquals(IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, problem.getID()); + IASTImplicitName n= bh.assertImplicitName("H({1})", 1, IProblemBinding.class); + IProblemBinding problem= (IProblemBinding) n.resolveBinding(); + assertEquals(IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, problem.getID()); bh.assertProblem("fH(1)", 2); bh.assertNonProblem("fH({1})", 2); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTImplicitName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTImplicitName.java index d239176555b..886801825f9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTImplicitName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTImplicitName.java @@ -27,34 +27,32 @@ public interface IASTImplicitName extends IASTName { * {@inheritDoc} * Redeclared with strengthened postcondition. * - * Will not return null or a problem binding. - * Implicit names are not generated unless they resolve to something. + * Will not return {@code null}, but may return a problem binding, for example for an implicit + * constructor call. */ @Override public IBinding resolveBinding(); /** - * Returns true if this node is an alternate. + * Returns {@code true} if this node is an alternate. * - * Sometimes more than one implicit name is generated for the same binding - * but with different offsets, when this happens the additional names - * generated are considered alternates. + * Sometimes more than one implicit name is generated for the same binding but with different + * offsets, when this happens the additional names generated are considered alternates. * * @see ASTVisitor#shouldVisitImplicitNameAlternates */ public boolean isAlternate(); /** - * Convenience method that returns true if this - * name represents an overloaded operator. + * Convenience method that returns true if this name represents an overloaded operator. */ public boolean isOperator(); /** * This method is not supported on implicit names. * - * Implicit names are not copied when an AST is copied, - * instead the implicit names are regenerated when needed. + * Implicit names are not copied when an AST is copied, instead the implicit names are + * regenerated when needed. * * @throws UnsupportedOperationException always */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java index e98bd8708bc..d9b96c6ca88 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java @@ -241,7 +241,7 @@ public class CPPASTConstructorChainInitializer extends ASTNode implements @Override public IASTImplicitName[] getImplicitNames() { if (implicitNames == null) { - ICPPConstructor ctor = CPPSemantics.findImplicitlyCalledConstructor(this); + IBinding ctor = CPPSemantics.findImplicitlyCalledConstructor(this); if (ctor == null) { implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; } else { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeclarator.java index 8b503ce3b30..82406fdc64b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeclarator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeclarator.java @@ -28,11 +28,11 @@ import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTTypeId; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; 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.ASTQueries; @@ -305,7 +305,7 @@ public class CPPASTDeclarator extends ASTNode implements ICPPASTDeclarator, IAST @Override public IASTImplicitName[] getImplicitNames() { if (implicitNames == null) { - ICPPConstructor ctor = CPPSemantics.findImplicitlyCalledConstructor(this); + IBinding ctor = CPPSemantics.findImplicitlyCalledConstructor(this); if (ctor == null) { implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; } else { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java index ac823d098d6..5c6098b719c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java @@ -28,10 +28,10 @@ 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.IBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; 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.ASTQueries; @@ -175,7 +175,7 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression } CPPASTImplicitName constructorName = null; - ICPPConstructor constructor = CPPSemantics.findImplicitlyCalledConstructor(this); + IBinding constructor = CPPSemantics.findImplicitlyCalledConstructor(this); if (constructor != null) { constructorName = new CPPASTImplicitName(constructor.getNameCharArray(), this); constructorName.setBinding(constructor); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index fba2efd2066..ee7f8c4d3a4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -3074,9 +3074,9 @@ public class CPPSemantics { } /** - * Returns constructor called by a declarator, or null if no constructor is called. + * Returns constructor called by a declarator, or {@code null} if no constructor is called. */ - public static ICPPConstructor findImplicitlyCalledConstructor(final ICPPASTDeclarator declarator) { + public static IBinding findImplicitlyCalledConstructor(final ICPPASTDeclarator declarator) { if (declarator.getNestedDeclarator() != null) return null; IASTDeclarator dtor= ASTQueries.findOutermostDeclarator(declarator); @@ -3100,17 +3100,17 @@ public class CPPSemantics { /** * Returns constructor called by a class member initializer in a constructor initializer chain. - * Returns null if no constructor is called. + * Returns {@code null} if no constructor is called. */ - public static ICPPConstructor findImplicitlyCalledConstructor(ICPPASTConstructorChainInitializer initializer) { + public static IBinding findImplicitlyCalledConstructor(ICPPASTConstructorChainInitializer initializer) { return findImplicitlyCalledConstructor(initializer.getMemberInitializerId(), initializer.getInitializer()); } /** - * Returns constructor called by a variable declarator or an initializer in a constructor initializer - * chain. Returns null if no constructor is called. + * Returns constructor called by a variable declarator or an initializer in a constructor + * initializer chain. Returns {@code null} if no constructor is called. */ - private static ICPPConstructor findImplicitlyCalledConstructor(IASTName name, IASTInitializer initializer) { + private static IBinding findImplicitlyCalledConstructor(IASTName name, IASTInitializer initializer) { IBinding binding = name.resolveBinding(); if (!(binding instanceof ICPPVariable)) return null; @@ -3125,7 +3125,7 @@ public class CPPSemantics { return findImplicitlyCalledConstructor((ICPPClassType) type, initializer, name); } - public static ICPPConstructor findImplicitlyCalledConstructor(ICPPASTNewExpression expr) { + public static IBinding findImplicitlyCalledConstructor(ICPPASTNewExpression expr) { IType type = getNestedType(expr.getExpressionType(), TDEF | REF | CVTYPE); if (!(type instanceof IPointerType)) return null; @@ -3137,7 +3137,7 @@ public class CPPSemantics { return null; } - private static ICPPConstructor findImplicitlyCalledConstructor(ICPPClassType type, IASTInitializer initializer, + private static IBinding findImplicitlyCalledConstructor(ICPPClassType type, IASTInitializer initializer, IASTNode typeId) { try { if (initializer instanceof IASTEqualsInitializer) { @@ -3157,7 +3157,7 @@ public class CPPSemantics { if (c.converts()) { ICPPFunction f = c.getUserDefinedConversion(); if (f instanceof ICPPConstructor) - return (ICPPConstructor) f; + return f; // If a conversion is used, the constructor is elided. } } @@ -3169,7 +3169,7 @@ public class CPPSemantics { if (c.converts()) { ICPPFunction f = c.getUserDefinedConversion(); if (f instanceof ICPPConstructor) - return (ICPPConstructor) f; + return f; } } } else if (initializer instanceof ICPPASTConstructorInitializer) { @@ -3190,7 +3190,7 @@ public class CPPSemantics { return null; } - private static ICPPConstructor findImplicitlyCalledConstructor(ICPPClassType classType, + private static IBinding findImplicitlyCalledConstructor(ICPPClassType classType, ICPPASTConstructorInitializer initializer, IASTNode typeId) { final IASTInitializerClause[] arguments = initializer.getArguments(); CPPASTName astName = new CPPASTName(); @@ -3204,14 +3204,11 @@ public class CPPSemantics { data.setFunctionArguments(false, arguments); data.qualified = true; data.foundItems = ClassTypeHelper.getConstructors(classType, typeId); - IBinding binding; try { - binding = resolveAmbiguities(data); - if (binding instanceof ICPPConstructor) - return (ICPPConstructor) binding; + return resolveAmbiguities(data); } catch (DOMException e) { + return null; } - return null; } public static ICPPFunction findImplicitlyCalledDestructor(ICPPASTDeleteExpression expr) {