mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-04 14:55:41 +02:00
Create implicit name wrapping a problem binding for an invalid
constructor call.
This commit is contained in:
parent
30081f07d5
commit
f987bfe27c
6 changed files with 44 additions and 43 deletions
|
@ -1561,6 +1561,18 @@ public class AST2CPPTests extends AST2TestBase {
|
||||||
assertSame(ctor, ctor2);
|
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 {
|
// struct A {
|
||||||
// A(int x);
|
// A(int x);
|
||||||
// };
|
// };
|
||||||
|
@ -8391,9 +8403,7 @@ public class AST2CPPTests extends AST2TestBase {
|
||||||
// fH({1}); // H(G(1))
|
// fH({1}); // H(G(1))
|
||||||
// }
|
// }
|
||||||
public void testListInitialization_302412f() throws Exception {
|
public void testListInitialization_302412f() throws Exception {
|
||||||
IProblemBinding problem;
|
BindingAssertionHelper bh= getAssertionHelper();
|
||||||
String code= getAboveComment();
|
|
||||||
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
|
||||||
bh.assertProblem("f({1,1})", 1);
|
bh.assertProblem("f({1,1})", 1);
|
||||||
bh.assertImplicitName("F({1,1})", 1, ICPPConstructor.class);
|
bh.assertImplicitName("F({1,1})", 1, ICPPConstructor.class);
|
||||||
bh.assertNonProblem("fF({1,1})", 2);
|
bh.assertNonProblem("fF({1,1})", 2);
|
||||||
|
@ -8402,13 +8412,9 @@ public class AST2CPPTests extends AST2TestBase {
|
||||||
bh.assertNonProblem("fG({1})", 2);
|
bh.assertNonProblem("fG({1})", 2);
|
||||||
|
|
||||||
bh.assertImplicitName("H(1)", 1, ICPPConstructor.class);
|
bh.assertImplicitName("H(1)", 1, ICPPConstructor.class);
|
||||||
bh.assertNoImplicitName("H({1})", 1);
|
IASTImplicitName n= bh.assertImplicitName("H({1})", 1, IProblemBinding.class);
|
||||||
// TODO(nathanridge): Perhaps we should store implicit names even if they
|
IProblemBinding problem= (IProblemBinding) n.resolveBinding();
|
||||||
// resolve to ProblemBindings. Then we can do the stronger check in the
|
assertEquals(IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, problem.getID());
|
||||||
// 3 commented lines below.
|
|
||||||
//IASTImplicitName n= bh.assertImplicitName("H({1})", 1, IProblemBinding.class);
|
|
||||||
//problem= (IProblemBinding) n.resolveBinding();
|
|
||||||
//assertEquals(IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, problem.getID());
|
|
||||||
bh.assertProblem("fH(1)", 2);
|
bh.assertProblem("fH(1)", 2);
|
||||||
bh.assertNonProblem("fH({1})", 2);
|
bh.assertNonProblem("fH({1})", 2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,34 +27,32 @@ public interface IASTImplicitName extends IASTName {
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* Redeclared with strengthened postcondition.
|
* Redeclared with strengthened postcondition.
|
||||||
*
|
*
|
||||||
* Will not return null or a problem binding.
|
* Will not return {@code null}, but may return a problem binding, for example for an implicit
|
||||||
* Implicit names are not generated unless they resolve to something.
|
* constructor call.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public IBinding resolveBinding();
|
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
|
* Sometimes more than one implicit name is generated for the same binding but with different
|
||||||
* but with different offsets, when this happens the additional names
|
* offsets, when this happens the additional names generated are considered alternates.
|
||||||
* generated are considered alternates.
|
|
||||||
*
|
*
|
||||||
* @see ASTVisitor#shouldVisitImplicitNameAlternates
|
* @see ASTVisitor#shouldVisitImplicitNameAlternates
|
||||||
*/
|
*/
|
||||||
public boolean isAlternate();
|
public boolean isAlternate();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method that returns true if this
|
* Convenience method that returns true if this name represents an overloaded operator.
|
||||||
* name represents an overloaded operator.
|
|
||||||
*/
|
*/
|
||||||
public boolean isOperator();
|
public boolean isOperator();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is not supported on implicit names.
|
* This method is not supported on implicit names.
|
||||||
*
|
*
|
||||||
* Implicit names are not copied when an AST is copied,
|
* Implicit names are not copied when an AST is copied, instead the implicit names are
|
||||||
* instead the implicit names are regenerated when needed.
|
* regenerated when needed.
|
||||||
*
|
*
|
||||||
* @throws UnsupportedOperationException always
|
* @throws UnsupportedOperationException always
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -241,7 +241,7 @@ public class CPPASTConstructorChainInitializer extends ASTNode implements
|
||||||
@Override
|
@Override
|
||||||
public IASTImplicitName[] getImplicitNames() {
|
public IASTImplicitName[] getImplicitNames() {
|
||||||
if (implicitNames == null) {
|
if (implicitNames == null) {
|
||||||
ICPPConstructor ctor = CPPSemantics.findImplicitlyCalledConstructor(this);
|
IBinding ctor = CPPSemantics.findImplicitlyCalledConstructor(this);
|
||||||
if (ctor == null) {
|
if (ctor == null) {
|
||||||
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -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.IASTPointerOperator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
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.ICPPASTDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
|
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.ICPPASTQualifiedName;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
|
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.core.parser.util.ArrayUtil;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
||||||
|
@ -305,7 +305,7 @@ public class CPPASTDeclarator extends ASTNode implements ICPPASTDeclarator, IAST
|
||||||
@Override
|
@Override
|
||||||
public IASTImplicitName[] getImplicitNames() {
|
public IASTImplicitName[] getImplicitNames() {
|
||||||
if (implicitNames == null) {
|
if (implicitNames == null) {
|
||||||
ICPPConstructor ctor = CPPSemantics.findImplicitlyCalledConstructor(this);
|
IBinding ctor = CPPSemantics.findImplicitlyCalledConstructor(this);
|
||||||
if (ctor == null) {
|
if (ctor == null) {
|
||||||
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -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.IASTPointerOperator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||||
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
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.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
|
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.ICPPASTNewExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
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.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
||||||
|
@ -175,7 +175,7 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPASTImplicitName constructorName = null;
|
CPPASTImplicitName constructorName = null;
|
||||||
ICPPConstructor constructor = CPPSemantics.findImplicitlyCalledConstructor(this);
|
IBinding constructor = CPPSemantics.findImplicitlyCalledConstructor(this);
|
||||||
if (constructor != null) {
|
if (constructor != null) {
|
||||||
constructorName = new CPPASTImplicitName(constructor.getNameCharArray(), this);
|
constructorName = new CPPASTImplicitName(constructor.getNameCharArray(), this);
|
||||||
constructorName.setBinding(constructor);
|
constructorName.setBinding(constructor);
|
||||||
|
|
|
@ -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)
|
if (declarator.getNestedDeclarator() != null)
|
||||||
return null;
|
return null;
|
||||||
IASTDeclarator dtor= ASTQueries.findOutermostDeclarator(declarator);
|
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 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());
|
return findImplicitlyCalledConstructor(initializer.getMemberInitializerId(), initializer.getInitializer());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns constructor called by a variable declarator or an initializer in a constructor initializer
|
* Returns constructor called by a variable declarator or an initializer in a constructor
|
||||||
* chain. Returns <code>null</code> if no constructor is called.
|
* 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();
|
IBinding binding = name.resolveBinding();
|
||||||
if (!(binding instanceof ICPPVariable))
|
if (!(binding instanceof ICPPVariable))
|
||||||
return null;
|
return null;
|
||||||
|
@ -3125,7 +3125,7 @@ public class CPPSemantics {
|
||||||
return findImplicitlyCalledConstructor((ICPPClassType) type, initializer, name);
|
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);
|
IType type = getNestedType(expr.getExpressionType(), TDEF | REF | CVTYPE);
|
||||||
if (!(type instanceof IPointerType))
|
if (!(type instanceof IPointerType))
|
||||||
return null;
|
return null;
|
||||||
|
@ -3137,7 +3137,7 @@ public class CPPSemantics {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ICPPConstructor findImplicitlyCalledConstructor(ICPPClassType type, IASTInitializer initializer,
|
private static IBinding findImplicitlyCalledConstructor(ICPPClassType type, IASTInitializer initializer,
|
||||||
IASTNode typeId) {
|
IASTNode typeId) {
|
||||||
try {
|
try {
|
||||||
if (initializer instanceof IASTEqualsInitializer) {
|
if (initializer instanceof IASTEqualsInitializer) {
|
||||||
|
@ -3157,7 +3157,7 @@ public class CPPSemantics {
|
||||||
if (c.converts()) {
|
if (c.converts()) {
|
||||||
ICPPFunction f = c.getUserDefinedConversion();
|
ICPPFunction f = c.getUserDefinedConversion();
|
||||||
if (f instanceof ICPPConstructor)
|
if (f instanceof ICPPConstructor)
|
||||||
return (ICPPConstructor) f;
|
return f;
|
||||||
// If a conversion is used, the constructor is elided.
|
// If a conversion is used, the constructor is elided.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3169,7 +3169,7 @@ public class CPPSemantics {
|
||||||
if (c.converts()) {
|
if (c.converts()) {
|
||||||
ICPPFunction f = c.getUserDefinedConversion();
|
ICPPFunction f = c.getUserDefinedConversion();
|
||||||
if (f instanceof ICPPConstructor)
|
if (f instanceof ICPPConstructor)
|
||||||
return (ICPPConstructor) f;
|
return f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (initializer instanceof ICPPASTConstructorInitializer) {
|
} else if (initializer instanceof ICPPASTConstructorInitializer) {
|
||||||
|
@ -3190,7 +3190,7 @@ public class CPPSemantics {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ICPPConstructor findImplicitlyCalledConstructor(ICPPClassType classType,
|
private static IBinding findImplicitlyCalledConstructor(ICPPClassType classType,
|
||||||
ICPPASTConstructorInitializer initializer, IASTNode typeId) {
|
ICPPASTConstructorInitializer initializer, IASTNode typeId) {
|
||||||
final IASTInitializerClause[] arguments = initializer.getArguments();
|
final IASTInitializerClause[] arguments = initializer.getArguments();
|
||||||
CPPASTName astName = new CPPASTName();
|
CPPASTName astName = new CPPASTName();
|
||||||
|
@ -3204,15 +3204,12 @@ public class CPPSemantics {
|
||||||
data.setFunctionArguments(false, arguments);
|
data.setFunctionArguments(false, arguments);
|
||||||
data.qualified = true;
|
data.qualified = true;
|
||||||
data.foundItems = ClassTypeHelper.getConstructors(classType, typeId);
|
data.foundItems = ClassTypeHelper.getConstructors(classType, typeId);
|
||||||
IBinding binding;
|
|
||||||
try {
|
try {
|
||||||
binding = resolveAmbiguities(data);
|
return resolveAmbiguities(data);
|
||||||
if (binding instanceof ICPPConstructor)
|
|
||||||
return (ICPPConstructor) binding;
|
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static ICPPFunction findImplicitlyCalledDestructor(ICPPASTDeleteExpression expr) {
|
public static ICPPFunction findImplicitlyCalledDestructor(ICPPASTDeleteExpression expr) {
|
||||||
IType t = getTypeOfPointer(expr.getOperand().getExpressionType());
|
IType t = getTypeOfPointer(expr.getOperand().getExpressionType());
|
||||||
|
|
Loading…
Add table
Reference in a new issue