refactor C++ bitfield checking a bit (haha)

llvm-svn: 66213
This commit is contained in:
Chris Lattner 2009-03-05 23:01:03 +00:00
parent f804897ee9
commit d26760aecb
4 changed files with 39 additions and 61 deletions

View File

@ -244,10 +244,10 @@ DIAG(err_mutable_nonmember, ERROR,
"'mutable' can only be applied to member variables")
DIAG(err_virtual_non_function, ERROR,
"'virtual' can only appear on non-static member functions")
DIAG(err_not_bitfield_type, ERROR,
"cannot declare %0 to be a bit-field type")
DIAG(err_static_not_bitfield, ERROR,
"static member %0 cannot be a bit-field")
DIAG(err_typedef_not_bitfield, ERROR,
"typedef member %0 cannot be a bit-field")
DIAG(err_not_integral_type_bitfield, ERROR,
"bit-field %0 has non-integral type")
DIAG(err_member_initialization, ERROR,

View File

@ -3152,12 +3152,14 @@ void Sema::ActOnTagFinishDefinition(Scope *S, DeclTy *TagD) {
bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
QualType FieldTy, const Expr *BitWidth) {
// C99 6.7.2.1p4 - verify the field type.
// C++ 9.6p3: A bit-field shall have integral or enumeration type.
if (!FieldTy->isIntegralType()) {
// Handle incomplete types with specific error.
if (FieldTy->isIncompleteType())
return Diag(FieldLoc, diag::err_field_incomplete) << FieldTy;
return Diag(FieldLoc, diag::err_not_integral_type_bitfield) << FieldName;
return Diag(FieldLoc, diag::err_field_incomplete)
<< FieldTy << BitWidth->getSourceRange();
return Diag(FieldLoc, diag::err_not_integral_type_bitfield)
<< FieldName << BitWidth->getSourceRange();
}
llvm::APSInt Value;

View File

@ -545,8 +545,6 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
!isFunc);
Decl *Member;
bool InvalidDecl = false;
if (isInstField) {
FieldDecl *FD =
HandleField(S, cast<CXXRecordDecl>(CurContext), Loc, D, BitWidth);
@ -555,6 +553,31 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
Member = FD;
} else {
Member = static_cast<Decl*>(ActOnDeclarator(S, D, LastInGroup));
// Non-instance-fields can't have a bitfield.
if (BitWidth) {
if (Member->isInvalidDecl()) {
// don't emit another diagnostic.
} else if (isa<CXXClassVarDecl>(Member)) {
// C++ 9.6p3: A bit-field shall not be a static member.
// "static member 'A' cannot be a bit-field"
Diag(Loc, diag::err_static_not_bitfield)
<< Name << BitWidth->getSourceRange();
} else if (isa<TypedefDecl>(Member)) {
// "typedef member 'x' cannot be a bit-field"
Diag(Loc, diag::err_typedef_not_bitfield)
<< Name << BitWidth->getSourceRange();
} else {
// A function typedef ("typedef int f(); f a;").
// C++ 9.6p3: A bit-field shall have integral or enumeration type.
Diag(Loc, diag::err_not_integral_type_bitfield)
<< Name << BitWidth->getSourceRange();
}
DeleteExpr(BitWidth);
BitWidth = 0;
Member->setInvalidDecl();
}
}
if (!Member) return LastInGroup;
@ -579,7 +602,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
if (DS.isVirtualSpecified()) {
if (!isFunc || DS.getStorageClassSpec() == DeclSpec::SCS_static) {
Diag(DS.getVirtualSpecLoc(), diag::err_virtual_non_function);
InvalidDecl = true;
Member->setInvalidDecl();
} else {
cast<CXXMethodDecl>(Member)->setVirtual();
CXXRecordDecl *CurClass = cast<CXXRecordDecl>(CurContext);
@ -593,50 +616,6 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
// also virtual if it overrides an already virtual function. This is important
// to do here because it decides the validity of a pure specifier.
if (BitWidth) {
// C++ 9.6p2: Only when declaring an unnamed bit-field may the
// constant-expression be a value equal to zero.
// FIXME: Check this.
if (D.isFunctionDeclarator()) {
// FIXME: Emit diagnostic about only constructors taking base initializers
// or something similar, when constructor support is in place.
Diag(Loc, diag::err_not_bitfield_type)
<< Name << BitWidth->getSourceRange();
InvalidDecl = true;
} else if (isInstField) {
// C++ 9.6p3: A bit-field shall have integral or enumeration type.
if (!cast<FieldDecl>(Member)->getType()->isIntegralType()) {
Diag(Loc, diag::err_not_integral_type_bitfield)
<< Name << BitWidth->getSourceRange();
InvalidDecl = true;
}
} else if (isa<FunctionDecl>(Member)) {
// A function typedef ("typedef int f(); f a;").
// C++ 9.6p3: A bit-field shall have integral or enumeration type.
Diag(Loc, diag::err_not_integral_type_bitfield)
<< Name << BitWidth->getSourceRange();
InvalidDecl = true;
} else if (isa<TypedefDecl>(Member)) {
// "cannot declare 'A' to be a bit-field type"
Diag(Loc, diag::err_not_bitfield_type)
<< Name << BitWidth->getSourceRange();
InvalidDecl = true;
} else {
assert(isa<CXXClassVarDecl>(Member) &&
"Didn't we cover all member kinds?");
// C++ 9.6p3: A bit-field shall not be a static member.
// "static member 'A' cannot be a bit-field"
Diag(Loc, diag::err_static_not_bitfield)
<< Name << BitWidth->getSourceRange();
InvalidDecl = true;
}
}
if (Init) {
// C++ 9.2p4: A member-declarator can contain a constant-initializer only
// if it declares a static member of const integral or const enumeration
@ -649,13 +628,13 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
CVD->getType()->isIntegralType()) {
// constant-initializer
if (CheckForConstantInitializer(Init, CVD->getType()))
InvalidDecl = true;
Member->setInvalidDecl();
} else {
// not const integral.
Diag(Loc, diag::err_member_initialization)
<< Name << Init->getSourceRange();
InvalidDecl = true;
Member->setInvalidDecl();
}
} else {
@ -672,24 +651,21 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
else {
Diag(Loc, diag::err_non_virtual_pure)
<< Name << Init->getSourceRange();
InvalidDecl = true;
Member->setInvalidDecl();
}
} else {
Diag(Loc, diag::err_member_function_initialization)
<< Name << Init->getSourceRange();
InvalidDecl = true;
Member->setInvalidDecl();
}
} else {
Diag(Loc, diag::err_member_initialization)
<< Name << Init->getSourceRange();
InvalidDecl = true;
Member->setInvalidDecl();
}
}
}
if (InvalidDecl)
Member->setInvalidDecl();
if (isInstField) {
FieldCollector->Add(cast<FieldDecl>(Member));
return LastInGroup;

View File

@ -20,7 +20,7 @@ public:
int b : 1, w : 2;
int : 1, : 2;
typedef int E : 1; // expected-error {{error: cannot declare 'E' to be a bit-field type}}
typedef int E : 1; // expected-error {{typedef member 'E' cannot be a bit-field}}
static int sb : 1; // expected-error {{error: static member 'sb' cannot be a bit-field}}
static int vs;