1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-15 13:05:22 +02:00

Implemented is_empty type trait.

Change-Id: I1bb6fc98920eded16186889d66e33a7ca7432456
This commit is contained in:
Sergey Prigogin 2016-01-03 22:08:13 -08:00
parent f3ff649041
commit ec9a9fb5c7
3 changed files with 129 additions and 32 deletions

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2011, 2013 Google, Inc and others. * Copyright (c) 2011, 2016 Google, Inc and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -12,12 +12,13 @@ package org.eclipse.cdt.core.parser.tests.ast2;
import java.io.IOException; import java.io.IOException;
import junit.framework.TestSuite; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; 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.dom.parser.cpp.semantics.TypeTraits;
import org.eclipse.cdt.internal.core.parser.ParserException; import org.eclipse.cdt.internal.core.parser.ParserException;
import junit.framework.TestSuite;
/** /**
* Tests for ClassTypeHelper class. * Tests for ClassTypeHelper class.
*/ */
@ -58,11 +59,11 @@ public class TypeTraitsTests extends AST2TestBase {
// }; // };
public void testHasTrivialCopyCtor() throws Exception { public void testHasTrivialCopyCtor() throws Exception {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
ICPPClassType classA = helper.assertNonProblem("A {", 1, ICPPClassType.class); ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {");
assertFalse(TypeTraits.hasTrivialCopyCtor(classA, null)); assertFalse(TypeTraits.hasTrivialCopyCtor(classA, null));
ICPPClassType classB = helper.assertNonProblem("B {", 1, ICPPClassType.class); ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B {");
assertTrue(TypeTraits.hasTrivialCopyCtor(classB, null)); assertTrue(TypeTraits.hasTrivialCopyCtor(classB, null));
ICPPClassType classC = helper.assertNonProblem("C {", 1, ICPPClassType.class); ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C {");
assertFalse(TypeTraits.hasTrivialCopyCtor(classC, null)); assertFalse(TypeTraits.hasTrivialCopyCtor(classC, null));
} }
@ -86,14 +87,69 @@ public class TypeTraitsTests extends AST2TestBase {
// }; // };
public void testHasTrivialDestructor() throws Exception { public void testHasTrivialDestructor() throws Exception {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
ICPPClassType classA = helper.assertNonProblem("A {", 1, ICPPClassType.class); ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {");
assertFalse(TypeTraits.hasTrivialDestructor(classA, null)); assertFalse(TypeTraits.hasTrivialDestructor(classA, null));
ICPPClassType classB = helper.assertNonProblem("B {", 1, ICPPClassType.class); ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B {");
assertTrue(TypeTraits.hasTrivialDestructor(classB, null)); assertTrue(TypeTraits.hasTrivialDestructor(classB, null));
ICPPClassType classC = helper.assertNonProblem("C {", 1, ICPPClassType.class); ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C {");
assertFalse(TypeTraits.hasTrivialDestructor(classC, null)); assertFalse(TypeTraits.hasTrivialDestructor(classC, null));
} }
// struct A {
// static int x;
// ~A();
// };
//
// class B : public A {
// };
//
// struct C {
// A a;
// };
//
// struct D : public A, C {
// };
//
// struct E {
// virtual ~E();
// };
//
// struct F {
// virtual void m();
// };
//
// struct G : public virtual A {
// };
//
// typedef const A H;
//
// typedef A* I;
//
// typedef A J[0];
public void testIsEmpty() throws Exception {
BindingAssertionHelper helper = getAssertionHelper();
ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {");
assertTrue(TypeTraits.isEmpty(classA, null));
ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B :");
assertTrue(TypeTraits.isEmpty(classB, null));
ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C {");
assertFalse(TypeTraits.isEmpty(classC, null));
ICPPClassType classD = helper.assertNonProblemOnFirstIdentifier("D :");
assertFalse(TypeTraits.isEmpty(classD, null));
ICPPClassType classE = helper.assertNonProblemOnFirstIdentifier("E {");
assertFalse(TypeTraits.isEmpty(classE, null));
ICPPClassType classF = helper.assertNonProblemOnFirstIdentifier("F {");
assertFalse(TypeTraits.isEmpty(classF, null));
ICPPClassType classG = helper.assertNonProblemOnFirstIdentifier("G :");
assertFalse(TypeTraits.isEmpty(classG, null));
IType typeH = helper.assertNonProblemOnFirstIdentifier("H;");
assertTrue(TypeTraits.isEmpty(typeH, null));
IType typeI = helper.assertNonProblemOnFirstIdentifier("I;");
assertFalse(TypeTraits.isEmpty(typeI, null));
IType typeJ = helper.assertNonProblemOnFirstIdentifier("J[");
assertFalse(TypeTraits.isEmpty(typeJ, null));
}
// struct A { // struct A {
// virtual void m(); // virtual void m();
// }; // };
@ -112,11 +168,11 @@ public class TypeTraitsTests extends AST2TestBase {
// }; // };
public void testIsPolymorphic() throws Exception { public void testIsPolymorphic() throws Exception {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
ICPPClassType classA = helper.assertNonProblem("A {", 1, ICPPClassType.class); ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {");
assertTrue(TypeTraits.isPolymorphic(classA, null)); assertTrue(TypeTraits.isPolymorphic(classA, null));
ICPPClassType classB = helper.assertNonProblem("B {", 1, ICPPClassType.class); ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B {");
assertFalse(TypeTraits.isPolymorphic(classB, null)); assertFalse(TypeTraits.isPolymorphic(classB, null));
ICPPClassType classC = helper.assertNonProblem("C", 1, ICPPClassType.class); ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C");
assertTrue(TypeTraits.isPolymorphic(classC, null)); assertTrue(TypeTraits.isPolymorphic(classC, null));
} }
@ -159,21 +215,21 @@ public class TypeTraitsTests extends AST2TestBase {
// }; // };
public void testIsStandardLayout() throws Exception { public void testIsStandardLayout() throws Exception {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
ICPPClassType classA = helper.assertNonProblem("A {", 1, ICPPClassType.class); ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {");
assertTrue(TypeTraits.isStandardLayout(classA, null)); assertTrue(TypeTraits.isStandardLayout(classA, null));
ICPPClassType classB = helper.assertNonProblem("B {", 1, ICPPClassType.class); ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B {");
assertTrue(TypeTraits.isStandardLayout(classB, null)); assertTrue(TypeTraits.isStandardLayout(classB, null));
ICPPClassType classC = helper.assertNonProblem("C :", 1, ICPPClassType.class); ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C :");
assertFalse(TypeTraits.isStandardLayout(classC, null)); assertFalse(TypeTraits.isStandardLayout(classC, null));
ICPPClassType classD = helper.assertNonProblem("D {", 1, ICPPClassType.class); ICPPClassType classD = helper.assertNonProblemOnFirstIdentifier("D {");
assertFalse(TypeTraits.isStandardLayout(classD, null)); assertFalse(TypeTraits.isStandardLayout(classD, null));
ICPPClassType classE = helper.assertNonProblem("E :", 1, ICPPClassType.class); ICPPClassType classE = helper.assertNonProblemOnFirstIdentifier("E :");
assertFalse(TypeTraits.isStandardLayout(classE, null)); assertFalse(TypeTraits.isStandardLayout(classE, null));
ICPPClassType classF = helper.assertNonProblem("F :", 1, ICPPClassType.class); ICPPClassType classF = helper.assertNonProblemOnFirstIdentifier("F :");
assertFalse(TypeTraits.isStandardLayout(classF, null)); assertFalse(TypeTraits.isStandardLayout(classF, null));
ICPPClassType classG = helper.assertNonProblem("G {", 1, ICPPClassType.class); ICPPClassType classG = helper.assertNonProblemOnFirstIdentifier("G {");
assertFalse(TypeTraits.isStandardLayout(classG, null)); assertFalse(TypeTraits.isStandardLayout(classG, null));
ICPPClassType classH = helper.assertNonProblem("H {", 1, ICPPClassType.class); ICPPClassType classH = helper.assertNonProblemOnFirstIdentifier("H {");
assertFalse(TypeTraits.isStandardLayout(classH, null)); assertFalse(TypeTraits.isStandardLayout(classH, null));
} }
@ -217,23 +273,23 @@ public class TypeTraitsTests extends AST2TestBase {
// }; // };
public void testIsTrivial() throws Exception { public void testIsTrivial() throws Exception {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
ICPPClassType classA = helper.assertNonProblem("A {", 1, ICPPClassType.class); ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {");
assertTrue(TypeTraits.isTrivial(classA, null)); assertTrue(TypeTraits.isTrivial(classA, null));
ICPPClassType classB = helper.assertNonProblem("B :", 1, ICPPClassType.class); ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B :");
assertTrue(TypeTraits.isTrivial(classB, null)); assertTrue(TypeTraits.isTrivial(classB, null));
ICPPClassType classC = helper.assertNonProblem("C {", 1, ICPPClassType.class); ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C {");
assertFalse(TypeTraits.isTrivial(classC, null)); assertFalse(TypeTraits.isTrivial(classC, null));
ICPPClassType classD = helper.assertNonProblem("D {", 1, ICPPClassType.class); ICPPClassType classD = helper.assertNonProblemOnFirstIdentifier("D {");
assertFalse(TypeTraits.isTrivial(classD, null)); assertFalse(TypeTraits.isTrivial(classD, null));
ICPPClassType classE = helper.assertNonProblem("E {", 1, ICPPClassType.class); ICPPClassType classE = helper.assertNonProblemOnFirstIdentifier("E {");
assertFalse(TypeTraits.isTrivial(classE, null)); assertFalse(TypeTraits.isTrivial(classE, null));
ICPPClassType classF = helper.assertNonProblem("F {", 1, ICPPClassType.class); ICPPClassType classF = helper.assertNonProblemOnFirstIdentifier("F {");
assertFalse(TypeTraits.isTrivial(classF, null)); assertFalse(TypeTraits.isTrivial(classF, null));
ICPPClassType classG = helper.assertNonProblem("G {", 1, ICPPClassType.class); ICPPClassType classG = helper.assertNonProblemOnFirstIdentifier("G {");
assertFalse(TypeTraits.isTrivial(classG, null)); assertFalse(TypeTraits.isTrivial(classG, null));
ICPPClassType classH = helper.assertNonProblem("H :", 1, ICPPClassType.class); ICPPClassType classH = helper.assertNonProblemOnFirstIdentifier("H :");
assertFalse(TypeTraits.isTrivial(classH, null)); assertFalse(TypeTraits.isTrivial(classH, null));
ICPPClassType classI = helper.assertNonProblem("I {", 1, ICPPClassType.class); ICPPClassType classI = helper.assertNonProblemOnFirstIdentifier("I {");
assertFalse(TypeTraits.isTrivial(classI, null)); assertFalse(TypeTraits.isTrivial(classI, null));
} }
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008, 2015 Wind River Systems, Inc. and others. * Copyright (c) 2008, 2016 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -333,7 +333,7 @@ public class Value implements IValue {
return type instanceof ICompositeType && return type instanceof ICompositeType &&
((ICompositeType) type).getKey() != ICompositeType.k_union ? 1 : 0; ((ICompositeType) type).getKey() != ICompositeType.k_union ? 1 : 0;
case op_is_empty: case op_is_empty:
break; // TODO(sprigogin): Implement return TypeTraits.isEmpty(type, point) ? 1 : 0;
case op_is_enum: case op_is_enum:
return type instanceof IEnumeration ? 1 : 0; return type instanceof IEnumeration ? 1 : 0;
case op_is_final: case op_is_final:

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2012, 2014 Google, Inc and others. * Copyright (c) 2012, 2016 Google, Inc and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -152,6 +152,47 @@ public class TypeTraits {
return isTrivial((ICPPClassType) type, point); return isTrivial((ICPPClassType) type, point);
} }
/**
* Returns true if the given type is a class type, but not a union type, with no non-static
* data members other than bit-fields of length 0, no virtual member functions, no virtual
* base classes, and no base class for which isEmpty is false. [meta.unary.prop]
*/
public static boolean isEmpty(IType type, IASTNode point) {
type = SemanticUtil.getNestedType(type, CVTYPE | TDEF);
if (!(type instanceof ICPPClassType))
return false;
ICPPClassType classType = (ICPPClassType) type;
if (!isItselfEmpty(classType, point))
return false;
ICPPClassType[] baseClasses = ClassTypeHelper.getAllBases(classType, point);
for (ICPPClassType baseClass : baseClasses) {
if (!isItselfEmpty(baseClass, point))
return false;
}
return true;
}
private static boolean isItselfEmpty(ICPPClassType classType, IASTNode point) {
ICPPField[] fields = ClassTypeHelper.getDeclaredFields(classType, point);
for (ICPPField field : fields) {
if (!field.isStatic()) {
// TODO(sprigogin): Check for empty bit fields when bit field size becomes available.
return false;
}
}
ICPPMethod[] methods = ClassTypeHelper.getDeclaredMethods(classType, point);
for (ICPPMethod method : methods) {
if (method.isVirtual())
return false;
}
ICPPBase[] bases = ClassTypeHelper.getBases(classType, point);
for (ICPPBase base : bases) {
if (base.isVirtual())
return false;
}
return true;
}
/** /**
* 8.5.1 Aggregates [dcl.init.aggr] * 8.5.1 Aggregates [dcl.init.aggr]
* An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), * An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1),