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:
parent
9dc5a7dffd
commit
a0e5adac22
6 changed files with 136 additions and 4 deletions
|
@ -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() );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 )
|
||||
|
|
Loading…
Add table
Reference in a new issue