mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-01 13:25:45 +02:00
Bug 401152 - Incorrect semantic error in class template specialization
Change-Id: I962872a55bcc34f6ebfb944b7406c94af8f8d489 Signed-off-by: Nathan Ridge <zeratul976@hotmail.com> Reviewed-on: https://git.eclipse.org/r/15834 Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com> IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com> Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
parent
50c5677fcf
commit
7fc4c9b937
3 changed files with 41 additions and 2 deletions
|
@ -8019,4 +8019,21 @@ public class AST2TemplateTests extends AST2TestBase {
|
||||||
public void testInstantiationOfTypedef_412555() throws Exception {
|
public void testInstantiationOfTypedef_412555() throws Exception {
|
||||||
parseAndCheckBindings();
|
parseAndCheckBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template <class T>
|
||||||
|
// struct B {};
|
||||||
|
//
|
||||||
|
// template <class Abstract, class T>
|
||||||
|
// struct A;
|
||||||
|
//
|
||||||
|
// template <class T>
|
||||||
|
// struct A<B<T>, T> {
|
||||||
|
// void method();
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// template <class T>
|
||||||
|
// void A<B<T>, T>::method() {}
|
||||||
|
public void testOutOfLineMethodOfPartialSpecialization_401152() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,4 +172,16 @@ public class ASTQueries {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether 'ancestor' is an ancestor of 'descendant' in the AST.
|
||||||
|
*/
|
||||||
|
public static boolean isAncestorOf(IASTNode ancestor, IASTNode descendant) {
|
||||||
|
do {
|
||||||
|
if (descendant == ancestor)
|
||||||
|
return true;
|
||||||
|
descendant = descendant.getParent();
|
||||||
|
} while (descendant != null);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,8 +289,18 @@ public class CPPTemplates {
|
||||||
if (node.getPropertyInParent() == IASTCompositeTypeSpecifier.TYPE_NAME)
|
if (node.getPropertyInParent() == IASTCompositeTypeSpecifier.TYPE_NAME)
|
||||||
return null;
|
return null;
|
||||||
if (node instanceof IASTFunctionDefinition) {
|
if (node instanceof IASTFunctionDefinition) {
|
||||||
name= ASTQueries.findInnermostDeclarator(((IASTFunctionDefinition) node).getDeclarator()).getName().getLastName();
|
IASTName functionName= ASTQueries.findInnermostDeclarator(((IASTFunctionDefinition) node).getDeclarator()).getName().getLastName();
|
||||||
scope= CPPVisitor.getContainingScope(name);
|
// 'name' may be inside the qualifier of a method name in a out-of-line method definition.
|
||||||
|
// In such a case, calling getContainingScope() on the method name will attempt to
|
||||||
|
// resolve the qualifier, which will attempt to resolve 'name', which will get into
|
||||||
|
// a recursion as 'name' is currently being resolved. Since an out-of-line method
|
||||||
|
// definition cannot be inside a template scope, we can accurately return null
|
||||||
|
// in this case.
|
||||||
|
if (functionName.getParent() instanceof ICPPASTQualifiedName
|
||||||
|
&& ASTQueries.isAncestorOf(functionName.getParent(), name)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
scope= CPPVisitor.getContainingScope(functionName);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (node instanceof ICPPASTCompositeTypeSpecifier) {
|
if (node instanceof ICPPASTCompositeTypeSpecifier) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue