/// (C++0x [basic.types]p9)
bool isTrivialType() const;
+ /// \brief Test if this type is a standard-layout type.
+ /// (C++0x [basic.type]p9)
+ bool isStandardLayoutType() const;
+
/// isCXX11PODType() - Return true if this is a POD type according to the
/// more relaxed rules of the C++11 standard, regardless of the current
/// compilation's language.
// const, it needs to return false.
bool hasConstFields() const { return false; }
- /// \brief Whether this class has standard layout
- bool hasStandardLayout() const;
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
return false;
}
-// This is effectively the intersection of isTrivialType and hasStandardLayout.
-// We implement it dircetly to avoid redundant conversions from a type to
-// a CXXRecordDecl.
+bool Type::isStandardLayoutType() const {
+ if (isIncompleteType())
+ return false;
+
+ // C++0x [basic.types]p9:
+ // Scalar types, standard-layout class types, arrays of such types, and
+ // cv-qualified versions of these types are collectively called
+ // standard-layout types.
+ const Type *BaseTy = getBaseElementTypeUnsafe();
+ assert(BaseTy && "NULL element type");
+ if (BaseTy->isScalarType()) return true;
+ if (const RecordType *RT = BaseTy->getAs<RecordType>()) {
+ if (const CXXRecordDecl *ClassDecl =
+ dyn_cast<CXXRecordDecl>(RT->getDecl()))
+ if (!ClassDecl->hasStandardLayout())
+ return false;
+
+ // Default to 'true' for non-C++ class types.
+ // FIXME: This is a bit dubious, but plain C structs should trivially meet
+ // all the requirements of standard layout classes.
+ return true;
+ }
+
+ // No other types can match.
+ return false;
+}
+
+// This is effectively the intersection of isTrivialType and
+// isStandardLayoutType. We implement it dircetly to avoid redundant
+// conversions from a type to a CXXRecordDecl.
bool Type::isCXX11PODType() const {
if (isIncompleteType())
return false;
return BasesWithFields;
}
-bool RecordType::hasStandardLayout() const {
- CXXRecordDecl *RD = cast<CXXRecordDecl>(getDecl());
- if (! RD) {
- assert(cast<RecordDecl>(getDecl()) &&
- "RecordType does not have a corresponding RecordDecl");
- return true;
- }
-
- return RD->hasStandardLayout();
-}
-
bool EnumType::classof(const TagType *TT) {
return isa<EnumDecl>(TT->getDecl());
}
case UTT_IsSigned:
return T->isSignedIntegerType();
case UTT_IsStandardLayout:
- // Error if T is an incomplete type.
- if (Self.RequireCompleteType(KeyLoc, T, diag::err_incomplete_typeid))
- return false;
-
- // A standard layout type is:
- // - a scalar type
- // - an array of standard layout types
- // - a standard layout class type:
- if (EvaluateUnaryTypeTrait(Self, UTT_IsScalar, T, KeyLoc))
- return true;
- if (EvaluateUnaryTypeTrait(Self, UTT_IsScalar, C.getBaseElementType(T),
- KeyLoc))
- return true;
- if (const RecordType *RT = C.getBaseElementType(T)->getAs<RecordType>())
- return RT->hasStandardLayout();
- return false;
+ return T->isStandardLayoutType();
case UTT_IsUnsigned:
return T->isUnsignedIntegerType();
case UTT_IsVoid: