mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
fixing invalid problem bindings:
- default constructors via parameters with default values - expression types with typedefs - default values vs void
This commit is contained in:
parent
3462e648ba
commit
86baacedc8
5 changed files with 108 additions and 20 deletions
|
@ -4498,4 +4498,22 @@ public class AST2CPPTests extends AST2BaseTest {
|
||||||
ICPPFunction copy = (ICPPFunction) col.getName(1).resolveBinding();
|
ICPPFunction copy = (ICPPFunction) col.getName(1).resolveBinding();
|
||||||
assertSame( copy, col.getName(5).resolveBinding() );
|
assertSame( copy, col.getName(5).resolveBinding() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testDefaultConstructor() throws Exception {
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
buffer.append("class A { \n"); //$NON-NLS-1$
|
||||||
|
buffer.append(" A( int i = 0 ); \n"); //$NON-NLS-1$
|
||||||
|
buffer.append("}; \n"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
|
||||||
|
CPPNameCollector col = new CPPNameCollector();
|
||||||
|
tu.accept(col);
|
||||||
|
|
||||||
|
ICPPClassType A = (ICPPClassType) col.getName(0).resolveBinding();
|
||||||
|
ICPPConstructor ctor = (ICPPConstructor) col.getName(1).resolveBinding();
|
||||||
|
|
||||||
|
ICPPConstructor [] cs = A.getConstructors();
|
||||||
|
assertTrue( cs.length == 2 );
|
||||||
|
assertSame( cs[1], ctor );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,10 +14,16 @@
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
|
||||||
|
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.IBasicType;
|
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
|
@ -26,6 +32,7 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||||
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.ICPPASTOperatorName;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||||
|
@ -81,17 +88,18 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
||||||
}
|
}
|
||||||
char [] className = name.toCharArray();
|
char [] className = name.toCharArray();
|
||||||
|
|
||||||
//default constructor: A()
|
IParameter [] voidPs = new IParameter [] { new CPPParameter( CPPSemantics.VOID_TYPE ) };
|
||||||
IType voidType = new CPPBasicType( IBasicType.t_void, 0 );
|
if( !hasNonStandardDefaultConstructor( compTypeSpec ) ) {
|
||||||
IParameter [] voidPs = new IParameter [] { new CPPParameter( voidType ) };
|
//default constructor: A(void)
|
||||||
ICPPMethod m = new CPPImplicitConstructor( this, className, voidPs );
|
ICPPMethod m = new CPPImplicitConstructor( this, className, voidPs );
|
||||||
implicits[0] = m;
|
implicits[0] = m;
|
||||||
addBinding( m );
|
addBinding( m );
|
||||||
|
}
|
||||||
|
|
||||||
//copy constructor: A( const A & )
|
//copy constructor: A( const A & )
|
||||||
IType pType = new CPPReferenceType( new CPPQualifierType( clsType, true, false ) );
|
IType pType = new CPPReferenceType( new CPPQualifierType( clsType, true, false ) );
|
||||||
IParameter [] ps = new IParameter [] { new CPPParameter( pType ) };
|
IParameter [] ps = new IParameter [] { new CPPParameter( pType ) };
|
||||||
m = new CPPImplicitConstructor( this, className, ps );
|
ICPPMethod m = new CPPImplicitConstructor( this, className, ps );
|
||||||
implicits[1] = m;
|
implicits[1] = m;
|
||||||
addBinding( m );
|
addBinding( m );
|
||||||
|
|
||||||
|
@ -108,6 +116,47 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
||||||
addBinding( m );
|
addBinding( m );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean hasNonStandardDefaultConstructor( ICPPASTCompositeTypeSpecifier compSpec ){
|
||||||
|
IASTDeclaration [] members = compSpec.getMembers();
|
||||||
|
char [] name = compSpec.getName().toCharArray();
|
||||||
|
IASTDeclarator dtor = null;
|
||||||
|
IASTDeclSpecifier spec = null;
|
||||||
|
for( int i = 0; i < members.length; i++ ){
|
||||||
|
if( members[i] instanceof IASTSimpleDeclaration ){
|
||||||
|
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)members[i]).getDeclarators();
|
||||||
|
if( dtors.length == 0 || dtors.length > 1 )
|
||||||
|
continue;
|
||||||
|
dtor = dtors[0];
|
||||||
|
spec = ((IASTSimpleDeclaration)members[i]).getDeclSpecifier();
|
||||||
|
} else if( members[i] instanceof IASTFunctionDefinition ){
|
||||||
|
dtor = ((IASTFunctionDefinition)members[i]).getDeclarator();
|
||||||
|
spec = ((IASTFunctionDefinition)members[i]).getDeclSpecifier();
|
||||||
|
}
|
||||||
|
if( !(dtor instanceof ICPPASTFunctionDeclarator) || !(spec instanceof IASTSimpleDeclSpecifier) ||
|
||||||
|
((IASTSimpleDeclSpecifier)spec).getType() != IASTSimpleDeclSpecifier.t_unspecified ||
|
||||||
|
!CharArrayUtils.equals( dtor.getName().toCharArray(), name ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
IASTParameterDeclaration [] ps = ((ICPPASTFunctionDeclarator)dtor).getParameters();
|
||||||
|
if( ps.length >= 1 ){
|
||||||
|
IASTDeclarator d = ps[0].getDeclarator();
|
||||||
|
IASTDeclSpecifier s = ps[0].getDeclSpecifier();
|
||||||
|
if( s instanceof IASTSimpleDeclSpecifier &&
|
||||||
|
((IASTSimpleDeclSpecifier)s).getType() == IASTSimpleDeclSpecifier.t_void &&
|
||||||
|
d.getPointerOperators().length == 0 && !(d instanceof IASTArrayDeclarator) )
|
||||||
|
{
|
||||||
|
continue; //A(void)
|
||||||
|
}
|
||||||
|
|
||||||
|
if( d.getInitializer() != null )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public IScope getParent() {
|
public IScope getParent() {
|
||||||
ICPPASTCompositeTypeSpecifier compType = (ICPPASTCompositeTypeSpecifier) getPhysicalNode();
|
ICPPASTCompositeTypeSpecifier compType = (ICPPASTCompositeTypeSpecifier) getPhysicalNode();
|
||||||
IASTName compName = compType.getName();
|
IASTName compName = compType.getName();
|
||||||
|
|
|
@ -172,7 +172,7 @@ public class CPPClassType implements ICPPClassType, ICPPInternalClassType {
|
||||||
|
|
||||||
private IASTName definition;
|
private IASTName definition;
|
||||||
private IASTName [] declarations;
|
private IASTName [] declarations;
|
||||||
|
private boolean checked = false;
|
||||||
public CPPClassType( IASTName name ){
|
public CPPClassType( IASTName name ){
|
||||||
if( name instanceof ICPPASTQualifiedName ){
|
if( name instanceof ICPPASTQualifiedName ){
|
||||||
IASTName [] ns = ((ICPPASTQualifiedName)name).getNames();
|
IASTName [] ns = ((ICPPASTQualifiedName)name).getNames();
|
||||||
|
@ -250,17 +250,19 @@ public class CPPClassType implements ICPPClassType, ICPPInternalClassType {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkForDefinition(){
|
private void checkForDefinition(){
|
||||||
FindDefinitionAction action = new FindDefinitionAction();
|
if( !checked ) {
|
||||||
IASTNode node = CPPVisitor.getContainingBlockItem( getPhysicalNode() ).getParent();
|
FindDefinitionAction action = new FindDefinitionAction();
|
||||||
|
IASTNode node = CPPVisitor.getContainingBlockItem( getPhysicalNode() ).getParent();
|
||||||
|
|
||||||
node.accept( action );
|
node.accept( action );
|
||||||
definition = action.result;
|
|
||||||
|
|
||||||
if( definition == null ){
|
|
||||||
node.getTranslationUnit().accept( action );
|
|
||||||
definition = action.result;
|
definition = action.result;
|
||||||
}
|
|
||||||
|
|
||||||
|
if( definition == null ){
|
||||||
|
node.getTranslationUnit().accept( action );
|
||||||
|
definition = action.result;
|
||||||
|
}
|
||||||
|
checked = true;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,6 +367,9 @@ public class CPPClassType implements ICPPClassType, ICPPInternalClassType {
|
||||||
* @see org.eclipse.cdt.core.dom.ast.ICompositeType#getCompositeScope()
|
* @see org.eclipse.cdt.core.dom.ast.ICompositeType#getCompositeScope()
|
||||||
*/
|
*/
|
||||||
public IScope getCompositeScope() {
|
public IScope getCompositeScope() {
|
||||||
|
if( definition == null ){
|
||||||
|
checkForDefinition();
|
||||||
|
}
|
||||||
return (definition != null ) ? getCompositeTypeSpecifier().getScope() : null;
|
return (definition != null ) ? getCompositeTypeSpecifier().getScope() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1969,6 +1969,7 @@ public class CPPSemantics {
|
||||||
|
|
||||||
IType [] sourceParameters = getSourceParameterTypes( data.functionParameters ); //the parameters the function is being called with
|
IType [] sourceParameters = getSourceParameterTypes( data.functionParameters ); //the parameters the function is being called with
|
||||||
IType [] targetParameters = null;
|
IType [] targetParameters = null;
|
||||||
|
boolean sourceVoid = ( data.functionParameters == null || data.functionParameters.length == 0 );
|
||||||
int numSourceParams = 0;
|
int numSourceParams = 0;
|
||||||
int targetLength = 0;
|
int targetLength = 0;
|
||||||
int numFns = fns.length;
|
int numFns = fns.length;
|
||||||
|
@ -2028,7 +2029,9 @@ public class CPPSemantics {
|
||||||
} else if( varArgs ){
|
} else if( varArgs ){
|
||||||
cost = new Cost( source, null );
|
cost = new Cost( source, null );
|
||||||
cost.rank = Cost.ELLIPSIS_CONVERSION;
|
cost.rank = Cost.ELLIPSIS_CONVERSION;
|
||||||
} else if( source.isSameType( target ) ){
|
} else if( source.isSameType( target ) ||
|
||||||
|
( sourceVoid && ((useImplicitObj && j == 1)||(!useImplicitObj && j == 0)) ) )
|
||||||
|
{
|
||||||
cost = new Cost( source, target );
|
cost = new Cost( source, target );
|
||||||
cost.rank = Cost.IDENTITY_RANK; //exact match, no cost
|
cost.rank = Cost.IDENTITY_RANK; //exact match, no cost
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1679,6 +1679,9 @@ public class CPPVisitor {
|
||||||
} else if( binding instanceof IVariable ){
|
} else if( binding instanceof IVariable ){
|
||||||
try {
|
try {
|
||||||
IType t = ((IVariable)binding).getType();
|
IType t = ((IVariable)binding).getType();
|
||||||
|
while( t instanceof ITypedef ){
|
||||||
|
t = ((ITypedef)t).getType();
|
||||||
|
}
|
||||||
if( t instanceof IPointerType && ((IPointerType)t).getType() instanceof IFunctionType ){
|
if( t instanceof IPointerType && ((IPointerType)t).getType() instanceof IFunctionType ){
|
||||||
IFunctionType ftype = (IFunctionType) ((IPointerType)t).getType();
|
IFunctionType ftype = (IFunctionType) ((IPointerType)t).getType();
|
||||||
if( ftype != null )
|
if( ftype != null )
|
||||||
|
@ -1751,7 +1754,7 @@ public class CPPVisitor {
|
||||||
else if( expression instanceof IASTUnaryExpression )
|
else if( expression instanceof IASTUnaryExpression )
|
||||||
{
|
{
|
||||||
int op = ((IASTUnaryExpression)expression).getOperator();
|
int op = ((IASTUnaryExpression)expression).getOperator();
|
||||||
if( op == IASTTypeIdExpression.op_sizeof ){
|
if( op == IASTUnaryExpression.op_sizeof ){
|
||||||
IScope scope = getContainingScope( expression );
|
IScope scope = getContainingScope( expression );
|
||||||
try {
|
try {
|
||||||
IBinding [] bs = scope.find( SIZE_T );
|
IBinding [] bs = scope.find( SIZE_T );
|
||||||
|
@ -1764,6 +1767,13 @@ public class CPPVisitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
IType type = getExpressionType(((IASTUnaryExpression)expression).getOperand() );
|
IType type = getExpressionType(((IASTUnaryExpression)expression).getOperand() );
|
||||||
|
while( type instanceof ITypedef ){
|
||||||
|
try {
|
||||||
|
type = ((ITypeContainer)type).getType();
|
||||||
|
} catch (DOMException e) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if( op == IASTUnaryExpression.op_star && (type instanceof IPointerType || type instanceof IArrayType) ){
|
if( op == IASTUnaryExpression.op_star && (type instanceof IPointerType || type instanceof IArrayType) ){
|
||||||
try {
|
try {
|
||||||
return ((ITypeContainer)type).getType();
|
return ((ITypeContainer)type).getType();
|
||||||
|
@ -1814,6 +1824,9 @@ public class CPPVisitor {
|
||||||
} else if( expression instanceof IASTArraySubscriptExpression ){
|
} else if( expression instanceof IASTArraySubscriptExpression ){
|
||||||
IType t = getExpressionType( ((IASTArraySubscriptExpression) expression).getArrayExpression() );
|
IType t = getExpressionType( ((IASTArraySubscriptExpression) expression).getArrayExpression() );
|
||||||
try {
|
try {
|
||||||
|
while( t instanceof ITypedef ){
|
||||||
|
t = ((ITypedef)t).getType();
|
||||||
|
}
|
||||||
if( t instanceof IPointerType )
|
if( t instanceof IPointerType )
|
||||||
return ((IPointerType)t).getType();
|
return ((IPointerType)t).getType();
|
||||||
else if( t instanceof IArrayType )
|
else if( t instanceof IArrayType )
|
||||||
|
|
Loading…
Add table
Reference in a new issue