mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Definitions of members of partial specializations, bug 177418.
This commit is contained in:
parent
0dea0424ac
commit
8e55e2392f
6 changed files with 243 additions and 140 deletions
|
@ -1285,8 +1285,7 @@ public class AST2TemplateTests extends AST2BaseTest {
|
|||
IBinding U2 = col.getName(10).resolveBinding();
|
||||
assertSame(U, U2);
|
||||
|
||||
assertTrue(f2 instanceof ICPPSpecialization);
|
||||
assertSame(((ICPPSpecialization)f2).getSpecializedBinding(), f1);
|
||||
assertSame(f1, f2);
|
||||
}
|
||||
|
||||
// template<typename T>
|
||||
|
@ -1792,9 +1791,10 @@ public class AST2TemplateTests extends AST2BaseTest {
|
|||
ICPPClassTemplate B = (ICPPClassTemplate) col.getName(4).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(T2, col.getName(14).resolveBinding());
|
||||
assertSame(T2ofPartialSpec, col.getName(14).resolveBinding());
|
||||
|
||||
ICPPClassTemplatePartialSpecialization spec = (ICPPClassTemplatePartialSpecialization) col.getName(12).resolveBinding();
|
||||
assertSame(spec.getPrimaryClassTemplate(), B);
|
||||
|
@ -3234,7 +3234,7 @@ public class AST2TemplateTests extends AST2BaseTest {
|
|||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP);
|
||||
parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP);
|
||||
} catch (Throwable e) {
|
||||
th[0]= e;
|
||||
}
|
||||
|
@ -3247,4 +3247,50 @@ public class AST2TemplateTests extends AST2BaseTest {
|
|||
if (th[0] != null)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -187,4 +187,24 @@ public class PreprocessorBugsTests extends PreprocessorTestsBase {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.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.ICPPField;
|
||||
|
@ -1490,7 +1491,6 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
|
|||
assertSame(charInst1, charInst2);
|
||||
}
|
||||
|
||||
|
||||
// template<typename T> class XT {
|
||||
// public: void method() {};
|
||||
// };
|
||||
|
@ -1508,4 +1508,16 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
|
|||
assertEquals(1, ms.length);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,14 +122,11 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
|
|||
super.addDeclaration(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
*/
|
||||
private void updateFunctionParameterBindings(IASTName paramName) {
|
||||
private void updateFunctionParameterBindings(IASTName declName) {
|
||||
IASTName defName = definition != null ? definition : declarations[0];
|
||||
ICPPASTFunctionDeclarator orig = (ICPPASTFunctionDeclarator) defName.getParent();
|
||||
ICPPASTFunctionDeclarator orig = getDeclaratorByName(defName);
|
||||
IASTParameterDeclaration[] ops = orig.getParameters();
|
||||
IASTParameterDeclaration[] nps = ((ICPPASTFunctionDeclarator)paramName.getParent()).getParameters();
|
||||
IASTParameterDeclaration[] nps = getDeclaratorByName(declName).getParameters();
|
||||
CPPParameter temp = null;
|
||||
for(int i = 0; i < nps.length; i++) {
|
||||
temp = (CPPParameter) CPPVisitor.findInnermostDeclarator(ops[i].getDeclarator()).getName().getBinding();
|
||||
|
|
|
@ -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.IScope;
|
||||
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.IASTEnumerationSpecifier.IASTEnumerator;
|
||||
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.IASTInternalScope;
|
||||
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.CPPASTIdExpression;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
|
||||
|
@ -220,12 +218,6 @@ public class CPPSemantics {
|
|||
return postResolution(binding, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param binding
|
||||
* @param data
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
private static IBinding postResolution(IBinding binding, LookupData data) {
|
||||
if (data.checkAssociatedScopes()) {
|
||||
//3.4.2 argument dependent name lookup, aka Koenig lookup
|
||||
|
@ -321,58 +313,23 @@ public class CPPSemantics {
|
|||
}
|
||||
}
|
||||
|
||||
// mstodo this looks like a hack?
|
||||
// in template declarations the template-ids get instantiated to deferred instances, revert that.
|
||||
IASTName name = data.astName;
|
||||
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) {
|
||||
IASTName name= data.astName;
|
||||
IASTNode nameParent= name.getParent();
|
||||
if (nameParent instanceof ICPPASTTemplateId) {
|
||||
if (binding instanceof ICPPTemplateInstance) {
|
||||
IBinding b = binding;
|
||||
binding = ((ICPPTemplateInstance)binding).getSpecializedBinding();
|
||||
final ICPPTemplateInstance instance = (ICPPTemplateInstance)binding;
|
||||
binding = instance.getSpecializedBinding();
|
||||
name.setBinding(binding);
|
||||
name = (IASTName) name.getParent();
|
||||
name.setBinding(b);
|
||||
} else {
|
||||
name = (IASTName) name.getParent();
|
||||
}
|
||||
((ICPPASTTemplateId) nameParent).setBinding(instance);
|
||||
}
|
||||
name= (ICPPASTTemplateId) nameParent;
|
||||
nameParent= name.getParent();
|
||||
}
|
||||
if (name.getParent() instanceof ICPPASTQualifiedName) {
|
||||
if (name == ((ICPPASTQualifiedName)name.getParent()).getLastName())
|
||||
name = (IASTName) name.getParent();
|
||||
if (nameParent instanceof ICPPASTQualifiedName) {
|
||||
if (name == ((ICPPASTQualifiedName) nameParent).getLastName()) {
|
||||
name= (IASTName) nameParent;
|
||||
nameParent= name.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
return null;
|
||||
|
||||
// specialization is selected during instantiation
|
||||
// mstodo why not?
|
||||
// if (candidate instanceof ICPPTemplateInstance && candidate instanceof IType)
|
||||
// candidate= ((ICPPTemplateInstance) candidate).getSpecializedBinding();
|
||||
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
@ -1737,9 +1699,16 @@ public class CPPSemantics {
|
|||
} else {
|
||||
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.
|
||||
if (temp instanceof IProblemBinding)
|
||||
if (temp instanceof IProblemBinding)
|
||||
continue;
|
||||
|
||||
if (!(temp instanceof ICPPMember) && !declaredBefore)
|
||||
continue;
|
||||
if (temp instanceof ICPPUsingDeclaration) {
|
||||
|
|
|
@ -381,7 +381,7 @@ public class CPPTemplates {
|
|||
if (element instanceof ICPPASTTemplateId) {
|
||||
++i;
|
||||
if (i == idx) {
|
||||
binding = ((ICPPASTTemplateId) element).getTemplateName().resolveBinding();
|
||||
binding = ((ICPPASTTemplateId) element).resolveBinding();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -426,10 +426,9 @@ public class CPPTemplates {
|
|||
|
||||
public static IBinding createBinding(ICPPASTTemplateId id) {
|
||||
IASTNode parent = id.getParent();
|
||||
int segment = -1;
|
||||
boolean isLastName= true;
|
||||
if (parent instanceof ICPPASTQualifiedName) {
|
||||
IASTName[] ns = ((ICPPASTQualifiedName) parent).getNames();
|
||||
segment = (ns[ns.length - 1] == id) ? 1 : 0;
|
||||
isLastName= ((ICPPASTQualifiedName) parent).getLastName() == id;
|
||||
parent = parent.getParent();
|
||||
}
|
||||
|
||||
|
@ -443,50 +442,65 @@ public class CPPTemplates {
|
|||
}
|
||||
|
||||
try {
|
||||
if (decl instanceof ICPPASTExplicitTemplateInstantiation &&
|
||||
parent instanceof ICPPASTElaboratedTypeSpecifier && segment != 0) {
|
||||
return createExplicitClassInstantiation((ICPPASTElaboratedTypeSpecifier) parent);
|
||||
} else if (((parent instanceof ICPPASTElaboratedTypeSpecifier &&
|
||||
decl instanceof ICPPASTTemplateDeclaration) ||
|
||||
parent instanceof ICPPASTCompositeTypeSpecifier) &&
|
||||
segment != 0) {
|
||||
return createExplicitClassSpecialization((ICPPASTDeclSpecifier) parent);
|
||||
} else if (parent instanceof ICPPASTFunctionDeclarator && segment != 0) {
|
||||
return createFunctionSpecialization(id);
|
||||
}
|
||||
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);
|
||||
|
||||
//a reference: class or function template?
|
||||
IBinding template = null;
|
||||
if (parent instanceof ICPPASTNamedTypeSpecifier ||
|
||||
parent instanceof ICPPASTElaboratedTypeSpecifier ||
|
||||
parent instanceof ICPPASTBaseSpecifier ||
|
||||
segment == 0) {
|
||||
//class template
|
||||
if (parent instanceof ICPPASTFunctionDeclarator)
|
||||
return createFunctionSpecialization(id);
|
||||
}
|
||||
|
||||
if (!isLastName || isClassDecl || parent instanceof ICPPASTNamedTypeSpecifier ||
|
||||
parent instanceof ICPPASTBaseSpecifier) {
|
||||
// class template instance
|
||||
IASTName templateName = id.getTemplateName();
|
||||
template = templateName.resolveBinding();
|
||||
if (template instanceof ICPPClassTemplatePartialSpecialization) {
|
||||
//specializations are selected during the instantiation, start with the primary template
|
||||
try {
|
||||
template = ((ICPPClassTemplatePartialSpecialization) template).getPrimaryClassTemplate();
|
||||
} catch (DOMException e) {
|
||||
return e.getProblem();
|
||||
}
|
||||
} else if (template instanceof ICPPSpecialization && !(template instanceof ICPPTemplateDefinition)) {
|
||||
template = ((ICPPSpecialization) template).getSpecializedBinding();
|
||||
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 ICPPTemplateDefinition) {
|
||||
ICPPTemplateArgument[] args= CPPTemplates.createTemplateArgumentArray(id);
|
||||
IBinding instance= instantiate((ICPPTemplateDefinition) template, args);
|
||||
return CPPSemantics.postResolution(instance, id);
|
||||
}
|
||||
} else {
|
||||
//functions are instantiated as part of the resolution process
|
||||
template = CPPVisitor.createBinding(id);
|
||||
if (template instanceof ICPPTemplateInstance) {
|
||||
IASTName templateName = id.getTemplateName();
|
||||
templateName.setBinding(((ICPPTemplateInstance) template).getTemplateDefinition());
|
||||
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);
|
||||
}
|
||||
|
||||
//functions are instantiated as part of the resolution process
|
||||
IBinding template = CPPVisitor.createBinding(id);
|
||||
if (template instanceof ICPPTemplateInstance) {
|
||||
IASTName templateName = id.getTemplateName();
|
||||
templateName.setBinding(((ICPPTemplateInstance) template).getTemplateDefinition());
|
||||
}
|
||||
return template;
|
||||
} catch (DOMException e) {
|
||||
|
@ -571,22 +585,10 @@ public class CPPTemplates {
|
|||
}
|
||||
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 instanceof ICPPInternalBinding)
|
||||
((ICPPInternalBinding) spec).addDefinition(id);
|
||||
|
@ -594,6 +596,7 @@ public class CPPTemplates {
|
|||
}
|
||||
|
||||
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;
|
||||
|
@ -609,7 +612,7 @@ public class CPPTemplates {
|
|||
}
|
||||
CPPSemantics.lookup(data, scope);
|
||||
|
||||
ICPPFunctionTemplate function = resolveTemplateFunctions((Object[]) data.foundItems, name);
|
||||
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)
|
||||
|
@ -628,22 +631,33 @@ public class CPPTemplates {
|
|||
if (args == null)
|
||||
return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_TYPE, name.toCharArray());
|
||||
|
||||
IBinding result= null;
|
||||
if (hasDependentArgument(args)) {
|
||||
// we are looking at a definition for a function-template.
|
||||
final ICPPTemplateParameter[] pars= function.getTemplateParameters();
|
||||
if (!argsAreTrivial(pars, args)) {
|
||||
return new ProblemBinding(name, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, name.toCharArray());
|
||||
}
|
||||
result= function;
|
||||
} else {
|
||||
result= getInstance(function, args);
|
||||
if (result == null) {
|
||||
IBinding owner= function.getOwner();
|
||||
ICPPTemplateInstance instance= createInstance(owner, function, tpMap, args);
|
||||
addInstance(function, args, instance);
|
||||
result= instance;
|
||||
}
|
||||
}
|
||||
while (!(parent instanceof IASTDeclaration))
|
||||
parent = parent.getParent();
|
||||
|
||||
IBinding owner= function.getOwner();
|
||||
ICPPTemplateInstance instance= getInstance(function, args);
|
||||
if (instance == null) {
|
||||
instance = createInstance(owner, function, tpMap, args);
|
||||
addInstance(function, args, instance);
|
||||
}
|
||||
if (instance instanceof ICPPInternalBinding) {
|
||||
if (result instanceof ICPPInternalBinding) {
|
||||
if (parent instanceof IASTSimpleDeclaration)
|
||||
((ICPPInternalBinding) instance).addDeclaration(name);
|
||||
((ICPPInternalBinding) result).addDeclaration(name);
|
||||
else if (parent instanceof IASTFunctionDefinition)
|
||||
((ICPPInternalBinding) instance).addDefinition(name);
|
||||
((ICPPInternalBinding) result).addDefinition(name);
|
||||
}
|
||||
return instance;
|
||||
return result;
|
||||
} catch (DOMException e) {
|
||||
return e.getProblem();
|
||||
}
|
||||
|
@ -1642,6 +1656,22 @@ public class CPPTemplates {
|
|||
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)
|
||||
throws DOMException {
|
||||
if (template == null) {
|
||||
|
@ -1874,12 +1904,41 @@ public class CPPTemplates {
|
|||
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) {
|
||||
if (arg.isTypeValue())
|
||||
return isDependentType(arg.getTypeValue());
|
||||
|
||||
return Value.isDependentValue(arg.getNonTypeValue());
|
||||
}
|
||||
|
||||
public static boolean isDependentType(IType t) {
|
||||
// mstodo needs to be extended
|
||||
if (t instanceof ICPPTemplateParameter)
|
||||
|
|
Loading…
Add table
Reference in a new issue