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

- consider template parameter default values

- partially fixes 76951, fixes 90670
This commit is contained in:
Andrew Niefer 2005-04-22 20:32:54 +00:00
parent 8230e97539
commit 5b282cb2f4
9 changed files with 174 additions and 80 deletions

View file

@ -661,23 +661,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
}
}
/**
[--Start Example(CPP 14.1-13):
template<class T, T* p, class U = T> class X { };
template<class T> void f(T* p = new T);
--End Example]
*/
public void test14_1s13() { // TODO raised bug 60670
StringBuffer buffer = new StringBuffer();
buffer.append("template<class T, T* p, class U = T> class X { };\n"); //$NON-NLS-1$
buffer.append("template<class T> void f(T* p = new T);\n"); //$NON-NLS-1$
try {
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
assertTrue(false);
} catch (Exception e) {
}
}
/**
[--Start Example(CPP 14.3-2):
template<class T> void f();
@ -931,23 +914,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
}
}
/**
[--Start Example(CPP 14.6.1-3a):
template<class T, T* p, class U = T> class X { };
template<class T> void f(T* p = new T);
--End Example]
*/
public void test14_6_1s3a() { // TODO already have bug on this one
StringBuffer buffer = new StringBuffer();
buffer.append("template<class T, T* p, class U = T> class X { };\n"); //$NON-NLS-1$
buffer.append("template<class T> void f(T* p = new T);\n"); //$NON-NLS-1$
try {
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
assertTrue(false);
} catch (Exception e) {
}
}
/**
[--Start Example(CPP 14.6.1-6):
namespace N {
@ -1005,43 +971,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
} catch (Exception e) {
}
}
/**
[--Start Example(CPP 14.7-3):
template<class T = int> struct A {
static int x;
};
template<class U> void g(U) { }
template<> struct A<double> { }; // specialize for T == double
template<> struct A<> { }; // specialize for T == int
template<> void g(char) { } // specialize for U == char
// U is deduced from the parameter type
template<> void g<int>(int) { } // specialize for U == int
template<> int A<char>::x = 0; // specialize for T == char
template<class T = int> struct B {
static int x;
};
template<> int B<>::x = 1; // specialize for T == int
--End Example]
*/
public void test14_7s3() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("template<class T = int> struct A {\n"); //$NON-NLS-1$
buffer.append("static int x;\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
buffer.append("template<class U> void g(U) { }\n"); //$NON-NLS-1$
buffer.append("template<> struct A<double> { }; // specialize for T == double\n"); //$NON-NLS-1$
buffer.append("template<> struct A<> { }; // specialize for T == int\n"); //$NON-NLS-1$
buffer.append("template<> void g(char) { } // specialize for U == char\n"); //$NON-NLS-1$
buffer.append("// U is deduced from the parameter type\n"); //$NON-NLS-1$
buffer.append("template<> void g<int>(int) { } // specialize for U == int\n"); //$NON-NLS-1$
buffer.append("template<> int A<char>::x = 0; // specialize for T == char\n"); //$NON-NLS-1$
buffer.append("template<class T = int> struct B {\n"); //$NON-NLS-1$
buffer.append("static int x;\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
buffer.append("template<> int B<>::x = 1; // specialize for T == int\n"); //$NON-NLS-1$
parse(buffer.toString(), ParserLanguage.CPP, true, 2);
}
/**
[--Start Example(CPP 14.7.1-5):

View file

@ -8480,6 +8480,20 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
}
/**
[--Start Example(CPP 14.1-13):
template<class T, T* p, class U = T> class X { };
template<class T> void f(T* p = new T);
--End Example]
*/
public void test14_1s13() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("template<class T, T* p, class U = T> class X { };\n"); //$NON-NLS-1$
buffer.append("template<class T> void f(T* p = new T);\n"); //$NON-NLS-1$
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
}
/**
[--Start Example(CPP 14.1-15):
template<int i = (3 > 4) > // OK
@ -9597,7 +9611,20 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
parse(buffer.toString(), ParserLanguage.CPP, false, 0);
}
/**
[--Start Example(CPP 14.6.1-3a):
template<class T, T* p, class U = T> class X { };
template<class T> void f(T* p = new T);
--End Example]
*/
public void test14_6_1s3a() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("template<class T, T* p, class U = T> class X { };\n"); //$NON-NLS-1$
buffer.append("template<class T> void f(T* p = new T);\n"); //$NON-NLS-1$
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
}
/**
[--Start Example(CPP 14.6.1-1):
template<class T> class X {
@ -9966,6 +9993,44 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
}
/**
[--Start Example(CPP 14.7-3):
template<class T = int> struct A {
static int x;
};
template<class U> void g(U) { }
template<> struct A<double> { }; // specialize for T == double
template<> struct A<> { }; // specialize for T == int
template<> void g(char) { } // specialize for U == char
// U is deduced from the parameter type
template<> void g<int>(int) { } // specialize for U == int
template<> int A<char>::x = 0; // specialize for T == char
template<class T = int> struct B {
static int x;
};
template<> int B<>::x = 1; // specialize for T == int
--End Example]
*/
public void test14_7s3() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("template<class T = int> struct A {\n"); //$NON-NLS-1$
buffer.append("static int x;\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
buffer.append("template<class U> void g(U) { }\n"); //$NON-NLS-1$
buffer.append("template<> struct A<double> { }; // specialize for T == double\n"); //$NON-NLS-1$
buffer.append("template<> struct A<> { }; // specialize for T == int\n"); //$NON-NLS-1$
buffer.append("template<> void g(char) { } // specialize for U == char\n"); //$NON-NLS-1$
buffer.append("// U is deduced from the parameter type\n"); //$NON-NLS-1$
buffer.append("template<> void g<int>(int) { } // specialize for U == int\n"); //$NON-NLS-1$
buffer.append("template<> int A<char>::x = 0; // specialize for T == char\n"); //$NON-NLS-1$
buffer.append("template<class T = int> struct B {\n"); //$NON-NLS-1$
buffer.append("static int x;\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
buffer.append("template<> int B<>::x = 1; // specialize for T == int\n"); //$NON-NLS-1$
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
}
/**
[--Start Example(CPP 14.7.1-10):
namespace N {

View file

@ -778,4 +778,64 @@ public class AST2TemplateTests extends AST2BaseTest {
assertSame( ((ICPPTemplateInstance)f2).getOriginalBinding(), f1 );
assertSame( g1, g2 );
}
public void testBug76951_1() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("template <class T, class U = T > U f( T ); \n"); //$NON-NLS-1$
buffer.append("void g() { \n"); //$NON-NLS-1$
buffer.append(" f( 1 ); \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
CPPNameCollector col = new CPPNameCollector();
tu.accept( col );
ICPPTemplateParameter T = (ICPPTemplateParameter) col.getName(0).resolveBinding();
ICPPTemplateParameter T2 = (ICPPTemplateParameter) col.getName(2).resolveBinding();
assertSame( T, T2 );
ICPPFunctionTemplate f1 = (ICPPFunctionTemplate) col.getName(4).resolveBinding();
ICPPFunction f2 = (ICPPFunction) col.getName(8).resolveBinding();
assertTrue( f2 instanceof ICPPTemplateInstance );
assertSame( ((ICPPTemplateInstance)f2).getOriginalBinding(), f1 );
IFunctionType ft = f2.getType();
assertTrue( ft.getReturnType() instanceof IBasicType );
assertEquals( ((IBasicType)ft.getReturnType()).getType(), IBasicType.t_int );
}
public void testBug76951_2() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("template <class T, class U = T > class A { \n"); //$NON-NLS-1$
buffer.append(" U u; \n"); //$NON-NLS-1$
buffer.append("}; \n"); //$NON-NLS-1$
buffer.append("void f() { \n"); //$NON-NLS-1$
buffer.append(" A<int> a; \n"); //$NON-NLS-1$
buffer.append(" a.u; \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
CPPNameCollector col = new CPPNameCollector();
tu.accept( col );
ICPPTemplateParameter T = (ICPPTemplateParameter) col.getName(0).resolveBinding();
ICPPTemplateTypeParameter U = (ICPPTemplateTypeParameter) col.getName(1).resolveBinding();
assertSame( U.getDefault(), T );
ICPPClassTemplate A = (ICPPClassTemplate) col.getName(3).resolveBinding();
ICPPField u1 = (ICPPField) col.getName(5).resolveBinding();
assertSame( u1.getType(), U );
ICPPClassType A1 = (ICPPClassType) col.getName(7).resolveBinding();
assertTrue( A1 instanceof ICPPTemplateInstance );
assertSame( ((ICPPTemplateInstance)A1).getOriginalBinding(), A );
ICPPField u2 = (ICPPField) col.getName(11).resolveBinding();
assertTrue( u2 instanceof ICPPTemplateInstance );
assertSame( ((ICPPTemplateInstance)u2).getOriginalBinding(), u1 );
IType type = u2.getType();
assertTrue( type instanceof IBasicType );
assertEquals( ((IBasicType)type).getType(), IBasicType.t_int );
}
}

View file

@ -77,8 +77,9 @@ public class CPPASTSimpleTypeTemplateParameter extends CPPASTNode implements
}
}
if( typeId != null ) if( !typeId.accept( action ) ) return false;
if( name != null ) if( !name.accept( action ) ) return false;
if( typeId != null ) if( !typeId.accept( action ) ) return false;
return true;
}

View file

@ -199,6 +199,8 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements
* @see org.eclipse.cdt.core.dom.ast.ICompositeType#getCompositeScope()
*/
public IScope getCompositeScope() {
if( definition == null )
checkForDefinition();
if( definition != null ){
ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) definition.getParent();
return compSpec.getScope();

View file

@ -138,7 +138,7 @@ public abstract class CPPTemplateDefinition implements ICPPTemplateDefinition, I
IType[] actualArgs = new IType[ numParams ];
for( int i = 0; i < numParams; i++ ){
arg = null;
param = parameters[i];
if( i < numArgs ){
@ -164,7 +164,9 @@ public abstract class CPPTemplateDefinition implements ICPPTemplateDefinition, I
if( map.containsKey( defaultType ) ){
arg = (IType) map.get( defaultType );
}
}
} else {
arg = defaultType;
}
} else {
//TODO problem
return null;

View file

@ -13,10 +13,12 @@
*/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
/**
@ -35,8 +37,15 @@ public class CPPTemplateTypeParameter extends CPPTemplateParameter implements
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter#getDefault()
*/
public IType getDefault() throws DOMException {
// TODO Auto-generated method stub
public IType getDefault() {
IASTNode [] nds = getDeclarations();
if( nds == null || nds.length == 0 )
return null;
IASTName name = (IASTName) nds[0];
ICPPASTSimpleTypeTemplateParameter simple = (ICPPASTSimpleTypeTemplateParameter) name.getParent();
IASTTypeId typeId = simple.getDefaultType();
if( typeId != null )
return CPPVisitor.createType( typeId );
return null;
}

View file

@ -703,9 +703,31 @@ public class CPPTemplates {
instanceArgs = (IType[]) ArrayUtil.append( IType.class, instanceArgs, arg );
else
continue outer;
else if( arg == null && mapped == null )
continue outer;
else
else if( arg == null && mapped == null ) {
IType def = null;
try {
if( templateParams[i] instanceof ICPPTemplateTypeParameter ){
def = ((ICPPTemplateTypeParameter)templateParams[i]).getDefault();
} else if( templateParams[i] instanceof ICPPTemplateTemplateParameter ){
def = ((ICPPTemplateTemplateParameter)templateParams[i]).getDefault();
} else if( templateParams[i] instanceof ICPPTemplateNonTypeParameter ){
def = CPPVisitor.getExpressionType( ((ICPPTemplateNonTypeParameter)templateParams[i]).getDefault() );
}
} catch ( DOMException e ) {
continue outer;
}
if( def != null ){
if( def instanceof ICPPTemplateParameter ){
for ( int j = 0; j < i; j++ ) {
if( templateParams[j] == def ) {
def = instanceArgs[j];
}
}
}
instanceArgs = (IType[]) ArrayUtil.append( IType.class, instanceArgs, def );
} else
continue outer;
} else
instanceArgs = (IType[]) ArrayUtil.append( IType.class, instanceArgs, (arg != null) ? arg : mapped );
}
instanceArgs = (IType[]) ArrayUtil.trim( IType.class, instanceArgs );

View file

@ -638,6 +638,8 @@ public class CPPVisitor {
return getContainingScope( (IASTStatement) node );
} else if( node instanceof IASTTypeId ){
node = node.getParent();
if( node instanceof ICPPASTTemplateParameter )
return CPPTemplates.getContainingScope( node );
} else if( node instanceof IASTParameterDeclaration ){
IASTNode parent = node.getParent();
if( parent instanceof ICPPASTFunctionDeclarator ){
@ -1366,6 +1368,8 @@ public class CPPVisitor {
}
public static IType createType( IASTNode node ){
if( node == null )
return null;
if( node instanceof IASTExpression )
return getExpressionType( (IASTExpression) node );
if( node instanceof IASTTypeId )