From 492d8e61e0cffe44102c0621d14bbdf62a81a3e8 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Mon, 8 Mar 2010 10:24:16 +0000 Subject: [PATCH] Bug 296427: Api to distinguish explicit specializatio --- .../parser/tests/ast2/AST2TemplateTests.java | 28 +++++++++++++++++++ .../tests/IndexBindingResolutionTestBase.java | 3 ++ .../tests/IndexCPPTemplateResolutionTest.java | 25 +++++++++++++++++ .../dom/ast/cpp/ICPPTemplateInstance.java | 12 ++++++-- .../core/dom/parser/cpp/CPPClassInstance.java | 11 +++++++- .../parser/cpp/CPPDeferredClassInstance.java | 4 +++ .../dom/parser/cpp/CPPFunctionInstance.java | 16 ++++++++++- .../parser/cpp/semantics/CPPTemplates.java | 16 ++++------- .../cpp/CompositeCPPClassInstance.java | 6 +++- .../CompositeCPPDeferredClassInstance.java | 6 +++- .../cpp/CompositeCPPFunctionInstance.java | 6 +++- .../pdom/dom/cpp/PDOMCPPClassInstance.java | 7 ++++- .../dom/cpp/PDOMCPPDeferredClassInstance.java | 6 +++- .../pdom/dom/cpp/PDOMCPPFunctionInstance.java | 11 ++++++-- 14 files changed, 135 insertions(+), 22 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 e38758bd93f..810ef3a3a18 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 @@ -4835,4 +4835,32 @@ public class AST2TemplateTests extends AST2BaseTest { assertSame(ct, inst.getSpecializedBinding()); } + // template class X {}; + // template class Y {}; + // template<> class Y {}; + // template void f(T t) {} + // template void g(T t) {} + // template<> void g(int t) {} + // void test() { + // X x; + // Y y; + // f(1); + // g(1); + // } + public void testExplicitSpecializations_296427() throws Exception { + final String code= getAboveComment(); + BindingAssertionHelper bh= new BindingAssertionHelper(code, true); + + ICPPTemplateInstance inst; + inst= bh.assertNonProblem("X", 0); + assertFalse(inst.isExplicitSpecialization()); + inst = bh.assertNonProblem("Y y;", 6); + assertTrue(inst.isExplicitSpecialization()); + + inst = bh.assertNonProblem("f(1)", 1); + assertFalse(inst.isExplicitSpecialization()); + inst = bh.assertNonProblem("g(1)", 1); + assertTrue(inst.isExplicitSpecialization()); + } + } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java index dacb2fac63f..86e7f36b317 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBindingResolutionTestBase.java @@ -117,6 +117,9 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase { * @see IndexBindingResolutionTestBase#getBindingFromASTName(Class, String, int) */ protected T getBindingFromASTName(String section, int len) { + if (len <= 0) + len+= section.length(); + IASTName name= findName(section, len); assertNotNull("name not found for \""+section+"\"", name); assertEquals(section.substring(0, len), name.getRawSignature()); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java index 1489c8241c8..726808116df 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java @@ -1721,4 +1721,29 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa assertEquals("T", ct.getTemplateParameters()[0].getName()); } + // template class X {}; + // template class Y {}; + // template<> class Y {}; + // template void f(T t) {} + // template void g(T t) {} + // template<> void g(int t) {} + + // void test() { + // X x; + // Y y; + // f(1); + // g(1); + // } + public void testExplicitSpecializations_296427() throws Exception { + ICPPTemplateInstance inst; + inst= getBindingFromASTName("X", 0); + assertFalse(inst.isExplicitSpecialization()); + inst = getBindingFromASTName("Y", 0); + assertTrue(inst.isExplicitSpecialization()); + + inst = getBindingFromASTName("f(1)", 1); + assertFalse(inst.isExplicitSpecialization()); + inst = getBindingFromASTName("g(1)", 1); + assertTrue(inst.isExplicitSpecialization()); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateInstance.java index d048f6be766..2ea5efd0cd4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateInstance.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2009 IBM Corporation and others. + * Copyright (c) 2005, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * IBM - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.core.dom.ast.cpp; @@ -42,7 +43,14 @@ public interface ICPPTemplateInstance extends ICPPSpecialization { public ICPPTemplateArgument[] getTemplateArguments(); /** - * @deprecated use {@link #getTemplateArguments()}, instead. + * Explicit specializations are modeled as instances of a template. + * Returns true if this binding is an explicit specialization. + * @since 5.2 + */ + public boolean isExplicitSpecialization(); + + /** + * @deprecated Replaced by {@link #getTemplateArguments()}. */ @Deprecated public IType[] getArguments(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java index 24042721dd2..9c4549166db 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2009 IBM Corporation and others. + * Copyright (c) 2005, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -15,6 +15,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; +import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IType; @@ -45,6 +46,14 @@ public class CPPClassInstance extends CPPClassSpecialization implements ICPPTemp return arguments; } + public boolean isExplicitSpecialization() { + try { + return !(getCompositeScope() instanceof ICPPClassSpecializationScope); + } catch (DOMException e) { + return false; + } + } + @Deprecated public IType[] getArguments() { return CPPTemplates.getArguments(getTemplateArguments()); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java index a5bb3c89423..7a420c80655 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java @@ -62,6 +62,10 @@ public class CPPDeferredClassInstance extends CPPUnknownClass implements ICPPDef return (ICPPClassTemplate) getSpecializedBinding(); } + public boolean isExplicitSpecialization() { + return false; + } + @Override public CPPDeferredClassInstance clone() { CPPDeferredClassInstance cloned= (CPPDeferredClassInstance) super.clone(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java index 1b84257783a..4dbb545a3b2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2009 IBM Corporation and others. + * Copyright (c) 2005, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; @@ -47,6 +48,19 @@ public class CPPFunctionInstance extends CPPFunctionSpecialization implements IC return fArguments; } + public boolean isExplicitSpecialization() { + if (getDefinition() != null) + return true; + IASTNode[] decls = getDeclarations(); + if (decls != null) { + for (IASTNode decl : decls) { + if (decl != null) + return true; + } + } + return false; + } + /* (non-Javadoc) * For debug purposes only */ 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 96e4c3e7433..07228934332 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 @@ -129,7 +129,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClass; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalTemplateDeclaration; -import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; @@ -1279,16 +1278,11 @@ public class CPPTemplates { if (j++ == missingTemplateDecls) { IBinding b= n.resolveBinding(); if (b instanceof ICPPTemplateInstance && b instanceof ICPPClassType) { - try { - IScope s= ((ICPPClassType) b).getCompositeScope(); - if (!(s instanceof ICPPClassSpecializationScope)) { - // template-id of an explicit specialization. - // here we don't have a template declaration. (see 14.7.3.5) - missingTemplateDecls++; - lastIsTemplate= true; - } - } catch (DOMException e) { - // assume that it is not an explicit instance + if (((ICPPTemplateInstance) b).isExplicitSpecialization()) { + // For a template-id of an explicit specialization. + // we don't have a template declaration. (see 14.7.3.5) + missingTemplateDecls++; + lastIsTemplate= true; } } break; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassInstance.java index 18e81719619..4085f7d9ebf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassInstance.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Symbian Software Systems and others. + * Copyright (c) 2007, 2010 Symbian Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -37,6 +37,10 @@ public class CompositeCPPClassInstance extends CompositeCPPClassSpecialization i public ICPPTemplateParameterMap getTemplateParameterMap() { return TemplateInstanceUtil.getTemplateParameterMap(cf, (ICPPTemplateInstance) rbinding); } + + public boolean isExplicitSpecialization() { + return ((ICPPTemplateInstance) rbinding).isExplicitSpecialization(); + } @Deprecated public IType[] getArguments() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPDeferredClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPDeferredClassInstance.java index 3b57f356c54..856c4de85ce 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPDeferredClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPDeferredClassInstance.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Symbian Software Systems and others. + * Copyright (c) 2007, 2010 Symbian Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -76,6 +76,10 @@ public class CompositeCPPDeferredClassInstance extends CompositeCPPClassType imp return TemplateInstanceUtil.getTemplateArguments(cf, (ICPPTemplateInstance) rbinding); } + public boolean isExplicitSpecialization() { + return false; + } + @Deprecated public IType[] getArguments() { return TemplateInstanceUtil.getArguments(cf, (ICPPTemplateInstance) rbinding); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunctionInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunctionInstance.java index 1d5edbca6b1..5ec99e09551 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunctionInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFunctionInstance.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Symbian Software Systems and others. + * Copyright (c) 2007, 2010 Symbian Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -43,6 +43,10 @@ public class CompositeCPPFunctionInstance extends CompositeCPPFunction implement return TemplateInstanceUtil.getTemplateParameterMap(cf, (ICPPTemplateInstance) rbinding); } + public boolean isExplicitSpecialization() { + return ((ICPPTemplateInstance) rbinding).isExplicitSpecialization(); + } + @Deprecated public IType[] getArguments() { return TemplateInstanceUtil.getArguments(cf, (ICPPTemplateInstance) rbinding); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassInstance.java index dc89417c4cf..b2b61df7471 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassInstance.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 QNX Software Systems and others. + * Copyright (c) 2007, 2010 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -20,6 +20,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassInstance; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; @@ -76,6 +77,10 @@ class PDOMCPPClassInstance extends PDOMCPPClassSpecialization implements ICPPTem } } + public boolean isExplicitSpecialization() { + return !(getCompositeScope() instanceof ICPPClassSpecializationScope); + } + @Override public boolean isSameType(IType type) { if (type instanceof ITypedef) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPDeferredClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPDeferredClassInstance.java index 14b1992f095..e6fc9322bd1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPDeferredClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPDeferredClassInstance.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 QNX Software Systems and others. + * Copyright (c) 2007, 2010 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -80,6 +80,10 @@ class PDOMCPPDeferredClassInstance extends PDOMCPPSpecialization implements ICPP public int getNodeType() { return IIndexCPPBindingConstants.CPP_DEFERRED_CLASS_INSTANCE; } + + public boolean isExplicitSpecialization() { + return false; + } public IScope getCompositeScope() throws DOMException { return asScope(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionInstance.java index 0bc0af0f677..a6f14b6baa5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionInstance.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 QNX Software Systems and others. + * Copyright (c) 2007, 2010 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -70,11 +70,18 @@ class PDOMCPPFunctionInstance extends PDOMCPPFunctionSpecialization implements I return IIndexCPPBindingConstants.CPP_FUNCTION_INSTANCE; } - public ICPPTemplateDefinition getTemplateDefinition() { return (ICPPTemplateDefinition) getSpecializedBinding(); } + public boolean isExplicitSpecialization() { + try { + return hasDefinition(); + } catch (CoreException e) { + return false; + } + } + public ICPPTemplateArgument[] getTemplateArguments() { try { final long rec= getPDOM().getDB().getRecPtr(record+ARGUMENTS);