aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Type.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-04-30 09:17:49 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-04-30 09:17:49 +0000
commit636a617cc6021a4366380b3ce673f4472f3d99db (patch)
treef0b747364b0ef1909ef809e07a106db9e86e1341 /lib/AST/Type.cpp
parenta8225449421e8c1e996a7c48300521028946482a (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130602 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Type.cpp')
-rw-r--r--lib/AST/Type.cpp44
1 files changed, 30 insertions, 14 deletions
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 55f01e5822..dbced252aa 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -943,9 +943,36 @@ bool Type::isTrivialType() const {
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 @@ static uint64_t countBasesWithFields(QualType BaseType) {
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());
}