Implement __is_empty. Patch by Sean Hunt.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79143 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index d75f322..bf1dd91 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2536,6 +2536,7 @@
CXXRecordDecl *CurClass = cast<CXXRecordDecl>(DC);
CurClass->setAggregate(false);
CurClass->setPOD(false);
+ CurClass->setEmpty(false);
CurClass->setPolymorphic(true);
CurClass->setHasTrivialConstructor(false);
CurClass->setHasTrivialCopyConstructor(false);
@@ -4331,8 +4332,12 @@
// Note that FieldName may be null for anonymous bitfields.
bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
- QualType FieldTy, const Expr *BitWidth) {
-
+ QualType FieldTy, const Expr *BitWidth,
+ bool *ZeroWidth) {
+ // Default to true; that shouldn't confuse checks for emptiness
+ if (ZeroWidth)
+ *ZeroWidth = true;
+
// C99 6.7.2.1p4 - verify the field type.
// C++ 9.6p3: A bit-field shall have integral or enumeration type.
if (!FieldTy->isDependentType() && !FieldTy->isIntegralType()) {
@@ -4355,6 +4360,9 @@
if (VerifyIntegerConstantExpression(BitWidth, &Value))
return true;
+ if (Value != 0 && ZeroWidth)
+ *ZeroWidth = false;
+
// Zero-width bitfield is ok for anonymous field.
if (Value == 0 && FieldName)
return Diag(FieldLoc, diag::err_bitfield_has_zero_width) << FieldName;
@@ -4490,11 +4498,13 @@
AbstractFieldType))
InvalidDecl = true;
+ bool ZeroWidth = false;
// If this is declared as a bit-field, check the bit-field.
- if (BitWidth && VerifyBitField(Loc, II, T, BitWidth)) {
+ if (BitWidth && VerifyBitField(Loc, II, T, BitWidth, &ZeroWidth)) {
InvalidDecl = true;
DeleteExpr(BitWidth);
BitWidth = 0;
+ ZeroWidth = false;
}
FieldDecl *NewFD = FieldDecl::Create(Context, Record, Loc, II, T, BitWidth,
@@ -4511,17 +4521,24 @@
if (getLangOptions().CPlusPlus) {
QualType EltTy = Context.getBaseElementType(T);
+ CXXRecordDecl* CXXRecord = cast<CXXRecordDecl>(Record);
+
+ if (!T->isPODType())
+ CXXRecord->setPOD(false);
+ if (!ZeroWidth)
+ CXXRecord->setEmpty(false);
+
if (const RecordType *RT = EltTy->getAs<RecordType>()) {
CXXRecordDecl* RDecl = cast<CXXRecordDecl>(RT->getDecl());
if (!RDecl->hasTrivialConstructor())
- cast<CXXRecordDecl>(Record)->setHasTrivialConstructor(false);
+ CXXRecord->setHasTrivialConstructor(false);
if (!RDecl->hasTrivialCopyConstructor())
- cast<CXXRecordDecl>(Record)->setHasTrivialCopyConstructor(false);
+ CXXRecord->setHasTrivialCopyConstructor(false);
if (!RDecl->hasTrivialCopyAssignment())
- cast<CXXRecordDecl>(Record)->setHasTrivialCopyAssignment(false);
+ CXXRecord->setHasTrivialCopyAssignment(false);
if (!RDecl->hasTrivialDestructor())
- cast<CXXRecordDecl>(Record)->setHasTrivialDestructor(false);
+ CXXRecord->setHasTrivialDestructor(false);
// C++ 9.5p1: An object of a class with a non-trivial
// constructor, a non-trivial copy constructor, a non-trivial
@@ -4557,9 +4574,6 @@
}
}
- if (getLangOptions().CPlusPlus && !T->isPODType())
- cast<CXXRecordDecl>(Record)->setPOD(false);
-
// FIXME: We need to pass in the attributes given an AST
// representation, not a parser representation.
if (D)