mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 10:16:03 +02:00
Fix template scoping
- helps with nested templates & template specializations - fxes bug 90686
This commit is contained in:
parent
ecd91d8fe3
commit
ce4decd0a0
11 changed files with 563 additions and 155 deletions
|
@ -560,37 +560,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
[--Start Example(CPP 14.6.1-6):
|
||||
namespace N {
|
||||
class C { };
|
||||
template<class T> class B {
|
||||
void f(T);
|
||||
};
|
||||
}
|
||||
template<class C> void N::B<C>::f(C) {
|
||||
C b; // C is the template parameter, not N::C
|
||||
}
|
||||
--End Example]
|
||||
*/
|
||||
public void test14_6_1s6() { // TODO raised bug 90686
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("namespace N {\n"); //$NON-NLS-1$
|
||||
buffer.append("int C;\n"); //$NON-NLS-1$
|
||||
buffer.append("template<class T> class B {\n"); //$NON-NLS-1$
|
||||
buffer.append("void f(T);\n"); //$NON-NLS-1$
|
||||
buffer.append("};\n"); //$NON-NLS-1$
|
||||
buffer.append("}\n"); //$NON-NLS-1$
|
||||
buffer.append("template<class C> void N::B<C>::f(C) {\n"); //$NON-NLS-1$
|
||||
buffer.append("C b; // C is the template parameter, not N::C\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.6.2-3):
|
||||
typedef double A;
|
||||
|
@ -709,55 +678,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
|
|||
parse(buffer.toString(), ParserLanguage.CPP, true, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
[--Start Example(CPP 14.7.3-16):
|
||||
template<class T> struct A {
|
||||
void f(T);
|
||||
template<class X> void g(T,X);
|
||||
void h(T) { }
|
||||
};
|
||||
// specialization
|
||||
template<> void A<int>::f(int);
|
||||
// out of class member template definition
|
||||
template<class T> template<class X> void A<T>::g(T,X) { }
|
||||
// member template partial specialization
|
||||
template<> template<class X> void A<int>::g(int,X);
|
||||
// member template specialization
|
||||
template<> template<>
|
||||
void A<int>::g(int,char); // X deduced as char
|
||||
template<> template<>
|
||||
void A<int>::g<char>(int,char); // X specified as char
|
||||
// member specialization even if defined in class definition
|
||||
template<> void A<int>::h(int) { }
|
||||
--End Example]
|
||||
*/
|
||||
public void test14_7_3s16() { // TODO similar bug already
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("template<class T> struct A {\n"); //$NON-NLS-1$
|
||||
buffer.append("void f(T);\n"); //$NON-NLS-1$
|
||||
buffer.append("template<class X> void g(T,X);\n"); //$NON-NLS-1$
|
||||
buffer.append("void h(T) { }\n"); //$NON-NLS-1$
|
||||
buffer.append("};\n"); //$NON-NLS-1$
|
||||
buffer.append("// specialization\n"); //$NON-NLS-1$
|
||||
buffer.append("template<> void A<int>::f(int);\n"); //$NON-NLS-1$
|
||||
buffer.append("// out of class member template definition\n"); //$NON-NLS-1$
|
||||
buffer.append("template<class T> template<class X> void A<T>::g(T,X) { }\n"); //$NON-NLS-1$
|
||||
buffer.append("// member template partial specialization\n"); //$NON-NLS-1$
|
||||
buffer.append("template<> template<class X> void A<int>::g(int,X);\n"); //$NON-NLS-1$
|
||||
buffer.append("// member template specialization\n"); //$NON-NLS-1$
|
||||
buffer.append("template<> template<>\n"); //$NON-NLS-1$
|
||||
buffer.append("void A<int>::g(int,char); // X deduced as char\n"); //$NON-NLS-1$
|
||||
buffer.append("template<> template<>\n"); //$NON-NLS-1$
|
||||
buffer.append("void A<int>::g<char>(int,char); // X specified as char\n"); //$NON-NLS-1$
|
||||
buffer.append("// member specialization even if defined in class definition\n"); //$NON-NLS-1$
|
||||
buffer.append("template<> void A<int>::h(int) { }\n"); //$NON-NLS-1$
|
||||
try {
|
||||
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
|
||||
assertTrue(false);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
[--Start Example(CPP 14.8.2-2b):
|
||||
template <class T> int f(typename T::B*);
|
||||
|
|
|
@ -9767,6 +9767,34 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
[--Start Example(CPP 14.6.1-6):
|
||||
namespace N {
|
||||
class C { };
|
||||
template<class T> class B {
|
||||
void f(T);
|
||||
};
|
||||
}
|
||||
template<class C> void N::B<C>::f(C) {
|
||||
C b; // C is the template parameter, not N::C
|
||||
}
|
||||
--End Example]
|
||||
*/
|
||||
public void test14_6_1s6() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("namespace N {\n"); //$NON-NLS-1$
|
||||
buffer.append("int C;\n"); //$NON-NLS-1$
|
||||
buffer.append("template<class T> class B {\n"); //$NON-NLS-1$
|
||||
buffer.append("void f(T);\n"); //$NON-NLS-1$
|
||||
buffer.append("};\n"); //$NON-NLS-1$
|
||||
buffer.append("}\n"); //$NON-NLS-1$
|
||||
buffer.append("template<class C> void N::B<C>::f(C) {\n"); //$NON-NLS-1$
|
||||
buffer.append("C b; // C is the template parameter, not N::C\n"); //$NON-NLS-1$
|
||||
buffer.append("}\n"); //$NON-NLS-1$
|
||||
|
||||
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
[--Start Example(CPP 14.6.1-7):
|
||||
struct A {
|
||||
|
@ -10427,6 +10455,51 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
[--Start Example(CPP 14.7.3-16):
|
||||
template<class T> struct A {
|
||||
void f(T);
|
||||
template<class X> void g(T,X);
|
||||
void h(T) { }
|
||||
};
|
||||
// specialization
|
||||
template<> void A<int>::f(int);
|
||||
// out of class member template definition
|
||||
template<class T> template<class X> void A<T>::g(T,X) { }
|
||||
// member template partial specialization
|
||||
template<> template<class X> void A<int>::g(int,X);
|
||||
// member template specialization
|
||||
template<> template<>
|
||||
void A<int>::g(int,char); // X deduced as char
|
||||
template<> template<>
|
||||
void A<int>::g<char>(int,char); // X specified as char
|
||||
// member specialization even if defined in class definition
|
||||
template<> void A<int>::h(int) { }
|
||||
--End Example]
|
||||
*/
|
||||
public void test14_7_3s16() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("template<class T> struct A {\n"); //$NON-NLS-1$
|
||||
buffer.append("void f(T);\n"); //$NON-NLS-1$
|
||||
buffer.append("template<class X> void g(T,X);\n"); //$NON-NLS-1$
|
||||
buffer.append("void h(T) { }\n"); //$NON-NLS-1$
|
||||
buffer.append("};\n"); //$NON-NLS-1$
|
||||
buffer.append("// specialization\n"); //$NON-NLS-1$
|
||||
buffer.append("template<> void A<int>::f(int);\n"); //$NON-NLS-1$
|
||||
buffer.append("// out of class member template definition\n"); //$NON-NLS-1$
|
||||
buffer.append("template<class T> template<class X> void A<T>::g(T,X) { }\n"); //$NON-NLS-1$
|
||||
buffer.append("// member template partial specialization\n"); //$NON-NLS-1$
|
||||
buffer.append("template<> template<class X> void A<int>::g(int,X);\n"); //$NON-NLS-1$
|
||||
buffer.append("// member template specialization\n"); //$NON-NLS-1$
|
||||
buffer.append("template<> template<>\n"); //$NON-NLS-1$
|
||||
buffer.append("void A<int>::g(int,char); // X deduced as char\n"); //$NON-NLS-1$
|
||||
buffer.append("template<> template<>\n"); //$NON-NLS-1$
|
||||
buffer.append("void A<int>::g<char>(int,char); // X specified as char\n"); //$NON-NLS-1$
|
||||
buffer.append("// member specialization even if defined in class definition\n"); //$NON-NLS-1$
|
||||
buffer.append("template<> void A<int>::h(int) { }\n"); //$NON-NLS-1$
|
||||
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
[--Start Example(CPP 14.7.3-18):
|
||||
template<class T1> class A {
|
||||
|
|
|
@ -1174,6 +1174,79 @@ public class AST2TemplateTests extends AST2BaseTest {
|
|||
assertTrue( x4 instanceof ICPPSpecialization );
|
||||
assertEquals( ((ICPPSpecialization)x4).getSpecializedBinding(), x2 );
|
||||
}
|
||||
public void _testNestedTypeSpecializations() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("template <class T> class A { \n"); //$NON-NLS-1$
|
||||
buffer.append(" typedef T _T; \n"); //$NON-NLS-1$
|
||||
buffer.append(" _T t; \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.t; \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();
|
||||
ITypedef _T = (ITypedef) col.getName(3).resolveBinding();
|
||||
assertSame( _T.getType(), T );
|
||||
|
||||
ICPPField t = (ICPPField) col.getName(5).resolveBinding();
|
||||
assertSame( t.getType(), _T );
|
||||
|
||||
ICPPField t2 = (ICPPField) col.getName(11).resolveBinding();
|
||||
assertTrue( t2 instanceof ICPPSpecialization );
|
||||
assertSame( ((ICPPSpecialization)t2).getSpecializedBinding(), t );
|
||||
|
||||
IType type = t2.getType();
|
||||
assertTrue( type instanceof ITypedef );
|
||||
assertTrue( type instanceof ICPPSpecialization );
|
||||
assertSame( ((ICPPSpecialization)type).getSpecializedBinding(), _T );
|
||||
|
||||
type = ((ITypedef)type).getType();
|
||||
assertTrue( type instanceof IBasicType );
|
||||
assertEquals( ((IBasicType)type).getType(), IBasicType.t_int );
|
||||
}
|
||||
|
||||
public void _testNestedClassTypeSpecializations() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("template <class T> class A { \n"); //$NON-NLS-1$
|
||||
buffer.append(" class B { T t; }; \n"); //$NON-NLS-1$
|
||||
buffer.append(" B b; \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.b.t; \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();
|
||||
ICPPClassType B = (ICPPClassType) col.getName(2).resolveBinding();
|
||||
ICPPField t = (ICPPField) col.getName(4).resolveBinding();
|
||||
assertSame( t.getType(), T );
|
||||
ICPPField b = (ICPPField) col.getName(6).resolveBinding();
|
||||
assertSame( b.getType(), B );
|
||||
|
||||
ICPPField b2 = (ICPPField) col.getName(12).resolveBinding();
|
||||
ICPPField t2 = (ICPPField) col.getName(13).resolveBinding();
|
||||
|
||||
assertTrue( b2 instanceof ICPPSpecialization );
|
||||
assertSame( ((ICPPSpecialization)b2).getSpecializedBinding(), b );
|
||||
|
||||
IType type = b2.getType();
|
||||
assertTrue( type instanceof ICPPSpecialization );
|
||||
assertSame( ((ICPPSpecialization)type).getSpecializedBinding(), B );
|
||||
|
||||
assertTrue( t2 instanceof ICPPSpecialization );
|
||||
assertSame( ((ICPPSpecialization)t2).getSpecializedBinding(), t );
|
||||
assertTrue( t2.getType() instanceof IBasicType );
|
||||
assertEquals( ((IBasicType)t2.getType()).getType(), IBasicType.t_int );
|
||||
}
|
||||
|
||||
public void testTemplateParameterQualifiedType_1() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
@ -1234,5 +1307,170 @@ public class AST2TemplateTests extends AST2BaseTest {
|
|||
assertSame( t, B );
|
||||
}
|
||||
|
||||
public void testTemplateScopes() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("template <class T> class A { \n"); //$NON-NLS-1$
|
||||
buffer.append(" A<T> a; \n"); //$NON-NLS-1$
|
||||
buffer.append(" void f(); \n"); //$NON-NLS-1$
|
||||
buffer.append("}; \n"); //$NON-NLS-1$
|
||||
buffer.append("template <class U> void A<U>::f(){ \n"); //$NON-NLS-1$
|
||||
buffer.append(" U 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();
|
||||
ICPPClassTemplate A = (ICPPClassTemplate) col.getName(1).resolveBinding();
|
||||
ICPPClassType A2 = (ICPPClassType) col.getName(2).resolveBinding();
|
||||
|
||||
ICPPTemplateParameter U = (ICPPTemplateParameter) col.getName(7).resolveBinding();
|
||||
assertSame( U, T );
|
||||
ICPPClassType A3 = (ICPPClassType) col.getName(9).resolveBinding();
|
||||
assertTrue( A3 instanceof ICPPTemplateInstance );
|
||||
assertSame( ((ICPPTemplateInstance) A3).getTemplateDefinition(), A );
|
||||
assertSame( A2, A3 );
|
||||
|
||||
|
||||
ICPPTemplateParameter U2 = (ICPPTemplateParameter) col.getName(13).resolveBinding();
|
||||
assertSame( U, U2 );
|
||||
assertSame( T, U );
|
||||
}
|
||||
|
||||
public void testTemplateScopes_2() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("class A { \n"); //$NON-NLS-1$
|
||||
buffer.append(" template < class T > void f(T); \n"); //$NON-NLS-1$
|
||||
buffer.append("}; \n"); //$NON-NLS-1$
|
||||
buffer.append("template <class U> void A::f<>(U){} \n"); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
tu.accept( col );
|
||||
|
||||
ICPPClassType A = (ICPPClassType) col.getName(0).resolveBinding();
|
||||
ICPPTemplateParameter T = (ICPPTemplateParameter) col.getName(1).resolveBinding();
|
||||
ICPPFunctionTemplate f1 = (ICPPFunctionTemplate) col.getName(2).resolveBinding();
|
||||
ICPPTemplateParameter T2 = (ICPPTemplateParameter) col.getName(3).resolveBinding();
|
||||
assertSame( T, T2 );
|
||||
|
||||
ICPPTemplateParameter U = (ICPPTemplateParameter) col.getName(5).resolveBinding();
|
||||
assertSame( T, U );
|
||||
ICPPClassType A2 = (ICPPClassType) col.getName(7).resolveBinding();
|
||||
assertSame( A, A2 );
|
||||
ICPPMethod f2 = (ICPPMethod) col.getName(8).resolveBinding();
|
||||
IBinding U2 = col.getName(10).resolveBinding();
|
||||
assertSame( U, U2 );
|
||||
|
||||
assertTrue( f2 instanceof ICPPSpecialization );
|
||||
assertSame( ((ICPPSpecialization)f2).getSpecializedBinding(), f1 );
|
||||
}
|
||||
|
||||
public void test14_7_3s16() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("template<class T> struct A { \n"); //$NON-NLS-1$
|
||||
buffer.append(" void f(T); \n"); //$NON-NLS-1$
|
||||
buffer.append(" template<class X> void g(T,X); \n"); //$NON-NLS-1$
|
||||
buffer.append(" void h(T) { } \n"); //$NON-NLS-1$
|
||||
buffer.append("}; \n"); //$NON-NLS-1$
|
||||
buffer.append("template<> void A<int>::f(int); \n"); //$NON-NLS-1$
|
||||
buffer.append("template<class T> template<class X> void A<T>::g(T,X) { } \n"); //$NON-NLS-1$
|
||||
buffer.append("template<> template<class X> void A<int>::g(int,X); \n"); //$NON-NLS-1$
|
||||
buffer.append("template<> template<> void A<int>::g(int,char); \n"); //$NON-NLS-1$
|
||||
buffer.append("template<> template<> void A<int>::g<char>(int,char); \n"); //$NON-NLS-1$
|
||||
buffer.append("template<> void A<int>::h(int) { } \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();
|
||||
ICPPClassType A = (ICPPClassType) col.getName(1).resolveBinding();
|
||||
ICPPMethod f = (ICPPMethod) col.getName(2).resolveBinding();
|
||||
ICPPTemplateParameter T2 = (ICPPTemplateParameter) col.getName(3).resolveBinding();
|
||||
assertSame( T, T2 );
|
||||
|
||||
ICPPTemplateParameter X = (ICPPTemplateParameter) col.getName(5).resolveBinding();
|
||||
ICPPFunctionTemplate g = (ICPPFunctionTemplate) col.getName(6).resolveBinding();
|
||||
ICPPTemplateParameter T3 = (ICPPTemplateParameter) col.getName(7).resolveBinding();
|
||||
assertSame( T, T3 );
|
||||
ICPPTemplateParameter X2 = (ICPPTemplateParameter) col.getName(9).resolveBinding();
|
||||
assertSame( X, X2 );
|
||||
|
||||
ICPPMethod h = (ICPPMethod) col.getName(11).resolveBinding();
|
||||
ICPPTemplateParameter T4 = (ICPPTemplateParameter) col.getName(12).resolveBinding();
|
||||
assertSame( T, T4 );
|
||||
|
||||
ICPPClassType A2 = (ICPPClassType) col.getName(15).resolveBinding();
|
||||
assertTrue( A2 instanceof ICPPTemplateInstance );
|
||||
assertSame( ((ICPPTemplateInstance)A2).getTemplateDefinition(), A );
|
||||
ICPPMethod f2 = (ICPPMethod) col.getName(17).resolveBinding();
|
||||
assertTrue( f2 instanceof ICPPSpecialization );
|
||||
assertSame( ((ICPPSpecialization)f2).getSpecializedBinding(), f );
|
||||
|
||||
ICPPTemplateParameter TR = (ICPPTemplateParameter) col.getName(19).resolveBinding();
|
||||
assertSame( T, TR );
|
||||
ICPPTemplateParameter XR = (ICPPTemplateParameter) col.getName(20).resolveBinding();
|
||||
assertSame( X, XR );
|
||||
ICPPClassType A3 = (ICPPClassType) col.getName(22).resolveBinding();
|
||||
assertTrue( A3 instanceof ICPPTemplateInstance );
|
||||
assertSame( ((ICPPTemplateInstance)A3).getTemplateDefinition(), A );
|
||||
assertNotSame( A2, A3 );
|
||||
|
||||
ICPPMethod g2 = (ICPPMethod) col.getName(25).resolveBinding();
|
||||
assertSame( g2, g );
|
||||
TR = (ICPPTemplateParameter) col.getName(26).resolveBinding();
|
||||
assertSame( T, TR );
|
||||
XR = (ICPPTemplateParameter) col.getName(28).resolveBinding();
|
||||
assertSame( X, XR );
|
||||
|
||||
assertSame( col.getName(32).resolveBinding(), A2 );
|
||||
assertSame( col.getName(39).resolveBinding(), A2 );
|
||||
assertSame( col.getName(45).resolveBinding(), A2 );
|
||||
assertSame( col.getName(52).resolveBinding(), A2 );
|
||||
|
||||
ICPPMethod h2 = (ICPPMethod) col.getName(54).resolveBinding();
|
||||
assertTrue( h2 instanceof ICPPSpecialization );
|
||||
assertSame( ((ICPPSpecialization)h2).getSpecializedBinding(), h );
|
||||
}
|
||||
|
||||
public void test14_6_1s6() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("namespace N { \n"); //$NON-NLS-1$
|
||||
buffer.append(" int C; \n"); //$NON-NLS-1$
|
||||
buffer.append(" template<class T> class B { \n"); //$NON-NLS-1$
|
||||
buffer.append(" void f(T); \n"); //$NON-NLS-1$
|
||||
buffer.append(" }; \n"); //$NON-NLS-1$
|
||||
buffer.append("} \n"); //$NON-NLS-1$
|
||||
buffer.append("template<class C> void N::B<C>::f(C) { \n"); //$NON-NLS-1$
|
||||
buffer.append(" C b; // C is the template parameter, not N::C \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(2).resolveBinding();
|
||||
ICPPClassTemplate B = (ICPPClassTemplate) col.getName(3).resolveBinding();
|
||||
ICPPMethod f = (ICPPMethod) col.getName(4).resolveBinding();
|
||||
ICPPTemplateParameter TR = (ICPPTemplateParameter) col.getName(5).resolveBinding();
|
||||
assertSame( T, TR );
|
||||
|
||||
ICPPTemplateParameter C = (ICPPTemplateParameter) col.getName(7).resolveBinding();
|
||||
assertSame( C, T );
|
||||
|
||||
ICPPClassType B2 = (ICPPClassType) col.getName(10).resolveBinding();
|
||||
assertTrue( B2 instanceof ICPPTemplateInstance );
|
||||
assertSame( ((ICPPTemplateInstance)B2).getTemplateDefinition(), B );
|
||||
|
||||
ICPPTemplateParameter CR = (ICPPTemplateParameter) col.getName(12).resolveBinding();
|
||||
assertSame( CR, T );
|
||||
|
||||
ICPPMethod f2 = (ICPPMethod) col.getName(13).resolveBinding();
|
||||
assertSame( f2, f );
|
||||
|
||||
CR = (ICPPTemplateParameter) col.getName(14).resolveBinding();
|
||||
assertSame( CR, T );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IBasicType;
|
|||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
||||
|
@ -66,7 +67,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
|||
name = ns[ ns.length - 1 ];
|
||||
}
|
||||
|
||||
IBinding binding = compTypeSpec.getName().resolveBinding();
|
||||
IBinding binding = name.resolveBinding();
|
||||
if( !(binding instanceof ICPPClassType ) )
|
||||
return;
|
||||
|
||||
|
@ -100,6 +101,16 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
|||
addBinding( m );
|
||||
}
|
||||
|
||||
public IScope getParent() {
|
||||
ICPPASTCompositeTypeSpecifier compType = (ICPPASTCompositeTypeSpecifier) getPhysicalNode();
|
||||
IASTName compName = compType.getName();
|
||||
if( compName instanceof ICPPASTQualifiedName ){
|
||||
IASTName [] ns = ((ICPPASTQualifiedName)compName).getNames();
|
||||
compName = ns[ ns.length - 1 ];
|
||||
}
|
||||
return CPPVisitor.getContainingScope( compName );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#addBinding(org.eclipse.cdt.core.dom.ast.IBinding)
|
||||
*/
|
||||
|
@ -172,7 +183,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
|||
return CPPSemantics.resolveAmbiguities( name, getConstructors( resolve ) );
|
||||
}
|
||||
//9.2 ... The class-name is also inserted into the scope of the class itself
|
||||
return compType.getName().resolveBinding();
|
||||
return compName.resolveBinding();
|
||||
}
|
||||
return super.getBinding( name, resolve );
|
||||
}
|
||||
|
@ -195,7 +206,12 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
|||
public IBinding[] find(String name) throws DOMException {
|
||||
char [] n = name.toCharArray();
|
||||
ICPPASTCompositeTypeSpecifier compType = (ICPPASTCompositeTypeSpecifier) getPhysicalNode();
|
||||
if( CharArrayUtils.equals( n, compType.getName().toCharArray() ) ){
|
||||
IASTName compName = compType.getName();
|
||||
if( compName instanceof ICPPASTQualifiedName ){
|
||||
IASTName [] ns = ((ICPPASTQualifiedName)compName).getNames();
|
||||
compName = ns[ ns.length - 1 ];
|
||||
}
|
||||
if( CharArrayUtils.equals( n, compName.toCharArray() ) ){
|
||||
return (IBinding[]) ArrayUtil.addAll( IBinding.class, null, getConstructors( true ) );
|
||||
}
|
||||
return super.find( name );
|
||||
|
|
|
@ -169,9 +169,7 @@ public class CPPFunction implements ICPPFunction, ICPPInternalFunction {
|
|||
IScope scope = getScope();
|
||||
try {
|
||||
IASTNode node = scope.getPhysicalNode();
|
||||
while( !( node instanceof IASTTranslationUnit) )
|
||||
node = node.getParent();
|
||||
tu = (IASTTranslationUnit) node;
|
||||
tu = node.getTranslationUnit();
|
||||
} catch ( DOMException e ) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,8 @@ public class CPPFunctionScope extends CPPScope implements ICPPFunctionScope {
|
|||
IASTFunctionDeclarator fdtor = (IASTFunctionDeclarator) getPhysicalNode();
|
||||
IASTName name = fdtor.getName();
|
||||
if( name instanceof ICPPASTQualifiedName ){
|
||||
IASTName [] ns = ((ICPPASTQualifiedName)name).getNames();
|
||||
ICPPASTQualifiedName qual = (ICPPASTQualifiedName) name;
|
||||
IASTName [] ns = qual.getNames();
|
||||
if( ns.length > 1){
|
||||
IBinding binding = ns[ ns.length - 2 ].resolveBinding();
|
||||
if( binding instanceof ICPPClassType )
|
||||
|
@ -91,10 +92,12 @@ public class CPPFunctionScope extends CPPScope implements ICPPFunctionScope {
|
|||
else if( binding instanceof ICPPNamespace )
|
||||
return ((ICPPNamespace)binding).getNamespaceScope();
|
||||
return binding.getScope();
|
||||
} else if( qual.isFullyQualified() ){
|
||||
return qual.getTranslationUnit().getScope();
|
||||
}
|
||||
}
|
||||
|
||||
return CPPVisitor.getContainingScope( fdtor );
|
||||
return CPPVisitor.getContainingScope( name );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -730,7 +730,13 @@ public class CPPSemantics {
|
|||
IASTNode parent = name.getParent();
|
||||
|
||||
if( parent instanceof ICPPASTBaseSpecifier ) {
|
||||
IASTNode n = CPPVisitor.getContainingBlockItem( parent );
|
||||
ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) parent.getParent();
|
||||
IASTName n = compSpec.getName();
|
||||
if( n instanceof ICPPASTQualifiedName ){
|
||||
IASTName [] ns = ((ICPPASTQualifiedName)n).getNames();
|
||||
n = ns[ ns.length - 1 ];
|
||||
}
|
||||
|
||||
return (ICPPScope) CPPVisitor.getContainingScope( n );
|
||||
} else if( parent instanceof ICPPASTConstructorChainInitializer ){
|
||||
ICPPASTConstructorChainInitializer initializer = (ICPPASTConstructorChainInitializer) parent;
|
||||
|
@ -810,8 +816,6 @@ public class CPPSemantics {
|
|||
|
||||
while( scope != null ){
|
||||
IASTNode blockItem = CPPVisitor.getContainingBlockItem( node );
|
||||
if( blockItem != null && scope.getPhysicalNode() != blockItem.getParent() && !(scope instanceof ICPPNamespaceScope) )
|
||||
blockItem = node;
|
||||
|
||||
ArrayWrapper directives = null;
|
||||
if( !data.usingDirectivesOnly ){
|
||||
|
@ -871,7 +875,7 @@ public class CPPSemantics {
|
|||
return;
|
||||
|
||||
//if still not found, loop and check our containing scope
|
||||
if( data.qualified() ) {
|
||||
if( data.qualified() && !(scope instanceof ICPPTemplateScope) ) {
|
||||
if( !data.usingDirectives.isEmpty() )
|
||||
data.usingDirectivesOnly = true;
|
||||
else
|
||||
|
@ -880,7 +884,23 @@ public class CPPSemantics {
|
|||
|
||||
if( blockItem != null )
|
||||
node = blockItem;
|
||||
scope = (ICPPScope) scope.getParent();
|
||||
|
||||
ICPPScope parentScope = (ICPPScope) scope.getParent();
|
||||
if( parentScope instanceof ICPPTemplateScope ){
|
||||
IASTNode parent = node.getParent();
|
||||
while( parent != null && !(parent instanceof ICPPASTTemplateDeclaration) ){
|
||||
node = parent;
|
||||
parent = parent.getParent();
|
||||
}
|
||||
if( parent != null ){
|
||||
ICPPASTTemplateDeclaration templateDecl = (ICPPASTTemplateDeclaration) parent;
|
||||
ICPPTemplateScope templateScope = templateDecl.getScope();
|
||||
if( templateScope.getTemplateDefinition() == ((ICPPTemplateScope)parentScope).getTemplateDefinition() ){
|
||||
parentScope = templateScope;
|
||||
}
|
||||
}
|
||||
}
|
||||
scope = parentScope;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2837,14 +2857,13 @@ public class CPPSemantics {
|
|||
}
|
||||
|
||||
public static boolean isSameFunction(IFunction function, IASTDeclarator declarator) {
|
||||
IASTNode parent = declarator.getParent();
|
||||
while( !(parent instanceof IASTDeclaration) ){
|
||||
parent = parent.getParent();
|
||||
}
|
||||
IASTName name = declarator.getName();
|
||||
ICPPASTTemplateDeclaration templateDecl = CPPTemplates.getTemplateDeclaration( name );
|
||||
|
||||
boolean fnIsTemplate = ( function instanceof ICPPFunctionTemplate );
|
||||
boolean dtorIsTemplate = (parent.getPropertyInParent() == ICPPASTTemplateDeclaration.OWNED_DECLARATION );
|
||||
boolean dtorIsTemplate = ( templateDecl != null );
|
||||
if( fnIsTemplate && dtorIsTemplate ){
|
||||
return CPPTemplates.isSameTemplate( (ICPPTemplateDefinition)function, declarator.getName() );
|
||||
return CPPTemplates.isSameTemplate( (ICPPTemplateDefinition)function, name );
|
||||
} else if( fnIsTemplate ^ dtorIsTemplate ){
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -164,6 +164,19 @@ public abstract class CPPTemplateDefinition implements ICPPTemplateDefinition, I
|
|||
break;
|
||||
}
|
||||
|
||||
if( definition != null || (declarations != null && declarations.length > 0 ) ){
|
||||
IASTName templateName = ( definition != null ) ? definition : declarations[0];
|
||||
ICPPASTTemplateDeclaration temp = CPPTemplates.getTemplateDeclaration( templateName );
|
||||
ICPPASTTemplateParameter [] params = temp.getTemplateParameters();
|
||||
if( params.length > i ) {
|
||||
IASTName paramName = CPPTemplates.getTemplateParameterName( params[i] );
|
||||
if( paramName.getBinding() != null ){
|
||||
binding = paramName.getBinding();
|
||||
name.setBinding( binding );
|
||||
return binding;
|
||||
}
|
||||
}
|
||||
}
|
||||
//create a new binding and set it for the corresponding parameter in all known decls
|
||||
if( templateParameter instanceof ICPPASTSimpleTypeTemplateParameter )
|
||||
binding = new CPPTemplateTypeParameter( name );
|
||||
|
@ -211,7 +224,7 @@ public abstract class CPPTemplateDefinition implements ICPPTemplateDefinition, I
|
|||
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
|
||||
*/
|
||||
public IScope getScope() {
|
||||
return CPPVisitor.getContainingScope( getTemplateName().getParent() );
|
||||
return CPPVisitor.getContainingScope( getTemplateName() );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
|
|
@ -13,8 +13,17 @@
|
|||
*/
|
||||
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.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
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.ICPPClassType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope;
|
||||
|
||||
|
@ -53,4 +62,40 @@ public class CPPTemplateScope extends CPPScope implements ICPPTemplateScope {
|
|||
return null;
|
||||
}
|
||||
|
||||
public IScope getParent() {
|
||||
ICPPASTTemplateDeclaration templateDecl = (ICPPASTTemplateDeclaration) getPhysicalNode();
|
||||
IASTName name = CPPTemplates.getTemplateName( templateDecl );
|
||||
IASTNode p = name.getParent();
|
||||
if( p instanceof ICPPASTQualifiedName ){
|
||||
ICPPASTQualifiedName qual = (ICPPASTQualifiedName) p;
|
||||
IASTName [] names = qual.getNames();
|
||||
int i = 0;
|
||||
for( ; i < names.length; i++ ){
|
||||
if( names[i] == name ) break;
|
||||
}
|
||||
if( i > 0 ){
|
||||
try {
|
||||
IBinding binding = names[i - 1].resolveBinding();
|
||||
if( binding instanceof ICPPClassType ){
|
||||
return ((ICPPClassType)binding).getCompositeScope();
|
||||
} else if( binding instanceof ICPPNamespace ){
|
||||
return ((ICPPNamespace)binding).getNamespaceScope();
|
||||
} else if( binding instanceof ICPPInternalUnknown ){
|
||||
return ((ICPPInternalUnknown)binding).getUnknownScope();
|
||||
} else if( binding instanceof IProblemBinding ){
|
||||
if( binding instanceof ICPPScope )
|
||||
return (IScope) binding;
|
||||
return new CPPScope.CPPScopeProblem( names[i-1], IProblemBinding.SEMANTIC_BAD_SCOPE, names[i-1].toCharArray() );
|
||||
}
|
||||
} catch( DOMException e ){
|
||||
return e.getProblem();
|
||||
}
|
||||
} else if( qual.isFullyQualified() ){
|
||||
return qual.getTranslationUnit().getScope();
|
||||
}
|
||||
}
|
||||
while( templateDecl.getParent() instanceof ICPPASTTemplateDeclaration )
|
||||
templateDecl = (ICPPASTTemplateDeclaration) templateDecl.getParent();
|
||||
return CPPVisitor.getContainingScope( templateDecl );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
|
||||
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.ICPPField;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
|
@ -68,7 +69,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
|
||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
|
@ -98,6 +98,13 @@ public class CPPTemplates {
|
|||
IASTNode parent = param.getParent();
|
||||
IBinding binding = null;
|
||||
if( parent instanceof ICPPASTTemplateDeclaration ){
|
||||
// IASTName name = getTemplateName( (ICPPASTTemplateDeclaration) parent );
|
||||
// if( name != null ){
|
||||
// if( name instanceof ICPPASTTemplateId && !(name.getParent() instanceof ICPPASTQualifiedName) )
|
||||
// name = ((ICPPASTTemplateId)name).getTemplateName();
|
||||
//
|
||||
// binding = name.resolveBinding();
|
||||
// }
|
||||
ICPPASTTemplateDeclaration [] templates = new ICPPASTTemplateDeclaration [] { (ICPPASTTemplateDeclaration) parent };
|
||||
|
||||
while( parent.getParent() instanceof ICPPASTTemplateDeclaration ){
|
||||
|
@ -315,7 +322,7 @@ public class CPPTemplates {
|
|||
CPPSemantics.LookupData data = new CPPSemantics.LookupData( name );
|
||||
data.forceQualified = true;
|
||||
IScope scope = CPPVisitor.getContainingScope( name );
|
||||
if( scope instanceof ICPPTemplateScope && name.getPropertyInParent() != ICPPASTQualifiedName.SEGMENT_NAME ){
|
||||
if( scope instanceof ICPPTemplateScope ){
|
||||
try {
|
||||
scope = scope.getParent();
|
||||
} catch (DOMException e) {
|
||||
|
@ -501,14 +508,6 @@ public class CPPTemplates {
|
|||
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* @param scope
|
||||
* @return
|
||||
*/
|
||||
public static ICPPTemplateDefinition getTemplateDefinition(ICPPTemplateScope scope) {
|
||||
if( scope != null ) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param decl
|
||||
|
@ -608,55 +607,109 @@ public class CPPTemplates {
|
|||
public static ICPPASTTemplateDeclaration getTemplateDeclaration( IASTName name ){
|
||||
if( name == null ) return null;
|
||||
|
||||
// if( name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME )
|
||||
// name = (IASTName) name.getParent();
|
||||
//
|
||||
// if( !(name instanceof ICPPASTTemplateId) )
|
||||
// return null;
|
||||
|
||||
IASTNode parent = name.getParent();
|
||||
while( parent != null && !(parent instanceof ICPPASTTemplateDeclaration) &&
|
||||
!(parent instanceof ICPPASTTemplatedTypeTemplateParameter) )
|
||||
{
|
||||
parent = parent.getParent();
|
||||
while( parent instanceof IASTName ){
|
||||
parent = parent.getParent();
|
||||
}
|
||||
if( parent instanceof IASTDeclSpecifier ){
|
||||
parent = parent.getParent();
|
||||
} else {
|
||||
while( parent instanceof IASTDeclarator ){
|
||||
parent = parent.getParent();
|
||||
}
|
||||
}
|
||||
if( parent instanceof IASTDeclaration && parent.getParent() instanceof ICPPASTTemplateDeclaration ){
|
||||
parent = parent.getParent();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
if( parent == null ) return null;
|
||||
|
||||
if( parent instanceof ICPPASTTemplateDeclaration ){
|
||||
ICPPASTTemplateDeclaration [] templates = new ICPPASTTemplateDeclaration [] { (ICPPASTTemplateDeclaration) parent };
|
||||
|
||||
while( parent.getParent() instanceof ICPPASTTemplateDeclaration ){
|
||||
parent = parent.getParent();
|
||||
templates = (ICPPASTTemplateDeclaration[]) ArrayUtil.append( ICPPASTTemplateDeclaration.class, templates, parent );
|
||||
ICPPASTTemplateDeclaration templateDecl = (ICPPASTTemplateDeclaration) parent;
|
||||
while( templateDecl.getParent() instanceof ICPPASTTemplateDeclaration )
|
||||
templateDecl = (ICPPASTTemplateDeclaration) templateDecl.getParent();
|
||||
|
||||
IASTName [] ns = null;
|
||||
if( name instanceof ICPPASTQualifiedName ){
|
||||
ns = ((ICPPASTQualifiedName)name).getNames();
|
||||
name = ns[ ns.length - 1 ];
|
||||
} else if( name.getParent() instanceof ICPPASTQualifiedName ){
|
||||
ns = ((ICPPASTQualifiedName)name.getParent()).getNames();
|
||||
}
|
||||
templates = (ICPPASTTemplateDeclaration[]) ArrayUtil.trim( ICPPASTTemplateDeclaration.class, templates );
|
||||
|
||||
if( name == null )
|
||||
return null;
|
||||
|
||||
if( name.getParent() instanceof ICPPASTQualifiedName ){
|
||||
int idx = templates.length;
|
||||
int i = -1;
|
||||
IASTName [] ns = ((ICPPASTQualifiedName) name.getParent()).getNames();
|
||||
if( ns != null ){
|
||||
IASTDeclaration currDecl = templateDecl;
|
||||
for (int j = 0; j < ns.length; j++) {
|
||||
if( ns[j] instanceof ICPPASTTemplateId || j + 1 == ns.length){
|
||||
++i;
|
||||
}
|
||||
if( ns[j] == name ){
|
||||
if( i < idx )
|
||||
return templates[ i ];
|
||||
return null;
|
||||
if( ns[j] instanceof ICPPASTTemplateId || j + 1 == ns.length ){
|
||||
if( currDecl instanceof ICPPASTTemplateDeclaration )
|
||||
return (ICPPASTTemplateDeclaration) currDecl;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if( ns[j] instanceof ICPPASTTemplateId ){
|
||||
if( currDecl instanceof ICPPASTTemplateDeclaration )
|
||||
currDecl = ((ICPPASTTemplateDeclaration) currDecl).getDeclaration();
|
||||
else
|
||||
return null; //??? this would imply bad ast or code
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return templates[0];
|
||||
return templateDecl;
|
||||
}
|
||||
} else if( parent instanceof ICPPASTTemplatedTypeTemplateParameter ){
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IASTName getTemplateName( ICPPASTTemplateDeclaration templateDecl ){
|
||||
if( templateDecl == null ) return null;
|
||||
|
||||
ICPPASTTemplateDeclaration decl = templateDecl;
|
||||
while( decl.getParent() instanceof ICPPASTTemplateDeclaration )
|
||||
decl = (ICPPASTTemplateDeclaration) decl.getParent();
|
||||
|
||||
IASTDeclaration nestedDecl = templateDecl.getDeclaration();
|
||||
while( nestedDecl instanceof ICPPASTTemplateDeclaration ){
|
||||
nestedDecl = ((ICPPASTTemplateDeclaration)nestedDecl).getDeclaration();
|
||||
}
|
||||
|
||||
IASTName name = null;
|
||||
if( nestedDecl instanceof IASTSimpleDeclaration ){
|
||||
IASTSimpleDeclaration simple = (IASTSimpleDeclaration) nestedDecl;
|
||||
if( simple.getDeclarators().length == 1 ){
|
||||
IASTDeclarator dtor = simple.getDeclarators()[0];
|
||||
while( dtor.getNestedDeclarator() != null )
|
||||
dtor = dtor.getNestedDeclarator();
|
||||
name = dtor.getName();
|
||||
} else if( simple.getDeclarators().length == 0 ){
|
||||
IASTDeclSpecifier spec = simple.getDeclSpecifier();
|
||||
if( spec instanceof ICPPASTCompositeTypeSpecifier )
|
||||
name = ((ICPPASTCompositeTypeSpecifier)spec).getName();
|
||||
else if( spec instanceof ICPPASTElaboratedTypeSpecifier )
|
||||
name = ((ICPPASTElaboratedTypeSpecifier)spec).getName();
|
||||
}
|
||||
} else if( nestedDecl instanceof IASTFunctionDefinition ){
|
||||
name = ((IASTFunctionDefinition)nestedDecl).getDeclarator().getName();
|
||||
}
|
||||
if( name != null ){
|
||||
if( name instanceof ICPPASTQualifiedName ){
|
||||
IASTName [] ns = ((ICPPASTQualifiedName) name).getNames();
|
||||
IASTDeclaration currDecl = decl;
|
||||
for (int j = 0; j < ns.length; j++) {
|
||||
if( ns[j] instanceof ICPPASTTemplateId || j + 1 == ns.length){
|
||||
if( currDecl == templateDecl )
|
||||
return ns[j];
|
||||
if( currDecl instanceof ICPPASTTemplateDeclaration )
|
||||
currDecl = ((ICPPASTTemplateDeclaration)currDecl).getDeclaration();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class ClearBindingAction extends CPPASTVisitor {
|
||||
|
@ -692,6 +745,9 @@ public class CPPTemplates {
|
|||
return false;
|
||||
}
|
||||
ICPPASTTemplateDeclaration templateDecl = getTemplateDeclaration( name );
|
||||
if( templateDecl == null )
|
||||
return false;
|
||||
|
||||
ICPPASTTemplateParameter [] templateParams = templateDecl.getTemplateParameters();
|
||||
if( defParams.length != templateParams.length )
|
||||
return false;
|
||||
|
@ -718,7 +774,7 @@ public class CPPTemplates {
|
|||
int i = 0;
|
||||
for(; i < ps.length; i++) {
|
||||
IType t1 = CPPVisitor.createType( params[i].getDeclarator() );
|
||||
IType t2 = ps[0].getType();
|
||||
IType t2 = ps[i].getType();
|
||||
if( ! t1.isSameType( t2 ) ){
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -450,7 +450,7 @@ public class CPPVisitor {
|
|||
}
|
||||
|
||||
boolean template = false;
|
||||
ICPPScope scope = (ICPPScope) getContainingScope( name );
|
||||
ICPPScope scope = (ICPPScope) getContainingScope( (IASTNode) name );
|
||||
if( scope instanceof ICPPTemplateScope ){
|
||||
ICPPScope parentScope = null;
|
||||
try {
|
||||
|
@ -598,7 +598,12 @@ public class CPPVisitor {
|
|||
} catch ( DOMException e ) {
|
||||
return false;
|
||||
}
|
||||
return isConstructor( clsTypeSpec.getName(), declarator );
|
||||
IASTName clsName = clsTypeSpec.getName();
|
||||
if( clsName instanceof ICPPASTQualifiedName ){
|
||||
IASTName [] names = ((ICPPASTQualifiedName)clsName).getNames();
|
||||
clsName = names[ names.length - 1 ];
|
||||
}
|
||||
return isConstructor( clsName, declarator );
|
||||
}
|
||||
public static boolean isConstructor( IASTName parentName, IASTDeclarator declarator ){
|
||||
if( declarator == null || !(declarator instanceof IASTFunctionDeclarator) )
|
||||
|
@ -631,9 +636,10 @@ public class CPPVisitor {
|
|||
if( node == null )
|
||||
return null;
|
||||
while( node != null ){
|
||||
if( node instanceof IASTName ){
|
||||
if( node instanceof IASTName && !( node instanceof ICPPASTQualifiedName ) ){
|
||||
return getContainingScope( (IASTName) node );
|
||||
} else if( node instanceof IASTDeclaration ){
|
||||
}
|
||||
if( node instanceof IASTDeclaration ){
|
||||
IASTNode parent = node.getParent();
|
||||
if( parent instanceof IASTTranslationUnit ){
|
||||
return ((IASTTranslationUnit)parent).getScope();
|
||||
|
@ -645,15 +651,19 @@ public class CPPVisitor {
|
|||
return ((IASTCompositeTypeSpecifier)parent).getScope();
|
||||
} else if( parent instanceof ICPPASTNamespaceDefinition ) {
|
||||
return ((ICPPASTNamespaceDefinition)parent).getScope();
|
||||
} else if( parent instanceof ICPPASTTemplateDeclaration ){
|
||||
return ((ICPPASTTemplateDeclaration)parent).getScope();
|
||||
}
|
||||
} else if( node instanceof IASTStatement ){
|
||||
return getContainingScope( (IASTStatement) node );
|
||||
} else if( node instanceof IASTTypeId ){
|
||||
node = node.getParent();
|
||||
if( node instanceof ICPPASTTemplateParameter )
|
||||
return CPPTemplates.getContainingScope( node );
|
||||
if( node.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT ){
|
||||
ICPPASTTemplateDeclaration decl = CPPTemplates.getTemplateDeclaration( (IASTName) node.getParent() );
|
||||
if( decl == null ){
|
||||
node = node.getParent();
|
||||
while( node instanceof IASTName )
|
||||
node = node.getParent();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else if( node instanceof IASTParameterDeclaration ){
|
||||
IASTNode parent = node.getParent();
|
||||
if( parent instanceof ICPPASTFunctionDeclarator ){
|
||||
|
@ -691,6 +701,15 @@ public class CPPVisitor {
|
|||
}
|
||||
} else if( node instanceof ICPPASTTemplateParameter ){
|
||||
return CPPTemplates.getContainingScope( node );
|
||||
} else if( node instanceof ICPPASTBaseSpecifier ) {
|
||||
ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) node.getParent();
|
||||
IASTName n = compSpec.getName();
|
||||
if( n instanceof ICPPASTQualifiedName ){
|
||||
IASTName [] ns = ((ICPPASTQualifiedName)n).getNames();
|
||||
n = ns[ ns.length - 1 ];
|
||||
}
|
||||
|
||||
return (ICPPScope) CPPVisitor.getContainingScope( n );
|
||||
}
|
||||
node = node.getParent();
|
||||
}
|
||||
|
@ -700,6 +719,14 @@ public class CPPVisitor {
|
|||
public static IScope getContainingScope( IASTName name ){
|
||||
IASTNode parent = name.getParent();
|
||||
try {
|
||||
if( parent instanceof ICPPASTTemplateId ){
|
||||
name = (IASTName) parent;
|
||||
parent = name.getParent();
|
||||
}
|
||||
ICPPASTTemplateDeclaration decl = CPPTemplates.getTemplateDeclaration( name );
|
||||
if( decl != null )
|
||||
return decl.getScope();
|
||||
|
||||
if( parent instanceof ICPPASTQualifiedName ){
|
||||
IASTName [] names = ((ICPPASTQualifiedName) parent).getNames();
|
||||
int i = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue