mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 10:16:03 +02:00
Correct argument deduction for function templates, bug 256113
This commit is contained in:
parent
941076063d
commit
5b9cd2b43e
15 changed files with 658 additions and 693 deletions
|
@ -13,8 +13,6 @@ package org.eclipse.cdt.core.parser.tests.ast2;
|
||||||
|
|
||||||
import junit.framework.TestSuite;
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
|
|
||||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,58 +59,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
|
||||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// template<class T> class task;
|
|
||||||
// template<class T> task<T>* preempt(task<T>*);
|
|
||||||
// template<class T> class task {
|
|
||||||
// // ...
|
|
||||||
// friend void next_time();
|
|
||||||
// friend void process(task<T>*);
|
|
||||||
// friend task<T>* preempt<T>(task<T>*);
|
|
||||||
// template<class C> friend int func(C);
|
|
||||||
// friend class task<int>;
|
|
||||||
// template<class P> friend class frd;
|
|
||||||
// // ...
|
|
||||||
// };
|
|
||||||
public void _test14_5_3s1() throws Exception { // TODO raised bug 90678
|
|
||||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// template <int I> class A;
|
|
||||||
// template <int I, int J> A<I+J> f/*1*/(A<I>, A<J>); // #1
|
|
||||||
// template <int K, int L> A<K+L> f/*2*/(A<K>, A<L>); // same as #1
|
|
||||||
// template <int I, int J> A<I-J> f/*3*/(A<I>, A<J>); // different from #1
|
|
||||||
public void _test14_5_5_1s5() throws Exception {
|
|
||||||
final String content= getAboveComment();
|
|
||||||
IASTTranslationUnit tu= parse(content, ParserLanguage.CPP, true, 0);
|
|
||||||
BindingAssertionHelper bh= new BindingAssertionHelper(content, true);
|
|
||||||
ICPPFunctionTemplate f1= bh.assertNonProblem("f/*1*/", 1);
|
|
||||||
ICPPFunctionTemplate f2= bh.assertNonProblem("f/*2*/", 1);
|
|
||||||
ICPPFunctionTemplate f3= bh.assertNonProblem("f/*3*/", 1);
|
|
||||||
assertSame(f1, f2);
|
|
||||||
assertNotSame(f1, f3);
|
|
||||||
}
|
|
||||||
|
|
||||||
// template <class T> void f(T t);
|
|
||||||
// template <class X> void g(const X x);
|
|
||||||
// template <class Z> void h(Z, Z*);
|
|
||||||
// int main()
|
|
||||||
// {
|
|
||||||
// // #1: function type is f(int), t is nonconst
|
|
||||||
// f<int>(1);
|
|
||||||
// // #2: function type is f(int), t is const
|
|
||||||
// f<const int>(1);
|
|
||||||
// // #3: function type is g(int), x is const
|
|
||||||
// g<int>(1);
|
|
||||||
// // #4: function type is g(int), x is const
|
|
||||||
// g<const int>(1);
|
|
||||||
// // #5: function type is h(int, const int*)
|
|
||||||
// h<const int>(1,0);
|
|
||||||
// }
|
|
||||||
public void _test14_8_2s3() throws Exception {
|
|
||||||
// mstodo this one must pass
|
|
||||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// template <class T> struct B { };
|
// template <class T> struct B { };
|
||||||
// template <class T> struct D : public B<T> {};
|
// template <class T> struct D : public B<T> {};
|
||||||
// struct D2 : public B<int> {};
|
// struct D2 : public B<int> {};
|
||||||
|
@ -128,19 +74,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
|
||||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// template<class T> void f(T);
|
|
||||||
// class Complex {
|
|
||||||
// // ...
|
|
||||||
// Complex(double);
|
|
||||||
// };
|
|
||||||
// void g()
|
|
||||||
// {
|
|
||||||
// f<Complex>(1); // OK, means f<Complex>(Complex(1))
|
|
||||||
// }
|
|
||||||
public void _test14_8_1s4() throws Exception {
|
|
||||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// template<int i, typename T>
|
// template<int i, typename T>
|
||||||
// T deduce(typename A<T>::X x, // T is not deduced here
|
// T deduce(typename A<T>::X x, // T is not deduced here
|
||||||
// T t, // but T is deduced here
|
// T t, // but T is deduced here
|
||||||
|
@ -155,17 +88,4 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
|
||||||
public void _test14_8_2_4s14() throws Exception {
|
public void _test14_8_2_4s14() throws Exception {
|
||||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// template<class T> void f(T*,int); // #1
|
|
||||||
// template<class T> void f(T,char); // #2
|
|
||||||
// void h(int* pi, int i, char c)
|
|
||||||
// {
|
|
||||||
// f(pi,i); //#1: f<int>(pi,i)
|
|
||||||
// f(pi,c); //#2: f<int*>(pi,c)
|
|
||||||
// f(i,c); //#2: f<int>(i,c);
|
|
||||||
// f(i,i); //#2: f<int>(i,char(i))
|
|
||||||
// }
|
|
||||||
public void _test14_8_3s5() throws Exception {
|
|
||||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4604,6 +4604,22 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
||||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template<class T> class task;
|
||||||
|
// template<class T> task<T>* preempt(task<T>*);
|
||||||
|
// template<class T> class task {
|
||||||
|
// // ...
|
||||||
|
// friend void next_time();
|
||||||
|
// friend void process(task<T>*);
|
||||||
|
// friend task<T>* preempt<T>(task<T>*);
|
||||||
|
// template<class C> friend int func(C);
|
||||||
|
// friend class task<int>;
|
||||||
|
// template<class P> friend class frd;
|
||||||
|
// // ...
|
||||||
|
// };
|
||||||
|
public void test14_5_3s1() throws Exception {
|
||||||
|
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// namespace N {
|
// namespace N {
|
||||||
// template <class T> void f(T);
|
// template <class T> void f(T);
|
||||||
// void g(int);
|
// void g(int);
|
||||||
|
@ -5364,7 +5380,8 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
||||||
// template <> void f<int>(int*); // OK
|
// template <> void f<int>(int*); // OK
|
||||||
// template <> void f(int); // OK
|
// template <> void f(int); // OK
|
||||||
public void test14_7_3s12() throws Exception {
|
public void test14_7_3s12() throws Exception {
|
||||||
parse(getAboveComment(), ParserLanguage.CPP, true, 1);
|
// gcc does not report the explicit instantiation as ambiguous, so we accept it as well.
|
||||||
|
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// template<class T> void f(T) { }
|
// template<class T> void f(T) { }
|
||||||
|
@ -5467,6 +5484,19 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
||||||
parse(getAboveComment(), ParserLanguage.CPP, false, 0);
|
parse(getAboveComment(), ParserLanguage.CPP, false, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template<class T> void f(T);
|
||||||
|
// class Complex {
|
||||||
|
// // ...
|
||||||
|
// Complex(double);
|
||||||
|
// };
|
||||||
|
// void g()
|
||||||
|
// {
|
||||||
|
// f<Complex>(1); // OK, means f<Complex>(Complex(1))
|
||||||
|
// }
|
||||||
|
public void test14_8_1s4() throws Exception {
|
||||||
|
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// namespace A {
|
// namespace A {
|
||||||
// struct B { };
|
// struct B { };
|
||||||
// template<int X> void f();
|
// template<int X> void f();
|
||||||
|
@ -5545,6 +5575,26 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
||||||
parse(getAboveComment(), ParserLanguage.CPP, false, 1);
|
parse(getAboveComment(), ParserLanguage.CPP, false, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template <class T> void f(T t);
|
||||||
|
// template <class X> void g(const X x);
|
||||||
|
// template <class Z> void h(Z, Z*);
|
||||||
|
// int main()
|
||||||
|
// {
|
||||||
|
// // #1: function type is f(int), t is nonconst
|
||||||
|
// f<int>(1);
|
||||||
|
// // #2: function type is f(int), t is const
|
||||||
|
// f<const int>(1);
|
||||||
|
// // #3: function type is g(int), x is const
|
||||||
|
// g<int>(1);
|
||||||
|
// // #4: function type is g(int), x is const
|
||||||
|
// g<const int>(1);
|
||||||
|
// // #5: function type is h(int, const int*)
|
||||||
|
// h<const int>(1,0);
|
||||||
|
// }
|
||||||
|
public void test14_8_2s3() throws Exception {
|
||||||
|
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// template <int> int f(int);
|
// template <int> int f(int);
|
||||||
// template <signed char> int f(int);
|
// template <signed char> int f(int);
|
||||||
// int i1 = f<1>(0); // ambiguous
|
// int i1 = f<1>(0); // ambiguous
|
||||||
|
@ -5707,6 +5757,19 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
||||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template<class T> void f(T*,int); // #1
|
||||||
|
// template<class T> void f(T,char); // #2
|
||||||
|
// void h(int* pi, int i, char c)
|
||||||
|
// {
|
||||||
|
// f(pi,i); //#1: f<int>(pi,i)
|
||||||
|
// f(pi,c); //#2: f<int*>(pi,c)
|
||||||
|
// f(i,c); //#2: f<int>(i,c);
|
||||||
|
// f(i,i); //#2: f<int>(i,char(i))
|
||||||
|
// }
|
||||||
|
public void test14_8_3s5() throws Exception {
|
||||||
|
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// template<class T> void f(T); // declaration
|
// template<class T> void f(T); // declaration
|
||||||
// void g() {
|
// void g() {
|
||||||
// f("Annemarie"); // call of f<const char*>
|
// f("Annemarie"); // call of f<const char*>
|
||||||
|
@ -6209,6 +6272,21 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
||||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template <int I> class A;
|
||||||
|
// template <int I, int J> A<I+J> f/*1*/(A<I>, A<J>); // #1
|
||||||
|
// template <int K, int L> A<K+L> f/*2*/(A<K>, A<L>); // same as #1
|
||||||
|
// template <int I, int J> A<I-J> f/*3*/(A<I>, A<J>); // different from #1
|
||||||
|
public void test14_5_5_1s5() throws Exception {
|
||||||
|
final String content= getAboveComment();
|
||||||
|
IASTTranslationUnit tu= parse(content, ParserLanguage.CPP, true, 0);
|
||||||
|
BindingAssertionHelper bh= new BindingAssertionHelper(content, true);
|
||||||
|
ICPPFunctionTemplate f1= bh.assertNonProblem("f/*1*/", 1);
|
||||||
|
ICPPFunctionTemplate f2= bh.assertNonProblem("f/*2*/", 1);
|
||||||
|
ICPPFunctionTemplate f3= bh.assertNonProblem("f/*3*/", 1);
|
||||||
|
assertSame(f1, f2);
|
||||||
|
assertNotSame(f1, f3);
|
||||||
|
}
|
||||||
|
|
||||||
// template <int I> class A;
|
// template <int I> class A;
|
||||||
// template <int I, int J> void f/*1*/(A<I+J>); // #1
|
// template <int I, int J> void f/*1*/(A<I+J>); // #1
|
||||||
// template <int K, int L> void f/*2*/(A<K+L>); // same as #1
|
// template <int K, int L> void f/*2*/(A<K+L>); // same as #1
|
||||||
|
|
|
@ -2947,7 +2947,7 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
assertFalse(th1sCtor instanceof ICPPSpecialization);
|
assertFalse(th1sCtor instanceof ICPPSpecialization);
|
||||||
|
|
||||||
ICPPTemplateNonTypeParameter np = ba.assertNonProblem("I>(I)", 1, ICPPTemplateNonTypeParameter.class);
|
ICPPTemplateNonTypeParameter np = ba.assertNonProblem("I>(I)", 1, ICPPTemplateNonTypeParameter.class);
|
||||||
ICPPClassType clazz= ba.assertNonProblem("That<I>(I)", 4, ICPPClassType.class);
|
ICPPConstructor clazz= ba.assertNonProblem("That<I>(I)", 4, ICPPConstructor.class);
|
||||||
ICPPConstructor ctor= ba.assertNonProblem("That<I>(I)", 7, ICPPConstructor.class);
|
ICPPConstructor ctor= ba.assertNonProblem("That<I>(I)", 7, ICPPConstructor.class);
|
||||||
|
|
||||||
ICPPTemplateNonTypeParameter np1 = ba.assertNonProblem("I)", 1, ICPPTemplateNonTypeParameter.class);
|
ICPPTemplateNonTypeParameter np1 = ba.assertNonProblem("I)", 1, ICPPTemplateNonTypeParameter.class);
|
||||||
|
@ -2978,7 +2978,7 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
assertFalse(th1sCtor instanceof ICPPSpecialization);
|
assertFalse(th1sCtor instanceof ICPPSpecialization);
|
||||||
|
|
||||||
ICPPTemplateTypeParameter np= ba.assertNonProblem("I>()", 1, ICPPTemplateTypeParameter.class);
|
ICPPTemplateTypeParameter np= ba.assertNonProblem("I>()", 1, ICPPTemplateTypeParameter.class);
|
||||||
ICPPClassType clazz= ba.assertNonProblem("That<I>()", 4, ICPPClassType.class);
|
ICPPConstructor clazz= ba.assertNonProblem("That<I>()", 4, ICPPConstructor.class);
|
||||||
ICPPConstructor ctor= ba.assertNonProblem("That<I>()", 7, ICPPConstructor.class);
|
ICPPConstructor ctor= ba.assertNonProblem("That<I>()", 7, ICPPConstructor.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3294,4 +3294,50 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
public void testNewOfThisTemplate() throws Exception {
|
public void testNewOfThisTemplate() throws Exception {
|
||||||
parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP);
|
parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template <class T> void f(T);
|
||||||
|
// class X {
|
||||||
|
// friend void f<>(int);
|
||||||
|
// };
|
||||||
|
public void testFunctionSpecializationAsFriend() throws Exception {
|
||||||
|
final String code = getAboveComment();
|
||||||
|
parseAndCheckBindings(code, ParserLanguage.CPP);
|
||||||
|
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||||
|
ICPPFunctionTemplate f= bh.assertNonProblem("f(T)", 1);
|
||||||
|
IFunction fref1= bh.assertNonProblem("f<>", 1);
|
||||||
|
assertSame(fref1, f);
|
||||||
|
IFunction fref2= bh.assertNonProblem("f<>", 3);
|
||||||
|
assertInstance(fref2, ICPPTemplateInstance.class);
|
||||||
|
assertSame(f, ((ICPPTemplateInstance) fref2).getSpecializedBinding());
|
||||||
|
}
|
||||||
|
|
||||||
|
// template <typename T> class XT {
|
||||||
|
// typedef int mytype1;
|
||||||
|
// mytype1 m1();
|
||||||
|
// };
|
||||||
|
// template <typename T> class XT<T*> {
|
||||||
|
// typedef int mytype2;
|
||||||
|
// mytype2 m2();
|
||||||
|
// };
|
||||||
|
// template <> class XT<int> {
|
||||||
|
// typedef int mytype3;
|
||||||
|
// mytype3 m3();
|
||||||
|
// };
|
||||||
|
// template <typename T> typename XT<T>::mytype1 XT<T>::m1() {}
|
||||||
|
// template <typename T> typename XT<T*>::mytype2 XT<T*>::m2() {}
|
||||||
|
// template <> typename XT<int>::mytype3 XT<int>::m3() {}
|
||||||
|
public void testMethodImplWithNonDeferredType() throws Exception {
|
||||||
|
final String code = getAboveComment();
|
||||||
|
parseAndCheckBindings(code, ParserLanguage.CPP);
|
||||||
|
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||||
|
ICPPMethod m1= bh.assertNonProblem("m1();", 2);
|
||||||
|
ICPPMethod m2= bh.assertNonProblem("m1() ", 2);
|
||||||
|
assertSame(m1, m2);
|
||||||
|
m1= bh.assertNonProblem("m2();", 2);
|
||||||
|
m2= bh.assertNonProblem("m2() ", 2);
|
||||||
|
assertSame(m1, m2);
|
||||||
|
m1= bh.assertNonProblem("m3();", 2);
|
||||||
|
m2= bh.assertNonProblem("m3() ", 2);
|
||||||
|
assertSame(m1, m2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1419,7 +1419,7 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ICPPTemplateNonTypeParameter np= getBindingFromASTName("I>(I)", 1, ICPPTemplateNonTypeParameter.class);
|
ICPPTemplateNonTypeParameter np= getBindingFromASTName("I>(I)", 1, ICPPTemplateNonTypeParameter.class);
|
||||||
ICPPClassType clazz= getBindingFromASTName("That<I>(I)", 4, ICPPClassType.class);
|
ICPPConstructor clazz= getBindingFromASTName("That<I>(I)", 4, ICPPConstructor.class);
|
||||||
ICPPConstructor ctor= getBindingFromASTName("That<I>(I)", 7, ICPPConstructor.class);
|
ICPPConstructor ctor= getBindingFromASTName("That<I>(I)", 7, ICPPConstructor.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1445,7 +1445,7 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
|
||||||
assertFalse(th1sCtor instanceof ICPPSpecialization);
|
assertFalse(th1sCtor instanceof ICPPSpecialization);
|
||||||
|
|
||||||
ICPPTemplateTypeParameter np= getBindingFromASTName("I>()", 1, ICPPTemplateTypeParameter.class);
|
ICPPTemplateTypeParameter np= getBindingFromASTName("I>()", 1, ICPPTemplateTypeParameter.class);
|
||||||
ICPPClassType clazz= getBindingFromASTName("That<I>()", 4, ICPPClassType.class);
|
ICPPConstructor clazz= getBindingFromASTName("That<I>()", 4, ICPPConstructor.class);
|
||||||
ICPPConstructor ctor= getBindingFromASTName("That<I>()", 7, ICPPConstructor.class);
|
ICPPConstructor ctor= getBindingFromASTName("That<I>()", 7, ICPPConstructor.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
|
||||||
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.gnu.cpp.IGPPBasicType;
|
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPBasicType;
|
||||||
|
@ -331,6 +332,10 @@ public class ASTTypeUtil {
|
||||||
} else {
|
} else {
|
||||||
result.append(getNameForAnonymous((ICompositeType) type));
|
result.append(getNameForAnonymous((ICompositeType) type));
|
||||||
}
|
}
|
||||||
|
if (type instanceof ICPPTemplateInstance) {
|
||||||
|
ICPPTemplateInstance inst = (ICPPTemplateInstance) type;
|
||||||
|
result.append(getArgumentListString(inst.getTemplateArguments(), normalize));
|
||||||
|
}
|
||||||
} else if (type instanceof ICPPReferenceType) {
|
} else if (type instanceof ICPPReferenceType) {
|
||||||
result.append(Keywords.cpAMPER);
|
result.append(Keywords.cpAMPER);
|
||||||
} else if (type instanceof IEnumeration) {
|
} else if (type instanceof IEnumeration) {
|
||||||
|
|
|
@ -106,6 +106,6 @@ public class CPPDeferredClassInstance extends CPPUnknownClass implements ICPPDef
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getName() + ASTTypeUtil.getArgumentListString(fArguments, true);
|
return ASTTypeUtil.getType(this, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,10 @@
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* IBM - Initial API and implementation
|
* Andrew Niefer (IBM) - Initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
* Sergey Prigogin (Google)
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
/*
|
|
||||||
* Created on Feb 11, 2005
|
|
||||||
*/
|
|
||||||
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.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
|
@ -28,7 +25,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexType;
|
import org.eclipse.cdt.internal.core.index.IIndexType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author aniefer
|
* Models pointer to members.
|
||||||
*/
|
*/
|
||||||
public class CPPPointerToMemberType extends CPPPointerType implements ICPPPointerToMemberType {
|
public class CPPPointerToMemberType extends CPPPointerType implements ICPPPointerToMemberType {
|
||||||
private ICPPASTPointerToMember operator;
|
private ICPPASTPointerToMember operator;
|
||||||
|
@ -83,7 +80,7 @@ public class CPPPointerToMemberType extends CPPPointerType implements ICPPPointe
|
||||||
name = ns[ns.length - 1];
|
name = ns[ns.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
IBinding binding = name.resolveBinding();
|
IBinding binding = CPPASTNameBase.resolvePreBinding(name);
|
||||||
if (binding instanceof IType) {
|
if (binding instanceof IType) {
|
||||||
classType = (IType) binding;
|
classType = (IType) binding;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -370,13 +370,13 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (binding != null && !(binding instanceof IProblemBinding)) {
|
if (binding != null && !(binding instanceof IProblemBinding)) {
|
||||||
if (data.forDefinition()) {
|
if (data.forFunctionDeclaration()) {
|
||||||
addDefinition(binding, data.astName);
|
addDefinition(binding, data.astName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If we're still null...
|
// If we're still null...
|
||||||
if (binding == null) {
|
if (binding == null) {
|
||||||
if (name instanceof ICPPASTQualifiedName && data.forDefinition())
|
if (name instanceof ICPPASTQualifiedName && data.forFunctionDeclaration())
|
||||||
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND, data.name());
|
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND, data.name());
|
||||||
else
|
else
|
||||||
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, data.name());
|
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, data.name());
|
||||||
|
@ -1563,9 +1563,10 @@ public class CPPSemantics {
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// specialization is selected during instantiation
|
// specialization is selected during instantiation
|
||||||
if (candidate instanceof ICPPTemplateInstance && candidate instanceof IType)
|
if (candidate instanceof ICPPTemplateInstance)
|
||||||
candidate= ((ICPPTemplateInstance) candidate).getSpecializedBinding();
|
candidate= ((ICPPTemplateInstance) candidate).getSpecializedBinding();
|
||||||
|
|
||||||
|
if (!(candidate instanceof ICPPFunctionTemplate))
|
||||||
return candidate;
|
return candidate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1736,6 +1737,12 @@ public class CPPSemantics {
|
||||||
items = (Object[]) data.foundItems;
|
items = (Object[]) data.foundItems;
|
||||||
continue;
|
continue;
|
||||||
} else if (temp instanceof IFunction) {
|
} else if (temp instanceof IFunction) {
|
||||||
|
if (temp instanceof ICPPTemplateInstance) {
|
||||||
|
temp= ((ICPPTemplateInstance) temp).getSpecializedBinding();
|
||||||
|
if (!(temp instanceof IFunction))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
IFunction function= (IFunction) temp;
|
IFunction function= (IFunction) temp;
|
||||||
if (function instanceof ICPPFunctionTemplate) {
|
if (function instanceof ICPPFunctionTemplate) {
|
||||||
if (templateFns == ObjectSet.EMPTY_SET)
|
if (templateFns == ObjectSet.EMPTY_SET)
|
||||||
|
@ -1811,7 +1818,8 @@ public class CPPSemantics {
|
||||||
|
|
||||||
int numTemplateFns = templateFns.size();
|
int numTemplateFns = templateFns.size();
|
||||||
if (numTemplateFns > 0) {
|
if (numTemplateFns > 0) {
|
||||||
if (data.functionParameters != null && !data.forDefinition()) {
|
if (data.functionParameters != null &&
|
||||||
|
(!data.forFunctionDeclaration() || data.forExplicitFunctionSpecialization())) {
|
||||||
IFunction[] fs = CPPTemplates.selectTemplateFunctions(templateFns, data.functionParameters, data.astName);
|
IFunction[] fs = CPPTemplates.selectTemplateFunctions(templateFns, data.functionParameters, data.astName);
|
||||||
if (fs != null && fs.length > 0) {
|
if (fs != null && fs.length > 0) {
|
||||||
if (fns == ObjectSet.EMPTY_SET)
|
if (fns == ObjectSet.EMPTY_SET)
|
||||||
|
@ -1853,19 +1861,6 @@ public class CPPSemantics {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static private boolean functionHasParameters(IFunction function, IASTParameterDeclaration[] params) throws DOMException{
|
|
||||||
IFunctionType ftype = function.getType();
|
|
||||||
if (params.length == 0) {
|
|
||||||
return ftype.getParameterTypes().length == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
IASTNode node = params[0].getParent();
|
|
||||||
if (node instanceof ICPPASTFunctionDeclarator) {
|
|
||||||
return isSameFunction(function, (IASTDeclarator) node);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static private void reduceToViable(LookupData data, IBinding[] functions) throws DOMException{
|
static private void reduceToViable(LookupData data, IBinding[] functions) throws DOMException{
|
||||||
if (functions == null || functions.length == 0)
|
if (functions == null || functions.length == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -1873,7 +1868,7 @@ public class CPPSemantics {
|
||||||
Object[] fParams = data.functionParameters;
|
Object[] fParams = data.functionParameters;
|
||||||
int numParameters = (fParams != null) ? fParams.length : 0;
|
int numParameters = (fParams != null) ? fParams.length : 0;
|
||||||
int num;
|
int num;
|
||||||
boolean def = data.forDefinition();
|
boolean def = data.forFunctionDeclaration();
|
||||||
// Trim the list down to the set of viable functions
|
// Trim the list down to the set of viable functions
|
||||||
IFunction function = null;
|
IFunction function = null;
|
||||||
int size = functions.length;
|
int size = functions.length;
|
||||||
|
@ -1927,28 +1922,11 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static private boolean isMatchingFunctionDeclaration(IFunction candidate, LookupData data) {
|
static private boolean isMatchingFunctionDeclaration(IFunction candidate, LookupData data) {
|
||||||
IASTName name = data.astName;
|
|
||||||
ICPPASTTemplateDeclaration decl = CPPTemplates.getTemplateDeclaration(name);
|
|
||||||
if (decl != null && !(candidate instanceof ICPPTemplateDefinition))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (candidate instanceof ICPPTemplateDefinition && decl instanceof ICPPASTTemplateSpecialization) {
|
|
||||||
ICPPFunctionTemplate fn = CPPTemplates.resolveTemplateFunctions(new Object[] { candidate }, data.astName);
|
|
||||||
return (fn != null && !(fn instanceof IProblemBinding));
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
IASTNode node = data.astName.getParent();
|
IASTNode node = data.astName.getParent();
|
||||||
while (node instanceof IASTName)
|
while (node instanceof IASTName)
|
||||||
node = node.getParent();
|
node = node.getParent();
|
||||||
if (!(node instanceof ICPPASTFunctionDeclarator))
|
if (node instanceof IASTDeclarator) {
|
||||||
return false;
|
return isSameFunction(candidate, (IASTDeclarator) node);
|
||||||
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) node;
|
|
||||||
ICPPFunctionType ftype = (ICPPFunctionType) candidate.getType();
|
|
||||||
if (dtor.isConst() != ftype.isConst() || dtor.isVolatile() != ftype.isVolatile())
|
|
||||||
return false;
|
|
||||||
return functionHasParameters(candidate, (IASTParameterDeclaration[]) data.functionParameters);
|
|
||||||
} catch (DOMException e) {
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2028,7 +2006,7 @@ public class CPPSemantics {
|
||||||
deferredOnly= false;
|
deferredOnly= false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (deferredOnly || data.forDefinition() || data.forExplicitInstantiation()) {
|
if (deferredOnly || data.forFunctionDeclaration()) {
|
||||||
for (IFunction fn : fns) {
|
for (IFunction fn : fns) {
|
||||||
if (fn != null) {
|
if (fn != null) {
|
||||||
return fn;
|
return fn;
|
||||||
|
@ -2147,6 +2125,7 @@ public class CPPSemantics {
|
||||||
// then this is an ambiguity (unless we find something better than both later).
|
// then this is an ambiguity (unless we find something better than both later).
|
||||||
ambiguous |= (hasWorse && hasBetter) || (!hasWorse && !hasBetter);
|
ambiguous |= (hasWorse && hasBetter) || (!hasWorse && !hasBetter);
|
||||||
|
|
||||||
|
// mstodo if ambigous ??
|
||||||
if (!hasWorse) {
|
if (!hasWorse) {
|
||||||
// If they are both template functions, we can order them that way
|
// If they are both template functions, we can order them that way
|
||||||
ICPPFunctionTemplate bestAsTemplate= asTemplate(bestFn);
|
ICPPFunctionTemplate bestAsTemplate= asTemplate(bestFn);
|
||||||
|
@ -2336,10 +2315,10 @@ public class CPPSemantics {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ICPPTemplateDefinition template = (ICPPTemplateDefinition) id.getTemplateName().resolveBinding();
|
IBinding template =id.getTemplateName().resolveBinding();
|
||||||
if (template != null) {
|
if (template instanceof ICPPTemplateDefinition) {
|
||||||
try {
|
try {
|
||||||
ICPPTemplateParameter[] ps = template.getTemplateParameters();
|
ICPPTemplateParameter[] ps = ((ICPPTemplateDefinition)template).getTemplateParameters();
|
||||||
if (i < args.length && i < ps.length && ps[i] instanceof ICPPTemplateNonTypeParameter) {
|
if (i < args.length && i < ps.length && ps[i] instanceof ICPPTemplateNonTypeParameter) {
|
||||||
return ((ICPPTemplateNonTypeParameter)ps[i]).getType();
|
return ((ICPPTemplateNonTypeParameter)ps[i]).getType();
|
||||||
}
|
}
|
||||||
|
@ -2668,20 +2647,24 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSameFunction(IFunction function, IASTDeclarator declarator) {
|
public static boolean isSameFunction(IFunction function, IASTDeclarator declarator) {
|
||||||
IASTName name = declarator.getName();
|
IASTName name = CPPVisitor.findInnermostDeclarator(declarator).getName();
|
||||||
ICPPASTTemplateDeclaration templateDecl = CPPTemplates.getTemplateDeclaration(name);
|
ICPPASTTemplateDeclaration templateDecl = CPPTemplates.getTemplateDeclaration(name);
|
||||||
|
if (templateDecl != null) {
|
||||||
boolean fnIsTemplate = (function instanceof ICPPFunctionTemplate);
|
if (templateDecl instanceof ICPPASTTemplateSpecialization) {
|
||||||
boolean dtorIsTemplate = (templateDecl != null);
|
if (!(function instanceof ICPPTemplateInstance))
|
||||||
if (fnIsTemplate && dtorIsTemplate) {
|
return false;
|
||||||
return CPPTemplates.isSameTemplate((ICPPTemplateDefinition)function, name);
|
} else {
|
||||||
} else if (fnIsTemplate ^ dtorIsTemplate) {
|
if (!(function instanceof ICPPTemplateDefinition))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
IType type = null;
|
}
|
||||||
|
|
||||||
|
declarator= CPPVisitor.findTypeRelevantDeclarator(declarator);
|
||||||
try {
|
try {
|
||||||
type = function.getType();
|
if (declarator instanceof ICPPASTFunctionDeclarator) {
|
||||||
|
IType type = function.getType();
|
||||||
return type.isSameType(CPPVisitor.createType(declarator));
|
return type.isSameType(CPPVisitor.createType(declarator));
|
||||||
|
}
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -44,7 +44,6 @@ import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||||
import org.eclipse.cdt.core.dom.ast.IValue;
|
import org.eclipse.cdt.core.dom.ast.IValue;
|
||||||
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.ICPPASTDeclSpecifier;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||||
|
@ -55,7 +54,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
|
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.ICPPASTTemplatedTypeTemplateParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
|
||||||
|
@ -77,7 +75,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.ICPPTemplateParameterMap;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope;
|
|
||||||
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.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||||
|
@ -173,7 +170,7 @@ public class CPPTemplates {
|
||||||
return instance;
|
return instance;
|
||||||
|
|
||||||
CPPTemplateParameterMap tpMap= new CPPTemplateParameterMap(args.length);
|
CPPTemplateParameterMap tpMap= new CPPTemplateParameterMap(args.length);
|
||||||
if (!CPPTemplates.deduceTemplateParameterMap(partialSpec.getTemplateArguments(), args, true, tpMap))
|
if (!CPPTemplates.deduceTemplateParameterMap(partialSpec.getTemplateArguments(), args, tpMap))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
ICPPTemplateParameter[] params= partialSpec.getTemplateParameters();
|
ICPPTemplateParameter[] params= partialSpec.getTemplateParameters();
|
||||||
|
@ -303,8 +300,12 @@ public class CPPTemplates {
|
||||||
* Instantiates the template for usage within its own body. May return <code>null</code>.
|
* Instantiates the template for usage within its own body. May return <code>null</code>.
|
||||||
*/
|
*/
|
||||||
public static IBinding instantiateWithinClassTemplate(ICPPClassTemplate template) throws DOMException {
|
public static IBinding instantiateWithinClassTemplate(ICPPClassTemplate template) throws DOMException {
|
||||||
|
ICPPTemplateArgument[] args;
|
||||||
|
if (template instanceof ICPPClassTemplatePartialSpecialization) {
|
||||||
|
args= ((ICPPClassTemplatePartialSpecialization) template).getTemplateArguments();
|
||||||
|
} else {
|
||||||
ICPPTemplateParameter[] templateParameters = template.getTemplateParameters();
|
ICPPTemplateParameter[] templateParameters = template.getTemplateParameters();
|
||||||
ICPPTemplateArgument[] args = new ICPPTemplateArgument[templateParameters.length];
|
args = new ICPPTemplateArgument[templateParameters.length];
|
||||||
for (int i = 0; i < templateParameters.length; i++) {
|
for (int i = 0; i < templateParameters.length; i++) {
|
||||||
final ICPPTemplateParameter tp = templateParameters[i];
|
final ICPPTemplateParameter tp = templateParameters[i];
|
||||||
if (tp instanceof IType) {
|
if (tp instanceof IType) {
|
||||||
|
@ -316,6 +317,7 @@ public class CPPTemplates {
|
||||||
assert false;
|
assert false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return deferredInstance(template, args);
|
return deferredInstance(template, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,40 +427,46 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IBinding createBinding(ICPPASTTemplateId id) {
|
public static IBinding createBinding(ICPPASTTemplateId id) {
|
||||||
IASTNode parent = id.getParent();
|
if (!isClassTemplate(id)) {
|
||||||
boolean isLastName= true;
|
//functions are instantiated as part of the resolution process
|
||||||
if (parent instanceof ICPPASTQualifiedName) {
|
IBinding result= CPPVisitor.createBinding(id);
|
||||||
isLastName= ((ICPPASTQualifiedName) parent).getLastName() == id;
|
IASTName templateName = id.getTemplateName();
|
||||||
parent = parent.getParent();
|
if (result instanceof ICPPTemplateInstance) {
|
||||||
|
templateName.setBinding(((ICPPTemplateInstance) result).getTemplateDefinition());
|
||||||
|
} else {
|
||||||
|
templateName.setBinding(result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
IASTNode decl= parent;
|
IASTNode parentOfName = id.getParent();
|
||||||
while (decl != null) {
|
boolean isLastName= true;
|
||||||
if (decl instanceof IASTDeclaration) {
|
if (parentOfName instanceof ICPPASTQualifiedName) {
|
||||||
decl= decl.getParent();
|
isLastName= ((ICPPASTQualifiedName) parentOfName).getLastName() == id;
|
||||||
|
parentOfName = parentOfName.getParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isDecl= false;
|
||||||
|
boolean isDef= false;
|
||||||
|
if (isLastName) {
|
||||||
|
if (parentOfName instanceof ICPPASTElaboratedTypeSpecifier) {
|
||||||
|
IASTNode parentOfDeclaration= parentOfName;
|
||||||
|
while (parentOfDeclaration != null) {
|
||||||
|
if (parentOfDeclaration instanceof IASTDeclaration) {
|
||||||
|
parentOfDeclaration= parentOfDeclaration.getParent();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
decl= decl.getParent();
|
parentOfDeclaration= parentOfDeclaration.getParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isDecl= !(parentOfDeclaration instanceof ICPPASTExplicitTemplateInstantiation);
|
||||||
|
} else if (parentOfName instanceof ICPPASTCompositeTypeSpecifier) {
|
||||||
|
isDef= true;
|
||||||
|
}
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
final boolean isClassDecl= parent instanceof ICPPASTElaboratedTypeSpecifier;
|
|
||||||
final boolean isClassDef = parent instanceof ICPPASTCompositeTypeSpecifier;
|
|
||||||
|
|
||||||
if (isLastName) {
|
|
||||||
if (isClassDecl && decl instanceof ICPPASTExplicitTemplateInstantiation)
|
|
||||||
return createExplicitClassInstantiation((ICPPASTElaboratedTypeSpecifier) parent);
|
|
||||||
|
|
||||||
if (isClassDef || (isClassDecl && decl instanceof ICPPASTTemplateDeclaration))
|
|
||||||
return createExplicitClassSpecialization((ICPPASTDeclSpecifier) parent);
|
|
||||||
|
|
||||||
if (parent instanceof ICPPASTFunctionDeclarator)
|
|
||||||
return createFunctionSpecialization(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isLastName || isClassDecl || parent instanceof ICPPASTNamedTypeSpecifier ||
|
|
||||||
parent instanceof ICPPASTBaseSpecifier) {
|
|
||||||
// class template instance
|
// class template instance
|
||||||
|
IBinding result= null;
|
||||||
IASTName templateName = id.getTemplateName();
|
IASTName templateName = id.getTemplateName();
|
||||||
IBinding template = templateName.resolveBinding();
|
IBinding template = templateName.resolveBinding();
|
||||||
if (template instanceof ICPPUnknownClassInstance) {
|
if (template instanceof ICPPUnknownClassInstance) {
|
||||||
|
@ -478,337 +486,102 @@ public class CPPTemplates {
|
||||||
ICPPASTTemplateDeclaration tdecl= getTemplateDeclaration(id);
|
ICPPASTTemplateDeclaration tdecl= getTemplateDeclaration(id);
|
||||||
if (tdecl != null) {
|
if (tdecl != null) {
|
||||||
if (hasDependentArgument(args)) {
|
if (hasDependentArgument(args)) {
|
||||||
IBinding result= null;
|
|
||||||
if (argsAreTrivial(classTemplate.getTemplateParameters(), args)) {
|
if (argsAreTrivial(classTemplate.getTemplateParameters(), args)) {
|
||||||
result= classTemplate;
|
result= classTemplate;
|
||||||
} else {
|
} else {
|
||||||
ICPPClassTemplatePartialSpecialization partialSpec= findPartialSpecialization(classTemplate, args);
|
ICPPClassTemplatePartialSpecialization partialSpec= findPartialSpecialization(classTemplate, args);
|
||||||
|
if (isDecl || isDef) {
|
||||||
|
if (partialSpec == null) {
|
||||||
|
partialSpec = new CPPClassTemplatePartialSpecialization(id);
|
||||||
|
// mstodo how to add partial specialization to class template from index?
|
||||||
|
if (template instanceof ICPPInternalClassTemplate)
|
||||||
|
((ICPPInternalClassTemplate) template).addPartialSpecialization(partialSpec);
|
||||||
|
return partialSpec;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (partialSpec == null)
|
if (partialSpec == null)
|
||||||
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TYPE, templateName.toCharArray());
|
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TYPE, templateName.toCharArray());
|
||||||
result= partialSpec;
|
result= partialSpec;
|
||||||
}
|
}
|
||||||
if (isClassDecl && result instanceof ICPPInternalBinding)
|
|
||||||
((ICPPInternalBinding) result).addDeclaration(id);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IBinding instance= instantiate(classTemplate, args);
|
|
||||||
return CPPSemantics.postResolution(instance, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
//functions are instantiated as part of the resolution process
|
|
||||||
IBinding template = CPPVisitor.createBinding(id);
|
|
||||||
if (template instanceof ICPPTemplateInstance) {
|
|
||||||
IASTName templateName = id.getTemplateName();
|
|
||||||
templateName.setBinding(((ICPPTemplateInstance) template).getTemplateDefinition());
|
|
||||||
}
|
|
||||||
return template;
|
|
||||||
} catch (DOMException e) {
|
|
||||||
return e.getProblem();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static IBinding createExplicitClassInstantiation(ICPPASTElaboratedTypeSpecifier elabSpec) {
|
|
||||||
IASTName name = elabSpec.getName();
|
|
||||||
if (name instanceof ICPPASTQualifiedName) {
|
|
||||||
IASTName[] ns = ((ICPPASTQualifiedName) name).getNames();
|
|
||||||
name = ns[ns.length - 1];
|
|
||||||
}
|
|
||||||
ICPPASTTemplateId id = (ICPPASTTemplateId) name;
|
|
||||||
IBinding template = id.getTemplateName().resolveBinding();
|
|
||||||
try {
|
|
||||||
if (template instanceof ICPPClassTemplate) {
|
|
||||||
ICPPClassTemplate classTemplate = (ICPPClassTemplate) template;
|
|
||||||
ICPPTemplateArgument[] args= createTemplateArgumentArray(id);
|
|
||||||
IBinding binding= instantiate(classTemplate, args);
|
|
||||||
if (binding != null)
|
|
||||||
return binding;
|
|
||||||
}
|
|
||||||
} catch (DOMException e) {
|
|
||||||
return e.getProblem();
|
|
||||||
}
|
|
||||||
return new ProblemBinding(elabSpec, IProblemBinding.SEMANTIC_INVALID_TYPE, name.toCharArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the binding for a partial or explicit class specialization.
|
|
||||||
* @throws DOMException
|
|
||||||
*/
|
|
||||||
protected static IBinding createExplicitClassSpecialization(ICPPASTDeclSpecifier compSpec) throws DOMException {
|
|
||||||
IASTName name = null;
|
|
||||||
if (compSpec instanceof ICPPASTElaboratedTypeSpecifier)
|
|
||||||
name = ((ICPPASTElaboratedTypeSpecifier) compSpec).getName();
|
|
||||||
else if (compSpec instanceof ICPPASTCompositeTypeSpecifier)
|
|
||||||
name = ((ICPPASTCompositeTypeSpecifier) compSpec).getName();
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (name instanceof ICPPASTQualifiedName) {
|
|
||||||
IASTName[] ns = ((ICPPASTQualifiedName) name).getNames();
|
|
||||||
name = ns[ns.length - 1];
|
|
||||||
}
|
|
||||||
ICPPASTTemplateId id = (ICPPASTTemplateId) name;
|
|
||||||
|
|
||||||
IBinding binding = id.getTemplateName().resolveBinding();
|
|
||||||
if (!(binding instanceof ICPPClassTemplate))
|
|
||||||
return null; //TODO: problem?
|
|
||||||
|
|
||||||
ICPPClassTemplate template = (ICPPClassTemplate) binding;
|
|
||||||
|
|
||||||
ICPPASTTemplateDeclaration templateDecl = getTemplateDeclaration(id);
|
|
||||||
if (templateDecl instanceof ICPPASTTemplateSpecialization) {
|
|
||||||
ICPPTemplateInstance inst = null;
|
|
||||||
ICPPTemplateParameter[] templateParams= template.getTemplateParameters();
|
|
||||||
ICPPTemplateArgument[] args= createTemplateArgumentArray(id);
|
|
||||||
CPPTemplateParameterMap tpMap = new CPPTemplateParameterMap(templateParams.length);
|
|
||||||
if (templateParams.length != args.length) {
|
|
||||||
return null; // mstodo problem or use default args?
|
|
||||||
}
|
|
||||||
args= SemanticUtil.getSimplifiedArguments(args);
|
|
||||||
for (int i = 0; i < templateParams.length; i++) {
|
|
||||||
tpMap.put(templateParams[i], args[i]);
|
|
||||||
}
|
|
||||||
inst= getInstance(template, args);
|
|
||||||
if (inst == null) {
|
|
||||||
IBinding owner= binding.getOwner();
|
|
||||||
inst= new CPPClassInstance(owner, template, tpMap, args);
|
|
||||||
addInstance(template, args, inst);
|
|
||||||
}
|
|
||||||
if (inst instanceof ICPPInternalBinding) {
|
|
||||||
IASTNode parent = id.getParent();
|
|
||||||
while (!(parent instanceof IASTDeclSpecifier))
|
|
||||||
parent = parent.getParent();
|
|
||||||
if (parent instanceof IASTElaboratedTypeSpecifier)
|
|
||||||
((ICPPInternalBinding) inst).addDeclaration(id);
|
|
||||||
else if (parent instanceof IASTCompositeTypeSpecifier)
|
|
||||||
((ICPPInternalBinding) inst).addDefinition(id);
|
|
||||||
}
|
|
||||||
return inst;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we have a partial specialization
|
|
||||||
ICPPTemplateArgument[] args= createTemplateArgumentArray(id);
|
|
||||||
ICPPClassTemplatePartialSpecialization spec= findPartialSpecialization(template, args);
|
|
||||||
if (spec != null) {
|
|
||||||
if (spec instanceof ICPPInternalBinding)
|
|
||||||
((ICPPInternalBinding) spec).addDefinition(id);
|
|
||||||
return spec;
|
|
||||||
}
|
|
||||||
|
|
||||||
spec = new CPPClassTemplatePartialSpecialization(id);
|
|
||||||
// mstodo how to add partial specialization to class template from index?
|
|
||||||
if (template instanceof ICPPInternalClassTemplate)
|
|
||||||
((ICPPInternalClassTemplate) template).addPartialSpecialization(spec);
|
|
||||||
return spec;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static IBinding createFunctionSpecialization(IASTName name) throws DOMException {
|
|
||||||
try {
|
|
||||||
LookupData data = new LookupData(name);
|
|
||||||
data.forceQualified = true;
|
|
||||||
ICPPScope scope = (ICPPScope) CPPVisitor.getContainingScope(name);
|
|
||||||
if (scope instanceof ICPPTemplateScope) {
|
|
||||||
scope = (ICPPScope) scope.getParent();
|
|
||||||
}
|
|
||||||
CPPSemantics.lookup(data, scope);
|
|
||||||
|
|
||||||
ICPPFunctionTemplate function= resolveTemplateFunctions((Object[]) data.foundItems, name);
|
|
||||||
if (function == null)
|
|
||||||
return new ProblemBinding(name, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, name.toCharArray());
|
|
||||||
if (function instanceof IProblemBinding)
|
|
||||||
return function;
|
|
||||||
|
|
||||||
if (name instanceof ICPPASTTemplateId) {
|
|
||||||
((ICPPASTTemplateId) name).getTemplateName().setBinding(function);
|
|
||||||
}
|
|
||||||
IASTNode parent = name.getParent();
|
|
||||||
while (parent instanceof IASTName)
|
|
||||||
parent = parent.getParent();
|
|
||||||
|
|
||||||
IASTParameterDeclaration[] ps = ((ICPPASTFunctionDeclarator) parent).getParameters();
|
|
||||||
final CPPTemplateParameterMap tpMap= new CPPTemplateParameterMap(ps.length);
|
|
||||||
ICPPTemplateArgument[] args= deduceTemplateFunctionArguments(function, ps, data.templateId, tpMap);
|
|
||||||
if (args == null)
|
|
||||||
return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_TYPE, name.toCharArray());
|
|
||||||
|
|
||||||
IBinding result= null;
|
|
||||||
if (hasDependentArgument(args)) {
|
|
||||||
// we are looking at a definition for a function-template.
|
|
||||||
final ICPPTemplateParameter[] pars= function.getTemplateParameters();
|
|
||||||
if (!argsAreTrivial(pars, args)) {
|
|
||||||
return new ProblemBinding(name, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, name.toCharArray());
|
|
||||||
}
|
|
||||||
result= function;
|
|
||||||
} else {
|
|
||||||
result= getInstance(function, args);
|
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
IBinding owner= function.getOwner();
|
result= instantiate(classTemplate, args);
|
||||||
ICPPTemplateInstance instance= createInstance(owner, function, tpMap, args);
|
|
||||||
addInstance(function, args, instance);
|
|
||||||
result= instance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (!(parent instanceof IASTDeclaration))
|
|
||||||
parent = parent.getParent();
|
|
||||||
|
|
||||||
if (result instanceof ICPPInternalBinding) {
|
if (result instanceof ICPPInternalBinding) {
|
||||||
if (parent instanceof IASTSimpleDeclaration)
|
if (isDecl) {
|
||||||
((ICPPInternalBinding) result).addDeclaration(name);
|
((ICPPInternalBinding) result).addDeclaration(id);
|
||||||
else if (parent instanceof IASTFunctionDefinition)
|
} else if (isDef) {
|
||||||
((ICPPInternalBinding) result).addDefinition(name);
|
((ICPPInternalBinding) result).addDefinition(id);
|
||||||
}
|
}
|
||||||
return result;
|
}
|
||||||
|
}
|
||||||
|
return CPPSemantics.postResolution(result, id);
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
return e.getProblem();
|
return e.getProblem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static protected ICPPFunctionTemplate resolveTemplateFunctions(Object[] items, IASTName name) {
|
static boolean isClassTemplate(ICPPASTTemplateId id) {
|
||||||
if (items == null)
|
IASTNode parentOfName = id.getParent();
|
||||||
return null;
|
|
||||||
ICPPFunctionTemplate[] templates = null;
|
if (parentOfName instanceof ICPPASTQualifiedName) {
|
||||||
IBinding temp = null;
|
if (((ICPPASTQualifiedName) parentOfName).getLastName() != id)
|
||||||
for (Object o : items) {
|
return true;
|
||||||
if (o instanceof IASTName) {
|
parentOfName= parentOfName.getParent();
|
||||||
temp = ((IASTName) o).resolveBinding();
|
|
||||||
if (temp == null)
|
|
||||||
continue;
|
|
||||||
} else if (o instanceof IBinding) {
|
|
||||||
temp = (IBinding) o;
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (temp instanceof ICPPTemplateInstance)
|
IASTNode parentOfDeclaration= parentOfName;
|
||||||
temp = ((ICPPTemplateInstance) temp).getTemplateDefinition();
|
while (parentOfDeclaration != null) {
|
||||||
if (temp instanceof ICPPFunctionTemplate)
|
if (parentOfDeclaration instanceof IASTDeclaration) {
|
||||||
templates = (ICPPFunctionTemplate[]) ArrayUtil.append(ICPPFunctionTemplate.class, templates, temp);
|
parentOfDeclaration= parentOfDeclaration.getParent();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
parentOfDeclaration= parentOfDeclaration.getParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (templates == null)
|
return parentOfName instanceof ICPPASTElaboratedTypeSpecifier ||
|
||||||
return null;
|
parentOfName instanceof ICPPASTCompositeTypeSpecifier ||
|
||||||
|
parentOfName instanceof ICPPASTNamedTypeSpecifier ||
|
||||||
ICPPTemplateArgument[] templateArguments = null;
|
parentOfName instanceof ICPPASTBaseSpecifier;
|
||||||
|
|
||||||
if (name instanceof ICPPASTTemplateId) {
|
|
||||||
try {
|
|
||||||
templateArguments= createTemplateArgumentArray((ICPPASTTemplateId) name);
|
|
||||||
} catch (DOMException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int numArgs = (templateArguments != null) ? templateArguments.length : 0;
|
|
||||||
|
|
||||||
|
|
||||||
if (name.getParent() instanceof IASTName)
|
|
||||||
name = (IASTName) name.getParent();
|
|
||||||
IASTNode n = name.getParent();
|
|
||||||
if (n instanceof ICPPASTQualifiedName) {
|
|
||||||
n = n.getParent();
|
|
||||||
}
|
|
||||||
ICPPASTFunctionDeclarator fdtor = (ICPPASTFunctionDeclarator) n;
|
|
||||||
IType[] functionParameters = createTypeArray(fdtor.getParameters());
|
|
||||||
|
|
||||||
ICPPFunctionTemplate result = null;
|
|
||||||
outer: for (int i = 0; i < templates.length && templates[i] != null; i++) {
|
|
||||||
ICPPFunctionTemplate tmpl = templates[i];
|
|
||||||
|
|
||||||
CPPTemplateParameterMap map= new CPPTemplateParameterMap(functionParameters.length);
|
|
||||||
try {
|
|
||||||
if (!deduceTemplateParameterMapFromFunctionParameters(tmpl, functionParameters, map))
|
|
||||||
continue;
|
|
||||||
} catch (DOMException e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ICPPTemplateParameter[] params = null;
|
|
||||||
try {
|
|
||||||
params = tmpl.getTemplateParameters();
|
|
||||||
} catch (DOMException e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int numParams = params.length;
|
|
||||||
ICPPTemplateArgument arg = null;
|
|
||||||
for (int j = 0; j < numParams; j++) {
|
|
||||||
ICPPTemplateParameter param = params[j];
|
|
||||||
if (j < numArgs && templateArguments != null) {
|
|
||||||
arg = templateArguments[j];
|
|
||||||
} else {
|
|
||||||
arg = null;
|
|
||||||
}
|
|
||||||
ICPPTemplateArgument deducedArg= map.getArgument(param);
|
|
||||||
if (deducedArg != null) {
|
|
||||||
if (arg == null) {
|
|
||||||
map.put(param, deducedArg);
|
|
||||||
arg = deducedArg;
|
|
||||||
} else if (!deducedArg.isSameValue(arg)) {
|
|
||||||
continue outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
arg= matchTemplateParameterAndArgument(param, arg, map);
|
|
||||||
if (arg == null) {
|
|
||||||
continue outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//made it this far, its a match
|
|
||||||
if (result != null) {
|
|
||||||
return new CPPFunctionTemplate.CPPFunctionTemplateProblem(name, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, name.toCharArray());
|
|
||||||
}
|
|
||||||
result = tmpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deduce arguments for a template function from the template id + the template function parameters.
|
* Deduce arguments for a template function from the template id + the template function parameters.
|
||||||
*/
|
*/
|
||||||
static protected ICPPTemplateArgument[] deduceTemplateFunctionArguments(ICPPFunctionTemplate primaryTemplate,
|
static private ICPPTemplateArgument[] deduceTemplateFunctionArguments(ICPPFunctionTemplate template,
|
||||||
IASTParameterDeclaration[] ps, ICPPASTTemplateId id, CPPTemplateParameterMap map) throws DOMException {
|
ICPPTemplateArgument[] tmplArgs, IType[] fnArgs, CPPTemplateParameterMap map) throws DOMException {
|
||||||
ICPPTemplateParameter[] templateParameters = primaryTemplate.getTemplateParameters();
|
final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters();
|
||||||
ICPPTemplateArgument[] arguments= createTemplateArgumentArray(id);
|
final int length = tmplParams.length;
|
||||||
ICPPTemplateArgument[] result = new ICPPTemplateArgument[templateParameters.length];
|
if (tmplArgs.length > length)
|
||||||
|
return null;
|
||||||
|
|
||||||
arguments= SemanticUtil.getSimplifiedArguments(arguments);
|
ICPPTemplateArgument[] result = new ICPPTemplateArgument[length];
|
||||||
if (arguments.length == result.length) {
|
tmplArgs= SemanticUtil.getSimplifiedArguments(tmplArgs);
|
||||||
for (int i = 0; i < templateParameters.length; i++) {
|
for (int i = 0; i < tmplArgs.length; i++) {
|
||||||
result[i] = arguments[i];
|
ICPPTemplateArgument tmplArg= tmplArgs[i];
|
||||||
map.put(templateParameters[i], arguments[i]);
|
final ICPPTemplateParameter tmplParam= tmplParams[i];
|
||||||
|
tmplArg= matchTemplateParameterAndArgument(tmplParam, tmplArg, map);
|
||||||
|
if (tmplArg == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
map.put(tmplParam, tmplArg);
|
||||||
|
result[i]= tmplArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!deduceTemplateParameterMapFromFunctionParameters(template, fnArgs, map))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
if (result[i] == null) {
|
||||||
|
ICPPTemplateArgument deducedArg= map.getArgument(tmplParams[i]);
|
||||||
|
if (deducedArg == null)
|
||||||
|
return null;
|
||||||
|
result[i]= deducedArg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
//else need to deduce some arguments
|
|
||||||
IType[] paramTypes = createTypeArray(ps);
|
|
||||||
if (deduceTemplateParameterMapFromFunctionParameters(primaryTemplate, paramTypes, map)) {
|
|
||||||
for (int i = 0; i < templateParameters.length; i++) {
|
|
||||||
ICPPTemplateParameter param = templateParameters[i];
|
|
||||||
ICPPTemplateArgument arg = null;
|
|
||||||
if (i < arguments.length)
|
|
||||||
arg = arguments[i];
|
|
||||||
|
|
||||||
ICPPTemplateArgument deducedArg= map.getArgument(param);
|
|
||||||
if (deducedArg != null) {
|
|
||||||
if (arg == null) {
|
|
||||||
map.put(param, deducedArg);
|
|
||||||
arg = deducedArg;
|
|
||||||
} else if (!deducedArg.isSameValue(arg)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
arg= matchTemplateParameterAndArgument(param, arg, map);
|
|
||||||
if (arg == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
result[i] = arg;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ICPPTemplateInstance createInstance(IBinding owner, ICPPTemplateDefinition template,
|
public static ICPPTemplateInstance createInstance(IBinding owner, ICPPTemplateDefinition template,
|
||||||
CPPTemplateParameterMap tpMap, ICPPTemplateArgument[] args) {
|
CPPTemplateParameterMap tpMap, ICPPTemplateArgument[] args) {
|
||||||
if (owner instanceof ICPPSpecialization) {
|
if (owner instanceof ICPPSpecialization) {
|
||||||
|
@ -868,7 +641,16 @@ public class CPPTemplates {
|
||||||
public static IValue instantiateValue(IValue value, ICPPTemplateParameterMap tpMap) {
|
public static IValue instantiateValue(IValue value, ICPPTemplateParameterMap tpMap) {
|
||||||
if (value == null)
|
if (value == null)
|
||||||
return null;
|
return null;
|
||||||
// mstodo- instantiate values
|
// mstodo- instantiate values correctly
|
||||||
|
int parPos= Value.isTemplateParameter(value);
|
||||||
|
if (parPos > 0) {
|
||||||
|
ICPPTemplateArgument arg = tpMap.getArgument(parPos);
|
||||||
|
if (arg != null) {
|
||||||
|
IValue mappedValue = arg.getNonTypeValue();
|
||||||
|
if (mappedValue != null)
|
||||||
|
return mappedValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -938,11 +720,13 @@ public class CPPTemplates {
|
||||||
ICPPPointerToMemberType ptm = (ICPPPointerToMemberType) type;
|
ICPPPointerToMemberType ptm = (ICPPPointerToMemberType) type;
|
||||||
IType memberOfClass = ptm.getMemberOfClass();
|
IType memberOfClass = ptm.getMemberOfClass();
|
||||||
IType newMemberOfClass = instantiateType(memberOfClass, tpMap, within);
|
IType newMemberOfClass = instantiateType(memberOfClass, tpMap, within);
|
||||||
if ((newNestedType != nestedType || newMemberOfClass != memberOfClass) &&
|
if (newNestedType != nestedType || newMemberOfClass != memberOfClass) {
|
||||||
newMemberOfClass instanceof ICPPClassType) {
|
if (newMemberOfClass instanceof ICPPClassType) {
|
||||||
return new CPPPointerToMemberType(newNestedType, (ICPPClassType) newMemberOfClass,
|
return new CPPPointerToMemberType(newNestedType, (ICPPClassType) newMemberOfClass,
|
||||||
ptm.isConst(), ptm.isVolatile());
|
ptm.isConst(), ptm.isVolatile());
|
||||||
}
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (newNestedType != nestedType) {
|
if (newNestedType != nestedType) {
|
||||||
// bug 249085 make sure not to add unnecessary qualifications
|
// bug 249085 make sure not to add unnecessary qualifications
|
||||||
|
@ -1203,13 +987,9 @@ public class CPPTemplates {
|
||||||
ICPPClassTemplatePartialSpecialization spec = (ICPPClassTemplatePartialSpecialization) definition;
|
ICPPClassTemplatePartialSpecialization spec = (ICPPClassTemplatePartialSpecialization) definition;
|
||||||
ICPPTemplateArgument[] args= createTemplateArgumentArray((ICPPASTTemplateId)name);
|
ICPPTemplateArgument[] args= createTemplateArgumentArray((ICPPASTTemplateId)name);
|
||||||
ICPPTemplateArgument[] specArgs = spec.getTemplateArguments();
|
ICPPTemplateArgument[] specArgs = spec.getTemplateArguments();
|
||||||
if (args.length == specArgs.length) {
|
if (!areSameArguments(args, specArgs))
|
||||||
for (int i=0; i < args.length; i++) {
|
|
||||||
if (!specArgs[i].isSameValue(args[i]))
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1220,6 +1000,16 @@ public class CPPTemplates {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean areSameArguments(ICPPTemplateArgument[] args, ICPPTemplateArgument[] specArgs) {
|
||||||
|
if (args.length == specArgs.length) {
|
||||||
|
for (int i=0; i < args.length; i++) {
|
||||||
|
if (!specArgs[i].isSameValue(args[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param id the template id containing the template arguments
|
* @param id the template id containing the template arguments
|
||||||
* @return an array of template arguments, currently modeled as IType objects. The
|
* @return an array of template arguments, currently modeled as IType objects. The
|
||||||
|
@ -1285,64 +1075,33 @@ public class CPPTemplates {
|
||||||
if (templates == null || templates.size() == 0)
|
if (templates == null || templates.size() == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
IFunction[] instances = null;
|
ICPPTemplateArgument[] templateArguments = ICPPTemplateArgument.EMPTY_ARGUMENTS;
|
||||||
|
|
||||||
int size = templates.size();
|
|
||||||
|
|
||||||
int numTemplateArgs = 0;
|
|
||||||
ICPPTemplateArgument[] templateArguments = null;
|
|
||||||
if (name instanceof ICPPASTTemplateId) {
|
if (name instanceof ICPPASTTemplateId) {
|
||||||
try {
|
try {
|
||||||
templateArguments = createTemplateArgumentArray((ICPPASTTemplateId) name);
|
templateArguments = createTemplateArgumentArray((ICPPASTTemplateId) name);
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
return new IFunction[0];
|
return new IFunction[0];
|
||||||
}
|
}
|
||||||
numTemplateArgs = templateArguments.length;
|
|
||||||
}
|
}
|
||||||
|
final IType[] fnArgs= createTypeArray(functionArguments);
|
||||||
|
|
||||||
IType[] fnArgs= createTypeArray(functionArguments);
|
IFunction[] instances= null;
|
||||||
|
final int size = templates.size();
|
||||||
outer: for (int idx = 0; idx < size; idx++) {
|
for (int idx = 0; idx < size; idx++) {
|
||||||
ICPPFunctionTemplate template = (ICPPFunctionTemplate) templates.keyAt(idx);
|
ICPPFunctionTemplate template = (ICPPFunctionTemplate) templates.keyAt(idx);
|
||||||
|
|
||||||
CPPTemplateParameterMap map= new CPPTemplateParameterMap(fnArgs.length);
|
CPPTemplateParameterMap map= new CPPTemplateParameterMap(fnArgs.length);
|
||||||
try {
|
try {
|
||||||
if (!deduceTemplateParameterMapFromFunctionParameters(template, fnArgs, map))
|
ICPPTemplateArgument[] args= deduceTemplateFunctionArguments(template, templateArguments, fnArgs, map);
|
||||||
continue;
|
if (args != null) {
|
||||||
} catch (DOMException e) {
|
IBinding temp= instantiate(template, args);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ICPPTemplateParameter[] templateParams = null;
|
|
||||||
try {
|
|
||||||
templateParams = template.getTemplateParameters();
|
|
||||||
} catch (DOMException e1) {
|
|
||||||
continue outer;
|
|
||||||
}
|
|
||||||
int numTemplateParams = templateParams.length;
|
|
||||||
|
|
||||||
ICPPTemplateArgument[] instanceArgs = null;
|
|
||||||
for (int i = 0; i < numTemplateParams; i++) {
|
|
||||||
ICPPTemplateArgument arg = (i < numTemplateArgs && templateArguments != null) ? templateArguments[i] : null;
|
|
||||||
ICPPTemplateArgument mapped = map.getArgument(templateParams[i]);
|
|
||||||
|
|
||||||
if (arg != null && mapped != null) {
|
|
||||||
if (arg.isSameValue(mapped))
|
|
||||||
instanceArgs = (ICPPTemplateArgument[]) ArrayUtil.append(ICPPTemplateArgument.class, instanceArgs, arg);
|
|
||||||
else
|
|
||||||
continue outer;
|
|
||||||
} else if (arg == null && mapped == null) {
|
|
||||||
continue outer;
|
|
||||||
} else {
|
|
||||||
instanceArgs = (ICPPTemplateArgument[]) ArrayUtil.append(ICPPTemplateArgument.class, instanceArgs, (arg != null) ? arg : mapped);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
instanceArgs= (ICPPTemplateArgument[]) ArrayUtil.trim(ICPPTemplateArgument.class, instanceArgs);
|
|
||||||
IBinding temp= instantiate(template, instanceArgs);
|
|
||||||
if (temp instanceof IFunction) {
|
if (temp instanceof IFunction) {
|
||||||
instances = (IFunction[]) ArrayUtil.append(IFunction.class, instances, temp);
|
instances = (IFunction[]) ArrayUtil.append(IFunction.class, instances, temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (DOMException e) {
|
||||||
|
// try next candidate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (IFunction[]) ArrayUtil.trim(IFunction.class, instances);
|
return (IFunction[]) ArrayUtil.trim(IFunction.class, instances);
|
||||||
}
|
}
|
||||||
|
@ -1351,41 +1110,36 @@ public class CPPTemplates {
|
||||||
* Deduces the mapping for the template parameters from the function parameters,
|
* Deduces the mapping for the template parameters from the function parameters,
|
||||||
* returns <code>false</code> if there is no mapping.
|
* returns <code>false</code> if there is no mapping.
|
||||||
*/
|
*/
|
||||||
private static boolean deduceTemplateParameterMapFromFunctionParameters(ICPPFunctionTemplate template, IType[] arguments, CPPTemplateParameterMap map) throws DOMException{
|
private static boolean deduceTemplateParameterMapFromFunctionParameters(ICPPFunctionTemplate template, IType[] fnArgs, CPPTemplateParameterMap map) throws DOMException{
|
||||||
ICPPFunction function = (ICPPFunction) template;
|
ICPPFunction function = (ICPPFunction) template;
|
||||||
IType[] functionParameters = null;
|
|
||||||
try {
|
try {
|
||||||
functionParameters = function.getType().getParameterTypes();
|
IType[] fnPars = function.getType().getParameterTypes();
|
||||||
return deduceTemplateParameterMap(functionParameters, arguments, false, map);
|
int len= Math.min(fnPars.length, fnArgs.length);
|
||||||
|
for (int j= 0; j < len; j++) {
|
||||||
|
IType par= fnPars[j];
|
||||||
|
par= instantiateType(par, map, null);
|
||||||
|
if (!isValidType(par))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
par= SemanticUtil.adjustParameterType(par);
|
||||||
|
if (isDependentType(par) && !deduceTemplateParameterMap(par, fnArgs[j], map)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Deduces the template parameter mapping from pairs of types.
|
|
||||||
*/
|
|
||||||
public static boolean deduceTemplateParameterMap(final IType[] specArgs, final IType[] args, final boolean all, CPPTemplateParameterMap map) throws DOMException {
|
|
||||||
if (specArgs == null || (all && specArgs.length != args.length)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
int len= all ? specArgs.length : Math.min(specArgs.length, args.length);
|
|
||||||
for (int j= 0; j < len; j++) {
|
|
||||||
if (!deduceTemplateParameterMap(specArgs[j], args[j], map)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deduces the template parameter mapping from pairs of template arguments.
|
* Deduces the template parameter mapping from pairs of template arguments.
|
||||||
*/
|
*/
|
||||||
public static boolean deduceTemplateParameterMap(final ICPPTemplateArgument[] p, final ICPPTemplateArgument[] a, final boolean all, CPPTemplateParameterMap map) throws DOMException {
|
public static boolean deduceTemplateParameterMap(final ICPPTemplateArgument[] p, final ICPPTemplateArgument[] a, CPPTemplateParameterMap map) throws DOMException {
|
||||||
if (p == null || (all && p.length != a.length)) {
|
final int len= a.length;
|
||||||
|
if (p == null || p.length != len) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int len= Math.min(p.length, a.length);
|
|
||||||
for (int j=0; j<len; j++) {
|
for (int j=0; j<len; j++) {
|
||||||
if (!deduceTemplateParameterMap(p[j], a[j], map)) {
|
if (!deduceTemplateParameterMap(p[j], a[j], map)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1691,7 +1445,7 @@ public class CPPTemplates {
|
||||||
boolean bestMatchIsBest = true;
|
boolean bestMatchIsBest = true;
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
spec = specializations[i];
|
spec = specializations[i];
|
||||||
if (deduceTemplateParameterMap(spec.getTemplateArguments(), args, true, new CPPTemplateParameterMap(args.length))) {
|
if (deduceTemplateParameterMap(spec.getTemplateArguments(), args, new CPPTemplateParameterMap(args.length))) {
|
||||||
int compare = orderSpecializations(bestMatch, spec);
|
int compare = orderSpecializations(bestMatch, spec);
|
||||||
if (compare == 0) {
|
if (compare == 0) {
|
||||||
bestMatchIsBest = false;
|
bestMatchIsBest = false;
|
||||||
|
@ -1781,14 +1535,12 @@ public class CPPTemplates {
|
||||||
*/
|
*/
|
||||||
static private ICPPFunctionTemplate classTemplateSpecializationToFunctionTemplate(ICPPClassTemplatePartialSpecialization specialization) {
|
static private ICPPFunctionTemplate classTemplateSpecializationToFunctionTemplate(ICPPClassTemplatePartialSpecialization specialization) {
|
||||||
try {
|
try {
|
||||||
ICPPTemplateDefinition template = specialization;
|
// ICPPTemplateArgument[] args= specialization.getTemplateArguments();
|
||||||
ICPPTemplateArgument[] args= specialization.getTemplateArguments();
|
IBinding paramType = instantiateWithinClassTemplate(specialization);
|
||||||
|
if (!(paramType instanceof IType))
|
||||||
IType paramType = (IType) instantiate(template, args);
|
|
||||||
if (paramType == null)
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
IParameter[] functionParameters = new IParameter[] { new CPPParameter(paramType) };
|
IParameter[] functionParameters = new IParameter[] { new CPPParameter((IType) paramType) };
|
||||||
|
|
||||||
return new CPPImplicitFunctionTemplate(specialization.getTemplateParameters(), functionParameters);
|
return new CPPImplicitFunctionTemplate(specialization.getTemplateParameters(), functionParameters);
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
|
@ -1796,8 +1548,7 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static private boolean isValidArgument(ICPPTemplateParameter param, ICPPTemplateArgument argument) {
|
static private boolean isValidType(IType t) {
|
||||||
IType t= argument.getTypeValue();
|
|
||||||
try {
|
try {
|
||||||
while (t instanceof ITypeContainer) {
|
while (t instanceof ITypeContainer) {
|
||||||
t = ((ITypeContainer) t).getType();
|
t = ((ITypeContainer) t).getType();
|
||||||
|
@ -1810,7 +1561,7 @@ public class CPPTemplates {
|
||||||
|
|
||||||
static protected ICPPTemplateArgument matchTemplateParameterAndArgument(ICPPTemplateParameter param,
|
static protected ICPPTemplateArgument matchTemplateParameterAndArgument(ICPPTemplateParameter param,
|
||||||
ICPPTemplateArgument arg, CPPTemplateParameterMap map) {
|
ICPPTemplateArgument arg, CPPTemplateParameterMap map) {
|
||||||
if (arg == null || !isValidArgument(param, arg)) {
|
if (arg == null || !isValidType(arg.getTypeValue())) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (param instanceof ICPPTemplateTypeParameter) {
|
if (param instanceof ICPPTemplateTypeParameter) {
|
||||||
|
@ -1904,7 +1655,7 @@ public class CPPTemplates {
|
||||||
return cost != null && cost.rank != Cost.NO_MATCH_RANK;
|
return cost != null && cost.rank != Cost.NO_MATCH_RANK;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean argsAreTrivial(ICPPTemplateParameter[] pars, ICPPTemplateArgument[] args) {
|
static boolean argsAreTrivial(ICPPTemplateParameter[] pars, ICPPTemplateArgument[] args) {
|
||||||
if (pars.length != args.length) {
|
if (pars.length != args.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1940,11 +1691,33 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isDependentType(IType t) {
|
public static boolean isDependentType(IType t) {
|
||||||
// mstodo needs to be extended
|
try {
|
||||||
if (t instanceof ICPPTemplateParameter)
|
while (true) {
|
||||||
|
if (t instanceof ICPPTemplateParameter || t instanceof ICPPUnknownBinding)
|
||||||
return true;
|
return true;
|
||||||
t = SemanticUtil.getUltimateType(t, false);
|
if (t instanceof ICPPFunctionType) {
|
||||||
return t instanceof ICPPUnknownBinding;
|
final ICPPFunctionType ft = (ICPPFunctionType) t;
|
||||||
|
IType[] types= ft.getParameterTypes();
|
||||||
|
for (IType type : types) {
|
||||||
|
if (isDependentType(type))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
t= ft.getReturnType();
|
||||||
|
} else if (t instanceof ICPPPointerToMemberType) {
|
||||||
|
ICPPPointerToMemberType ptmt= (ICPPPointerToMemberType) t;
|
||||||
|
if (isDependentType(ptmt.getMemberOfClass()))
|
||||||
|
return true;
|
||||||
|
t= ptmt.getType();
|
||||||
|
} else if (t instanceof ITypeContainer) {
|
||||||
|
t= ((ITypeContainer) t).getType();
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (DOMException e) {
|
||||||
|
// treat as non-dependent
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean containsDependentArg(ObjectMap tpMap) {
|
public static boolean containsDependentArg(ObjectMap tpMap) {
|
||||||
|
|
|
@ -93,6 +93,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
|
||||||
|
@ -120,6 +121,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
|
||||||
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.ICPPConstructor;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
|
@ -131,6 +133,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
|
||||||
|
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;
|
||||||
|
@ -176,6 +180,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariable;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPBasicType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPBasicType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPPointerToMemberType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPPointerToMemberType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPPointerType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPPointerType;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
||||||
|
@ -190,9 +195,6 @@ public class CPPVisitor extends ASTQueries {
|
||||||
public static final String STD = "std"; //$NON-NLS-1$
|
public static final String STD = "std"; //$NON-NLS-1$
|
||||||
public static final String TYPE_INFO= "type_info"; //$NON-NLS-1$
|
public static final String TYPE_INFO= "type_info"; //$NON-NLS-1$
|
||||||
|
|
||||||
/**
|
|
||||||
* @param name
|
|
||||||
*/
|
|
||||||
public static IBinding createBinding(IASTName name) {
|
public static IBinding createBinding(IASTName name) {
|
||||||
IASTNode parent = name.getParent();
|
IASTNode parent = name.getParent();
|
||||||
IBinding binding = null;
|
IBinding binding = null;
|
||||||
|
@ -200,8 +202,7 @@ public class CPPVisitor extends ASTQueries {
|
||||||
parent instanceof ICPPASTQualifiedName ||
|
parent instanceof ICPPASTQualifiedName ||
|
||||||
parent instanceof ICPPASTBaseSpecifier ||
|
parent instanceof ICPPASTBaseSpecifier ||
|
||||||
parent instanceof ICPPASTConstructorChainInitializer ||
|
parent instanceof ICPPASTConstructorChainInitializer ||
|
||||||
name.getPropertyInParent() == ICPPASTNamespaceAlias.MAPPING_NAME ||
|
name.getPropertyInParent() == ICPPASTNamespaceAlias.MAPPING_NAME) {
|
||||||
parent instanceof ICPPASTTemplateId) {
|
|
||||||
binding = CPPSemantics.resolveBinding(name);
|
binding = CPPSemantics.resolveBinding(name);
|
||||||
if (binding instanceof IProblemBinding && parent instanceof ICPPASTQualifiedName &&
|
if (binding instanceof IProblemBinding && parent instanceof ICPPASTQualifiedName &&
|
||||||
!(parent.getParent() instanceof ICPPASTNamespaceAlias)) {
|
!(parent.getParent() instanceof ICPPASTNamespaceAlias)) {
|
||||||
|
@ -225,6 +226,14 @@ public class CPPVisitor extends ASTQueries {
|
||||||
} else {
|
} else {
|
||||||
return binding;
|
return binding;
|
||||||
}
|
}
|
||||||
|
} else if (parent instanceof ICPPASTTemplateId) {
|
||||||
|
final ICPPASTTemplateId id = (ICPPASTTemplateId) parent;
|
||||||
|
if (CPPTemplates.isClassTemplate(id))
|
||||||
|
return CPPSemantics.resolveBinding(name);
|
||||||
|
|
||||||
|
// function templates/instances/specializations must be resolved via the id
|
||||||
|
id.resolveBinding();
|
||||||
|
return name.getBinding();
|
||||||
}
|
}
|
||||||
if (parent instanceof IASTIdExpression) {
|
if (parent instanceof IASTIdExpression) {
|
||||||
return resolveBinding(parent);
|
return resolveBinding(parent);
|
||||||
|
@ -425,7 +434,7 @@ public class CPPVisitor extends ASTQueries {
|
||||||
scope= (ICPPScope) scope.getParent();
|
scope= (ICPPScope) scope.getParent();
|
||||||
}
|
}
|
||||||
if (name instanceof ICPPASTTemplateId) {
|
if (name instanceof ICPPASTTemplateId) {
|
||||||
return CPPTemplates.createExplicitClassSpecialization(compType);
|
return CPPTemplates.createBinding((ICPPASTTemplateId) name);
|
||||||
}
|
}
|
||||||
if (name.toCharArray().length > 0 && scope != null) //can't lookup anonymous things
|
if (name.toCharArray().length > 0 && scope != null) //can't lookup anonymous things
|
||||||
binding = scope.getBinding(name, false);
|
binding = scope.getBinding(name, false);
|
||||||
|
@ -522,24 +531,36 @@ public class CPPVisitor extends ASTQueries {
|
||||||
return candidate;
|
return candidate;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTNodeProperty prop = parent.getPropertyInParent();
|
// function type
|
||||||
if (parent instanceof IASTTypeId) {
|
if (parent instanceof IASTTypeId)
|
||||||
return CPPSemantics.resolveBinding(name);
|
return CPPSemantics.resolveBinding(name);
|
||||||
} else if (prop == ICPPASTTemplateSpecialization.OWNED_DECLARATION ||
|
|
||||||
prop == ICPPASTExplicitTemplateInstantiation.OWNED_DECLARATION) {
|
// explicit instantiations
|
||||||
try {
|
ASTNodeProperty prop = parent.getPropertyInParent();
|
||||||
return CPPTemplates.createFunctionSpecialization(name);
|
if (prop == ICPPASTExplicitTemplateInstantiation.OWNED_DECLARATION)
|
||||||
} catch (DOMException e) {
|
return CPPSemantics.resolveBinding(name);
|
||||||
return e.getProblem();
|
|
||||||
|
// explicit specializations
|
||||||
|
if (prop == ICPPASTTemplateSpecialization.OWNED_DECLARATION) {
|
||||||
|
IBinding b= CPPSemantics.resolveBinding(name);
|
||||||
|
if (b instanceof ICPPInternalBinding) {
|
||||||
|
if (parent instanceof ICPPASTFunctionDefinition)
|
||||||
|
((ICPPInternalBinding) b).addDefinition(name);
|
||||||
|
else
|
||||||
|
((ICPPInternalBinding) b).addDeclaration(name);
|
||||||
}
|
}
|
||||||
} else if (prop == ICPPASTTemplateDeclaration.PARAMETER) {
|
return b;
|
||||||
|
}
|
||||||
|
// function type for non-type template parameter
|
||||||
|
if (prop == ICPPASTTemplateDeclaration.PARAMETER) {
|
||||||
return CPPTemplates.createBinding((ICPPASTTemplateParameter) parent);
|
return CPPTemplates.createBinding((ICPPASTTemplateParameter) parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// function declaration/defintion
|
||||||
IBinding binding;
|
IBinding binding;
|
||||||
ICPPScope scope = (ICPPScope) getContainingScope((IASTNode) name);
|
ICPPScope scope = (ICPPScope) getContainingScope((IASTNode) name);
|
||||||
|
|
||||||
boolean template= false;
|
boolean template= false;
|
||||||
|
boolean isFriendDecl= false;
|
||||||
try {
|
try {
|
||||||
while (scope instanceof ICPPTemplateScope) {
|
while (scope instanceof ICPPTemplateScope) {
|
||||||
template = true;
|
template = true;
|
||||||
|
@ -550,11 +571,13 @@ public class CPPVisitor extends ASTQueries {
|
||||||
if (declSpec.isFriend()) {
|
if (declSpec.isFriend()) {
|
||||||
try {
|
try {
|
||||||
scope = (ICPPScope) getParentScope(scope, name.getTranslationUnit());
|
scope = (ICPPScope) getParentScope(scope, name.getTranslationUnit());
|
||||||
|
isFriendDecl= true;
|
||||||
} catch (DOMException e1) {
|
} catch (DOMException e1) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
binding = (scope != null) ? scope.getBinding(name, false) : null;
|
boolean forceResolve= isFriendDecl && name instanceof ICPPASTTemplateId;
|
||||||
|
binding = (scope != null) ? scope.getBinding(name, forceResolve) : null;
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
return e.getProblem();
|
return e.getProblem();
|
||||||
}
|
}
|
||||||
|
@ -866,6 +889,20 @@ public class CPPVisitor extends ASTQueries {
|
||||||
inputNode.getRawSignature().toCharArray());
|
inputNode.getRawSignature().toCharArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for an enclosing function definition or declaration, returns
|
||||||
|
* the name of the function. If you pass the name of a function, it will be returned.
|
||||||
|
*/
|
||||||
|
public static ICPPASTFunctionDefinition findEnclosingFunctionDefinition(IASTNode node) {
|
||||||
|
while (node != null) {
|
||||||
|
if (node instanceof ICPPASTFunctionDefinition) {
|
||||||
|
return (ICPPASTFunctionDefinition) node;
|
||||||
|
}
|
||||||
|
node= node.getParent();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static IScope getContainingScope(IASTName name) {
|
public static IScope getContainingScope(IASTName name) {
|
||||||
IScope scope= getContainingScopeOrNull(name);
|
IScope scope= getContainingScopeOrNull(name);
|
||||||
if (scope == null) {
|
if (scope == null) {
|
||||||
|
@ -910,6 +947,10 @@ public class CPPVisitor extends ASTQueries {
|
||||||
boolean done= true;
|
boolean done= true;
|
||||||
IScope scope= null;
|
IScope scope= null;
|
||||||
if (binding instanceof ICPPClassType) {
|
if (binding instanceof ICPPClassType) {
|
||||||
|
if (binding instanceof ICPPDeferredClassInstance) {
|
||||||
|
scope= checkForSpecializedScope((ICPPDeferredClassInstance) binding, qname);
|
||||||
|
}
|
||||||
|
if (scope == null)
|
||||||
scope= ((ICPPClassType)binding).getCompositeScope();
|
scope= ((ICPPClassType)binding).getCompositeScope();
|
||||||
} else if (binding instanceof ICPPNamespace) {
|
} else if (binding instanceof ICPPNamespace) {
|
||||||
scope= ((ICPPNamespace)binding).getNamespaceScope();
|
scope= ((ICPPNamespace)binding).getNamespaceScope();
|
||||||
|
@ -956,6 +997,47 @@ public class CPPVisitor extends ASTQueries {
|
||||||
return getContainingScope(parent);
|
return getContainingScope(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the scope for a deferred instance should be a specialized variant of
|
||||||
|
* the class-template.
|
||||||
|
*/
|
||||||
|
private static IScope checkForSpecializedScope(ICPPDeferredClassInstance dcli, final ICPPASTQualifiedName qname)
|
||||||
|
throws DOMException {
|
||||||
|
ICPPClassTemplate ct = dcli.getClassTemplate();
|
||||||
|
ICPPTemplateArgument[] args = dcli.getTemplateArguments();
|
||||||
|
IASTName start= qname;
|
||||||
|
ICPPASTFunctionDefinition func= findEnclosingFunctionDefinition(qname);
|
||||||
|
if (func != null) {
|
||||||
|
start= findInnermostDeclarator(func.getDeclarator()).getName();
|
||||||
|
if (start == qname)
|
||||||
|
return null;
|
||||||
|
start= start.getLastName();
|
||||||
|
}
|
||||||
|
IScope lookupScope= getContainingNonTemplateScope(start);
|
||||||
|
while (lookupScope != null) {
|
||||||
|
if (lookupScope instanceof ICPPClassScope) {
|
||||||
|
ICPPClassScope clscope= (ICPPClassScope) lookupScope;
|
||||||
|
ICPPClassType ctype = clscope.getClassType();
|
||||||
|
if (ctype instanceof ICPPClassTemplatePartialSpecialization) {
|
||||||
|
ICPPTemplateArgument[] args1 = ((ICPPClassTemplatePartialSpecialization) ctype).getTemplateArguments();
|
||||||
|
if (CPPTemplates.areSameArguments(args, args1))
|
||||||
|
return lookupScope;
|
||||||
|
} else if (ctype instanceof ICPPTemplateInstance) {
|
||||||
|
ICPPTemplateArgument[] args1 = ((ICPPTemplateInstance) ctype).getTemplateArguments();
|
||||||
|
if (CPPTemplates.areSameArguments(args, args1))
|
||||||
|
return lookupScope;
|
||||||
|
} else if (ctype instanceof ICPPClassTemplate) {
|
||||||
|
if (ct.isSameType(ctype) &&
|
||||||
|
CPPTemplates.argsAreTrivial(ct.getTemplateParameters(), args)) {
|
||||||
|
return lookupScope;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lookupScope= lookupScope.getParent();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static IScope getContainingScope(IASTStatement statement) {
|
public static IScope getContainingScope(IASTStatement statement) {
|
||||||
IASTNode parent = statement.getParent();
|
IASTNode parent = statement.getParent();
|
||||||
IScope scope = null;
|
IScope scope = null;
|
||||||
|
@ -1495,36 +1577,7 @@ public class CPPVisitor extends ASTQueries {
|
||||||
pt = createType(pDeclSpec);
|
pt = createType(pDeclSpec);
|
||||||
pt = createType(pt, pDtor);
|
pt = createType(pt, pDtor);
|
||||||
|
|
||||||
// bug 239975
|
pt = SemanticUtil.adjustParameterType(pt);
|
||||||
IType noTypedef= SemanticUtil.getUltimateTypeViaTypedefs(pt);
|
|
||||||
|
|
||||||
//8.3.5-3
|
|
||||||
//Any cv-qualifier modifying a parameter type is deleted.
|
|
||||||
//so only create the base type from the declspec and not the qualifiers
|
|
||||||
try {
|
|
||||||
if (noTypedef instanceof IQualifierType) {
|
|
||||||
pt= ((IQualifierType) noTypedef).getType();
|
|
||||||
noTypedef= SemanticUtil.getUltimateTypeViaTypedefs(pt);
|
|
||||||
}
|
|
||||||
if (noTypedef instanceof CPPPointerType) {
|
|
||||||
pt= ((CPPPointerType) noTypedef).stripQualifiers();
|
|
||||||
noTypedef= SemanticUtil.getUltimateTypeViaTypedefs(pt);
|
|
||||||
}
|
|
||||||
//any parameter of type array of T is adjusted to be pointer to T
|
|
||||||
if (noTypedef instanceof IArrayType) {
|
|
||||||
IArrayType at = (IArrayType) noTypedef;
|
|
||||||
pt = new CPPPointerType(at.getType());
|
|
||||||
noTypedef= SemanticUtil.getUltimateTypeViaTypedefs(pt);
|
|
||||||
}
|
|
||||||
} catch (DOMException e) {
|
|
||||||
pt = e.getProblem();
|
|
||||||
}
|
|
||||||
|
|
||||||
//any parameter to type function returning T is adjusted to be pointer to function
|
|
||||||
if (noTypedef instanceof IFunctionType) {
|
|
||||||
pt = new CPPPointerType(pt);
|
|
||||||
}
|
|
||||||
|
|
||||||
pTypes[i] = pt;
|
pTypes[i] = pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
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.ICPPASTTemplateDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
||||||
|
@ -160,7 +161,7 @@ class LookupData {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean forDefinition() {
|
public boolean forFunctionDeclaration() {
|
||||||
if (astName == null) return false;
|
if (astName == null) return false;
|
||||||
if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false;
|
if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false;
|
||||||
|
|
||||||
|
@ -169,19 +170,28 @@ class LookupData {
|
||||||
n = (IASTName) n.getParent();
|
n = (IASTName) n.getParent();
|
||||||
IASTNode p1 = n.getParent();
|
IASTNode p1 = n.getParent();
|
||||||
if (p1 instanceof ICPPASTQualifiedName) {
|
if (p1 instanceof ICPPASTQualifiedName) {
|
||||||
IASTName[] ns = ((ICPPASTQualifiedName)p1).getNames();
|
if (((ICPPASTQualifiedName) p1).getLastName() != n)
|
||||||
if (ns[ns.length - 1] != n)
|
|
||||||
return false;
|
return false;
|
||||||
p1 = p1.getParent();
|
p1 = p1.getParent();
|
||||||
}
|
}
|
||||||
IASTNode p2 = p1.getParent();
|
|
||||||
if (p1 instanceof IASTDeclarator && p2 instanceof IASTSimpleDeclaration) {
|
if (p1 instanceof IASTDeclarator) {
|
||||||
return !(p2.getParent() instanceof ICPPASTExplicitTemplateInstantiation);
|
IASTNode p2= CPPVisitor.findOutermostDeclarator((IASTDeclarator) p1).getParent();
|
||||||
|
if (p2 instanceof IASTSimpleDeclaration) {
|
||||||
|
if (p2.getParent() instanceof ICPPASTExplicitTemplateInstantiation)
|
||||||
|
return false;
|
||||||
|
if (astName instanceof ICPPASTTemplateId &&
|
||||||
|
((ICPPASTDeclSpecifier)((IASTSimpleDeclaration)p2).getDeclSpecifier()).isFriend())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return (p1 instanceof IASTDeclarator && p2 instanceof IASTFunctionDefinition);
|
return p2 instanceof IASTFunctionDefinition;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean forExplicitInstantiation() {
|
public boolean forExplicitFunctionSpecialization() {
|
||||||
if (astName == null) return false;
|
if (astName == null) return false;
|
||||||
if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false;
|
if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false;
|
||||||
|
|
||||||
|
@ -190,14 +200,39 @@ class LookupData {
|
||||||
n = (IASTName) n.getParent();
|
n = (IASTName) n.getParent();
|
||||||
IASTNode p1 = n.getParent();
|
IASTNode p1 = n.getParent();
|
||||||
if (p1 instanceof ICPPASTQualifiedName) {
|
if (p1 instanceof ICPPASTQualifiedName) {
|
||||||
IASTName[] ns = ((ICPPASTQualifiedName)p1).getNames();
|
if (((ICPPASTQualifiedName) p1).getLastName() != n)
|
||||||
if (ns[ns.length - 1] != n)
|
|
||||||
return false;
|
return false;
|
||||||
p1 = p1.getParent();
|
p1 = p1.getParent();
|
||||||
}
|
}
|
||||||
IASTNode p2 = p1.getParent();
|
|
||||||
if (p1 instanceof IASTDeclarator && p2 instanceof IASTSimpleDeclaration) {
|
if (p1 instanceof IASTDeclarator) {
|
||||||
return (p2.getParent() instanceof ICPPASTExplicitTemplateInstantiation);
|
IASTNode p2= CPPVisitor.findOutermostDeclarator((IASTDeclarator) p1).getParent();
|
||||||
|
if (p2 instanceof IASTSimpleDeclaration || p2 instanceof IASTFunctionDefinition) {
|
||||||
|
return p2.getParent() instanceof ICPPASTTemplateSpecialization;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean forExplicitFunctionInstantiation() {
|
||||||
|
if (astName == null) return false;
|
||||||
|
if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false;
|
||||||
|
|
||||||
|
IASTName n = astName;
|
||||||
|
if (n.getParent() instanceof ICPPASTTemplateId)
|
||||||
|
n = (IASTName) n.getParent();
|
||||||
|
IASTNode p1 = n.getParent();
|
||||||
|
if (p1 instanceof ICPPASTQualifiedName) {
|
||||||
|
if (((ICPPASTQualifiedName) p1).getLastName() != n)
|
||||||
|
return false;
|
||||||
|
p1 = p1.getParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p1 instanceof IASTDeclarator) {
|
||||||
|
IASTNode p2= CPPVisitor.findOutermostDeclarator((IASTDeclarator) p1).getParent();
|
||||||
|
if (p2 instanceof IASTDeclaration) {
|
||||||
|
return p2.getParent() instanceof ICPPASTExplicitTemplateInstantiation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -351,6 +386,14 @@ class LookupData {
|
||||||
}
|
}
|
||||||
return implied;
|
return implied;
|
||||||
}
|
}
|
||||||
|
if (prop == IASTDeclarator.DECLARATOR_NAME) {
|
||||||
|
if (forExplicitFunctionInstantiation()) {
|
||||||
|
IScope scope = CPPVisitor.getContainingScope(astName);
|
||||||
|
if (scope instanceof ICPPClassScope) {
|
||||||
|
return ((ICPPClassScope)scope).getClassType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
return e.getProblem();
|
return e.getProblem();
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||||
|
@ -35,6 +36,7 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
|
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
|
||||||
|
@ -322,4 +324,41 @@ public class SemanticUtil {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts the parameter type according to 8.3.5-3:
|
||||||
|
* cv-qualifiers are deleted, arrays and function types are converted to pointers.
|
||||||
|
*/
|
||||||
|
public static IType adjustParameterType(IType pt) {
|
||||||
|
// bug 239975
|
||||||
|
IType noTypedef= SemanticUtil.getUltimateTypeViaTypedefs(pt);
|
||||||
|
|
||||||
|
//8.3.5-3
|
||||||
|
//Any cv-qualifier modifying a parameter type is deleted.
|
||||||
|
//so only create the base type from the declspec and not the qualifiers
|
||||||
|
try {
|
||||||
|
if (noTypedef instanceof IQualifierType) {
|
||||||
|
pt= ((IQualifierType) noTypedef).getType();
|
||||||
|
noTypedef= SemanticUtil.getUltimateTypeViaTypedefs(pt);
|
||||||
|
}
|
||||||
|
if (noTypedef instanceof CPPPointerType) {
|
||||||
|
pt= ((CPPPointerType) noTypedef).stripQualifiers();
|
||||||
|
noTypedef= SemanticUtil.getUltimateTypeViaTypedefs(pt);
|
||||||
|
}
|
||||||
|
//any parameter of type array of T is adjusted to be pointer to T
|
||||||
|
if (noTypedef instanceof IArrayType) {
|
||||||
|
IArrayType at = (IArrayType) noTypedef;
|
||||||
|
pt = new CPPPointerType(at.getType());
|
||||||
|
noTypedef= SemanticUtil.getUltimateTypeViaTypedefs(pt);
|
||||||
|
}
|
||||||
|
} catch (DOMException e) {
|
||||||
|
pt = e.getProblem();
|
||||||
|
}
|
||||||
|
|
||||||
|
//any parameter to type function returning T is adjusted to be pointer to function
|
||||||
|
if (noTypedef instanceof IFunctionType) {
|
||||||
|
pt = new CPPPointerType(pt);
|
||||||
|
}
|
||||||
|
return pt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IEnumeration;
|
import org.eclipse.cdt.core.dom.ast.IEnumeration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
||||||
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.ICPPDeferredTemplateInstance;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeferredTemplateInstance;
|
||||||
|
@ -240,7 +241,10 @@ abstract public class PDOMWriter {
|
||||||
Throwable th= null;
|
Throwable th= null;
|
||||||
try {
|
try {
|
||||||
final IBinding binding = name.resolveBinding();
|
final IBinding binding = name.resolveBinding();
|
||||||
if (binding instanceof IProblemBinding) {
|
if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME &&
|
||||||
|
((IASTName) name.getParent()).getBinding() == binding) {
|
||||||
|
na[0]= null;
|
||||||
|
} else if (binding instanceof IProblemBinding) {
|
||||||
fStatistics.fProblemBindingCount++;
|
fStatistics.fProblemBindingCount++;
|
||||||
if (fShowProblems) {
|
if (fShowProblems) {
|
||||||
reportProblem((IProblemBinding) binding);
|
reportProblem((IProblemBinding) binding);
|
||||||
|
|
|
@ -31,6 +31,7 @@ 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.ICPPTemplateTemplateParameter;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
|
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
|
||||||
|
@ -243,7 +244,17 @@ public class PDOMCPPClassTemplate extends PDOMCPPClassType
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + PARAMETERS, getLinkageImpl());
|
PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + PARAMETERS, getLinkageImpl());
|
||||||
return (ICPPTemplateParameter) list.getNodeAt(pos);
|
ICPPTemplateParameter result= (ICPPTemplateParameter) list.getNodeAt(pos);
|
||||||
|
if (param instanceof ICPPTemplateTypeParameter) {
|
||||||
|
if (result instanceof ICPPTemplateTypeParameter)
|
||||||
|
return result;
|
||||||
|
} else if (param instanceof ICPPTemplateNonTypeParameter) {
|
||||||
|
if (result instanceof ICPPTemplateNonTypeParameter)
|
||||||
|
return result;
|
||||||
|
} else if (param instanceof ICPPTemplateTemplateParameter) {
|
||||||
|
if (result instanceof ICPPTemplateTemplateParameter)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
} catch (CoreException e) {
|
} catch (CoreException e) {
|
||||||
CCorePlugin.log(e);
|
CCorePlugin.log(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,10 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
|
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.ICPPTemplateParameter;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
|
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
|
||||||
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
||||||
|
@ -131,7 +134,17 @@ class PDOMCPPFunctionTemplate extends PDOMCPPFunction
|
||||||
int pos = param.getParameterPosition();
|
int pos = param.getParameterPosition();
|
||||||
try {
|
try {
|
||||||
PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + TEMPLATE_PARAMS, getLinkageImpl());
|
PDOMNodeLinkedList list = new PDOMNodeLinkedList(pdom, record + TEMPLATE_PARAMS, getLinkageImpl());
|
||||||
return (ICPPTemplateParameter) list.getNodeAt(pos);
|
ICPPTemplateParameter result= (ICPPTemplateParameter) list.getNodeAt(pos);
|
||||||
|
if (param instanceof ICPPTemplateTypeParameter) {
|
||||||
|
if (result instanceof ICPPTemplateTypeParameter)
|
||||||
|
return result;
|
||||||
|
} else if (param instanceof ICPPTemplateNonTypeParameter) {
|
||||||
|
if (result instanceof ICPPTemplateNonTypeParameter)
|
||||||
|
return result;
|
||||||
|
} else if (param instanceof ICPPTemplateTemplateParameter) {
|
||||||
|
if (result instanceof ICPPTemplateTemplateParameter)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
} catch (CoreException e) {
|
} catch (CoreException e) {
|
||||||
CCorePlugin.log(e);
|
CCorePlugin.log(e);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue