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:
parent
a5348a47ba
commit
952c64a0bc
3 changed files with 95 additions and 1 deletions
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue