mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 18:26:01 +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):
|
[--Start Example(CPP 14.6.2-3):
|
||||||
typedef double A;
|
typedef double A;
|
||||||
|
@ -709,55 +678,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
|
||||||
parse(buffer.toString(), ParserLanguage.CPP, true, 1);
|
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):
|
[--Start Example(CPP 14.8.2-2b):
|
||||||
template <class T> int f(typename T::B*);
|
template <class T> int f(typename T::B*);
|
||||||
|
|
|
@ -9767,6 +9767,34 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
||||||
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
|
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):
|
[--Start Example(CPP 14.6.1-7):
|
||||||
struct A {
|
struct A {
|
||||||
|
@ -10427,6 +10455,51 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
||||||
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
|
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):
|
[--Start Example(CPP 14.7.3-18):
|
||||||
template<class T1> class A {
|
template<class T1> class A {
|
||||||
|
|
|
@ -1174,6 +1174,79 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
assertTrue( x4 instanceof ICPPSpecialization );
|
assertTrue( x4 instanceof ICPPSpecialization );
|
||||||
assertEquals( ((ICPPSpecialization)x4).getSpecializedBinding(), x2 );
|
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 {
|
public void testTemplateParameterQualifiedType_1() throws Exception {
|
||||||
StringBuffer buffer = new StringBuffer();
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
@ -1234,5 +1307,170 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
assertSame( t, B );
|
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.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IParameter;
|
import org.eclipse.cdt.core.dom.ast.IParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
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.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
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 ];
|
name = ns[ ns.length - 1 ];
|
||||||
}
|
}
|
||||||
|
|
||||||
IBinding binding = compTypeSpec.getName().resolveBinding();
|
IBinding binding = name.resolveBinding();
|
||||||
if( !(binding instanceof ICPPClassType ) )
|
if( !(binding instanceof ICPPClassType ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -100,6 +101,16 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
||||||
addBinding( m );
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#addBinding(org.eclipse.cdt.core.dom.ast.IBinding)
|
* @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 ) );
|
return CPPSemantics.resolveAmbiguities( name, getConstructors( resolve ) );
|
||||||
}
|
}
|
||||||
//9.2 ... The class-name is also inserted into the scope of the class itself
|
//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 );
|
return super.getBinding( name, resolve );
|
||||||
}
|
}
|
||||||
|
@ -195,7 +206,12 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
||||||
public IBinding[] find(String name) throws DOMException {
|
public IBinding[] find(String name) throws DOMException {
|
||||||
char [] n = name.toCharArray();
|
char [] n = name.toCharArray();
|
||||||
ICPPASTCompositeTypeSpecifier compType = (ICPPASTCompositeTypeSpecifier) getPhysicalNode();
|
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 (IBinding[]) ArrayUtil.addAll( IBinding.class, null, getConstructors( true ) );
|
||||||
}
|
}
|
||||||
return super.find( name );
|
return super.find( name );
|
||||||
|
|
|
@ -169,9 +169,7 @@ public class CPPFunction implements ICPPFunction, ICPPInternalFunction {
|
||||||
IScope scope = getScope();
|
IScope scope = getScope();
|
||||||
try {
|
try {
|
||||||
IASTNode node = scope.getPhysicalNode();
|
IASTNode node = scope.getPhysicalNode();
|
||||||
while( !( node instanceof IASTTranslationUnit) )
|
tu = node.getTranslationUnit();
|
||||||
node = node.getParent();
|
|
||||||
tu = (IASTTranslationUnit) node;
|
|
||||||
} catch ( DOMException e ) {
|
} catch ( DOMException e ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,8 @@ public class CPPFunctionScope extends CPPScope implements ICPPFunctionScope {
|
||||||
IASTFunctionDeclarator fdtor = (IASTFunctionDeclarator) getPhysicalNode();
|
IASTFunctionDeclarator fdtor = (IASTFunctionDeclarator) getPhysicalNode();
|
||||||
IASTName name = fdtor.getName();
|
IASTName name = fdtor.getName();
|
||||||
if( name instanceof ICPPASTQualifiedName ){
|
if( name instanceof ICPPASTQualifiedName ){
|
||||||
IASTName [] ns = ((ICPPASTQualifiedName)name).getNames();
|
ICPPASTQualifiedName qual = (ICPPASTQualifiedName) name;
|
||||||
|
IASTName [] ns = qual.getNames();
|
||||||
if( ns.length > 1){
|
if( ns.length > 1){
|
||||||
IBinding binding = ns[ ns.length - 2 ].resolveBinding();
|
IBinding binding = ns[ ns.length - 2 ].resolveBinding();
|
||||||
if( binding instanceof ICPPClassType )
|
if( binding instanceof ICPPClassType )
|
||||||
|
@ -91,10 +92,12 @@ public class CPPFunctionScope extends CPPScope implements ICPPFunctionScope {
|
||||||
else if( binding instanceof ICPPNamespace )
|
else if( binding instanceof ICPPNamespace )
|
||||||
return ((ICPPNamespace)binding).getNamespaceScope();
|
return ((ICPPNamespace)binding).getNamespaceScope();
|
||||||
return binding.getScope();
|
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();
|
IASTNode parent = name.getParent();
|
||||||
|
|
||||||
if( parent instanceof ICPPASTBaseSpecifier ) {
|
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 );
|
return (ICPPScope) CPPVisitor.getContainingScope( n );
|
||||||
} else if( parent instanceof ICPPASTConstructorChainInitializer ){
|
} else if( parent instanceof ICPPASTConstructorChainInitializer ){
|
||||||
ICPPASTConstructorChainInitializer initializer = (ICPPASTConstructorChainInitializer) parent;
|
ICPPASTConstructorChainInitializer initializer = (ICPPASTConstructorChainInitializer) parent;
|
||||||
|
@ -810,8 +816,6 @@ public class CPPSemantics {
|
||||||
|
|
||||||
while( scope != null ){
|
while( scope != null ){
|
||||||
IASTNode blockItem = CPPVisitor.getContainingBlockItem( node );
|
IASTNode blockItem = CPPVisitor.getContainingBlockItem( node );
|
||||||
if( blockItem != null && scope.getPhysicalNode() != blockItem.getParent() && !(scope instanceof ICPPNamespaceScope) )
|
|
||||||
blockItem = node;
|
|
||||||
|
|
||||||
ArrayWrapper directives = null;
|
ArrayWrapper directives = null;
|
||||||
if( !data.usingDirectivesOnly ){
|
if( !data.usingDirectivesOnly ){
|
||||||
|
@ -871,7 +875,7 @@ public class CPPSemantics {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//if still not found, loop and check our containing scope
|
//if still not found, loop and check our containing scope
|
||||||
if( data.qualified() ) {
|
if( data.qualified() && !(scope instanceof ICPPTemplateScope) ) {
|
||||||
if( !data.usingDirectives.isEmpty() )
|
if( !data.usingDirectives.isEmpty() )
|
||||||
data.usingDirectivesOnly = true;
|
data.usingDirectivesOnly = true;
|
||||||
else
|
else
|
||||||
|
@ -880,7 +884,23 @@ public class CPPSemantics {
|
||||||
|
|
||||||
if( blockItem != null )
|
if( blockItem != null )
|
||||||
node = blockItem;
|
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) {
|
public static boolean isSameFunction(IFunction function, IASTDeclarator declarator) {
|
||||||
IASTNode parent = declarator.getParent();
|
IASTName name = declarator.getName();
|
||||||
while( !(parent instanceof IASTDeclaration) ){
|
ICPPASTTemplateDeclaration templateDecl = CPPTemplates.getTemplateDeclaration( name );
|
||||||
parent = parent.getParent();
|
|
||||||
}
|
|
||||||
boolean fnIsTemplate = ( function instanceof ICPPFunctionTemplate );
|
boolean fnIsTemplate = ( function instanceof ICPPFunctionTemplate );
|
||||||
boolean dtorIsTemplate = (parent.getPropertyInParent() == ICPPASTTemplateDeclaration.OWNED_DECLARATION );
|
boolean dtorIsTemplate = ( templateDecl != null );
|
||||||
if( fnIsTemplate && dtorIsTemplate ){
|
if( fnIsTemplate && dtorIsTemplate ){
|
||||||
return CPPTemplates.isSameTemplate( (ICPPTemplateDefinition)function, declarator.getName() );
|
return CPPTemplates.isSameTemplate( (ICPPTemplateDefinition)function, name );
|
||||||
} else if( fnIsTemplate ^ dtorIsTemplate ){
|
} else if( fnIsTemplate ^ dtorIsTemplate ){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,6 +164,19 @@ public abstract class CPPTemplateDefinition implements ICPPTemplateDefinition, I
|
||||||
break;
|
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
|
//create a new binding and set it for the corresponding parameter in all known decls
|
||||||
if( templateParameter instanceof ICPPASTSimpleTypeTemplateParameter )
|
if( templateParameter instanceof ICPPASTSimpleTypeTemplateParameter )
|
||||||
binding = new CPPTemplateTypeParameter( name );
|
binding = new CPPTemplateTypeParameter( name );
|
||||||
|
@ -211,7 +224,7 @@ public abstract class CPPTemplateDefinition implements ICPPTemplateDefinition, I
|
||||||
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
|
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
|
||||||
*/
|
*/
|
||||||
public IScope getScope() {
|
public IScope getScope() {
|
||||||
return CPPVisitor.getContainingScope( getTemplateName().getParent() );
|
return CPPVisitor.getContainingScope( getTemplateName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
|
|
@ -13,8 +13,17 @@
|
||||||
*/
|
*/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
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.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
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.ICPPTemplateDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope;
|
||||||
|
|
||||||
|
@ -53,4 +62,40 @@ public class CPPTemplateScope extends CPPScope implements ICPPTemplateScope {
|
||||||
return null;
|
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.ICPPASTTemplateSpecialization;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter;
|
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.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.ICPPClassType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
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.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.ICPPTemplateNonTypeParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
|
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.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.ICPPTemplateTemplateParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
|
||||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
|
@ -98,6 +98,13 @@ public class CPPTemplates {
|
||||||
IASTNode parent = param.getParent();
|
IASTNode parent = param.getParent();
|
||||||
IBinding binding = null;
|
IBinding binding = null;
|
||||||
if( parent instanceof ICPPASTTemplateDeclaration ){
|
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 };
|
ICPPASTTemplateDeclaration [] templates = new ICPPASTTemplateDeclaration [] { (ICPPASTTemplateDeclaration) parent };
|
||||||
|
|
||||||
while( parent.getParent() instanceof ICPPASTTemplateDeclaration ){
|
while( parent.getParent() instanceof ICPPASTTemplateDeclaration ){
|
||||||
|
@ -315,7 +322,7 @@ public class CPPTemplates {
|
||||||
CPPSemantics.LookupData data = new CPPSemantics.LookupData( name );
|
CPPSemantics.LookupData data = new CPPSemantics.LookupData( name );
|
||||||
data.forceQualified = true;
|
data.forceQualified = true;
|
||||||
IScope scope = CPPVisitor.getContainingScope( name );
|
IScope scope = CPPVisitor.getContainingScope( name );
|
||||||
if( scope instanceof ICPPTemplateScope && name.getPropertyInParent() != ICPPASTQualifiedName.SEGMENT_NAME ){
|
if( scope instanceof ICPPTemplateScope ){
|
||||||
try {
|
try {
|
||||||
scope = scope.getParent();
|
scope = scope.getParent();
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
|
@ -501,14 +508,6 @@ public class CPPTemplates {
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* @param scope
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static ICPPTemplateDefinition getTemplateDefinition(ICPPTemplateScope scope) {
|
|
||||||
if( scope != null ) {}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param decl
|
* @param decl
|
||||||
|
@ -608,55 +607,109 @@ public class CPPTemplates {
|
||||||
public static ICPPASTTemplateDeclaration getTemplateDeclaration( IASTName name ){
|
public static ICPPASTTemplateDeclaration getTemplateDeclaration( IASTName name ){
|
||||||
if( name == null ) return null;
|
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();
|
IASTNode parent = name.getParent();
|
||||||
while( parent != null && !(parent instanceof ICPPASTTemplateDeclaration) &&
|
while( parent instanceof IASTName ){
|
||||||
!(parent instanceof ICPPASTTemplatedTypeTemplateParameter) )
|
parent = parent.getParent();
|
||||||
{
|
}
|
||||||
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 ){
|
if( parent instanceof ICPPASTTemplateDeclaration ){
|
||||||
ICPPASTTemplateDeclaration [] templates = new ICPPASTTemplateDeclaration [] { (ICPPASTTemplateDeclaration) parent };
|
ICPPASTTemplateDeclaration templateDecl = (ICPPASTTemplateDeclaration) parent;
|
||||||
|
while( templateDecl.getParent() instanceof ICPPASTTemplateDeclaration )
|
||||||
while( parent.getParent() instanceof ICPPASTTemplateDeclaration ){
|
templateDecl = (ICPPASTTemplateDeclaration) templateDecl.getParent();
|
||||||
parent = parent.getParent();
|
|
||||||
templates = (ICPPASTTemplateDeclaration[]) ArrayUtil.append( ICPPASTTemplateDeclaration.class, templates, parent );
|
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( ns != null ){
|
||||||
|
IASTDeclaration currDecl = templateDecl;
|
||||||
if( name == null )
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if( name.getParent() instanceof ICPPASTQualifiedName ){
|
|
||||||
int idx = templates.length;
|
|
||||||
int i = -1;
|
|
||||||
IASTName [] ns = ((ICPPASTQualifiedName) name.getParent()).getNames();
|
|
||||||
for (int j = 0; j < ns.length; j++) {
|
for (int j = 0; j < ns.length; j++) {
|
||||||
if( ns[j] instanceof ICPPASTTemplateId || j + 1 == ns.length){
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
if( ns[j] == name ){
|
if( ns[j] == name ){
|
||||||
if( i < idx )
|
if( ns[j] instanceof ICPPASTTemplateId || j + 1 == ns.length ){
|
||||||
return templates[ i ];
|
if( currDecl instanceof ICPPASTTemplateDeclaration )
|
||||||
return null;
|
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 {
|
} else {
|
||||||
return templates[0];
|
return templateDecl;
|
||||||
}
|
}
|
||||||
} else if( parent instanceof ICPPASTTemplatedTypeTemplateParameter ){
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
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 {
|
private static class ClearBindingAction extends CPPASTVisitor {
|
||||||
|
@ -692,6 +745,9 @@ public class CPPTemplates {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ICPPASTTemplateDeclaration templateDecl = getTemplateDeclaration( name );
|
ICPPASTTemplateDeclaration templateDecl = getTemplateDeclaration( name );
|
||||||
|
if( templateDecl == null )
|
||||||
|
return false;
|
||||||
|
|
||||||
ICPPASTTemplateParameter [] templateParams = templateDecl.getTemplateParameters();
|
ICPPASTTemplateParameter [] templateParams = templateDecl.getTemplateParameters();
|
||||||
if( defParams.length != templateParams.length )
|
if( defParams.length != templateParams.length )
|
||||||
return false;
|
return false;
|
||||||
|
@ -718,7 +774,7 @@ public class CPPTemplates {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(; i < ps.length; i++) {
|
for(; i < ps.length; i++) {
|
||||||
IType t1 = CPPVisitor.createType( params[i].getDeclarator() );
|
IType t1 = CPPVisitor.createType( params[i].getDeclarator() );
|
||||||
IType t2 = ps[0].getType();
|
IType t2 = ps[i].getType();
|
||||||
if( ! t1.isSameType( t2 ) ){
|
if( ! t1.isSameType( t2 ) ){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -450,7 +450,7 @@ public class CPPVisitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean template = false;
|
boolean template = false;
|
||||||
ICPPScope scope = (ICPPScope) getContainingScope( name );
|
ICPPScope scope = (ICPPScope) getContainingScope( (IASTNode) name );
|
||||||
if( scope instanceof ICPPTemplateScope ){
|
if( scope instanceof ICPPTemplateScope ){
|
||||||
ICPPScope parentScope = null;
|
ICPPScope parentScope = null;
|
||||||
try {
|
try {
|
||||||
|
@ -598,7 +598,12 @@ public class CPPVisitor {
|
||||||
} catch ( DOMException e ) {
|
} catch ( DOMException e ) {
|
||||||
return false;
|
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 ){
|
public static boolean isConstructor( IASTName parentName, IASTDeclarator declarator ){
|
||||||
if( declarator == null || !(declarator instanceof IASTFunctionDeclarator) )
|
if( declarator == null || !(declarator instanceof IASTFunctionDeclarator) )
|
||||||
|
@ -631,9 +636,10 @@ public class CPPVisitor {
|
||||||
if( node == null )
|
if( node == null )
|
||||||
return null;
|
return null;
|
||||||
while( node != null ){
|
while( node != null ){
|
||||||
if( node instanceof IASTName ){
|
if( node instanceof IASTName && !( node instanceof ICPPASTQualifiedName ) ){
|
||||||
return getContainingScope( (IASTName) node );
|
return getContainingScope( (IASTName) node );
|
||||||
} else if( node instanceof IASTDeclaration ){
|
}
|
||||||
|
if( node instanceof IASTDeclaration ){
|
||||||
IASTNode parent = node.getParent();
|
IASTNode parent = node.getParent();
|
||||||
if( parent instanceof IASTTranslationUnit ){
|
if( parent instanceof IASTTranslationUnit ){
|
||||||
return ((IASTTranslationUnit)parent).getScope();
|
return ((IASTTranslationUnit)parent).getScope();
|
||||||
|
@ -645,15 +651,19 @@ public class CPPVisitor {
|
||||||
return ((IASTCompositeTypeSpecifier)parent).getScope();
|
return ((IASTCompositeTypeSpecifier)parent).getScope();
|
||||||
} else if( parent instanceof ICPPASTNamespaceDefinition ) {
|
} else if( parent instanceof ICPPASTNamespaceDefinition ) {
|
||||||
return ((ICPPASTNamespaceDefinition)parent).getScope();
|
return ((ICPPASTNamespaceDefinition)parent).getScope();
|
||||||
} else if( parent instanceof ICPPASTTemplateDeclaration ){
|
|
||||||
return ((ICPPASTTemplateDeclaration)parent).getScope();
|
|
||||||
}
|
}
|
||||||
} else if( node instanceof IASTStatement ){
|
} else if( node instanceof IASTStatement ){
|
||||||
return getContainingScope( (IASTStatement) node );
|
return getContainingScope( (IASTStatement) node );
|
||||||
} else if( node instanceof IASTTypeId ){
|
} else if( node instanceof IASTTypeId ){
|
||||||
node = node.getParent();
|
if( node.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT ){
|
||||||
if( node instanceof ICPPASTTemplateParameter )
|
ICPPASTTemplateDeclaration decl = CPPTemplates.getTemplateDeclaration( (IASTName) node.getParent() );
|
||||||
return CPPTemplates.getContainingScope( node );
|
if( decl == null ){
|
||||||
|
node = node.getParent();
|
||||||
|
while( node instanceof IASTName )
|
||||||
|
node = node.getParent();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if( node instanceof IASTParameterDeclaration ){
|
} else if( node instanceof IASTParameterDeclaration ){
|
||||||
IASTNode parent = node.getParent();
|
IASTNode parent = node.getParent();
|
||||||
if( parent instanceof ICPPASTFunctionDeclarator ){
|
if( parent instanceof ICPPASTFunctionDeclarator ){
|
||||||
|
@ -691,6 +701,15 @@ public class CPPVisitor {
|
||||||
}
|
}
|
||||||
} else if( node instanceof ICPPASTTemplateParameter ){
|
} else if( node instanceof ICPPASTTemplateParameter ){
|
||||||
return CPPTemplates.getContainingScope( node );
|
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();
|
node = node.getParent();
|
||||||
}
|
}
|
||||||
|
@ -700,6 +719,14 @@ public class CPPVisitor {
|
||||||
public static IScope getContainingScope( IASTName name ){
|
public static IScope getContainingScope( IASTName name ){
|
||||||
IASTNode parent = name.getParent();
|
IASTNode parent = name.getParent();
|
||||||
try {
|
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 ){
|
if( parent instanceof ICPPASTQualifiedName ){
|
||||||
IASTName [] names = ((ICPPASTQualifiedName) parent).getNames();
|
IASTName [] names = ((ICPPASTQualifiedName) parent).getNames();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue