diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index d88aae9b02b..2e0fd4a2d7d 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -13502,6 +13502,51 @@ public class AST2CPPTests extends AST2CPPTestBase { assertTrue(((CPPClassInstance) var3Spec.getType()).isNoDiscard()); } + //template + //struct Foo {}; + //template + //struct Foo final {}; + //template <> + //struct Foo final {}; + // + //Foo var1; + //Foo var2; + //Foo var3; + public void testFinalTemplateSpecialization_Bug561631() throws Exception { + String code = getAboveComment(); + parseAndCheckBindings(code); + + BindingAssertionHelper bh = new AST2AssertionHelper(code, true); + + CPPClassTemplate structFoo = bh.assertNonProblem("Foo {", 3); + assertFalse(structFoo.isFinal()); + IASTNode fooDefinitionName = structFoo.getDefinition(); + IASTNode fooDefinition = fooDefinitionName.getParent(); + assertInstance(fooDefinition, ICPPASTCompositeTypeSpecifier.class); + assertFalse((((ICPPASTCompositeTypeSpecifier) fooDefinition)).isFinal()); + + CPPClassTemplatePartialSpecialization structSpec = bh.assertNonProblem("Foo", 7); + assertTrue(structSpec.isFinal()); + IASTNode specDefinitionName = structSpec.getDefinition(); + IASTNode specDefinition = specDefinitionName.getParent(); + assertInstance(specDefinition, ICPPASTCompositeTypeSpecifier.class); + assertTrue((((ICPPASTCompositeTypeSpecifier) specDefinition)).isFinal()); + + CPPClassInstance structFullSpec = bh.assertNonProblem("Foo", 8); + assertTrue(structSpec.isFinal()); + IASTNode specFullDefinitionName = structFullSpec.getDefinition(); + IASTNode specFullDefinition = specFullDefinitionName.getParent(); + assertInstance(specFullDefinition, ICPPASTCompositeTypeSpecifier.class); + assertTrue((((ICPPASTCompositeTypeSpecifier) specFullDefinition)).isFinal()); + + CPPVariable var1Base = bh.assertNonProblem("var1", 4); + CPPVariable var2Spec = bh.assertNonProblem("var2", 4); + CPPVariable var3Spec = bh.assertNonProblem("var3", 4); + assertFalse(((CPPClassInstance) var1Base.getType()).isFinal()); + assertTrue(((CPPClassInstance) var2Spec.getType()).isFinal()); + assertTrue(((CPPClassInstance) var3Spec.getType()).isFinal()); + } + // enum [[nodiscard]] hue { red, blue, green }; // enum fruit { apple, banana }; // enum hue col; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java index e9d866e4d9a..db1d5b2455d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java @@ -508,6 +508,10 @@ public class CPPClassSpecialization extends CPPSpecialization if (typeSpecifier != null) { return typeSpecifier.isFinal(); } + ICPPClassType clazz = getSpecializedBinding(); + if (clazz != null) { + return clazz.isFinal(); + } return false; }