mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-09 18:15:23 +02:00
Fix for template type resolution bug 229917.
This commit is contained in:
parent
e100fce79a
commit
1318ab37dd
4 changed files with 74 additions and 49 deletions
|
@ -15,9 +15,6 @@
|
||||||
package org.eclipse.cdt.core.parser.tests.ast2;
|
package org.eclipse.cdt.core.parser.tests.ast2;
|
||||||
|
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateType;
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateType;
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
import junit.framework.TestSuite;
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
||||||
|
@ -1525,6 +1522,9 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
|
|
||||||
CR = (ICPPTemplateParameter) col.getName(14).resolveBinding();
|
CR = (ICPPTemplateParameter) col.getName(14).resolveBinding();
|
||||||
assertSame(CR, T);
|
assertSame(CR, T);
|
||||||
|
|
||||||
|
CR = (ICPPTemplateParameter) col.getName(16).resolveBinding();
|
||||||
|
assertSame(CR, T);
|
||||||
}
|
}
|
||||||
|
|
||||||
// template <class T> class Array {};
|
// template <class T> class Array {};
|
||||||
|
@ -2055,7 +2055,7 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
//
|
//
|
||||||
// template <class _C>
|
// template <class _C>
|
||||||
// typename _C::value_type GetPair(_C& collection, typename _C::value_type::first_type key);
|
// typename _C::value_type GetPair(_C& collection, typename _C::value_type::first_type key);
|
||||||
public void _testBug229917_2() throws Exception {
|
public void testBug229917_2() throws Exception {
|
||||||
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true);
|
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
IBinding b0 = bh.assertNonProblem("value_type GetPair", 10, IBinding.class);
|
IBinding b0 = bh.assertNonProblem("value_type GetPair", 10, IBinding.class);
|
||||||
}
|
}
|
||||||
|
@ -2168,8 +2168,8 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
tu.accept(col);
|
tu.accept(col);
|
||||||
|
|
||||||
IASTName name;
|
IASTName name;
|
||||||
for (Iterator i = col.nameList.iterator(); i.hasNext();) {
|
for (Object element : col.nameList) {
|
||||||
name = (IASTName) i.next();
|
name = (IASTName) element;
|
||||||
assertFalse(name.resolveBinding() instanceof IProblemBinding);
|
assertFalse(name.resolveBinding() instanceof IProblemBinding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ import junit.framework.Test;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
import junit.framework.TestSuite;
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.parser.tests.ParserTestSuite;
|
|
||||||
import org.eclipse.cdt.core.parser.tests.prefix.CompletionTestSuite;
|
import org.eclipse.cdt.core.parser.tests.prefix.CompletionTestSuite;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,7 +23,7 @@ import org.eclipse.cdt.core.parser.tests.prefix.CompletionTestSuite;
|
||||||
*/
|
*/
|
||||||
public class DOMParserTestSuite extends TestCase {
|
public class DOMParserTestSuite extends TestCase {
|
||||||
public static Test suite() {
|
public static Test suite() {
|
||||||
TestSuite suite= new TestSuite(ParserTestSuite.class.getName());
|
TestSuite suite= new TestSuite(DOMParserTestSuite.class.getName());
|
||||||
suite.addTest(AST2Tests.suite());
|
suite.addTest(AST2Tests.suite());
|
||||||
suite.addTestSuite(GCCTests.class);
|
suite.addTestSuite(GCCTests.class);
|
||||||
suite.addTest(AST2CPPTests.suite());
|
suite.addTest(AST2CPPTests.suite());
|
||||||
|
|
|
@ -773,63 +773,79 @@ public class CPPTemplates {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a given name corresponds to a template declaration and returns the ast node for it.
|
||||||
|
* This works for the name of a template-definition and also for a name needed to qualify a member
|
||||||
|
* definition:
|
||||||
|
* <pre>
|
||||||
|
* template <typename T> void MyTemplate<T>::member() {}
|
||||||
|
* </pre>
|
||||||
|
* @param name a name for which the corresponding template declaration is searched for.
|
||||||
|
* @return the template declaration or <code>null</code> if <code>name</code> does not
|
||||||
|
* correspond to a template declaration.
|
||||||
|
*/
|
||||||
public static ICPPASTTemplateDeclaration getTemplateDeclaration(IASTName name) {
|
public static ICPPASTTemplateDeclaration getTemplateDeclaration(IASTName name) {
|
||||||
if (name == null) return null;
|
if (name == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
IASTNode parent = name.getParent();
|
IASTNode parent = name.getParent();
|
||||||
while (parent instanceof IASTName) {
|
while (parent instanceof IASTName) {
|
||||||
parent = parent.getParent();
|
parent = parent.getParent();
|
||||||
}
|
}
|
||||||
if (parent instanceof IASTDeclSpecifier) {
|
if (parent instanceof IASTDeclSpecifier) {
|
||||||
parent = parent.getParent();
|
if (parent instanceof IASTCompositeTypeSpecifier == false
|
||||||
|
&& parent instanceof IASTElaboratedTypeSpecifier == false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
parent = parent.getParent();
|
||||||
} else {
|
} else {
|
||||||
while (parent instanceof IASTDeclarator) {
|
while (parent instanceof IASTDeclarator) {
|
||||||
parent = parent.getParent();
|
parent = parent.getParent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (parent instanceof IASTDeclaration && parent.getParent() instanceof ICPPASTTemplateDeclaration) {
|
if (parent instanceof IASTDeclaration == false) {
|
||||||
parent = parent.getParent();
|
|
||||||
} else {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parent = parent.getParent();
|
||||||
if (parent instanceof ICPPASTTemplateDeclaration) {
|
if (parent instanceof ICPPASTTemplateDeclaration) {
|
||||||
ICPPASTTemplateDeclaration templateDecl = (ICPPASTTemplateDeclaration) parent;
|
ICPPASTTemplateDeclaration templateDecl = (ICPPASTTemplateDeclaration) parent;
|
||||||
while (templateDecl.getParent() instanceof ICPPASTTemplateDeclaration)
|
|
||||||
templateDecl = (ICPPASTTemplateDeclaration) templateDecl.getParent();
|
|
||||||
|
|
||||||
IASTName[] ns = null;
|
IASTName[] ns;
|
||||||
if (name instanceof ICPPASTQualifiedName) {
|
if (name instanceof ICPPASTQualifiedName) {
|
||||||
ns = ((ICPPASTQualifiedName) name).getNames();
|
ns = ((ICPPASTQualifiedName) name).getNames();
|
||||||
name = ns[ns.length - 1];
|
name = ns[ns.length - 1];
|
||||||
} else if (name.getParent() instanceof ICPPASTQualifiedName) {
|
} else if (name.getParent() instanceof ICPPASTQualifiedName) {
|
||||||
ns = ((ICPPASTQualifiedName) name.getParent()).getNames();
|
ns = ((ICPPASTQualifiedName) name.getParent()).getNames();
|
||||||
}
|
|
||||||
if (ns != null) {
|
|
||||||
IASTDeclaration currDecl = templateDecl;
|
|
||||||
for (int j = 0; j < ns.length; j++) {
|
|
||||||
if (ns[j] == name) {
|
|
||||||
if (ns[j] instanceof ICPPASTTemplateId || j + 1 == ns.length) {
|
|
||||||
if (currDecl instanceof ICPPASTTemplateDeclaration)
|
|
||||||
return (ICPPASTTemplateDeclaration) currDecl;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ns[j] instanceof ICPPASTTemplateId) {
|
|
||||||
if (currDecl instanceof ICPPASTTemplateDeclaration)
|
|
||||||
currDecl = ((ICPPASTTemplateDeclaration) currDecl).getDeclaration();
|
|
||||||
else
|
|
||||||
return null; //??? this would imply bad ast or code
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
while (templateDecl.getDeclaration() instanceof ICPPASTTemplateDeclaration) {
|
// one name: use innermost template declaration
|
||||||
templateDecl = (ICPPASTTemplateDeclaration) templateDecl.getDeclaration();
|
|
||||||
}
|
|
||||||
return templateDecl;
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IASTName getTemplateName(ICPPASTTemplateDeclaration templateDecl) {
|
public static IASTName getTemplateName(ICPPASTTemplateDeclaration templateDecl) {
|
||||||
|
|
|
@ -778,6 +778,8 @@ public class CPPVisitor {
|
||||||
return ((ICPPASTIfStatement)parent).getScope();
|
return ((ICPPASTIfStatement)parent).getScope();
|
||||||
} else if (parent instanceof ICPPASTWhileStatement) {
|
} else if (parent instanceof ICPPASTWhileStatement) {
|
||||||
return ((ICPPASTWhileStatement)parent).getScope();
|
return ((ICPPASTWhileStatement)parent).getScope();
|
||||||
|
} else if (parent instanceof ICPPASTTemplateDeclaration) {
|
||||||
|
return ((ICPPASTTemplateDeclaration)parent).getScope();
|
||||||
}
|
}
|
||||||
} else if (node instanceof IASTStatement) {
|
} else if (node instanceof IASTStatement) {
|
||||||
return getContainingScope((IASTStatement) node);
|
return getContainingScope((IASTStatement) node);
|
||||||
|
@ -886,18 +888,30 @@ public class CPPVisitor {
|
||||||
name = (IASTName) parent;
|
name = (IASTName) parent;
|
||||||
parent = name.getParent();
|
parent = name.getParent();
|
||||||
}
|
}
|
||||||
ICPPASTTemplateDeclaration decl = CPPTemplates.getTemplateDeclaration(name);
|
ICPPASTTemplateDeclaration tmplDecl = CPPTemplates.getTemplateDeclaration(name);
|
||||||
if (decl != null)
|
if (tmplDecl != null)
|
||||||
return decl.getScope();
|
return tmplDecl.getScope();
|
||||||
|
|
||||||
if (parent instanceof ICPPASTQualifiedName) {
|
if (parent instanceof ICPPASTQualifiedName) {
|
||||||
IASTName[] names = ((ICPPASTQualifiedName) parent).getNames();
|
final ICPPASTQualifiedName qname= (ICPPASTQualifiedName) parent;
|
||||||
|
final IASTName[] names = qname.getNames();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (; i < names.length; i++) {
|
for (; i < names.length; i++) {
|
||||||
if (names[i] == name) break;
|
if (names[i] == name) break;
|
||||||
}
|
}
|
||||||
|
if (i == 0) {
|
||||||
|
if (qname.isFullyQualified()) {
|
||||||
|
return parent.getTranslationUnit().getScope();
|
||||||
|
}
|
||||||
|
for (int j=1; j < names.length; j++) {
|
||||||
|
tmplDecl = CPPTemplates.getTemplateDeclaration(names[j]);
|
||||||
|
if (tmplDecl != null) {
|
||||||
|
return getContainingScope(tmplDecl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
IBinding binding = names[i - 1].resolveBinding();
|
IBinding binding = names[i-1].resolveBinding();
|
||||||
while (binding instanceof ITypedef) {
|
while (binding instanceof ITypedef) {
|
||||||
IType t = ((ITypedef)binding).getType();
|
IType t = ((ITypedef)binding).getType();
|
||||||
if (t instanceof IBinding)
|
if (t instanceof IBinding)
|
||||||
|
@ -925,11 +939,7 @@ public class CPPVisitor {
|
||||||
}
|
}
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (((ICPPASTQualifiedName)parent).isFullyQualified())
|
|
||||||
{
|
|
||||||
return parent.getTranslationUnit().getScope();
|
|
||||||
}
|
|
||||||
} else if (parent instanceof ICPPASTFieldReference) {
|
} else if (parent instanceof ICPPASTFieldReference) {
|
||||||
final ICPPASTFieldReference fieldReference = (ICPPASTFieldReference)parent;
|
final ICPPASTFieldReference fieldReference = (ICPPASTFieldReference)parent;
|
||||||
IASTExpression owner = fieldReference.getFieldOwner();
|
IASTExpression owner = fieldReference.getFieldOwner();
|
||||||
|
|
Loading…
Add table
Reference in a new issue