1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

bug 91707 - overloaded operators [] and ->

-also fix issue with defered template instances
This commit is contained in:
Andrew Niefer 2005-06-01 17:55:35 +00:00
parent 9dc5a7dffd
commit a0e5adac22
6 changed files with 136 additions and 4 deletions

View file

@ -4565,4 +4565,28 @@ public class AST2CPPTests extends AST2BaseTest {
assertTrue( cs.length == 2 );
assertSame( cs[1], ctor );
}
public void testBug91707() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("class C { public: int foo; }; \n");
buffer.append("class B { \n");
buffer.append(" C* operator ->(); \n");
buffer.append(" C& operator [] ( int ); \n");
buffer.append("}; \n");
buffer.append("void f(){ \n");
buffer.append(" B b; \n");
buffer.append(" b->foo; \n");
buffer.append(" b[0].foo; \n");
buffer.append("} \n");
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
CPPNameCollector col = new CPPNameCollector();
tu.accept(col);
ICPPField foo = (ICPPField) col.getName(1).resolveBinding();
assertSame( foo, col.getName(12).resolveBinding() );
assertSame( foo, col.getName(14).resolveBinding() );
}
}

View file

@ -1589,4 +1589,45 @@ public class AST2TemplateTests extends AST2BaseTest {
ICPPMethod init = (ICPPMethod) col.getName(4).resolveBinding();
assertSame( init, col.getName(19).resolveBinding() );
}
public void testBug91707() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("template <class Tp, class Tr > class iter { \n"); //$NON-NLS-1$
buffer.append(" Tp operator -> () const; \n"); //$NON-NLS-1$
buffer.append(" Tr operator [] (int) const; \n"); //$NON-NLS-1$
buffer.append("}; \n"); //$NON-NLS-1$
buffer.append("template <class T> class list { \n"); //$NON-NLS-1$
buffer.append(" typedef iter< T*, T& > iterator; \n"); //$NON-NLS-1$
buffer.append(" iterator begin(); \n"); //$NON-NLS-1$
buffer.append(" iterator end(); \n"); //$NON-NLS-1$
buffer.append("}; \n"); //$NON-NLS-1$
buffer.append("class Bar { public: int foo; }; \n"); //$NON-NLS-1$
buffer.append("void f() { \n"); //$NON-NLS-1$
buffer.append(" list<Bar> bar; \n"); //$NON-NLS-1$
buffer.append(" for( list<Bar>::iterator i = bar.begin(); i != bar.end(); ++i ){ \n"); //$NON-NLS-1$
buffer.append(" i->foo; i[0].foo; \n"); //$NON-NLS-1$
buffer.append(" } \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
CPPNameCollector col = new CPPNameCollector();
tu.accept( col );
ICPPMethod begin = (ICPPMethod) col.getName(16).resolveBinding();
ICPPMethod end = (ICPPMethod) col.getName(18).resolveBinding();
ICPPField foo = (ICPPField) col.getName(20).resolveBinding();
IBinding r = col.getName(33).resolveBinding();
assertTrue( r instanceof ICPPSpecialization );
assertSame( ((ICPPSpecialization)r).getSpecializedBinding(), begin );
r = col.getName(36).resolveBinding();
assertTrue( r instanceof ICPPSpecialization );
assertSame( ((ICPPSpecialization)r).getSpecializedBinding(), end );
assertSame( foo, col.getName(39).resolveBinding() );
assertSame( foo, col.getName(41).resolveBinding() );
}
}

View file

@ -76,7 +76,7 @@ public class CPPClassTemplatePartialSpecialization extends CPPClassTemplate impl
IType arg = args[i];
//If the argument is a template parameter, we can't instantiate yet, defer for later
if( arg instanceof ICPPTemplateParameter ){
if( CPPTemplates.typeContainsTemplateParameter( arg ) ){
return deferredInstance( args );
}
try {

View file

@ -15,6 +15,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
@ -74,6 +75,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
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;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
@ -338,7 +340,9 @@ public class CPPSemantics {
tempName = (IASTName) tempName.getParent();
ASTNodeProperty prop = tempName.getPropertyInParent();
if( prop == IASTFieldReference.FIELD_NAME ){
if( prop == IASTFieldReference.FIELD_NAME ||
(prop == STRING_LOOKUP_PROPERTY && tempName.getParent() instanceof ICPPASTFieldReference) )
{
ICPPASTFieldReference fieldRef = (ICPPASTFieldReference) tempName.getParent();
implied = CPPVisitor.getExpressionType( fieldRef.getFieldOwner() );
if( fieldRef.isPointerDereference() && implied instanceof IPointerType ){
@ -362,6 +366,9 @@ public class CPPSemantics {
}
}
}
} else if( prop == STRING_LOOKUP_PROPERTY && tempName.getParent() instanceof IASTArraySubscriptExpression ){
IASTExpression exp = ((IASTArraySubscriptExpression)tempName.getParent()).getArrayExpression();
implied = CPPVisitor.getExpressionType( exp );
}
}
return implied;
@ -2916,6 +2923,42 @@ public class CPPSemantics {
return -1;
}
public static ICPPFunction findOperator( IASTExpression exp, ICPPClassType cls ){
IScope scope = null;
try {
scope = cls.getCompositeScope();
} catch (DOMException e1) {
return null;
}
CPPASTName astName = new CPPASTName();
astName.setParent( exp );
astName.setPropertyInParent( STRING_LOOKUP_PROPERTY );
LookupData data = null;
if( exp instanceof IASTArraySubscriptExpression ){
astName.setName( ICPPASTOperatorName.OPERATOR_BRACKET );
data = new LookupData( astName );
data.forceQualified = true;
data.functionParameters = new IASTExpression [] { ((IASTArraySubscriptExpression)exp).getSubscriptExpression() };
} else if( exp instanceof IASTFieldReference ){
astName.setName( ICPPASTOperatorName.OPERATOR_ARROW );
data = new LookupData( astName );
data.forceQualified = true;
data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY;
} else {
return null;
}
try {
lookup( data, scope );
IBinding binding = resolveAmbiguities( data, astName );
if( binding instanceof ICPPFunction )
return (ICPPFunction) binding;
} catch( DOMException e ){
}
return null;
}
public static IBinding[] findBindings( IScope scope, String name, boolean qualified ) throws DOMException{
return findBindings( scope, name.toCharArray(), qualified );
}

View file

@ -1453,6 +1453,13 @@ public class CPPTemplates {
return template;
}
public static boolean typeContainsTemplateParameter( IType t ){
if( t instanceof ICPPTemplateParameter )
return true;
t = CPPSemantics.getUltimateType( t, false );
return (t instanceof ICPPTemplateParameter);
}
public static IBinding instantiateTemplate( ICPPTemplateDefinition template, IType [] arguments, ObjectMap specializedArgs ){
if( template == null ){
template = null;
@ -1484,7 +1491,7 @@ public class CPPTemplates {
if( i < numArgs ){
arg = arguments[i];
//If the argument is a template parameter, we can't instantiate yet, defer for later
if( arg instanceof ICPPTemplateParameter ){
if( typeContainsTemplateParameter( arg ) ){
return ((ICPPInternalTemplate)template).deferredInstance( arguments );
}
} else {

View file

@ -790,7 +790,18 @@ public class CPPVisitor {
}
} else if( parent instanceof ICPPASTFieldReference ){
IASTExpression owner = ((ICPPASTFieldReference)parent).getFieldOwner();
IType type = CPPSemantics.getUltimateType( getExpressionType( owner ), false );
IType type = getExpressionType( owner );
if( ((ICPPASTFieldReference)parent).isPointerDereference() ){
while( type instanceof ITypedef )
type = ((ITypedef)type).getType();
if( type instanceof ICPPClassType ){
ICPPFunction op = CPPSemantics.findOperator( (IASTFieldReference)parent, (ICPPClassType) type );
if( op != null ){
type = op.getType().getReturnType();
}
}
}
type = CPPSemantics.getUltimateType( type, false );
if( type instanceof ICPPClassType ){
return ((ICPPClassType) type).getCompositeScope();
}
@ -1830,6 +1841,12 @@ public class CPPVisitor {
while( t instanceof ITypedef ){
t = ((ITypedef)t).getType();
}
if( t instanceof ICPPClassType ){
ICPPFunction op = CPPSemantics.findOperator( expression, (ICPPClassType) t );
if( op != null ){
return op.getType().getReturnType();
}
}
if( t instanceof IPointerType )
return ((IPointerType)t).getType();
else if( t instanceof IArrayType )