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

Bug 162230 - Fix a stack overflow that was happening with function template specializations.

This commit is contained in:
Doug Schaefer 2006-11-16 21:35:51 +00:00
parent 494ab7d964
commit 58a835d441
3 changed files with 65 additions and 8 deletions

View file

@ -44,6 +44,7 @@ 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;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
@ -1942,4 +1943,47 @@ public class AST2TemplateTests extends AST2BaseTest {
ICPPVariable c = (ICPPVariable) col.getName(13).resolveBinding();
assertSame( c, col.getName(4).resolveBinding() );
}
public void testBug162230() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("template< class T > class C { \n"); //$NON-NLS-1$
buffer.append(" public: void * blah; \n"); //$NON-NLS-1$
buffer.append(" template<typename G> C(G* g) : blah(g) {} \n"); //$NON-NLS-1$
buffer.append(" template <> C(char * c) : blah(c) {} \n"); //$NON-NLS-1$
buffer.append(" template <> C(wchar_t * c) : blah(c) {} \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 );
ICPPTemplateParameter T = (ICPPTemplateParameter) col.getName(0).resolveBinding();
ICPPClassTemplate C = (ICPPClassTemplate) col.getName(1).resolveBinding();
ICPPField blah = (ICPPField) col.getName(2).resolveBinding();
ICPPTemplateTypeParameter G = (ICPPTemplateTypeParameter) col.getName(3).resolveBinding();
ICPPFunctionTemplate ctor = (ICPPFunctionTemplate) col.getName(4).resolveBinding();
assertSame(G, col.getName(5).resolveBinding());
ICPPParameter g = (ICPPParameter) col.getName(6).resolveBinding();
assertSame(blah, col.getName(7).resolveBinding());
assertSame(g, col.getName(8).resolveBinding());
ICPPSpecialization spec = (ICPPSpecialization) col.getName(9).resolveBinding();
assertSame(spec.getSpecializedBinding(), ctor);
ICPPSpecialization c = (ICPPSpecialization) col.getName(10).resolveBinding();
assertSame(c.getSpecializedBinding(), g);
assertSame(blah, col.getName(11).resolveBinding());
assertSame(c, col.getName(12).resolveBinding());
ICPPSpecialization spec2 = (ICPPSpecialization) col.getName(13).resolveBinding();
assertSame(spec.getSpecializedBinding(), ctor);
ICPPSpecialization c2 = (ICPPSpecialization) col.getName(14).resolveBinding();
assertSame(c2.getSpecializedBinding(), g);
assertSame(blah, col.getName(15).resolveBinding());
assertSame(c2, col.getName(16).resolveBinding());
}
}

View file

@ -96,7 +96,7 @@ public class CPPClassInstanceScope implements ICPPClassScope, IASTInternalScope
if( instanceMap.containsKey( n ) ){
binding = (IBinding) instanceMap.get( n );
} else {
binding = forceResolve ? n.resolveBinding() : n.getBinding();
binding = CPPClassScope.shouldResolve(forceResolve, n, name) ? n.resolveBinding() : n.getBinding();
if (binding instanceof ICPPClassTemplatePartialSpecialization ){
binding = null;
}

View file

@ -232,7 +232,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
}
if( CharArrayUtils.equals( c, compName.toCharArray() ) ){
if( isConstructorReference( name ) ){
return CPPSemantics.resolveAmbiguities( name, getConstructors( bindings, resolve ) );
return CPPSemantics.resolveAmbiguities( name, getConstructors( bindings, resolve, name ) );
}
//9.2 ... The class-name is also inserted into the scope of the class itself
return compName.resolveBinding();
@ -240,10 +240,23 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
return super.getBinding( name, resolve );
}
static protected boolean shouldResolve(boolean force, IASTName candidate, IASTName forName) {
if(!force || candidate == forName)
return false;
if(forName == null)
return true;
if(!forName.isReference() && !CPPSemantics.declaredBefore(candidate, forName))
return false;
return true;
}
protected ICPPConstructor [] getConstructors( boolean forceResolve ){
return getConstructors( bindings, forceResolve );
return getConstructors( bindings, forceResolve, null );
}
static protected ICPPConstructor [] getConstructors( CharArrayObjectMap bindings, boolean forceResolve ) {
return getConstructors(bindings, forceResolve, null);
}
static protected ICPPConstructor [] getConstructors( CharArrayObjectMap bindings, boolean forceResolve, IASTName forName ){
if( bindings == null )
return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY;
@ -257,7 +270,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
Object obj = set.keyAt( i );
if( obj instanceof IASTName ){
IASTName n = (IASTName) obj;
binding = forceResolve ? n.resolveBinding() : n.getBinding();
binding = shouldResolve(forceResolve, n, forName) ? n.resolveBinding() : n.getBinding();
if( binding != null ) {
set.remove( n );
set.put( binding );
@ -269,7 +282,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
}
return (ICPPConstructor[]) ArrayUtil.trim( ICPPConstructor.class, bs );
} else if( o instanceof IASTName ){
if( forceResolve || ((IASTName)o).getBinding() != null ){
if( shouldResolve(forceResolve, (IASTName) o, forName) || ((IASTName)o).getBinding() != null ){
binding = ((IASTName)o).resolveBinding();
bindings.put( CONSTRUCTOR_KEY, binding );
}