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

fix bug 103715 and partial for 98171 (getBases)

This commit is contained in:
Andrew Niefer 2005-07-13 21:59:15 +00:00
parent 0fdbe3e9c4
commit c683a357d4
11 changed files with 128 additions and 69 deletions

View file

@ -500,35 +500,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
}
}
/**
[--Start Example(CPP 14.8.3-4):
template<class T> struct B { };
template<class T> struct D : public B<T> { };
template<class T> void f(B<T>&);
void g(B<int>& bi, D<int>& di)
{
f(bi); // f(bi)
f(di); // f( (B<int>&)di )
}
--End Example]
*/
public void test14_8_3s4() {
StringBuffer buffer = new StringBuffer();
buffer.append("template<class T> struct B { };\n"); //$NON-NLS-1$
buffer.append("template<class T> struct D : public B<T> { };\n"); //$NON-NLS-1$
buffer.append("template<class T> void f(B<T>&);\n"); //$NON-NLS-1$
buffer.append("void g(B<int>& bi, D<int>& di)\n"); //$NON-NLS-1$
buffer.append("{\n"); //$NON-NLS-1$
buffer.append("f(bi); // f(bi)\n"); //$NON-NLS-1$
buffer.append("f(di); // f( (B<int>&)di )\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
try {
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
assertTrue(false);
} catch (Exception e) {
}
}
/**
[--Start Example(CPP 14.5.5.1-8a):
// Guaranteed to be the same

View file

@ -11213,6 +11213,31 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
}
/**
[--Start Example(CPP 14.8.3-4):
template<class T> struct B { };
template<class T> struct D : public B<T> { };
template<class T> void f(B<T>&);
void g(B<int>& bi, D<int>& di)
{
f(bi); // f(bi)
f(di); // f( (B<int>&)di )
}
--End Example]
*/
public void test14_8_3s4() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("template<class T> struct B { };\n"); //$NON-NLS-1$
buffer.append("template<class T> struct D : public B<T> { };\n"); //$NON-NLS-1$
buffer.append("template<class T> void f(B<T>&);\n"); //$NON-NLS-1$
buffer.append("void g(B<int>& bi, D<int>& di)\n"); //$NON-NLS-1$
buffer.append("{\n"); //$NON-NLS-1$
buffer.append("f(bi); // f(bi)\n"); //$NON-NLS-1$
buffer.append("f(di); // f( (B<int>&)di )\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
}
/**
[--Start Example(CPP 14.8.3-6):

View file

@ -33,6 +33,7 @@ import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
@ -1846,4 +1847,28 @@ public class AST2TemplateTests extends AST2BaseTest {
assertSame( ((ICPPTemplateInstance)a).getTemplateDefinition(), A );
assertSame( local, col.getName(7).resolveBinding() );
}
public void testBug103715() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("template <class T> class A : public T {}; \n"); //$NON-NLS-1$
buffer.append("class B { int base; }; \n"); //$NON-NLS-1$
buffer.append("void f() { \n"); //$NON-NLS-1$
buffer.append(" A< B > a; \n"); //$NON-NLS-1$
buffer.append(" a.base; \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP, true, true );
CPPNameCollector col = new CPPNameCollector();
tu.accept( col );
ICPPField base = (ICPPField) col.getName(4).resolveBinding();
assertSame( base, col.getName(11).resolveBinding() );
ICPPClassType B = (ICPPClassType) col.getName(3).resolveBinding();
ICPPClassType A = (ICPPClassType) col.getName(6).resolveBinding();
ICPPBase [] bases = A.getBases();
assertEquals( bases.length, 1 );
assertSame( bases[0].getBaseClass(), B );
}
}

View file

@ -353,7 +353,10 @@ public class CPPGenerateIndexVisitor extends CPPASTVisitor {
ICPPBase[] baseClasses = cppClassBinding.getBases();
for (int i = 0; i < baseClasses.length; i++) {
ICPPBase base = baseClasses[i];
ICPPClassType baseClass = baseClasses[i].getBaseClass();
IBinding b = baseClasses[i].getBaseClass();
if( !(b instanceof ICPPClassType) )
continue;
ICPPClassType baseClass = (ICPPClassType) b;
// skip problem bindings
if (baseClass instanceof IProblemBinding)
continue;

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
/**
@ -22,11 +23,13 @@ public interface ICPPBase {
public static final ICPPBase[] EMPTY_BASE_ARRAY = new ICPPBase[0];
/**
* The base class.
* The base class. Generally a ICPPClassType, but may be a ICPPTemplateParameter.
* In the case of typedefs, the binding being typedefed will be returned instead of
* the typedef itself.
*
* @return
*/
public ICPPClassType getBaseClass() throws DOMException;
public IBinding getBaseClass() throws DOMException;
/**
* The visibility qualifier applied to the base class.

View file

@ -18,9 +18,11 @@ import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
@ -33,7 +35,7 @@ public class CPPBaseClause implements ICPPBase {
public CPPBaseProblem( IASTNode node, int id, char[] arg ) {
super( node, id, arg );
}
public ICPPClassType getBaseClass() {
public IBinding getBaseClass() {
if( classProblem == null ){
classProblem = new CPPClassType.CPPClassTypeProblem( node, id, arg );
}
@ -49,7 +51,7 @@ public class CPPBaseClause implements ICPPBase {
}
}
private ICPPASTBaseSpecifier base = null;
private ICPPClassType baseClass = null;
private IBinding baseClass = null;
public CPPBaseClause( ICPPASTBaseSpecifier base ){
this.base = base;
@ -58,11 +60,15 @@ public class CPPBaseClause implements ICPPBase {
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPBase#getBaseClass()
*/
public ICPPClassType getBaseClass() {
public IBinding getBaseClass() throws DOMException {
if( baseClass == null ){
IBinding b = base.getName().resolveBinding();
if( b instanceof ICPPClassType )
baseClass = (ICPPClassType) b;
while( b instanceof ITypedef && ((ITypedef)b).getType() instanceof IBinding ){
b = (IBinding) ((ITypedef)b).getType();
}
if( b instanceof ICPPClassType || b instanceof ICPPTemplateParameter )
baseClass = b;
else if( b instanceof IProblemBinding ){
baseClass = new CPPClassType.CPPClassTypeProblem( base.getName(), ((IProblemBinding)b).getID(), base.getName().toCharArray() );
} else {

View file

@ -28,6 +28,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
import org.eclipse.cdt.core.parser.util.ObjectMap;
/**
@ -48,7 +49,20 @@ public class CPPClassInstance extends CPPInstance implements ICPPClassType, ICPP
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getBases()
*/
public ICPPBase[] getBases() {
public ICPPBase[] getBases() throws DOMException {
ICPPClassType cls = (ICPPClassType) getSpecializedBinding();
if( cls != null ){
ICPPBase [] bases = cls.getBases();
for (int i = 0; i < bases.length; i++) {
IBinding T = bases[i].getBaseClass();
if( T instanceof ICPPTemplateTypeParameter && argumentMap.containsKey( T ) ){
IType t = (IType) argumentMap.get( T );
if( t instanceof ICPPClassType )
((CPPBaseClause)bases[i]).setBaseClass( (ICPPClassType) argumentMap.get(T) );
}
}
return bases;
}
return ICPPBase.EMPTY_BASE_ARRAY;
}

View file

@ -55,7 +55,7 @@ public class CPPClassSpecialization extends CPPSpecialization implements
if( cls != null ){
ICPPBase [] bases = cls.getBases();
for (int i = 0; i < bases.length; i++) {
ICPPClassType T = bases[i].getBaseClass();
IBinding T = bases[i].getBaseClass();
if( T instanceof ICPPTemplateTypeParameter && argumentMap.containsKey( T ) ){
IType t = (IType) argumentMap.get( T );
if( t instanceof ICPPClassType )
@ -64,7 +64,6 @@ public class CPPClassSpecialization extends CPPSpecialization implements
}
return bases;
}
// TODO Auto-generated method stub
return ICPPBase.EMPTY_BASE_ARRAY;
}

View file

@ -218,7 +218,9 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements
IField[] fields = getDeclaredFields();
ICPPBase [] bases = getBases();
for ( int i = 0; i < bases.length; i++ ) {
fields = (IField[]) ArrayUtil.addAll( IField.class, fields, bases[i].getBaseClass().getFields() );
IBinding b = bases[i].getBaseClass();
if( b instanceof ICPPClassType )
fields = (IField[]) ArrayUtil.addAll( IField.class, fields, ((ICPPClassType)b).getFields() );
}
return (IField[]) ArrayUtil.trim( IField.class, fields );
}

View file

@ -317,7 +317,9 @@ public class CPPClassType implements ICPPClassType, ICPPInternalClassType {
IField[] fields = getDeclaredFields();
ICPPBase [] bases = getBases();
for ( int i = 0; i < bases.length; i++ ) {
fields = (IField[]) ArrayUtil.addAll( IField.class, fields, bases[i].getBaseClass().getFields() );
IBinding b = bases[i].getBaseClass();
if( b instanceof ICPPClassType )
fields = (IField[]) ArrayUtil.addAll( IField.class, fields, ((ICPPClassType)b).getFields() );
}
return (IField[]) ArrayUtil.trim( IField.class, fields );
}
@ -548,14 +550,16 @@ public class CPPClassType implements ICPPClassType, ICPPInternalClassType {
ICPPBase [] bases = getBases();
for ( int i = 0; i < bases.length; i++ ) {
ICPPClassType cls;
ICPPClassType cls = null;
try {
cls = bases[i].getBaseClass();
IBinding b = bases[i].getBaseClass();
if( b instanceof ICPPClassType )
cls = (ICPPClassType) b;
} catch (DOMException e) {
continue;
}
if( cls instanceof CPPClassType )
result = (ICPPMethod[]) ArrayUtil.addAll( ICPPMethod.class, result, ((CPPClassType)cls).getConversionOperators() );
if( cls instanceof ICPPInternalClassType )
result = (ICPPMethod[]) ArrayUtil.addAll( ICPPMethod.class, result, ((ICPPInternalClassType)cls).getConversionOperators() );
}
return (ICPPMethod[]) ArrayUtil.trim( ICPPMethod.class, result );
}
@ -571,7 +575,9 @@ public class CPPClassType implements ICPPClassType, ICPPInternalClassType {
set.addAll( scope.getImplicitMethods() );
ICPPBase [] bases = getBases();
for ( int i = 0; i < bases.length; i++ ) {
set.addAll( bases[i].getBaseClass().getMethods() );
IBinding b = bases[i].getBaseClass();
if( b instanceof ICPPClassType )
set.addAll( ((ICPPClassType)b).getMethods() );
}
return (ICPPMethod[]) set.keyArray( ICPPMethod.class );
}
@ -591,7 +597,9 @@ public class CPPClassType implements ICPPClassType, ICPPInternalClassType {
ICPPMethod[] methods = getDeclaredMethods();
ICPPBase [] bases = getBases();
for ( int i = 0; i < bases.length; i++ ) {
methods = (ICPPMethod[]) ArrayUtil.addAll( ICPPMethod.class, methods, bases[i].getBaseClass().getAllDeclaredMethods() );
IBinding b = bases[i].getBaseClass();
if( b instanceof ICPPClassType )
methods = (ICPPMethod[]) ArrayUtil.addAll( ICPPMethod.class, methods, ((ICPPClassType)b).getAllDeclaredMethods() );
}
return (ICPPMethod[]) ArrayUtil.trim( ICPPMethod.class, methods );
}

View file

@ -852,7 +852,9 @@ public class CPPSemantics {
for( int i = 0; i < bases.length; i++ ){
if( bases[i] instanceof IProblemBinding )
continue;
getAssociatedScopes( bases[i].getBaseClass(), namespaces, classes );
IBinding b = bases[i].getBaseClass();
if( b instanceof IType )
getAssociatedScopes( (IType) b, namespaces, classes );
}
}
} else if( t instanceof IEnumeration ){
@ -1094,12 +1096,11 @@ public class CPPSemantics {
}
private static Object lookupInParents( CPPSemantics.LookupData data, ICPPScope lookIn ) throws DOMException{
IASTNode node = lookIn.getPhysicalNode();
if( node == null || !(node instanceof ICPPASTCompositeTypeSpecifier) )
return null;
ICPPASTCompositeTypeSpecifier compositeTypeSpec = (ICPPASTCompositeTypeSpecifier) node;
ICPPASTBaseSpecifier [] bases = compositeTypeSpec.getBaseSpecifiers();
ICPPBase [] bases = null;
if( lookIn instanceof ICPPClassScope ){
ICPPClassType c = ((ICPPClassScope)lookIn).getClassType();
bases = c.getBases();
}
Object inherited = null;
Object result = null;
@ -1118,12 +1119,9 @@ public class CPPSemantics {
{
inherited = null;
ICPPClassType cls = null;
IBinding binding = bases[i].getName().resolveBinding();
while( binding instanceof ITypedef && ((ITypedef)binding).getType() instanceof IBinding ){
binding = (IBinding) ((ITypedef)binding).getType();
}
if( binding instanceof ICPPClassType )
cls = (ICPPClassType) binding;
IBinding b = bases[i].getBaseClass();
if( b instanceof ICPPClassType )
cls = (ICPPClassType) b;
else
continue;
ICPPScope parent = (ICPPScope) cls.getCompositeScope();
@ -1159,7 +1157,7 @@ public class CPPSemantics {
visitVirtualBaseClasses( data, cls );
}
} else {
data.problem = new ProblemBinding( bases[i].getName(), IProblemBinding.SEMANTIC_CIRCULAR_INHERITANCE, bases[i].getName().toCharArray() );
data.problem = new ProblemBinding( null, IProblemBinding.SEMANTIC_CIRCULAR_INHERITANCE, cls.getNameCharArray() );
return null;
}
}
@ -1218,9 +1216,13 @@ public class CPPSemantics {
if( bases[i].isVirtual() ){
if( data.visited == ObjectSet.EMPTY_SET )
data.visited = new ObjectSet(2);
data.visited.put( bases[i].getBaseClass().getCompositeScope() );
IBinding b = bases[i].getBaseClass();
if( b instanceof ICPPClassType )
data.visited.put( ((ICPPClassType)b).getCompositeScope() );
} else {
visitVirtualBaseClasses( data, bases[i].getBaseClass() );
IBinding b = bases[i].getBaseClass();
if( b instanceof ICPPClassType )
visitVirtualBaseClasses( data, (ICPPClassType) b );
}
} catch ( DOMException e1 ) {
}
@ -3104,17 +3106,18 @@ public class CPPSemantics {
else return -1;
ICPPClassType parent = null;
IBinding parent = null;
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.isSameType( clsBase ) ||
(clsBase instanceof ICPPSpecialization && //allow some flexibility with templates
((IType)((ICPPSpecialization)clsBase).getSpecializedBinding()).isSameType( parent ) ) )
if( parent instanceof IType &&
( ((IType)parent).isSameType( clsBase ) ||
( clsBase instanceof ICPPSpecialization && //allow some flexibility with templates
((IType)((ICPPSpecialization)clsBase).getSpecializedBinding()).isSameType( (IType) parent ) ) ) )
{
if( needVisibility && !isVisible )
return -1;