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) {