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:
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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 <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) {
|
||||
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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Reference in a new issue