[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