mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-15 04:55:22 +02:00
Implemented is_empty type trait.
Change-Id: I1bb6fc98920eded16186889d66e33a7ca7432456
This commit is contained in:
parent
f3ff649041
commit
ec9a9fb5c7
3 changed files with 129 additions and 32 deletions
|
@ -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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* 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 junit.framework.TestSuite;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
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;
|
||||
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
/**
|
||||
* Tests for ClassTypeHelper class.
|
||||
*/
|
||||
|
@ -58,11 +59,11 @@ public class TypeTraitsTests extends AST2TestBase {
|
|||
// };
|
||||
public void testHasTrivialCopyCtor() throws Exception {
|
||||
BindingAssertionHelper helper = getAssertionHelper();
|
||||
ICPPClassType classA = helper.assertNonProblem("A {", 1, ICPPClassType.class);
|
||||
ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {");
|
||||
assertFalse(TypeTraits.hasTrivialCopyCtor(classA, null));
|
||||
ICPPClassType classB = helper.assertNonProblem("B {", 1, ICPPClassType.class);
|
||||
ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B {");
|
||||
assertTrue(TypeTraits.hasTrivialCopyCtor(classB, null));
|
||||
ICPPClassType classC = helper.assertNonProblem("C {", 1, ICPPClassType.class);
|
||||
ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C {");
|
||||
assertFalse(TypeTraits.hasTrivialCopyCtor(classC, null));
|
||||
}
|
||||
|
||||
|
@ -86,14 +87,69 @@ public class TypeTraitsTests extends AST2TestBase {
|
|||
// };
|
||||
public void testHasTrivialDestructor() throws Exception {
|
||||
BindingAssertionHelper helper = getAssertionHelper();
|
||||
ICPPClassType classA = helper.assertNonProblem("A {", 1, ICPPClassType.class);
|
||||
ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {");
|
||||
assertFalse(TypeTraits.hasTrivialDestructor(classA, null));
|
||||
ICPPClassType classB = helper.assertNonProblem("B {", 1, ICPPClassType.class);
|
||||
ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B {");
|
||||
assertTrue(TypeTraits.hasTrivialDestructor(classB, null));
|
||||
ICPPClassType classC = helper.assertNonProblem("C {", 1, ICPPClassType.class);
|
||||
ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C {");
|
||||
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 {
|
||||
// virtual void m();
|
||||
// };
|
||||
|
@ -112,11 +168,11 @@ public class TypeTraitsTests extends AST2TestBase {
|
|||
// };
|
||||
public void testIsPolymorphic() throws Exception {
|
||||
BindingAssertionHelper helper = getAssertionHelper();
|
||||
ICPPClassType classA = helper.assertNonProblem("A {", 1, ICPPClassType.class);
|
||||
ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {");
|
||||
assertTrue(TypeTraits.isPolymorphic(classA, null));
|
||||
ICPPClassType classB = helper.assertNonProblem("B {", 1, ICPPClassType.class);
|
||||
ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B {");
|
||||
assertFalse(TypeTraits.isPolymorphic(classB, null));
|
||||
ICPPClassType classC = helper.assertNonProblem("C", 1, ICPPClassType.class);
|
||||
ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C");
|
||||
assertTrue(TypeTraits.isPolymorphic(classC, null));
|
||||
}
|
||||
|
||||
|
@ -159,21 +215,21 @@ public class TypeTraitsTests extends AST2TestBase {
|
|||
// };
|
||||
public void testIsStandardLayout() throws Exception {
|
||||
BindingAssertionHelper helper = getAssertionHelper();
|
||||
ICPPClassType classA = helper.assertNonProblem("A {", 1, ICPPClassType.class);
|
||||
ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {");
|
||||
assertTrue(TypeTraits.isStandardLayout(classA, null));
|
||||
ICPPClassType classB = helper.assertNonProblem("B {", 1, ICPPClassType.class);
|
||||
ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B {");
|
||||
assertTrue(TypeTraits.isStandardLayout(classB, null));
|
||||
ICPPClassType classC = helper.assertNonProblem("C :", 1, ICPPClassType.class);
|
||||
ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C :");
|
||||
assertFalse(TypeTraits.isStandardLayout(classC, null));
|
||||
ICPPClassType classD = helper.assertNonProblem("D {", 1, ICPPClassType.class);
|
||||
ICPPClassType classD = helper.assertNonProblemOnFirstIdentifier("D {");
|
||||
assertFalse(TypeTraits.isStandardLayout(classD, null));
|
||||
ICPPClassType classE = helper.assertNonProblem("E :", 1, ICPPClassType.class);
|
||||
ICPPClassType classE = helper.assertNonProblemOnFirstIdentifier("E :");
|
||||
assertFalse(TypeTraits.isStandardLayout(classE, null));
|
||||
ICPPClassType classF = helper.assertNonProblem("F :", 1, ICPPClassType.class);
|
||||
ICPPClassType classF = helper.assertNonProblemOnFirstIdentifier("F :");
|
||||
assertFalse(TypeTraits.isStandardLayout(classF, null));
|
||||
ICPPClassType classG = helper.assertNonProblem("G {", 1, ICPPClassType.class);
|
||||
ICPPClassType classG = helper.assertNonProblemOnFirstIdentifier("G {");
|
||||
assertFalse(TypeTraits.isStandardLayout(classG, null));
|
||||
ICPPClassType classH = helper.assertNonProblem("H {", 1, ICPPClassType.class);
|
||||
ICPPClassType classH = helper.assertNonProblemOnFirstIdentifier("H {");
|
||||
assertFalse(TypeTraits.isStandardLayout(classH, null));
|
||||
}
|
||||
|
||||
|
@ -217,23 +273,23 @@ public class TypeTraitsTests extends AST2TestBase {
|
|||
// };
|
||||
public void testIsTrivial() throws Exception {
|
||||
BindingAssertionHelper helper = getAssertionHelper();
|
||||
ICPPClassType classA = helper.assertNonProblem("A {", 1, ICPPClassType.class);
|
||||
ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {");
|
||||
assertTrue(TypeTraits.isTrivial(classA, null));
|
||||
ICPPClassType classB = helper.assertNonProblem("B :", 1, ICPPClassType.class);
|
||||
ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B :");
|
||||
assertTrue(TypeTraits.isTrivial(classB, null));
|
||||
ICPPClassType classC = helper.assertNonProblem("C {", 1, ICPPClassType.class);
|
||||
ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C {");
|
||||
assertFalse(TypeTraits.isTrivial(classC, null));
|
||||
ICPPClassType classD = helper.assertNonProblem("D {", 1, ICPPClassType.class);
|
||||
ICPPClassType classD = helper.assertNonProblemOnFirstIdentifier("D {");
|
||||
assertFalse(TypeTraits.isTrivial(classD, null));
|
||||
ICPPClassType classE = helper.assertNonProblem("E {", 1, ICPPClassType.class);
|
||||
ICPPClassType classE = helper.assertNonProblemOnFirstIdentifier("E {");
|
||||
assertFalse(TypeTraits.isTrivial(classE, null));
|
||||
ICPPClassType classF = helper.assertNonProblem("F {", 1, ICPPClassType.class);
|
||||
ICPPClassType classF = helper.assertNonProblemOnFirstIdentifier("F {");
|
||||
assertFalse(TypeTraits.isTrivial(classF, null));
|
||||
ICPPClassType classG = helper.assertNonProblem("G {", 1, ICPPClassType.class);
|
||||
ICPPClassType classG = helper.assertNonProblemOnFirstIdentifier("G {");
|
||||
assertFalse(TypeTraits.isTrivial(classG, null));
|
||||
ICPPClassType classH = helper.assertNonProblem("H :", 1, ICPPClassType.class);
|
||||
ICPPClassType classH = helper.assertNonProblemOnFirstIdentifier("H :");
|
||||
assertFalse(TypeTraits.isTrivial(classH, null));
|
||||
ICPPClassType classI = helper.assertNonProblem("I {", 1, ICPPClassType.class);
|
||||
ICPPClassType classI = helper.assertNonProblemOnFirstIdentifier("I {");
|
||||
assertFalse(TypeTraits.isTrivial(classI, null));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -333,7 +333,7 @@ public class Value implements IValue {
|
|||
return type instanceof ICompositeType &&
|
||||
((ICompositeType) type).getKey() != ICompositeType.k_union ? 1 : 0;
|
||||
case op_is_empty:
|
||||
break; // TODO(sprigogin): Implement
|
||||
return TypeTraits.isEmpty(type, point) ? 1 : 0;
|
||||
case op_is_enum:
|
||||
return type instanceof IEnumeration ? 1 : 0;
|
||||
case op_is_final:
|
||||
|
|
|
@ -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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -152,6 +152,47 @@ public class TypeTraits {
|
|||
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]
|
||||
* An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1),
|
||||
|
|
Loading…
Add table
Reference in a new issue