mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 14:42:11 +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 org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
|
||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||
|
||||
/**
|
||||
|
@ -60,59 +58,7 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
|
|||
public void _test7_3_3s12() throws Exception { // raised bug 161562 for that
|
||||
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 D : public B<T> {};
|
||||
// struct D2 : public B<int> {};
|
||||
|
@ -128,19 +74,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
|
|||
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>
|
||||
// T deduce(typename A<T>::X x, // T is not 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 {
|
||||
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);
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// template <class T> void f(T);
|
||||
// void g(int);
|
||||
|
@ -5364,7 +5380,8 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
// template <> void f<int>(int*); // OK
|
||||
// template <> void f(int); // OK
|
||||
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) { }
|
||||
|
@ -5467,6 +5484,19 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
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 {
|
||||
// struct B { };
|
||||
// template<int X> void f();
|
||||
|
@ -5545,6 +5575,26 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
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 <signed char> int f(int);
|
||||
// int i1 = f<1>(0); // ambiguous
|
||||
|
@ -5707,6 +5757,19 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
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
|
||||
// void g() {
|
||||
// f("Annemarie"); // call of f<const char*>
|
||||
|
@ -6209,6 +6272,21 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
|
|||
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, int J> void f/*1*/(A<I+J>); // #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);
|
||||
|
||||
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);
|
||||
|
||||
ICPPTemplateNonTypeParameter np1 = ba.assertNonProblem("I)", 1, ICPPTemplateNonTypeParameter.class);
|
||||
|
@ -2978,7 +2978,7 @@ public class AST2TemplateTests extends AST2BaseTest {
|
|||
assertFalse(th1sCtor instanceof ICPPSpecialization);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -3294,4 +3294,50 @@ public class AST2TemplateTests extends AST2BaseTest {
|
|||
public void testNewOfThisTemplate() throws Exception {
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1445,7 +1445,7 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
|
|||
assertFalse(th1sCtor instanceof ICPPSpecialization);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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.ICPPScope;
|
||||
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.ICPPTemplateScope;
|
||||
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPBasicType;
|
||||
|
@ -331,6 +332,10 @@ public class ASTTypeUtil {
|
|||
} else {
|
||||
result.append(getNameForAnonymous((ICompositeType) type));
|
||||
}
|
||||
if (type instanceof ICPPTemplateInstance) {
|
||||
ICPPTemplateInstance inst = (ICPPTemplateInstance) type;
|
||||
result.append(getArgumentListString(inst.getTemplateArguments(), normalize));
|
||||
}
|
||||
} else if (type instanceof ICPPReferenceType) {
|
||||
result.append(Keywords.cpAMPER);
|
||||
} else if (type instanceof IEnumeration) {
|
||||
|
|
|
@ -106,6 +106,6 @@ public class CPPDeferredClassInstance extends CPPUnknownClass implements ICPPDef
|
|||
|
||||
@Override
|
||||
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
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* Andrew Niefer (IBM) - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
/*
|
||||
* Created on Feb 11, 2005
|
||||
*/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
* Models pointer to members.
|
||||
*/
|
||||
public class CPPPointerToMemberType extends CPPPointerType implements ICPPPointerToMemberType {
|
||||
private ICPPASTPointerToMember operator;
|
||||
|
@ -83,7 +80,7 @@ public class CPPPointerToMemberType extends CPPPointerType implements ICPPPointe
|
|||
name = ns[ns.length - 1];
|
||||
}
|
||||
|
||||
IBinding binding = name.resolveBinding();
|
||||
IBinding binding = CPPASTNameBase.resolvePreBinding(name);
|
||||
if (binding instanceof IType) {
|
||||
classType = (IType) binding;
|
||||
} else {
|
||||
|
|
|
@ -370,13 +370,13 @@ public class CPPSemantics {
|
|||
}
|
||||
|
||||
if (binding != null && !(binding instanceof IProblemBinding)) {
|
||||
if (data.forDefinition()) {
|
||||
if (data.forFunctionDeclaration()) {
|
||||
addDefinition(binding, data.astName);
|
||||
}
|
||||
}
|
||||
// If we're still 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());
|
||||
else
|
||||
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, data.name());
|
||||
|
@ -1563,10 +1563,11 @@ public class CPPSemantics {
|
|||
return null;
|
||||
|
||||
// specialization is selected during instantiation
|
||||
if (candidate instanceof ICPPTemplateInstance && candidate instanceof IType)
|
||||
if (candidate instanceof ICPPTemplateInstance)
|
||||
candidate= ((ICPPTemplateInstance) candidate).getSpecializedBinding();
|
||||
|
||||
return candidate;
|
||||
if (!(candidate instanceof ICPPFunctionTemplate))
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1736,6 +1737,12 @@ public class CPPSemantics {
|
|||
items = (Object[]) data.foundItems;
|
||||
continue;
|
||||
} else if (temp instanceof IFunction) {
|
||||
if (temp instanceof ICPPTemplateInstance) {
|
||||
temp= ((ICPPTemplateInstance) temp).getSpecializedBinding();
|
||||
if (!(temp instanceof IFunction))
|
||||
continue;
|
||||
}
|
||||
|
||||
IFunction function= (IFunction) temp;
|
||||
if (function instanceof ICPPFunctionTemplate) {
|
||||
if (templateFns == ObjectSet.EMPTY_SET)
|
||||
|
@ -1811,7 +1818,8 @@ public class CPPSemantics {
|
|||
|
||||
int numTemplateFns = templateFns.size();
|
||||
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);
|
||||
if (fs != null && fs.length > 0) {
|
||||
if (fns == ObjectSet.EMPTY_SET)
|
||||
|
@ -1853,19 +1861,6 @@ public class CPPSemantics {
|
|||
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{
|
||||
if (functions == null || functions.length == 0)
|
||||
return;
|
||||
|
@ -1873,7 +1868,7 @@ public class CPPSemantics {
|
|||
Object[] fParams = data.functionParameters;
|
||||
int numParameters = (fParams != null) ? fParams.length : 0;
|
||||
int num;
|
||||
boolean def = data.forDefinition();
|
||||
boolean def = data.forFunctionDeclaration();
|
||||
// Trim the list down to the set of viable functions
|
||||
IFunction function = null;
|
||||
int size = functions.length;
|
||||
|
@ -1926,30 +1921,13 @@ public class CPPSemantics {
|
|||
}
|
||||
}
|
||||
}
|
||||
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();
|
||||
while (node instanceof IASTName)
|
||||
node = node.getParent();
|
||||
if (!(node instanceof ICPPASTFunctionDeclarator))
|
||||
return false;
|
||||
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) {
|
||||
}
|
||||
static private boolean isMatchingFunctionDeclaration(IFunction candidate, LookupData data) {
|
||||
IASTNode node = data.astName.getParent();
|
||||
while (node instanceof IASTName)
|
||||
node = node.getParent();
|
||||
if (node instanceof IASTDeclarator) {
|
||||
return isSameFunction(candidate, (IASTDeclarator) node);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2028,7 +2006,7 @@ public class CPPSemantics {
|
|||
deferredOnly= false;
|
||||
}
|
||||
}
|
||||
if (deferredOnly || data.forDefinition() || data.forExplicitInstantiation()) {
|
||||
if (deferredOnly || data.forFunctionDeclaration()) {
|
||||
for (IFunction fn : fns) {
|
||||
if (fn != null) {
|
||||
return fn;
|
||||
|
@ -2147,6 +2125,7 @@ public class CPPSemantics {
|
|||
// then this is an ambiguity (unless we find something better than both later).
|
||||
ambiguous |= (hasWorse && hasBetter) || (!hasWorse && !hasBetter);
|
||||
|
||||
// mstodo if ambigous ??
|
||||
if (!hasWorse) {
|
||||
// If they are both template functions, we can order them that way
|
||||
ICPPFunctionTemplate bestAsTemplate= asTemplate(bestFn);
|
||||
|
@ -2336,10 +2315,10 @@ public class CPPSemantics {
|
|||
break;
|
||||
}
|
||||
}
|
||||
ICPPTemplateDefinition template = (ICPPTemplateDefinition) id.getTemplateName().resolveBinding();
|
||||
if (template != null) {
|
||||
IBinding template =id.getTemplateName().resolveBinding();
|
||||
if (template instanceof ICPPTemplateDefinition) {
|
||||
try {
|
||||
ICPPTemplateParameter[] ps = template.getTemplateParameters();
|
||||
ICPPTemplateParameter[] ps = ((ICPPTemplateDefinition)template).getTemplateParameters();
|
||||
if (i < args.length && i < ps.length && ps[i] instanceof ICPPTemplateNonTypeParameter) {
|
||||
return ((ICPPTemplateNonTypeParameter)ps[i]).getType();
|
||||
}
|
||||
|
@ -2668,20 +2647,24 @@ public class CPPSemantics {
|
|||
}
|
||||
|
||||
public static boolean isSameFunction(IFunction function, IASTDeclarator declarator) {
|
||||
IASTName name = declarator.getName();
|
||||
IASTName name = CPPVisitor.findInnermostDeclarator(declarator).getName();
|
||||
ICPPASTTemplateDeclaration templateDecl = CPPTemplates.getTemplateDeclaration(name);
|
||||
|
||||
boolean fnIsTemplate = (function instanceof ICPPFunctionTemplate);
|
||||
boolean dtorIsTemplate = (templateDecl != null);
|
||||
if (fnIsTemplate && dtorIsTemplate) {
|
||||
return CPPTemplates.isSameTemplate((ICPPTemplateDefinition)function, name);
|
||||
} else if (fnIsTemplate ^ dtorIsTemplate) {
|
||||
return false;
|
||||
if (templateDecl != null) {
|
||||
if (templateDecl instanceof ICPPASTTemplateSpecialization) {
|
||||
if (!(function instanceof ICPPTemplateInstance))
|
||||
return false;
|
||||
} else {
|
||||
if (!(function instanceof ICPPTemplateDefinition))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
IType type = null;
|
||||
|
||||
declarator= CPPVisitor.findTypeRelevantDeclarator(declarator);
|
||||
try {
|
||||
type = function.getType();
|
||||
return type.isSameType(CPPVisitor.createType(declarator));
|
||||
if (declarator instanceof ICPPASTFunctionDeclarator) {
|
||||
IType type = function.getType();
|
||||
return type.isSameType(CPPVisitor.createType(declarator));
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
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.IValue;
|
||||
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.ICPPASTExplicitTemplateInstantiation;
|
||||
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.ICPPASTTemplateId;
|
||||
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.ICPPClassSpecialization;
|
||||
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.ICPPTemplateParameter;
|
||||
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.ICPPTemplateTypeParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||
|
@ -173,7 +170,7 @@ public class CPPTemplates {
|
|||
return instance;
|
||||
|
||||
CPPTemplateParameterMap tpMap= new CPPTemplateParameterMap(args.length);
|
||||
if (!CPPTemplates.deduceTemplateParameterMap(partialSpec.getTemplateArguments(), args, true, tpMap))
|
||||
if (!CPPTemplates.deduceTemplateParameterMap(partialSpec.getTemplateArguments(), args, tpMap))
|
||||
return null;
|
||||
|
||||
ICPPTemplateParameter[] params= partialSpec.getTemplateParameters();
|
||||
|
@ -303,17 +300,22 @@ public class CPPTemplates {
|
|||
* Instantiates the template for usage within its own body. May return <code>null</code>.
|
||||
*/
|
||||
public static IBinding instantiateWithinClassTemplate(ICPPClassTemplate template) throws DOMException {
|
||||
ICPPTemplateParameter[] templateParameters = template.getTemplateParameters();
|
||||
ICPPTemplateArgument[] args = new ICPPTemplateArgument[templateParameters.length];
|
||||
for (int i = 0; i < templateParameters.length; i++) {
|
||||
final ICPPTemplateParameter tp = templateParameters[i];
|
||||
if (tp instanceof IType) {
|
||||
args[i] = new CPPTemplateArgument((IType) tp);
|
||||
} else if (tp instanceof ICPPTemplateNonTypeParameter) {
|
||||
final ICPPTemplateNonTypeParameter nttp = (ICPPTemplateNonTypeParameter) tp;
|
||||
args[i] = new CPPTemplateArgument(Value.create(nttp), nttp.getType());
|
||||
} else {
|
||||
assert false;
|
||||
ICPPTemplateArgument[] args;
|
||||
if (template instanceof ICPPClassTemplatePartialSpecialization) {
|
||||
args= ((ICPPClassTemplatePartialSpecialization) template).getTemplateArguments();
|
||||
} else {
|
||||
ICPPTemplateParameter[] templateParameters = template.getTemplateParameters();
|
||||
args = new ICPPTemplateArgument[templateParameters.length];
|
||||
for (int i = 0; i < templateParameters.length; i++) {
|
||||
final ICPPTemplateParameter tp = templateParameters[i];
|
||||
if (tp instanceof IType) {
|
||||
args[i] = new CPPTemplateArgument((IType) tp);
|
||||
} else if (tp instanceof ICPPTemplateNonTypeParameter) {
|
||||
final ICPPTemplateNonTypeParameter nttp = (ICPPTemplateNonTypeParameter) tp;
|
||||
args[i] = new CPPTemplateArgument(Value.create(nttp), nttp.getType());
|
||||
} else {
|
||||
assert false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return deferredInstance(template, args);
|
||||
|
@ -425,388 +427,159 @@ public class CPPTemplates {
|
|||
}
|
||||
|
||||
public static IBinding createBinding(ICPPASTTemplateId id) {
|
||||
IASTNode parent = id.getParent();
|
||||
boolean isLastName= true;
|
||||
if (parent instanceof ICPPASTQualifiedName) {
|
||||
isLastName= ((ICPPASTQualifiedName) parent).getLastName() == id;
|
||||
parent = parent.getParent();
|
||||
}
|
||||
|
||||
IASTNode decl= parent;
|
||||
while (decl != null) {
|
||||
if (decl instanceof IASTDeclaration) {
|
||||
decl= decl.getParent();
|
||||
break;
|
||||
}
|
||||
decl= decl.getParent();
|
||||
}
|
||||
|
||||
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
|
||||
IASTName templateName = id.getTemplateName();
|
||||
IBinding template = templateName.resolveBinding();
|
||||
if (template instanceof ICPPUnknownClassInstance) {
|
||||
// mstodo we should not get here, rather than that an unknown class
|
||||
// should be made to an unknown class instance here
|
||||
return template;
|
||||
}
|
||||
if (template instanceof ICPPConstructor) {
|
||||
template= template.getOwner();
|
||||
}
|
||||
|
||||
if (!(template instanceof ICPPClassTemplate) || template instanceof ICPPClassTemplatePartialSpecialization)
|
||||
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TYPE, templateName.toCharArray());
|
||||
|
||||
final ICPPClassTemplate classTemplate = (ICPPClassTemplate) template;
|
||||
ICPPTemplateArgument[] args= createTemplateArgumentArray(id);
|
||||
ICPPASTTemplateDeclaration tdecl= getTemplateDeclaration(id);
|
||||
if (tdecl != null) {
|
||||
if (hasDependentArgument(args)) {
|
||||
IBinding result= null;
|
||||
if (argsAreTrivial(classTemplate.getTemplateParameters(), args)) {
|
||||
result= classTemplate;
|
||||
} else {
|
||||
ICPPClassTemplatePartialSpecialization partialSpec= findPartialSpecialization(classTemplate, args);
|
||||
if (partialSpec == null)
|
||||
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TYPE, templateName.toCharArray());
|
||||
result= partialSpec;
|
||||
}
|
||||
if (isClassDecl && result instanceof ICPPInternalBinding)
|
||||
((ICPPInternalBinding) result).addDeclaration(id);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
IBinding instance= instantiate(classTemplate, args);
|
||||
return CPPSemantics.postResolution(instance, id);
|
||||
}
|
||||
|
||||
if (!isClassTemplate(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());
|
||||
IBinding result= CPPVisitor.createBinding(id);
|
||||
IASTName templateName = id.getTemplateName();
|
||||
if (result instanceof ICPPTemplateInstance) {
|
||||
templateName.setBinding(((ICPPTemplateInstance) result).getTemplateDefinition());
|
||||
} else {
|
||||
templateName.setBinding(result);
|
||||
}
|
||||
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;
|
||||
return result;
|
||||
}
|
||||
|
||||
// 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;
|
||||
IASTNode parentOfName = id.getParent();
|
||||
boolean isLastName= true;
|
||||
if (parentOfName instanceof ICPPASTQualifiedName) {
|
||||
isLastName= ((ICPPASTQualifiedName) parentOfName).getLastName() == id;
|
||||
parentOfName = parentOfName.getParent();
|
||||
}
|
||||
|
||||
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());
|
||||
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;
|
||||
}
|
||||
parentOfDeclaration= parentOfDeclaration.getParent();
|
||||
}
|
||||
result= function;
|
||||
} else {
|
||||
result= getInstance(function, args);
|
||||
if (result == null) {
|
||||
IBinding owner= function.getOwner();
|
||||
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 (parent instanceof IASTSimpleDeclaration)
|
||||
((ICPPInternalBinding) result).addDeclaration(name);
|
||||
else if (parent instanceof IASTFunctionDefinition)
|
||||
((ICPPInternalBinding) result).addDefinition(name);
|
||||
}
|
||||
return result;
|
||||
isDecl= !(parentOfDeclaration instanceof ICPPASTExplicitTemplateInstantiation);
|
||||
} else if (parentOfName instanceof ICPPASTCompositeTypeSpecifier) {
|
||||
isDef= true;
|
||||
}
|
||||
}
|
||||
try {
|
||||
// class template instance
|
||||
IBinding result= null;
|
||||
IASTName templateName = id.getTemplateName();
|
||||
IBinding template = templateName.resolveBinding();
|
||||
if (template instanceof ICPPUnknownClassInstance) {
|
||||
// mstodo we should not get here, rather than that an unknown class
|
||||
// should be made to an unknown class instance here
|
||||
return template;
|
||||
}
|
||||
if (template instanceof ICPPConstructor) {
|
||||
template= template.getOwner();
|
||||
}
|
||||
|
||||
if (!(template instanceof ICPPClassTemplate) || template instanceof ICPPClassTemplatePartialSpecialization)
|
||||
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TYPE, templateName.toCharArray());
|
||||
|
||||
final ICPPClassTemplate classTemplate = (ICPPClassTemplate) template;
|
||||
ICPPTemplateArgument[] args= createTemplateArgumentArray(id);
|
||||
ICPPASTTemplateDeclaration tdecl= getTemplateDeclaration(id);
|
||||
if (tdecl != null) {
|
||||
if (hasDependentArgument(args)) {
|
||||
if (argsAreTrivial(classTemplate.getTemplateParameters(), args)) {
|
||||
result= classTemplate;
|
||||
} else {
|
||||
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)
|
||||
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TYPE, templateName.toCharArray());
|
||||
result= partialSpec;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result == null) {
|
||||
result= instantiate(classTemplate, args);
|
||||
if (result instanceof ICPPInternalBinding) {
|
||||
if (isDecl) {
|
||||
((ICPPInternalBinding) result).addDeclaration(id);
|
||||
} else if (isDef) {
|
||||
((ICPPInternalBinding) result).addDefinition(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
return CPPSemantics.postResolution(result, id);
|
||||
} catch (DOMException e) {
|
||||
return e.getProblem();
|
||||
}
|
||||
}
|
||||
|
||||
static protected ICPPFunctionTemplate resolveTemplateFunctions(Object[] items, IASTName name) {
|
||||
if (items == null)
|
||||
return null;
|
||||
ICPPFunctionTemplate[] templates = null;
|
||||
IBinding temp = null;
|
||||
for (Object o : items) {
|
||||
if (o instanceof IASTName) {
|
||||
temp = ((IASTName) o).resolveBinding();
|
||||
if (temp == null)
|
||||
continue;
|
||||
} else if (o instanceof IBinding) {
|
||||
temp = (IBinding) o;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
static boolean isClassTemplate(ICPPASTTemplateId id) {
|
||||
IASTNode parentOfName = id.getParent();
|
||||
|
||||
if (temp instanceof ICPPTemplateInstance)
|
||||
temp = ((ICPPTemplateInstance) temp).getTemplateDefinition();
|
||||
if (temp instanceof ICPPFunctionTemplate)
|
||||
templates = (ICPPFunctionTemplate[]) ArrayUtil.append(ICPPFunctionTemplate.class, templates, temp);
|
||||
if (parentOfName instanceof ICPPASTQualifiedName) {
|
||||
if (((ICPPASTQualifiedName) parentOfName).getLastName() != id)
|
||||
return true;
|
||||
parentOfName= parentOfName.getParent();
|
||||
}
|
||||
|
||||
if (templates == null)
|
||||
return null;
|
||||
|
||||
ICPPTemplateArgument[] templateArguments = null;
|
||||
|
||||
if (name instanceof ICPPASTTemplateId) {
|
||||
try {
|
||||
templateArguments= createTemplateArgumentArray((ICPPASTTemplateId) name);
|
||||
} catch (DOMException e) {
|
||||
return null;
|
||||
IASTNode parentOfDeclaration= parentOfName;
|
||||
while (parentOfDeclaration != null) {
|
||||
if (parentOfDeclaration instanceof IASTDeclaration) {
|
||||
parentOfDeclaration= parentOfDeclaration.getParent();
|
||||
break;
|
||||
}
|
||||
}
|
||||
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;
|
||||
parentOfDeclaration= parentOfDeclaration.getParent();
|
||||
}
|
||||
|
||||
return result;
|
||||
return parentOfName instanceof ICPPASTElaboratedTypeSpecifier ||
|
||||
parentOfName instanceof ICPPASTCompositeTypeSpecifier ||
|
||||
parentOfName instanceof ICPPASTNamedTypeSpecifier ||
|
||||
parentOfName instanceof ICPPASTBaseSpecifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deduce arguments for a template function from the template id + the template function parameters.
|
||||
*/
|
||||
static protected ICPPTemplateArgument[] deduceTemplateFunctionArguments(ICPPFunctionTemplate primaryTemplate,
|
||||
IASTParameterDeclaration[] ps, ICPPASTTemplateId id, CPPTemplateParameterMap map) throws DOMException {
|
||||
ICPPTemplateParameter[] templateParameters = primaryTemplate.getTemplateParameters();
|
||||
ICPPTemplateArgument[] arguments= createTemplateArgumentArray(id);
|
||||
ICPPTemplateArgument[] result = new ICPPTemplateArgument[templateParameters.length];
|
||||
|
||||
arguments= SemanticUtil.getSimplifiedArguments(arguments);
|
||||
if (arguments.length == result.length) {
|
||||
for (int i = 0; i < templateParameters.length; i++) {
|
||||
result[i] = arguments[i];
|
||||
map.put(templateParameters[i], arguments[i]);
|
||||
}
|
||||
return result;
|
||||
static private ICPPTemplateArgument[] deduceTemplateFunctionArguments(ICPPFunctionTemplate template,
|
||||
ICPPTemplateArgument[] tmplArgs, IType[] fnArgs, CPPTemplateParameterMap map) throws DOMException {
|
||||
final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters();
|
||||
final int length = tmplParams.length;
|
||||
if (tmplArgs.length > length)
|
||||
return null;
|
||||
|
||||
ICPPTemplateArgument[] result = new ICPPTemplateArgument[length];
|
||||
tmplArgs= SemanticUtil.getSimplifiedArguments(tmplArgs);
|
||||
for (int i = 0; i < tmplArgs.length; i++) {
|
||||
ICPPTemplateArgument tmplArg= tmplArgs[i];
|
||||
final ICPPTemplateParameter tmplParam= tmplParams[i];
|
||||
tmplArg= matchTemplateParameterAndArgument(tmplParam, tmplArg, map);
|
||||
if (tmplArg == null)
|
||||
return null;
|
||||
|
||||
map.put(tmplParam, tmplArg);
|
||||
result[i]= tmplArg;
|
||||
}
|
||||
|
||||
//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)
|
||||
|
||||
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] = arg;
|
||||
result[i]= deducedArg;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return null;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static ICPPTemplateInstance createInstance(IBinding owner, ICPPTemplateDefinition template,
|
||||
|
@ -868,7 +641,16 @@ public class CPPTemplates {
|
|||
public static IValue instantiateValue(IValue value, ICPPTemplateParameterMap tpMap) {
|
||||
if (value == 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;
|
||||
}
|
||||
|
||||
|
@ -938,10 +720,12 @@ public class CPPTemplates {
|
|||
ICPPPointerToMemberType ptm = (ICPPPointerToMemberType) type;
|
||||
IType memberOfClass = ptm.getMemberOfClass();
|
||||
IType newMemberOfClass = instantiateType(memberOfClass, tpMap, within);
|
||||
if ((newNestedType != nestedType || newMemberOfClass != memberOfClass) &&
|
||||
newMemberOfClass instanceof ICPPClassType) {
|
||||
return new CPPPointerToMemberType(newNestedType, (ICPPClassType) newMemberOfClass,
|
||||
if (newNestedType != nestedType || newMemberOfClass != memberOfClass) {
|
||||
if (newMemberOfClass instanceof ICPPClassType) {
|
||||
return new CPPPointerToMemberType(newNestedType, (ICPPClassType) newMemberOfClass,
|
||||
ptm.isConst(), ptm.isVolatile());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
||||
if (newNestedType != nestedType) {
|
||||
|
@ -1203,12 +987,8 @@ public class CPPTemplates {
|
|||
ICPPClassTemplatePartialSpecialization spec = (ICPPClassTemplatePartialSpecialization) definition;
|
||||
ICPPTemplateArgument[] args= createTemplateArgumentArray((ICPPASTTemplateId)name);
|
||||
ICPPTemplateArgument[] specArgs = spec.getTemplateArguments();
|
||||
if (args.length == specArgs.length) {
|
||||
for (int i=0; i < args.length; i++) {
|
||||
if (!specArgs[i].isSameValue(args[i]))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!areSameArguments(args, specArgs))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1219,6 +999,16 @@ public class CPPTemplates {
|
|||
}
|
||||
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
|
||||
|
@ -1285,62 +1075,31 @@ public class CPPTemplates {
|
|||
if (templates == null || templates.size() == 0)
|
||||
return null;
|
||||
|
||||
IFunction[] instances = null;
|
||||
|
||||
int size = templates.size();
|
||||
|
||||
int numTemplateArgs = 0;
|
||||
ICPPTemplateArgument[] templateArguments = null;
|
||||
if (name instanceof ICPPASTTemplateId) {
|
||||
ICPPTemplateArgument[] templateArguments = ICPPTemplateArgument.EMPTY_ARGUMENTS;
|
||||
if (name instanceof ICPPASTTemplateId) {
|
||||
try {
|
||||
templateArguments = createTemplateArgumentArray((ICPPASTTemplateId) name);
|
||||
} catch (DOMException e) {
|
||||
return new IFunction[0];
|
||||
}
|
||||
numTemplateArgs = templateArguments.length;
|
||||
}
|
||||
final IType[] fnArgs= createTypeArray(functionArguments);
|
||||
|
||||
IType[] fnArgs= createTypeArray(functionArguments);
|
||||
|
||||
outer: for (int idx = 0; idx < size; idx++) {
|
||||
IFunction[] instances= null;
|
||||
final int size = templates.size();
|
||||
for (int idx = 0; idx < size; idx++) {
|
||||
ICPPFunctionTemplate template = (ICPPFunctionTemplate) templates.keyAt(idx);
|
||||
|
||||
CPPTemplateParameterMap map= new CPPTemplateParameterMap(fnArgs.length);
|
||||
try {
|
||||
if (!deduceTemplateParameterMapFromFunctionParameters(template, fnArgs, map))
|
||||
continue;
|
||||
} catch (DOMException e) {
|
||||
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);
|
||||
ICPPTemplateArgument[] args= deduceTemplateFunctionArguments(template, templateArguments, fnArgs, map);
|
||||
if (args != null) {
|
||||
IBinding temp= instantiate(template, args);
|
||||
if (temp instanceof IFunction) {
|
||||
instances = (IFunction[]) ArrayUtil.append(IFunction.class, instances, temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
instanceArgs= (ICPPTemplateArgument[]) ArrayUtil.trim(ICPPTemplateArgument.class, instanceArgs);
|
||||
IBinding temp= instantiate(template, instanceArgs);
|
||||
if (temp instanceof IFunction) {
|
||||
instances = (IFunction[]) ArrayUtil.append(IFunction.class, instances, temp);
|
||||
} catch (DOMException e) {
|
||||
// try next candidate
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1351,41 +1110,36 @@ public class CPPTemplates {
|
|||
* Deduces the mapping for the template parameters from the function parameters,
|
||||
* 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;
|
||||
IType[] functionParameters = null;
|
||||
try {
|
||||
functionParameters = function.getType().getParameterTypes();
|
||||
return deduceTemplateParameterMap(functionParameters, arguments, false, map);
|
||||
IType[] fnPars = function.getType().getParameterTypes();
|
||||
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) {
|
||||
}
|
||||
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.
|
||||
*/
|
||||
public static boolean deduceTemplateParameterMap(final ICPPTemplateArgument[] p, final ICPPTemplateArgument[] a, final boolean all, CPPTemplateParameterMap map) throws DOMException {
|
||||
if (p == null || (all && p.length != a.length)) {
|
||||
public static boolean deduceTemplateParameterMap(final ICPPTemplateArgument[] p, final ICPPTemplateArgument[] a, CPPTemplateParameterMap map) throws DOMException {
|
||||
final int len= a.length;
|
||||
if (p == null || p.length != len) {
|
||||
return false;
|
||||
}
|
||||
int len= Math.min(p.length, a.length);
|
||||
for (int j=0; j<len; j++) {
|
||||
if (!deduceTemplateParameterMap(p[j], a[j], map)) {
|
||||
return false;
|
||||
|
@ -1691,7 +1445,7 @@ public class CPPTemplates {
|
|||
boolean bestMatchIsBest = true;
|
||||
for (int i = 0; i < size; 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);
|
||||
if (compare == 0) {
|
||||
bestMatchIsBest = false;
|
||||
|
@ -1781,14 +1535,12 @@ public class CPPTemplates {
|
|||
*/
|
||||
static private ICPPFunctionTemplate classTemplateSpecializationToFunctionTemplate(ICPPClassTemplatePartialSpecialization specialization) {
|
||||
try {
|
||||
ICPPTemplateDefinition template = specialization;
|
||||
ICPPTemplateArgument[] args= specialization.getTemplateArguments();
|
||||
|
||||
IType paramType = (IType) instantiate(template, args);
|
||||
if (paramType == null)
|
||||
// ICPPTemplateArgument[] args= specialization.getTemplateArguments();
|
||||
IBinding paramType = instantiateWithinClassTemplate(specialization);
|
||||
if (!(paramType instanceof IType))
|
||||
return null;
|
||||
|
||||
IParameter[] functionParameters = new IParameter[] { new CPPParameter(paramType) };
|
||||
IParameter[] functionParameters = new IParameter[] { new CPPParameter((IType) paramType) };
|
||||
|
||||
return new CPPImplicitFunctionTemplate(specialization.getTemplateParameters(), functionParameters);
|
||||
} catch (DOMException e) {
|
||||
|
@ -1796,8 +1548,7 @@ public class CPPTemplates {
|
|||
}
|
||||
}
|
||||
|
||||
static private boolean isValidArgument(ICPPTemplateParameter param, ICPPTemplateArgument argument) {
|
||||
IType t= argument.getTypeValue();
|
||||
static private boolean isValidType(IType t) {
|
||||
try {
|
||||
while (t instanceof ITypeContainer) {
|
||||
t = ((ITypeContainer) t).getType();
|
||||
|
@ -1810,7 +1561,7 @@ public class CPPTemplates {
|
|||
|
||||
static protected ICPPTemplateArgument matchTemplateParameterAndArgument(ICPPTemplateParameter param,
|
||||
ICPPTemplateArgument arg, CPPTemplateParameterMap map) {
|
||||
if (arg == null || !isValidArgument(param, arg)) {
|
||||
if (arg == null || !isValidType(arg.getTypeValue())) {
|
||||
return null;
|
||||
}
|
||||
if (param instanceof ICPPTemplateTypeParameter) {
|
||||
|
@ -1904,7 +1655,7 @@ public class CPPTemplates {
|
|||
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) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1940,11 +1691,33 @@ public class CPPTemplates {
|
|||
}
|
||||
|
||||
public static boolean isDependentType(IType t) {
|
||||
// mstodo needs to be extended
|
||||
if (t instanceof ICPPTemplateParameter)
|
||||
return true;
|
||||
t = SemanticUtil.getUltimateType(t, false);
|
||||
return t instanceof ICPPUnknownBinding;
|
||||
try {
|
||||
while (true) {
|
||||
if (t instanceof ICPPTemplateParameter || t instanceof ICPPUnknownBinding)
|
||||
return true;
|
||||
if (t instanceof ICPPFunctionType) {
|
||||
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) {
|
||||
|
|
|
@ -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.ICPPASTFieldReference;
|
||||
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.ICPPASTLinkageSpecification;
|
||||
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.ICPPClassScope;
|
||||
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.ICPPConstructor;
|
||||
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.ICPPScope;
|
||||
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.ICPPTemplateParameter;
|
||||
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.GPPPointerToMemberType;
|
||||
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.ICPPInternalFunction;
|
||||
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 TYPE_INFO= "type_info"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* @param name
|
||||
*/
|
||||
public static IBinding createBinding(IASTName name) {
|
||||
IASTNode parent = name.getParent();
|
||||
IBinding binding = null;
|
||||
|
@ -200,8 +202,7 @@ public class CPPVisitor extends ASTQueries {
|
|||
parent instanceof ICPPASTQualifiedName ||
|
||||
parent instanceof ICPPASTBaseSpecifier ||
|
||||
parent instanceof ICPPASTConstructorChainInitializer ||
|
||||
name.getPropertyInParent() == ICPPASTNamespaceAlias.MAPPING_NAME ||
|
||||
parent instanceof ICPPASTTemplateId) {
|
||||
name.getPropertyInParent() == ICPPASTNamespaceAlias.MAPPING_NAME) {
|
||||
binding = CPPSemantics.resolveBinding(name);
|
||||
if (binding instanceof IProblemBinding && parent instanceof ICPPASTQualifiedName &&
|
||||
!(parent.getParent() instanceof ICPPASTNamespaceAlias)) {
|
||||
|
@ -225,7 +226,15 @@ public class CPPVisitor extends ASTQueries {
|
|||
} else {
|
||||
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) {
|
||||
return resolveBinding(parent);
|
||||
} else if (parent instanceof ICPPASTFieldReference) {
|
||||
|
@ -425,7 +434,7 @@ public class CPPVisitor extends ASTQueries {
|
|||
scope= (ICPPScope) scope.getParent();
|
||||
}
|
||||
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
|
||||
binding = scope.getBinding(name, false);
|
||||
|
@ -522,24 +531,36 @@ public class CPPVisitor extends ASTQueries {
|
|||
return candidate;
|
||||
}
|
||||
|
||||
ASTNodeProperty prop = parent.getPropertyInParent();
|
||||
if (parent instanceof IASTTypeId) {
|
||||
// function type
|
||||
if (parent instanceof IASTTypeId)
|
||||
return CPPSemantics.resolveBinding(name);
|
||||
} else if (prop == ICPPASTTemplateSpecialization.OWNED_DECLARATION ||
|
||||
prop == ICPPASTExplicitTemplateInstantiation.OWNED_DECLARATION) {
|
||||
try {
|
||||
return CPPTemplates.createFunctionSpecialization(name);
|
||||
} catch (DOMException e) {
|
||||
return e.getProblem();
|
||||
|
||||
// explicit instantiations
|
||||
ASTNodeProperty prop = parent.getPropertyInParent();
|
||||
if (prop == ICPPASTExplicitTemplateInstantiation.OWNED_DECLARATION)
|
||||
return CPPSemantics.resolveBinding(name);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// function declaration/defintion
|
||||
IBinding binding;
|
||||
ICPPScope scope = (ICPPScope) getContainingScope((IASTNode) name);
|
||||
|
||||
boolean template = false;
|
||||
boolean template= false;
|
||||
boolean isFriendDecl= false;
|
||||
try {
|
||||
while (scope instanceof ICPPTemplateScope) {
|
||||
template = true;
|
||||
|
@ -550,11 +571,13 @@ public class CPPVisitor extends ASTQueries {
|
|||
if (declSpec.isFriend()) {
|
||||
try {
|
||||
scope = (ICPPScope) getParentScope(scope, name.getTranslationUnit());
|
||||
isFriendDecl= true;
|
||||
} 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) {
|
||||
return e.getProblem();
|
||||
}
|
||||
|
@ -866,6 +889,20 @@ public class CPPVisitor extends ASTQueries {
|
|||
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) {
|
||||
IScope scope= getContainingScopeOrNull(name);
|
||||
if (scope == null) {
|
||||
|
@ -910,7 +947,11 @@ public class CPPVisitor extends ASTQueries {
|
|||
boolean done= true;
|
||||
IScope scope= null;
|
||||
if (binding instanceof ICPPClassType) {
|
||||
scope= ((ICPPClassType)binding).getCompositeScope();
|
||||
if (binding instanceof ICPPDeferredClassInstance) {
|
||||
scope= checkForSpecializedScope((ICPPDeferredClassInstance) binding, qname);
|
||||
}
|
||||
if (scope == null)
|
||||
scope= ((ICPPClassType)binding).getCompositeScope();
|
||||
} else if (binding instanceof ICPPNamespace) {
|
||||
scope= ((ICPPNamespace)binding).getNamespaceScope();
|
||||
} else if (binding instanceof ICPPUnknownBinding) {
|
||||
|
@ -956,6 +997,47 @@ public class CPPVisitor extends ASTQueries {
|
|||
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) {
|
||||
IASTNode parent = statement.getParent();
|
||||
IScope scope = null;
|
||||
|
@ -1495,36 +1577,7 @@ public class CPPVisitor extends ASTQueries {
|
|||
pt = createType(pDeclSpec);
|
||||
pt = createType(pt, pDtor);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
pt = SemanticUtil.adjustParameterType(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.ICPPASTTemplateDeclaration;
|
||||
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.ICPPASTUsingDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
||||
|
@ -160,7 +161,7 @@ class LookupData {
|
|||
return false;
|
||||
}
|
||||
|
||||
public boolean forDefinition() {
|
||||
public boolean forFunctionDeclaration() {
|
||||
if (astName == null) return false;
|
||||
if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false;
|
||||
|
||||
|
@ -169,39 +170,73 @@ class LookupData {
|
|||
n = (IASTName) n.getParent();
|
||||
IASTNode p1 = n.getParent();
|
||||
if (p1 instanceof ICPPASTQualifiedName) {
|
||||
IASTName[] ns = ((ICPPASTQualifiedName)p1).getNames();
|
||||
if (ns[ns.length - 1] != n)
|
||||
return false;
|
||||
if (((ICPPASTQualifiedName) p1).getLastName() != n)
|
||||
return false;
|
||||
p1 = p1.getParent();
|
||||
}
|
||||
IASTNode p2 = p1.getParent();
|
||||
if (p1 instanceof IASTDeclarator && p2 instanceof IASTSimpleDeclaration) {
|
||||
return !(p2.getParent() instanceof ICPPASTExplicitTemplateInstantiation);
|
||||
}
|
||||
return (p1 instanceof IASTDeclarator && p2 instanceof IASTFunctionDefinition);
|
||||
}
|
||||
|
||||
public boolean forExplicitInstantiation() {
|
||||
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) {
|
||||
IASTName[] ns = ((ICPPASTQualifiedName)p1).getNames();
|
||||
if (ns[ns.length - 1] != n)
|
||||
return false;
|
||||
p1 = p1.getParent();
|
||||
}
|
||||
IASTNode p2 = p1.getParent();
|
||||
if (p1 instanceof IASTDeclarator && p2 instanceof IASTSimpleDeclaration) {
|
||||
return (p2.getParent() instanceof ICPPASTExplicitTemplateInstantiation);
|
||||
if (p1 instanceof IASTDeclarator) {
|
||||
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 p2 instanceof IASTFunctionDefinition;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean forExplicitFunctionSpecialization() {
|
||||
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 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;
|
||||
}
|
||||
|
||||
private boolean considerConstructors() {
|
||||
if (astName == null) return false;
|
||||
if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false;
|
||||
|
@ -351,6 +386,14 @@ class LookupData {
|
|||
}
|
||||
return implied;
|
||||
}
|
||||
if (prop == IASTDeclarator.DECLARATOR_NAME) {
|
||||
if (forExplicitFunctionInstantiation()) {
|
||||
IScope scope = CPPVisitor.getContainingScope(astName);
|
||||
if (scope instanceof ICPPClassScope) {
|
||||
return ((ICPPClassScope)scope).getClassType();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
} catch (DOMException e) {
|
||||
return e.getProblem();
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
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.IArrayType;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||
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.internal.core.dom.parser.ITypeContainer;
|
||||
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.ICPPDeferredClassInstance;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
|
||||
|
@ -322,4 +324,41 @@ public class SemanticUtil {
|
|||
}
|
||||
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.IProblemBinding;
|
||||
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.ICPPClassTemplate;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeferredTemplateInstance;
|
||||
|
@ -240,7 +241,10 @@ abstract public class PDOMWriter {
|
|||
Throwable th= null;
|
||||
try {
|
||||
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++;
|
||||
if (fShowProblems) {
|
||||
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.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.ProblemBinding;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
|
||||
|
@ -243,7 +244,17 @@ public class PDOMCPPClassTemplate extends PDOMCPPClassType
|
|||
}
|
||||
try {
|
||||
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) {
|
||||
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.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.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.index.IIndexCPPBindingConstants;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
||||
|
@ -131,7 +134,17 @@ class PDOMCPPFunctionTemplate extends PDOMCPPFunction
|
|||
int pos = param.getParameterPosition();
|
||||
try {
|
||||
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) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue