1
0
Fork 0
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:
Andrew Niefer 2005-05-26 19:43:59 +00:00
parent 3462e648ba
commit 86baacedc8
5 changed files with 108 additions and 20 deletions

View file

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

View file

@ -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;
@ -80,18 +87,19 @@ 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 ) };
ICPPMethod m = new CPPImplicitConstructor( this, className, voidPs );
implicits[0] = m;
addBinding( m );
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();

View file

@ -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,17 +250,19 @@ public class CPPClassType implements ICPPClassType, ICPPInternalClassType {
}
private void checkForDefinition(){
FindDefinitionAction action = new FindDefinitionAction();
IASTNode node = CPPVisitor.getContainingBlockItem( getPhysicalNode() ).getParent();
node.accept( action );
definition = action.result;
if( definition == null ){
node.getTranslationUnit().accept( action );
if( !checked ) {
FindDefinitionAction action = new FindDefinitionAction();
IASTNode node = CPPVisitor.getContainingBlockItem( getPhysicalNode() ).getParent();
node.accept( action );
definition = action.result;
if( definition == null ){
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;
}

View file

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

View file

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