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:
parent
e2ce799dae
commit
45f3fe8e97
8 changed files with 436 additions and 104 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,28 +41,31 @@ 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;
|
||||
for (IASTNode node= name.getParent(); node != null; node= node.getParent()) {
|
||||
ICPPASTTemplateParameter[] tps= null;
|
||||
if (node instanceof ICPPASTTemplateParameter) {
|
||||
for (IASTNode node= name.getParent(); node != null; node= node.getParent()) {
|
||||
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) {
|
||||
}
|
||||
int pos= 0;
|
||||
if (tps != null && tp != null) {
|
||||
for (int i = 0; i < tps.length; i++) {
|
||||
if (tps[i] == tp) {
|
||||
pos= i;
|
||||
|
@ -71,13 +73,8 @@ public abstract class CPPTemplateParameter extends PlatformObject
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nesting < 0)
|
||||
nesting= 0;
|
||||
if (pos < 0)
|
||||
pos= 0;
|
||||
|
||||
return (nesting << 16) + pos;
|
||||
return (nesting << 16) + (pos & 0xffff);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
if (hasDependentArgument(args)) {
|
||||
ICPPASTTemplateDeclaration tdecl= getTemplateDeclaration(id);
|
||||
if (tdecl != null) {
|
||||
if (hasDependentArgument(args)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ICPPASTInternalTemplateDeclaration getDirectlyEnclosingTemplateDeclaration(
|
||||
ICPPASTInternalTemplateDeclaration tdecl ) {
|
||||
final IASTNode parent= tdecl.getParent();
|
||||
if (parent instanceof ICPPASTInternalTemplateDeclaration)
|
||||
return (ICPPASTInternalTemplateDeclaration) parent;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
@ -651,19 +663,6 @@ public class CPPVisitor extends ASTQueries {
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue