1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

Resolving class specialization member function template, bug 104262

This commit is contained in:
Markus Schorn 2008-11-28 15:54:15 +00:00
parent e2ce799dae
commit 45f3fe8e97
8 changed files with 436 additions and 104 deletions

View file

@ -3326,7 +3326,7 @@ public class AST2TemplateTests extends AST2BaseTest {
// };
// 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() {}
// XT<int>::mytype3 XT<int>::m3() {}
public void testMethodImplWithNonDeferredType() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
@ -3352,7 +3352,7 @@ public class AST2TemplateTests extends AST2BaseTest {
// template<typename T> void f(T);
// };
// template<typename T> void A<float>::f(T){} //problem on f
public void _testClassTemplateMemberFunctionTemplate_Bug104262() throws Exception {
public void testClassTemplateMemberFunctionTemplate_Bug104262() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
@ -3367,4 +3367,22 @@ public class AST2TemplateTests extends AST2BaseTest {
method= bh.assertNonProblem("A<float>::f", 11);
assertSame(method.getOwner(), special);
}
// template<typename T> class XT {
// class Nested {
// template<typename V> void Nested::m(V);
// };
// };
// template<typename T> template <typename V> void XT<T>::Nested::m(V) {
// }
public void testQualifiedMethodTemplate() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
ICPPMethod mt1= bh.assertNonProblem("m(V);", 1);
ICPPMethod mt2= bh.assertNonProblem("m(V) ", 1);
assertSame(mt1, mt2);
assertInstance(mt1, ICPPFunctionTemplate.class);
}
}

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* John Camelon (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -14,20 +14,22 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
/**
* @author jcamelon
* Represents a template declaration.
*/
public class CPPASTTemplateDeclaration extends ASTNode implements
ICPPASTTemplateDeclaration, IASTAmbiguityParent {
ICPPASTInternalTemplateDeclaration, IASTAmbiguityParent {
private boolean exported;
private byte isAssociatedWithLastName= -1;
private short nestingLevel= -1;
private IASTDeclaration declaration;
private ICPPTemplateScope templateScope;
@ -116,4 +118,29 @@ public class CPPASTTemplateDeclaration extends ASTNode implements
declaration = (IASTDeclaration) other;
}
}
public short getNestingLevel() {
if (nestingLevel == -1) {
CPPTemplates.associateTemplateDeclarations(this);
}
assert nestingLevel != -1;
return nestingLevel;
}
public boolean isAssociatedWithLastName() {
if (isAssociatedWithLastName == -1)
CPPTemplates.associateTemplateDeclarations(this);
assert isAssociatedWithLastName != -1;
return isAssociatedWithLastName != 0;
}
public void setAssociatedWithLastName(boolean value) {
isAssociatedWithLastName= value ? (byte) 1 : (byte) 0;
}
public void setNestingLevel(short level) {
assert level >= 0;
nestingLevel= level;
}
}

View file

@ -6,28 +6,31 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* John Camelon (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
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.ICPPTemplateScope;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
/**
* @author jcamelon
* Node for template specialization syntax.
*/
public class CPPASTTemplateSpecialization extends ASTNode implements
ICPPASTTemplateSpecialization, ICPPASTTemplateDeclaration, IASTAmbiguityParent {
ICPPASTTemplateSpecialization, ICPPASTInternalTemplateDeclaration, IASTAmbiguityParent {
private IASTDeclaration declaration;
private ICPPTemplateScope templateScope;
private short nestingLevel= -1;
private byte isAssociatedWithLastName= -1;
public CPPASTTemplateSpecialization() {
@ -98,4 +101,29 @@ public class CPPASTTemplateSpecialization extends ASTNode implements
declaration = (IASTDeclaration) other;
}
}
public short getNestingLevel() {
if (nestingLevel == -1) {
CPPTemplates.associateTemplateDeclarations(this);
}
assert nestingLevel != -1;
return nestingLevel;
}
public boolean isAssociatedWithLastName() {
if (isAssociatedWithLastName == -1)
CPPTemplates.associateTemplateDeclarations(this);
assert isAssociatedWithLastName != -1;
return isAssociatedWithLastName != 0;
}
public void setAssociatedWithLastName(boolean value) {
isAssociatedWithLastName= value ? (byte) 1 : (byte) 0;
}
public void setNestingLevel(short level) {
assert level >= 0;
nestingLevel= level;
}
}

View file

@ -19,7 +19,6 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
@ -42,42 +41,40 @@ public abstract class CPPTemplateParameter extends PlatformObject
public CPPTemplateParameter(IASTName name) {
declarations = new IASTName[] {name};
fParameterID= computeParameterPosition(name);
fParameterID= computeParameterID(name);
}
private int computeParameterPosition(IASTName name) {
int pos= -1;
int nesting= -1;
private int computeParameterID(IASTName name) {
int nesting= 0;
ICPPASTTemplateParameter tp= null;
ICPPASTTemplateParameter[] tps= null;
for (IASTNode node= name.getParent(); node != null; node= node.getParent()) {
ICPPASTTemplateParameter[] tps= null;
if (node instanceof ICPPASTTemplateParameter) {
if (tp == null && node instanceof ICPPASTTemplateParameter) {
tp= (ICPPASTTemplateParameter) node;
} else if (node instanceof ICPPASTTemplateDeclaration) {
if (++nesting == 0) {
tps= ((ICPPASTTemplateDeclaration) node).getTemplateParameters();
} else if (node instanceof ICPPASTInternalTemplateDeclaration) {
final ICPPASTInternalTemplateDeclaration tdecl= (ICPPASTInternalTemplateDeclaration) node;
nesting+= tdecl.getNestingLevel();
if (tps == null) {
tps= tdecl.getTemplateParameters();
}
} else if (node instanceof ICPPASTTemplatedTypeTemplateParameter) {
if (++nesting == 0) {
nesting++;
if (tps == null) {
tps= ((ICPPASTTemplatedTypeTemplateParameter) node).getTemplateParameters();
}
}
if (pos == -1 && tps != null && tp != null) {
for (int i = 0; i < tps.length; i++) {
if (tps[i] == tp) {
pos= i;
break;
}
}
int pos= 0;
if (tps != null && tp != null) {
for (int i = 0; i < tps.length; i++) {
if (tps[i] == tp) {
pos= i;
break;
}
}
}
if (nesting < 0)
nesting= 0;
if (pos < 0)
pos= 0;
return (nesting << 16) + pos;
return (nesting << 16) + (pos & 0xffff);
}
@Override

View file

@ -0,0 +1,44 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
/**
* Adds method that assist in finding the relation-ship between a template declaration
* and the names of the nested declaration.
*/
public interface ICPPASTInternalTemplateDeclaration extends ICPPASTTemplateDeclaration {
/**
* Returns whether this template declaration is associated with the last name of
* the possibly qualified name of the enclosing declaration. If this template declaration
* encloses another one, <code>false</code> is returned.
*/
boolean isAssociatedWithLastName();
/**
* Returns the nesting level of this template declaration.
* @see ICPPTemplateParameter#getTemplateNestingLevel()
*/
short getNestingLevel();
/**
* Sets the nesting level, once it is determined
*/
void setNestingLevel(short level);
/**
* Sets whether the template declaration is associated with the last name.
*/
void setAssociatedWithLastName(boolean value);
}

View file

@ -18,6 +18,7 @@ import java.util.Collections;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
@ -26,6 +27,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
@ -79,6 +81,7 @@ 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;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArraySet;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.core.parser.util.ObjectSet;
@ -118,6 +121,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedefSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClass;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalTemplateDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
@ -483,9 +488,9 @@ public class CPPTemplates {
final ICPPClassTemplate classTemplate = (ICPPClassTemplate) template;
ICPPTemplateArgument[] args= createTemplateArgumentArray(id);
ICPPASTTemplateDeclaration tdecl= getTemplateDeclaration(id);
if (tdecl != null) {
if (hasDependentArgument(args)) {
if (hasDependentArgument(args)) {
ICPPASTTemplateDeclaration tdecl= getTemplateDeclaration(id);
if (tdecl != null) {
if (argsAreTrivial(classTemplate.getTemplateParameters(), args)) {
result= classTemplate;
} else {
@ -830,10 +835,248 @@ public class CPPTemplates {
* correspond to a template declaration.
*/
public static ICPPASTTemplateDeclaration getTemplateDeclaration(IASTName name) {
if (name == null) {
if (name == null)
return null;
}
// first look for a related sequence of template declarations
ICPPASTInternalTemplateDeclaration tdecl= getInnerTemplateDeclaration(name);
if (tdecl == null)
return null;
name= name.getLastName();
IASTNode parent= name.getParent();
if (!(parent instanceof ICPPASTQualifiedName)) {
if (parent instanceof ICPPASTTemplateId) {
return null;
}
// one name: use innermost template declaration
return tdecl;
}
// last name can be associated even if it is not a template-id
final ICPPASTQualifiedName qname= (ICPPASTQualifiedName) parent;
final IASTName lastName = qname.getLastName();
final boolean lastIsTemplate= lastName instanceof ICPPASTTemplateId ||
tdecl.isAssociatedWithLastName();
if (name == lastName) {
if (lastIsTemplate) {
return tdecl;
}
return null;
}
// not the last name, search for the matching template declaration
if (!(name instanceof ICPPASTTemplateId))
return null;
if (lastIsTemplate) {
// skip one
tdecl= getDirectlyEnclosingTemplateDeclaration(tdecl);
}
final IASTName[] ns= qname.getNames();
for (int i = ns.length-2; tdecl != null && i >= 0; i--) {
final IASTName n = ns[i];
if (n == name) {
return tdecl;
}
if (n instanceof ICPPASTTemplateId) {
tdecl= getDirectlyEnclosingTemplateDeclaration(tdecl);
}
}
// not enough template declartaions
return null;
}
public static void associateTemplateDeclarations(ICPPASTInternalTemplateDeclaration tdecl) {
// find innermost template decl
IASTDeclaration decl= tdecl.getDeclaration();
while (decl instanceof ICPPASTInternalTemplateDeclaration) {
tdecl= (ICPPASTInternalTemplateDeclaration) decl;
decl= tdecl.getDeclaration();
}
final ICPPASTInternalTemplateDeclaration innerMostTDecl= tdecl;
// find name declared in nested declaration
IASTName name= getNameForDeclarationInTemplateDeclaration(decl);
// count template declarations
int tdeclcount= 1;
IASTNode node= tdecl.getParent();
while (node instanceof ICPPASTInternalTemplateDeclaration) {
tdeclcount++;
tdecl = (ICPPASTInternalTemplateDeclaration) node;
node= node.getParent();
}
final ICPPASTInternalTemplateDeclaration outerMostTDecl= tdecl;
// determine association of names with template declarations
boolean lastIsTemplate= true;
int additionalLevels= 0;
if (name instanceof ICPPASTQualifiedName) {
ICPPASTQualifiedName qname= (ICPPASTQualifiedName) name;
final boolean lastIsID = qname.getLastName() instanceof ICPPASTTemplateId;
// count template-ids
int idcount= 0;
final IASTName[] ns= qname.getNames();
for (int j = 0; j < ns.length; j++) {
final IASTName n = ns[j];
if (n instanceof ICPPASTTemplateId) {
idcount++;
}
}
if (lastIsID) {
additionalLevels= idcount-tdeclcount;
} else {
additionalLevels= idcount+1-tdeclcount;
if (additionalLevels > 0) {
// last name is probably not a template
additionalLevels--;
lastIsTemplate= false;
CharArraySet tparnames= collectTemplateParameterNames(outerMostTDecl);
int j= 0;
IASTName n;
for (int i = 0; i < ns.length; i++) {
n = ns[j];
if (n instanceof ICPPASTTemplateId) {
// if we find a dependent id, there can be no explicit specialization.
ICPPASTTemplateId id= (ICPPASTTemplateId) n;
if (usesTemplateParameter(id, tparnames))
break;
if (j++ == additionalLevels) {
IBinding b= n.resolveBinding();
if (b instanceof ICPPTemplateInstance && b instanceof ICPPClassType) {
try {
IScope s= ((ICPPClassType) b).getCompositeScope();
if (!(s instanceof ICPPClassSpecializationScope)) {
// template-id of an explicit specialization.
// here we don't have a template declaration. (see 14.7.3.5)
additionalLevels++;
lastIsTemplate= true;
}
} catch (DOMException e) {
// assume that it is not an explicit instance
}
}
break;
}
}
}
}
}
}
if (additionalLevels < 0) {
additionalLevels= 0; // too many template declarations
}
// determine nesting level of parent
int level= 0;
node= outerMostTDecl.getParent();
while (node != null) {
if (node instanceof ICPPASTInternalTemplateDeclaration) {
level= ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1;
break;
}
node= node.getParent();
}
level += additionalLevels;
tdecl= outerMostTDecl;
while(true) {
tdecl.setNestingLevel((short) level++);
node= tdecl.getDeclaration();
if (node instanceof ICPPASTInternalTemplateDeclaration) {
tdecl= (ICPPASTInternalTemplateDeclaration) node;
} else {
break;
}
}
innerMostTDecl.setAssociatedWithLastName(lastIsTemplate);
}
private static CharArraySet collectTemplateParameterNames(ICPPASTTemplateDeclaration tdecl) {
CharArraySet set= new CharArraySet(4);
while(true) {
ICPPASTTemplateParameter[] pars = tdecl.getTemplateParameters();
for (ICPPASTTemplateParameter par : pars) {
IASTName name= CPPTemplates.getTemplateParameterName(par);
if (name != null)
set.put(name.toCharArray());
}
final IASTNode next= tdecl.getDeclaration();
if (next instanceof ICPPASTTemplateDeclaration) {
tdecl= (ICPPASTTemplateDeclaration) next;
} else {
break;
}
}
return set;
}
private static boolean usesTemplateParameter(final ICPPASTTemplateId id, final CharArraySet names) {
final boolean[] result= {false};
ASTVisitor v= new ASTVisitor(false) {
{ shouldVisitNames= true;}
@Override
public int visit(IASTName name) {
if (name instanceof ICPPASTTemplateId)
return PROCESS_CONTINUE;
if (name instanceof ICPPASTQualifiedName) {
ICPPASTQualifiedName qname= (ICPPASTQualifiedName) name;
if (qname.isFullyQualified())
return PROCESS_SKIP;
return PROCESS_CONTINUE;
}
if (names.containsKey(name.toCharArray())) {
IASTNode parent= name.getParent();
if (parent instanceof ICPPASTQualifiedName) {
if (((ICPPASTQualifiedName) parent).getNames()[0] != name) {
return PROCESS_CONTINUE;
}
result[0]= true;
return PROCESS_ABORT;
} else if (parent instanceof IASTIdExpression ||
parent instanceof ICPPASTNamedTypeSpecifier) {
result[0]= true;
return PROCESS_ABORT;
}
}
return PROCESS_CONTINUE;
}
};
id.accept(v);
return result[0];
}
private static IASTName getNameForDeclarationInTemplateDeclaration(IASTDeclaration decl) {
IASTName name= null;
if (decl instanceof IASTSimpleDeclaration) {
IASTSimpleDeclaration sdecl= (IASTSimpleDeclaration) decl;
IASTDeclarator[] dtors = sdecl.getDeclarators();
if (dtors != null && dtors.length > 0) {
name= CPPVisitor.findInnermostDeclarator(dtors[0]).getName();
} else {
IASTDeclSpecifier declspec = sdecl.getDeclSpecifier();
if (declspec instanceof IASTCompositeTypeSpecifier) {
name= ((IASTCompositeTypeSpecifier) declspec).getName();
} else if (declspec instanceof IASTElaboratedTypeSpecifier) {
name= ((IASTElaboratedTypeSpecifier) declspec).getName();
}
}
} else if (decl instanceof IASTFunctionDefinition) {
IASTFunctionDefinition fdef= (IASTFunctionDefinition) decl;
name= CPPVisitor.findInnermostDeclarator(fdef.getDeclarator()).getName();
}
return name;
}
private static ICPPASTInternalTemplateDeclaration getInnerTemplateDeclaration(final IASTName name) {
IASTNode parent = name.getParent();
while (parent instanceof IASTName) {
parent = parent.getParent();
@ -849,47 +1092,22 @@ public class CPPTemplates {
parent = parent.getParent();
}
}
if (!(parent instanceof IASTDeclaration)) {
if (!(parent instanceof IASTDeclaration))
return null;
}
parent = parent.getParent();
if (parent instanceof ICPPASTTemplateDeclaration) {
ICPPASTTemplateDeclaration templateDecl = (ICPPASTTemplateDeclaration) parent;
if (parent instanceof ICPPASTInternalTemplateDeclaration)
return (ICPPASTInternalTemplateDeclaration) parent;
IASTName[] ns;
if (name instanceof ICPPASTQualifiedName) {
ns = ((ICPPASTQualifiedName) name).getNames();
name = ns[ns.length - 1];
} else if (name.getParent() instanceof ICPPASTQualifiedName) {
ns = ((ICPPASTQualifiedName) name.getParent()).getNames();
} else {
// one name: use innermost template declaration
return templateDecl;
}
// start with outermost template declaration
while (templateDecl.getParent() instanceof ICPPASTTemplateDeclaration)
templateDecl = (ICPPASTTemplateDeclaration) templateDecl.getParent();
for (int j = 0; j < ns.length; j++) {
final IASTName singleName = ns[j];
if (singleName == name) {
if (singleName instanceof ICPPASTTemplateId || j == ns.length-1) {
return templateDecl;
}
return null;
}
if (singleName instanceof ICPPASTTemplateId) {
final IASTDeclaration next= templateDecl.getDeclaration();
if (next instanceof ICPPASTTemplateDeclaration) {
templateDecl= (ICPPASTTemplateDeclaration) next;
} else {
return null;
}
}
}
}
return null;
}
private static ICPPASTInternalTemplateDeclaration getDirectlyEnclosingTemplateDeclaration(
ICPPASTInternalTemplateDeclaration tdecl ) {
final IASTNode parent= tdecl.getParent();
if (parent instanceof ICPPASTInternalTemplateDeclaration)
return (ICPPASTInternalTemplateDeclaration) parent;
return null;
}

View file

@ -215,12 +215,23 @@ public class CPPVisitor extends ASTQueries {
if (((IProblemBinding)binding).getID() == IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND) {
IASTNode node = getContainingBlockItem(name.getParent());
ASTNodeProperty prop= node.getPropertyInParent();
while (prop == ICPPASTTemplateDeclaration.OWNED_DECLARATION) {
node= node.getParent();
prop= node.getPropertyInParent();
}
if (prop != IASTCompositeTypeSpecifier.MEMBER_DECLARATION &&
prop != ICPPASTNamespaceDefinition.OWNED_DECLARATION) {
return binding;
}
if (getContainingScope(qname) != getContainingScope(name))
IScope scope= getContainingScope(qname);
while (scope instanceof ICPPTemplateScope) {
try {
scope= scope.getParent();
} catch (DOMException e) {
return binding;
}
}
if (scope != getContainingScope(name))
return binding;
}
} else {
@ -535,13 +546,19 @@ public class CPPVisitor extends ASTQueries {
if (parent instanceof IASTTypeId)
return CPPSemantics.resolveBinding(name);
// explicit instantiations
// function type for non-type template parameter
ASTNodeProperty prop = parent.getPropertyInParent();
if (prop == ICPPASTTemplateDeclaration.PARAMETER) {
return CPPTemplates.createBinding((ICPPASTTemplateParameter) parent);
}
// explicit instantiations
if (prop == ICPPASTExplicitTemplateInstantiation.OWNED_DECLARATION)
return CPPSemantics.resolveBinding(name);
// explicit specializations
if (prop == ICPPASTTemplateSpecialization.OWNED_DECLARATION) {
ICPPASTTemplateDeclaration tmplDecl= CPPTemplates.getTemplateDeclaration(name);
if (tmplDecl instanceof ICPPASTTemplateSpecialization) {
IBinding b= CPPSemantics.resolveBinding(name);
if (b instanceof ICPPInternalBinding) {
if (parent instanceof ICPPASTFunctionDefinition)
@ -551,19 +568,14 @@ public class CPPVisitor extends ASTQueries {
}
return b;
}
// function type for non-type template parameter
if (prop == ICPPASTTemplateDeclaration.PARAMETER) {
return CPPTemplates.createBinding((ICPPASTTemplateParameter) parent);
}
// function declaration/defintion
// function declaration/definition
IBinding binding;
ICPPScope scope = (ICPPScope) getContainingScope((IASTNode) name);
boolean template= false;
final boolean template= tmplDecl != null;
boolean isFriendDecl= false;
ICPPScope scope = (ICPPScope) getContainingScope((IASTNode) name);
try {
while (scope instanceof ICPPTemplateScope) {
template = true;
scope= (ICPPScope) scope.getParent();
}
if (parent instanceof IASTSimpleDeclaration && scope instanceof ICPPClassScope) {
@ -650,20 +662,7 @@ public class CPPVisitor extends ASTQueries {
return function;
}
}
if (binding instanceof IIndexBinding) {
ICPPASTTemplateDeclaration templateDecl = CPPTemplates.getTemplateDeclaration(name);
if (templateDecl != null) {
ICPPASTTemplateParameter[] params = templateDecl.getTemplateParameters();
for (ICPPASTTemplateParameter param : params) {
IASTName paramName = CPPTemplates.getTemplateParameterName(param);
paramName.setBinding(null);
//unsetting the index bindings so that they
//can be re-resolved with normal bindings
}
}
}
if (scope instanceof ICPPClassScope) {
if (isConstructor(scope, funcDeclarator)) {
binding = template ? (ICPPConstructor) new CPPConstructorTemplate(name)

View file

@ -208,7 +208,8 @@ class LookupData {
if (p1 instanceof IASTDeclarator) {
IASTNode p2= CPPVisitor.findOutermostDeclarator((IASTDeclarator) p1).getParent();
if (p2 instanceof IASTSimpleDeclaration || p2 instanceof IASTFunctionDefinition) {
return p2.getParent() instanceof ICPPASTTemplateSpecialization;
ICPPASTTemplateDeclaration tmplDecl = CPPTemplates.getTemplateDeclaration(n);
return tmplDecl instanceof ICPPASTTemplateSpecialization;
}
}
return false;