summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ExprCXX.cpp6
-rw-r--r--clang/lib/Parse/ParseExpr.cpp1
-rw-r--r--clang/lib/Sema/Sema.h4
-rw-r--r--clang/lib/Sema/SemaDecl.cpp34
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp13
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp1
6 files changed, 46 insertions, 13 deletions
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index 454dc14b6c8..006f69890ab 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -223,6 +223,12 @@ bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) const {
if (const RecordType *RT = QueriedType->getAs<RecordType>())
return cast<CXXRecordDecl>(RT->getDecl())->isAbstract();
return false;
+ case UTT_IsEmpty:
+ if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
+ return !Record->getDecl()->isUnion()
+ && cast<CXXRecordDecl>(Record->getDecl())->isEmpty();
+ }
+ return false;
case UTT_HasTrivialConstructor:
// http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
// If __is_pod (type) is true then the trait is true, else if type is
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 6e7deef95dc..57604a8dc9f 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -815,6 +815,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
case tok::kw___is_class:
case tok::kw___is_enum:
case tok::kw___is_union:
+ case tok::kw___is_empty:
case tok::kw___is_polymorphic:
case tok::kw___is_abstract:
case tok::kw___has_trivial_constructor:
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index ddd6d7b5712..98fa698a8df 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -3324,8 +3324,10 @@ public:
/// VerifyBitField - verifies that a bit field expression is an ICE and has
/// the correct width, and that the field type is valid.
/// Returns false on success.
+ /// Can optionally return whether the bit-field is of width 0
bool VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
- QualType FieldTy, const Expr *BitWidth);
+ QualType FieldTy, const Expr *BitWidth,
+ bool *ZeroWidth = 0);
//===--------------------------------------------------------------------===//
// Extra semantic analysis beyond the C type system
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index d75f322aa55..bf1dd91f74b 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2536,6 +2536,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
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 @@ void Sema::ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagD,
// 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 @@ bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
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 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
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 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
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 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
}
}
- 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)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index a8afa4f1de2..889d5c91caa 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -383,12 +383,16 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
SpecifierRange))
return 0;
- // If the base class is polymorphic, the new one is, too.
+ // If the base class is polymorphic or isn't empty, the new one is/isn't, too.
RecordDecl *BaseDecl = BaseType->getAs<RecordType>()->getDecl();
assert(BaseDecl && "Record type has no declaration");
BaseDecl = BaseDecl->getDefinition(Context);
assert(BaseDecl && "Base type is not incomplete, but has no definition");
- if (cast<CXXRecordDecl>(BaseDecl)->isPolymorphic())
+ CXXRecordDecl * CXXBaseDecl = cast<CXXRecordDecl>(BaseDecl);
+ assert(CXXBaseDecl && "Base type is not a C++ type");
+ if (!CXXBaseDecl->isEmpty())
+ Class->setEmpty(false);
+ if (CXXBaseDecl->isPolymorphic())
Class->setPolymorphic(true);
// C++ [dcl.init.aggr]p1:
@@ -409,6 +413,11 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
// A copy assignment operator is trivial if its class has no virtual
// base classes.
Class->setHasTrivialCopyAssignment(false);
+
+ // C++0x [meta.unary.prop] is_empty:
+ // T is a class type, but not a union type, with ... no virtual base
+ // classes
+ Class->setEmpty(false);
} else {
// C++ [class.ctor]p5:
// A constructor is trivial if all the direct base classes of its
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 32129231945..b216ec18bfc 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -749,6 +749,7 @@ TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New,
New->setVirtualAsWritten(true);
Record->setAggregate(false);
Record->setPOD(false);
+ Record->setEmpty(false);
Record->setPolymorphic(true);
}
if (Tmpl->isPure()) {
OpenPOWER on IntegriCloud