mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 17:05:26 +02:00
Bug 539052 - Add support for __is_constructible type trait intrinsic
Change-Id: I582881808e19342bf55d62d6002365c3733ebf31
This commit is contained in:
parent
9d84c30b5a
commit
7831931f3a
11 changed files with 53 additions and 9 deletions
|
@ -12677,6 +12677,18 @@ public class AST2CPPTests extends AST2CPPTestBase {
|
|||
helper.assertVariableValue("waldo5", 0);
|
||||
}
|
||||
|
||||
// template <typename T, typename U>
|
||||
// struct pair {
|
||||
// pair();
|
||||
// pair(T, U);
|
||||
// };
|
||||
//
|
||||
// constexpr bool waldo = __is_constructible(pair<const int>, pair<int, int>&&);
|
||||
public void testIsConstructible_539052() throws Exception {
|
||||
BindingAssertionHelper helper = getAssertionHelper();
|
||||
helper.assertVariableValue("waldo", 1);
|
||||
}
|
||||
|
||||
// namespace x {
|
||||
// void foo();
|
||||
// }
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue