refactor C++ bitfield checking a bit (haha)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66213 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 0e5adc4..178853e 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -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;