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();
|
||||
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;
|
||||
|
||||
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.IASTDeclaration;
|
||||
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.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.IBasicType;
|
||||
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.IType;
|
||||
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.ICPPASTOperatorName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||
|
@ -81,17 +88,18 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
|||
}
|
||||
char [] className = name.toCharArray();
|
||||
|
||||
//default constructor: A()
|
||||
IType voidType = new CPPBasicType( IBasicType.t_void, 0 );
|
||||
IParameter [] voidPs = new IParameter [] { new CPPParameter( voidType ) };
|
||||
IParameter [] voidPs = new IParameter [] { new CPPParameter( CPPSemantics.VOID_TYPE ) };
|
||||
if( !hasNonStandardDefaultConstructor( compTypeSpec ) ) {
|
||||
//default constructor: A(void)
|
||||
ICPPMethod m = new CPPImplicitConstructor( this, className, voidPs );
|
||||
implicits[0] = m;
|
||||
addBinding( m );
|
||||
}
|
||||
|
||||
//copy constructor: A( const A & )
|
||||
IType pType = new CPPReferenceType( new CPPQualifierType( clsType, true, false ) );
|
||||
IParameter [] ps = new IParameter [] { new CPPParameter( pType ) };
|
||||
m = new CPPImplicitConstructor( this, className, ps );
|
||||
ICPPMethod m = new CPPImplicitConstructor( this, className, ps );
|
||||
implicits[1] = m;
|
||||
addBinding( m );
|
||||
|
||||
|
@ -108,6 +116,47 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
|||
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() {
|
||||
ICPPASTCompositeTypeSpecifier compType = (ICPPASTCompositeTypeSpecifier) getPhysicalNode();
|
||||
IASTName compName = compType.getName();
|
||||
|
|
|
@ -172,7 +172,7 @@ public class CPPClassType implements ICPPClassType, ICPPInternalClassType {
|
|||
|
||||
private IASTName definition;
|
||||
private IASTName [] declarations;
|
||||
|
||||
private boolean checked = false;
|
||||
public CPPClassType( IASTName name ){
|
||||
if( name instanceof ICPPASTQualifiedName ){
|
||||
IASTName [] ns = ((ICPPASTQualifiedName)name).getNames();
|
||||
|
@ -250,6 +250,7 @@ public class CPPClassType implements ICPPClassType, ICPPInternalClassType {
|
|||
}
|
||||
|
||||
private void checkForDefinition(){
|
||||
if( !checked ) {
|
||||
FindDefinitionAction action = new FindDefinitionAction();
|
||||
IASTNode node = CPPVisitor.getContainingBlockItem( getPhysicalNode() ).getParent();
|
||||
|
||||
|
@ -260,7 +261,8 @@ public class CPPClassType implements ICPPClassType, ICPPInternalClassType {
|
|||
node.getTranslationUnit().accept( action );
|
||||
definition = action.result;
|
||||
}
|
||||
|
||||
checked = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -365,6 +367,9 @@ public class CPPClassType implements ICPPClassType, ICPPInternalClassType {
|
|||
* @see org.eclipse.cdt.core.dom.ast.ICompositeType#getCompositeScope()
|
||||
*/
|
||||
public IScope getCompositeScope() {
|
||||
if( definition == null ){
|
||||
checkForDefinition();
|
||||
}
|
||||
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 [] targetParameters = null;
|
||||
boolean sourceVoid = ( data.functionParameters == null || data.functionParameters.length == 0 );
|
||||
int numSourceParams = 0;
|
||||
int targetLength = 0;
|
||||
int numFns = fns.length;
|
||||
|
@ -2028,7 +2029,9 @@ public class CPPSemantics {
|
|||
} else if( varArgs ){
|
||||
cost = new Cost( source, null );
|
||||
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.rank = Cost.IDENTITY_RANK; //exact match, no cost
|
||||
} else {
|
||||
|
|
|
@ -1679,6 +1679,9 @@ public class CPPVisitor {
|
|||
} else if( binding instanceof IVariable ){
|
||||
try {
|
||||
IType t = ((IVariable)binding).getType();
|
||||
while( t instanceof ITypedef ){
|
||||
t = ((ITypedef)t).getType();
|
||||
}
|
||||
if( t instanceof IPointerType && ((IPointerType)t).getType() instanceof IFunctionType ){
|
||||
IFunctionType ftype = (IFunctionType) ((IPointerType)t).getType();
|
||||
if( ftype != null )
|
||||
|
@ -1751,7 +1754,7 @@ public class CPPVisitor {
|
|||
else if( expression instanceof IASTUnaryExpression )
|
||||
{
|
||||
int op = ((IASTUnaryExpression)expression).getOperator();
|
||||
if( op == IASTTypeIdExpression.op_sizeof ){
|
||||
if( op == IASTUnaryExpression.op_sizeof ){
|
||||
IScope scope = getContainingScope( expression );
|
||||
try {
|
||||
IBinding [] bs = scope.find( SIZE_T );
|
||||
|
@ -1764,6 +1767,13 @@ public class CPPVisitor {
|
|||
}
|
||||
|
||||
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) ){
|
||||
try {
|
||||
return ((ITypeContainer)type).getType();
|
||||
|
@ -1814,6 +1824,9 @@ public class CPPVisitor {
|
|||
} else if( expression instanceof IASTArraySubscriptExpression ){
|
||||
IType t = getExpressionType( ((IASTArraySubscriptExpression) expression).getArrayExpression() );
|
||||
try {
|
||||
while( t instanceof ITypedef ){
|
||||
t = ((ITypedef)t).getType();
|
||||
}
|
||||
if( t instanceof IPointerType )
|
||||
return ((IPointerType)t).getType();
|
||||
else if( t instanceof IArrayType )
|
||||
|
|
Loading…
Add table
Reference in a new issue