1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 06:05:24 +02:00

Fix for template type resolution bug 229917.

This commit is contained in:
Markus Schorn 2008-05-06 12:40:24 +00:00
parent e100fce79a
commit 1318ab37dd
4 changed files with 74 additions and 49 deletions

View file

@ -15,9 +15,6 @@
package org.eclipse.cdt.core.parser.tests.ast2;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateType;
import java.util.Iterator;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
@ -1525,6 +1522,9 @@ public class AST2TemplateTests extends AST2BaseTest {
CR = (ICPPTemplateParameter) col.getName(14).resolveBinding();
assertSame(CR, T);
CR = (ICPPTemplateParameter) col.getName(16).resolveBinding();
assertSame(CR, T);
}
// template <class T> class Array {};
@ -2055,7 +2055,7 @@ public class AST2TemplateTests extends AST2BaseTest {
//
// template <class _C>
// 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);
IBinding b0 = bh.assertNonProblem("value_type GetPair", 10, IBinding.class);
}
@ -2168,8 +2168,8 @@ public class AST2TemplateTests extends AST2BaseTest {
tu.accept(col);
IASTName name;
for (Iterator i = col.nameList.iterator(); i.hasNext();) {
name = (IASTName) i.next();
for (Object element : col.nameList) {
name = (IASTName) element;
assertFalse(name.resolveBinding() instanceof IProblemBinding);
}

View file

@ -16,7 +16,6 @@ import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.parser.tests.ParserTestSuite;
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 static Test suite() {
TestSuite suite= new TestSuite(ParserTestSuite.class.getName());
TestSuite suite= new TestSuite(DOMParserTestSuite.class.getName());
suite.addTest(AST2Tests.suite());
suite.addTestSuite(GCCTests.class);
suite.addTest(AST2CPPTests.suite());

View file

@ -773,63 +773,79 @@ public class CPPTemplates {
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 &lttypename T&gt void MyTemplate&ltT&gt::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) {
if (name == null) return null;
if (name == null) {
return null;
}
IASTNode parent = name.getParent();
while (parent instanceof IASTName) {
parent = parent.getParent();
}
if (parent instanceof IASTDeclSpecifier) {
parent = parent.getParent();
if (parent instanceof IASTCompositeTypeSpecifier == false
&& parent instanceof IASTElaboratedTypeSpecifier == false) {
return null;
}
parent = parent.getParent();
} else {
while (parent instanceof IASTDeclarator) {
parent = parent.getParent();
}
}
if (parent instanceof IASTDeclaration && parent.getParent() instanceof ICPPASTTemplateDeclaration) {
parent = parent.getParent();
} else {
if (parent instanceof IASTDeclaration == false) {
return null;
}
parent = parent.getParent();
if (parent instanceof ICPPASTTemplateDeclaration) {
ICPPASTTemplateDeclaration templateDecl = (ICPPASTTemplateDeclaration) parent;
while (templateDecl.getParent() instanceof ICPPASTTemplateDeclaration)
templateDecl = (ICPPASTTemplateDeclaration) templateDecl.getParent();
IASTName[] ns = null;
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();
}
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 {
while (templateDecl.getDeclaration() instanceof ICPPASTTemplateDeclaration) {
templateDecl = (ICPPASTTemplateDeclaration) templateDecl.getDeclaration();
}
// 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;
return null;
}
public static IASTName getTemplateName(ICPPASTTemplateDeclaration templateDecl) {

View file

@ -778,6 +778,8 @@ public class CPPVisitor {
return ((ICPPASTIfStatement)parent).getScope();
} else if (parent instanceof ICPPASTWhileStatement) {
return ((ICPPASTWhileStatement)parent).getScope();
} else if (parent instanceof ICPPASTTemplateDeclaration) {
return ((ICPPASTTemplateDeclaration)parent).getScope();
}
} else if (node instanceof IASTStatement) {
return getContainingScope((IASTStatement) node);
@ -886,18 +888,30 @@ public class CPPVisitor {
name = (IASTName) parent;
parent = name.getParent();
}
ICPPASTTemplateDeclaration decl = CPPTemplates.getTemplateDeclaration(name);
if (decl != null)
return decl.getScope();
ICPPASTTemplateDeclaration tmplDecl = CPPTemplates.getTemplateDeclaration(name);
if (tmplDecl != null)
return tmplDecl.getScope();
if (parent instanceof ICPPASTQualifiedName) {
IASTName[] names = ((ICPPASTQualifiedName) parent).getNames();
final ICPPASTQualifiedName qname= (ICPPASTQualifiedName) parent;
final IASTName[] names = qname.getNames();
int i = 0;
for (; i < names.length; i++) {
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) {
IBinding binding = names[i - 1].resolveBinding();
IBinding binding = names[i-1].resolveBinding();
while (binding instanceof ITypedef) {
IType t = ((ITypedef)binding).getType();
if (t instanceof IBinding)
@ -925,11 +939,7 @@ public class CPPVisitor {
}
return scope;
}
}
else if (((ICPPASTQualifiedName)parent).isFullyQualified())
{
return parent.getTranslationUnit().getScope();
}
}
} else if (parent instanceof ICPPASTFieldReference) {
final ICPPASTFieldReference fieldReference = (ICPPASTFieldReference)parent;
IASTExpression owner = fieldReference.getFieldOwner();