1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-25 18:05:33 +02:00

Create implicit name wrapping a problem binding for an invalid

constructor call.
This commit is contained in:
Sergey Prigogin 2013-04-02 21:04:50 -07:00
parent 30081f07d5
commit f987bfe27c
6 changed files with 44 additions and 43 deletions

View file

@ -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);
}

View file

@ -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
*/

View file

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

View file

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

View file

@ -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);

View file

@ -3074,9 +3074,9 @@ public class CPPSemantics {
}
/**
* Returns constructor called by a declarator, or <code>null</code> 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 <code>null</code> 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 <code>null</code> 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) {