[cfe-commits] r66213 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.def lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp test/SemaCXX/class.cpp
Chris Lattner
sabre at nondot.org
Thu Mar 5 15:01:03 PST 2009
Author: lattner
Date: Thu Mar 5 17:01:03 2009
New Revision: 66213
URL: http://llvm.org/viewvc/llvm-project?rev=66213&view=rev
Log:
refactor C++ bitfield checking a bit (haha)
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/SemaCXX/class.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def?rev=66213&r1=66212&r2=66213&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def Thu Mar 5 17:01:03 2009
@@ -244,10 +244,10 @@
"'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,
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=66213&r1=66212&r2=66213&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Mar 5 17:01:03 2009
@@ -3152,12 +3152,14 @@
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;
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=66213&r1=66212&r2=66213&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Mar 5 17:01:03 2009
@@ -545,8 +545,6 @@
!isFunc);
Decl *Member;
- bool InvalidDecl = false;
-
if (isInstField) {
FieldDecl *FD =
HandleField(S, cast<CXXRecordDecl>(CurContext), Loc, D, BitWidth);
@@ -555,6 +553,31 @@
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 @@
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 @@
// 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 @@
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 @@
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;
Modified: cfe/trunk/test/SemaCXX/class.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/class.cpp?rev=66213&r1=66212&r2=66213&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/class.cpp (original)
+++ cfe/trunk/test/SemaCXX/class.cpp Thu Mar 5 17:01:03 2009
@@ -20,7 +20,7 @@
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;
More information about the cfe-commits
mailing list