mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
more c++ pointers to members
This commit is contained in:
parent
c20e7686d9
commit
87ca6fed25
5 changed files with 214 additions and 61 deletions
|
@ -1500,7 +1500,7 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
IType t = pm.getType();
|
||||
assertNotNull(t);
|
||||
assertTrue(t instanceof ICPPPointerToMemberType);
|
||||
ICPPClassType cls = ((ICPPPointerToMemberType) t).getMemberOfClass();
|
||||
ICPPClassType cls = (ICPPClassType) ((ICPPPointerToMemberType) t).getMemberOfClass();
|
||||
assertSame(S, cls);
|
||||
assertTrue(((ICPPPointerToMemberType) t).getType() instanceof IBasicType);
|
||||
}
|
||||
|
@ -1547,7 +1547,7 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
assertTrue(t instanceof ICPPPointerToMemberType);
|
||||
IFunctionType ft = (IFunctionType) ((ICPPPointerToMemberType) t)
|
||||
.getType();
|
||||
ICPPClassType ST = ((ICPPPointerToMemberType) t)
|
||||
ICPPClassType ST = (ICPPClassType) ((ICPPPointerToMemberType) t)
|
||||
.getMemberOfClass();
|
||||
|
||||
assertTrue(ft.getReturnType() instanceof IPointerType);
|
||||
|
@ -1619,5 +1619,90 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
// assertTrue( body.getStatements()[0] instanceof IASTDeclarationStatement );
|
||||
// }
|
||||
|
||||
|
||||
public void testPMConversions() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("class A { public: int i; }; \n"); //$NON-NLS-1$
|
||||
buffer.append("class B : public A {}; \n"); //$NON-NLS-1$
|
||||
buffer.append("void f( int B::* ); \n"); //$NON-NLS-1$
|
||||
buffer.append("void g() { \n"); //$NON-NLS-1$
|
||||
buffer.append(" int A::* pm = &A::i; \n"); //$NON-NLS-1$
|
||||
buffer.append(" f( pm ); \n"); //$NON-NLS-1$
|
||||
buffer.append("} \n"); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP);
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit(tu, col);
|
||||
|
||||
IFunction f = (IFunction) col.getName(15).resolveBinding();
|
||||
ICPPClassType A = (ICPPClassType) col.getName(0).resolveBinding();
|
||||
ICPPField i = (ICPPField) col.getName(1).resolveBinding();
|
||||
ICPPClassType B = (ICPPClassType) col.getName(2).resolveBinding();
|
||||
IVariable pm = (IVariable) col.getName(11).resolveBinding();
|
||||
|
||||
assertInstances( col, f, 2 );
|
||||
assertInstances( col, A, 4 );
|
||||
assertInstances( col, i, 3 );
|
||||
assertInstances( col, B, 2 );
|
||||
assertInstances( col, pm, 2 );
|
||||
}
|
||||
|
||||
public void testPMKoenig() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append( "namespace N { \n" ); //$NON-NLS-1$
|
||||
buffer.append( " class A { public: int i; }; \n" ); //$NON-NLS-1$
|
||||
buffer.append( " void f( int A::* ); \n" ); //$NON-NLS-1$
|
||||
buffer.append( "} \n" ); //$NON-NLS-1$
|
||||
buffer.append( "int N::A::* pm = &N::A::i; \n" ); //$NON-NLS-1$
|
||||
buffer.append( "void g() { \n" ); //$NON-NLS-1$
|
||||
buffer.append( " f( pm ); \n" ); //$NON-NLS-1$
|
||||
buffer.append( "} \n" ); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP);
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit(tu, col);
|
||||
|
||||
IFunction f = (IFunction) col.getName(16).resolveBinding();
|
||||
ICPPNamespace N = (ICPPNamespace) col.getName(0).resolveBinding();
|
||||
ICPPClassType A = (ICPPClassType) col.getName(1).resolveBinding();
|
||||
|
||||
assertInstances( col, f, 2 );
|
||||
assertInstances( col, N, 3 );
|
||||
assertInstances( col, A, 4 );
|
||||
}
|
||||
|
||||
public void testPMKoenig_2() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append( "namespace M { \n" ); //$NON-NLS-1$
|
||||
buffer.append( " class B { }; \n" ); //$NON-NLS-1$
|
||||
buffer.append( " void f( B* ); \n" ); //$NON-NLS-1$
|
||||
buffer.append( "} \n" ); //$NON-NLS-1$
|
||||
buffer.append( "namespace N { \n" ); //$NON-NLS-1$
|
||||
buffer.append( " class A { public: M::B * b; }; \n" ); //$NON-NLS-1$
|
||||
buffer.append( "} \n" ); //$NON-NLS-1$
|
||||
buffer.append( "M::B* N::A::* pm = &N::A::b; \n" ); //$NON-NLS-1$
|
||||
buffer.append( "void g() { \n" ); //$NON-NLS-1$
|
||||
buffer.append( " N::A * a; \n" ); //$NON-NLS-1$
|
||||
buffer.append( " f( a->*pm ); \n" ); //$NON-NLS-1$
|
||||
buffer.append( "} \n" ); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP);
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit(tu, col);
|
||||
|
||||
IFunction f = (IFunction) col.getName(27).resolveBinding();
|
||||
ICPPNamespace M = (ICPPNamespace) col.getName(0).resolveBinding();
|
||||
ICPPClassType B = (ICPPClassType) col.getName(1).resolveBinding();
|
||||
ICPPNamespace N = (ICPPNamespace) col.getName(5).resolveBinding();
|
||||
ICPPClassType A = (ICPPClassType) col.getName(6).resolveBinding();
|
||||
IVariable pm = (IVariable) col.getName(17).resolveBinding();
|
||||
|
||||
assertInstances( col, f, 2 );
|
||||
assertInstances( col, M, 3 );
|
||||
assertInstances( col, B, 6 );
|
||||
assertInstances( col, N, 4 );
|
||||
assertInstances( col, A, 5 );
|
||||
assertInstances( col, pm, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,11 +14,12 @@
|
|||
*/
|
||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
*/
|
||||
public interface ICPPPointerToMemberType extends IPointerType {
|
||||
public ICPPClassType getMemberOfClass();
|
||||
public IBinding getMemberOfClass();
|
||||
}
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
/**********************************************************************
|
||||
* Copyright (c) 2005 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
**********************************************************************/
|
||||
/*
|
||||
* Created on Feb 11, 2005
|
||||
*
|
||||
* TODO To change the template for this generated file go to
|
||||
* Window - Preferences - Java - Code Style - Code Templates
|
||||
*/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
|
@ -10,6 +17,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
|
|||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
|
@ -17,9 +25,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
|
|||
|
||||
/**
|
||||
* @author aniefer
|
||||
*
|
||||
* TODO To change the template for this generated type comment go to
|
||||
* Window - Preferences - Java - Code Style - Code Templates
|
||||
*/
|
||||
public class CPPPointerToMemberType extends CPPPointerType implements
|
||||
ICPPPointerToMemberType {
|
||||
|
@ -33,10 +38,29 @@ public class CPPPointerToMemberType extends CPPPointerType implements
|
|||
super(type, operator);
|
||||
}
|
||||
|
||||
public boolean equals( Object o ){
|
||||
if( !super.equals( o ) )
|
||||
return false;
|
||||
|
||||
if( !( o instanceof CPPPointerToMemberType ) )
|
||||
return false;
|
||||
|
||||
|
||||
if( o instanceof ITypedef )
|
||||
return o.equals( this );
|
||||
|
||||
|
||||
CPPPointerToMemberType pt = (CPPPointerToMemberType) o;
|
||||
IBinding cls = pt.getMemberOfClass();
|
||||
if( cls != null )
|
||||
return cls.equals( getMemberOfClass() );
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType#getMemberOfClass()
|
||||
*/
|
||||
public ICPPClassType getMemberOfClass() {
|
||||
public IBinding getMemberOfClass() {
|
||||
if( clsType == null ){
|
||||
ICPPASTPointerToMember pm = (ICPPASTPointerToMember) operator;
|
||||
IASTName name = pm.getName();
|
||||
|
|
|
@ -76,6 +76,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||
|
@ -465,7 +466,7 @@ public class CPPSemantics {
|
|||
ObjectSet classes = new ObjectSet(2);
|
||||
for( int i = 0; i < ps.length; i++ ){
|
||||
IType p = getSourceParameterType( ps, i );
|
||||
p = getUltimateType( p );
|
||||
p = getUltimateType( p, true );
|
||||
try {
|
||||
getAssociatedScopes( p, namespaces, classes );
|
||||
} catch ( DOMException e ) {
|
||||
|
@ -492,11 +493,16 @@ public class CPPSemantics {
|
|||
} else if( t instanceof IFunctionType ){
|
||||
IFunctionType ft = (IFunctionType) t;
|
||||
|
||||
getAssociatedScopes( getUltimateType( ft.getReturnType() ), namespaces, classes );
|
||||
getAssociatedScopes( getUltimateType( ft.getReturnType(), true ), namespaces, classes );
|
||||
IType [] ps = ft.getParameterTypes();
|
||||
for( int i = 0; i < ps.length; i++ ){
|
||||
getAssociatedScopes( getUltimateType( ps[i] ), namespaces, classes );
|
||||
getAssociatedScopes( getUltimateType( ps[i], true ), namespaces, classes );
|
||||
}
|
||||
} else if( t instanceof ICPPPointerToMemberType ){
|
||||
IBinding binding = ((ICPPPointerToMemberType)t).getMemberOfClass();
|
||||
if( binding instanceof IType )
|
||||
getAssociatedScopes( (IType)binding, namespaces, classes );
|
||||
getAssociatedScopes( getUltimateType( ((ICPPPointerToMemberType)t).getType(), true ), namespaces, classes );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1413,8 +1419,8 @@ public class CPPSemantics {
|
|||
}
|
||||
|
||||
//was the qualification conversion enough?
|
||||
IType s = getUltimateType( cost.source );
|
||||
IType t = getUltimateType( cost.target );
|
||||
IType s = getUltimateType( cost.source, true );
|
||||
IType t = getUltimateType( cost.target, true );
|
||||
if( s.equals( t ) ){
|
||||
return cost;
|
||||
}
|
||||
|
@ -1439,8 +1445,8 @@ public class CPPSemantics {
|
|||
Cost constructorCost = null;
|
||||
Cost conversionCost = null;
|
||||
|
||||
IType s = getUltimateType( source );
|
||||
IType t = getUltimateType( target );
|
||||
IType s = getUltimateType( source, true );
|
||||
IType t = getUltimateType( target, true );
|
||||
|
||||
ICPPConstructor constructor = null;
|
||||
ICPPMethod conversion = null;
|
||||
|
@ -1453,7 +1459,9 @@ public class CPPSemantics {
|
|||
ICPPConstructor [] constructors = ((ICPPClassType)t).getConstructors();
|
||||
|
||||
if( constructors.length > 0 ){
|
||||
constructor = (ICPPConstructor) resolveFunction( data, Arrays.asList( constructors ) );
|
||||
//the list out of Arrays.asList does not support remove, which we need
|
||||
ArrayList list = new ArrayList( Arrays.asList( constructors ) );
|
||||
constructor = (ICPPConstructor) resolveFunction( data, list );
|
||||
}
|
||||
if( constructor != null && constructor.isExplicit() ){
|
||||
constructor = null;
|
||||
|
@ -1503,13 +1511,15 @@ public class CPPSemantics {
|
|||
return cost;
|
||||
}
|
||||
|
||||
static protected IType getUltimateType( IType type ){
|
||||
static protected IType getUltimateType( IType type, boolean stopAtPointerToMember ){
|
||||
try {
|
||||
while( true ){
|
||||
if( type instanceof ITypedef )
|
||||
type = ((ITypedef)type).getType();
|
||||
else if( type instanceof IQualifierType )
|
||||
type = ((IQualifierType)type).getType();
|
||||
else if( stopAtPointerToMember && type instanceof ICPPPointerToMemberType )
|
||||
return type;
|
||||
else if( type instanceof IPointerType )
|
||||
type = ((IPointerType) type).getType();
|
||||
else if( type instanceof ICPPReferenceType )
|
||||
|
@ -1523,7 +1533,7 @@ public class CPPSemantics {
|
|||
}
|
||||
|
||||
static private boolean isCompleteType( IType type ){
|
||||
type = getUltimateType( type );
|
||||
type = getUltimateType( type, false );
|
||||
if( type instanceof ICPPClassType && ((ICPPBinding)type).getDefinition() == null ){
|
||||
return false;
|
||||
}
|
||||
|
@ -1583,7 +1593,10 @@ public class CPPSemantics {
|
|||
else if( op1 == null ^ op2 == null) {
|
||||
canConvert = false;
|
||||
break;
|
||||
}
|
||||
} else if( op1 instanceof ICPPPointerToMemberType ^ op2 instanceof ICPPPointerToMemberType ){
|
||||
canConvert = false;
|
||||
break;
|
||||
}
|
||||
|
||||
//if const is in cv1,j then const is in cv2,j. Similary for volatile
|
||||
if( ( op1.isConst() && !op2.isConst() ) || ( op1.isVolatile() && !op2.isVolatile() ) ) {
|
||||
|
@ -1634,8 +1647,8 @@ public class CPPSemantics {
|
|||
* @throws DOMException
|
||||
*/
|
||||
static private void promotion( Cost cost ) throws DOMException{
|
||||
IType src = getUltimateType( cost.source );
|
||||
IType trg = getUltimateType( cost.target );
|
||||
IType src = getUltimateType( cost.source, true );
|
||||
IType trg = getUltimateType( cost.target, true );
|
||||
|
||||
if( src.equals( trg ) )
|
||||
return;
|
||||
|
@ -1666,15 +1679,10 @@ public class CPPSemantics {
|
|||
|
||||
cost.conversion = 0;
|
||||
cost.detail = 0;
|
||||
|
||||
// if( !src.hasSamePtrs( trg ) ){
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
IType s = getUltimateType( src );
|
||||
IType t = getUltimateType( trg );
|
||||
|
||||
|
||||
|
||||
IType s = getUltimateType( src, true );
|
||||
IType t = getUltimateType( trg, true );
|
||||
|
||||
if( s instanceof ICPPClassType ){
|
||||
//4.10-2 an rvalue of type "pointer to cv T", where T is an object type can be
|
||||
//converted to an rvalue of type "pointer to cv void"
|
||||
|
@ -1698,32 +1706,24 @@ public class CPPSemantics {
|
|||
//An rvalue of an enumeration type can be converted to an rvalue of an integer type.
|
||||
cost.rank = Cost.CONVERSION_RANK;
|
||||
cost.conversion = 1;
|
||||
}
|
||||
|
||||
//TODO
|
||||
// else if( ptr.getType() == ITypeInfo.PtrOp.t_memberPointer ){
|
||||
// //4.11-2 An rvalue of type "pointer to member of B of type cv T", where B is a class type,
|
||||
// //can be converted to an rvalue of type "pointer to member of D of type cv T" where D is a
|
||||
// //derived class of B
|
||||
// ITypeInfo.PtrOp srcPtr = trg.hasPtrOperators() ? (ITypeInfo.PtrOp)trg.getPtrOperators().get(0) : null;
|
||||
// if( trgDecl.isType( srcDecl.getType() ) && srcPtr != null && srcPtr.getType() == ITypeInfo.PtrOp.t_memberPointer ){
|
||||
// try {
|
||||
// temp = hasBaseClass( ptr.getMemberOf(), srcPtr.getMemberOf() );
|
||||
// } catch (ParserSymbolTableException e) {
|
||||
// //not going to happen since we didn't ask for the visibility exception
|
||||
// }
|
||||
// cost.rank = ( temp > -1 ) ? Cost.CONVERSION_RANK : Cost.NO_MATCH_RANK;
|
||||
// cost.detail = 1;
|
||||
// cost.conversion = ( temp > -1 ) ? temp : 0;
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
} else if( s instanceof ICPPPointerToMemberType && t instanceof ICPPPointerToMemberType ){
|
||||
//4.11-2 An rvalue of type "pointer to member of B of type cv T", where B is a class type,
|
||||
//can be converted to an rvalue of type "pointer to member of D of type cv T" where D is a
|
||||
//derived class of B
|
||||
ICPPPointerToMemberType spm = (ICPPPointerToMemberType) s;
|
||||
ICPPPointerToMemberType tpm = (ICPPPointerToMemberType) t;
|
||||
if( spm.getType().equals( tpm.getType() ) ){
|
||||
temp = hasBaseClass( tpm.getMemberOfClass(), spm.getMemberOfClass(), false );
|
||||
cost.rank = ( temp > -1 ) ? Cost.CONVERSION_RANK : Cost.NO_MATCH_RANK;
|
||||
cost.conversion = ( temp > -1 ) ? temp : 0;
|
||||
cost.detail = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static private void derivedToBaseConversion( Cost cost ) throws DOMException {
|
||||
IType s = getUltimateType( cost.source );
|
||||
IType t = getUltimateType( cost.target );
|
||||
IType s = getUltimateType( cost.source, true );
|
||||
IType t = getUltimateType( cost.target, true );
|
||||
|
||||
if( cost.targetHadReference && s instanceof ICPPClassType && t instanceof ICPPClassType ){
|
||||
int temp = hasBaseClass( (ICPPClassType) s, (ICPPClassType) t, true );
|
||||
|
@ -1735,24 +1735,48 @@ public class CPPSemantics {
|
|||
}
|
||||
}
|
||||
|
||||
static private int hasBaseClass( ICPPClassType symbol, ICPPClassType base, boolean needVisibility ) throws DOMException {
|
||||
static private int hasBaseClass( IBinding symbol, IBinding base, boolean needVisibility ) throws DOMException {
|
||||
if( symbol == base ){
|
||||
return 0;
|
||||
}
|
||||
ICPPClassType clsSymbol = null;
|
||||
ICPPClassType clsBase = null;
|
||||
IType temp = null;
|
||||
while( symbol instanceof ITypedef ){
|
||||
temp = ((ITypedef)symbol).getType();
|
||||
if( temp instanceof IBinding )
|
||||
symbol = (IBinding) temp;
|
||||
else return -1;
|
||||
}
|
||||
if( symbol instanceof ICPPClassType )
|
||||
clsSymbol = (ICPPClassType) symbol;
|
||||
else return -1;
|
||||
|
||||
while( base instanceof ITypedef ){
|
||||
temp = ((ITypedef)base).getType();
|
||||
if( temp instanceof IBinding )
|
||||
base= (IBinding) temp;
|
||||
else return -1;
|
||||
}
|
||||
if( base instanceof ICPPClassType )
|
||||
clsBase = (ICPPClassType) base;
|
||||
else return -1;
|
||||
|
||||
|
||||
ICPPClassType parent = null;
|
||||
ICPPBase [] bases = symbol.getBases();
|
||||
ICPPBase [] bases = clsSymbol.getBases();
|
||||
|
||||
for( int i = 0; i < bases.length; i ++ ){
|
||||
ICPPBase wrapper = bases[i];
|
||||
parent = bases[i].getBaseClass();
|
||||
boolean isVisible = ( wrapper.getVisibility() == ICPPBase.v_public);
|
||||
|
||||
if( parent == base ){
|
||||
if( parent == clsBase ){
|
||||
if( needVisibility && !isVisible )
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
int n = hasBaseClass( parent, base, needVisibility );
|
||||
int n = hasBaseClass( parent, clsBase, needVisibility );
|
||||
if( n > 0 )
|
||||
return n + 1;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,7 @@ import org.eclipse.cdt.core.dom.ast.ITypedef;
|
|||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
|
||||
import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
|
||||
|
@ -122,12 +123,14 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
|
@ -537,7 +540,7 @@ public class CPPVisitor {
|
|||
}
|
||||
} else if( parent instanceof ICPPASTFieldReference ){
|
||||
IASTExpression owner = ((ICPPASTFieldReference)parent).getFieldOwner();
|
||||
IType type = CPPSemantics.getUltimateType( getExpressionType( owner ) );
|
||||
IType type = CPPSemantics.getUltimateType( getExpressionType( owner ), false );
|
||||
if( type instanceof ICPPClassType ){
|
||||
return ((ICPPClassType) type).getCompositeScope();
|
||||
}
|
||||
|
@ -1571,7 +1574,7 @@ public class CPPVisitor {
|
|||
|
||||
private static IType getPointerTypes( IType type, IASTDeclarator declarator ){
|
||||
IASTPointerOperator [] ptrOps = declarator.getPointerOperators();
|
||||
for( int i = ptrOps.length - 1; i >= 0; i-- ){
|
||||
for( int i = 0; i < ptrOps.length; i++ ){
|
||||
if( ptrOps[i] instanceof ICPPASTPointerToMember )
|
||||
type = new CPPPointerToMemberType( type, (ICPPASTPointerToMember) ptrOps[i] );
|
||||
else if( ptrOps[i] instanceof IASTPointer )
|
||||
|
@ -1751,6 +1754,22 @@ public class CPPVisitor {
|
|||
return e.getProblem();
|
||||
}
|
||||
}
|
||||
} else if( expression instanceof IASTBinaryExpression ){
|
||||
IASTBinaryExpression binary = (IASTBinaryExpression) expression;
|
||||
IType type = getExpressionType( ((IASTBinaryExpression) expression).getOperand2() );
|
||||
if( binary.getOperator() == ICPPASTBinaryExpression.op_pmarrow ||
|
||||
binary.getOperator() == ICPPASTBinaryExpression.op_pmdot )
|
||||
{
|
||||
if( type instanceof ICPPPointerToMemberType ){
|
||||
try {
|
||||
return ((ICPPPointerToMemberType)type).getType();
|
||||
} catch ( DOMException e ) {
|
||||
return e.getProblem();
|
||||
}
|
||||
}
|
||||
return new ProblemBinding( IProblemBinding.SEMANTIC_INVALID_TYPE, new char[0] );
|
||||
}
|
||||
return type;
|
||||
}
|
||||
else if( expression instanceof IASTUnaryExpression )
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue