1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-16 20:55:44 +02:00

Definitions of members of partial specializations, bug 177418.

This commit is contained in:
Markus Schorn 2008-11-14 09:31:43 +00:00
parent 0dea0424ac
commit 8e55e2392f
6 changed files with 243 additions and 140 deletions

View file

@ -1285,8 +1285,7 @@ public class AST2TemplateTests extends AST2BaseTest {
IBinding U2 = col.getName(10).resolveBinding(); IBinding U2 = col.getName(10).resolveBinding();
assertSame(U, U2); assertSame(U, U2);
assertTrue(f2 instanceof ICPPSpecialization); assertSame(f1, f2);
assertSame(((ICPPSpecialization)f2).getSpecializedBinding(), f1);
} }
// template<typename T> // template<typename T>
@ -1792,9 +1791,10 @@ public class AST2TemplateTests extends AST2BaseTest {
ICPPClassTemplate B = (ICPPClassTemplate) col.getName(4).resolveBinding(); ICPPClassTemplate B = (ICPPClassTemplate) col.getName(4).resolveBinding();
assertSame(T, col.getName(5).resolveBinding()); assertSame(T, col.getName(5).resolveBinding());
assertSame(T2, col.getName(6).resolveBinding()); final IBinding T2ofPartialSpec = col.getName(6).resolveBinding();
assertNotSame(T2, T2ofPartialSpec); // partial spec has its own template params
assertSame(T, col.getName(10).resolveBinding()); assertSame(T, col.getName(10).resolveBinding());
assertSame(T2, col.getName(14).resolveBinding()); assertSame(T2ofPartialSpec, col.getName(14).resolveBinding());
ICPPClassTemplatePartialSpecialization spec = (ICPPClassTemplatePartialSpecialization) col.getName(12).resolveBinding(); ICPPClassTemplatePartialSpecialization spec = (ICPPClassTemplatePartialSpecialization) col.getName(12).resolveBinding();
assertSame(spec.getPrimaryClassTemplate(), B); assertSame(spec.getPrimaryClassTemplate(), B);
@ -3234,7 +3234,7 @@ public class AST2TemplateTests extends AST2BaseTest {
@Override @Override
public void run() { public void run() {
try { try {
parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP); parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP);
} catch (Throwable e) { } catch (Throwable e) {
th[0]= e; th[0]= e;
} }
@ -3247,4 +3247,50 @@ public class AST2TemplateTests extends AST2BaseTest {
if (th[0] != null) if (th[0] != null)
throw th[0]; throw th[0];
} }
// template<class T, class U> class A {};
// template<class T> class A<T, int> {
// void foo(T t);
// };
// template<class T> void A<T, int>::foo(T t) {}
public void testBug177418() throws Exception {
IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP, true, true );
CPPNameCollector col = new CPPNameCollector();
tu.accept( col );
ICPPTemplateParameter T1 = (ICPPTemplateParameter) col.getName(0).resolveBinding();
ICPPTemplateParameter U = (ICPPTemplateParameter) col.getName(1).resolveBinding();
ICPPClassTemplate A = (ICPPClassTemplate) col.getName(2).resolveBinding();
ICPPTemplateParameter T2 = (ICPPTemplateParameter) col.getName(3).resolveBinding();
assertNotSame(T1, T2);
ICPPClassTemplatePartialSpecialization A2 = (ICPPClassTemplatePartialSpecialization) col.getName(4).resolveBinding();
assertSame(A2.getPrimaryClassTemplate(), A);
assertSame(A, col.getName(5).resolveBinding());
assertSame(T2, col.getName(6).resolveBinding());
ICPPMethod foo = (ICPPMethod) col.getName(7).resolveBinding();
assertSame(T2, col.getName(8).resolveBinding());
assertSame(T2, col.getName(10).resolveBinding());
ICPPParameter t = (ICPPParameter) col.getName(9).resolveBinding();
assertSame(A2, col.getName(12).resolveBinding());
assertSame(A, col.getName(13).resolveBinding());
assertSame(T2, col.getName(14).resolveBinding());
assertSame(foo, col.getName(15).resolveBinding());
assertSame(T2, col.getName(16).resolveBinding());
assertSame(t, col.getName(17).resolveBinding());
}
// template <typename T, typename U> class CT {
// T* instance(void);
// };
// template <class T, class U> T * CT<T, U>::instance (void) {
// return new CT<T, U>;
// }
public void testNewOfThisTemplate() throws Exception {
parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP);
}
} }

View file

@ -187,4 +187,24 @@ public class PreprocessorBugsTests extends PreprocessorTestsBase {
validateProblem(0, IProblem.PREPROCESSOR_MISSING_RPAREN_PARMLIST, null); validateProblem(0, IProblem.PREPROCESSOR_MISSING_RPAREN_PARMLIST, null);
} }
// #ifdef 0
// /**/ #else
// OK1
// #endif
// #ifdef 0
// a /*
// */ #else
// OK2
// #endif
// #ifdef 0
// a /**/ #else
// NOTOK
// #endif
public void testCommentBeforeDirective_Bug255318() throws Exception {
initializeScanner();
validateIdentifier("OK1");
validateIdentifier("OK2");
validateEOF();
validateProblemCount(0);
}
} }

View file

@ -31,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
@ -1490,7 +1491,6 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
assertSame(charInst1, charInst2); assertSame(charInst1, charInst2);
} }
// template<typename T> class XT { // template<typename T> class XT {
// public: void method() {}; // public: void method() {};
// }; // };
@ -1508,4 +1508,16 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
assertEquals(1, ms.length); assertEquals(1, ms.length);
assertEquals(m, ms[0]); assertEquals(m, ms[0]);
} }
// template<class T, class U> class A {};
// template<class T> class A<T, int> {
// void foo(T t);
// };
// template<class T> void A<T, int>::foo(T t) {}
public void testBug177418() throws Exception {
ICPPMethod m= getBindingFromASTName("foo", 3, ICPPMethod.class);
ICPPClassType owner= m.getClassOwner();
assertInstance(owner, ICPPClassTemplatePartialSpecialization.class);
}
} }

View file

@ -122,14 +122,11 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
super.addDeclaration(node); super.addDeclaration(node);
} }
/** private void updateFunctionParameterBindings(IASTName declName) {
* @param name
*/
private void updateFunctionParameterBindings(IASTName paramName) {
IASTName defName = definition != null ? definition : declarations[0]; IASTName defName = definition != null ? definition : declarations[0];
ICPPASTFunctionDeclarator orig = (ICPPASTFunctionDeclarator) defName.getParent(); ICPPASTFunctionDeclarator orig = getDeclaratorByName(defName);
IASTParameterDeclaration[] ops = orig.getParameters(); IASTParameterDeclaration[] ops = orig.getParameters();
IASTParameterDeclaration[] nps = ((ICPPASTFunctionDeclarator)paramName.getParent()).getParameters(); IASTParameterDeclaration[] nps = getDeclaratorByName(declName).getParameters();
CPPParameter temp = null; CPPParameter temp = null;
for(int i = 0; i < nps.length; i++) { for(int i = 0; i < nps.length; i++) {
temp = (CPPParameter) CPPVisitor.findInnermostDeclarator(ops[i].getDeclarator()).getName().getBinding(); temp = (CPPParameter) CPPVisitor.findInnermostDeclarator(ops[i].getDeclarator()).getName().getBinding();

View file

@ -67,7 +67,6 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IQualifierType;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
@ -132,7 +131,6 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope; import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
@ -220,12 +218,6 @@ public class CPPSemantics {
return postResolution(binding, data); return postResolution(binding, data);
} }
/**
* @param binding
* @param data
* @param name
* @return
*/
private static IBinding postResolution(IBinding binding, LookupData data) { private static IBinding postResolution(IBinding binding, LookupData data) {
if (data.checkAssociatedScopes()) { if (data.checkAssociatedScopes()) {
//3.4.2 argument dependent name lookup, aka Koenig lookup //3.4.2 argument dependent name lookup, aka Koenig lookup
@ -321,58 +313,23 @@ public class CPPSemantics {
} }
} }
// mstodo this looks like a hack? IASTName name= data.astName;
// in template declarations the template-ids get instantiated to deferred instances, revert that. IASTNode nameParent= name.getParent();
IASTName name = data.astName; if (nameParent instanceof ICPPASTTemplateId) {
if (name instanceof ICPPASTTemplateId) {
if (binding instanceof ICPPDeferredTemplateInstance && CPPTemplates.getTemplateDeclaration(name) != null ) {
ICPPDeferredTemplateInstance deferred= (ICPPDeferredTemplateInstance) binding;
IBinding spec= deferred.getSpecializedBinding();
if (spec instanceof ICPPTemplateDefinition) {
try {
ICPPTemplateArgument[] args= deferred.getTemplateArguments();
ICPPTemplateParameter[] pars= ((ICPPTemplateDefinition) spec).getTemplateParameters();
if (args.length == pars.length) {
boolean useOriginal= true;
for (int i = 0; useOriginal && i < pars.length; i++) {
ICPPTemplateParameter par= pars[i];
if (par instanceof ICPPTemplateNonTypeParameter) {
IValue val= args[i].getNonTypeValue();
if (val == null || par.getParameterPosition() != Value.isTemplateParameter(val)) {
useOriginal= false;
}
} else {
IType other= args[i].getTypeValue();
if (!(other instanceof ICPPTemplateParameter)) {
useOriginal= false;
} else if (par.getParameterPosition() != ((ICPPTemplateParameter) other).getParameterPosition()) {
useOriginal= false;
}
}
}
if (useOriginal) {
binding= spec;
}
}
} catch (DOMException e) {
}
}
}
}
if (name.getParent() instanceof ICPPASTTemplateId) {
if (binding instanceof ICPPTemplateInstance) { if (binding instanceof ICPPTemplateInstance) {
IBinding b = binding; final ICPPTemplateInstance instance = (ICPPTemplateInstance)binding;
binding = ((ICPPTemplateInstance)binding).getSpecializedBinding(); binding = instance.getSpecializedBinding();
name.setBinding(binding); name.setBinding(binding);
name = (IASTName) name.getParent(); ((ICPPASTTemplateId) nameParent).setBinding(instance);
name.setBinding(b);
} else {
name = (IASTName) name.getParent();
} }
name= (ICPPASTTemplateId) nameParent;
nameParent= name.getParent();
} }
if (name.getParent() instanceof ICPPASTQualifiedName) { if (nameParent instanceof ICPPASTQualifiedName) {
if (name == ((ICPPASTQualifiedName)name.getParent()).getLastName()) if (name == ((ICPPASTQualifiedName) nameParent).getLastName()) {
name = (IASTName) name.getParent(); name= (IASTName) nameParent;
nameParent= name.getParent();
}
} }
// if the lookup in base-classes ran into a deferred instance, use the computed unknown binding. // if the lookup in base-classes ran into a deferred instance, use the computed unknown binding.
@ -1585,6 +1542,11 @@ public class CPPSemantics {
if (candidate instanceof ICPPClassTemplatePartialSpecialization) if (candidate instanceof ICPPClassTemplatePartialSpecialization)
return null; return null;
// specialization is selected during instantiation
// mstodo why not?
// if (candidate instanceof ICPPTemplateInstance && candidate instanceof IType)
// candidate= ((ICPPTemplateInstance) candidate).getSpecializedBinding();
return candidate; return candidate;
} }
} }
@ -1737,9 +1699,16 @@ public class CPPSemantics {
} else { } else {
continue; continue;
} }
// specialization is selected during instantiation
// mstodo why not?
// if (temp instanceof ICPPTemplateInstance && temp instanceof IType)
// temp= ((ICPPTemplateInstance) temp).getSpecializedBinding();
// select among those bindings that have been created without problems. // select among those bindings that have been created without problems.
if (temp instanceof IProblemBinding) if (temp instanceof IProblemBinding)
continue; continue;
if (!(temp instanceof ICPPMember) && !declaredBefore) if (!(temp instanceof ICPPMember) && !declaredBefore)
continue; continue;
if (temp instanceof ICPPUsingDeclaration) { if (temp instanceof ICPPUsingDeclaration) {

View file

@ -381,7 +381,7 @@ public class CPPTemplates {
if (element instanceof ICPPASTTemplateId) { if (element instanceof ICPPASTTemplateId) {
++i; ++i;
if (i == idx) { if (i == idx) {
binding = ((ICPPASTTemplateId) element).getTemplateName().resolveBinding(); binding = ((ICPPASTTemplateId) element).resolveBinding();
break; break;
} }
} }
@ -426,10 +426,9 @@ public class CPPTemplates {
public static IBinding createBinding(ICPPASTTemplateId id) { public static IBinding createBinding(ICPPASTTemplateId id) {
IASTNode parent = id.getParent(); IASTNode parent = id.getParent();
int segment = -1; boolean isLastName= true;
if (parent instanceof ICPPASTQualifiedName) { if (parent instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName) parent).getNames(); isLastName= ((ICPPASTQualifiedName) parent).getLastName() == id;
segment = (ns[ns.length - 1] == id) ? 1 : 0;
parent = parent.getParent(); parent = parent.getParent();
} }
@ -443,50 +442,65 @@ public class CPPTemplates {
} }
try { try {
if (decl instanceof ICPPASTExplicitTemplateInstantiation && final boolean isClassDecl= parent instanceof ICPPASTElaboratedTypeSpecifier;
parent instanceof ICPPASTElaboratedTypeSpecifier && segment != 0) { final boolean isClassDef = parent instanceof ICPPASTCompositeTypeSpecifier;
return createExplicitClassInstantiation((ICPPASTElaboratedTypeSpecifier) parent);
} else if (((parent instanceof ICPPASTElaboratedTypeSpecifier && if (isLastName) {
decl instanceof ICPPASTTemplateDeclaration) || if (isClassDecl && decl instanceof ICPPASTExplicitTemplateInstantiation)
parent instanceof ICPPASTCompositeTypeSpecifier) && return createExplicitClassInstantiation((ICPPASTElaboratedTypeSpecifier) parent);
segment != 0) {
return createExplicitClassSpecialization((ICPPASTDeclSpecifier) parent); if (isClassDef || (isClassDecl && decl instanceof ICPPASTTemplateDeclaration))
} else if (parent instanceof ICPPASTFunctionDeclarator && segment != 0) { return createExplicitClassSpecialization((ICPPASTDeclSpecifier) parent);
return createFunctionSpecialization(id);
if (parent instanceof ICPPASTFunctionDeclarator)
return createFunctionSpecialization(id);
} }
//a reference: class or function template? if (!isLastName || isClassDecl || parent instanceof ICPPASTNamedTypeSpecifier ||
IBinding template = null; parent instanceof ICPPASTBaseSpecifier) {
if (parent instanceof ICPPASTNamedTypeSpecifier || // class template instance
parent instanceof ICPPASTElaboratedTypeSpecifier ||
parent instanceof ICPPASTBaseSpecifier ||
segment == 0) {
//class template
IASTName templateName = id.getTemplateName(); IASTName templateName = id.getTemplateName();
template = templateName.resolveBinding(); IBinding template = templateName.resolveBinding();
if (template instanceof ICPPClassTemplatePartialSpecialization) { if (template instanceof ICPPUnknownClassInstance) {
//specializations are selected during the instantiation, start with the primary template // mstodo we should not get here, rather than that an unknown class
try { // should be made to an unknown class instance here
template = ((ICPPClassTemplatePartialSpecialization) template).getPrimaryClassTemplate(); return template;
} catch (DOMException e) { }
return e.getProblem(); if (template instanceof ICPPConstructor) {
} template= template.getOwner();
} else if (template instanceof ICPPSpecialization && !(template instanceof ICPPTemplateDefinition)) {
template = ((ICPPSpecialization) template).getSpecializedBinding();
} }
if (template instanceof ICPPTemplateDefinition) { if (!(template instanceof ICPPClassTemplate) || template instanceof ICPPClassTemplatePartialSpecialization)
ICPPTemplateArgument[] args= CPPTemplates.createTemplateArgumentArray(id); return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TYPE, templateName.toCharArray());
IBinding instance= instantiate((ICPPTemplateDefinition) template, args);
return CPPSemantics.postResolution(instance, id); final ICPPClassTemplate classTemplate = (ICPPClassTemplate) template;
} ICPPTemplateArgument[] args= createTemplateArgumentArray(id);
} else { ICPPASTTemplateDeclaration tdecl= getTemplateDeclaration(id);
//functions are instantiated as part of the resolution process if (tdecl != null) {
template = CPPVisitor.createBinding(id); if (hasDependentArgument(args)) {
if (template instanceof ICPPTemplateInstance) { IBinding result= null;
IASTName templateName = id.getTemplateName(); if (argsAreTrivial(classTemplate.getTemplateParameters(), args)) {
templateName.setBinding(((ICPPTemplateInstance) template).getTemplateDefinition()); 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);
}
//functions are instantiated as part of the resolution process
IBinding template = CPPVisitor.createBinding(id);
if (template instanceof ICPPTemplateInstance) {
IASTName templateName = id.getTemplateName();
templateName.setBinding(((ICPPTemplateInstance) template).getTemplateDefinition());
} }
return template; return template;
} catch (DOMException e) { } catch (DOMException e) {
@ -571,22 +585,10 @@ public class CPPTemplates {
} }
return inst; return inst;
} }
//else partial specialization
//CPPClassTemplate template = (CPPClassTemplate) binding;
ICPPClassTemplatePartialSpecialization spec= null;
try {
ICPPClassTemplatePartialSpecialization[] specs = template.getPartialSpecializations();
if (specs != null) {
for (ICPPClassTemplatePartialSpecialization specialization : specs) {
if (isSameTemplate(specialization, id)) {
spec = specialization;
break;
}
}
}
} catch (DOMException e) {
}
// we have a partial specialization
ICPPTemplateArgument[] args= createTemplateArgumentArray(id);
ICPPClassTemplatePartialSpecialization spec= findPartialSpecialization(template, args);
if (spec != null) { if (spec != null) {
if (spec instanceof ICPPInternalBinding) if (spec instanceof ICPPInternalBinding)
((ICPPInternalBinding) spec).addDefinition(id); ((ICPPInternalBinding) spec).addDefinition(id);
@ -594,6 +596,7 @@ public class CPPTemplates {
} }
spec = new CPPClassTemplatePartialSpecialization(id); spec = new CPPClassTemplatePartialSpecialization(id);
// mstodo how to add partial specialization to class template from index?
if (template instanceof ICPPInternalClassTemplate) if (template instanceof ICPPInternalClassTemplate)
((ICPPInternalClassTemplate) template).addPartialSpecialization(spec); ((ICPPInternalClassTemplate) template).addPartialSpecialization(spec);
return spec; return spec;
@ -609,7 +612,7 @@ public class CPPTemplates {
} }
CPPSemantics.lookup(data, scope); CPPSemantics.lookup(data, scope);
ICPPFunctionTemplate function = resolveTemplateFunctions((Object[]) data.foundItems, name); ICPPFunctionTemplate function= resolveTemplateFunctions((Object[]) data.foundItems, name);
if (function == null) if (function == null)
return new ProblemBinding(name, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, name.toCharArray()); return new ProblemBinding(name, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, name.toCharArray());
if (function instanceof IProblemBinding) if (function instanceof IProblemBinding)
@ -628,22 +631,33 @@ public class CPPTemplates {
if (args == null) if (args == null)
return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_TYPE, name.toCharArray()); return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_TYPE, name.toCharArray());
IBinding result= null;
if (hasDependentArgument(args)) {
// we are looking at a definition for a function-template.
final ICPPTemplateParameter[] pars= function.getTemplateParameters();
if (!argsAreTrivial(pars, args)) {
return new ProblemBinding(name, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, name.toCharArray());
}
result= function;
} else {
result= getInstance(function, args);
if (result == null) {
IBinding owner= function.getOwner();
ICPPTemplateInstance instance= createInstance(owner, function, tpMap, args);
addInstance(function, args, instance);
result= instance;
}
}
while (!(parent instanceof IASTDeclaration)) while (!(parent instanceof IASTDeclaration))
parent = parent.getParent(); parent = parent.getParent();
IBinding owner= function.getOwner(); if (result instanceof ICPPInternalBinding) {
ICPPTemplateInstance instance= getInstance(function, args);
if (instance == null) {
instance = createInstance(owner, function, tpMap, args);
addInstance(function, args, instance);
}
if (instance instanceof ICPPInternalBinding) {
if (parent instanceof IASTSimpleDeclaration) if (parent instanceof IASTSimpleDeclaration)
((ICPPInternalBinding) instance).addDeclaration(name); ((ICPPInternalBinding) result).addDeclaration(name);
else if (parent instanceof IASTFunctionDefinition) else if (parent instanceof IASTFunctionDefinition)
((ICPPInternalBinding) instance).addDefinition(name); ((ICPPInternalBinding) result).addDefinition(name);
} }
return instance; return result;
} catch (DOMException e) { } catch (DOMException e) {
return e.getProblem(); return e.getProblem();
} }
@ -1642,6 +1656,22 @@ public class CPPTemplates {
return d1 - d2; return d1 - d2;
} }
private static ICPPClassTemplatePartialSpecialization findPartialSpecialization(ICPPClassTemplate ct, ICPPTemplateArgument[] args) throws DOMException {
ICPPClassTemplatePartialSpecialization[] pspecs = ct.getPartialSpecializations();
if (pspecs != null && pspecs.length > 0) {
final String argStr= ASTTypeUtil.getArgumentListString(args, true);
for (ICPPClassTemplatePartialSpecialization pspec : pspecs) {
try {
if (argStr.equals(ASTTypeUtil.getArgumentListString(pspec.getTemplateArguments(), true)))
return pspec;
} catch (DOMException e) {
// ignore partial specializations with problems
}
}
}
return null;
}
static public ICPPTemplateDefinition selectSpecialization(ICPPClassTemplate template, ICPPTemplateArgument[] args) static public ICPPTemplateDefinition selectSpecialization(ICPPClassTemplate template, ICPPTemplateArgument[] args)
throws DOMException { throws DOMException {
if (template == null) { if (template == null) {
@ -1874,12 +1904,41 @@ public class CPPTemplates {
return cost != null && cost.rank != Cost.NO_MATCH_RANK; return cost != null && cost.rank != Cost.NO_MATCH_RANK;
} }
private static boolean argsAreTrivial(ICPPTemplateParameter[] pars, ICPPTemplateArgument[] args) {
if (pars.length != args.length) {
return false;
}
for (int i = 0; i < args.length; i++) {
ICPPTemplateParameter par= pars[i];
ICPPTemplateArgument arg = args[i];
if (par instanceof IType) {
IType argType= arg.getTypeValue();
if (argType == null || !argType.isSameType((IType) par))
return false;
} else {
int parpos= Value.isTemplateParameter(arg.getNonTypeValue());
if (parpos != par.getParameterPosition())
return false;
}
}
return true;
}
public static boolean hasDependentArgument(ICPPTemplateArgument[] args) {
for (ICPPTemplateArgument arg : args) {
if (isDependentArgument(arg))
return true;
}
return false;
}
public static boolean isDependentArgument(ICPPTemplateArgument arg) { public static boolean isDependentArgument(ICPPTemplateArgument arg) {
if (arg.isTypeValue()) if (arg.isTypeValue())
return isDependentType(arg.getTypeValue()); return isDependentType(arg.getTypeValue());
return Value.isDependentValue(arg.getNonTypeValue()); return Value.isDependentValue(arg.getNonTypeValue());
} }
public static boolean isDependentType(IType t) { public static boolean isDependentType(IType t) {
// mstodo needs to be extended // mstodo needs to be extended
if (t instanceof ICPPTemplateParameter) if (t instanceof ICPPTemplateParameter)