mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 08:55:25 +02:00
Bug 326900: Update for template argument deduction.
This commit is contained in:
parent
1fff26625d
commit
a0add23230
17 changed files with 493 additions and 267 deletions
|
@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTProblemDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
|
@ -35,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
|
||||
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.ICPPSpecialization;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
|
||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
||||
|
@ -4246,7 +4248,8 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// b.f(); //Calls X::f()
|
||||
// }
|
||||
public void test13_3_3_2s3b() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||
String[] problems= {"g"};
|
||||
parse(getAboveComment(), ParserLanguage.CPP, problems);
|
||||
}
|
||||
|
||||
// struct A {
|
||||
|
@ -4670,7 +4673,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// template<class P> friend class frd;
|
||||
// // ...
|
||||
// };
|
||||
public void test14_5_3s1() throws Exception {
|
||||
public void test14_5_4s1() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
|
||||
|
@ -4689,7 +4692,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// };
|
||||
// }
|
||||
// }
|
||||
public void test14_5_3s2() throws Exception {
|
||||
public void test14_5_4s2() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, false, 0);
|
||||
}
|
||||
|
||||
|
@ -4697,7 +4700,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// template<class T> friend class B; // OK
|
||||
// template<class T> friend void f(T){ } // OK
|
||||
// };
|
||||
public void test14_5_3s3() throws Exception {
|
||||
public void test14_5_4s3() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
|
||||
|
@ -4707,7 +4710,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// };
|
||||
// template<class T> struct A { X::Y ab; }; // OK
|
||||
// template<class T> struct A<T*> { X::Y ab; }; // OK
|
||||
public void test14_5_3s4() throws Exception {
|
||||
public void test14_5_4s4() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
|
||||
|
@ -4719,7 +4722,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// template<class T> friend struct A<T>::B;
|
||||
// template<class T> friend void A<T>::f();
|
||||
// };
|
||||
public void test14_5_3s6() throws Exception {
|
||||
public void test14_5_4s6() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
|
||||
|
@ -4731,7 +4734,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// A<char>::B<int*> abcip; // uses #2
|
||||
// A<short>::B<int*> absip; // uses #3
|
||||
// A<char>::B<int> abci; // uses #1
|
||||
public void test14_5_4_3s2() throws Exception {
|
||||
public void test14_5_5_3s2() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
|
||||
|
@ -4740,13 +4743,13 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// template<class T1, class T2, int I> class A<T1*, T2, I> { }; // #3
|
||||
// template<class T> class A<int, T*, 5> { }; // #4
|
||||
// template<class T1, class T2, int I> class A<T1, T2*, I> { }; // #5
|
||||
public void test14_5_4s4() throws Exception {
|
||||
public void test14_5_5s4() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
|
||||
// template <int I, int J> struct B {};
|
||||
// template <int I> struct B<I, I> {}; // OK
|
||||
public void test14_5_4s9b() throws Exception {
|
||||
public void test14_5_5s9b() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
|
||||
|
@ -4759,7 +4762,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// A<int, int*, 1> a2; // uses #2, T is int, I is 1
|
||||
// A<int, char*, 5> a3; // uses #4, T is char
|
||||
// A<int, char*, 1> a4; // uses #5, T1 is int, T2 is char, I is 1
|
||||
public void test14_5_4_1s2a() throws Exception {
|
||||
public void test14_5_5_1s2a() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
|
||||
|
@ -4769,7 +4772,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// template<class T> class A<int, T*, 5> { }; // #4
|
||||
// template<class T1, class T2, int I> class A<T1, T2*, I> { }; // #5
|
||||
// A<int*, int*, 2> a5; // ambiguous: matches #3 and #5 : expect problem
|
||||
public void test14_5_4_1s2b() throws Exception {
|
||||
public void test14_5_5_1s2b() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, true, 1);
|
||||
}
|
||||
|
||||
|
@ -4778,7 +4781,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// template<int I> class X<I, I, int> { }; // #2
|
||||
// template<int I, int J> void f(X<I, J, int>); // #A
|
||||
// template<int I> void f(X<I, I, int>); // #B
|
||||
public void test14_5_4_2s2() throws Exception {
|
||||
public void test14_5_5_2s2() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
|
||||
|
@ -4809,13 +4812,13 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// a2.f(); //illformed, no definition of f for A<T,2>
|
||||
// // the primary template is not used here
|
||||
// }
|
||||
public void test14_5_4_3s1() throws Exception {
|
||||
public void test14_5_5_3s1() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, false, 0);
|
||||
}
|
||||
|
||||
// template<class T> class Array { };
|
||||
// template<class T> void sort(Array<T>&);
|
||||
public void test14_5_5s1() throws Exception {
|
||||
public void test14_5_6s1() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
|
||||
|
@ -4826,7 +4829,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// f(p); // call
|
||||
// // f<int>(int*)
|
||||
// }
|
||||
public void test14_5_5_1s1a() throws Exception {
|
||||
public void test14_5_6_1s1a() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
// // file2.c
|
||||
|
@ -4836,7 +4839,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// f(p); // call
|
||||
// // f<int*>(int*)
|
||||
// }
|
||||
public void test14_5_5_1s1b() throws Exception {
|
||||
public void test14_5_6_1s1b() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
|
||||
|
@ -4846,7 +4849,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// template <int I> void f/*2*/(A<I>, A<I+10>);
|
||||
// // Guaranteed to be different
|
||||
// template <int I> void f/*3*/(A<I>, A<I+11>);
|
||||
public void test14_5_5_1s8a() throws Exception {
|
||||
public void test14_5_6_1s8a() throws Exception {
|
||||
final String content= getAboveComment();
|
||||
IASTTranslationUnit tu= parse(content, ParserLanguage.CPP, true, 0);
|
||||
BindingAssertionHelper bh= new BindingAssertionHelper(content, true);
|
||||
|
@ -4860,11 +4863,33 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// // Illformed, no diagnostic required
|
||||
// template <int I> void f(A<I>, A<I+10>);
|
||||
// template <int I> void f(A<I>, A<I+1+2+3+4>);
|
||||
public void test14_5_5_1s8b() throws Exception {
|
||||
public void test14_5_6_1s8b() throws Exception {
|
||||
//test is only for syntax, semantics are not checked here.
|
||||
parse(getAboveComment(), ParserLanguage.CPP, false, 0);
|
||||
}
|
||||
|
||||
// struct A { };
|
||||
// template<class T> struct B {
|
||||
// template<class R> int operator*(R&); // #1
|
||||
// };
|
||||
// template<class T, class R> int operator*(T&, R&); // #2
|
||||
// // The declaration of B::operator* is transformed into the equivalent of
|
||||
// // template<class R> int operator*(B<A>&, R&); // #1a
|
||||
// int main() {
|
||||
// A a;
|
||||
// B<A> b;
|
||||
// b * a; // calls #1a
|
||||
// }
|
||||
public void test14_5_6_2s3() throws Exception {
|
||||
String code= getAboveComment();
|
||||
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||
IBinding op1= bh.assertNonProblem("operator*(R&)", -4);
|
||||
IASTImplicitName name= bh.assertImplicitName("* a", 1, ICPPFunction.class);
|
||||
ICPPTemplateInstance inst= (ICPPTemplateInstance) name.resolveBinding();
|
||||
ICPPSpecialization templateSpecialization = (ICPPSpecialization) inst.getTemplateDefinition();
|
||||
assertSame(op1, templateSpecialization.getSpecializedBinding());
|
||||
}
|
||||
|
||||
// template<class T> struct A { A(); };
|
||||
// template<class T> void f(T);
|
||||
// template<class T> void f(T*);
|
||||
|
@ -4883,7 +4908,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// const A<int> z2;
|
||||
// h(z2); // h(const T&) is called because h(A<T>&) is not callable
|
||||
// }
|
||||
public void test14_5_5_2s5() throws Exception {
|
||||
public void test14_5_6_2s5() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, false, 0);
|
||||
}
|
||||
|
||||
|
@ -4896,7 +4921,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// f(ip); //calls #2
|
||||
// g(ip); //calls #4
|
||||
// }
|
||||
public void test14_5_5_2s6() throws Exception {
|
||||
public void test14_5_6_2s6() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
|
||||
|
@ -5657,7 +5682,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
|
||||
// template <class T> int f(T[5]);
|
||||
// int I = f<int>(0);
|
||||
// int j = f<void>(0); // invalid array
|
||||
// int j = f<void>(0); // invalid array // also no error with gcc
|
||||
public void _test14_8_2s8b() throws Exception {
|
||||
final String content= getAboveComment();
|
||||
BindingAssertionHelper bh= new BindingAssertionHelper(content, true);
|
||||
|
@ -5829,7 +5854,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// char g(char);
|
||||
// template <class T> T g(T);
|
||||
// int i = f(1, g); // calls f(int, int (*)(int))
|
||||
public void _test14_8_2_1s9() throws Exception {
|
||||
public void test14_8_2_1s9() throws Exception {
|
||||
final String code= getAboveComment();
|
||||
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||
ICPPTemplateInstance inst;
|
||||
|
@ -5962,13 +5987,13 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// f(i); // calls f<int&>(int&), i.e., #1
|
||||
// f(0); // calls f<int>(int&&), i.e., #2
|
||||
// }
|
||||
public void _test14_8_2_5s10() throws Exception {
|
||||
public void test14_8_2_5s10() throws Exception {
|
||||
final String code= getAboveComment();
|
||||
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||
ICPPTemplateInstance inst;
|
||||
inst= bh.assertNonProblem("f(i)", 1);
|
||||
assertEquals("<int &>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true));
|
||||
inst= bh.assertNonProblem("f(i)", 1);
|
||||
inst= bh.assertNonProblem("f(0)", 1);
|
||||
assertEquals("<int>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true));
|
||||
}
|
||||
|
||||
|
@ -6021,7 +6046,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// g<0>(a1); // OK
|
||||
// f(a1, a2); // OK
|
||||
// }
|
||||
public void _test14_8_2_5s16a() throws Exception {
|
||||
public void test14_8_2_5s16a() throws Exception {
|
||||
final String code= getAboveComment();
|
||||
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||
ICPPTemplateInstance inst;
|
||||
|
@ -6069,7 +6094,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// B<1> b;
|
||||
// g(b); // OK: cv-qualifiers are ignored on template parameter types
|
||||
// }
|
||||
public void _test14_8_2_5s17() throws Exception {
|
||||
public void test14_8_2_5s17() throws Exception {
|
||||
final String code= getAboveComment();
|
||||
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||
ICPPTemplateInstance inst;
|
||||
|
@ -6684,7 +6709,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
}
|
||||
|
||||
// template<class T1, class T2, int I> class A<T1, T2, I> { }; // error
|
||||
public void test14_5_4s5() throws Exception {
|
||||
public void test14_5_5s5() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, false, 0);
|
||||
}
|
||||
|
||||
|
@ -6697,7 +6722,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// template<class T> template<class T2>
|
||||
// struct A<T>::C::B<T2*> { };
|
||||
// A<short>::C::B<int*> absip; // uses partial specialization
|
||||
public void test14_5_4s6() throws Exception {
|
||||
public void test14_5_5s6() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
|
||||
|
@ -6710,14 +6735,14 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// }
|
||||
// A<int,int*> a; // uses the partial specialization, which is found through
|
||||
// // the using declaration which refers to the primary template
|
||||
public void test14_5_4s7() throws Exception {
|
||||
public void test14_5_5s7() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
|
||||
// template<class T> void f();
|
||||
// template<int I> void f(); // OK: overloads the first template
|
||||
// // distinguishable with an explicit template argument list
|
||||
public void test14_5_5_1s4() throws Exception {
|
||||
public void test14_5_6_1s4() throws Exception {
|
||||
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
|
||||
}
|
||||
|
||||
|
@ -6725,7 +6750,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// 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 {
|
||||
public void test14_5_6_1s5() throws Exception {
|
||||
final String content= getAboveComment();
|
||||
IASTTranslationUnit tu= parse(content, ParserLanguage.CPP, true, 0);
|
||||
BindingAssertionHelper bh= new BindingAssertionHelper(content, true);
|
||||
|
@ -6739,7 +6764,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// template <int I> class A;
|
||||
// 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
|
||||
public void test14_5_5_1s6() throws Exception {
|
||||
public void test14_5_6_1s6() throws Exception {
|
||||
final String content= getAboveComment();
|
||||
IASTTranslationUnit tu= parse(content, ParserLanguage.CPP, true, 0);
|
||||
BindingAssertionHelper bh= new BindingAssertionHelper(content, true);
|
||||
|
|
|
@ -4896,6 +4896,55 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
assertSame( col.getName(2).resolveBinding(), col.getName(5).resolveBinding() );
|
||||
}
|
||||
|
||||
// void f(const int&);
|
||||
// void f(int&);
|
||||
// void g(const int&);
|
||||
// void g(int);
|
||||
// void h(const int * const&);
|
||||
// void h(int *);
|
||||
// void i(int * const &);
|
||||
// void i(const int *);
|
||||
// void test() {
|
||||
// const int ca= 1; int a;
|
||||
// f(ca); // f(const int&)
|
||||
// f(a); // f(int &)
|
||||
// g(ca); // ambiguous
|
||||
// g(a); // ambiguous
|
||||
// h(&ca); // h(const int * const&)
|
||||
// h(&a); // void h(int *)
|
||||
// i(&ca); // i(const int *)
|
||||
// i(&a); // i(int * const &)
|
||||
// }
|
||||
public void testRankingQualificationConversions_c() throws Exception {
|
||||
String code= getAboveComment();
|
||||
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||
|
||||
ICPPFunction f1= bh.assertNonProblem("f(const int&)", 1);
|
||||
ICPPFunction f2= bh.assertNonProblem("f(int&)", 1);
|
||||
ICPPFunction g1= bh.assertNonProblem("g(const int&)", 1);
|
||||
ICPPFunction g2= bh.assertNonProblem("g(int)", 1);
|
||||
ICPPFunction h1= bh.assertNonProblem("h(const int * const&)", 1);
|
||||
ICPPFunction h2= bh.assertNonProblem("h(int *)", 1);
|
||||
ICPPFunction i1= bh.assertNonProblem("i(int * const &)", 1);
|
||||
ICPPFunction i2= bh.assertNonProblem("i(const int *)", 1);
|
||||
|
||||
ICPPFunction ref;
|
||||
ref= bh.assertNonProblem("f(ca)", 1);
|
||||
assertSame(f1, ref);
|
||||
ref= bh.assertNonProblem("f(a)", 1);
|
||||
assertSame(f2, ref);
|
||||
bh.assertProblem("g(ca)", 1);
|
||||
bh.assertProblem("g(a)", 1);
|
||||
ref= bh.assertNonProblem("h(&ca)", 1);
|
||||
assertSame(h1, ref);
|
||||
ref= bh.assertNonProblem("h(&a)", 1);
|
||||
assertSame(h2, ref);
|
||||
ref= bh.assertNonProblem("i(&ca)", 1);
|
||||
assertSame(i2, ref);
|
||||
ref= bh.assertNonProblem("i(&a)", 1);
|
||||
assertSame(i1, ref);
|
||||
}
|
||||
|
||||
// namespace n {
|
||||
// namespace m {
|
||||
// class A;
|
||||
|
|
|
@ -64,7 +64,7 @@ public class ASTCPPSpecDefectTests extends AST2BaseTest {
|
|||
// void test() {
|
||||
// fp(f0);
|
||||
// }
|
||||
public void testADLForOverloadSet_324842() throws Exception {
|
||||
public void test33_ADLForOverloadSet_324842() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,15 @@ public class ASTCPPSpecDefectTests extends AST2BaseTest {
|
|||
// struct A {
|
||||
// friend A operator + <>(A&);
|
||||
// };
|
||||
public void testTemplateArgForOperator() throws Exception {
|
||||
public void test38_templateArgForOperator() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
// template <class T1, class ...Z> class S; // #1
|
||||
// template <class T1, class ...Z> class S<T1, const Z&...> {}; // #2
|
||||
// template <class T1, class T2> class S<T1, const T2&> {};; // #3
|
||||
// S<int, const int&> s; // both #2 and #3 match; #3 is more specialized
|
||||
public void test692_partialOrdering() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
|
|
|
@ -416,6 +416,8 @@ public class ASTTypeUtil {
|
|||
needSpace= appendCVQ(result, needSpace, qt.isConst(), qt.isVolatile());
|
||||
} else if (type instanceof ITypedef) {
|
||||
result.append(((ITypedef) type).getNameCharArray());
|
||||
} else if (type != null) {
|
||||
result.append('@').append(type.hashCode());
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
|
|
|
@ -446,7 +446,7 @@ public class Value implements IValue {
|
|||
unknownSigs.put(sig, idx);
|
||||
unknowns.add(unknown);
|
||||
}
|
||||
return REFERENCE_CHAR + idx.toString();
|
||||
return "" + REFERENCE_CHAR + idx.toString(); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
private static Object evaluateValue(IValue cv, Map<String, Integer> unknownSigs, List<ICPPUnknownBinding> unknowns) throws UnknownValueException {
|
||||
|
@ -536,7 +536,7 @@ public class Value implements IValue {
|
|||
case IASTUnaryExpression.op_minus:
|
||||
case IASTUnaryExpression.op_tilde:
|
||||
case IASTUnaryExpression.op_not:
|
||||
return UNARY_OP_CHAR + unaryOp + SEPARATOR + value.toString();
|
||||
return "" + UNARY_OP_CHAR + unaryOp + SEPARATOR + value.toString(); //$NON-NLS-1$
|
||||
}
|
||||
throw UNKNOWN_EX;
|
||||
}
|
||||
|
@ -634,7 +634,7 @@ public class Value implements IValue {
|
|||
throw UNKNOWN_EX;
|
||||
}
|
||||
|
||||
return BINARY_OP_CHAR + op + SEPARATOR + o1.toString() + SEPARATOR + o2.toString();
|
||||
return "" + BINARY_OP_CHAR + op + SEPARATOR + o1.toString() + SEPARATOR + o2.toString(); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public static IValue reevaluate(IValue val, int packOffset, IBinding[] resolvedUnknowns, ICPPTemplateParameterMap map, int maxdepth) {
|
||||
|
@ -699,7 +699,7 @@ public class Value implements IValue {
|
|||
}
|
||||
return po;
|
||||
}
|
||||
return CONDITIONAL_CHAR + SEPARATOR + cond.toString() + SEPARATOR + po.toString() + SEPARATOR + neg.toString();
|
||||
return "" + CONDITIONAL_CHAR + SEPARATOR + cond.toString() + SEPARATOR + po.toString() + SEPARATOR + neg.toString(); //$NON-NLS-1$
|
||||
case REFERENCE_CHAR:
|
||||
int num= parseNonNegative(buf, idx+1);
|
||||
final IBinding[] resolvedUnknowns= reeval.fResolvedUnknown;
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.eclipse.core.runtime.CoreException;
|
|||
* Integral c++ type.
|
||||
*/
|
||||
public class CPPBasicType implements ICPPBasicType, ISerializableType {
|
||||
// mstodo replace with problem type
|
||||
public static int UNIQUE_TYPE_QUALIFIER= -1;
|
||||
private final Kind fKind;
|
||||
private final int fModifiers;
|
||||
|
|
|
@ -31,6 +31,10 @@ public class CPPTemplateParameterMap implements ICPPTemplateParameterMap {
|
|||
fMap= new ObjectMap(initialSize);
|
||||
}
|
||||
|
||||
public CPPTemplateParameterMap(CPPTemplateParameterMap other) {
|
||||
fMap= (ObjectMap) other.fMap.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the map contains the given parameter
|
||||
*/
|
||||
|
|
|
@ -2294,7 +2294,7 @@ public class CPPSemantics {
|
|||
return resolveFunctionDeclaration(data, fns);
|
||||
|
||||
// Reduce our set of candidate functions to only those who have the right number of parameters
|
||||
final IType[] argTypes = data.getFunctionArgumentTypes();
|
||||
final IType[] argTypes = data.getFunctionArgumentTypes();
|
||||
ICPPFunction[] tmp= selectByArgumentCount(data, fns);
|
||||
tmp= CPPTemplates.instantiateForFunctionCall(data.astName, tmp,
|
||||
Arrays.asList(argTypes),
|
||||
|
@ -2820,7 +2820,7 @@ public class CPPSemantics {
|
|||
if (inst != null) {
|
||||
int cmp= -1;
|
||||
if (result != null) {
|
||||
cmp= CPPTemplates.orderTemplateFunctions(resultTemplate, template);
|
||||
cmp= CPPTemplates.orderFunctionTemplates(resultTemplate, template);
|
||||
if (cmp == 0)
|
||||
cmp= compareByRelevance(tu, resultTemplate, template);
|
||||
}
|
||||
|
|
|
@ -14,14 +14,11 @@
|
|||
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||
|
||||
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
|
||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.addQualifiers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.core.dom.IName;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
||||
|
@ -41,8 +38,6 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
||||
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IEnumeration;
|
||||
import org.eclipse.cdt.core.dom.ast.IEnumerator;
|
||||
|
@ -104,7 +99,6 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
|||
import org.eclipse.cdt.internal.core.dom.parser.Value;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArrayType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassInstance;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassSpecialization;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassTemplatePartialSpecialization;
|
||||
|
@ -125,6 +119,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodTemplateSpecializat
|
|||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameterPackType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateDefinition;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeParameter;
|
||||
|
@ -157,7 +152,7 @@ public class CPPTemplates {
|
|||
private static final int PACK_SIZE_FAIL = -2;
|
||||
private static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE;
|
||||
private static final ICPPFunction[] NO_FUNCTIONS = {};
|
||||
|
||||
|
||||
/**
|
||||
* Instantiates a class template with the given arguments. May return <code>null</code>.
|
||||
*/
|
||||
|
@ -1111,10 +1106,9 @@ public class CPPTemplates {
|
|||
ICPPPointerToMemberType ptm = (ICPPPointerToMemberType) typeContainer;
|
||||
IType memberOfClass = ptm.getMemberOfClass();
|
||||
IType newMemberOfClass = instantiateType(memberOfClass, tpMap, packOffset, within);
|
||||
if (!(newMemberOfClass instanceof ICPPClassType) &&
|
||||
!(newMemberOfClass instanceof IBasicType && ((IBasicType) newMemberOfClass).getModifiers() == CPPBasicType.UNIQUE_TYPE_QUALIFIER) &&
|
||||
!(newMemberOfClass instanceof ICPPUnknownBinding)) {
|
||||
newMemberOfClass= memberOfClass;
|
||||
if (!(newMemberOfClass instanceof ICPPClassType || newMemberOfClass instanceof UniqueType
|
||||
|| newMemberOfClass instanceof ICPPUnknownBinding)) {
|
||||
newMemberOfClass = memberOfClass;
|
||||
}
|
||||
if (newNestedType != nestedType || newMemberOfClass != memberOfClass) {
|
||||
return new CPPPointerToMemberType(newNestedType, newMemberOfClass,
|
||||
|
@ -1580,16 +1574,13 @@ public class CPPTemplates {
|
|||
return fns;
|
||||
|
||||
final List<ICPPFunction> result= new ArrayList<ICPPFunction>(fns.length);
|
||||
final List<List<IType>> crossProduct= expandOverloadedSets(fnArgs);
|
||||
for (ICPPFunction fn : fns) {
|
||||
if (fn != null) {
|
||||
if (fn instanceof ICPPFunctionTemplate) {
|
||||
ICPPFunctionTemplate fnTmpl= (ICPPFunctionTemplate) fn;
|
||||
for (List<IType> args : crossProduct) {
|
||||
ICPPFunction inst = instantiateForFunctionCall(fnTmpl, tmplArgs, args, argCats, withImpliedObjectArg);
|
||||
if (inst != null)
|
||||
result.add(inst);
|
||||
}
|
||||
ICPPFunction inst = instantiateForFunctionCall(fnTmpl, tmplArgs, fnArgs, argCats, withImpliedObjectArg);
|
||||
if (inst != null)
|
||||
result.add(inst);
|
||||
} else if (!requireTemplate || fn instanceof ICPPUnknownBinding) {
|
||||
result.add(fn);
|
||||
}
|
||||
|
@ -1598,47 +1589,6 @@ public class CPPTemplates {
|
|||
return result.toArray(new ICPPFunction[result.size()]);
|
||||
}
|
||||
|
||||
private static List<List<IType>> expandOverloadedSets(List<IType> fnArgs) {
|
||||
List<List<IType>> result= Collections.singletonList(fnArgs);
|
||||
int i= 0;
|
||||
for (IType arg : fnArgs) {
|
||||
if (arg instanceof FunctionSetType) {
|
||||
Collection<ICPPFunctionType> targetTypes= getFunctionTypes((FunctionSetType) arg);
|
||||
if (targetTypes.isEmpty())
|
||||
return Collections.emptyList();
|
||||
|
||||
List<List<IType>> expanded= new ArrayList<List<IType>>(targetTypes.size() * result.size());
|
||||
for (IType targetType : targetTypes) {
|
||||
for (List<IType> orig : result) {
|
||||
ArrayList<IType> copy = new ArrayList<IType>(orig);
|
||||
copy.set(i, new CPPPointerType(targetType));
|
||||
expanded.add(copy);
|
||||
}
|
||||
}
|
||||
result= expanded;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Collection<ICPPFunctionType> getFunctionTypes(FunctionSetType fst) {
|
||||
final ICPPFunction[] functionSet = fst.getFunctionSet();
|
||||
Set<String> handled= new HashSet<String>();
|
||||
Collection<ICPPFunctionType> result= new ArrayList<ICPPFunctionType>(functionSet.length);
|
||||
for (ICPPFunction f : functionSet) {
|
||||
if (! (f instanceof ICPPFunctionTemplate)) {
|
||||
try {
|
||||
ICPPFunctionType t= f.getType();
|
||||
if (handled.add(ASTTypeUtil.getType(t, true)))
|
||||
result.add(t);
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ICPPFunction instantiateForFunctionCall(ICPPFunctionTemplate template,
|
||||
ICPPTemplateArgument[] tmplArgs, List<IType> fnArgs, List<ValueCategory> argCats,
|
||||
boolean withImpliedObjectArg) {
|
||||
|
@ -1732,90 +1682,92 @@ public class CPPTemplates {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transforms a function template for use in partial ordering, as described in the
|
||||
* spec 14.5.5.2-3
|
||||
* @param template
|
||||
* @return
|
||||
* -for each type template parameter, synthesize a unique type and substitute that for each
|
||||
* occurrence of that parameter in the function parameter list
|
||||
* -for each non-type template parameter, synthesize a unique value of the appropriate type and
|
||||
* substitute that for each occurrence of that parameter in the function parameter list
|
||||
* for each template template parameter, synthesize a unique class template and substitute that
|
||||
* for each occurrence of that parameter in the function parameter list
|
||||
* @throws DOMException
|
||||
*/
|
||||
static private ICPPTemplateArgument[] createArgsForFunctionTemplateOrdering(ICPPTemplateParameter[] paramList)
|
||||
throws DOMException{
|
||||
int size = paramList.length;
|
||||
ICPPTemplateArgument[] args = new ICPPTemplateArgument[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
ICPPTemplateParameter param = paramList[i];
|
||||
if (param instanceof ICPPTemplateNonTypeParameter) {
|
||||
args[i]= new CPPTemplateArgument(Value.unique(), ((ICPPTemplateNonTypeParameter) param).getType());
|
||||
} else {
|
||||
args[i] = new CPPTemplateArgument(new CPPBasicType(Kind.eUnspecified, CPPBasicType.UNIQUE_TYPE_QUALIFIER));
|
||||
}
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
static int orderTemplateFunctions(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2)
|
||||
// 14.5.6.2 Partial ordering of function templates
|
||||
static int orderFunctionTemplates(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2)
|
||||
throws DOMException {
|
||||
// 14.5.5.2
|
||||
// A template is more specialized than another if and only if it is at least as specialized as the
|
||||
// other template and that template is not at least as specialized as the first.
|
||||
boolean f1IsAtLeastAsSpecializedAsF2 = isAtLeastAsSpecializedAs(f1, f2);
|
||||
boolean f2IsAtLeastAsSpecializedAsF1 = isAtLeastAsSpecializedAs(f2, f1);
|
||||
|
||||
if (f1IsAtLeastAsSpecializedAsF2 == f2IsAtLeastAsSpecializedAsF1)
|
||||
int s1 = compareSpecialization(f1, f2);
|
||||
int s2 = compareSpecialization(f2, f1);
|
||||
|
||||
if (s1 == s2)
|
||||
return 0;
|
||||
|
||||
if (f1IsAtLeastAsSpecializedAsF2)
|
||||
return 1;
|
||||
|
||||
return -1;
|
||||
if (s1 < 0 || s2 > 0)
|
||||
return -1;
|
||||
assert s2 < 0 || s1 > 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static boolean isAtLeastAsSpecializedAs(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2) throws DOMException {
|
||||
// mstodo use function-type, parameter-types or return type.
|
||||
// mstodo perform transformations (references, cv-qualifiers)
|
||||
// mstodo if equal, use differences in cv-qualifiers
|
||||
// mstodo special rule for parameter packs.
|
||||
// 14.5.5.2
|
||||
// Using the transformed parameter list, perform argument deduction against the other
|
||||
// function template
|
||||
// The transformed template is at least as specialized as the other if and only if the deduction
|
||||
// succeeds and the deduced parameter types are an exact match.
|
||||
private static ICPPFunction transferFunctionTemplate(ICPPFunctionTemplate f) throws DOMException {
|
||||
final ICPPTemplateParameter[] tpars = f.getTemplateParameters();
|
||||
final int argLen = tpars.length;
|
||||
|
||||
// Check for parameter packs
|
||||
|
||||
final ICPPTemplateParameter[] tmplParams1 = f1.getTemplateParameters();
|
||||
ICPPTemplateArgument[] transferArgs = createArgsForFunctionTemplateOrdering(tmplParams1);
|
||||
|
||||
final int length = transferArgs.length;
|
||||
CPPTemplateParameterMap map = new CPPTemplateParameterMap(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
map.put(tmplParams1[i], transferArgs[i]);
|
||||
}
|
||||
IBinding transferredTemplate = instantiateFunctionTemplate(f1, transferArgs, map);
|
||||
if (!(transferredTemplate instanceof ICPPFunction))
|
||||
return false;
|
||||
|
||||
map= new CPPTemplateParameterMap(2);
|
||||
final IType[] transferredParameterTypes = ((ICPPFunction) transferredTemplate).getType().getParameterTypes();
|
||||
if (!TemplateArgumentDeduction.deduceFromFunctionArgs(f2, Arrays.asList(transferredParameterTypes), null, map, true))
|
||||
return false;
|
||||
|
||||
final int last = tmplParams1.length -1;
|
||||
if (last >= 0 && tmplParams1[last].isParameterPack()) {
|
||||
final ICPPTemplateParameter[] tmplParams2 = f2.getTemplateParameters();
|
||||
if (last < tmplParams2.length && !tmplParams2[last].isParameterPack()) {
|
||||
return false;
|
||||
// Create arguments and map
|
||||
ICPPTemplateArgument[] args = new ICPPTemplateArgument[argLen];
|
||||
CPPTemplateParameterMap map = new CPPTemplateParameterMap(argLen);
|
||||
for (int i = 0; i < argLen; i++) {
|
||||
final ICPPTemplateParameter tpar = tpars[i];
|
||||
final CPPTemplateArgument arg = uniqueArg(tpar);
|
||||
args[i]= arg;
|
||||
if (tpar.isParameterPack()) {
|
||||
map.put(tpar, new ICPPTemplateArgument[] {arg});
|
||||
} else {
|
||||
map.put(tpar, arg);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
IBinding result = instantiateFunctionTemplate(f, args, map);
|
||||
if (result instanceof ICPPFunction)
|
||||
return (ICPPFunction) result;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static CPPTemplateArgument uniqueArg(final ICPPTemplateParameter tpar) throws DOMException {
|
||||
final CPPTemplateArgument arg;
|
||||
if (tpar instanceof ICPPTemplateNonTypeParameter) {
|
||||
arg = new CPPTemplateArgument(Value.unique(), ((ICPPTemplateNonTypeParameter) tpar).getType());
|
||||
} else {
|
||||
arg = new CPPTemplateArgument(new UniqueType(tpar.isParameterPack()));
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
||||
private static int compareSpecialization(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2) throws DOMException {
|
||||
ICPPFunction transF1 = transferFunctionTemplate(f1);
|
||||
if (transF1 == null)
|
||||
return -1;
|
||||
|
||||
// mstodo use function-type, parameter-types or return type.
|
||||
IType[] pars= f2.getType().getParameterTypes();
|
||||
IType[] args = transF1.getType().getParameterTypes();
|
||||
boolean nonStaticMember1= isNonStaticMember(f1);
|
||||
boolean nonStaticMember2= isNonStaticMember(f2);
|
||||
if (nonStaticMember1 != nonStaticMember2) {
|
||||
if (nonStaticMember1) {
|
||||
args= addImplicitObjectType(args, (ICPPMethod) f1);
|
||||
} else {
|
||||
pars= addImplicitObjectType(pars, (ICPPMethod) f2);
|
||||
}
|
||||
}
|
||||
return TemplateArgumentDeduction.deduceForPartialOrdering(f2.getTemplateParameters(), pars, args);
|
||||
}
|
||||
|
||||
private static boolean isNonStaticMember(ICPPFunctionTemplate f) {
|
||||
return (f instanceof ICPPMethod) && !((ICPPMethod) f).isStatic();
|
||||
}
|
||||
|
||||
private static IType[] addImplicitObjectType(IType[] types, ICPPMethod f1) {
|
||||
ICPPClassType ct = f1.getClassOwner();
|
||||
if (ct != null) {
|
||||
try {
|
||||
ICPPFunctionType ft = f1.getType();
|
||||
IType[] result= new IType[types.length+1];
|
||||
result[0]= new CPPReferenceType(addQualifiers(ct, ft.isConst(), ft.isVolatile()), false);
|
||||
System.arraycopy(types, 0, result, 1, types.length);
|
||||
return result;
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
private static ICPPClassTemplatePartialSpecialization findPartialSpecialization(ICPPClassTemplate ct,
|
||||
|
@ -1918,21 +1870,25 @@ public class CPPTemplates {
|
|||
final ICPPTemplateArgument[] targs2 = f2.getTemplateArguments();
|
||||
if (targs1.length != targs2.length)
|
||||
return false;
|
||||
|
||||
// transfer arguments of specialization 1
|
||||
final ICPPTemplateArgument[] helperArgs = createArgsForFunctionTemplateOrdering(tpars1);
|
||||
final CPPTemplateParameterMap transferMap= new CPPTemplateParameterMap(5);
|
||||
for (int i = 0; i < tpars1.length; i++) {
|
||||
transferMap.put(tpars1[i], helperArgs[i]);
|
||||
|
||||
// Transfer arguments of specialization 1
|
||||
final int tpars1Len = tpars1.length;
|
||||
ICPPTemplateArgument[] args = new ICPPTemplateArgument[tpars1Len];
|
||||
final CPPTemplateParameterMap transferMap= new CPPTemplateParameterMap(tpars1Len);
|
||||
for (int i = 0; i < tpars1Len; i++) {
|
||||
final ICPPTemplateParameter param = tpars1[i];
|
||||
final CPPTemplateArgument arg = uniqueArg(param);
|
||||
args[i]= arg;
|
||||
transferMap.put(param, arg);
|
||||
}
|
||||
final ICPPTemplateArgument[] transferredArgs1 = instantiateArguments(targs1, transferMap, -1, null);
|
||||
|
||||
// deduce arguments for specialization 2
|
||||
// Deduce arguments for specialization 2
|
||||
final CPPTemplateParameterMap deductionMap= new CPPTemplateParameterMap(2);
|
||||
if (!TemplateArgumentDeduction.fromTemplateArguments(tpars2, targs2, transferredArgs1, deductionMap))
|
||||
return false;
|
||||
|
||||
// compare
|
||||
// Compare
|
||||
for (int i = 0; i < targs2.length; i++) {
|
||||
ICPPTemplateArgument transferredArg2= instantiateArgument(targs2[i], deductionMap, -1, null);
|
||||
if (!transferredArg2.isSameValue(transferredArgs1[i]))
|
||||
|
|
|
@ -1821,7 +1821,7 @@ public class CPPVisitor extends ASTQueries {
|
|||
ICPPFunctionTemplate template = new AutoTypeResolver(type);
|
||||
CPPTemplateParameterMap paramMap = new CPPTemplateParameterMap(1);
|
||||
TemplateArgumentDeduction.deduceFromFunctionArgs(template, Collections.singletonList(initType),
|
||||
Collections.singletonList(valueCat), paramMap, false);
|
||||
Collections.singletonList(valueCat), paramMap);
|
||||
ICPPTemplateArgument argument = paramMap.getArgument(0, 0);
|
||||
if (argument == null) {
|
||||
return null;
|
||||
|
|
|
@ -35,6 +35,10 @@ public enum CVQualifier {
|
|||
return other == _ || this == other || this == cv;
|
||||
}
|
||||
|
||||
public boolean isMoreQualifiedThan(CVQualifier other) {
|
||||
return this != other && (other == _ || this == cv);
|
||||
}
|
||||
|
||||
public CVQualifier remove(CVQualifier arg) {
|
||||
if (this == arg)
|
||||
return _;
|
||||
|
|
|
@ -95,8 +95,8 @@ public class Conversions {
|
|||
final IType cv1T1= getNestedType(target, TDEF | REF);
|
||||
final IType T1= getNestedType(cv1T1, TDEF | REF | ALLCVQ);
|
||||
|
||||
ReferenceBinding refBindingType= ReferenceBinding.OTHER;
|
||||
if (target instanceof ICPPReferenceType) {
|
||||
ReferenceBinding refBindingType= ReferenceBinding.OTHER_REF;
|
||||
// [8.5.3-5] initialization of a reference
|
||||
final boolean isLValueRef= !((ICPPReferenceType) target).isRValueReference();
|
||||
final IType cv2T2= exprType;
|
||||
|
@ -239,8 +239,8 @@ public class Conversions {
|
|||
if (!isImpliedObject && ctx != Context.REQUIRE_DIRECT_BINDING) {
|
||||
if (isReferenceRelated(T1, T2) < 0 || compareQualifications(cv1T1, cv2T2) >= 0) {
|
||||
Cost cost= nonReferenceConversion(valueCat, cv2T2, T1, udc, false);
|
||||
if (!isImplicitWithoutRefQualifier && cost.converts()) {
|
||||
cost.setReferenceBinding(isLValueRef ? ReferenceBinding.LVALUE_REF : ReferenceBinding.RVALUE_REF_BINDS_RVALUE);
|
||||
if (cost.converts()) {
|
||||
cost.setReferenceBinding(refBindingType);
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
@ -249,11 +249,7 @@ public class Conversions {
|
|||
}
|
||||
|
||||
// Non-reference binding
|
||||
Cost cost= nonReferenceConversion(valueCat, exprType, T1, udc, isImpliedObject);
|
||||
if (cost.converts()) {
|
||||
cost.setReferenceBinding(refBindingType);
|
||||
}
|
||||
return cost;
|
||||
return nonReferenceConversion(valueCat, exprType, T1, udc, isImpliedObject);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -279,6 +275,8 @@ public class Conversions {
|
|||
IType implicitParameterType= CPPSemantics.getImplicitParameterType(op, ft.isConst(), ft.isVolatile());
|
||||
Cost udcCost= isReferenceCompatible(getNestedType(implicitParameterType, TDEF | REF), cv2T2, true); // expression type to implicit object type
|
||||
if (udcCost != null) {
|
||||
// Make sure top-level cv-qualifiers are compared
|
||||
udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF);
|
||||
FunctionCost udcFuncCost= new FunctionCost(op, udcCost);
|
||||
int cmp= udcFuncCost.compareTo(null, bestUdcCost);
|
||||
if (cmp <= 0) {
|
||||
|
@ -729,6 +727,8 @@ public class Conversions {
|
|||
IType implicitType= CPPSemantics.getImplicitParameterType(op, ft.isConst(), ft.isVolatile());
|
||||
final Cost udcCost = isReferenceCompatible(getNestedType(implicitType, TDEF | REF), source, true);
|
||||
if (udcCost != null) {
|
||||
// Make sure top-level cv-qualifiers are compared
|
||||
udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF);
|
||||
FunctionCost c1= new FunctionCost(op, udcCost);
|
||||
int cmp= c1.compareTo(null, cost1);
|
||||
if (cmp <= 0) {
|
||||
|
@ -783,6 +783,8 @@ public class Conversions {
|
|||
IType implicitType= CPPSemantics.getImplicitParameterType(op, ftype.isConst(), ftype.isVolatile());
|
||||
final Cost udcCost = isReferenceCompatible(getNestedType(implicitType, TDEF | REF), source, true);
|
||||
if (udcCost != null) {
|
||||
// Make sure top-level cv-qualifiers are compared
|
||||
udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF);
|
||||
FunctionCost c1= new FunctionCost(op, udcCost);
|
||||
int cmp= c1.compareTo(null, cost1);
|
||||
if (cmp <= 0) {
|
||||
|
@ -868,7 +870,7 @@ public class Conversions {
|
|||
IASTLiteralExpression lit= (IASTLiteralExpression) val;
|
||||
if (lit.getKind() == IASTLiteralExpression.lk_string_literal) {
|
||||
source= new CPPPointerType(srcTarget, false, false);
|
||||
cost.setQualificationAdjustment(getCVQualifier(targetPtrTgt).isVolatile() ? 2 : 1);
|
||||
cost.setQualificationAdjustment((getCVQualifier(targetPtrTgt).isVolatile() ? 2 : 1) << 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -886,11 +888,11 @@ public class Conversions {
|
|||
boolean constInEveryCV2k = true;
|
||||
boolean firstPointer= true;
|
||||
int adjustments= 0;
|
||||
int shift=0;
|
||||
while (true) {
|
||||
s= getNestedType(s, TDEF | REF);
|
||||
t= getNestedType(t, TDEF | REF);
|
||||
if (s instanceof IPointerType && t instanceof IPointerType) {
|
||||
adjustments <<= 2;
|
||||
final int cmp= compareQualifications(t, s); // is t more qualified than s?
|
||||
if (cmp < 0 || (cmp > 0 && !constInEveryCV2k)) {
|
||||
return false;
|
||||
|
@ -904,19 +906,19 @@ public class Conversions {
|
|||
s= sPtr.getType();
|
||||
t= tPtr.getType();
|
||||
firstPointer= false;
|
||||
adjustments |= cmp;
|
||||
adjustments |= (cmp << shift);
|
||||
shift+= 2;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
adjustments <<= 2;
|
||||
int cmp= compareQualifications(t, s); // is t more qualified than s?
|
||||
if (cmp < 0 || (cmp > 0 && !constInEveryCV2k)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
adjustments |= cmp;
|
||||
adjustments |= (cmp << shift);
|
||||
s= getNestedType(s, ALLCVQ | TDEF | REF);
|
||||
t= getNestedType(t, ALLCVQ | TDEF | REF);
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ public class Cost {
|
|||
USER_DEFINED_CONVERSION, ELLIPSIS_CONVERSION, NO_MATCH
|
||||
}
|
||||
enum ReferenceBinding {
|
||||
RVALUE_REF_BINDS_RVALUE, LVALUE_REF, OTHER
|
||||
RVALUE_REF_BINDS_RVALUE, LVALUE_REF, OTHER_REF, NO_REF
|
||||
}
|
||||
|
||||
public static final Cost NO_CONVERSION = new Cost(null, null, Rank.NO_MATCH) {
|
||||
|
@ -99,7 +99,7 @@ public class Cost {
|
|||
source = s;
|
||||
target = t;
|
||||
fRank= rank;
|
||||
fReferenceBinding= ReferenceBinding.OTHER;
|
||||
fReferenceBinding= ReferenceBinding.NO_REF;
|
||||
}
|
||||
|
||||
public final Rank getRank() {
|
||||
|
@ -207,7 +207,11 @@ public class Cost {
|
|||
return -1;
|
||||
}
|
||||
|
||||
// Top level cv-qualifiers are compared only for reference bindings.
|
||||
int qdiff= fQualificationAdjustments ^ other.fQualificationAdjustments;
|
||||
if (fReferenceBinding == ReferenceBinding.NO_REF || other.fReferenceBinding == ReferenceBinding.NO_REF)
|
||||
qdiff &= ~3;
|
||||
|
||||
if (qdiff != 0) {
|
||||
if ((fQualificationAdjustments & qdiff) == 0)
|
||||
return -1;
|
||||
|
|
|
@ -155,7 +155,7 @@ class FunctionCost {
|
|||
} else if (!isTemplate && otherIsTemplate) {
|
||||
haveBetter = true;
|
||||
} else if (isTemplate && otherIsTemplate) {
|
||||
int order = CPPTemplates.orderTemplateFunctions(otherAsTemplate, asTemplate);
|
||||
int order = CPPTemplates.orderFunctionTemplates(otherAsTemplate, asTemplate);
|
||||
if (order < 0) {
|
||||
haveBetter= true;
|
||||
} else if (order > 0) {
|
||||
|
|
|
@ -38,6 +38,7 @@ 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.ICPPSpecialization;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
|
||||
import org.eclipse.cdt.core.index.IIndexBinding;
|
||||
import org.eclipse.cdt.core.parser.Keywords;
|
||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
|
@ -577,4 +578,50 @@ public class SemanticUtil {
|
|||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static boolean containsUniqueTypeForParameterPack(IType type) {
|
||||
if (type instanceof ICPPFunctionType) {
|
||||
final ICPPFunctionType ft = (ICPPFunctionType) type;
|
||||
if (containsUniqueTypeForParameterPack(ft.getReturnType()))
|
||||
return true;
|
||||
|
||||
for (IType pt : ft.getParameterTypes()) {
|
||||
if (containsUniqueTypeForParameterPack(pt))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type instanceof ICPPPointerToMemberType) {
|
||||
if (containsUniqueTypeForParameterPack(((ICPPPointerToMemberType) type).getMemberOfClass()))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type instanceof IBinding) {
|
||||
IBinding owner = ((IBinding) type).getOwner();
|
||||
if (owner instanceof IType) {
|
||||
if (containsUniqueTypeForParameterPack((IType) owner))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (type instanceof ICPPTemplateInstance) {
|
||||
ICPPTemplateArgument[] args = ((ICPPTemplateInstance) type).getTemplateArguments();
|
||||
for (ICPPTemplateArgument arg : args) {
|
||||
if (containsUniqueTypeForParameterPack(arg.getTypeValue()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (type instanceof ITypeContainer) {
|
||||
final ITypeContainer tc = (ITypeContainer) type;
|
||||
final IType nestedType= tc.getType();
|
||||
return containsUniqueTypeForParameterPack(nestedType);
|
||||
}
|
||||
|
||||
if (type instanceof UniqueType) {
|
||||
return ((UniqueType) type).isForParameterPack();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
|
||||
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
||||
|
@ -35,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
|
|||
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.ICPPFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
|
||||
|
@ -97,7 +99,7 @@ public class TemplateArgumentDeduction {
|
|||
map.put(tmplParam, pack);
|
||||
}
|
||||
|
||||
if (!deduceFromFunctionArgs(template, fnArgs, argIsLValue, map, false))
|
||||
if (!deduceFromFunctionArgs(template, fnArgs, argIsLValue, map))
|
||||
return null;
|
||||
|
||||
List<ICPPTemplateArgument> result= new ArrayList<ICPPTemplateArgument>(numTmplParams);
|
||||
|
@ -236,7 +238,7 @@ public class TemplateArgumentDeduction {
|
|||
* returns <code>false</code> if there is no mapping.
|
||||
*/
|
||||
static boolean deduceFromFunctionArgs(ICPPFunctionTemplate template, List<IType> fnArgs, List<ValueCategory> argCats,
|
||||
CPPTemplateParameterMap map, boolean checkExactMatch) {
|
||||
CPPTemplateParameterMap map) {
|
||||
try {
|
||||
IType[] fnPars = template.getType().getParameterTypes();
|
||||
final int fnParCount = fnPars.length;
|
||||
|
@ -246,7 +248,7 @@ public class TemplateArgumentDeduction {
|
|||
final ICPPTemplateParameter[] tmplPars = template.getTemplateParameters();
|
||||
TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplPars, map, new CPPTemplateParameterMap(fnParCount), 0);
|
||||
IType fnParPack= null;
|
||||
for (int j= 0; j < fnArgs.size(); j++) {
|
||||
argLoop: for (int j= 0; j < fnArgs.size(); j++) {
|
||||
IType par;
|
||||
if (fnParPack != null) {
|
||||
par= fnParPack;
|
||||
|
@ -255,7 +257,7 @@ public class TemplateArgumentDeduction {
|
|||
par= fnPars[j];
|
||||
if (par instanceof ICPPParameterPackType) {
|
||||
if (j != fnParCount - 1)
|
||||
continue; // non-deduced context
|
||||
continue argLoop; // Non-deduced context
|
||||
|
||||
par= fnParPack= ((ICPPParameterPackType) par).getType();
|
||||
deduct= new TemplateArgumentDeduction(deduct, fnArgs.size() - j);
|
||||
|
@ -268,14 +270,12 @@ public class TemplateArgumentDeduction {
|
|||
if (!CPPTemplates.isValidType(par))
|
||||
return false;
|
||||
|
||||
boolean isDependentPar= CPPTemplates.isDependentType(par);
|
||||
if (checkExactMatch || isDependentPar) {
|
||||
if (CPPTemplates.isDependentType(par)) {
|
||||
IType arg = fnArgs.get(j);
|
||||
par= SemanticUtil.getNestedType(par, SemanticUtil.TDEF); // adjustParameterType preserves typedefs
|
||||
|
||||
// C++0x: 14.9.2.1-1
|
||||
if (arg instanceof InitializerListType) {
|
||||
assert !checkExactMatch;
|
||||
par= SemanticUtil.getNestedType(par, TDEF | REF | CVTYPE);
|
||||
|
||||
// Check if this is a deduced context
|
||||
|
@ -285,23 +285,44 @@ public class TemplateArgumentDeduction {
|
|||
IType[] types = initListType.getExpressionTypes();
|
||||
ValueCategory[] valueCats = initListType.getValueCategories();
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
if (!deduceFromFunctionArg(inner, types[i], valueCats[i], checkExactMatch, isDependentPar, deduct))
|
||||
if (!deduceFromFunctionArg(inner, types[i], valueCats[i], deduct))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// 14.8.2.1-2
|
||||
ValueCategory cat= argCats != null ? argCats.get(j) : LVALUE;
|
||||
if (!deduceFromFunctionArg(par, arg, cat, checkExactMatch, isDependentPar, deduct)) {
|
||||
return false;
|
||||
} else if (arg instanceof FunctionSetType) {
|
||||
// 14.8.2.1-6 Handling of overloaded function sets
|
||||
ICPPFunction[] fs= ((FunctionSetType) arg).getFunctionSet();
|
||||
for (ICPPFunction f : fs) {
|
||||
if (f instanceof ICPPFunctionTemplate)
|
||||
continue argLoop; // Non-deduced context
|
||||
}
|
||||
|
||||
// Do trial deduction
|
||||
CPPTemplateParameterMap success= null;
|
||||
Set<String> handled= new HashSet<String>();
|
||||
for (ICPPFunction f : fs) {
|
||||
arg= f.getType();
|
||||
if (handled.add(ASTTypeUtil.getType(arg, true))) {
|
||||
final CPPTemplateParameterMap state = deduct.saveState();
|
||||
if (deduceFromFunctionArg(par, arg, argCats.get(j), deduct)) {
|
||||
if (success != null) {
|
||||
deduct.restoreState(state);
|
||||
continue argLoop; // Non-deduced context
|
||||
}
|
||||
success= deduct.saveState();
|
||||
}
|
||||
deduct.restoreState(state);
|
||||
}
|
||||
}
|
||||
if (success == null)
|
||||
return false;
|
||||
deduct.restoreState(success);
|
||||
} else {
|
||||
if (!deduceFromFunctionArg(par, arg, argCats.get(j), deduct))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Bug 309564: For partial ordering not all arguments need to be deduced
|
||||
if (checkExactMatch)
|
||||
return true;
|
||||
|
||||
if (!deduct.fExplicitArgs.mergeToExplicit(deduct.fDeducedArgs))
|
||||
return false;
|
||||
|
@ -312,7 +333,7 @@ public class TemplateArgumentDeduction {
|
|||
return false;
|
||||
}
|
||||
|
||||
private static boolean deduceFromFunctionArg(IType par, IType arg, ValueCategory valueCat, boolean checkExactMatch, boolean isDependentPar, TemplateArgumentDeduction deduct) throws DOMException {
|
||||
private static boolean deduceFromFunctionArg(IType par, IType arg, ValueCategory valueCat, TemplateArgumentDeduction deduct) throws DOMException {
|
||||
boolean isReferenceTypeParameter= false;
|
||||
if (par instanceof ICPPReferenceType) {
|
||||
// If P is an rvalue reference to a cv-unqualified template parameter and the argument is an
|
||||
|
@ -330,61 +351,113 @@ public class TemplateArgumentDeduction {
|
|||
arg= getArgumentTypeForDeduction(arg, false);
|
||||
}
|
||||
|
||||
if (!checkExactMatch) {
|
||||
// 14.8.2.1-3
|
||||
CVQualifier cvPar= SemanticUtil.getCVQualifier(par);
|
||||
CVQualifier cvArg= SemanticUtil.getCVQualifier(arg);
|
||||
if (cvPar == cvArg || (isReferenceTypeParameter && cvPar.isAtLeastAsQualifiedAs(cvArg))) {
|
||||
IType pcheck= SemanticUtil.getNestedType(par, CVTYPE);
|
||||
if (!(pcheck instanceof ICPPTemplateParameter)) {
|
||||
par= pcheck;
|
||||
arg= SemanticUtil.getNestedType(arg, CVTYPE);
|
||||
IType argcheck= arg;
|
||||
if (par instanceof IPointerType && arg instanceof IPointerType) {
|
||||
pcheck= ((IPointerType) par).getType();
|
||||
argcheck= ((IPointerType) arg).getType();
|
||||
if (pcheck instanceof ICPPTemplateParameter) {
|
||||
pcheck= null;
|
||||
// 14.8.2.1-3
|
||||
CVQualifier cvPar= SemanticUtil.getCVQualifier(par);
|
||||
CVQualifier cvArg= SemanticUtil.getCVQualifier(arg);
|
||||
if (cvPar == cvArg || (isReferenceTypeParameter && cvPar.isAtLeastAsQualifiedAs(cvArg))) {
|
||||
IType pcheck= SemanticUtil.getNestedType(par, CVTYPE);
|
||||
if (!(pcheck instanceof ICPPTemplateParameter)) {
|
||||
par= pcheck;
|
||||
arg= SemanticUtil.getNestedType(arg, CVTYPE);
|
||||
IType argcheck= arg;
|
||||
if (par instanceof IPointerType && arg instanceof IPointerType) {
|
||||
pcheck= ((IPointerType) par).getType();
|
||||
argcheck= ((IPointerType) arg).getType();
|
||||
if (pcheck instanceof ICPPTemplateParameter) {
|
||||
pcheck= null;
|
||||
} else {
|
||||
cvPar= SemanticUtil.getCVQualifier(pcheck);
|
||||
cvArg= SemanticUtil.getCVQualifier(argcheck);
|
||||
if (cvPar.isAtLeastAsQualifiedAs(cvArg)) {
|
||||
pcheck= SemanticUtil.getNestedType(pcheck, CVTYPE);
|
||||
argcheck= SemanticUtil.getNestedType(argcheck, CVTYPE);
|
||||
} else {
|
||||
cvPar= SemanticUtil.getCVQualifier(pcheck);
|
||||
cvArg= SemanticUtil.getCVQualifier(argcheck);
|
||||
if (cvPar.isAtLeastAsQualifiedAs(cvArg)) {
|
||||
pcheck= SemanticUtil.getNestedType(pcheck, CVTYPE);
|
||||
argcheck= SemanticUtil.getNestedType(argcheck, CVTYPE);
|
||||
} else {
|
||||
pcheck= null;
|
||||
}
|
||||
pcheck= null;
|
||||
}
|
||||
}
|
||||
if (pcheck instanceof ICPPTemplateInstance && argcheck instanceof ICPPClassType) {
|
||||
ICPPTemplateInstance pInst = (ICPPTemplateInstance) pcheck;
|
||||
ICPPClassTemplate pTemplate= getPrimaryTemplate(pInst);
|
||||
if (pTemplate != null) {
|
||||
ICPPClassType aInst= findBaseInstance((ICPPClassType) argcheck, pTemplate, CPPSemantics.MAX_INHERITANCE_DEPTH);
|
||||
if (aInst != null && aInst != argcheck) {
|
||||
par= pcheck;
|
||||
arg= aInst;
|
||||
}
|
||||
}
|
||||
if (pcheck instanceof ICPPTemplateInstance && argcheck instanceof ICPPClassType) {
|
||||
ICPPTemplateInstance pInst = (ICPPTemplateInstance) pcheck;
|
||||
ICPPClassTemplate pTemplate= getPrimaryTemplate(pInst);
|
||||
if (pTemplate != null) {
|
||||
ICPPClassType aInst= findBaseInstance((ICPPClassType) argcheck, pTemplate, CPPSemantics.MAX_INHERITANCE_DEPTH);
|
||||
if (aInst != null && aInst != argcheck) {
|
||||
par= pcheck;
|
||||
arg= aInst;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isDependentPar && !deduct.fromType(par, arg, true)) {
|
||||
return false;
|
||||
return deduct.fromType(par, arg, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deduces the mapping for the template parameters from the function parameters,
|
||||
* returns <code>false</code> if there is no mapping.
|
||||
*/
|
||||
static int deduceForPartialOrdering(ICPPTemplateParameter[] tmplPars, IType[] fnPars, IType[] fnArgs) {
|
||||
try {
|
||||
final int fnParCount = fnPars.length;
|
||||
final int fnArgCount = fnArgs.length;
|
||||
int result= 0;
|
||||
TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplPars, new CPPTemplateParameterMap(0), new CPPTemplateParameterMap(fnParCount), 0);
|
||||
IType fnParPack= null;
|
||||
for (int j= 0; j < fnArgCount; j++) {
|
||||
IType par;
|
||||
if (fnParPack != null) {
|
||||
par= fnParPack;
|
||||
deduct.incPackOffset();
|
||||
} else {
|
||||
if (j >= fnParCount)
|
||||
return result;
|
||||
|
||||
par= fnPars[j];
|
||||
if (par instanceof ICPPParameterPackType) {
|
||||
if (j != fnParCount - 1)
|
||||
continue; // non-deduced context
|
||||
|
||||
par= fnParPack= ((ICPPParameterPackType) par).getType();
|
||||
deduct= new TemplateArgumentDeduction(deduct, fnArgs.length - j);
|
||||
}
|
||||
}
|
||||
|
||||
IType arg = fnArgs[j];
|
||||
int cmpSpecialized= deduceForPartialOrdering(par, arg, deduct);
|
||||
if (cmpSpecialized < 0)
|
||||
return cmpSpecialized;
|
||||
if (cmpSpecialized > 0)
|
||||
result= cmpSpecialized;
|
||||
}
|
||||
return result;
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
if (checkExactMatch) {
|
||||
IType instantiated= CPPTemplates.instantiateType(par, deduct.fDeducedArgs, deduct.fPackOffset, null);
|
||||
if (!instantiated.isSameType(arg))
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static int deduceForPartialOrdering(IType par, IType arg, TemplateArgumentDeduction deduct) throws DOMException {
|
||||
par= getNestedType(par, TDEF);
|
||||
arg= getNestedType(arg, TDEF);
|
||||
boolean isMoreCVQualified= false;
|
||||
if (par instanceof ICPPReferenceType && arg instanceof ICPPReferenceType) {
|
||||
par= getNestedType(par, REF | TDEF);
|
||||
arg= getNestedType(arg, REF | TDEF);
|
||||
CVQualifier cvp= getCVQualifier(par);
|
||||
CVQualifier cva= getCVQualifier(arg);
|
||||
isMoreCVQualified= cva.isMoreQualifiedThan(cvp);
|
||||
}
|
||||
return true;
|
||||
par= getNestedType(par, TDEF | REF | ALLCVQ);
|
||||
arg= getNestedType(arg, TDEF | REF | ALLCVQ);
|
||||
|
||||
if (!deduct.fromType(par, arg, false))
|
||||
return -1;
|
||||
|
||||
return isMoreCVQualified ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 14.8.2.1.3 If P is a class and has the form template-id, then A can be a derived class of the deduced A.
|
||||
* @throws DOMException
|
||||
*/
|
||||
private static ICPPClassType findBaseInstance(ICPPClassType a, ICPPClassTemplate pTemplate, int maxdepth) throws DOMException {
|
||||
if (a instanceof ICPPTemplateInstance) {
|
||||
|
@ -519,6 +592,14 @@ public class TemplateArgumentDeduction {
|
|||
fPackSize= packSize;
|
||||
fPackOffset= packSize > 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
private CPPTemplateParameterMap saveState() {
|
||||
return new CPPTemplateParameterMap(fDeducedArgs);
|
||||
}
|
||||
|
||||
private void restoreState(CPPTemplateParameterMap saved) {
|
||||
fDeducedArgs= saved;
|
||||
}
|
||||
|
||||
private void incPackOffset() {
|
||||
fPackOffset++;
|
||||
|
@ -535,15 +616,21 @@ public class TemplateArgumentDeduction {
|
|||
if (p.isNonTypeValue()) {
|
||||
IValue tval= p.getNonTypeValue();
|
||||
|
||||
int parId= Value.isTemplateParameter(tval);
|
||||
if (parId >= 0) {
|
||||
ICPPTemplateArgument old= fDeducedArgs.getArgument(parId, fPackOffset);
|
||||
if (old == null) {
|
||||
return deduce(parId, a);
|
||||
if (Value.referencesTemplateParameter(tval)) {
|
||||
int parId= Value.isTemplateParameter(tval);
|
||||
if (parId >= 0) {
|
||||
if (!p.getTypeOfNonTypeValue().isSameType(a.getTypeOfNonTypeValue()))
|
||||
return false;
|
||||
ICPPTemplateArgument old= fDeducedArgs.getArgument(parId, fPackOffset);
|
||||
if (old == null) {
|
||||
return deduce(parId, a);
|
||||
}
|
||||
return old.isSameValue(a);
|
||||
} else {
|
||||
// Non-deduced context
|
||||
return true;
|
||||
}
|
||||
return old.isSameValue(a);
|
||||
}
|
||||
|
||||
IValue sval= a.getNonTypeValue();
|
||||
return tval.equals(sval);
|
||||
}
|
||||
|
@ -758,6 +845,8 @@ public class TemplateArgumentDeduction {
|
|||
return false;
|
||||
return fDeducedArgs.putPackElement(parID, fPackOffset, arg, fPackSize);
|
||||
}
|
||||
if (SemanticUtil.containsUniqueTypeForParameterPack(arg.getTypeValue()))
|
||||
return false;
|
||||
fDeducedArgs.put(parID, arg);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* UniqueType.java
|
||||
* Created on 04.10.2010
|
||||
*
|
||||
* Copyright 2010 Wind River Systems, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
|
||||
/**
|
||||
* Used for computing the partial ordering of function templates.
|
||||
*/
|
||||
class UniqueType implements IType {
|
||||
|
||||
private boolean fForParameterPack;
|
||||
|
||||
public UniqueType(boolean forParameterPack) {
|
||||
fForParameterPack= forParameterPack;
|
||||
}
|
||||
|
||||
public boolean isSameType(IType type) {
|
||||
return type == this;
|
||||
}
|
||||
|
||||
public boolean isForParameterPack() {
|
||||
return fForParameterPack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue