1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 01:15:29 +02:00

Bug 485720 - Evaluation of __is_trivially_copyable

Change-Id: I969dc47ed20c28b0e8ce476c586f8d22af7c8894
Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
This commit is contained in:
Nathan Ridge 2016-01-14 01:16:38 -05:00 committed by Sergey Prigogin
parent a5348a47ba
commit 952c64a0bc
3 changed files with 95 additions and 1 deletions

View file

@ -13,6 +13,7 @@ package org.eclipse.cdt.core.parser.tests.ast2;
import java.io.IOException;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeTraits;
import org.eclipse.cdt.internal.core.parser.ParserException;
@ -292,4 +293,36 @@ public class TypeTraitsTests extends AST2TestBase {
ICPPClassType classI = helper.assertNonProblemOnFirstIdentifier("I {");
assertFalse(TypeTraits.isTrivial(classI, null));
}
// int a;
// char* const b;
// void* volatile c;
// char* const d[42];
// enum E {} e;
// struct F {
// int x, y;
// F();
// } f;
// struct G {
// int x, y;
// G();
// G(const G&);
// } g;
public void testIsTriviallyCopyable() throws Exception {
BindingAssertionHelper helper = getAssertionHelper();
IVariable a = helper.assertNonProblemOnFirstIdentifier("a;");
assertTrue(TypeTraits.isTriviallyCopyable(a.getType(), null));
IVariable b = helper.assertNonProblemOnFirstIdentifier("b;");
assertTrue(TypeTraits.isTriviallyCopyable(b.getType(), null));
IVariable c = helper.assertNonProblemOnFirstIdentifier("c;");
assertFalse(TypeTraits.isTriviallyCopyable(c.getType(), null));
IVariable d = helper.assertNonProblemOnFirstIdentifier("d[");
assertTrue(TypeTraits.isTriviallyCopyable(d.getType(), null));
IVariable e = helper.assertNonProblemOnFirstIdentifier("e;");
assertTrue(TypeTraits.isTriviallyCopyable(e.getType(), null));
IVariable f = helper.assertNonProblemOnFirstIdentifier("f;");
assertTrue(TypeTraits.isTriviallyCopyable(f.getType(), null));
IVariable g = helper.assertNonProblemOnFirstIdentifier("g;");
assertFalse(TypeTraits.isTriviallyCopyable(g.getType(), null));
}
}

View file

@ -352,7 +352,7 @@ public class Value implements IValue {
return type instanceof ICPPClassType &&
TypeTraits.isTrivial((ICPPClassType) type, point) ? 1 : 0;
case op_is_trivially_copyable:
break; // TODO: Implement
return TypeTraits.isTriviallyCopyable(type, point) ? 1 : 0;
case op_is_union:
return type instanceof ICompositeType &&
((ICompositeType) type).getKey() == ICompositeType.k_union ? 1 : 0;

View file

@ -15,7 +15,10 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
@ -58,11 +61,20 @@ public class TypeTraits {
* C++11: 9-6
*/
public static boolean isTrivial(ICPPClassType classType, IASTNode point) {
return isTrivialImpl(classType, point, true);
}
private static boolean isTrivialImpl(ICPPClassType classType, IASTNode point,
boolean checkDefaultConstructors) {
for (ICPPMethod method : ClassTypeHelper.getDeclaredMethods(classType, point)) {
if (method.isVirtual())
return false;
switch (ClassTypeHelper.getMethodKind(classType, method)) {
case DEFAULT_CTOR:
if (checkDefaultConstructors) {
return false;
}
break;
case COPY_CTOR:
case MOVE_CTOR:
case COPY_ASSIGNMENT_OP:
@ -432,4 +444,53 @@ public class TypeTraits {
}
return types[types.length - 1]; // Assume it fits into the largest type provided.
}
/**
* Returns true if 'type' is scalar, as defined in [basic.types] p9:
*
* "Arithmetic types, enumeration types, pointer types, pointer to member
* types, std::nullptr_t, and cv-qualified versions of these types are
* collectively called scalar types."
*/
private static boolean isScalar(IType type) {
type = SemanticUtil.getNestedType(type, SemanticUtil.ALLCVQ);
return type instanceof IBasicType || type instanceof IEnumeration || type instanceof IPointerType;
}
/**
* Returns true if 'type' is a trivially copyable class, as defined in [class] p6:
*
* "A trivially copyable class is a class that:
* - has no non-trivial copy constructors,
* - has no non-trivial move constructors,
* - has no non-trivial copy assignment operators,
* - has no non-trivial move assignment operators, and
* - has a trivial destructor."
*/
private static boolean isTriviallyCopyableClass(ICPPClassType type, IASTNode point) {
return isTrivialImpl(type, point, false);
}
/**
* Returns true if 'type' is trivially copyable, as defined in [basic.types] p9:
*
* "Cv-unqualified scalar types, trivially copyable class types, arrays
* of such types, and non-volatile const-qualified versions of these
* types are collectively called trivially copyable types."
*/
public static boolean isTriviallyCopyable(IType type, IASTNode point) {
type = SemanticUtil.getSimplifiedType(type);
CVQualifier qualifier = SemanticUtil.getCVQualifier(type);
if (qualifier.isVolatile()) {
return false;
} else if (qualifier.isConst()) {
return isTriviallyCopyable(SemanticUtil.getNestedType(type, SemanticUtil.ALLCVQ), point);
} else if (type instanceof IArrayType) {
return isTriviallyCopyable(((IArrayType) type).getType(), point);
} else if (type instanceof ICPPClassType) {
return isTriviallyCopyableClass((ICPPClassType) type, point);
} else {
return isScalar(type);
}
}
}