[cfe-commits] r130602 - in /cfe/trunk: include/clang/AST/Type.h lib/AST/Type.cpp lib/Sema/SemaExprCXX.cpp

Chandler Carruth chandlerc at gmail.com
Sat Apr 30 02:17:49 PDT 2011


Author: chandlerc
Date: Sat Apr 30 04:17:49 2011
New Revision: 130602

URL: http://llvm.org/viewvc/llvm-project?rev=130602&view=rev
Log:
Hoist all of the type-specific trait logic for __is_standard_layout into
a Type method isStandardLayoutType, to keep our user API matching the
type trait builtins as closely as possible. Also, implement it in terms
of other Type APIs rather than in terms of other type traits. This
models the implementation on that of isLiteralType and isTrivialType.
There remain some common problems with these traits still, so this is
a bit of a WIP. However, we can now fix all of these traits at the same
time and in a consistent manner.

Modified:
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=130602&r1=130601&r2=130602&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Sat Apr 30 04:17:49 2011
@@ -1179,6 +1179,10 @@
   /// (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.
@@ -2842,9 +2846,6 @@
   // 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); }
 

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=130602&r1=130601&r2=130602&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Sat Apr 30 04:17:49 2011
@@ -943,9 +943,36 @@
   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;
@@ -1448,17 +1475,6 @@
   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());
 }

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=130602&r1=130601&r2=130602&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Sat Apr 30 04:17:49 2011
@@ -2438,22 +2438,7 @@
   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:





More information about the cfe-commits mailing list