diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2VariableTemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2VariableTemplateTests.java new file mode 100644 index 00000000000..501724c877d --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2VariableTemplateTests.java @@ -0,0 +1,315 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.parser.tests.ast2; + +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFieldTemplate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPPartialSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableInstance; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate; +import org.eclipse.cdt.core.parser.ParserLanguage; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFieldTemplateSpecialization; + +import junit.framework.TestSuite; + +public class AST2VariableTemplateTests extends AST2TestBase { + + public static TestSuite suite() { + return suite(AST2VariableTemplateTests.class); + } + + // template constexpr T pi = T(3); + public void testVariableTemplate() throws Exception { + parseAndCheckBindings(); + + BindingAssertionHelper ah = getAssertionHelper(ParserLanguage.CPP); + + ICPPVariableTemplate pi = ah.assertNonProblem("pi", ICPPVariableTemplate.class); + assertFalse(pi.isMutable()); + assertFalse(pi.isStatic()); + } + + // struct S { + // template static constexpr T pi = T(3); + // }; + public void testFieldTemplate() throws Exception { + parseAndCheckBindings(); + + BindingAssertionHelper ah = getAssertionHelper(ParserLanguage.CPP); + + ICPPFieldTemplate pi = ah.assertNonProblem("pi", ICPPFieldTemplate.class); + assertTrue(pi.isStatic()); + assertFalse(pi.isMutable()); + assertEquals(ICPPASTVisibilityLabel.v_public, pi.getVisibility()); + } + + // template const T c; + // template const T c = T{}; + public void testVariableTemplateDeclaration() throws Exception { + parseAndCheckBindings(); + + BindingAssertionHelper ah = getAssertionHelper(ParserLanguage.CPP); + + ICPPVariableTemplate decl = ah.assertNonProblem("c;", "c", ICPPVariableTemplate.class); + ICPPVariableTemplate def = ah.assertNonProblem("c =", "c", ICPPVariableTemplate.class); + + assertEquals(decl, def); + } + + // struct S{ + // template static const T c; + // }; + // template const T S::c = T{}; + public void testFieldTemplateDeclaration() throws Exception { + parseAndCheckBindings(); + + BindingAssertionHelper ah = getAssertionHelper(ParserLanguage.CPP); + + ICPPFieldTemplate decl = ah.assertNonProblem("c;", "c", ICPPFieldTemplate.class); + ICPPFieldTemplate def = ah.assertNonProblem("c =", "c", ICPPFieldTemplate.class); + + assertEquals(decl, def); + } + + // template constexpr T pi = T(3); + // + // int foo() { return pi/*1*/; } + // int bar() { return pi/*2*/; } + public void testVariableTemplateUse() throws Exception { + parseAndCheckBindings(); + + BindingAssertionHelper ah = getAssertionHelper(ParserLanguage.CPP); + + ICPPVariableTemplate template = ah.assertNonProblem("pi/*1*/;", "pi", ICPPVariableTemplate.class); + ICPPVariableInstance inst1 = ah.assertNonProblem("pi/*1*/;", "pi", ICPPVariableInstance.class); + ICPPVariableInstance inst2 = ah.assertNonProblem("pi/*2*/;", "pi", ICPPVariableInstance.class); + + assertEquals("3", inst1.getInitialValue().toString()); + assertEquals(template, inst1.getSpecializedBinding()); + assertEquals(template, inst2.getSpecializedBinding()); + assertEquals(inst1, inst2); + } + + // struct S { + // template static constexpr T pi = T(3); + // }; + // + // int foo() { return S::pi; } + public void testFieldTemplateUse() throws Exception { + parseAndCheckBindings(); + + BindingAssertionHelper ah = getAssertionHelper(ParserLanguage.CPP); + + ICPPFieldTemplate template = ah.assertNonProblem("pi", "pi", ICPPFieldTemplate.class); + ICPPVariableInstance inst = ah.assertNonProblem("pi", "pi", + ICPPVariableInstance.class, ICPPField.class); + + assertEquals("3", inst.getInitialValue().toString()); + assertEquals(template, inst.getSpecializedBinding()); + } + + // template constexpr T pi = T(3); + // template<> constexpr float pi = 4; + // + // float f(){ return pi; } + public void testVariableTemplateSpecialization() throws Exception { + parseAndCheckBindings(); + + BindingAssertionHelper ah = getAssertionHelper(ParserLanguage.CPP); + + ICPPVariableTemplate template = ah.assertNonProblem("pi =", "pi", ICPPVariableTemplate.class); + ICPPVariableInstance inst = ah.assertNonProblem("pi =", "pi", ICPPVariableInstance.class); + ICPPVariableInstance ref = ah.assertNonProblem("pi;", "pi", ICPPVariableInstance.class); + + assertEquals("4", inst.getInitialValue().toString()); + assertEquals("4", ref.getInitialValue().toString()); + assertEquals(template, inst.getSpecializedBinding()); + assertEquals(template, ref.getSpecializedBinding()); + assertEquals(inst, ref); + } + + // struct S { + // template static constexpr T pi = T(3); + // }; + // template<> constexpr int S::pi = 4; + // + // float f(){ return S::pi; } + public void testFieldTemplateSpecialization() throws Exception { + parseAndCheckBindings(); + + BindingAssertionHelper ah = getAssertionHelper(ParserLanguage.CPP); + + ICPPFieldTemplate template = ah.assertNonProblem("pi", "pi", ICPPFieldTemplate.class); + ICPPVariableInstance inst = ah.assertNonProblem("pi = ", "pi", + ICPPVariableInstance.class, ICPPField.class); + ICPPVariableInstance ref = ah.assertNonProblem("pi;", "pi", ICPPVariableInstance.class); + + assertEquals("4", inst.getInitialValue().toString()); + assertEquals("4", ref.getInitialValue().toString()); + assertEquals(template, inst.getSpecializedBinding()); + assertEquals(template, ref.getSpecializedBinding()); + assertEquals(inst, ref); + } + + // template T c = T(I); + // template float c = float(I+1); + // float f() { return c; } + public void testVariableTemplatePartialSpecialization() throws Exception { + parseAndCheckBindings(); + + BindingAssertionHelper ah = getAssertionHelper(ParserLanguage.CPP); + + ICPPVariableTemplate template = ah.assertNonProblem("c", "c", ICPPVariableTemplate.class); + ICPPPartialSpecialization spec = ah.assertNonProblem("c", ICPPVariableTemplate.class, + ICPPPartialSpecialization.class); + ICPPVariableInstance inst = ah.assertNonProblem("c", ICPPVariableInstance.class); + + assertEquals("101", inst.getInitialValue().toString()); + assertEquals(template, spec.getPrimaryTemplate()); + assertEquals(spec, inst.getSpecializedBinding()); + } + + // struct S { + // template static constexpr T c = T(I); + // }; + // template constexpr float S::c = float(I+1); + // float f() { return S::c; } + public void testFieldTemplatePartialSpecialization() throws Exception { + parseAndCheckBindings(); + + BindingAssertionHelper ah = getAssertionHelper(ParserLanguage.CPP); + + ICPPFieldTemplate template = ah.assertNonProblem("c", "c", ICPPFieldTemplate.class); + ICPPPartialSpecialization spec = ah.assertNonProblem("c", ICPPFieldTemplate.class, + ICPPPartialSpecialization.class); + ICPPVariableInstance inst = ah.assertNonProblem("c", ICPPVariableInstance.class, ICPPField.class); + + assertEquals("101", inst.getInitialValue().toString()); + assertEquals(template, spec.getPrimaryTemplate()); + assertEquals(spec, inst.getSpecializedBinding()); + } + + // template constexpr T pi = T(3); + // template constexpr int pi; + // + // int f(){ return pi; } + public void testVariableTemplateInstantiation() throws Exception { + parseAndCheckBindings(); + + BindingAssertionHelper ah = getAssertionHelper(ParserLanguage.CPP); + + ICPPVariableTemplate template = ah.assertNonProblem("T pi", "pi"); + ICPPVariableTemplate instTemplate = ah.assertNonProblem("int pi", "pi", ICPPVariableTemplate.class); + ICPPVariableInstance inst = ah.assertNonProblem("int pi", "pi", ICPPVariableInstance.class); + ICPPVariableInstance use = ah.assertNonProblem("return pi", "pi", ICPPVariableInstance.class); + + assertEquals("3", use.getInitialValue().toString()); + assertEquals(template, instTemplate); + assertEquals(template, inst.getSpecializedBinding()); + assertEquals(template, use.getSpecializedBinding()); + assertEquals(inst, use); + } + + // struct S { + // template static constexpr T pi = T(3); + // }; + // template constexpr double S::pi; + // + // double f(){ return S::pi; } + public void testFieldTemplateInstantiation() throws Exception { + parseAndCheckBindings(); + + BindingAssertionHelper ah = getAssertionHelper(ParserLanguage.CPP); + + ICPPFieldTemplate template = ah.assertNonProblem("T pi", "pi"); + ICPPFieldTemplate instTemplate = ah.assertNonProblem("double S::pi", "pi", ICPPFieldTemplate.class); + ICPPVariableInstance inst = ah.assertNonProblem("double S::pi", "pi", + ICPPVariableInstance.class); + ICPPVariableInstance use = ah.assertNonProblem("return S::pi", "pi", + ICPPVariableInstance.class); + + assertEquals("3", use.getInitialValue().toString()); + assertEquals(template, instTemplate); + assertEquals(inst, use); + assertEquals(template, inst.getSpecializedBinding()); + assertEquals(template, use.getSpecializedBinding()); + } + + // template class C, typename T> constexpr C once = C{ T{} }; + // + // template struct Vec{ T t; }; + // + // void f(){ once; } + public void testVariableTemplateWithTemplateTemplateParameter() throws Exception { + parseAndCheckBindings(); + + BindingAssertionHelper ah = getAssertionHelper(ParserLanguage.CPP); + + ICPPVariableTemplate template = ah.assertNonProblem("once = ", "once"); + ICPPVariableInstance use = ah.assertNonProblem("once"); + + assertEquals(template, use.getSpecializedBinding()); + assertEquals("const Vec", use.getType().toString()); + } + + // template class C> + // struct S { + // template static constexpr C once = C{ T{} }; + // }; + // + // template struct Vec{ T t; }; + // + // void f(){ S::once; } + public void testFieldTemplateInTemplate() throws Exception { + parseAndCheckBindings(); + + BindingAssertionHelper ah = getAssertionHelper(ParserLanguage.CPP); + + ICPPFieldTemplate template = ah.assertNonProblem("once = ", "once", + ICPPField.class, ICPPTemplateDefinition.class); + CPPFieldTemplateSpecialization useName = ah.assertNonProblem("S::once", "once"); + ICPPVariableInstance useId = ah.assertNonProblem("S::once", ICPPField.class); + + assertEquals(useName, useId.getSpecializedBinding()); + assertEquals("const Vec", useId.getType().toString()); + } + + // template constexpr int Size = sizeof...(T); + // + // void f() { + // auto a = Size<>; + // auto b = Size; + // } + public void testVariableTemplatePack() throws Exception { + parseAndCheckBindings(); + + BindingAssertionHelper ah = getAssertionHelper(ParserLanguage.CPP); + + ICPPVariableTemplate template = ah.assertNonProblem("int Size", "Size"); + ICPPVariableTemplate aInstTemplate = ah.assertNonProblem("a = Size", "Size"); + ICPPVariableInstance aInst = ah.assertNonProblem("Size<>"); + ICPPVariableTemplate bInstTemplate = ah.assertNonProblem("b = Size", "Size"); + ICPPVariableInstance bInst = ah.assertNonProblem("Size"); + + assertEquals(template, aInstTemplate); + assertEquals(template, bInstTemplate); + assertEquals(template, aInst.getSpecializedBinding()); + assertEquals(template, bInst.getSpecializedBinding()); + } + + private IASTTranslationUnit parseAndCheckBindings() throws Exception { + return parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP); + } +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java index 845568d5f07..36694917a1b 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java @@ -59,6 +59,7 @@ public class DOMParserTestSuite extends TestCase { suite.addTest(AccessControlTests.suite()); suite.addTest(VariableReadWriteFlagsTest.suite()); suite.addTest(AST2CPPAttributeTests.suite()); + suite.addTest(AST2VariableTemplateTests.suite()); return suite; } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPVariableTemplateResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPVariableTemplateResolutionTest.java new file mode 100644 index 00000000000..36b3cf563fc --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPVariableTemplateResolutionTest.java @@ -0,0 +1,200 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.index.tests; + +import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFieldTemplate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableInstance; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplatePartialSpecialization; +import org.eclipse.cdt.core.index.IIndexBinding; + +import junit.framework.TestSuite; + +public class IndexCPPVariableTemplateResolutionTest extends IndexBindingResolutionTestBase { + + public static class SingleProject extends IndexCPPVariableTemplateResolutionTest { + public SingleProject() { + setStrategy(new SinglePDOMTestStrategy(true)); + } + + public static TestSuite suite() { + return suite(SingleProject.class); + } + } + + public static class ProjectWithDepProj extends IndexCPPVariableTemplateResolutionTest { + public ProjectWithDepProj() { + setStrategy(new ReferencedProject(true)); + } + + public static TestSuite suite() { + return suite(ProjectWithDepProj.class); + } + } + + public static void addTests(TestSuite suite) { + suite.addTest(SingleProject.suite()); + suite.addTest(ProjectWithDepProj.suite()); + } + + public IndexCPPVariableTemplateResolutionTest() { + setStrategy(new ReferencedProject(true)); + } + + // template constexpr T pi = T(3); + + // int f(){ return pi; }; + public void testVariableTemplateReference() { + checkBindings(); + ICPPVariableTemplate pi = getBindingFromASTName("pi", 0); + ICPPVariableInstance piOfInt = getBindingFromASTName("pi", 0); + + assertEquals(pi, piOfInt.getSpecializedBinding()); + } + + // struct S { + // template static constexpr T pi = T(3); + // }; + + // int f(){ return S::pi; }; + public void testFieldTemplateReference() { + checkBindings(); + ICPPFieldTemplate pi = getBindingFromASTName("pi", 0); + ICPPVariableInstance piOfInt = getBindingFromASTName("pi", 0); + + assertEquals(pi, piOfInt.getSpecializedBinding()); + } + + // template constexpr T pi = T(3); + // template constexpr int pi; + + // int f(){ return pi; } + public void testExplicitVariableInstance() { + checkBindings(); + ICPPVariableTemplate pi = getBindingFromASTName("pi", 0); + ICPPVariableInstance piOfInt = + getBindingFromASTName("pi", 0, ICPPVariableInstance.class, IIndexBinding.class); + + assertEquals(pi, piOfInt.getSpecializedBinding()); + } + + // struct S { + // template static constexpr T pi = T(3); + // }; + // template constexpr double S::pi; + + // double f(){ return S::pi; } + public void testExplicitFieldInstance() { + checkBindings(); + ICPPFieldTemplate pi = getBindingFromASTName("pi", 0); + ICPPVariableInstance piOfDouble = getBindingFromASTName("pi", 0, + ICPPVariableInstance.class, ICPPField.class, IIndexBinding.class); + + assertEquals(pi, piOfDouble.getSpecializedBinding()); + } + + // template constexpr T pi = T(3); + // template<> constexpr int pi = 4; + + // int f(){ return pi; } + public void testVariableSpecialization() { + checkBindings(); + ICPPVariableTemplate pi = getBindingFromASTName("pi", 0); + ICPPVariableInstance piOfInt = + getBindingFromASTName("pi", 0, ICPPVariableInstance.class, IIndexBinding.class); + + assertEquals(pi, piOfInt.getSpecializedBinding()); + } + + // struct S { + // template static constexpr T pi = T(3); + // }; + // template<> constexpr double S::pi = 4; + + // double f(){ return S::pi; } + public void testFieldSpecialization() { + checkBindings(); + ICPPFieldTemplate pi = getBindingFromASTName("pi", 0); + ICPPVariableInstance piOfDouble = getBindingFromASTName("pi", 0, + ICPPVariableInstance.class, ICPPField.class, IIndexBinding.class); + + assertEquals(pi, piOfDouble.getSpecializedBinding()); + } + + // struct S { + // template static constexpr T pi = T(3); + // }; + + // template<> constexpr double S::pi = 4; + public void testFieldSpecializationInRef() { + checkBindings(); + ICPPVariableInstance piOfDouble = getBindingFromASTName("pi", 0, + ICPPVariableInstance.class, ICPPField.class); + } + + // template T c = T(I); + // template float c = float(I); + + // float f() { return c; } + public void testVariableTemplatePartialSpecialization() { + checkBindings(); + ICPPVariableTemplate c = getBindingFromASTName("c", 0); + + ICPPVariableInstance cOfFloat = getBindingFromASTName("c", 0, + ICPPVariableInstance.class); + + assertInstance(cOfFloat.getSpecializedBinding(), + ICPPVariableTemplatePartialSpecialization.class, IIndexBinding.class); + + assertEquals(c, + ((ICPPVariableTemplatePartialSpecialization) cOfFloat.getSpecializedBinding()).getPrimaryTemplate()); + } + + // template T c = T(1); + // template T* c = T(10); + + // float f() { return c; } + public void testVariableTemplatePartialSpecialization2() { + checkBindings(); + ICPPVariableTemplate c = getBindingFromASTName("c", 0); + + ICPPVariableInstance cOfIntPtr = getBindingFromASTName("c", 0, + ICPPVariableInstance.class); + + assertInstance(cOfIntPtr.getSpecializedBinding(), + ICPPVariableTemplatePartialSpecialization.class, IIndexBinding.class); + + assertEquals(c, + ((ICPPVariableTemplatePartialSpecialization) cOfIntPtr.getSpecializedBinding()).getPrimaryTemplate()); + } + + // struct S { + // template static constexpr T c = T(I); + // }; + // template constexpr float S::c = float(I); + + // float f() { return S::c; } + public void testFieldTemplatePartialSpecialization() { + checkBindings(); + ICPPVariableTemplate c = getBindingFromASTName("c", 0); + + ICPPVariableInstance cOfIntPtr = getBindingFromASTName("c", 0, + ICPPVariableInstance.class, ICPPField.class); + + assertInstance(cOfIntPtr.getSpecializedBinding(), + ICPPVariableTemplatePartialSpecialization.class, IIndexBinding.class, ICPPField.class); + + assertEquals(c.getClass(), + ((ICPPVariableTemplatePartialSpecialization) cOfIntPtr.getSpecializedBinding()).getPrimaryTemplate().getClass()); + } +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java index 9d70e1b2a4c..ae09b5dc015 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java @@ -41,6 +41,7 @@ public class IndexTests extends TestSuite { IndexCPPTemplateResolutionTest.addTests(suite); IndexCBindingResolutionBugs.addTests(suite); IndexCBindingResolutionTest.addTests(suite); + IndexCPPVariableTemplateResolutionTest.addTests(suite); return suite; } diff --git a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterTemplateTestSource.awts b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterTemplateTestSource.awts index 3bd0783b0c9..494f57bf372 100644 --- a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterTemplateTestSource.awts +++ b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterTemplateTestSource.awts @@ -31,4 +31,37 @@ void f(T t, Args... args) template struct S { static const int size = sizeof...(Args); -}; \ No newline at end of file +}; + +//!Variable Template +//%CPP +template constexpr T c = T{100}; + +int f() +{ + return c; +} + +//!Field Template +//%CPP +struct S +{ + template static constexpr T c = T{100}; +}; + +int f() +{ + return S::c; +} + +//!Field Template in Template +//%CPP +template struct S +{ + template static constexpr T c = T{I}; +}; + +int f() +{ + return S::template c<100>; +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplate.java index db028ce07d9..5a80e511da4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplate.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2014 IBM Corporation and others. + * Copyright (c) 2005, 2015 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,14 +15,15 @@ package org.eclipse.cdt.core.dom.ast.cpp; * @noextend This interface is not intended to be extended by clients. * @noimplement This interface is not intended to be implemented by clients. */ -public interface ICPPClassTemplate extends ICPPTemplateDefinition, ICPPClassType { +public interface ICPPClassTemplate extends ICPPClassType, ICPPPartiallySpecializable { /** * Returns the partial specializations of this class template. */ + @Override public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations(); - + /** - * Returns a deferred instance that allows lookups within this class template. + * Returns a deferred instance that allows lookups within this class template. * @since 5.1 */ public ICPPTemplateInstance asDeferredInstance(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplatePartialSpecialization.java index 252e13f0248..a78a75a5a62 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplatePartialSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplatePartialSpecialization.java @@ -25,7 +25,7 @@ import org.eclipse.cdt.core.dom.ast.IType; * @noextend This interface is not intended to be extended by clients. * @noimplement This interface is not intended to be implemented by clients. */ -public interface ICPPClassTemplatePartialSpecialization extends ICPPClassTemplate { +public interface ICPPClassTemplatePartialSpecialization extends ICPPClassTemplate, ICPPPartialSpecialization { /** @since 5.12 */ public static final ICPPClassTemplatePartialSpecialization[] EMPTY_ARRAY = {}; /** @deprecated Use {@link #EMPTY_ARRAY} */ @@ -41,8 +41,9 @@ public interface ICPPClassTemplatePartialSpecialization extends ICPPClassTemplat * Returns the arguments of this partial specialization. * @since 5.1 */ + @Override public ICPPTemplateArgument[] getTemplateArguments(); - + /** * @deprecated use {@link #getTemplateArguments()}, instead. */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFieldTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFieldTemplate.java new file mode 100644 index 00000000000..a3589783636 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFieldTemplate.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.dom.ast.cpp; + +/** + * A field template. + * + * @since 5.12 + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ICPPFieldTemplate extends ICPPVariableTemplate, ICPPField { +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPPartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPPartialSpecialization.java new file mode 100644 index 00000000000..e7949dd7875 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPPartialSpecialization.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.dom.ast.cpp; + +/** + * A partially specialized variable or class template. + * + * @since 5.12 + */ +public interface ICPPPartialSpecialization extends ICPPTemplateDefinition { + public static final ICPPPartialSpecialization[] EMPTY_ARRAY = {}; + + /** + * Returns the ICPPTemplateDefinition which this is a specialization of. + */ + public ICPPTemplateDefinition getPrimaryTemplate(); + + /** + * Returns the arguments of this partial specialization. + */ + public ICPPTemplateArgument[] getTemplateArguments(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPPartiallySpecializable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPPartiallySpecializable.java new file mode 100644 index 00000000000..0855e5f7e1a --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPPartiallySpecializable.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.dom.ast.cpp; + +/** + * Something that can be partially specialized. Hence, a class or a variable template + * but not a function template. + * + * @since 5.12 + */ +public interface ICPPPartiallySpecializable extends ICPPTemplateDefinition { + /** + * Returns the partial specializations of this template. + */ + public ICPPPartialSpecialization[] getPartialSpecializations(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateTemplateParameter.java index 241e09944c4..49349b715ac 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateTemplateParameter.java @@ -35,4 +35,7 @@ public interface ICPPTemplateTemplateParameter extends ICPPTemplateParameter, IC */ @Override public boolean isSameType(IType type); + + @Override + public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPVariableInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPVariableInstance.java new file mode 100644 index 00000000000..da972cf7346 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPVariableInstance.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.dom.ast.cpp; + +/** + * Represents an instantiation or an explicit specialization of a variable template. + * + * @since 5.12 + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ICPPVariableInstance extends ICPPTemplateInstance, ICPPVariable { +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPVariableTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPVariableTemplate.java new file mode 100644 index 00000000000..2e5126bca2e --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPVariableTemplate.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.dom.ast.cpp; + +/** + * A variable template. + * + * @since 5.12 + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ICPPVariableTemplate extends ICPPVariable, ICPPPartiallySpecializable { +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPVariableTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPVariableTemplatePartialSpecialization.java new file mode 100644 index 00000000000..9767239c4bf --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPVariableTemplatePartialSpecialization.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.dom.ast.cpp; + +/** + * Partial specialization of a variable template. + * + * @since 5.12 + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ICPPVariableTemplatePartialSpecialization + extends ICPPVariableTemplate, ICPPPartialSpecialization { +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java index f1dfcd57eb9..9aa0d08adf7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2014 IBM Corporation and others. + * Copyright (c) 2005, 2015 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 @@ -20,13 +20,14 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; /** * A partial class template specialization. */ -public class CPPClassTemplatePartialSpecialization extends CPPClassTemplate +public class CPPClassTemplatePartialSpecialization extends CPPClassTemplate implements ICPPClassTemplatePartialSpecialization { private final ICPPTemplateArgument[] arguments; @@ -83,10 +84,15 @@ public class CPPClassTemplatePartialSpecialization extends CPPClassTemplate public String toString() { return super.toString() + ASTTypeUtil.getArgumentListString(getTemplateArguments(), true); } - + @Override @Deprecated public IType[] getArguments() throws DOMException { return CPPTemplates.getArguments(getTemplateArguments()); } + + @Override + public ICPPTemplateDefinition getPrimaryTemplate() { + return getPrimaryClassTemplate(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecializationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecializationSpecialization.java index adc644afe64..ed8486d4a4e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecializationSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecializationSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2014 Wind River Systems, Inc. and others. + * Copyright (c) 2009, 2015 Wind River Systems, Inc. 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 @@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecializationSpecialization; 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.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; @@ -82,7 +83,7 @@ public class CPPClassTemplatePartialSpecializationSpecialization extends CPPClas public IBinding resolveTemplateParameter(ICPPTemplateParameter param) { return param; } - + @Override public ICPPDeferredClassInstance asDeferredInstance() { if (fDeferredInstance == null) { @@ -109,7 +110,7 @@ public class CPPClassTemplatePartialSpecializationSpecialization extends CPPClas public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() { return ICPPClassTemplatePartialSpecialization.EMPTY_ARRAY; } - + @Override public boolean isSameType(IType type) { if (type == this) @@ -127,22 +128,27 @@ public class CPPClassTemplatePartialSpecializationSpecialization extends CPPClas public String toString() { return super.toString() + ASTTypeUtil.getArgumentListString(getTemplateArguments(), true); } - + @Override @Deprecated public ObjectMap getArgumentMap() { return CPPTemplates.getArgumentMap(getPrimaryClassTemplate(), getTemplateParameterMap()); } - + @Override @Deprecated public IType[] getArguments() throws DOMException { return CPPTemplates.getArguments(getTemplateArguments()); } - + @Override public ICPPTemplateArgument getDefaultArgFromIndex(int paramPos) throws DOMException { // No default arguments for partial specializations return null; } + + @Override + public ICPPTemplateDefinition getPrimaryTemplate() { + return getPrimaryClassTemplate(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPField.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPField.java index fba3b77d26e..640b6956b4b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPField.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPField.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2012 IBM Corporation and others. + * Copyright (c) 2004, 2015 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 @@ -11,22 +11,14 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; -import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; -import org.eclipse.cdt.core.dom.ast.IASTDeclaration; -import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.ICompositeType; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; -import org.eclipse.cdt.core.parser.util.CharArrayUtils; -import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; /** @@ -56,91 +48,25 @@ public class CPPField extends CPPVariable implements ICPPField { return getClassOwner(); } } - + public CPPField(IASTName name) { super(name); } - public IASTDeclaration getPrimaryDeclaration() { - // First check if we already know it - IASTDeclaration decl= findDeclaration(getDefinition()); - if (decl != null) { - return decl; - } - - IASTName[] declarations = (IASTName[]) getDeclarations(); - if (declarations != null) { - for (IASTName name : declarations) { - decl= findDeclaration(name); - if (decl != null) { - return decl; - } - } - } - - char[] myName = getNameCharArray(); - - ICPPClassScope scope = (ICPPClassScope) getScope(); - ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) ASTInternal.getPhysicalNodeOfScope(scope); - IASTDeclaration[] members = compSpec.getMembers(); - for (IASTDeclaration member : members) { - if (member instanceof IASTSimpleDeclaration) { - IASTDeclarator[] dtors = ((IASTSimpleDeclaration) member).getDeclarators(); - for (IASTDeclarator dtor : dtors) { - IASTName name = dtor.getName(); - if (CharArrayUtils.equals(name.getLookupKey(), myName) && name.resolveBinding() == this) { - return member; - } - } - } - } - return null; - } - - private IASTDeclaration findDeclaration(IASTNode node) { - while (node != null && !(node instanceof IASTDeclaration)) { - node = node.getParent(); - } - if (node != null && node.getParent() instanceof ICPPASTCompositeTypeSpecifier) { - return (IASTDeclaration) node; - } - return null; - } - @Override public int getVisibility() { - ICPPASTVisibilityLabel vis = null; - IASTDeclaration decl = getPrimaryDeclaration(); - if (decl != null) { - IASTCompositeTypeSpecifier cls = (IASTCompositeTypeSpecifier) decl.getParent(); - IASTDeclaration[] members = cls.getMembers(); - - for (IASTDeclaration member : members) { - if (member instanceof ICPPASTVisibilityLabel) { - vis = (ICPPASTVisibilityLabel) member; - } else if (member == decl) { - break; - } - } - - if (vis != null) { - return vis.getVisibility(); - } else if (cls.getKey() == ICPPASTCompositeTypeSpecifier.k_class) { - return ICPPASTVisibilityLabel.v_private; - } - } - return ICPPASTVisibilityLabel.v_public; + return VariableHelpers.getVisibility(this); } - + @Override public ICPPClassType getClassOwner() { ICPPClassScope scope = (ICPPClassScope) getScope(); return scope.getClassType(); } - + @Override public boolean isStatic() { - // definition of a static field doesn't necessarily say static + // Definition of a static field doesn't necessarily say static. if (getDeclarations() == null) { IASTNode def= getDefinition(); if (def instanceof ICPPASTQualifiedName) { @@ -149,18 +75,18 @@ public class CPPField extends CPPVariable implements ICPPField { } return super.isStatic(); } - + @Override public boolean isMutable() { return hasStorageClass(IASTDeclSpecifier.sc_mutable); } - + @Override public boolean isExtern() { - //7.1.1-5 The extern specifier can not be used in the declaration of class members + // 7.1.1-5 The extern specifier can not be used in the declaration of class members. return false; } - + @Override public ICompositeType getCompositeTypeOwner() { return getClassOwner(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldInstance.java new file mode 100644 index 00000000000..6b32bb47d52 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldInstance.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFieldTemplate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; + +/** + * An instance of a field template. + */ +public class CPPFieldInstance extends CPPVariableInstance implements ICPPField { + + public CPPFieldInstance(IBinding specialized, IBinding owner, ICPPTemplateParameterMap argumentMap, + ICPPTemplateArgument[] args, IType tpe, IValue value) { + super(specialized, owner, argumentMap, args, tpe, value); + } + + @Override + public ICompositeType getCompositeTypeOwner() { + return getClassOwner(); + } + + @Override + public int getVisibility() { + return ((ICPPFieldTemplate) getSpecializedBinding()).getVisibility(); + } + + @Override + public ICPPClassType getClassOwner() { + try { + ICPPClassScope scope = (ICPPClassScope) getScope(); + return scope.getClassType(); + } catch (DOMException e) { + return null; + } + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldTemplate.java new file mode 100644 index 00000000000..fe044c517ac --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldTemplate.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFieldTemplate; + +public class CPPFieldTemplate extends CPPVariableTemplate implements ICPPFieldTemplate { + + public CPPFieldTemplate(IASTName name) { + super(name); + } + + @Override + public ICompositeType getCompositeTypeOwner() { + return getClassOwner(); + } + + @Override + public int getVisibility() { + return VariableHelpers.getVisibility(this); + } + + @Override + public ICPPClassType getClassOwner() { + ICPPClassScope scope = (ICPPClassScope) getScope(); + return scope.getClassType(); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldTemplatePartialSpecialization.java new file mode 100644 index 00000000000..5ae00ae160f --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldTemplatePartialSpecialization.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFieldTemplate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; + +/** + * A partial specialization of a field template. + */ +public class CPPFieldTemplatePartialSpecialization extends CPPVariableTemplatePartialSpecialization + implements ICPPFieldTemplate { + + public CPPFieldTemplatePartialSpecialization(IASTName name, ICPPTemplateArgument[] args) { + super(name, args); + } + + @Override + public ICompositeType getCompositeTypeOwner() { + return getClassOwner(); + } + + @Override + public int getVisibility() { + return VariableHelpers.getVisibility(this); + } + + @Override + public ICPPClassType getClassOwner() { + ICPPClassScope scope = (ICPPClassScope) getScope(); + return scope.getClassType(); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldTemplateSpecialization.java new file mode 100644 index 00000000000..697c3bfed9d --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldTemplateSpecialization.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFieldTemplate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPPartialSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; +import org.eclipse.cdt.core.parser.util.ObjectMap; + +/** + * A field template of a specialized class template. + */ +public class CPPFieldTemplateSpecialization extends CPPFieldSpecialization + implements ICPPFieldTemplate, ICPPInternalTemplate { + private ICPPTemplateParameter[] templateParameters; + private ObjectMap instances; + + public CPPFieldTemplateSpecialization(IBinding orig, ICPPClassType owner, ICPPTemplateParameterMap tpmap, + IType type, IValue value) { + super(orig, owner, tpmap, type, value); + } + + @Override + public ICPPPartialSpecialization[] getPartialSpecializations() { + // Partial specializations of field template specializations is not specified + // and I've found no working example on recent compiler implementations + // see also http://wg21.cmeerw.net/cwg/issue1711 + return ICPPPartialSpecialization.EMPTY_ARRAY; + } + + public void setTemplateParameters(ICPPTemplateParameter[] params) { + templateParameters = params; + } + + @Override + public ICPPTemplateParameter[] getTemplateParameters() { + return templateParameters; + } + + @Override + public IBinding resolveTemplateParameter(ICPPTemplateParameter param) { + return param; + } + + @Override + public synchronized final void addInstance(ICPPTemplateArgument[] arguments, ICPPTemplateInstance instance) { + if (instances == null) + instances = new ObjectMap(2); + String key= ASTTypeUtil.getArgumentListString(arguments, true); + instances.put(key, instance); + } + + @Override + public synchronized final ICPPTemplateInstance getInstance(ICPPTemplateArgument[] arguments) { + if (instances != null) { + String key= ASTTypeUtil.getArgumentListString(arguments, true); + return (ICPPTemplateInstance) instances.get(key); + } + return null; + } + + @Override + public ICPPTemplateInstance[] getAllInstances() { + if (instances != null) { + ICPPTemplateInstance[] result= new ICPPTemplateInstance[instances.size()]; + for (int i= 0; i < instances.size(); i++) { + result[i]= (ICPPTemplateInstance) instances.getAt(i); + } + return result; + } + return ICPPTemplateInstance.EMPTY_TEMPLATE_INSTANCE_ARRAY; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java index ce2411e0ce1..bc9bf1c9631 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java @@ -1,12 +1,12 @@ /******************************************************************************* - * Copyright (c) 2004, 2014 IBM Corporation and others. + * Copyright (c) 2004, 2015 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Andrew Niefer (IBM Corporation) - Initial API and implementation + * Andrew Niefer (IBM Corporation) - Initial API and implementation * Markus Schorn (Wind River Systems) * Ed Swartz (Nokia) * Sergey Prigogin (Google) @@ -19,13 +19,8 @@ import java.util.Set; import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; -import org.eclipse.cdt.core.dom.ast.IASTDeclaration; -import org.eclipse.cdt.core.dom.ast.IASTDeclarator; -import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; -import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IScope; @@ -33,21 +28,19 @@ import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.core.runtime.PlatformObject; -public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInternalBinding { +public class CPPVariable extends PlatformObject implements ICPPInternalVariable { private IASTName fDefinition; private IASTName fDeclarations[]; private IType fType; private boolean fAllResolved; - + /** * The set of CPPVariable objects for which initial value computation is in progress on each thread. * This is used to guard against recursion during initial value computation. @@ -56,21 +49,21 @@ public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInt @Override protected Set initialValue() { return new HashSet<>(); - } + } }; - + public CPPVariable(IASTName name) { boolean isDef = name != null && name.isDefinition(); if (name instanceof ICPPASTQualifiedName) { name = name.getLastName(); } - + if (isDef) { fDefinition = name; } else { fDeclarations = new IASTName[] { name }; } - + // Built-in variables supply a null. if (name != null) { name.setBinding(this); @@ -78,22 +71,7 @@ public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInt assert this instanceof CPPBuiltinVariable; } } - - private IASTDeclarator findDeclarator(IASTName name) { - IASTNode node = name.getParent(); - if (node instanceof ICPPASTQualifiedName) - node = node.getParent(); - - if (!(node instanceof IASTDeclarator)) - return null; - - IASTDeclarator dtor = (IASTDeclarator) node; - while (dtor.getParent() instanceof IASTDeclarator) - dtor = (IASTDeclarator) dtor.getParent(); - - return dtor; - } - + @Override public void addDeclaration(IASTNode node) { if (!(node instanceof IASTName)) @@ -117,7 +95,7 @@ public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInt fType = null; } } - + @Override public IASTNode[] getDeclarations() { return fDeclarations; @@ -134,65 +112,13 @@ public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInt return fType; } - boolean doneWithDefinition = false; - IArrayType firstCandidate= null; - final int length = fDeclarations == null ? 0 : fDeclarations.length; - for (int i = 0; i <= length; i++) { - IASTName n; - // Process the definition according to its relative position among the declarations. - // See http://bugs.eclipse.org/434150 - if (fDefinition != null && !doneWithDefinition && - (i == length || ((ASTNode) fDefinition).getOffset() < ((ASTNode) fDeclarations[i]).getOffset())) { - n = fDefinition; - doneWithDefinition = true; - --i; // We still have to come back to the declaration at position i. - } else if (i < length) { - n = fDeclarations[i]; - } else { - break; - } - if (n != null) { - while (n.getParent() instanceof IASTName) - n = (IASTName) n.getParent(); + boolean allResolved = fAllResolved; + fAllResolved = true; + fType = VariableHelpers.createType(this, fDefinition, fDeclarations, allResolved); - IASTNode node = n.getParent(); - if (node instanceof IASTDeclarator) { - IType t= CPPVisitor.createType((IASTDeclarator) node); - if (t instanceof IArrayType && !((IArrayType) t).hasSize()) { - if (firstCandidate == null) { - firstCandidate= (IArrayType) t; - } - } else { - return fType= t; - } - } - } - } - fType= firstCandidate; - if (!fAllResolved) { - resolveAllDeclarations(); - return getType(); - } return fType; } - private void resolveAllDeclarations() { - if (fAllResolved) - return; - fAllResolved= true; - final int length = fDeclarations == null ? 0 : fDeclarations.length; - for (int i = -1; i < length; i++) { - IASTName n = i == -1 ? fDefinition : fDeclarations[i]; - if (n != null) { - IASTTranslationUnit tu = n.getTranslationUnit(); - if (tu != null) { - CPPVisitor.getDeclarations(tu, this); - return; - } - } - } - } - @Override public String getName() { return new String(getNameCharArray()); @@ -202,7 +128,7 @@ public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInt public char[] getNameCharArray() { if (fDeclarations != null) { return fDeclarations[0].getSimpleID(); - } + } return fDefinition.getSimpleID(); } @@ -210,7 +136,7 @@ public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInt public IScope getScope() { return CPPVisitor.getContainingScope(fDefinition != null ? fDefinition : fDeclarations[0]); } - + @Override public String[] getQualifiedName() { return CPPVisitor.getQualifiedName(this); @@ -240,30 +166,10 @@ public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInt public boolean hasStorageClass(int storage) { IASTName name = (IASTName) getDefinition(); IASTNode[] ns = getDeclarations(); - - int i = -1; - do { - if (name != null) { - IASTNode parent = name.getParent(); - while (!(parent instanceof IASTDeclaration)) - parent = parent.getParent(); - - if (parent instanceof IASTSimpleDeclaration) { - IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) parent).getDeclSpecifier(); - if (declSpec.getStorageClass() == storage) { - return true; - } - } - } - if (ns != null && ++i < ns.length) { - name = (IASTName) ns[i]; - } else { - break; - } - } while (name != null); - return false; + + return VariableHelpers.hasStorageClass(name, ns, storage); } - + @Override public boolean isMutable() { // 7.1.1-8 the mutable specifier can only be applied to names of class data members. @@ -282,18 +188,7 @@ public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInt @Override public boolean isExternC() { - if (CPPVisitor.isExternC(getDefinition())) { - return true; - } - IASTNode[] ds= getDeclarations(); - if (ds != null) { - for (IASTNode element : ds) { - if (CPPVisitor.isExternC(element)) { - return true; - } - } - } - return false; + return CPPVisitor.isExternC(getDefinition(), getDeclarations()); } @Override @@ -305,18 +200,18 @@ public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInt public boolean isRegister() { return hasStorageClass(IASTDeclSpecifier.sc_register); } - + @Override public ILinkage getLinkage() { return Linkage.CPP_LINKAGE; } - + @Override public IBinding getOwner() { IASTName node = fDefinition != null ? fDefinition : fDeclarations[0]; - return CPPVisitor.findNameOwner(node, !hasStorageClass(IASTDeclSpecifier.sc_extern)); + return CPPVisitor.findNameOwner(node, !hasStorageClass(IASTDeclSpecifier.sc_extern)); } - + @Override public IValue getInitialValue() { Set recursionProtectionSet = fInitialValueInProgress.get(); @@ -324,35 +219,10 @@ public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInt return Value.UNKNOWN; } try { - if (fDefinition != null) { - final IValue val= getInitialValue(fDefinition); - if (val != null) - return val; - } - if (fDeclarations != null) { - for (IASTName decl : fDeclarations) { - if (decl == null) - break; - final IValue val= getInitialValue(decl); - if (val != null) - return val; - } - } + return VariableHelpers.getInitialValue(fDefinition, fDeclarations, getType()); } finally { recursionProtectionSet.remove(this); } - return null; - } - - private IValue getInitialValue(IASTName name) { - IASTDeclarator dtor= findDeclarator(name); - if (dtor != null) { - IASTInitializer init= dtor.getInitializer(); - if (init != null) { - return SemanticUtil.getValueOfInitializer(init, getType()); - } - } - return null; } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariableInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariableInstance.java new file mode 100644 index 00000000000..f8605731aa5 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariableInstance.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTName; +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.IValue; +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.ICPPTemplateParameterMap; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableInstance; + +/** + * An instance of a variable template. + */ +public class CPPVariableInstance extends CPPSpecialization + implements ICPPVariableInstance, ICPPInternalVariable { + private ICPPTemplateArgument[] templateArguments; + private IType type; + private IValue initialValue; + + public CPPVariableInstance(IBinding specialized, IBinding owner, ICPPTemplateParameterMap argumentMap, + ICPPTemplateArgument[] args, IType tpe, IValue value) { + super(specialized, owner, argumentMap); + templateArguments = args; + type = tpe; + initialValue = value; + } + + @Override + public ICPPTemplateDefinition getTemplateDefinition() { + return (ICPPTemplateDefinition) getSpecializedBinding(); + } + + @Override + public ICPPTemplateArgument[] getTemplateArguments() { + return templateArguments; + } + + @Override + 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; + } + + @Override + public IType[] getArguments() { + return null; + } + + @Override + public boolean isMutable() { + return false; + } + + @Override + public boolean isExternC() { + return false; + } + + @Override + public IType getType() { + return type; + } + + @Override + public IValue getInitialValue() { + return initialValue; + } + + @Override + public boolean isStatic() { + return hasStorageClass(IASTDeclSpecifier.sc_static); + } + + @Override + public boolean isExtern() { + return hasStorageClass(IASTDeclSpecifier.sc_extern); + } + + @Override + public boolean isAuto() { + return hasStorageClass(IASTDeclSpecifier.sc_auto); + } + + @Override + public boolean isRegister() { + return hasStorageClass(IASTDeclSpecifier.sc_register); + } + + public boolean hasStorageClass(int storage) { + IASTName name = (IASTName) getDefinition(); + IASTNode[] ns = getDeclarations(); + + return VariableHelpers.hasStorageClass(name, ns, storage); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariableTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariableTemplate.java new file mode 100644 index 00000000000..9383b7c9416 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariableTemplate.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPPartialSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate; +import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; + +public class CPPVariableTemplate extends CPPTemplateDefinition + implements ICPPVariableTemplate, ICPPInternalVariable { + private IType fType; + private boolean fAllResolved; + private ICPPPartialSpecialization[] partialSpecializations = ICPPPartialSpecialization.EMPTY_ARRAY; + + public CPPVariableTemplate(IASTName name) { + super(name); + } + + @Override + public boolean isMutable() { + return false; + } + + @Override + public boolean isExternC() { + return CPPVisitor.isExternC(getDefinition(), getDeclarations()); + } + + @Override + public IType getType() { + if (fType != null) { + return fType; + } + + boolean allResolved = fAllResolved; + fAllResolved = true; + fType = VariableHelpers.createType(this, definition, declarations, allResolved); + + return fType; + } + + @Override + public IValue getInitialValue() { + return VariableHelpers.getInitialValue((IASTName)getDefinition(), (IASTName[]) getDeclarations(), getType()); + } + + @Override + public boolean isStatic() { + return hasStorageClass(IASTDeclSpecifier.sc_static); + } + + @Override + public boolean isExtern() { + return hasStorageClass(IASTDeclSpecifier.sc_extern); + } + + @Override + public boolean isAuto() { + return hasStorageClass(IASTDeclSpecifier.sc_auto); + } + + @Override + public boolean isRegister() { + return hasStorageClass(IASTDeclSpecifier.sc_register); + } + + public boolean hasStorageClass(int storage) { + IASTName name = (IASTName) getDefinition(); + IASTNode[] ns = getDeclarations(); + + return VariableHelpers.hasStorageClass(name, ns, storage); + } + + @Override + public ICPPPartialSpecialization[] getPartialSpecializations() { + partialSpecializations = ArrayUtil.trim(partialSpecializations); + return partialSpecializations; + } + + public void addPartialSpecialization(ICPPPartialSpecialization partSpec) { + partialSpecializations = ArrayUtil.append(partialSpecializations, partSpec); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariableTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariableTemplatePartialSpecialization.java new file mode 100644 index 00000000000..a9f070a56fc --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariableTemplatePartialSpecialization.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; +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.ICPPVariableTemplate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplatePartialSpecialization; + +/** + * A partial specialization of a variable template. + */ +public class CPPVariableTemplatePartialSpecialization extends CPPVariableTemplate + implements ICPPVariableTemplatePartialSpecialization { + private final ICPPTemplateArgument[] arguments; + + public CPPVariableTemplatePartialSpecialization(IASTName name, ICPPTemplateArgument[] args) { + super(name); + arguments = args; + } + + @Override + public ICPPTemplateDefinition getPrimaryTemplate() { + ICPPASTTemplateId id = (ICPPASTTemplateId) getTemplateName(); + return (ICPPVariableTemplate) id.getTemplateName().resolveBinding(); + } + + @Override + public ICPPTemplateArgument[] getTemplateArguments() { + return arguments; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalVariable.java new file mode 100644 index 00000000000..74de7105120 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalVariable.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; + +public interface ICPPInternalVariable extends ICPPVariable, ICPPInternalBinding { +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/VariableHelpers.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/VariableHelpers.java new file mode 100644 index 00000000000..3dc991784df --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/VariableHelpers.java @@ -0,0 +1,264 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTInitializer; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IArrayType; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; +import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; +import org.eclipse.cdt.internal.core.dom.parser.ASTNode; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; + +/** + * Collects functionality used by CPPVariable, CPPVariableTemplate and their subclasses. + */ +public class VariableHelpers { + public static boolean hasStorageClass(IASTName name, IASTNode[] declarations, int storage) { + int i = -1; + do { + if (name != null) { + IASTNode parent = name.getParent(); + while (!(parent instanceof IASTDeclaration)) + parent = parent.getParent(); + + if (parent instanceof IASTSimpleDeclaration) { + IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) parent).getDeclSpecifier(); + if (declSpec.getStorageClass() == storage) { + return true; + } + } + } + if (declarations != null && ++i < declarations.length) { + name = (IASTName) declarations[i]; + } else { + break; + } + } while (name != null); + return false; + } + + @SuppressWarnings("null") + public static IType createType(ICPPVariable variable, IASTName definition, IASTName[] declarations, + boolean allDeclarationsResolved) { + boolean doneWithDefinition = false; + IArrayType firstCandidate = null; + final int length = declarations == null ? 0 : declarations.length; + for (int i = 0; i <= length; i++) { + IASTName n; + // Process the definition according to its relative position among + // the declarations. + // See http://bugs.eclipse.org/434150 + if (definition != null && !doneWithDefinition + && (i == length + || ((ASTNode) definition).getOffset() < ((ASTNode) declarations[i]).getOffset())) { + n = definition; + doneWithDefinition = true; + --i; // We still have to come back to the declaration at position i. + } else if (i < length) { + n = declarations[i]; + } else { + break; + } + if (n != null) { + while (n.getParent() instanceof IASTName) { + n = (IASTName) n.getParent(); + } + + IASTNode node = n.getParent(); + if (node instanceof IASTDeclarator) { + IType t = CPPVisitor.createType((IASTDeclarator) node); + if (!(t instanceof IArrayType) || ((IArrayType) t).hasSize()) { + return t; + } + if (firstCandidate == null) { + firstCandidate = (IArrayType) t; + } + } + } + } + + if (!allDeclarationsResolved) { + resolveAllDeclarations(variable, definition, declarations); + return variable.getType(); + } + return firstCandidate; + } + + private static void resolveAllDeclarations(ICPPVariable variable, IASTName definition, + IASTName[] declarations) { + final int length = declarations == null ? 0 : declarations.length; + for (int i = -1; i < length; i++) { + @SuppressWarnings("null") + IASTName n = i == -1 ? definition : declarations[i]; + if (n != null) { + IASTTranslationUnit tu = n.getTranslationUnit(); + if (tu != null) { + CPPVisitor.getDeclarations(tu, variable); + return; + } + } + } + } + + public static IValue getInitialValue(IASTName definition, IASTName[] declarations, IType type) { + if (definition != null) { + final IValue val = getInitialValue(definition, type); + if (val != null) + return val; + } + if (declarations != null) { + for (IASTName decl : declarations) { + if (decl == null) + break; + final IValue val = getInitialValue(decl, type); + if (val != null) + return val; + } + } + return null; + } + + private static IValue getInitialValue(IASTName name, IType type) { + IASTDeclarator dtor = findDeclarator(name); + if (dtor != null) { + IASTInitializer init = dtor.getInitializer(); + if (init != null) { + return SemanticUtil.getValueOfInitializer(init, type); + } + } + return null; + } + + private static IASTDeclarator findDeclarator(IASTName name) { + IASTNode node = name.getParent(); + if (node instanceof ICPPASTQualifiedName) + node = node.getParent(); + + if (!(node instanceof IASTDeclarator)) + return null; + + IASTDeclarator dtor = (IASTDeclarator) node; + while (dtor.getParent() instanceof IASTDeclarator) { + dtor = (IASTDeclarator) dtor.getParent(); + } + + return dtor; + } + + public static int getVisibility(ICPPInternalVariable field) { + ICPPASTVisibilityLabel vis = null; + IASTDeclaration decl = getPrimaryDeclaration(field); + if (decl != null) { + IASTCompositeTypeSpecifier cls = (IASTCompositeTypeSpecifier) decl.getParent(); + IASTDeclaration[] members = cls.getMembers(); + + for (IASTDeclaration member : members) { + if (member == decl) + break; + if (member instanceof ICPPASTVisibilityLabel) + vis = (ICPPASTVisibilityLabel) member; + } + + if (vis != null) { + return vis.getVisibility(); + } else if (cls.getKey() == ICPPASTCompositeTypeSpecifier.k_class) { + return ICPPASTVisibilityLabel.v_private; + } + } + return ICPPASTVisibilityLabel.v_public; + } + + private static IASTDeclaration getPrimaryDeclaration(ICPPInternalVariable field) { + // First check if we already know it. + IASTDeclaration decl= findDeclaration(field.getDefinition()); + if (decl != null) { + return decl; + } + + IASTName[] declarations = (IASTName[]) field.getDeclarations(); + if (declarations != null) { + for (IASTName name : declarations) { + decl= findDeclaration(name); + if (decl != null) { + return decl; + } + } + } + + char[] myName = field.getNameCharArray(); + + ICPPClassScope scope = findClassScope(field); + ICPPASTCompositeTypeSpecifier compSpec = + (ICPPASTCompositeTypeSpecifier) ASTInternal.getPhysicalNodeOfScope(scope); + IASTDeclaration[] members = compSpec.getMembers(); + for (IASTDeclaration member : members) { + if (member instanceof IASTSimpleDeclaration) { + IASTDeclarator[] dtors = ((IASTSimpleDeclaration) member).getDeclarators(); + for (IASTDeclarator dtor : dtors) { + IASTName name = dtor.getName(); + if (CharArrayUtils.equals(name.getLookupKey(), myName) && name.resolveBinding() == field) { + return member; + } + } + } + } + return null; + } + + private static ICPPClassScope findClassScope(ICPPInternalVariable v) { + IScope scope; + try { + scope = v.getScope(); + } catch (DOMException e) { + scope = null; + } + while (scope != null){ + if (scope instanceof ICPPClassScope) { + return (ICPPClassScope) scope; + } + try { + scope = scope.getParent(); + } catch (DOMException e) { + return null; + } + } + return null; + } + + private static IASTDeclaration findDeclaration(IASTNode node) { + while (node != null && !(node instanceof IASTDeclaration)) { + node = node.getParent(); + } + if (node != null && node.getParent() instanceof ICPPASTCompositeTypeSpecifier) { + return (IASTDeclaration) node; + } + return null; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index 614ff83832a..0bfa474a5ef 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -161,6 +161,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPPartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; @@ -2060,6 +2061,16 @@ public class CPPSemantics { !(temp instanceof IEnumerator)) { continue; } + + // Specializations are selected during instantiation. + if (temp instanceof ICPPPartialSpecialization) + continue; + if (temp instanceof ICPPTemplateInstance && lookupName instanceof ICPPASTTemplateId) { + temp= ((ICPPTemplateInstance) temp).getSpecializedBinding(); + if (!(temp instanceof IType)) + continue; + } + if (temp instanceof ICPPUsingDeclaration) { IBinding[] bindings = ((ICPPUsingDeclaration) temp).getDelegates(); mergeResults(data, bindings, false); @@ -2080,15 +2091,6 @@ public class CPPSemantics { fns = new ObjectSet<>(2); fns.put((ICPPFunction) temp); } else if (temp instanceof IType) { - // Specializations are selected during instantiation. - if (temp instanceof ICPPClassTemplatePartialSpecialization) - continue; - if (temp instanceof ICPPTemplateInstance && lookupName instanceof ICPPASTTemplateId) { - temp= ((ICPPTemplateInstance) temp).getSpecializedBinding(); - if (!(temp instanceof IType)) - continue; - } - if (type == null) { type = temp; ambiguous = 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 82eef7470aa..b3be1d1df80 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 @@ -38,6 +38,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNameOwner; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTTypeId; @@ -59,6 +60,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAmbiguousTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; @@ -83,6 +85,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumerationSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFieldTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; @@ -90,6 +93,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPPartialSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPPartiallySpecializable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; @@ -104,6 +109,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUnaryTypeTransformation; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArraySet; @@ -131,7 +138,10 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructorTemplateSpecia import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPEnumerationSpecialization; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFieldInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFieldSpecialization; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFieldTemplatePartialSpecialization; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFieldTemplateSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionTemplateSpecialization; @@ -158,6 +168,9 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownMemberClass; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownMethod; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDeclarationSpecialization; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariableInstance; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariableTemplate; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariableTemplatePartialSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalTemplateDeclaration; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; @@ -216,7 +229,7 @@ public class CPPTemplates { /** * Instantiates a class template with the given arguments. May return {@code null}. */ - private static IBinding instantiate(ICPPClassTemplate template, ICPPTemplateArgument[] args, + private static IBinding instantiate(ICPPPartiallySpecializable template, ICPPTemplateArgument[] args, boolean isDefinition, boolean isExplicitSpecialization, IASTNode point) { try { ICPPTemplateArgument[] arguments= SemanticUtil.getSimplifiedArguments(args); @@ -257,7 +270,7 @@ public class CPPTemplates { } } - private static IBinding createProblem(ICPPClassTemplate template, int id, IASTNode point) { + private static IBinding createProblem(ICPPPartiallySpecializable template, int id, IASTNode point) { return new ProblemBinding(point, id, template.getNameCharArray()); } @@ -348,7 +361,7 @@ public class CPPTemplates { * Instantiates a partial class template specialization. */ private static IBinding instantiatePartialSpecialization( - ICPPClassTemplatePartialSpecialization partialSpec, ICPPTemplateArgument[] args, boolean isDef, + ICPPPartialSpecialization partialSpec, ICPPTemplateArgument[] args, boolean isDef, CPPTemplateParameterMap tpMap, IASTNode point) throws DOMException { ICPPTemplateInstance instance= getInstance(partialSpec, args, isDef); if (instance != null) @@ -370,7 +383,7 @@ public class CPPTemplates { * Instantiates the selected template, without looking for specializations. * May return {@code null}. */ - private static IBinding instantiatePrimaryTemplate(ICPPClassTemplate template, ICPPTemplateArgument[] arguments, + private static IBinding instantiatePrimaryTemplate(ICPPPartiallySpecializable template, ICPPTemplateArgument[] arguments, CPPTemplateParameterMap map, boolean isDef, IASTNode point) throws DOMException { assert !(template instanceof ICPPClassTemplatePartialSpecialization); ICPPTemplateInstance instance= getInstance(template, arguments, isDef); @@ -418,13 +431,15 @@ public class CPPTemplates { } } - private static IBinding deferredInstance(ICPPClassTemplate template, ICPPTemplateArgument[] arguments) throws DOMException { + private static IBinding deferredInstance(ICPPPartiallySpecializable template, ICPPTemplateArgument[] arguments) throws DOMException { ICPPTemplateInstance instance= getInstance(template, arguments, false); if (instance != null) return instance; - instance = new CPPDeferredClassInstance(template, arguments); - addInstance(template, arguments, instance); + if (template instanceof ICPPClassTemplate) { + instance = new CPPDeferredClassInstance((ICPPClassTemplate) template, arguments); + addInstance(template, arguments, instance); + } return instance; } @@ -639,7 +654,8 @@ public class CPPTemplates { // Functions are instantiated as part of the resolution process. IBinding result= CPPVisitor.createBinding(id); IASTName templateName = id.getTemplateName(); - if (result instanceof ICPPClassTemplate || result instanceof ICPPAliasTemplate) { + if (result instanceof ICPPClassTemplate || result instanceof ICPPAliasTemplate + || result instanceof ICPPVariableTemplate) { templateName.setBinding(result); id.setBinding(null); } else { @@ -669,6 +685,8 @@ public class CPPTemplates { isDeclaration= true; } else if (parentOfName instanceof ICPPASTCompositeTypeSpecifier) { isDefinition= true; + } else if (parentOfName instanceof ICPPASTDeclarator) { + isDeclaration= true; } if (isDeclaration || isDefinition) { IASTNode parentOfDeclaration = declaration.getParent(); @@ -724,7 +742,7 @@ public class CPPTemplates { return createAliasTemplaceInstance(aliasTemplate, args, parameterMap, aliasedType, owner, id); } - // Class template. + // Class or variable template. if (template instanceof ICPPConstructor) { template= template.getOwner(); } @@ -736,10 +754,10 @@ public class CPPTemplates { return new CPPUnknownClassInstance(owner, id.getSimpleID(), args); } - if (!(template instanceof ICPPClassTemplate) || template instanceof ICPPClassTemplatePartialSpecialization) + if (!(template instanceof ICPPPartiallySpecializable) || template instanceof ICPPClassTemplatePartialSpecialization) return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TYPE, templateName.toCharArray()); - final ICPPClassTemplate classTemplate = (ICPPClassTemplate) template; + final ICPPPartiallySpecializable classTemplate = (ICPPPartiallySpecializable) template; ICPPTemplateArgument[] args= createTemplateArgumentArray(id); if (hasDependentArgument(args)) { ICPPASTTemplateDeclaration tdecl= getTemplateDeclaration(id); @@ -751,12 +769,24 @@ public class CPPTemplates { if (args == null) { return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray()); } - ICPPClassTemplatePartialSpecialization partialSpec= findPartialSpecialization(classTemplate, args); + ICPPPartialSpecialization partialSpec= findPartialSpecialization(classTemplate, args); if (isDeclaration || isDefinition) { if (partialSpec == null) { - partialSpec = new CPPClassTemplatePartialSpecialization(id, args); - if (template instanceof ICPPInternalClassTemplate) - ((ICPPInternalClassTemplate) template).addPartialSpecialization(partialSpec); + if (template instanceof ICPPClassTemplate) { + partialSpec = new CPPClassTemplatePartialSpecialization(id, args); + if (template instanceof ICPPInternalClassTemplate) { + ((ICPPInternalClassTemplate) template).addPartialSpecialization( + (ICPPClassTemplatePartialSpecialization) partialSpec); + } + } else if (template instanceof ICPPVariableTemplate) { + if (template instanceof ICPPFieldTemplate) { + partialSpec = new CPPFieldTemplatePartialSpecialization(id, args); + } else { + partialSpec = new CPPVariableTemplatePartialSpecialization(id, args); + } + if (template instanceof CPPVariableTemplate) + ((CPPVariableTemplate) template).addPartialSpecialization(partialSpec); + } return partialSpec; } } @@ -846,6 +876,25 @@ public class CPPTemplates { } spec.setParameters(specializeParameters(func.getParameters(), spec, tpMap, -1, within, Value.MAX_RECURSION_DEPTH, point)); instance = (ICPPTemplateInstance) spec; + } else if (template instanceof ICPPVariable) { + ICPPVariable var = (ICPPVariable) template; + ICPPClassSpecialization within = getSpecializationContext(owner); + IType type = instantiateType(var.getType(), tpMap, -1, within, point); + + IValue value; + ICPPASTDeclarator decl = CPPVisitor.findAncestorWithType(point, ICPPASTDeclarator.class); + if (((IASTName) point).getRoleOfName(false) == IASTNameOwner.r_definition && decl != null && decl.getInitializer() != null) { + // Explicit specialization. + value = SemanticUtil.getValueOfInitializer(decl.getInitializer(), type); + } else { + value = instantiateValue(var.getInitialValue(), tpMap, -1, within, Value.MAX_RECURSION_DEPTH, point); + } + + if (template instanceof ICPPField) { + instance = new CPPFieldInstance(template, owner, tpMap, args, type, value); + } else { + instance = new CPPVariableInstance(template, owner, tpMap, args, type, value); + } } return instance; } @@ -916,7 +965,17 @@ public class CPPTemplates { ICPPField field= (ICPPField) decl; IType type= instantiateType(field.getType(), tpMap, -1, within, point); IValue value= instantiateValue(field.getInitialValue(), tpMap, -1, within, Value.MAX_RECURSION_DEPTH, point); - spec = new CPPFieldSpecialization(decl, owner, tpMap, type, value); + if (decl instanceof ICPPFieldTemplate) { + CPPFieldTemplateSpecialization fieldTempSpec = new CPPFieldTemplateSpecialization(decl, + owner, tpMap, type, value); + ICPPTemplateParameter[] params = CPPTemplates.specializeTemplateParameters(fieldTempSpec, + (ICPPScope) fieldTempSpec.getScope(), + ((ICPPFieldTemplate) decl).getTemplateParameters(), owner, point); + fieldTempSpec.setTemplateParameters(params); + spec = fieldTempSpec; + } else { + spec = new CPPFieldSpecialization(decl, owner, tpMap, type, value); + } } else if (decl instanceof ICPPFunction) { ICPPFunction func= (ICPPFunction) decl; ICPPClassSpecialization within = getSpecializationContext(owner); @@ -2319,12 +2378,12 @@ public class CPPTemplates { return result; } - private static ICPPClassTemplatePartialSpecialization findPartialSpecialization(ICPPClassTemplate ct, + private static ICPPPartialSpecialization findPartialSpecialization(ICPPPartiallySpecializable ct, ICPPTemplateArgument[] args) throws DOMException { - ICPPClassTemplatePartialSpecialization[] pspecs = ct.getPartialSpecializations(); + ICPPPartialSpecialization[] pspecs = ct.getPartialSpecializations(); if (pspecs != null && pspecs.length > 0) { final String argStr= ASTTypeUtil.getArgumentListString(args, true); - for (ICPPClassTemplatePartialSpecialization pspec : pspecs) { + for (ICPPPartialSpecialization pspec : pspecs) { if (argStr.equals(ASTTypeUtil.getArgumentListString(pspec.getTemplateArguments(), true))) return pspec; } @@ -2332,20 +2391,20 @@ public class CPPTemplates { return null; } - private static IBinding selectSpecialization(ICPPClassTemplate template, ICPPTemplateArgument[] args, + private static IBinding selectSpecialization(ICPPPartiallySpecializable template, ICPPTemplateArgument[] args, boolean isDef, IASTNode point) throws DOMException { if (template == null) { return null; } - ICPPClassTemplatePartialSpecialization[] specializations = template.getPartialSpecializations(); + ICPPPartialSpecialization[] specializations = template.getPartialSpecializations(); if (specializations == null || specializations.length == 0) { return null; } - ICPPClassTemplatePartialSpecialization bestMatch = null; + ICPPPartialSpecialization bestMatch = null; CPPTemplateParameterMap bestMap= null; boolean bestMatchIsBest = true; - for (ICPPClassTemplatePartialSpecialization specialization : specializations) { + for (ICPPPartialSpecialization specialization : specializations) { final CPPTemplateParameterMap map = new CPPTemplateParameterMap(args.length); ICPPTemplateArgument[] specializationArguments = specialization.getTemplateArguments(); if (TemplateArgumentDeduction.fromTemplateArguments(specialization.getTemplateParameters(), @@ -2390,7 +2449,7 @@ public class CPPTemplates { * @return * @throws DOMException */ - static private int orderSpecializations(ICPPClassTemplatePartialSpecialization spec1, ICPPClassTemplatePartialSpecialization spec2, IASTNode point) throws DOMException { + static private int orderSpecializations(ICPPPartialSpecialization spec1, ICPPPartialSpecialization spec2, IASTNode point) throws DOMException { if (spec1 == null) { return -1; } @@ -2413,7 +2472,7 @@ public class CPPTemplates { return -1; } - private static boolean isAtLeastAsSpecializedAs(ICPPClassTemplatePartialSpecialization f1, ICPPClassTemplatePartialSpecialization f2, IASTNode point) throws DOMException { + private static boolean isAtLeastAsSpecializedAs(ICPPPartialSpecialization f1, ICPPPartialSpecialization f2, IASTNode point) throws DOMException { // 14.5.5.2 // Using the transformed parameter list, perform argument deduction against the other // function template diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index fb07f09a744..fe5d1d8aa6d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -196,6 +196,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructorTemplate; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPEnumeration; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPEnumerator; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPField; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFieldTemplate; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionTemplate; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType; @@ -217,6 +218,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedef; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnaryTypeTransformation; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownTypeScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariable; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariableTemplate; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; @@ -736,7 +738,7 @@ public class CPPVisitor extends ASTQueries { binding = new ProblemBinding(alias.getAlias(), IProblemBinding.SEMANTIC_NAME_NOT_FOUND); } } - return binding; + return binding; } return null; } @@ -882,6 +884,12 @@ public class CPPVisitor extends ASTQueries { } } else if (simpleDecl.getParent() instanceof ICPPASTCompositeTypeSpecifier) { binding = new CPPField(name); + } else if (template) { + if (simpleDecl.getParent().getParent() instanceof ICPPASTCompositeTypeSpecifier) { + binding = new CPPFieldTemplate(name); + } else { + binding = new CPPVariableTemplate(name); + } } else { binding = new CPPVariable(name); } @@ -1030,7 +1038,7 @@ public class CPPVisitor extends ASTQueries { return false; } - + public static boolean isLastNameInUsingDeclaration(IASTName name) { IASTNode parent = name.getParent(); return parent instanceof ICPPASTQualifiedName @@ -1367,9 +1375,9 @@ public class CPPVisitor extends ASTQueries { scope = getContainingScope((IASTStatement) parent); } else if (parent instanceof IASTFunctionDefinition) { final IASTFunctionDefinition fdef = (IASTFunctionDefinition) parent; - if (statement instanceof ICPPASTCatchHandler) + if (statement instanceof ICPPASTCatchHandler) return fdef.getScope(); - + IASTFunctionDeclarator fnDeclarator = fdef.getDeclarator(); IASTName name = findInnermostDeclarator(fnDeclarator).getName().getLastName(); return getContainingScope(name); @@ -2058,7 +2066,7 @@ public class CPPVisitor extends ASTQueries { IType type = createType(declSpec); type = makeConstIfConstexpr(type, declSpec, declarator); type = createType(type, declarator); - + // C++ specification 8.3.4.3 and 8.5.1.4 IASTNode initClause= declarator.getInitializer(); if (initClause instanceof IASTEqualsInitializer) { @@ -2276,7 +2284,7 @@ public class CPPVisitor extends ASTQueries { } return type; } - + private static IType qualifyType(IType type, IASTDeclSpecifier declSpec) { return SemanticUtil.addQualifiers(type, declSpec.isConst(), declSpec.isVolatile(), declSpec.isRestrict()); } @@ -2534,6 +2542,19 @@ public class CPPVisitor extends ASTQueries { return false; } + public static boolean isExternC(IASTNode definition, IASTNode[] declarations) { + if (isExternC(definition)) + return true; + + if (declarations != null) { + for (IASTNode element : declarations) { + if (isExternC(element)) + return true; + } + } + return false; + } + @Deprecated public static boolean isLValueReference(IType t) { t= SemanticUtil.getNestedType(t, TDEF); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java index a56f3d3318f..96f82d84fe9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2013 Symbian Software Systems and others. + * Copyright (c) 2007, 2015 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 @@ -65,4 +65,10 @@ public interface IIndexCPPBindingConstants { int CPP_TEMPLATE_ALIAS = IIndexBindingConstants.LAST_CONSTANT + 51; int CPP_ENUMERATION_SPECIALIZATION = IIndexBindingConstants.LAST_CONSTANT + 52; int CPP_ENUMERATOR_SPECIALIZATION = IIndexBindingConstants.LAST_CONSTANT + 53; + int CPP_VARIABLE_TEMPLATE = IIndexBindingConstants.LAST_CONSTANT + 54; + int CPP_FIELD_TEMPLATE = IIndexBindingConstants.LAST_CONSTANT + 55; + int CPP_VARIABLE_INSTANCE = IIndexBindingConstants.LAST_CONSTANT + 56; + int CPP_FIELD_INSTANCE = IIndexBindingConstants.LAST_CONSTANT + 57; + int CPP_VARIABLE_TEMPLATE_PARTIAL_SPECIALIZATION = IIndexBindingConstants.LAST_CONSTANT + 58; + int CPP_FIELD_TEMPLATE_PARTIAL_SPECIALIZATION = IIndexBindingConstants.LAST_CONSTANT + 59; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java index d5a39a063d8..1e1583b7ec8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java @@ -36,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFieldTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; @@ -58,6 +59,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUnaryTypeTransformation; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableInstance; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplatePartialSpecialization; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexMacroContainer; @@ -555,6 +559,10 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { return new CompositeCPPMethodInstance(this, (ICPPMethod) binding); } else if (binding instanceof ICPPFunction) { return new CompositeCPPFunctionInstance(this, (ICPPFunction) binding); + } else if (binding instanceof ICPPField) { + return new CompositeCPPFieldInstance(this, (ICPPVariableInstance) binding); + } else if (binding instanceof ICPPVariable) { + return new CompositeCPPVariableInstance(this, (ICPPVariableInstance) binding); } else { throw new CompositingNotImplementedError("Composite binding unavailable for " + binding + " " + binding.getClass()); //$NON-NLS-1$ //$NON-NLS-2$ } @@ -600,6 +608,12 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { } } else if (binding instanceof ICPPClassTemplatePartialSpecialization) { return new CompositeCPPClassTemplatePartialSpecialization(this, (ICPPClassTemplatePartialSpecialization) findOneBinding(binding)); + } else if (binding instanceof ICPPVariableTemplatePartialSpecialization) { + if (binding instanceof ICPPField) { + return new CompositeCPPFieldTemplatePartialSpecialization(this, (ICPPVariableTemplatePartialSpecialization) binding); + } else { + return new CompositeCPPVariableTemplatePartialSpecialization(this, (ICPPVariableTemplatePartialSpecialization) binding); + } } else if (binding instanceof ICPPTemplateParameter) { if (binding instanceof ICPPTemplateTypeParameter) { result = new CompositeCPPTemplateTypeParameter(this, (ICPPTemplateTypeParameter) binding); @@ -622,6 +636,10 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { return new CompositeCPPFunctionTemplate(this, (ICPPFunction) binding); } else if (binding instanceof ICPPAliasTemplate) { return new CompositeCPPAliasTemplate(this, (ICPPBinding) binding); + } else if (binding instanceof ICPPFieldTemplate) { + return new CompositeCPPFieldTemplate(this, (ICPPField) binding); + } else if (binding instanceof ICPPVariableTemplate) { + return new CompositeCPPVariableTemplate(this, (ICPPVariable) binding); } else { throw new CompositingNotImplementedError("Composite binding unavailable for " + binding + " " + binding.getClass()); //$NON-NLS-1$ //$NON-NLS-2$ } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplatePartialSpecialization.java index 0516234648a..80981a5b26b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplatePartialSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplatePartialSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2013 Symbian Software Systems and others. + * Copyright (c) 2007, 2015 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 @@ -15,6 +15,7 @@ import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; import org.eclipse.cdt.internal.core.pdom.dom.IPDOMOverloader; @@ -46,4 +47,9 @@ public class CompositeCPPClassTemplatePartialSpecialization extends CompositeCPP public IType[] getArguments() { return TemplateInstanceUtil.getArguments(cf, (ICPPClassTemplatePartialSpecialization) rbinding); } + + @Override + public ICPPTemplateDefinition getPrimaryTemplate() { + return getPrimaryClassTemplate(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplatePartialSpecializationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplatePartialSpecializationSpecialization.java index 5cc461e4c3d..16aa1ec9e91 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplatePartialSpecializationSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplatePartialSpecializationSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2012 Wind River Systems, Inc. and others. + * Copyright (c) 2009, 2015 Wind River Systems, Inc. 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 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecializationSpecialization; 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.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; @@ -26,7 +27,8 @@ import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; public class CompositeCPPClassTemplatePartialSpecializationSpecialization extends CompositeCPPClassSpecialization implements ICPPClassTemplatePartialSpecializationSpecialization, ICPPInstanceCache { - public CompositeCPPClassTemplatePartialSpecializationSpecialization(ICompositesFactory cf, ICPPClassTemplatePartialSpecializationSpecialization rbinding) { + public CompositeCPPClassTemplatePartialSpecializationSpecialization(ICompositesFactory cf, + ICPPClassTemplatePartialSpecializationSpecialization rbinding) { super(cf, rbinding); } @@ -83,4 +85,9 @@ public class CompositeCPPClassTemplatePartialSpecializationSpecialization extend public IType[] getArguments() { return TemplateInstanceUtil.getArguments(cf, (ICPPClassTemplatePartialSpecialization) rbinding); } + + @Override + public ICPPTemplateDefinition getPrimaryTemplate() { + return getPrimaryClassTemplate(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFieldInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFieldInstance.java new file mode 100644 index 00000000000..ab54624bbea --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFieldInstance.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.index.composite.cpp; + +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableInstance; +import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; +import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; + +public class CompositeCPPFieldInstance extends CompositeCPPVariableInstance implements ICPPField { + + public CompositeCPPFieldInstance(ICompositesFactory cf, ICPPVariableInstance delegate) { + super(cf, delegate); + } + + @Override + public ICompositeType getCompositeTypeOwner() { + return getClassOwner(); + } + + @Override + public int getVisibility() { + return ((ICPPField) rbinding).getVisibility(); + } + + @Override + public ICPPClassType getClassOwner() { + return (ICPPClassType) cf.getCompositeBinding( + (IIndexFragmentBinding) ((ICPPField) rbinding).getClassOwner()); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFieldTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFieldTemplate.java new file mode 100644 index 00000000000..c57460f1bf3 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFieldTemplate.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.index.composite.cpp; + +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFieldTemplate; +import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; +import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; + +public class CompositeCPPFieldTemplate extends CompositeCPPVariableTemplate implements ICPPFieldTemplate { + + public CompositeCPPFieldTemplate(ICompositesFactory cf, ICPPField rbinding) { + super(cf, rbinding); + } + + @Override + public ICompositeType getCompositeTypeOwner() { + return getClassOwner(); + } + + @Override + public int getVisibility() { + return ((ICPPField) rbinding).getVisibility(); + } + + @Override + public ICPPClassType getClassOwner() { + return (ICPPClassType) cf.getCompositeBinding( + (IIndexFragmentBinding) ((ICPPField)rbinding).getClassOwner()); + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFieldTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFieldTemplatePartialSpecialization.java new file mode 100644 index 00000000000..ac922d80193 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPFieldTemplatePartialSpecialization.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.index.composite.cpp; + +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplatePartialSpecialization; +import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; +import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; + +public class CompositeCPPFieldTemplatePartialSpecialization + extends CompositeCPPVariableTemplatePartialSpecialization implements ICPPField { + + public CompositeCPPFieldTemplatePartialSpecialization(ICompositesFactory cf, + ICPPVariableTemplatePartialSpecialization delegate) { + super(cf, delegate); + } + + @Override + public ICompositeType getCompositeTypeOwner() { + return getClassOwner(); + } + + @Override + public int getVisibility() { + return ((ICPPField) rbinding).getVisibility(); + } + + @Override + public ICPPClassType getClassOwner() { + return (ICPPClassType) cf.getCompositeBinding( + (IIndexFragmentBinding) ((ICPPField) rbinding).getClassOwner()); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPVariableInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPVariableInstance.java new file mode 100644 index 00000000000..f739bafd741 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPVariableInstance.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.index.composite.cpp; + +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; +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.ICPPTemplateParameterMap; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableInstance; +import org.eclipse.cdt.core.parser.util.ObjectMap; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; +import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; + +public class CompositeCPPVariableInstance extends CompositeCPPVariable implements ICPPVariableInstance { + private ICPPVariableInstance delegate; + + public CompositeCPPVariableInstance(ICompositesFactory cf, ICPPVariableInstance delegate) { + super(cf, delegate); + this.delegate = delegate; + } + + @Override + public ICPPTemplateDefinition getTemplateDefinition() { + return TemplateInstanceUtil.getTemplateDefinition(cf, rbinding); + } + + @Override + public ICPPTemplateArgument[] getTemplateArguments() { + return TemplateInstanceUtil.getTemplateArguments(cf, delegate); + } + + @Override + public boolean isExplicitSpecialization() { + return delegate.isExplicitSpecialization(); + } + + @Override + @Deprecated + public IType[] getArguments() { + return TemplateInstanceUtil.getArguments(cf, delegate); + } + + @Override + public IBinding getSpecializedBinding() { + return TemplateInstanceUtil.getSpecializedBinding(cf, rbinding); + } + + @Override + public ICPPTemplateParameterMap getTemplateParameterMap() { + IBinding owner= getOwner(); + if (owner instanceof ICPPSpecialization) + return ((ICPPSpecialization) owner).getTemplateParameterMap(); + + return CPPTemplateParameterMap.EMPTY; + } + + @Override + @Deprecated + public ObjectMap getArgumentMap() { + return TemplateInstanceUtil.getArgumentMap(cf, rbinding); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPVariableTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPVariableTemplate.java new file mode 100644 index 00000000000..0dda3c98479 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPVariableTemplate.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.index.composite.cpp; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.IVariable; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPPartialSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplatePartialSpecialization; +import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache; +import org.eclipse.cdt.internal.core.index.CIndex; +import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; +import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; +import org.eclipse.core.runtime.CoreException; + +public class CompositeCPPVariableTemplate extends CompositeCPPVariable + implements ICPPVariableTemplate, ICPPInstanceCache { + + public CompositeCPPVariableTemplate(ICompositesFactory cf, IVariable delegate) { + super(cf, delegate); + } + + @Override + public ICPPTemplateParameter[] getTemplateParameters() { + return TemplateInstanceUtil.convert(cf, ((ICPPVariableTemplate) rbinding).getTemplateParameters()); + } + + @Override + public ICPPPartialSpecialization[] getPartialSpecializations() { + try { + final CIndex cIndex = (CIndex) ((CPPCompositesFactory) cf).getContext(); + IIndexFragmentBinding[] bindings = cIndex.findEquivalentBindings(rbinding); + IIndexFragmentBinding[][] preresult = new IIndexFragmentBinding[bindings.length][]; + + for (int i = 0; i < bindings.length; i++) { + final ICPPVariableTemplate template = (ICPPVariableTemplate) bindings[i]; + ICPPPartialSpecialization[] ss = template.getPartialSpecializations(); + preresult[i] = new IIndexFragmentBinding[ss.length]; + System.arraycopy(ss, 0, preresult[i], 0, ss.length); + } + + return ArrayUtil.addAll( + ICPPVariableTemplatePartialSpecialization.EMPTY_ARRAY, + cf.getCompositeBindings(preresult)); + } catch (CoreException e) { + CCorePlugin.log(e); + return ICPPVariableTemplatePartialSpecialization.EMPTY_ARRAY; + } + } + + @Override + public ICPPTemplateInstance getInstance(ICPPTemplateArgument[] arguments) { + return CompositeInstanceCache.getCache(cf, rbinding).getInstance(arguments); + } + + @Override + public void addInstance(ICPPTemplateArgument[] arguments, ICPPTemplateInstance instance) { + CompositeInstanceCache.getCache(cf, rbinding).addInstance(arguments, instance); + } + + @Override + public ICPPTemplateInstance[] getAllInstances() { + return CompositeInstanceCache.getCache(cf, rbinding).getAllInstances(); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPVariableTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPVariableTemplatePartialSpecialization.java new file mode 100644 index 00000000000..3bef0a92dc0 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPVariableTemplatePartialSpecialization.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.index.composite.cpp; + +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.ICPPVariableTemplatePartialSpecialization; +import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; +import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; + +public class CompositeCPPVariableTemplatePartialSpecialization extends CompositeCPPVariableTemplate + implements ICPPVariableTemplatePartialSpecialization { + + public CompositeCPPVariableTemplatePartialSpecialization(ICompositesFactory cf, ICPPVariableTemplatePartialSpecialization delegate) { + super(cf, delegate); + } + + @Override + public ICPPTemplateDefinition getPrimaryTemplate() { + return (ICPPTemplateDefinition) cf.getCompositeBinding( + (IIndexFragmentBinding) ((ICPPVariableTemplatePartialSpecialization) rbinding).getPrimaryTemplate()); + } + + @Override + public ICPPTemplateArgument[] getTemplateArguments() { + return TemplateInstanceUtil.getTemplateArguments(cf, (ICPPVariableTemplatePartialSpecialization) rbinding); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/TemplateInstanceUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/TemplateInstanceUtil.java index b58cde9455f..1e1bb89f62a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/TemplateInstanceUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/TemplateInstanceUtil.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2012 Symbian Software Systems and others. + * Copyright (c) 2007, 2015 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 @@ -18,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPPartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; @@ -42,7 +43,7 @@ public class TemplateInstanceUtil { ICPPTemplateParameterMap preresult= rbinding.getTemplateParameterMap(); Integer[] keys= preresult.getAllParameterPositions(); CPPTemplateParameterMap result= new CPPTemplateParameterMap(keys.length); - + try { for (Integer key : keys) { ICPPTemplateArgument arg= preresult.getArgument(key); @@ -58,12 +59,12 @@ public class TemplateInstanceUtil { } return result; } - + public static ICPPTemplateArgument[] getTemplateArguments(ICompositesFactory cf, ICPPTemplateInstance rbinding) { return convert(cf, rbinding.getTemplateArguments()); } - public static ICPPTemplateArgument[] getTemplateArguments(ICompositesFactory cf, ICPPClassTemplatePartialSpecialization rbinding) { + public static ICPPTemplateArgument[] getTemplateArguments(ICompositesFactory cf, ICPPPartialSpecialization rbinding) { return convert(cf, rbinding.getTemplateArguments()); } @@ -71,12 +72,12 @@ public class TemplateInstanceUtil { IBinding preresult= ((ICPPSpecialization) rbinding).getSpecializedBinding(); return cf.getCompositeBinding((IIndexFragmentBinding) preresult); } - + public static ICPPTemplateDefinition getTemplateDefinition(ICompositesFactory cf, IIndexBinding rbinding) { ICPPTemplateDefinition preresult= ((ICPPTemplateInstance)rbinding).getTemplateDefinition(); return (ICPPTemplateDefinition) cf.getCompositeBinding((IIndexFragmentBinding)preresult); } - + public static ICPPTemplateArgument[] convert(ICompositesFactory cf, ICPPTemplateArgument[] arguments) { if (arguments == null) return null; @@ -110,19 +111,19 @@ public class TemplateInstanceUtil { } return arg; } - + @Deprecated public static ObjectMap getArgumentMap(ICompositesFactory cf, IIndexBinding rbinding) { - ICPPSpecialization specn= (ICPPSpecialization) rbinding; + ICPPSpecialization specn= (ICPPSpecialization) rbinding; IBinding specd= ((CPPCompositesFactory) cf).findOneBinding(specn.getSpecializedBinding()); if (specd == null) specd= specn.getSpecializedBinding(); - + ObjectMap preresult= specn.getArgumentMap(); ObjectMap result= new ObjectMap(preresult.size()); Object[] keys= preresult.keyArray(); Object[] keysToAdapt= keys; - + if (specd instanceof ICPPTemplateDefinition) { keysToAdapt= ((ICPPTemplateDefinition) specd).getTemplateParameters(); } @@ -131,7 +132,7 @@ public class TemplateInstanceUtil { result.put( cf.getCompositeBinding((IIndexFragmentBinding) keysToAdapt[i]), cf.getCompositeType(type)); } - + return result; } @@ -139,7 +140,7 @@ public class TemplateInstanceUtil { public static IType[] getArguments(ICompositesFactory cf, ICPPTemplateInstance rbinding) { return getArguments(cf, rbinding.getArguments()); } - + @Deprecated public static IType[] getArguments(ICompositesFactory cf, ICPPClassTemplatePartialSpecialization rbinding) { try { @@ -149,7 +150,7 @@ public class TemplateInstanceUtil { return IType.EMPTY_TYPE_ARRAY; } } - + @Deprecated private static IType[] getArguments(ICompositesFactory cf, IType[] result) { for (int i= 0; i < result.length; i++) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMPartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMPartialSpecialization.java index ee9155ae2bc..598c16006ac 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMPartialSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMPartialSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Wind River Systems, Inc. and others. + * Copyright (c) 2009, 2015 Wind River Systems, Inc. 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 @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPPartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.internal.core.pdom.dom.IPDOMBinding; import org.eclipse.core.runtime.CoreException; @@ -18,9 +18,9 @@ import org.eclipse.core.runtime.CoreException; /** * Interface for partial specializations in the PDOM. */ -interface IPDOMPartialSpecialization extends ICPPClassTemplatePartialSpecialization, IPDOMBinding { +interface IPDOMPartialSpecialization extends ICPPPartialSpecialization, IPDOMBinding { /** * Allows for setting the arguments after the binding has been added to the PDOM. */ - void setArguments(ICPPTemplateArgument[] args) throws CoreException; + void setTemplateArguments(ICPPTemplateArgument[] args) throws CoreException; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecialization.java index 0f71a54ee03..dea88ef7219 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecialization.java @@ -18,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassTemplatePartialSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; @@ -34,7 +35,7 @@ import org.eclipse.core.runtime.CoreException; * Partial specialization of a class template for the index. */ class PDOMCPPClassTemplatePartialSpecialization extends PDOMCPPClassTemplate - implements IPDOMPartialSpecialization, IPDOMOverloader { + implements IPDOMPartialSpecialization, IPDOMOverloader, ICPPClassTemplatePartialSpecialization { private static final int ARGUMENTS = PDOMCPPClassTemplate.RECORD_SIZE + 0; private static final int SIGNATURE_HASH = PDOMCPPClassTemplate.RECORD_SIZE + 4; private static final int PRIMARY = PDOMCPPClassTemplate.RECORD_SIZE + 8; @@ -102,7 +103,7 @@ class PDOMCPPClassTemplatePartialSpecialization extends PDOMCPPClassTemplate } @Override - public void setArguments(ICPPTemplateArgument[] templateArguments) throws CoreException { + public void setTemplateArguments(ICPPTemplateArgument[] templateArguments) throws CoreException { final Database db = getPDOM().getDB(); long oldRec = db.getRecPtr(record + ARGUMENTS); long rec= PDOMCPPArgumentList.putArguments(this, templateArguments); @@ -170,4 +171,9 @@ class PDOMCPPClassTemplatePartialSpecialization extends PDOMCPPClassTemplate final ICPPClassTemplatePartialSpecialization rhs = (ICPPClassTemplatePartialSpecialization) type; return CPPClassTemplatePartialSpecialization.isSamePartialClassSpecialization(this, rhs); } + + @Override + public ICPPTemplateDefinition getPrimaryTemplate() { + return getPrimaryClassTemplate(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecializationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecializationSpecialization.java index 21d802a15dc..b8fa47f20ef 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecializationSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecializationSpecialization.java @@ -7,7 +7,7 @@ * * Contributors: * Markus Schorn - initial API and implementation - *******************************************************************************/ + *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; import org.eclipse.cdt.core.CCorePlugin; @@ -17,6 +17,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecializationSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassTemplatePartialSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; @@ -29,30 +30,30 @@ import org.eclipse.core.runtime.CoreException; /** * A partial specialization further specialized in the context of a class specialization. */ -class PDOMCPPClassTemplatePartialSpecializationSpecialization extends PDOMCPPClassTemplateSpecialization +class PDOMCPPClassTemplatePartialSpecializationSpecialization extends PDOMCPPClassTemplateSpecialization implements IPDOMPartialSpecialization, ICPPClassTemplatePartialSpecializationSpecialization { private static final int PRIMARY_TEMPLATE = PDOMCPPClassTemplateSpecialization.RECORD_SIZE; private static final int ARGUMENTS = PDOMCPPClassTemplateSpecialization.RECORD_SIZE+4; private static final int NEXT_PARTIAL = PDOMCPPClassTemplateSpecialization.RECORD_SIZE+8; @SuppressWarnings("hiding") protected static final int RECORD_SIZE= PDOMCPPClassTemplateSpecialization.RECORD_SIZE+12; - + private volatile ICPPClassTemplate fPrimaryTemplate; public PDOMCPPClassTemplatePartialSpecializationSpecialization(PDOMCPPLinkage linkage, - PDOMNode parent, PDOMBinding specialized, ICPPClassTemplatePartialSpecialization partial, + PDOMNode parent, PDOMBinding specialized, ICPPClassTemplatePartialSpecialization partial, PDOMCPPClassTemplateSpecialization primary) throws CoreException { - super(linkage, parent, partial, specialized); + super(linkage, parent, partial, specialized); getDB().putRecPtr(record + PRIMARY_TEMPLATE, primary.getRecord()); - + linkage.new ConfigurePartialSpecialization(this, partial); } public PDOMCPPClassTemplatePartialSpecializationSpecialization(PDOMLinkage linkage, long bindingRecord) { super(linkage, bindingRecord); } - + @Override protected int getRecordSize() { return RECORD_SIZE; @@ -62,17 +63,17 @@ class PDOMCPPClassTemplatePartialSpecializationSpecialization extends PDOMCPPCla public int getNodeType() { return IIndexCPPBindingConstants.CPP_CLASS_TEMPLATE_PARTIAL_SPEC_SPEC; } - + @Override public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() { return ICPPClassTemplatePartialSpecialization.EMPTY_ARRAY; } - + public PDOMCPPClassTemplatePartialSpecializationSpecialization getNextPartial() throws CoreException { long value = getDB().getRecPtr(record + NEXT_PARTIAL); return value != 0 ? new PDOMCPPClassTemplatePartialSpecializationSpecialization(getLinkage(), value) : null; } - + public void setNextPartial(PDOMCPPClassTemplatePartialSpecializationSpecialization partial) throws CoreException { long value = partial != null ? partial.getRecord() : 0; getDB().putRecPtr(record + NEXT_PARTIAL, value); @@ -83,14 +84,14 @@ class PDOMCPPClassTemplatePartialSpecializationSpecialization extends PDOMCPPCla if (type instanceof ITypedef) { return type.isSameType(this); } - + if (type instanceof PDOMNode) { PDOMNode node= (PDOMNode) type; if (node.getPDOM() == getPDOM()) { return node.getRecord() == getRecord(); } } - + if (!(type instanceof ICPPClassTemplatePartialSpecialization)) { return false; } @@ -111,9 +112,9 @@ class PDOMCPPClassTemplatePartialSpecializationSpecialization extends PDOMCPPCla } return fPrimaryTemplate; } - + @Override - public void setArguments(ICPPTemplateArgument[] templateArguments) throws CoreException { + public void setTemplateArguments(ICPPTemplateArgument[] templateArguments) throws CoreException { final Database db = getPDOM().getDB(); long oldRec = db.getRecPtr(record + ARGUMENTS); long rec= PDOMCPPArgumentList.putArguments(this, templateArguments); @@ -139,4 +140,9 @@ class PDOMCPPClassTemplatePartialSpecializationSpecialization extends PDOMCPPCla public IType[] getArguments() { return CPPTemplates.getArguments(getTemplateArguments()); } + + @Override + public ICPPTemplateDefinition getPrimaryTemplate() { + return getPrimaryClassTemplate(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPField.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPField.java index 1e78a2ff851..39acb1702cf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPField.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPField.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2012 QNX Software Systems and others. + * Copyright (c) 2005, 2015 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 @@ -25,9 +25,9 @@ import org.eclipse.core.runtime.CoreException; */ class PDOMCPPField extends PDOMCPPVariable implements ICPPField { - public PDOMCPPField(PDOMLinkage linkage, PDOMNode parent, ICPPField field) + public PDOMCPPField(PDOMLinkage linkage, PDOMNode parent, ICPPField field, boolean setTypeAndValue) throws CoreException { - super(linkage, parent, field); + super(linkage, parent, field, setTypeAndValue); } public PDOMCPPField(PDOMLinkage linkage, long bindingRecord) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFieldInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFieldInstance.java new file mode 100644 index 00000000000..4dd7c4a983a --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFieldInstance.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableInstance; +import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; +import org.eclipse.cdt.internal.core.pdom.dom.IPDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +public class PDOMCPPFieldInstance extends PDOMCPPVariableInstance implements ICPPField { + + public PDOMCPPFieldInstance(PDOMCPPLinkage linkage, PDOMNode parent, ICPPVariableInstance specialization, + IPDOMBinding orig) throws CoreException { + super(linkage, parent, specialization, orig); + } + + public PDOMCPPFieldInstance(PDOMLinkage linkage, long bindingRecord) { + super(linkage, bindingRecord); + } + + @Override + public ICompositeType getCompositeTypeOwner() { + return getClassOwner(); + } + + @Override + public int getVisibility() { + return PDOMCPPAnnotation.getVisibility(getByte(record + PDOMCPPVariableInstance.ANNOTATIONS)); + } + + @Override + public ICPPClassType getClassOwner() { + return (ICPPClassType) getOwner(); + } + + @Override + public int getNodeType() { + return IIndexCPPBindingConstants.CPP_FIELD_INSTANCE; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFieldTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFieldTemplate.java new file mode 100644 index 00000000000..b44c22821e0 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFieldTemplate.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFieldTemplate; +import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +public class PDOMCPPFieldTemplate extends PDOMCPPVariableTemplate implements ICPPFieldTemplate { + + public PDOMCPPFieldTemplate(PDOMCPPLinkage linkage, PDOMNode parent, ICPPFieldTemplate template) + throws CoreException, DOMException { + super(linkage, parent, template); + } + + public PDOMCPPFieldTemplate(PDOMLinkage pdomLinkage, long record) { + super(pdomLinkage, record); + } + + @Override + public int getNodeType() { + return IIndexCPPBindingConstants.CPP_FIELD_TEMPLATE; + } + + @Override + public ICompositeType getCompositeTypeOwner() { + return getClassOwner(); + } + + @Override + public int getVisibility() { + return PDOMCPPAnnotation.getVisibility(getByte(record + PDOMCPPVariableTemplate.ANNOTATIONS)); + } + + @Override + public ICPPClassType getClassOwner() { + return (ICPPClassType) getOwner(); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFieldTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFieldTemplatePartialSpecialization.java new file mode 100644 index 00000000000..9e5df94a0cd --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFieldTemplatePartialSpecialization.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplatePartialSpecialization; +import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +public class PDOMCPPFieldTemplatePartialSpecialization extends PDOMCPPVariableTemplatePartialSpecialization + implements ICPPField { + + public PDOMCPPFieldTemplatePartialSpecialization(PDOMCPPLinkage linkage, PDOMNode parent, + ICPPVariableTemplatePartialSpecialization parSpec, PDOMCPPFieldTemplate pdomPrimary) + throws CoreException, DOMException { + super(linkage, parent, parSpec, pdomPrimary); + } + + public PDOMCPPFieldTemplatePartialSpecialization(PDOMLinkage pdomLinkage, long record) { + super(pdomLinkage, record); + } + + @Override + public int getNodeType() { + return IIndexCPPBindingConstants.CPP_FIELD_TEMPLATE_PARTIAL_SPECIALIZATION; + } + + @Override + public ICompositeType getCompositeTypeOwner() { + return getClassOwner(); + } + + @Override + public int getVisibility() { + return PDOMCPPAnnotation.getVisibility(getByte(record + PDOMCPPVariableTemplate.ANNOTATIONS)); + } + + @Override + public ICPPClassType getClassOwner() { + return (ICPPClassType) getOwner(); + } + + @Override + public ICPPTemplateDefinition getPrimaryTemplate() { + try { + return new PDOMCPPFieldTemplate(getLinkage(), getPrimaryTemplateRec()); + } catch (CoreException e) { + CCorePlugin.log("Failed to load primary template for " + getName(), e); //$NON-NLS-1$ + return null; + } + } + + @Override + public PDOMCPPVariableTemplatePartialSpecialization getNextPartial() throws CoreException { + long rec = getNextPartialRec(); + if (rec == 0) + return null; + return new PDOMCPPFieldTemplatePartialSpecialization(getLinkage(), rec); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index 3fd80fc7c16..be92a6b5646 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -57,6 +57,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFieldTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; @@ -65,8 +66,10 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPPartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; 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.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; @@ -75,6 +78,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective; import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableInstance; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplatePartialSpecialization; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.Util; @@ -210,10 +216,10 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { class ConfigurePartialSpecialization implements Runnable { IPDOMPartialSpecialization partial; - ICPPClassTemplatePartialSpecialization binding; + ICPPPartialSpecialization binding; public ConfigurePartialSpecialization(IPDOMPartialSpecialization partial, - ICPPClassTemplatePartialSpecialization binding) { + ICPPPartialSpecialization binding) { this.partial = partial; this.binding = binding; postProcesses.add(this); @@ -223,7 +229,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { public void run() { try { ICPPTemplateArgument[] args = binding.getTemplateArguments(); - partial.setArguments(args); + partial.setTemplateArguments(args); } catch (CoreException e) { CCorePlugin.log(e); } finally { @@ -376,6 +382,31 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { } } + class ConfigureVariableTemplate implements Runnable { + private final PDOMCPPVariable fTemplate; + private final IPDOMCPPTemplateParameter[] fTemplateParameters; + private final ICPPTemplateParameter[] fOriginalTemplateParameters; + private final IType fOriginalType; + + public ConfigureVariableTemplate(ICPPVariableTemplate original, PDOMCPPVariable template) throws DOMException { + fTemplate = template; + fTemplateParameters= (IPDOMCPPTemplateParameter[]) ((ICPPVariableTemplate)template).getTemplateParameters(); + fOriginalTemplateParameters= original.getTemplateParameters(); + fOriginalType= original.getType(); + postProcesses.add(this); + } + + @Override + public void run() { + for (int i = 0; i < fOriginalTemplateParameters.length; i++) { + final IPDOMCPPTemplateParameter tp = fTemplateParameters[i]; + if (tp != null) + tp.configure(fOriginalTemplateParameters[i]); + } + PDOMCPPVariableTemplate.initData(fTemplate, fOriginalType); + } + } + /** * Adds or returns existing binding for the given name. */ @@ -519,16 +550,26 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { return null; pdomBinding = createSpecialization(parent, pdomSpecialized, binding, point); - } else if (binding instanceof ICPPClassTemplatePartialSpecialization) { - ICPPClassTemplate primary = ((ICPPClassTemplatePartialSpecialization) binding).getPrimaryClassTemplate(); + } else if (binding instanceof ICPPPartialSpecialization) { + ICPPTemplateDefinition primary = ((ICPPPartialSpecialization) binding).getPrimaryTemplate(); PDOMBinding pdomPrimary = addBinding(primary, null); if (pdomPrimary instanceof PDOMCPPClassTemplate) { pdomBinding = new PDOMCPPClassTemplatePartialSpecialization( this, parent, (ICPPClassTemplatePartialSpecialization) binding, (PDOMCPPClassTemplate) pdomPrimary); + } else if (pdomPrimary instanceof PDOMCPPFieldTemplate) { + pdomBinding = new PDOMCPPFieldTemplatePartialSpecialization( + this, parent, (ICPPVariableTemplatePartialSpecialization) binding, (PDOMCPPFieldTemplate) pdomPrimary); + } else if (pdomPrimary instanceof PDOMCPPVariableTemplate) { + pdomBinding = new PDOMCPPVariableTemplatePartialSpecialization( + this, parent, (ICPPVariableTemplatePartialSpecialization) binding, (PDOMCPPVariableTemplate) pdomPrimary); } } else if (binding instanceof ICPPField) { if (parent instanceof PDOMCPPClassType || parent instanceof PDOMCPPClassSpecialization) { - pdomBinding = new PDOMCPPField(this, parent, (ICPPField) binding); + if(binding instanceof ICPPFieldTemplate) { + pdomBinding = new PDOMCPPFieldTemplate(this, parent, (ICPPFieldTemplate) binding); + } else { + pdomBinding = new PDOMCPPField(this, parent, (ICPPField) binding, true); + } // If the field is inside an anonymous struct or union, add it to the parent node as well. if (((ICompositeType) parent).isAnonymous()) { parent2 = parent.getParentNode(); @@ -541,9 +582,11 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { pdomBinding= new PDOMCPPClassTemplate(this, parent, (ICPPClassTemplate) binding); } else if (binding instanceof ICPPClassType) { pdomBinding= new PDOMCPPClassType(this, parent, (ICPPClassType) binding); + } else if (binding instanceof ICPPVariableTemplate) { + pdomBinding = new PDOMCPPVariableTemplate(this, parent, (ICPPVariableTemplate) binding); } else if (binding instanceof ICPPVariable) { ICPPVariable var= (ICPPVariable) binding; - pdomBinding = new PDOMCPPVariable(this, parent, var); + pdomBinding = new PDOMCPPVariable(this, parent, var, true); } else if (binding instanceof ICPPFunctionTemplate) { if (binding instanceof ICPPConstructor) { pdomBinding= new PDOMCPPConstructorTemplate(this, parent, (ICPPConstructor) binding, point); @@ -607,9 +650,9 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { while (binding instanceof ICPPSpecialization) { binding = ((ICPPSpecialization) binding).getSpecializedBinding(); } - if (binding instanceof ICPPClassTemplatePartialSpecialization) { - // A class template partial specialization inherits the visibility of its primary class template. - binding = ((ICPPClassTemplatePartialSpecialization) binding).getPrimaryClassTemplate(); + if (binding instanceof ICPPPartialSpecialization) { + // A template partial specialization inherits the visibility of its primary template. + binding = ((ICPPPartialSpecialization) binding).getPrimaryTemplate(); } if (binding instanceof ICPPAliasTemplateInstance) { binding = ((ICPPAliasTemplateInstance) binding).getTemplateDefinition(); @@ -669,6 +712,10 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { result= new PDOMCPPFunctionInstance(this, parent, (ICPPFunction) special, orig, point); } else if (special instanceof ICPPClassType && orig instanceof ICPPClassType) { result= new PDOMCPPClassInstance(this, parent, (ICPPClassType) special, orig); + } else if (special instanceof ICPPField && orig instanceof ICPPField) { + result = new PDOMCPPFieldInstance(this, parent, (ICPPVariableInstance) special, orig); + } else if (special instanceof ICPPVariable && orig instanceof ICPPVariable) { + result= new PDOMCPPVariableInstance(this, parent, (ICPPVariableInstance) special, orig); } } else if (special instanceof ICPPField) { result= new PDOMCPPFieldSpecialization(this, parent, (ICPPField) special, orig); @@ -761,6 +808,10 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { return CPP_FUNCTION_INSTANCE; } else if (binding instanceof ICPPClassType) { return CPP_CLASS_INSTANCE; + } else if (binding instanceof ICPPField) { + return CPP_FIELD_INSTANCE; + } else if (binding instanceof ICPPVariable) { + return CPP_VARIABLE_INSTANCE; } } else if (binding instanceof ICPPClassTemplatePartialSpecialization) { return CPP_CLASS_TEMPLATE_PARTIAL_SPEC_SPEC; @@ -789,6 +840,12 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { } } else if (binding instanceof ICPPClassTemplatePartialSpecialization) { return CPP_CLASS_TEMPLATE_PARTIAL_SPEC; + } else if (binding instanceof ICPPVariableTemplatePartialSpecialization) { + if(binding instanceof ICPPField) { + return CPP_FIELD_TEMPLATE_PARTIAL_SPECIALIZATION; + } else { + return CPP_VARIABLE_TEMPLATE_PARTIAL_SPECIALIZATION; + } } else if (binding instanceof ICPPTemplateParameter) { if (binding instanceof ICPPTemplateTypeParameter) { return CPP_TEMPLATE_TYPE_PARAMETER; @@ -796,9 +853,13 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { return CPP_TEMPLATE_TEMPLATE_PARAMETER; else if (binding instanceof ICPPTemplateNonTypeParameter) return CPP_TEMPLATE_NON_TYPE_PARAMETER; + } else if (binding instanceof ICPPFieldTemplate) { + return CPP_FIELD_TEMPLATE; } else if (binding instanceof ICPPField) { // this must be before variables return CPPFIELD; + } else if (binding instanceof ICPPVariableTemplate) { + return CPP_VARIABLE_TEMPLATE; } else if (binding instanceof ICPPVariable) { return CPPVARIABLE; } else if (binding instanceof ICPPFunctionTemplate) { @@ -1064,6 +1125,18 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { return new PDOMCPPEnumerationSpecialization(this, record); case CPP_ENUMERATOR_SPECIALIZATION: return new PDOMCPPEnumeratorSpecialization(this, record); + case CPP_VARIABLE_TEMPLATE: + return new PDOMCPPVariableTemplate(this, record); + case CPP_FIELD_TEMPLATE: + return new PDOMCPPFieldTemplate(this, record); + case CPP_VARIABLE_INSTANCE: + return new PDOMCPPVariableInstance(this, record); + case CPP_FIELD_INSTANCE: + return new PDOMCPPFieldInstance(this, record); + case CPP_VARIABLE_TEMPLATE_PARTIAL_SPECIALIZATION: + return new PDOMCPPVariableTemplatePartialSpecialization(this, record); + case CPP_FIELD_TEMPLATE_PARTIAL_SPECIALIZATION: + return new PDOMCPPFieldTemplatePartialSpecialization(this, record); } assert false : "nodeid= " + nodeType; //$NON-NLS-1$ return null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariable.java index ad9199e3cd7..a89ab4ad5e8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariable.java @@ -40,14 +40,16 @@ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable { @SuppressWarnings("hiding") protected static final int RECORD_SIZE = ANNOTATIONS + 1; - public PDOMCPPVariable(PDOMLinkage linkage, PDOMNode parent, IVariable variable) throws CoreException { + public PDOMCPPVariable(PDOMLinkage linkage, PDOMNode parent, IVariable variable, boolean setTypeAndValue) throws CoreException { super(linkage, parent, variable.getNameCharArray()); // Find the type record Database db = getDB(); - setType(parent.getLinkage(), variable.getType()); db.putByte(record + ANNOTATIONS, encodeFlags(variable)); - setValue(db, variable); + if (setTypeAndValue) { + setType(parent.getLinkage(), variable.getType()); + setValue(db, variable); + } } private void setValue(Database db, IVariable variable) throws CoreException { @@ -67,8 +69,7 @@ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable { } } - - private void setType(final PDOMLinkage linkage, IType newType) throws CoreException { + protected void setType(final PDOMLinkage linkage, IType newType) throws CoreException { linkage.storeType(record+TYPE_OFFSET, newType); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariableInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariableInstance.java new file mode 100644 index 00000000000..fd1ab1d1d21 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariableInstance.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.ISemanticProblem; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +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.ICPPVariableInstance; +import org.eclipse.cdt.internal.core.dom.parser.ProblemType; +import org.eclipse.cdt.internal.core.dom.parser.Value; +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.db.Database; +import org.eclipse.cdt.internal.core.pdom.dom.IPDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCAnnotation; +import org.eclipse.core.runtime.CoreException; + +public class PDOMCPPVariableInstance extends PDOMCPPSpecialization implements ICPPVariableInstance { + private static final int TEMPLATE_ARGUMENTS = PDOMCPPSpecialization.RECORD_SIZE + 0; + private static final int TYPE = TEMPLATE_ARGUMENTS + Database.PTR_SIZE; + private static final int VALUE = TYPE + Database.TYPE_SIZE; + protected static final int ANNOTATIONS = VALUE + Database.VALUE_SIZE; + + @SuppressWarnings("hiding") + protected static final int RECORD_SIZE = ANNOTATIONS + 1; + + private IType type; + + public PDOMCPPVariableInstance(PDOMCPPLinkage linkage, PDOMNode parent, + ICPPVariableInstance specialization, IPDOMBinding orig) throws CoreException { + super(linkage, parent, specialization, orig); + + final long argListRec = PDOMCPPArgumentList.putArguments(this, specialization.getTemplateArguments()); + final Database db = getDB(); + db.putRecPtr(record + TEMPLATE_ARGUMENTS, argListRec); + getLinkage().storeType(record + TYPE, specialization.getType()); + getLinkage().storeValue(record + VALUE, specialization.getInitialValue()); + db.putByte(record + ANNOTATIONS, PDOMCPPAnnotation.encodeAnnotation(specialization)); + } + + public PDOMCPPVariableInstance(PDOMLinkage linkage, long bindingRecord) { + super(linkage, bindingRecord); + } + + @Override + public ICPPTemplateDefinition getTemplateDefinition() { + return (ICPPTemplateDefinition) getSpecializedBinding(); + } + + @Override + public ICPPTemplateArgument[] getTemplateArguments() { + try { + final long rec = getPDOM().getDB().getRecPtr(record + TEMPLATE_ARGUMENTS); + return PDOMCPPArgumentList.getArguments(this, rec); + } catch (CoreException e) { + CCorePlugin.log(e); + return ICPPTemplateArgument.EMPTY_ARGUMENTS; + } + } + + @Override + public boolean isExplicitSpecialization() { + try { + return hasDeclaration(); + } catch (CoreException e) { + return false; + } + } + + @Override + @Deprecated + public IType[] getArguments() { + return CPPTemplates.getArguments(getTemplateArguments()); + } + + @Override + public boolean isMutable() { + return false; + } + + @Override + public boolean isAuto() { + return getBit(getByte(record + ANNOTATIONS), PDOMCAnnotation.AUTO_OFFSET); + } + + @Override + public boolean isExtern() { + return getBit(getByte(record + ANNOTATIONS), PDOMCAnnotation.EXTERN_OFFSET); + } + + @Override + public boolean isExternC() { + return getBit(getByte(record + ANNOTATIONS), PDOMCPPAnnotation.EXTERN_C_OFFSET); + } + + @Override + public boolean isRegister() { + return getBit(getByte(record + ANNOTATIONS), PDOMCAnnotation.REGISTER_OFFSET); + } + + @Override + public boolean isStatic() { + return getBit(getByte(record + ANNOTATIONS), PDOMCAnnotation.STATIC_OFFSET); + } + + @Override + public IType getType() { + if (type == null) { + try { + type = getLinkage().loadType(record + TYPE); + } catch (CoreException e) { + CCorePlugin.log(e); + type = new ProblemType(ISemanticProblem.TYPE_NOT_PERSISTED); + } + } + return type; + } + + @Override + public IValue getInitialValue() { + try { + return getLinkage().loadValue(record + VALUE); + } catch (CoreException e) { + CCorePlugin.log(e); + return Value.UNKNOWN; + } + } + + @Override + protected int getRecordSize() { + return RECORD_SIZE; + } + + @Override + public int getNodeType() { + return IIndexCPPBindingConstants.CPP_VARIABLE_INSTANCE; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariableTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariableTemplate.java new file mode 100644 index 00000000000..a11c35e793c --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariableTemplate.java @@ -0,0 +1,172 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import java.util.ArrayList; + +import org.eclipse.cdt.core.CCorePlugin; +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.ICPPPartialSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplatePartialSpecialization; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache; +import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; +import org.eclipse.cdt.internal.core.pdom.db.Database; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +public class PDOMCPPVariableTemplate extends PDOMCPPVariable implements ICPPVariableTemplate, ICPPInstanceCache, IPDOMCPPTemplateParameterOwner { + private static final int TEMPLATE_PARAMS = PDOMCPPVariable.RECORD_SIZE; + private static final int FIRST_PARTIAL = TEMPLATE_PARAMS + Database.PTR_SIZE; + + @SuppressWarnings("hiding") + protected static final int RECORD_SIZE = FIRST_PARTIAL + Database.PTR_SIZE; + + private volatile IPDOMCPPTemplateParameter[] params; + + public PDOMCPPVariableTemplate(PDOMCPPLinkage linkage, PDOMNode parent, ICPPVariableTemplate template) + throws CoreException, DOMException { + super(linkage, parent, template, false); + + final ICPPTemplateParameter[] origParams = template.getTemplateParameters(); + params = PDOMTemplateParameterArray.createPDOMTemplateParameters(linkage, this, origParams); + + final Database db = getDB(); + long rec = PDOMTemplateParameterArray.putArray(db, params); + db.putRecPtr(record + TEMPLATE_PARAMS, rec); + + linkage.new ConfigureVariableTemplate(template, this); + } + + public PDOMCPPVariableTemplate(PDOMLinkage linkage, long record) { + super(linkage, record); + } + + @Override + public void update(PDOMLinkage linkage, IBinding name, IASTNode point) { + // No support for updating templates, yet. + } + + @Override + public IPDOMCPPTemplateParameter[] getTemplateParameters() { + if (params == null) { + try { + long rec= getDB().getRecPtr(record + TEMPLATE_PARAMS); + if (rec == 0) { + params= IPDOMCPPTemplateParameter.EMPTY_ARRAY; + } else { + params= PDOMTemplateParameterArray.getArray(this, rec); + } + } catch (CoreException e) { + CCorePlugin.log(e); + params = IPDOMCPPTemplateParameter.EMPTY_ARRAY; + } + } + return params; + } + + @Override + public int getNodeType() { + return IIndexCPPBindingConstants.CPP_VARIABLE_TEMPLATE; + } + + @Override + protected int getRecordSize() { + return RECORD_SIZE; + } + + public static void initData(PDOMCPPVariable binding, IType fOriginalType) { + try { + binding.setType(binding.getLinkage(), fOriginalType); + } catch (CoreException e) { + CCorePlugin.log(e); + } + } + + @Override + public ICPPPartialSpecialization[] getPartialSpecializations() { + try { + ArrayList partials = new ArrayList<>(); + for (PDOMCPPVariableTemplatePartialSpecialization partial = getFirstPartial(); partial != null; + partial = partial.getNextPartial()) { + partials.add(partial); + } + + return partials.toArray(new ICPPVariableTemplatePartialSpecialization[partials.size()]); + } catch (CoreException e) { + CCorePlugin.log(e); + return ICPPVariableTemplatePartialSpecialization.EMPTY_ARRAY; + } + } + + @Override + public ICPPTemplateInstance getInstance(ICPPTemplateArgument[] arguments) { + return PDOMInstanceCache.getCache(this).getInstance(arguments); + } + + @Override + public void addInstance(ICPPTemplateArgument[] arguments, ICPPTemplateInstance instance) { + PDOMInstanceCache.getCache(this).addInstance(arguments, instance); + } + + @Override + public ICPPTemplateInstance[] getAllInstances() { + return PDOMInstanceCache.getCache(this).getAllInstances(); + } + + private PDOMCPPVariableTemplatePartialSpecialization getFirstPartial() throws CoreException { + long value = getDB().getRecPtr(record + FIRST_PARTIAL); + if (this instanceof PDOMCPPFieldTemplate) + return value != 0 ? new PDOMCPPFieldTemplatePartialSpecialization(getLinkage(), value) : null; + else + return value != 0 ? new PDOMCPPVariableTemplatePartialSpecialization(getLinkage(), value) : null; + } + + public void addPartial(PDOMCPPVariableTemplatePartialSpecialization partial) throws CoreException { + PDOMCPPVariableTemplatePartialSpecialization first = getFirstPartial(); + partial.setNextPartial(first); + getDB().putRecPtr(record + FIRST_PARTIAL, partial.getRecord()); + } + + @Override + public ICPPTemplateParameter adaptTemplateParameter(ICPPTemplateParameter param) { + // Template parameters are identified by their position in the parameter list. + int pos = param.getParameterPosition(); + ICPPTemplateParameter[] pars = getTemplateParameters(); + + if (pars == null || pos >= pars.length) + return null; + + ICPPTemplateParameter result= pars[pos]; + if (param instanceof ICPPTemplateTypeParameter) { + if (result instanceof ICPPTemplateTypeParameter) + return result; + } else if (param instanceof ICPPTemplateNonTypeParameter) { + if (result instanceof ICPPTemplateNonTypeParameter) + return result; + } else if (param instanceof ICPPTemplateTemplateParameter) { + if (result instanceof ICPPTemplateTemplateParameter) + return result; + } + return null; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariableTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariableTemplatePartialSpecialization.java new file mode 100644 index 00000000000..37ce475c296 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariableTemplatePartialSpecialization.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2015 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences. + * 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lukas Wegmann (IFS) - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.DOMException; +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.ICPPVariableTemplatePartialSpecialization; +import org.eclipse.cdt.internal.core.Util; +import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; +import org.eclipse.cdt.internal.core.index.IndexCPPSignatureUtil; +import org.eclipse.cdt.internal.core.pdom.db.Database; +import org.eclipse.cdt.internal.core.pdom.dom.IPDOMOverloader; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +public class PDOMCPPVariableTemplatePartialSpecialization extends PDOMCPPVariableTemplate + implements ICPPVariableTemplatePartialSpecialization, IPDOMPartialSpecialization, IPDOMOverloader { + private static final int ARGUMENTS = PDOMCPPVariableTemplate.RECORD_SIZE + 0; + private static final int SIGNATURE_HASH = ARGUMENTS + Database.PTR_SIZE; + private static final int PRIMARY = SIGNATURE_HASH + Database.INT_SIZE; + private static final int NEXT_PARTIAL = PRIMARY + Database.PTR_SIZE; + @SuppressWarnings("hiding") + protected static final int RECORD_SIZE = NEXT_PARTIAL + Database.PTR_SIZE; + + public PDOMCPPVariableTemplatePartialSpecialization(PDOMCPPLinkage linkage, PDOMNode parent, + ICPPVariableTemplatePartialSpecialization parSpec, PDOMCPPVariableTemplate primary) + throws CoreException, DOMException { + super(linkage, parent, parSpec); + getDB().putRecPtr(record + PRIMARY, primary.getRecord()); + primary.addPartial(this); + + try { + Integer sigHash = IndexCPPSignatureUtil.getSignatureHash(parSpec); + getDB().putInt(record + SIGNATURE_HASH, sigHash != null ? sigHash.intValue() : 0); + } catch (DOMException e) { + throw new CoreException(Util.createStatus(e)); + } + + linkage.new ConfigurePartialSpecialization(this, parSpec); + } + + public PDOMCPPVariableTemplatePartialSpecialization(PDOMLinkage pdomLinkage, long record) { + super(pdomLinkage, record); + } + + @Override + public int getNodeType() { + return IIndexCPPBindingConstants.CPP_VARIABLE_TEMPLATE_PARTIAL_SPECIALIZATION; + } + + @Override + public ICPPTemplateDefinition getPrimaryTemplate() { + try { + return new PDOMCPPVariableTemplate(getLinkage(), getPrimaryTemplateRec()); + } catch (CoreException e) { + CCorePlugin.log("Failed to load primary template for " + getName(), e); //$NON-NLS-1$ + return null; + } + } + + protected final long getPrimaryTemplateRec() throws CoreException { + return getDB().getRecPtr(record + PRIMARY); + } + + @Override + public void setTemplateArguments(ICPPTemplateArgument[] args) throws CoreException { + final Database db = getPDOM().getDB(); + long oldRec = db.getRecPtr(record + ARGUMENTS); + long rec= PDOMCPPArgumentList.putArguments(this, args); + db.putRecPtr(record + ARGUMENTS, rec); + if (oldRec != 0) { + PDOMCPPArgumentList.clearArguments(this, oldRec); + } + } + + @Override + public ICPPTemplateArgument[] getTemplateArguments() { + try { + return PDOMCPPArgumentList.getArguments(this, getPDOM().getDB().getRecPtr(record + ARGUMENTS)); + } catch (CoreException e) { + CCorePlugin.log("Failed to load template arguments for " + getName(), e); //$NON-NLS-1$ + return ICPPTemplateArgument.EMPTY_ARGUMENTS; + } + } + + @Override + public int getSignatureHash() throws CoreException { + return getDB().getInt(record + SIGNATURE_HASH); + } + + public PDOMCPPVariableTemplatePartialSpecialization getNextPartial() throws CoreException { + long rec = getNextPartialRec(); + if (rec == 0) + return null; + return new PDOMCPPVariableTemplatePartialSpecialization(getLinkage(), rec); + } + + protected final long getNextPartialRec() throws CoreException { + return getDB().getRecPtr(record + NEXT_PARTIAL); + } + + public void setNextPartial(PDOMCPPVariableTemplatePartialSpecialization partial) throws CoreException { + long rec = partial != null ? partial.getRecord() : 0; + getDB().putRecPtr(record + NEXT_PARTIAL, rec); + } +}