mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-26 18:35:32 +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>::mytype1 XT<T>::m1() {}
|
||||||
// template <typename T> typename XT<T*>::mytype2 XT<T*>::m2() {}
|
// 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 {
|
public void testMethodImplWithNonDeferredType() throws Exception {
|
||||||
final String code = getAboveComment();
|
final String code = getAboveComment();
|
||||||
parseAndCheckBindings(code, ParserLanguage.CPP);
|
parseAndCheckBindings(code, ParserLanguage.CPP);
|
||||||
|
@ -3352,7 +3352,7 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
// template<typename T> void f(T);
|
// template<typename T> void f(T);
|
||||||
// };
|
// };
|
||||||
// template<typename T> void A<float>::f(T){} //problem on f
|
// 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();
|
final String code = getAboveComment();
|
||||||
parseAndCheckBindings(code, ParserLanguage.CPP);
|
parseAndCheckBindings(code, ParserLanguage.CPP);
|
||||||
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||||
|
@ -3367,4 +3367,22 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
method= bh.assertNonProblem("A<float>::f", 11);
|
method= bh.assertNonProblem("A<float>::f", 11);
|
||||||
assertSame(method.getOwner(), special);
|
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
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* IBM - Initial API and implementation
|
* John Camelon (IBM) - Initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
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.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
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.ICPPASTTemplateParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope;
|
||||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
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.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
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
|
public class CPPASTTemplateDeclaration extends ASTNode implements
|
||||||
ICPPASTTemplateDeclaration, IASTAmbiguityParent {
|
ICPPASTInternalTemplateDeclaration, IASTAmbiguityParent {
|
||||||
|
|
||||||
private boolean exported;
|
private boolean exported;
|
||||||
|
private byte isAssociatedWithLastName= -1;
|
||||||
|
private short nestingLevel= -1;
|
||||||
private IASTDeclaration declaration;
|
private IASTDeclaration declaration;
|
||||||
private ICPPTemplateScope templateScope;
|
private ICPPTemplateScope templateScope;
|
||||||
|
|
||||||
|
@ -116,4 +118,29 @@ public class CPPASTTemplateDeclaration extends ASTNode implements
|
||||||
declaration = (IASTDeclaration) other;
|
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
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* 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;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
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.ICPPASTTemplateParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope;
|
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.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
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
|
public class CPPASTTemplateSpecialization extends ASTNode implements
|
||||||
ICPPASTTemplateSpecialization, ICPPASTTemplateDeclaration, IASTAmbiguityParent {
|
ICPPASTTemplateSpecialization, ICPPASTInternalTemplateDeclaration, IASTAmbiguityParent {
|
||||||
|
|
||||||
private IASTDeclaration declaration;
|
private IASTDeclaration declaration;
|
||||||
private ICPPTemplateScope templateScope;
|
private ICPPTemplateScope templateScope;
|
||||||
|
private short nestingLevel= -1;
|
||||||
|
private byte isAssociatedWithLastName= -1;
|
||||||
|
|
||||||
|
|
||||||
public CPPASTTemplateSpecialization() {
|
public CPPASTTemplateSpecialization() {
|
||||||
|
@ -98,4 +101,29 @@ public class CPPASTTemplateSpecialization extends ASTNode implements
|
||||||
declaration = (IASTDeclaration) other;
|
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.IProblemBinding;
|
||||||
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.cpp.ICPPASTTemplateDeclaration;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
|
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.ICPPASTTemplatedTypeTemplateParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
|
||||||
|
@ -42,28 +41,31 @@ public abstract class CPPTemplateParameter extends PlatformObject
|
||||||
|
|
||||||
public CPPTemplateParameter(IASTName name) {
|
public CPPTemplateParameter(IASTName name) {
|
||||||
declarations = new IASTName[] {name};
|
declarations = new IASTName[] {name};
|
||||||
fParameterID= computeParameterPosition(name);
|
fParameterID= computeParameterID(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int computeParameterPosition(IASTName name) {
|
private int computeParameterID(IASTName name) {
|
||||||
int pos= -1;
|
int nesting= 0;
|
||||||
int nesting= -1;
|
|
||||||
ICPPASTTemplateParameter tp= null;
|
ICPPASTTemplateParameter tp= null;
|
||||||
for (IASTNode node= name.getParent(); node != null; node= node.getParent()) {
|
|
||||||
ICPPASTTemplateParameter[] tps= null;
|
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;
|
tp= (ICPPASTTemplateParameter) node;
|
||||||
} else if (node instanceof ICPPASTTemplateDeclaration) {
|
} else if (node instanceof ICPPASTInternalTemplateDeclaration) {
|
||||||
if (++nesting == 0) {
|
final ICPPASTInternalTemplateDeclaration tdecl= (ICPPASTInternalTemplateDeclaration) node;
|
||||||
tps= ((ICPPASTTemplateDeclaration) node).getTemplateParameters();
|
nesting+= tdecl.getNestingLevel();
|
||||||
|
if (tps == null) {
|
||||||
|
tps= tdecl.getTemplateParameters();
|
||||||
}
|
}
|
||||||
} else if (node instanceof ICPPASTTemplatedTypeTemplateParameter) {
|
} else if (node instanceof ICPPASTTemplatedTypeTemplateParameter) {
|
||||||
if (++nesting == 0) {
|
nesting++;
|
||||||
|
if (tps == null) {
|
||||||
tps= ((ICPPASTTemplatedTypeTemplateParameter) node).getTemplateParameters();
|
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++) {
|
for (int i = 0; i < tps.length; i++) {
|
||||||
if (tps[i] == tp) {
|
if (tps[i] == tp) {
|
||||||
pos= i;
|
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
|
@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 java.util.List;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
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.DOMException;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
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.IASTElaboratedTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
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.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
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.ICPPTemplateTypeParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
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.ArrayUtil;
|
||||||
|
import org.eclipse.cdt.core.parser.util.CharArraySet;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
import org.eclipse.cdt.core.parser.util.ObjectMap;
|
import org.eclipse.cdt.core.parser.util.ObjectMap;
|
||||||
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
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.CPPTypedefSpecialization;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClass;
|
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.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.ICPPDeferredClassInstance;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
|
||||||
|
@ -483,9 +488,9 @@ public class CPPTemplates {
|
||||||
|
|
||||||
final ICPPClassTemplate classTemplate = (ICPPClassTemplate) template;
|
final ICPPClassTemplate classTemplate = (ICPPClassTemplate) template;
|
||||||
ICPPTemplateArgument[] args= createTemplateArgumentArray(id);
|
ICPPTemplateArgument[] args= createTemplateArgumentArray(id);
|
||||||
|
if (hasDependentArgument(args)) {
|
||||||
ICPPASTTemplateDeclaration tdecl= getTemplateDeclaration(id);
|
ICPPASTTemplateDeclaration tdecl= getTemplateDeclaration(id);
|
||||||
if (tdecl != null) {
|
if (tdecl != null) {
|
||||||
if (hasDependentArgument(args)) {
|
|
||||||
if (argsAreTrivial(classTemplate.getTemplateParameters(), args)) {
|
if (argsAreTrivial(classTemplate.getTemplateParameters(), args)) {
|
||||||
result= classTemplate;
|
result= classTemplate;
|
||||||
} else {
|
} else {
|
||||||
|
@ -830,10 +835,248 @@ public class CPPTemplates {
|
||||||
* correspond to a template declaration.
|
* correspond to a template declaration.
|
||||||
*/
|
*/
|
||||||
public static ICPPASTTemplateDeclaration getTemplateDeclaration(IASTName name) {
|
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;
|
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();
|
IASTNode parent = name.getParent();
|
||||||
while (parent instanceof IASTName) {
|
while (parent instanceof IASTName) {
|
||||||
parent = parent.getParent();
|
parent = parent.getParent();
|
||||||
|
@ -849,47 +1092,22 @@ public class CPPTemplates {
|
||||||
parent = parent.getParent();
|
parent = parent.getParent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(parent instanceof IASTDeclaration)) {
|
if (!(parent instanceof IASTDeclaration))
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
parent = parent.getParent();
|
parent = parent.getParent();
|
||||||
if (parent instanceof ICPPASTTemplateDeclaration) {
|
if (parent instanceof ICPPASTInternalTemplateDeclaration)
|
||||||
ICPPASTTemplateDeclaration templateDecl = (ICPPASTTemplateDeclaration) parent;
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
if (singleName instanceof ICPPASTTemplateId) {
|
|
||||||
final IASTDeclaration next= templateDecl.getDeclaration();
|
private static ICPPASTInternalTemplateDeclaration getDirectlyEnclosingTemplateDeclaration(
|
||||||
if (next instanceof ICPPASTTemplateDeclaration) {
|
ICPPASTInternalTemplateDeclaration tdecl ) {
|
||||||
templateDecl= (ICPPASTTemplateDeclaration) next;
|
final IASTNode parent= tdecl.getParent();
|
||||||
} else {
|
if (parent instanceof ICPPASTInternalTemplateDeclaration)
|
||||||
return null;
|
return (ICPPASTInternalTemplateDeclaration) parent;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -215,12 +215,23 @@ public class CPPVisitor extends ASTQueries {
|
||||||
if (((IProblemBinding)binding).getID() == IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND) {
|
if (((IProblemBinding)binding).getID() == IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND) {
|
||||||
IASTNode node = getContainingBlockItem(name.getParent());
|
IASTNode node = getContainingBlockItem(name.getParent());
|
||||||
ASTNodeProperty prop= node.getPropertyInParent();
|
ASTNodeProperty prop= node.getPropertyInParent();
|
||||||
|
while (prop == ICPPASTTemplateDeclaration.OWNED_DECLARATION) {
|
||||||
|
node= node.getParent();
|
||||||
|
prop= node.getPropertyInParent();
|
||||||
|
}
|
||||||
if (prop != IASTCompositeTypeSpecifier.MEMBER_DECLARATION &&
|
if (prop != IASTCompositeTypeSpecifier.MEMBER_DECLARATION &&
|
||||||
prop != ICPPASTNamespaceDefinition.OWNED_DECLARATION) {
|
prop != ICPPASTNamespaceDefinition.OWNED_DECLARATION) {
|
||||||
return binding;
|
return binding;
|
||||||
}
|
}
|
||||||
|
IScope scope= getContainingScope(qname);
|
||||||
if (getContainingScope(qname) != getContainingScope(name))
|
while (scope instanceof ICPPTemplateScope) {
|
||||||
|
try {
|
||||||
|
scope= scope.getParent();
|
||||||
|
} catch (DOMException e) {
|
||||||
|
return binding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (scope != getContainingScope(name))
|
||||||
return binding;
|
return binding;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -535,13 +546,19 @@ public class CPPVisitor extends ASTQueries {
|
||||||
if (parent instanceof IASTTypeId)
|
if (parent instanceof IASTTypeId)
|
||||||
return CPPSemantics.resolveBinding(name);
|
return CPPSemantics.resolveBinding(name);
|
||||||
|
|
||||||
// explicit instantiations
|
// function type for non-type template parameter
|
||||||
ASTNodeProperty prop = parent.getPropertyInParent();
|
ASTNodeProperty prop = parent.getPropertyInParent();
|
||||||
|
if (prop == ICPPASTTemplateDeclaration.PARAMETER) {
|
||||||
|
return CPPTemplates.createBinding((ICPPASTTemplateParameter) parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// explicit instantiations
|
||||||
if (prop == ICPPASTExplicitTemplateInstantiation.OWNED_DECLARATION)
|
if (prop == ICPPASTExplicitTemplateInstantiation.OWNED_DECLARATION)
|
||||||
return CPPSemantics.resolveBinding(name);
|
return CPPSemantics.resolveBinding(name);
|
||||||
|
|
||||||
// explicit specializations
|
// explicit specializations
|
||||||
if (prop == ICPPASTTemplateSpecialization.OWNED_DECLARATION) {
|
ICPPASTTemplateDeclaration tmplDecl= CPPTemplates.getTemplateDeclaration(name);
|
||||||
|
if (tmplDecl instanceof ICPPASTTemplateSpecialization) {
|
||||||
IBinding b= CPPSemantics.resolveBinding(name);
|
IBinding b= CPPSemantics.resolveBinding(name);
|
||||||
if (b instanceof ICPPInternalBinding) {
|
if (b instanceof ICPPInternalBinding) {
|
||||||
if (parent instanceof ICPPASTFunctionDefinition)
|
if (parent instanceof ICPPASTFunctionDefinition)
|
||||||
|
@ -551,19 +568,14 @@ public class CPPVisitor extends ASTQueries {
|
||||||
}
|
}
|
||||||
return b;
|
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;
|
IBinding binding;
|
||||||
ICPPScope scope = (ICPPScope) getContainingScope((IASTNode) name);
|
final boolean template= tmplDecl != null;
|
||||||
boolean template= false;
|
|
||||||
boolean isFriendDecl= false;
|
boolean isFriendDecl= false;
|
||||||
|
ICPPScope scope = (ICPPScope) getContainingScope((IASTNode) name);
|
||||||
try {
|
try {
|
||||||
while (scope instanceof ICPPTemplateScope) {
|
while (scope instanceof ICPPTemplateScope) {
|
||||||
template = true;
|
|
||||||
scope= (ICPPScope) scope.getParent();
|
scope= (ICPPScope) scope.getParent();
|
||||||
}
|
}
|
||||||
if (parent instanceof IASTSimpleDeclaration && scope instanceof ICPPClassScope) {
|
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 (scope instanceof ICPPClassScope) {
|
||||||
if (isConstructor(scope, funcDeclarator)) {
|
if (isConstructor(scope, funcDeclarator)) {
|
||||||
binding = template ? (ICPPConstructor) new CPPConstructorTemplate(name)
|
binding = template ? (ICPPConstructor) new CPPConstructorTemplate(name)
|
||||||
|
|
|
@ -208,7 +208,8 @@ class LookupData {
|
||||||
if (p1 instanceof IASTDeclarator) {
|
if (p1 instanceof IASTDeclarator) {
|
||||||
IASTNode p2= CPPVisitor.findOutermostDeclarator((IASTDeclarator) p1).getParent();
|
IASTNode p2= CPPVisitor.findOutermostDeclarator((IASTDeclarator) p1).getParent();
|
||||||
if (p2 instanceof IASTSimpleDeclaration || p2 instanceof IASTFunctionDefinition) {
|
if (p2 instanceof IASTSimpleDeclaration || p2 instanceof IASTFunctionDefinition) {
|
||||||
return p2.getParent() instanceof ICPPASTTemplateSpecialization;
|
ICPPASTTemplateDeclaration tmplDecl = CPPTemplates.getTemplateDeclaration(n);
|
||||||
|
return tmplDecl instanceof ICPPASTTemplateSpecialization;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Add table
Reference in a new issue