diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java index c14c1323c75..cf89a300259 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java @@ -560,37 +560,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest { } } - /** - [--Start Example(CPP 14.6.1-6): - namespace N { - class C { }; - template class B { - void f(T); - }; - } - template void N::B::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 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 void N::B::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 struct A { - void f(T); - template void g(T,X); - void h(T) { } - }; - // specialization - template<> void A::f(int); - // out of class member template definition - template template void A::g(T,X) { } - // member template partial specialization - template<> template void A::g(int,X); - // member template specialization - template<> template<> - void A::g(int,char); // X deduced as char - template<> template<> - void A::g(int,char); // X specified as char - // member specialization even if defined in class definition - template<> void A::h(int) { } - --End Example] - */ - public void test14_7_3s16() { // TODO similar bug already - StringBuffer buffer = new StringBuffer(); - buffer.append("template struct A {\n"); //$NON-NLS-1$ - buffer.append("void f(T);\n"); //$NON-NLS-1$ - buffer.append("template 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::f(int);\n"); //$NON-NLS-1$ - buffer.append("// out of class member template definition\n"); //$NON-NLS-1$ - buffer.append("template template void A::g(T,X) { }\n"); //$NON-NLS-1$ - buffer.append("// member template partial specialization\n"); //$NON-NLS-1$ - buffer.append("template<> template void A::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::g(int,char); // X deduced as char\n"); //$NON-NLS-1$ - buffer.append("template<> template<>\n"); //$NON-NLS-1$ - buffer.append("void A::g(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::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 int f(typename T::B*); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java index 58f7364173d..fb9de73c259 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java @@ -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 B { + void f(T); + }; + } + template void N::B::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 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 void N::B::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 struct A { + void f(T); + template void g(T,X); + void h(T) { } + }; + // specialization + template<> void A::f(int); + // out of class member template definition + template template void A::g(T,X) { } + // member template partial specialization + template<> template void A::g(int,X); + // member template specialization + template<> template<> + void A::g(int,char); // X deduced as char + template<> template<> + void A::g(int,char); // X specified as char + // member specialization even if defined in class definition + template<> void A::h(int) { } + --End Example] + */ + public void test14_7_3s16() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("template struct A {\n"); //$NON-NLS-1$ + buffer.append("void f(T);\n"); //$NON-NLS-1$ + buffer.append("template 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::f(int);\n"); //$NON-NLS-1$ + buffer.append("// out of class member template definition\n"); //$NON-NLS-1$ + buffer.append("template template void A::g(T,X) { }\n"); //$NON-NLS-1$ + buffer.append("// member template partial specialization\n"); //$NON-NLS-1$ + buffer.append("template<> template void A::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::g(int,char); // X deduced as char\n"); //$NON-NLS-1$ + buffer.append("template<> template<>\n"); //$NON-NLS-1$ + buffer.append("void A::g(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::h(int) { }\n"); //$NON-NLS-1$ + parse(buffer.toString(), ParserLanguage.CPP, true, 0); + } + /** [--Start Example(CPP 14.7.3-18): template class A { diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 739ae6dda8e..10a43745e55 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -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 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 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 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 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 A { \n"); //$NON-NLS-1$ + buffer.append(" A a; \n"); //$NON-NLS-1$ + buffer.append(" void f(); \n"); //$NON-NLS-1$ + buffer.append("}; \n"); //$NON-NLS-1$ + buffer.append("template void A::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 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 struct A { \n"); //$NON-NLS-1$ + buffer.append(" void f(T); \n"); //$NON-NLS-1$ + buffer.append(" template 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::f(int); \n"); //$NON-NLS-1$ + buffer.append("template template void A::g(T,X) { } \n"); //$NON-NLS-1$ + buffer.append("template<> template void A::g(int,X); \n"); //$NON-NLS-1$ + buffer.append("template<> template<> void A::g(int,char); \n"); //$NON-NLS-1$ + buffer.append("template<> template<> void A::g(int,char); \n"); //$NON-NLS-1$ + buffer.append("template<> void A::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 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 void N::B::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 ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index ec679d65ddf..05d9e2fd39a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -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 ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java index c874db271fe..fa722ae998e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java @@ -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 ) { } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java index 0d71c875056..f0edced4fc4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java @@ -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 ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java index 60ee157019f..229c95aa11d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java @@ -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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java index 7f4c73d16bf..173173468d8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java @@ -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) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateScope.java index 31a82407d29..1222fb9f47f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateScope.java @@ -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 ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java index dc17d7b6e35..4ca76f2da87 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java @@ -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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index 35326432ece..fb009629632 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -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;