1
0
Fork 0
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:
Andrew Niefer 2005-06-15 22:29:38 +00:00
parent 3eb94cf34a
commit 71ecce9bed
14 changed files with 399 additions and 83 deletions

View file

@ -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() );
}
}

View file

@ -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)

View file

@ -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)

View file

@ -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 ){

View file

@ -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();
}
}

View file

@ -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)

View file

@ -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() );
}
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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 );

View file

@ -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();
}