From 733d884bc4dd27305c7d91391f7b7cc7564caf91 Mon Sep 17 00:00:00 2001 From: Marco Stornelli Date: Wed, 1 Apr 2020 10:48:25 +0200 Subject: [PATCH] Bug 534420 - Add support for nodiscard attribute for enum types Change-Id: Ib555c5d3f37c1159208a971affc7d31dc0ca3220 --- .../core/parser/tests/ast2/AST2CPPTests.java | 17 ++++++++++++++++ .../internal/pdom/tests/EnumerationTests.java | 11 +++++++++- .../pdomtests/enumerationTests/enumTest.cpp | 6 ++++++ .../cdt/core/dom/ast/cpp/ICPPEnumeration.java | 6 ++++++ .../core/dom/parser/cpp/CPPEnumeration.java | 20 +++++++++++++++++++ .../cpp/CPPEnumerationSpecialization.java | 5 +++++ .../cpp/CompositeCPPEnumeration.java | 5 +++++ .../eclipse/cdt/internal/core/pdom/PDOM.java | 7 ++++--- .../core/pdom/dom/PDOMASTAdapter.java | 5 +++++ .../core/pdom/dom/cpp/PDOMCPPEnumeration.java | 13 +++++++++++- .../cpp/PDOMCPPEnumerationSpecialization.java | 13 +++++++++++- 11 files changed, 102 insertions(+), 6 deletions(-) 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 c7f0d1a7af5..d88aae9b02b 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 @@ -13501,4 +13501,21 @@ public class AST2CPPTests extends AST2CPPTestBase { assertTrue(((CPPClassInstance) var2Spec.getType()).isNoDiscard()); assertTrue(((CPPClassInstance) var3Spec.getType()).isNoDiscard()); } + + // enum [[nodiscard]] hue { red, blue, green }; + // enum fruit { apple, banana }; + // enum hue col; + // enum fruit f; + public void testEnumerations_Bug534420() throws Exception { + IASTTranslationUnit tu = parse(getAboveComment(), CPP); + NameCollector collector = new NameCollector(); + tu.accept(collector); + + ICPPEnumeration hue = (ICPPEnumeration) collector.getName(0).resolveBinding(); + ICPPEnumeration fruit = (ICPPEnumeration) collector.getName(4).resolveBinding(); + ICPPVariable col = (ICPPVariable) collector.getName(8).resolveBinding(); + ICPPVariable f = (ICPPVariable) collector.getName(10).resolveBinding(); + assertTrue(((ICPPEnumeration) col.getType()).isNoDiscard()); + assertFalse(((ICPPEnumeration) f.getType()).isNoDiscard()); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/EnumerationTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/EnumerationTests.java index c5a195530de..abac00004b3 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/EnumerationTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/EnumerationTests.java @@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.core.model.ICProject; @@ -101,7 +102,8 @@ public class EnumerationTests extends PDOMTestBase { Pattern pattern = Pattern.compile("TestCPPEnum"); IBinding[] bindings = pdom.findBindings(pattern, false, IndexFilter.ALL, new NullProgressMonitor()); assertEquals(1, bindings.length); - IEnumeration enumeration = (IEnumeration) bindings[0]; + ICPPEnumeration enumeration = (ICPPEnumeration) bindings[0]; + assertFalse(enumeration.isNoDiscard()); assertEquals("TestCPPEnum", enumeration.getName()); IEnumerator[] enumerators = enumeration.getEnumerators(); assertEquals(3, enumerators.length); @@ -133,5 +135,12 @@ public class EnumerationTests extends PDOMTestBase { assertEquals(1, aRefs.length); loc = aRefs[0].getFileLocation(); assertEquals(offset("enumTest.cpp", "cppa;"), loc.getNodeOffset()); + + // Check bindings no discard + pattern = Pattern.compile("TestCPPEnumNoDis"); + bindings = pdom.findBindings(pattern, false, IndexFilter.ALL, new NullProgressMonitor()); + assertEquals(1, bindings.length); + enumeration = (ICPPEnumeration) bindings[0]; + assertTrue(enumeration.isNoDiscard()); } } diff --git a/core/org.eclipse.cdt.core.tests/resources/pdomtests/enumerationTests/enumTest.cpp b/core/org.eclipse.cdt.core.tests/resources/pdomtests/enumerationTests/enumTest.cpp index 83d528fd48b..3d470c8d298 100644 --- a/core/org.eclipse.cdt.core.tests/resources/pdomtests/enumerationTests/enumTest.cpp +++ b/core/org.eclipse.cdt.core.tests/resources/pdomtests/enumerationTests/enumTest.cpp @@ -7,3 +7,9 @@ enum TestCPPEnum { TestCPPEnum test() { return cppa; } + +enum [[nodiscard]] TestCPPEnumNoDis { + e1, + e2, + e3 +}; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPEnumeration.java index 3379fcf428b..0a6d5c1bd43 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPEnumeration.java @@ -43,4 +43,10 @@ public interface ICPPEnumeration extends IEnumeration, ICPPBinding { * will be returned. */ ICPPScope asScope(); + + /** + * Returns weather the enum is marked as 'nodiscard' + * @since 6.12 + */ + boolean isNoDiscard(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java index 82db1bb7345..abb80fb5044 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java @@ -42,6 +42,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.core.parser.util.AttributeUtil; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; @@ -90,6 +91,11 @@ public class CPPEnumeration extends PlatformObject implements ICPPEnumeration, I public ICPPScope asScope() { return this; } + + @Override + public boolean isNoDiscard() { + return false; + } } private final boolean fIsScoped; @@ -339,4 +345,18 @@ public class CPPEnumeration extends PlatformObject implements ICPPEnumeration, I node.accept(action); } } + + @Override + public boolean isNoDiscard() { + findDefinition(); + IASTName def = getDefinition(); + if (def == null) { + ICPPEnumeration indexBinding = getIndexBinding(); + if (indexBinding != null) { + return indexBinding.isNoDiscard(); + } + def = getADeclaration(); + } + return AttributeUtil.hasNodiscardAttribute(((ICPPASTEnumerationSpecifier) def.getParent())); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java index 4bb3faa93ec..5f0d7d90746 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java @@ -162,4 +162,9 @@ public class CPPEnumerationSpecialization extends CPPSpecialization implements I } return enumerator; } + + @Override + public boolean isNoDiscard() { + return getSpecializedBinding().isNoDiscard(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeration.java index 73ec8ab5905..bb7631be278 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeration.java @@ -76,4 +76,9 @@ class CompositeCPPEnumeration extends CompositeCPPBinding implements ICPPEnumera public ICPPScope asScope() { return new CompositeCPPEnumScope(cf, rbinding); } + + @Override + public boolean isNoDiscard() { + return ((ICPPEnumeration) rbinding).isNoDiscard(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index 6d9fc2f4028..d20d37e90bd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -306,10 +306,11 @@ public class PDOM extends PlatformObject implements IPDOM { * CDT 9.12 development (version not supported on the 9.11.x branch) * 216.0 - Added nodiscard function information, bug 534420 * 217.0 - Added nodiscard class/struct information, bug 534420 + * 218.0 - Added nodiscard enums information, bug 534420 */ - private static final int MIN_SUPPORTED_VERSION = version(217, 0); - private static final int MAX_SUPPORTED_VERSION = version(217, Short.MAX_VALUE); - private static final int DEFAULT_VERSION = version(217, 0); + private static final int MIN_SUPPORTED_VERSION = version(218, 0); + private static final int MAX_SUPPORTED_VERSION = version(218, Short.MAX_VALUE); + private static final int DEFAULT_VERSION = version(218, 0); private static int version(int major, int minor) { return (major << 16) + minor; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java index 94cc7f062ee..97a7ed6f697 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java @@ -578,6 +578,11 @@ public class PDOMASTAdapter { public ICPPScope asScope() { return ((ICPPEnumeration) fDelegate).asScope(); } + + @Override + public boolean isNoDiscard() { + return ((ICPPEnumeration) fDelegate).isNoDiscard(); + } } private static class AnonymousClassType extends AnonymousCPPBinding implements ICPPClassType { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java index dc59848d72c..6df692dc331 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java @@ -49,7 +49,8 @@ class PDOMCPPEnumeration extends PDOMCPPBinding implements IPDOMCPPEnumType, IPD private static final int OFFSET_MIN_VALUE = OFFSET_ENUMERATOR_LIST + Database.PTR_SIZE; private static final int OFFSET_MAX_VALUE = OFFSET_MIN_VALUE + 8; private static final int OFFSET_FIXED_TYPE = OFFSET_MAX_VALUE + 8; - private static final int OFFSET_FLAGS = OFFSET_FIXED_TYPE + Database.TYPE_SIZE; + private static final int OFFSET_NO_DISCARD = OFFSET_FIXED_TYPE + 8; + private static final int OFFSET_FLAGS = OFFSET_NO_DISCARD + Database.TYPE_SIZE; @SuppressWarnings("hiding") protected static final int RECORD_SIZE = OFFSET_FLAGS + 1; @@ -76,6 +77,7 @@ class PDOMCPPEnumeration extends PDOMCPPBinding implements IPDOMCPPEnumType, IPD private void storeProperties(ICPPEnumeration enumeration) throws CoreException { final Database db = getDB(); db.putByte(record + OFFSET_FLAGS, enumeration.isScoped() ? (byte) 1 : (byte) 0); + db.putByte(record + OFFSET_NO_DISCARD, enumeration.isNoDiscard() ? (byte) 1 : (byte) 0); getLinkage().storeType(record + OFFSET_FIXED_TYPE, enumeration.getFixedType()); @@ -194,6 +196,15 @@ class PDOMCPPEnumeration extends PDOMCPPBinding implements IPDOMCPPEnumType, IPD } } + @Override + public boolean isNoDiscard() { + try { + return getDB().getByte(record + OFFSET_NO_DISCARD) != 0; + } catch (CoreException e) { + return false; + } + } + @Override public IType getFixedType() { if (fFixedType == ProblemBinding.NOT_INITIALIZED) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java index 3bda300c388..2208f786de3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java @@ -51,7 +51,8 @@ class PDOMCPPEnumerationSpecialization extends PDOMCPPSpecialization private static final int OFFSET_MIN_VALUE = OFFSET_ENUMERATOR_LIST + Database.PTR_SIZE; private static final int OFFSET_MAX_VALUE = OFFSET_MIN_VALUE + 8; private static final int OFFSET_FIXED_TYPE = OFFSET_MAX_VALUE + 8; - private static final int OFFSET_FLAGS = OFFSET_FIXED_TYPE + Database.TYPE_SIZE; + private static final int OFFSET_NO_DISCARD = OFFSET_FIXED_TYPE + 8; + private static final int OFFSET_FLAGS = OFFSET_NO_DISCARD + Database.TYPE_SIZE; @SuppressWarnings("hiding") protected static final int RECORD_SIZE = OFFSET_FLAGS + 1; @@ -84,6 +85,7 @@ class PDOMCPPEnumerationSpecialization extends PDOMCPPSpecialization private void storeProperties(ICPPEnumeration enumeration) throws CoreException { final Database db = getDB(); db.putByte(record + OFFSET_FLAGS, enumeration.isScoped() ? (byte) 1 : (byte) 0); + db.putByte(record + OFFSET_NO_DISCARD, enumeration.isNoDiscard() ? (byte) 1 : (byte) 0); getLinkage().storeType(record + OFFSET_FIXED_TYPE, enumeration.getFixedType()); @@ -202,6 +204,15 @@ class PDOMCPPEnumerationSpecialization extends PDOMCPPSpecialization } } + @Override + public boolean isNoDiscard() { + try { + return getDB().getByte(record + OFFSET_NO_DISCARD) != 0; + } catch (CoreException e) { + return false; + } + } + @Override public IType getFixedType() { if (fFixedType == ProblemBinding.NOT_INITIALIZED) {