summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Ridge2013-08-25 01:55:18 (EDT)
committerSergey Prigogin2013-08-26 16:32:00 (EDT)
commit7fc4c9b937c5ffef9c17673a8cabc0953ee00f01 (patch)
treeaef7522a55688ea1b6ec4956765f90bad1b65123
parent50c5677fcfd26594c89550c72ccbf33e7534baab (diff)
downloadorg.eclipse.cdt-7fc4c9b937c5ffef9c17673a8cabc0953ee00f01.zip
org.eclipse.cdt-7fc4c9b937c5ffef9c17673a8cabc0953ee00f01.tar.gz
org.eclipse.cdt-7fc4c9b937c5ffef9c17673a8cabc0953ee00f01.tar.bz2
Bug 401152 - Incorrect semantic error in class template specializationrefs/changes/34/15834/2
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>
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java17
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTQueries.java12
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java14
3 files changed, 41 insertions, 2 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
index 6982923..f71aa75 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
@@ -8019,4 +8019,21 @@ public class AST2TemplateTests extends AST2TestBase {
public void testInstantiationOfTypedef_412555() throws Exception {
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();
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTQueries.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTQueries.java
index fe6042a..7c37366 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTQueries.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTQueries.java
@@ -172,4 +172,16 @@ public class ASTQueries {
}
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;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
index f1f1d1d..3806b7a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
@@ -289,8 +289,18 @@ public class CPPTemplates {
if (node.getPropertyInParent() == IASTCompositeTypeSpecifier.TYPE_NAME)
return null;
if (node instanceof IASTFunctionDefinition) {
- name= ASTQueries.findInnermostDeclarator(((IASTFunctionDefinition) node).getDeclarator()).getName().getLastName();
- scope= CPPVisitor.getContainingScope(name);
+ IASTName functionName= ASTQueries.findInnermostDeclarator(((IASTFunctionDefinition) node).getDeclarator()).getName().getLastName();
+ // '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;
}
if (node instanceof ICPPASTCompositeTypeSpecifier) {