From 7831931f3a328fe4672c06445b45496d31e53fa3 Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Sat, 15 Sep 2018 14:14:04 -0400 Subject: Bug 539052 - Add support for __is_constructible type trait intrinsic Change-Id: I582881808e19342bf55d62d6002365c3733ebf31 --- .../cdt/core/parser/tests/ast2/AST2CPPTests.java | 12 ++++++++++++ .../eclipse/cdt/core/testplugin/util/BaseTestCase.java | 2 +- .../core/dom/ast/cpp/ICPPASTNaryTypeIdExpression.java | 3 ++- .../parser/cpp/GPPScannerExtensionConfiguration.java | 9 +++++++++ .../parser/org/eclipse/cdt/core/parser/GCCKeywords.java | 4 ++++ .../parser/org/eclipse/cdt/core/parser/IGCCToken.java | 2 ++ .../cdt/internal/core/dom/parser/ValueFactory.java | 6 ++++-- .../core/dom/parser/cpp/GNUCPPSourceParser.java | 4 ++++ .../core/dom/parser/cpp/semantics/EvalNaryTypeId.java | 1 + .../core/dom/parser/cpp/semantics/TypeTraits.java | 17 +++++++++++++---- .../cdt/internal/core/parser/scanner/CPreprocessor.java | 2 +- 11 files changed, 53 insertions(+), 9 deletions(-) (limited to 'core') 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 bbc12d656b1..f685500cbea 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 @@ -12677,6 +12677,18 @@ public class AST2CPPTests extends AST2CPPTestBase { helper.assertVariableValue("waldo5", 0); } + // template + // struct pair { + // pair(); + // pair(T, U); + // }; + // + // constexpr bool waldo = __is_constructible(pair, pair&&); + public void testIsConstructible_539052() throws Exception { + BindingAssertionHelper helper = getAssertionHelper(); + helper.assertVariableValue("waldo", 1); + } + // namespace x { // void foo(); // } diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java index 911a9026579..f5a23f7641d 100644 --- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java @@ -70,7 +70,7 @@ public class BaseTestCase extends TestCase { * The GCC version to emulate when running tests. * We emulate the latest version whose extensions we support. */ - protected static final int GCC_MAJOR_VERSION_FOR_TESTS = 5; + protected static final int GCC_MAJOR_VERSION_FOR_TESTS = 8; protected static final int GCC_MINOR_VERSION_FOR_TESTS = 1; /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTNaryTypeIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTNaryTypeIdExpression.java index 3b73a099bd1..27dd77d2b73 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTNaryTypeIdExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTNaryTypeIdExpression.java @@ -24,7 +24,8 @@ public interface ICPPASTNaryTypeIdExpression extends ICPPASTExpression { public static final ASTNodeProperty OPERAND = new ASTNodeProperty("ICPPASTNaryTypeIdExpression.OPERAND [IASTTypeId]"); //$NON-NLS-1$ public static enum Operator { - __is_trivially_constructible + __is_trivially_constructible, + /** @since 6.6 */ __is_constructible } /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java index 76f6fee4fa5..5e8671d94e8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java @@ -34,12 +34,14 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu private static final int VERSION_4_6 = version(4, 6); private static final int VERSION_4_7 = version(4, 7); private static final int VERSION_5_0 = version(5, 0); + private static final int VERSION_8_0 = version(8, 0); private static GPPScannerExtensionConfiguration CONFIG= new GPPScannerExtensionConfiguration(); private static GPPScannerExtensionConfiguration CONFIG_4_2= new GPPScannerExtensionConfiguration(VERSION_4_2); private static GPPScannerExtensionConfiguration CONFIG_4_3= new GPPScannerExtensionConfiguration(VERSION_4_3); private static GPPScannerExtensionConfiguration CONFIG_4_6= new GPPScannerExtensionConfiguration(VERSION_4_6); private static GPPScannerExtensionConfiguration CONFIG_4_7= new GPPScannerExtensionConfiguration(VERSION_4_7); private static GPPScannerExtensionConfiguration CONFIG_5_0= new GPPScannerExtensionConfiguration(VERSION_5_0); + private static GPPScannerExtensionConfiguration CONFIG_8_0= new GPPScannerExtensionConfiguration(VERSION_8_0); private static GPPScannerExtensionConfiguration CONFIG_CLANG= new GPPScannerExtensionConfiguration(CompilerType.Clang, 0 /* version is ignored for now */); @@ -65,6 +67,9 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu int major= Integer.valueOf(definedSymbols.get("__GNUC__")); //$NON-NLS-1$ int minor= Integer.valueOf(definedSymbols.get("__GNUC_MINOR__")); //$NON-NLS-1$ int version= version(major, minor); + if (version >= VERSION_8_0) { + return CONFIG_8_0; + } if (version >= VERSION_5_0) { return CONFIG_5_0; } @@ -149,6 +154,9 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu addKeyword(GCCKeywords.cp__is_trivially_constructible, IGCCToken.tTT_is_trivially_constructible); addKeyword(GCCKeywords.cp__is_trivially_assignable, IGCCToken.tTT_is_trivially_assignable); } + if (version >= VERSION_8_0) { + addKeyword(GCCKeywords.cp__is_constructible, IGCCToken.tTT_is_constructible); + } } else if (compiler == CompilerType.Clang) { // As documented at // http://clang.llvm.org/docs/LanguageExtensions.html#checks-for-type-trait-primitives. @@ -173,6 +181,7 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu addKeyword(GCCKeywords.cp__underlying_type, IGCCToken.tTT_underlying_type); addKeyword(GCCKeywords.cp__is_trivially_constructible, IGCCToken.tTT_is_trivially_constructible); addKeyword(GCCKeywords.cp__is_trivially_assignable, IGCCToken.tTT_is_trivially_assignable); + addKeyword(GCCKeywords.cp__is_constructible, IGCCToken.tTT_is_constructible); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java index 063317f33b0..834335b2aa8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java @@ -108,4 +108,8 @@ public class GCCKeywords { cp__is_trivially_copyable= "__is_trivially_copyable".toCharArray(), cp__is_trivially_constructible= "__is_trivially_constructible".toCharArray(), cp__is_trivially_assignable= "__is_trivially_assignable".toCharArray(); + + /** @since 6.6 */ + public static final char[] + cp__is_constructible= "__is_constructible".toCharArray(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java index 3133b574ea9..6183abcfaba 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java @@ -58,4 +58,6 @@ public interface IGCCToken extends IToken { /** @since 6.0 */ int tTT_is_trivially_copyable= FIRST_RESERVED_IGCCToken + 32; /** @since 6.0 */ int tTT_is_trivially_constructible= FIRST_RESERVED_IGCCToken + 33; /** @since 6.0 */ int tTT_is_trivially_assignable= FIRST_RESERVED_IGCCToken + 34; + + /** @since 6.6 */ int tTT_is_constructible= FIRST_RESERVED_IGCCToken + 35; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java index d47fe042948..a0d1fe135ec 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java @@ -611,14 +611,16 @@ public class ValueFactory { private static IValue applyNaryTypeIdOperator(ICPPASTNaryTypeIdExpression.Operator operator, IType[] operands, IBinding pointOfDefinition) { switch (operator) { + case __is_constructible: case __is_trivially_constructible: if (operands.length == 0) { return IntegralValue.UNKNOWN; } + boolean checkTrivial = (operator == Operator.__is_trivially_constructible); IType typeToConstruct = operands[0]; IType[] argumentTypes = Arrays.copyOfRange(operands, 1, operands.length); - return IntegralValue.create(TypeTraits.isTriviallyConstructible(typeToConstruct, argumentTypes, - pointOfDefinition) ? 1 : 0); + return IntegralValue.create(TypeTraits.isConstructible(typeToConstruct, argumentTypes, + pointOfDefinition, checkTrivial) ? 1 : 0); } return IntegralValue.UNKNOWN; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index b47dba36e5f..4ec263f939c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -1543,6 +1543,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { case IGCCToken.tTT_is_trivially_copyable: case IGCCToken.tTT_is_trivially_constructible: case IGCCToken.tTT_is_trivially_assignable: + case IGCCToken.tTT_is_constructible: return parseTypeTrait(); default: @@ -1602,6 +1603,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { private boolean isNaryTrait(IToken operatorToken) { switch (operatorToken.getType()) { case IGCCToken.tTT_is_trivially_constructible: + case IGCCToken.tTT_is_constructible: return true; } return false; @@ -1623,6 +1625,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { switch (operatorToken.getType()) { case IGCCToken.tTT_is_trivially_constructible: return ICPPASTNaryTypeIdExpression.Operator.__is_trivially_constructible; + case IGCCToken.tTT_is_constructible: + return ICPPASTNaryTypeIdExpression.Operator.__is_constructible; } assert false; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalNaryTypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalNaryTypeId.java index 5eeb45f2fd7..1a9d27f51e5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalNaryTypeId.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalNaryTypeId.java @@ -88,6 +88,7 @@ public class EvalNaryTypeId extends CPPDependentEvaluation { public IType getType() { switch (fOperator) { case __is_trivially_constructible: + case __is_constructible: return CPPBasicType.BOOLEAN; } return ProblemType.UNKNOWN_FOR_EXPRESSION; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java index 75c3a9e3c2f..470999d33f9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java @@ -566,11 +566,14 @@ public class TypeTraits { } /** - * Returns true if 'typeToConstruct' is trivially constructible from arguments + * Returns true if 'typeToConstruct' is constructible from arguments * of type 'argumentTypes', as defined in [meta.unary.prop]. + * + * If 'checkTrivial' is true, additionally checks if 'typeToConstruct' + * is trivially constructible from said argument types. */ - public static boolean isTriviallyConstructible(IType typeToConstruct, IType[] argumentTypes, - IBinding pointOfDefinition) { + public static boolean isConstructible(IType typeToConstruct, IType[] argumentTypes, + IBinding pointOfDefinition, boolean checkTrivial) { IType type = SemanticUtil.getSimplifiedType(typeToConstruct); if (!(type instanceof ICPPClassType)) { return true; @@ -586,7 +589,13 @@ public class TypeTraits { } EvalTypeId eval = new EvalTypeId(type, pointOfDefinition, false, false, arguments); ICPPFunction constructor = eval.getConstructor(); + if (!(constructor instanceof ICPPMethod)) { + return false; + } // TODO check that conversions are trivial as well - return constructor instanceof ICPPMethod && ((ICPPMethod) constructor).isImplicit(); + if (checkTrivial && !((ICPPMethod) constructor).isImplicit()) { + return false; + } + return true; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java index 7322a44e54c..8855bbcb21d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java @@ -2206,7 +2206,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable { addTypeTraitPrimitive("is_abstract", GCCKeywords.cp__is_abstract); addTypeTraitPrimitive("is_base_of", GCCKeywords.cp__is_base_of); addTypeTraitPrimitive("is_class", GCCKeywords.cp__is_class); - // missing: is_constructible + addTypeTraitPrimitive("is_constructible", GCCKeywords.cp__is_constructible); // missing: is_convertible_to // missing: is_destructible addTypeTraitPrimitive("is_empty", GCCKeywords.cp__is_empty); -- cgit v1.2.3