mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 17:35:35 +02:00
- implement getConstructors for class templates and their instantiations
- fix bugs 99254, 99258 - fix NPE & ClassCastException
This commit is contained in:
parent
3eb94cf34a
commit
71ecce9bed
14 changed files with 399 additions and 83 deletions
|
@ -34,6 +34,7 @@ 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;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
|
@ -1673,4 +1674,78 @@ public class AST2TemplateTests extends AST2BaseTest {
|
|||
|
||||
assertSame( col.getName(5).resolveBinding(), col.getName(6).resolveBinding() );
|
||||
}
|
||||
|
||||
public void testBug99254() throws Exception{
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("template <class T> class A { \n");
|
||||
buffer.append(" A( T t ); \n");
|
||||
buffer.append("}; \n");
|
||||
buffer.append("void f( A<int> a ); \n");
|
||||
buffer.append("void m(){ \n");
|
||||
buffer.append(" f( A<int>(1) ); \n");
|
||||
buffer.append("} \n");
|
||||
|
||||
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
tu.accept( col );
|
||||
|
||||
ICPPConstructor ctor = (ICPPConstructor) col.getName(2).resolveBinding();
|
||||
ICPPFunction f = (ICPPFunction) col.getName(5).resolveBinding();
|
||||
|
||||
ICPPSpecialization spec = (ICPPSpecialization) col.getName(11).resolveBinding();
|
||||
assertSame( spec.getSpecializedBinding(), ctor );
|
||||
|
||||
assertSame( f, col.getName(10).resolveBinding() );
|
||||
}
|
||||
|
||||
public void testBug99254_2() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("namespace core { \n");
|
||||
buffer.append(" template<class T> class A { \n");
|
||||
buffer.append(" A( T x, T y ); \n");
|
||||
buffer.append(" }; \n");
|
||||
buffer.append("} \n");
|
||||
buffer.append("class B { \n");
|
||||
buffer.append(" int add(const core::A<int> &rect ); \n");
|
||||
buffer.append("}; \n");
|
||||
buffer.append("void f( B* b ){ \n");
|
||||
buffer.append(" b->add( core::A<int>(10, 2) ); \n");
|
||||
buffer.append("} \n");
|
||||
|
||||
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
tu.accept( col );
|
||||
|
||||
ICPPConstructor ctor = (ICPPConstructor) col.getName(3).resolveBinding();
|
||||
ICPPMethod add = (ICPPMethod) col.getName(9).resolveBinding();
|
||||
|
||||
ICPPSpecialization spec = (ICPPSpecialization) col.getName(20).resolveBinding();
|
||||
assertSame( spec.getSpecializedBinding(), ctor );
|
||||
|
||||
assertSame( add, col.getName(19).resolveBinding() );
|
||||
}
|
||||
|
||||
public void testBug99254_3() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("template <class T> class A { A( T ); }; \n");
|
||||
buffer.append("typedef signed int s32; \n");
|
||||
buffer.append("class B { \n");
|
||||
buffer.append(" int add(const A<s32> &rect ); \n");
|
||||
buffer.append("}; \n");
|
||||
buffer.append("void f( B* b ){ \n");
|
||||
buffer.append(" b->add( A<int>(10) ); \n");
|
||||
buffer.append("} \n");
|
||||
|
||||
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
tu.accept( col );
|
||||
|
||||
ICPPConstructor ctor = (ICPPConstructor) col.getName(2).resolveBinding();
|
||||
ICPPMethod add = (ICPPMethod) col.getName(7).resolveBinding();
|
||||
|
||||
ICPPSpecialization spec = (ICPPSpecialization) col.getName(17).resolveBinding();
|
||||
assertSame( spec.getSpecializedBinding(), ctor );
|
||||
|
||||
assertSame( add, col.getName(16).resolveBinding() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,6 +63,13 @@ public class CPPBasicType implements ICPPBasicType {
|
|||
return false;
|
||||
|
||||
CPPBasicType t = (CPPBasicType) object;
|
||||
if( type != t.type )
|
||||
return false;
|
||||
|
||||
if( type == IBasicType.t_int ){
|
||||
//signed int and int are equivalent
|
||||
return (qualifierBits & ~IS_SIGNED ) == (t.qualifierBits & ~IS_SIGNED );
|
||||
}
|
||||
return ( type == t.type && qualifierBits == t.qualifierBits );
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
|
|
|
@ -104,7 +104,10 @@ public class CPPClassInstance extends CPPInstance implements ICPPClassType, ICPP
|
|||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getConstructors()
|
||||
*/
|
||||
public ICPPConstructor[] getConstructors() throws DOMException {
|
||||
return new ICPPConstructor[0];
|
||||
CPPClassInstanceScope scope = (CPPClassInstanceScope) getCompositeScope();
|
||||
if( scope.isFullyCached() )
|
||||
return scope.getConstructors();
|
||||
return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
|
@ -22,10 +23,12 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
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.ICPPTemplateInstance;
|
||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
import org.eclipse.cdt.core.parser.util.ObjectMap;
|
||||
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
||||
|
||||
|
@ -33,11 +36,15 @@ import org.eclipse.cdt.core.parser.util.ObjectSet;
|
|||
* @author aniefer
|
||||
*/
|
||||
public class CPPClassInstanceScope implements ICPPClassScope {
|
||||
private static final char[] CONSTRUCTOR_KEY = "!!!CTOR!!!".toCharArray(); //$NON-NLS-1$
|
||||
|
||||
private CharArrayObjectMap bindings;
|
||||
private ObjectMap instanceMap = ObjectMap.EMPTY_MAP;
|
||||
|
||||
private ICPPTemplateInstance instance;
|
||||
private boolean isFullyCached = false;
|
||||
private boolean doneConstructors = false;
|
||||
|
||||
/**
|
||||
* @param instance
|
||||
*/
|
||||
|
@ -60,11 +67,14 @@ public class CPPClassInstanceScope implements ICPPClassScope {
|
|||
}
|
||||
|
||||
public IBinding getBinding( IASTName name, boolean forceResolve ) {
|
||||
//ICPPClassScope scope = (ICPPClassScope) getOriginalClass().getCompositeScope();
|
||||
char [] c = name.toCharArray();
|
||||
if( bindings == null )
|
||||
return null;
|
||||
|
||||
if( CharArrayUtils.equals( c, instance.getNameCharArray() ) && CPPClassScope.isConstructorReference( name ) ){
|
||||
c = CONSTRUCTOR_KEY;
|
||||
}
|
||||
|
||||
Object cache = bindings.get( c );
|
||||
if( cache != null ){
|
||||
int i = ( cache instanceof ObjectSet ) ? 0 : -1;
|
||||
|
@ -150,13 +160,17 @@ public class CPPClassInstanceScope implements ICPPClassScope {
|
|||
return;
|
||||
|
||||
if( bindings == null )
|
||||
bindings = new CharArrayObjectMap(1);
|
||||
bindings = new CharArrayObjectMap(1);
|
||||
char [] c = name.toCharArray();
|
||||
|
||||
IASTNode parent = name.getParent();
|
||||
if( parent instanceof IASTDeclarator && CPPVisitor.isConstructor( this, (IASTDeclarator) parent ) ){
|
||||
c = CONSTRUCTOR_KEY;
|
||||
}
|
||||
Object o = bindings.get( c );
|
||||
if( o != null ){
|
||||
if( o instanceof ObjectSet ){
|
||||
((ObjectSet)o).put( name );
|
||||
//bindings.put( c, ArrayUtil.append( Object.class, (Object[]) o, name ) );
|
||||
} else {
|
||||
ObjectSet temp = new ObjectSet( 2 );
|
||||
temp.put( o );
|
||||
|
@ -168,6 +182,36 @@ public class CPPClassInstanceScope implements ICPPClassScope {
|
|||
}
|
||||
}
|
||||
|
||||
protected ICPPConstructor [] getConstructors( ){
|
||||
if( bindings == null )
|
||||
return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY;
|
||||
|
||||
if( !doneConstructors ){
|
||||
ICPPConstructor[] ctors;
|
||||
try {
|
||||
ctors = ((ICPPClassType)instance.getTemplateDefinition()).getConstructors();
|
||||
for (int i = 0; i < ctors.length; i++) {
|
||||
addBinding( ctors[i] );
|
||||
}
|
||||
doneConstructors = true;
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
}
|
||||
ICPPConstructor[] ctors = CPPClassScope.getConstructors( bindings, true );
|
||||
for (int i = 0; i < ctors.length; i++) {
|
||||
if( instanceMap.containsKey( ctors[i] ) ){
|
||||
ctors[i] = (ICPPConstructor) instanceMap.get( ctors[i] );
|
||||
} else {
|
||||
IBinding b = CPPTemplates.createSpecialization( this, ctors[i], instance.getArgumentMap() );
|
||||
if( instanceMap == ObjectMap.EMPTY_MAP )
|
||||
instanceMap = new ObjectMap(2);
|
||||
instanceMap.put( ctors[i], b );
|
||||
ctors[i] = (ICPPConstructor) b;
|
||||
}
|
||||
}
|
||||
return ctors;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#setFullyCached(boolean)
|
||||
*/
|
||||
|
@ -248,7 +292,7 @@ public class CPPClassInstanceScope implements ICPPClassScope {
|
|||
public void addBinding(IBinding binding) {
|
||||
if( bindings == null )
|
||||
bindings = new CharArrayObjectMap(1);
|
||||
char [] c = binding.getNameCharArray();
|
||||
char [] c = (binding instanceof ICPPConstructor) ? CONSTRUCTOR_KEY : binding.getNameCharArray();
|
||||
Object o = bindings.get( c );
|
||||
if( o != null ){
|
||||
if( o instanceof ObjectSet ){
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
||||
|
||||
|
@ -50,8 +51,7 @@ import org.eclipse.cdt.core.parser.util.ObjectSet;
|
|||
* @author aniefer
|
||||
*/
|
||||
public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
||||
private ObjectSet constructorBindings = ObjectSet.EMPTY_SET;
|
||||
private ObjectSet constructorNames = ObjectSet.EMPTY_SET;
|
||||
private static final char [] CONSTRUCTOR_KEY = "!!!CTOR!!!".toCharArray(); //$NON-NLS-1$
|
||||
private ICPPMethod[] implicits = null;
|
||||
|
||||
public CPPClassScope( ICPPASTCompositeTypeSpecifier physicalNode ) {
|
||||
|
@ -193,17 +193,26 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
|||
}
|
||||
|
||||
private void addConstructor( Object constructor ){
|
||||
if( constructor instanceof IBinding ){
|
||||
if( constructorBindings == ObjectSet.EMPTY_SET )
|
||||
constructorBindings = new ObjectSet( 2 );
|
||||
|
||||
constructorBindings.put( constructor );
|
||||
} else {
|
||||
if( constructorNames == ObjectSet.EMPTY_SET )
|
||||
constructorNames = new ObjectSet( 2 );
|
||||
|
||||
constructorNames.put( constructor );
|
||||
if( bindings == null )
|
||||
bindings = new CharArrayObjectMap(1);
|
||||
|
||||
if( constructor instanceof IASTName && ((IASTName)constructor).getBinding() != null ){
|
||||
constructor = ((IASTName)constructor).getBinding();
|
||||
}
|
||||
|
||||
Object o = bindings.get( CONSTRUCTOR_KEY );
|
||||
if( o != null ){
|
||||
if( o instanceof ObjectSet ){
|
||||
((ObjectSet)o).put( constructor );
|
||||
} else {
|
||||
ObjectSet set = new ObjectSet(2);
|
||||
set.put( o );
|
||||
set.put( constructor );
|
||||
bindings.put( CONSTRUCTOR_KEY, set );
|
||||
}
|
||||
} else {
|
||||
bindings.put( CONSTRUCTOR_KEY, constructor );
|
||||
}
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#getBinding(int, char[])
|
||||
|
@ -219,9 +228,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
|||
}
|
||||
if( CharArrayUtils.equals( c, compName.toCharArray() ) ){
|
||||
if( isConstructorReference( name ) ){
|
||||
// if( constructors == null )
|
||||
// return null;
|
||||
return CPPSemantics.resolveAmbiguities( name, getConstructors( resolve ) );
|
||||
return CPPSemantics.resolveAmbiguities( name, getConstructors( bindings, resolve ) );
|
||||
}
|
||||
//9.2 ... The class-name is also inserted into the scope of the class itself
|
||||
return compName.resolveBinding();
|
||||
|
@ -230,15 +237,47 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
|||
}
|
||||
|
||||
protected ICPPConstructor [] getConstructors( boolean forceResolve ){
|
||||
if( forceResolve && constructorNames.size() > 0 ){
|
||||
Object [] names = constructorNames.keyArray();
|
||||
for( int i = 0; i < names.length; i++ ){
|
||||
ICPPConstructor ctor = (ICPPConstructor) ((IASTName)names[i]).resolveBinding();
|
||||
constructorBindings.put( ctor );
|
||||
}
|
||||
constructorNames.clear();
|
||||
}
|
||||
return (ICPPConstructor[]) ArrayUtil.trim( ICPPConstructor.class, constructorBindings.keyArray(), true);
|
||||
return getConstructors( bindings, forceResolve );
|
||||
}
|
||||
static protected ICPPConstructor [] getConstructors( CharArrayObjectMap bindings, boolean forceResolve ){
|
||||
if( bindings == null )
|
||||
return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY;
|
||||
|
||||
Object o = bindings.get( CONSTRUCTOR_KEY );
|
||||
if( o != null ){
|
||||
IBinding binding = null;
|
||||
if( o instanceof ObjectSet ) {
|
||||
ObjectSet set = (ObjectSet) o;
|
||||
IBinding [] bs = null;
|
||||
for( int i = 0; i < set.size(); i++ ){
|
||||
Object obj = set.keyAt( i );
|
||||
if( obj instanceof IASTName ){
|
||||
IASTName n = (IASTName) obj;
|
||||
binding = n.getBinding();
|
||||
if( binding != null || forceResolve ){
|
||||
binding = n.resolveBinding();
|
||||
set.remove( n );
|
||||
set.put( binding );
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
} else if( obj instanceof ICPPConstructor )
|
||||
bs = (IBinding[]) ArrayUtil.append( ICPPConstructor.class, bs, obj );
|
||||
}
|
||||
return (ICPPConstructor[]) ArrayUtil.trim( ICPPConstructor.class, bs );
|
||||
} else if( o instanceof IASTName ){
|
||||
if( forceResolve || ((IASTName)o).getBinding() != null ){
|
||||
binding = ((IASTName)o).resolveBinding();
|
||||
bindings.put( CONSTRUCTOR_KEY, binding );
|
||||
}
|
||||
} else if( o instanceof IBinding ){
|
||||
binding = (IBinding) o;
|
||||
}
|
||||
if( binding != null && binding instanceof ICPPConstructor){
|
||||
return new ICPPConstructor[] { (ICPPConstructor) binding };
|
||||
}
|
||||
}
|
||||
return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -253,12 +292,12 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
|||
compName = ns[ ns.length - 1 ];
|
||||
}
|
||||
if( CharArrayUtils.equals( n, compName.toCharArray() ) ){
|
||||
return (IBinding[]) ArrayUtil.addAll( IBinding.class, null, getConstructors( true ) );
|
||||
return (IBinding[]) ArrayUtil.addAll( IBinding.class, null, getConstructors( bindings, true ) );
|
||||
}
|
||||
return super.find( name );
|
||||
}
|
||||
|
||||
private boolean isConstructorReference( IASTName name ){
|
||||
static protected boolean isConstructorReference( IASTName name ){
|
||||
if( name.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY ) return false;
|
||||
IASTNode node = name.getParent();
|
||||
if( node instanceof ICPPASTTemplateId )
|
||||
|
@ -313,21 +352,9 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
|||
*/
|
||||
public void removeBinding(IBinding binding) {
|
||||
if( binding instanceof ICPPConstructor ){
|
||||
if( constructorBindings.containsKey( binding ) )
|
||||
constructorBindings.remove( binding );
|
||||
setFullyCached( false );
|
||||
removeBinding( CONSTRUCTOR_KEY, binding );
|
||||
} else {
|
||||
super.removeBinding( binding );
|
||||
removeBinding( binding.getNameCharArray(), binding );
|
||||
}
|
||||
}
|
||||
|
||||
public void flushCache() {
|
||||
constructorNames.clear();
|
||||
for( int i = constructorBindings.size() - 1; i >= 0; i-- ){
|
||||
IBinding binding = (IBinding) constructorBindings.keyAt(i);
|
||||
if( !(binding instanceof CPPImplicitConstructor) )
|
||||
constructorBindings.remove( binding );
|
||||
}
|
||||
super.flushCache();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.eclipse.cdt.core.dom.ast.DOMException;
|
|||
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.IASTSimpleDeclaration;
|
||||
|
@ -33,6 +34,7 @@ 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;
|
||||
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;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
|
@ -267,8 +269,37 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements
|
|||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getConstructors()
|
||||
*/
|
||||
public ICPPConstructor[] getConstructors() {
|
||||
return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY;
|
||||
public ICPPConstructor[] getConstructors() throws DOMException {
|
||||
if( definition == null ){
|
||||
checkForDefinition();
|
||||
if( definition == null ){
|
||||
IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null;
|
||||
return new ICPPConstructor [] { new CPPConstructor.CPPConstructorProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) };
|
||||
}
|
||||
}
|
||||
|
||||
ICPPClassScope scope = (ICPPClassScope) getCompositeScope();
|
||||
if( scope.isFullyCached() )
|
||||
return ((CPPClassScope)scope).getConstructors( true );
|
||||
|
||||
IASTDeclaration [] members = getCompositeTypeSpecifier().getMembers();
|
||||
for( int i = 0; i < members.length; i++ ){
|
||||
IASTDeclaration decl = members[i];
|
||||
if( decl instanceof ICPPASTTemplateDeclaration )
|
||||
decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration();
|
||||
if( decl instanceof IASTSimpleDeclaration ){
|
||||
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decl).getDeclarators();
|
||||
for( int j = 0; j < dtors.length; j++ ){
|
||||
if( dtors[j] == null ) break;
|
||||
scope.addName( dtors[j].getName() );
|
||||
}
|
||||
} else if( decl instanceof IASTFunctionDefinition ){
|
||||
IASTDeclarator dtor = ((IASTFunctionDefinition)decl).getDeclarator();
|
||||
scope.addName( dtor.getName() );
|
||||
}
|
||||
}
|
||||
|
||||
return ((CPPClassScope)scope).getConstructors( true );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
|
|
@ -674,14 +674,17 @@ public class CPPClassType implements ICPPClassType, ICPPInternalClassType {
|
|||
|
||||
IASTDeclaration [] members = getCompositeTypeSpecifier().getMembers();
|
||||
for( int i = 0; i < members.length; i++ ){
|
||||
if( members[i] instanceof IASTSimpleDeclaration ){
|
||||
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)members[i]).getDeclarators();
|
||||
IASTDeclaration decl = members[i];
|
||||
if( decl instanceof ICPPASTTemplateDeclaration )
|
||||
decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration();
|
||||
if( decl instanceof IASTSimpleDeclaration ){
|
||||
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decl).getDeclarators();
|
||||
for( int j = 0; j < dtors.length; j++ ){
|
||||
if( dtors[j] == null ) break;
|
||||
scope.addName( dtors[j].getName() );
|
||||
}
|
||||
} else if( members[i] instanceof IASTFunctionDefinition ){
|
||||
IASTDeclarator dtor = ((IASTFunctionDefinition)members[i]).getDeclarator();
|
||||
} else if( decl instanceof IASTFunctionDefinition ){
|
||||
IASTDeclarator dtor = ((IASTFunctionDefinition)decl).getDeclarator();
|
||||
scope.addName( dtor.getName() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*************************************************************************
|
||||
* 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 June 14, 2005
|
||||
*/
|
||||
|
||||
package org.eclipse.cdt.internal.core.dom.parser.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.ICPPConstructor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
||||
import org.eclipse.cdt.core.parser.util.ObjectMap;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
*
|
||||
*/
|
||||
public class CPPConstructorSpecialization extends CPPMethodSpecialization
|
||||
implements ICPPConstructor {
|
||||
|
||||
/**
|
||||
* @param orig
|
||||
* @param scope
|
||||
* @param argMap
|
||||
*/
|
||||
public CPPConstructorSpecialization(IBinding orig, ICPPScope scope, ObjectMap argMap) {
|
||||
super(orig, scope, argMap);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor#isExplicit()
|
||||
*/
|
||||
public boolean isExplicit() throws DOMException {
|
||||
return ((ICPPConstructor)getSpecializedBinding()).isExplicit();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*************************************************************************
|
||||
* 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 June 14, 2005
|
||||
*/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.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.ICPPConstructor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
||||
import org.eclipse.cdt.core.parser.util.ObjectMap;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
*
|
||||
*/
|
||||
public class CPPConstructorTemplateSpecialization extends
|
||||
CPPMethodTemplateSpecialization implements ICPPConstructor {
|
||||
|
||||
/**
|
||||
* @param specialized
|
||||
* @param scope
|
||||
* @param argumentMap
|
||||
*/
|
||||
public CPPConstructorTemplateSpecialization(IBinding specialized,
|
||||
ICPPScope scope, ObjectMap argumentMap) {
|
||||
super(specialized, scope, argumentMap);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor#isExplicit()
|
||||
*/
|
||||
public boolean isExplicit() throws DOMException {
|
||||
return ((ICPPConstructor)getSpecializedBinding()).isExplicit();
|
||||
}
|
||||
|
||||
}
|
|
@ -141,11 +141,15 @@ abstract public class CPPScope implements ICPPScope{
|
|||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#removeBinding(org.eclipse.cdt.core.dom.ast.IBinding)
|
||||
*/
|
||||
public void removeBinding(IBinding binding) {
|
||||
char [] name = binding.getNameCharArray();
|
||||
if( ! bindings.containsKey( name ) )
|
||||
char [] key = binding.getNameCharArray();
|
||||
removeBinding( key, binding );
|
||||
}
|
||||
|
||||
protected void removeBinding( char [] key, IBinding binding ){
|
||||
if( bindings == null || ! bindings.containsKey( key ) )
|
||||
return;
|
||||
|
||||
Object obj = bindings.get( name );
|
||||
Object obj = bindings.get( key );
|
||||
if( obj instanceof ObjectSet ){
|
||||
ObjectSet set = (ObjectSet) obj;
|
||||
for ( int i = set.size() - 1; i > 0; i-- ) {
|
||||
|
@ -157,13 +161,12 @@ abstract public class CPPScope implements ICPPScope{
|
|||
}
|
||||
}
|
||||
if( set.size() == 0 )
|
||||
bindings.remove( name, 0, name.length );
|
||||
bindings.remove( key, 0, key.length );
|
||||
} else if( (obj instanceof IBinding && obj == binding) ||
|
||||
(obj instanceof IASTName && ((IASTName)obj).getBinding() == binding) )
|
||||
{
|
||||
bindings.remove( name, 0, name.length );
|
||||
bindings.remove( key, 0, key.length );
|
||||
}
|
||||
|
||||
isfull = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -259,13 +259,17 @@ public class CPPSemantics {
|
|||
return true;
|
||||
if( p1 instanceof ICPPASTNamedTypeSpecifier && p2 instanceof IASTTypeId )
|
||||
return p2.getParent() instanceof ICPPASTNewExpression;
|
||||
else if( p1 instanceof ICPPASTQualifiedName && p2 instanceof ICPPASTFunctionDeclarator ){
|
||||
IASTName[] names = ((ICPPASTQualifiedName)p1).getNames();
|
||||
if( names.length >= 2 && names[ names.length - 1 ] == astName )
|
||||
return CPPVisitor.isConstructor( names[ names.length - 2 ], (IASTDeclarator) p2 );
|
||||
} else if( p1 instanceof ICPPASTQualifiedName && p2 instanceof ICPPASTNamedTypeSpecifier ){
|
||||
IASTNode p3 = p2.getParent();
|
||||
return p3 instanceof IASTTypeId && p3.getParent() instanceof ICPPASTNewExpression;
|
||||
else if( p1 instanceof ICPPASTQualifiedName ){
|
||||
if( p2 instanceof ICPPASTFunctionDeclarator ){
|
||||
IASTName[] names = ((ICPPASTQualifiedName)p1).getNames();
|
||||
if( names.length >= 2 && names[ names.length - 1 ] == astName )
|
||||
return CPPVisitor.isConstructor( names[ names.length - 2 ], (IASTDeclarator) p2 );
|
||||
} else if( p2 instanceof ICPPASTNamedTypeSpecifier ){
|
||||
IASTNode p3 = p2.getParent();
|
||||
return p3 instanceof IASTTypeId && p3.getParent() instanceof ICPPASTNewExpression;
|
||||
} else if( p2 instanceof IASTIdExpression ){
|
||||
return p2.getParent() instanceof IASTFunctionCallExpression;
|
||||
}
|
||||
} else if( p1 instanceof IASTFunctionCallExpression || p2 instanceof IASTFunctionCallExpression )
|
||||
return true;
|
||||
return false;
|
||||
|
@ -585,17 +589,24 @@ public class CPPSemantics {
|
|||
}
|
||||
}
|
||||
if( binding instanceof ICPPClassType && data.considerConstructors ){
|
||||
ICPPClassType cls = (ICPPClassType) binding;
|
||||
try {
|
||||
//force resolution of constructor bindings
|
||||
IBinding [] ctors = cls.getConstructors();
|
||||
if( ctors.length > 0 && !(ctors[0] instanceof IProblemBinding) ){
|
||||
//then use the class scope to resolve which one.
|
||||
binding = ((ICPPClassScope)cls.getCompositeScope()).getBinding( data.astName, true );
|
||||
}
|
||||
} catch ( DOMException e ) {
|
||||
binding = e.getProblem();
|
||||
}
|
||||
ICPPClassType cls = (ICPPClassType) binding;
|
||||
if( data.astName instanceof ICPPASTTemplateId && cls instanceof ICPPInternalTemplate ){
|
||||
ICPPASTTemplateId id = (ICPPASTTemplateId) data.astName;
|
||||
IType [] args = CPPTemplates.createTypeArray( id.getTemplateArguments() );
|
||||
cls = (ICPPClassType) ((ICPPInternalTemplate)cls).instantiate( args );
|
||||
}
|
||||
if( cls != null ){
|
||||
try {
|
||||
//force resolution of constructor bindings
|
||||
IBinding [] ctors = cls.getConstructors();
|
||||
if( ctors.length > 0 && !(ctors[0] instanceof IProblemBinding) ){
|
||||
//then use the class scope to resolve which one.
|
||||
binding = ((ICPPClassScope)cls.getCompositeScope()).getBinding( data.astName, true );
|
||||
}
|
||||
} catch ( DOMException e ) {
|
||||
binding = e.getProblem();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
IASTName name = data.astName;
|
||||
|
@ -2837,7 +2848,7 @@ public class CPPSemantics {
|
|||
//4.10-3 An rvalue of type "pointer to cv D", where D is a class type can be converted
|
||||
//to an rvalue of type "pointer to cv B", where B is a base class of D.
|
||||
else if( tPrev instanceof IPointerType && t instanceof ICPPClassType ){
|
||||
temp = hasBaseClass( (ICPPClassType)s, (ICPPClassType) t, true );
|
||||
temp = hasBaseClass( (ICPPClassType)s, (ICPPClassType) t, false );
|
||||
cost.rank = ( temp > -1 ) ? Cost.CONVERSION_RANK : Cost.NO_MATCH_RANK;
|
||||
cost.conversion = ( temp > -1 ) ? temp : 0;
|
||||
cost.detail = 1;
|
||||
|
@ -2872,7 +2883,7 @@ public class CPPSemantics {
|
|||
IType t = getUltimateType( cost.target, true );
|
||||
|
||||
if( cost.targetHadReference && s instanceof ICPPClassType && t instanceof ICPPClassType ){
|
||||
int temp = hasBaseClass( (ICPPClassType) s, (ICPPClassType) t, true );
|
||||
int temp = hasBaseClass( (ICPPClassType) s, (ICPPClassType) t, false );
|
||||
|
||||
if( temp > -1 ){
|
||||
cost.rank = Cost.DERIVED_TO_BASE_CONVERSION;
|
||||
|
|
|
@ -261,6 +261,8 @@ public abstract class CPPTemplateDefinition implements ICPPTemplateDefinition, I
|
|||
public ICPPTemplateParameter[] getTemplateParameters() {
|
||||
if( templateParameters == null ){
|
||||
ICPPASTTemplateDeclaration template = CPPTemplates.getTemplateDeclaration( getTemplateName() );
|
||||
if( template == null )
|
||||
return ICPPTemplateParameter.EMPTY_TEMPLATE_PARAMETER_ARRAY;
|
||||
ICPPASTTemplateParameter [] params = template.getTemplateParameters();
|
||||
ICPPTemplateParameter p = null;
|
||||
ICPPTemplateParameter [] result = null;
|
||||
|
|
|
@ -56,6 +56,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
|
||||
|
@ -390,7 +391,9 @@ public class CPPTemplates {
|
|||
} else {
|
||||
spec = ((ICPPInternalTemplate)function).getInstance( (IType[])map_types[1] );
|
||||
if( spec == null ) {
|
||||
if( function instanceof ICPPMethod )
|
||||
if( function instanceof ICPPConstructor )
|
||||
spec = new CPPConstructorSpecialization( function, scope, (ObjectMap) map_types[0] );
|
||||
else if( function instanceof ICPPMethod )
|
||||
spec = new CPPMethodSpecialization( function, scope, (ObjectMap) map_types[0] );
|
||||
else
|
||||
spec = new CPPFunctionSpecialization( function, scope, (ObjectMap) map_types[0] );
|
||||
|
@ -574,11 +577,16 @@ public class CPPTemplates {
|
|||
spec = new CPPClassSpecialization( decl, scope, argMap );
|
||||
} else if( decl instanceof ICPPField ){
|
||||
spec = new CPPFieldSpecialization( decl, scope, argMap );
|
||||
} else if( decl instanceof ICPPFunctionTemplate && decl instanceof ICPPMethod ){
|
||||
spec = new CPPMethodTemplateSpecialization( decl, scope, argMap );
|
||||
} else if( decl instanceof ICPPFunctionTemplate ){
|
||||
spec = new CPPFunctionTemplateSpecialization( decl, scope, argMap );
|
||||
}else if( decl instanceof ICPPMethod ) {
|
||||
if( decl instanceof ICPPConstructor )
|
||||
spec = new CPPConstructorTemplateSpecialization( decl, scope, argMap );
|
||||
else if( decl instanceof ICPPMethod )
|
||||
spec = new CPPMethodTemplateSpecialization( decl, scope, argMap );
|
||||
else
|
||||
spec = new CPPFunctionTemplateSpecialization( decl, scope, argMap );
|
||||
} else if( decl instanceof ICPPConstructor ){
|
||||
spec = new CPPConstructorSpecialization( decl, scope, argMap );
|
||||
} else if( decl instanceof ICPPMethod ) {
|
||||
spec = new CPPMethodSpecialization( decl, scope, argMap );
|
||||
} else if( decl instanceof ICPPFunction ) {
|
||||
spec = new CPPFunctionSpecialization( decl, scope, argMap );
|
||||
|
|
|
@ -1685,7 +1685,15 @@ public class CPPVisitor {
|
|||
|
||||
} else if( expression instanceof IASTFunctionCallExpression ){
|
||||
IBinding binding = resolveBinding( expression );
|
||||
if( binding instanceof IFunction ){
|
||||
if( binding instanceof ICPPConstructor ){
|
||||
ICPPClassScope scope;
|
||||
try {
|
||||
scope = (ICPPClassScope) ((ICPPConstructor)binding).getScope();
|
||||
} catch (DOMException e) {
|
||||
return e.getProblem();
|
||||
}
|
||||
return scope.getClassType();
|
||||
} else if( binding instanceof IFunction ){
|
||||
IFunctionType fType;
|
||||
try {
|
||||
fType = ((IFunction)binding).getType();
|
||||
|
@ -1842,6 +1850,8 @@ public class CPPVisitor {
|
|||
} else if( expression instanceof IASTArraySubscriptExpression ){
|
||||
IType t = getExpressionType( ((IASTArraySubscriptExpression) expression).getArrayExpression() );
|
||||
try {
|
||||
if( t instanceof ICPPReferenceType )
|
||||
t = ((ICPPReferenceType)t).getType();
|
||||
while( t instanceof ITypedef ){
|
||||
t = ((ITypedef)t).getType();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue