[llvm-branch-commits] [cfe-branch] r226593 - Revert "r222906 - Create a new 'flag_enum' attribute."

Hans Wennborg hans at hanshq.net
Tue Jan 20 11:27:49 PST 2015


Author: hans
Date: Tue Jan 20 13:27:49 2015
New Revision: 226593

URL: http://llvm.org/viewvc/llvm-project?rev=226593&view=rev
Log:
Revert "r222906 - Create a new 'flag_enum' attribute."

Removed:
    cfe/branches/release_36/test/Sema/attr-flag-enum.c
    cfe/branches/release_36/test/SemaCXX/attr-flag-enum-reject.cpp
Modified:
    cfe/branches/release_36/include/clang/Basic/Attr.td
    cfe/branches/release_36/include/clang/Basic/AttrDocs.td
    cfe/branches/release_36/include/clang/Basic/DiagnosticGroups.td
    cfe/branches/release_36/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/branches/release_36/include/clang/Sema/AttributeList.h
    cfe/branches/release_36/include/clang/Sema/Sema.h
    cfe/branches/release_36/lib/Sema/SemaDecl.cpp
    cfe/branches/release_36/lib/Sema/SemaDeclAttr.cpp
    cfe/branches/release_36/lib/Sema/SemaStmt.cpp
    cfe/branches/release_36/utils/TableGen/ClangAttrEmitter.cpp

Modified: cfe/branches/release_36/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_36/include/clang/Basic/Attr.td?rev=226593&r1=226592&r2=226593&view=diff
==============================================================================
--- cfe/branches/release_36/include/clang/Basic/Attr.td (original)
+++ cfe/branches/release_36/include/clang/Basic/Attr.td Tue Jan 20 13:27:49 2015
@@ -224,14 +224,12 @@ class SubjectList<list<AttrSubject> subj
   string CustomDiag = customDiag;
 }
 
-class LangOpt<string name, bit negated = 0> {
+class LangOpt<string name> {
   string Name = name;
-  bit Negated = negated;
 }
 def MicrosoftExt : LangOpt<"MicrosoftExt">;
 def Borland : LangOpt<"Borland">;
 def CUDA : LangOpt<"CUDA">;
-def COnly : LangOpt<"CPlusPlus", 1>;
 
 // Defines targets for target-specific attributes. The list of strings should
 // specify architectures for which the target applies, based off the ArchType
@@ -709,25 +707,6 @@ def MinSize : InheritableAttr {
   let Documentation = [Undocumented];
 }
 
-def FlagEnum : InheritableAttr {
-  let Spellings = [GNU<"flag_enum">];
-  let Subjects = SubjectList<[Enum]>;
-  let Documentation = [FlagEnumDocs];
-  let LangOpts = [COnly];
-  let AdditionalMembers = [{
-private:
-    llvm::APInt FlagBits;
-public:
-    llvm::APInt &getFlagBits() {
-      return FlagBits;
-    }
-
-    const llvm::APInt &getFlagBits() const {
-      return FlagBits;
-    }
-}];
-}
-
 def Flatten : InheritableAttr {
   let Spellings = [GCC<"flatten">];
   let Subjects = SubjectList<[Function], ErrorDiag>;

Modified: cfe/branches/release_36/include/clang/Basic/AttrDocs.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_36/include/clang/Basic/AttrDocs.td?rev=226593&r1=226592&r2=226593&view=diff
==============================================================================
--- cfe/branches/release_36/include/clang/Basic/AttrDocs.td (original)
+++ cfe/branches/release_36/include/clang/Basic/AttrDocs.td Tue Jan 20 13:27:49 2015
@@ -1196,16 +1196,6 @@ behavior of the program is undefined.
   }];
 }
 
-def FlagEnumDocs : Documentation {
-  let Category = DocCatType;
-  let Content = [{
-This attribute can be added to an enumerator to signal to the compiler that it
-is intended to be used as a flag type. This will cause the compiler to assume
-that the range of the type includes all of the values that you can get by
-manipulating bits of the enumerator when issuing warnings.
-  }];
-}
-
 def MSInheritanceDocs : Documentation {
   let Category = DocCatType;
   let Heading = "__single_inhertiance, __multiple_inheritance, __virtual_inheritance";

Modified: cfe/branches/release_36/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_36/include/clang/Basic/DiagnosticGroups.td?rev=226593&r1=226592&r2=226593&view=diff
==============================================================================
--- cfe/branches/release_36/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/branches/release_36/include/clang/Basic/DiagnosticGroups.td Tue Jan 20 13:27:49 2015
@@ -190,7 +190,6 @@ def OverloadedShiftOpParentheses: DiagGr
 def DanglingElse: DiagGroup<"dangling-else">;
 def DanglingField : DiagGroup<"dangling-field">;
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
-def FlagEnum : DiagGroup<"flag-enum">;
 def InfiniteRecursion : DiagGroup<"infinite-recursion">;
 def GNUImaginaryConstant : DiagGroup<"gnu-imaginary-constant">;
 def IgnoredQualifiers : DiagGroup<"ignored-qualifiers">;

Modified: cfe/branches/release_36/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_36/include/clang/Basic/DiagnosticSemaKinds.td?rev=226593&r1=226592&r2=226593&view=diff
==============================================================================
--- cfe/branches/release_36/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/branches/release_36/include/clang/Basic/DiagnosticSemaKinds.td Tue Jan 20 13:27:49 2015
@@ -2236,7 +2236,7 @@ def warn_attribute_wrong_decl_type : War
   "%0 attribute only applies to %select{functions|unions|"
   "variables and functions|functions and methods|parameters|"
   "functions, methods and blocks|functions, methods, and classes|"
-  "functions, methods, and parameters|classes|enums|variables|methods|"
+  "functions, methods, and parameters|classes|variables|methods|"
   "variables, functions and labels|fields and global variables|structs|"
   "variables and typedefs|thread-local variables|"
   "variables and fields|variables, data members and tag types|"
@@ -4059,9 +4059,6 @@ def ext_enum_too_large : ExtWarn<
 def ext_enumerator_increment_too_large : ExtWarn<
   "incremented enumerator value %0 is not representable in the "
   "largest integer type">, InGroup<EnumTooLarge>;
-def warn_flag_enum_constant_out_of_range : Warning<
-  "enumeration value %0 is out of range of flags in enumeration type %1">,
-  InGroup<FlagEnum>;
   
 def warn_illegal_constant_array_size : Extension<
   "size of static array must be an integer constant expression">;

Modified: cfe/branches/release_36/include/clang/Sema/AttributeList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_36/include/clang/Sema/AttributeList.h?rev=226593&r1=226592&r2=226593&view=diff
==============================================================================
--- cfe/branches/release_36/include/clang/Sema/AttributeList.h (original)
+++ cfe/branches/release_36/include/clang/Sema/AttributeList.h Tue Jan 20 13:27:49 2015
@@ -822,7 +822,6 @@ enum AttributeDeclKind {
   ExpectedFunctionMethodOrClass,
   ExpectedFunctionMethodOrParameter,
   ExpectedClass,
-  ExpectedEnum,
   ExpectedVariable,
   ExpectedMethod,
   ExpectedVariableFunctionOrLabel,

Modified: cfe/branches/release_36/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_36/include/clang/Sema/Sema.h?rev=226593&r1=226592&r2=226593&view=diff
==============================================================================
--- cfe/branches/release_36/include/clang/Sema/Sema.h (original)
+++ cfe/branches/release_36/include/clang/Sema/Sema.h Tue Jan 20 13:27:49 2015
@@ -7971,12 +7971,6 @@ public:
                                 Expr *SrcExpr, AssignmentAction Action,
                                 bool *Complained = nullptr);
 
-  /// IsValueInFlagEnum - Determine if a value is allowed as part of a flag
-  /// enum. If AllowMask is true, then we also allow the complement of a valid
-  /// value, to be used as a mask.
-  bool IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val,
-                         bool AllowMask) const;
-
   /// DiagnoseAssignmentEnum - Warn if assignment to enum is a constant
   /// integer not in the range of enum values.
   void DiagnoseAssignmentEnum(QualType DstType, QualType SrcType,

Modified: cfe/branches/release_36/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_36/lib/Sema/SemaDecl.cpp?rev=226593&r1=226592&r2=226593&view=diff
==============================================================================
--- cfe/branches/release_36/lib/Sema/SemaDecl.cpp (original)
+++ cfe/branches/release_36/lib/Sema/SemaDecl.cpp Tue Jan 20 13:27:49 2015
@@ -13519,49 +13519,6 @@ static void CheckForDuplicateEnumValues(
   }
 }
 
-bool
-Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val,
-                        bool AllowMask) const {
-  FlagEnumAttr *FEAttr = ED->getAttr<FlagEnumAttr>();
-  assert(FEAttr && "looking for value in non-flag enum");
-
-  llvm::APInt FlagMask = ~FEAttr->getFlagBits();
-  unsigned Width = FlagMask.getBitWidth();
-
-  // We will try a zero-extended value for the regular check first.
-  llvm::APInt ExtVal = Val.zextOrSelf(Width);
-
-  // A value is in a flag enum if either its bits are a subset of the enum's
-  // flag bits (the first condition) or we are allowing masks and the same is
-  // true of its complement (the second condition). When masks are allowed, we
-  // allow the common idiom of ~(enum1 | enum2) to be a valid enum value.
-  //
-  // While it's true that any value could be used as a mask, the assumption is
-  // that a mask will have all of the insignificant bits set. Anything else is
-  // likely a logic error.
-  if (!(FlagMask & ExtVal))
-    return true;
-
-  if (AllowMask) {
-    // Try a one-extended value instead. This can happen if the enum is wider
-    // than the constant used, in C with extensions to allow for wider enums.
-    // The mask will still have the correct behaviour, so we give the user the
-    // benefit of the doubt.
-    //
-    // FIXME: This heuristic can cause weird results if the enum was extended
-    // to a larger type and is signed, because then bit-masks of smaller types
-    // that get extended will fall out of range (e.g. ~0x1u). We currently don't
-    // detect that case and will get a false positive for it. In most cases,
-    // though, it can be fixed by making it a signed type (e.g. ~0x1), so it may
-    // be fine just to accept this as a warning.
-    ExtVal |= llvm::APInt::getHighBitsSet(Width, Width - Val.getBitWidth());
-    if (!(FlagMask & ~ExtVal))
-      return true;
-  }
-
-  return false;
-}
-
 void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
                          SourceLocation RBraceLoc, Decl *EnumDeclX,
                          ArrayRef<Decl *> Elements,
@@ -13647,8 +13604,10 @@ void Sema::ActOnEnumBody(SourceLocation
       BestPromotionType = Context.getPromotedIntegerType(BestType);
     else
       BestPromotionType = BestType;
-
-    BestWidth = Context.getIntWidth(BestType);
+    // We don't need to set BestWidth, because BestType is going to be the type
+    // of the enumerators, but we do anyway because otherwise some compilers
+    // warn that it might be used uninitialized.
+    BestWidth = CharWidth;
   }
   else if (NumNegativeBits) {
     // If there is a negative value, figure out the smallest integer type (of
@@ -13713,15 +13672,10 @@ void Sema::ActOnEnumBody(SourceLocation
     }
   }
 
-  FlagEnumAttr *FEAttr = Enum->getAttr<FlagEnumAttr>();
-  if (FEAttr)
-    FEAttr->getFlagBits() = llvm::APInt(BestWidth, 0);
-
   // Loop over all of the enumerator constants, changing their types to match
-  // the type of the enum if needed. If we have a flag type, we also prepare the
-  // FlagBits cache.
-  for (auto *D : Elements) {
-    auto *ECD = cast_or_null<EnumConstantDecl>(D);
+  // the type of the enum if needed.
+  for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
+    EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(Elements[i]);
     if (!ECD) continue;  // Already issued a diagnostic.
 
     // Standard C says the enumerators have int type, but we allow, as an
@@ -13751,7 +13705,7 @@ void Sema::ActOnEnumBody(SourceLocation
         // enum-specifier, each enumerator has the type of its
         // enumeration.
         ECD->setType(EnumType);
-      goto flagbits;
+      continue;
     } else {
       NewTy = BestType;
       NewWidth = BestWidth;
@@ -13778,32 +13732,8 @@ void Sema::ActOnEnumBody(SourceLocation
       ECD->setType(EnumType);
     else
       ECD->setType(NewTy);
-
-flagbits:
-    // Check to see if we have a constant with exactly one bit set. Note that x
-    // & (x - 1) will be nonzero if and only if x has more than one bit set.
-    if (FEAttr) {
-      llvm::APInt ExtVal = InitVal.zextOrSelf(BestWidth);
-      if (ExtVal != 0 && !(ExtVal & (ExtVal - 1))) {
-        FEAttr->getFlagBits() |= ExtVal;
-      }
-    }
   }
 
-  if (FEAttr) {
-    for (Decl *D : Elements) {
-      EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(D);
-      if (!ECD) continue;  // Already issued a diagnostic.
-
-      llvm::APSInt InitVal = ECD->getInitVal();
-      if (InitVal != 0 && !IsValueInFlagEnum(Enum, InitVal, true))
-        Diag(ECD->getLocation(), diag::warn_flag_enum_constant_out_of_range)
-          << ECD << Enum;
-    }
-  }
-
-
-
   Enum->completeDefinition(BestType, BestPromotionType,
                            NumPositiveBits, NumNegativeBits);
 

Modified: cfe/branches/release_36/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_36/lib/Sema/SemaDeclAttr.cpp?rev=226593&r1=226592&r2=226593&view=diff
==============================================================================
--- cfe/branches/release_36/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/branches/release_36/lib/Sema/SemaDeclAttr.cpp Tue Jan 20 13:27:49 2015
@@ -4395,9 +4395,6 @@ static void ProcessDeclAttribute(Sema &S
   case AttributeList::AT_OptimizeNone:
     handleOptimizeNoneAttr(S, D, Attr);
     break;
-  case AttributeList::AT_FlagEnum:
-    handleSimpleAttribute<FlagEnumAttr>(S, D, Attr);
-    break;
   case AttributeList::AT_Flatten:
     handleSimpleAttribute<FlattenAttr>(S, D, Attr);
     break;

Modified: cfe/branches/release_36/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_36/lib/Sema/SemaStmt.cpp?rev=226593&r1=226592&r2=226593&view=diff
==============================================================================
--- cfe/branches/release_36/lib/Sema/SemaStmt.cpp (original)
+++ cfe/branches/release_36/lib/Sema/SemaStmt.cpp Tue Jan 20 13:27:49 2015
@@ -687,39 +687,26 @@ static void checkCaseValue(Sema &S, Sour
   }
 }
 
-typedef SmallVector<std::pair<llvm::APSInt, EnumConstantDecl*>, 64> EnumValsTy;
-
 /// Returns true if we should emit a diagnostic about this case expression not
 /// being a part of the enum used in the switch controlling expression.
-static bool ShouldDiagnoseSwitchCaseNotInEnum(const Sema &S,
+static bool ShouldDiagnoseSwitchCaseNotInEnum(const ASTContext &Ctx,
                                               const EnumDecl *ED,
-                                              const Expr *CaseExpr,
-                                              EnumValsTy::iterator &EI,
-                                              EnumValsTy::iterator &EIEnd,
-                                              const llvm::APSInt &Val) {
-  bool FlagType = ED->hasAttr<FlagEnumAttr>();
-
-  if (const DeclRefExpr *DRE =
-          dyn_cast<DeclRefExpr>(CaseExpr->IgnoreParenImpCasts())) {
+                                              const Expr *CaseExpr) {
+  // Don't warn if the 'case' expression refers to a static const variable of
+  // the enum type.
+  CaseExpr = CaseExpr->IgnoreParenImpCasts();
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseExpr)) {
     if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
+      if (!VD->hasGlobalStorage())
+        return true;
       QualType VarType = VD->getType();
-      QualType EnumType = S.Context.getTypeDeclType(ED);
-      if (VD->hasGlobalStorage() && VarType.isConstQualified() &&
-          S.Context.hasSameUnqualifiedType(EnumType, VarType))
+      if (!VarType.isConstQualified())
+        return true;
+      QualType EnumType = Ctx.getTypeDeclType(ED);
+      if (Ctx.hasSameUnqualifiedType(EnumType, VarType))
         return false;
     }
   }
-
-  if (FlagType) {
-    return !S.IsValueInFlagEnum(ED, Val, false);
-  } else {
-    while (EI != EIEnd && EI->first < Val)
-      EI++;
-
-    if (EI != EIEnd && EI->first == Val)
-      return false;
-  }
-
   return true;
 }
 
@@ -1059,6 +1046,8 @@ Sema::ActOnFinishSwitchStmt(SourceLocati
     // If switch has default case, then ignore it.
     if (!CaseListIsErroneous  && !HasConstantCond && ET) {
       const EnumDecl *ED = ET->getDecl();
+      typedef SmallVector<std::pair<llvm::APSInt, EnumConstantDecl*>, 64>
+        EnumValsTy;
       EnumValsTy EnumVals;
 
       // Gather all enum values, set their type and sort them,
@@ -1069,48 +1058,57 @@ Sema::ActOnFinishSwitchStmt(SourceLocati
         EnumVals.push_back(std::make_pair(Val, EDI));
       }
       std::stable_sort(EnumVals.begin(), EnumVals.end(), CmpEnumVals);
-      auto EI = EnumVals.begin(), EIEnd =
+      EnumValsTy::iterator EIend =
         std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals);
 
       // See which case values aren't in enum.
+      EnumValsTy::const_iterator EI = EnumVals.begin();
       for (CaseValsTy::const_iterator CI = CaseVals.begin();
-          CI != CaseVals.end(); CI++) {
-        Expr *CaseExpr = CI->second->getLHS();
-        if (ShouldDiagnoseSwitchCaseNotInEnum(*this, ED, CaseExpr, EI, EIEnd,
-                                              CI->first))
-          Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
-            << CondTypeBeforePromotion;
+           CI != CaseVals.end(); CI++) {
+        while (EI != EIend && EI->first < CI->first)
+          EI++;
+        if (EI == EIend || EI->first > CI->first) {
+          Expr *CaseExpr = CI->second->getLHS();
+          if (ShouldDiagnoseSwitchCaseNotInEnum(Context, ED, CaseExpr))
+            Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
+              << CondTypeBeforePromotion;
+        }
       }
-
       // See which of case ranges aren't in enum
       EI = EnumVals.begin();
       for (CaseRangesTy::const_iterator RI = CaseRanges.begin();
-          RI != CaseRanges.end(); RI++) {
-        Expr *CaseExpr = RI->second->getLHS();
-        if (ShouldDiagnoseSwitchCaseNotInEnum(*this, ED, CaseExpr, EI, EIEnd,
-                                              RI->first))
-          Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
-            << CondTypeBeforePromotion;
+           RI != CaseRanges.end() && EI != EIend; RI++) {
+        while (EI != EIend && EI->first < RI->first)
+          EI++;
+
+        if (EI == EIend || EI->first != RI->first) {
+          Expr *CaseExpr = RI->second->getLHS();
+          if (ShouldDiagnoseSwitchCaseNotInEnum(Context, ED, CaseExpr))
+            Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
+              << CondTypeBeforePromotion;
+        }
 
         llvm::APSInt Hi =
           RI->second->getRHS()->EvaluateKnownConstInt(Context);
         AdjustAPSInt(Hi, CondWidth, CondIsSigned);
-
-        CaseExpr = RI->second->getRHS();
-        if (ShouldDiagnoseSwitchCaseNotInEnum(*this, ED, CaseExpr, EI, EIEnd,
-                                              Hi))
-          Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
-            << CondTypeBeforePromotion;
+        while (EI != EIend && EI->first < Hi)
+          EI++;
+        if (EI == EIend || EI->first != Hi) {
+          Expr *CaseExpr = RI->second->getRHS();
+          if (ShouldDiagnoseSwitchCaseNotInEnum(Context, ED, CaseExpr))
+            Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
+              << CondTypeBeforePromotion;
+        }
       }
 
       // Check which enum vals aren't in switch
-      auto CI = CaseVals.begin();
-      auto RI = CaseRanges.begin();
+      CaseValsTy::const_iterator CI = CaseVals.begin();
+      CaseRangesTy::const_iterator RI = CaseRanges.begin();
       bool hasCasesNotInSwitch = false;
 
       SmallVector<DeclarationName,8> UnhandledNames;
 
-      for (EI = EnumVals.begin(); EI != EIEnd; EI++){
+      for (EI = EnumVals.begin(); EI != EIend; EI++){
         // Drop unneeded case values
         while (CI != CaseVals.end() && CI->first < EI->first)
           CI++;
@@ -1197,37 +1195,30 @@ Sema::DiagnoseAssignmentEnum(QualType Ds
         llvm::APSInt RhsVal = SrcExpr->EvaluateKnownConstInt(Context);
         AdjustAPSInt(RhsVal, DstWidth, DstIsSigned);
         const EnumDecl *ED = ET->getDecl();
-
-        if (ED->hasAttr<FlagEnumAttr>()) {
-          if (!IsValueInFlagEnum(ED, RhsVal, true))
-            Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment)
+        typedef SmallVector<std::pair<llvm::APSInt, EnumConstantDecl *>, 64>
+            EnumValsTy;
+        EnumValsTy EnumVals;
+
+        // Gather all enum values, set their type and sort them,
+        // allowing easier comparison with rhs constant.
+        for (auto *EDI : ED->enumerators()) {
+          llvm::APSInt Val = EDI->getInitVal();
+          AdjustAPSInt(Val, DstWidth, DstIsSigned);
+          EnumVals.push_back(std::make_pair(Val, EDI));
+        }
+        if (EnumVals.empty())
+          return;
+        std::stable_sort(EnumVals.begin(), EnumVals.end(), CmpEnumVals);
+        EnumValsTy::iterator EIend =
+            std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals);
+
+        // See which values aren't in the enum.
+        EnumValsTy::const_iterator EI = EnumVals.begin();
+        while (EI != EIend && EI->first < RhsVal)
+          EI++;
+        if (EI == EIend || EI->first != RhsVal) {
+          Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment)
               << DstType.getUnqualifiedType();
-        } else {
-          typedef SmallVector<std::pair<llvm::APSInt, EnumConstantDecl *>, 64>
-              EnumValsTy;
-          EnumValsTy EnumVals;
-
-          // Gather all enum values, set their type and sort them,
-          // allowing easier comparison with rhs constant.
-          for (auto *EDI : ED->enumerators()) {
-            llvm::APSInt Val = EDI->getInitVal();
-            AdjustAPSInt(Val, DstWidth, DstIsSigned);
-            EnumVals.push_back(std::make_pair(Val, EDI));
-          }
-          if (EnumVals.empty())
-            return;
-          std::stable_sort(EnumVals.begin(), EnumVals.end(), CmpEnumVals);
-          EnumValsTy::iterator EIend =
-              std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals);
-
-          // See which values aren't in the enum.
-          EnumValsTy::const_iterator EI = EnumVals.begin();
-          while (EI != EIend && EI->first < RhsVal)
-            EI++;
-          if (EI == EIend || EI->first != RhsVal) {
-            Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment)
-                << DstType.getUnqualifiedType();
-          }
         }
       }
     }

Removed: cfe/branches/release_36/test/Sema/attr-flag-enum.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_36/test/Sema/attr-flag-enum.c?rev=226592&view=auto
==============================================================================
--- cfe/branches/release_36/test/Sema/attr-flag-enum.c (original)
+++ cfe/branches/release_36/test/Sema/attr-flag-enum.c (removed)
@@ -1,73 +0,0 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -std=c11 -Wassign-enum %s
-
-enum __attribute__((flag_enum)) flag {
-  ea = 0x1,
-  eb = 0x2,
-  ec = 0x8,
-};
-
-enum __attribute__((flag_enum)) flag2 {
-  ga = 0x1,
-  gb = 0x4,
-
-  gc = 0x5, // no-warning
-  gd = 0x7, // expected-warning {{enumeration value 'gd' is out of range}}
-  ge = ~0x2, // expected-warning {{enumeration value 'ge' is out of range}}
-  gf = ~0x4, // no-warning
-  gg = ~0x1, // no-warning
-  gh = ~0x5, // no-warning
-  gi = ~0x11, // expected-warning {{enumeration value 'gi' is out of range}}
-};
-
-enum __attribute__((flag_enum)) flag3 {
-  fa = 0x1,
-  fb = ~0x1u, // no-warning
-};
-
-// What happens here is that ~0x2 is negative, and so the enum must be signed.
-// But ~0x1u is unsigned and has the high bit set, so the enum must be 64-bit.
-// The result is that ~0x1u does not have high bits set, and so it is considered
-// to be an invalid value. See Sema::IsValueInFlagEnum in SemaDecl.cpp for more
-// discussion.
-enum __attribute__((flag_enum)) flag4 {
-  ha = 0x1,
-  hb = 0x2,
-
-  hc = ~0x1u, // expected-warning {{enumeration value 'hc' is out of range}}
-  hd = ~0x2, // no-warning
-};
-
-void f(void) {
-  enum flag e = 0; // no-warning
-  e = 0x1; // no-warning
-  e = 0x3; // no-warning
-  e = 0xa; // no-warning
-  e = 0x4; // expected-warning {{integer constant not in range of enumerated type}}
-  e = 0xf; // expected-warning {{integer constant not in range of enumerated type}}
-  e = ~0; // no-warning
-  e = ~0x1; // no-warning
-  e = ~0x2; // no-warning
-  e = ~0x3; // no-warning
-  e = ~0x4; // expected-warning {{integer constant not in range of enumerated type}}
-
-  switch (e) {
-    case 0: break; // no-warning
-    case 0x1: break; // no-warning
-    case 0x3: break; // no-warning
-    case 0xa: break; // no-warning
-    case 0x4: break; // expected-warning {{case value not in enumerated type}}
-    case 0xf: break; // expected-warning {{case value not in enumerated type}}
-    case ~0: break; // expected-warning {{case value not in enumerated type}}
-    case ~0x1: break; // expected-warning {{case value not in enumerated type}}
-    case ~0x2: break; // expected-warning {{case value not in enumerated type}}
-    case ~0x3: break; // expected-warning {{case value not in enumerated type}}
-    case ~0x4: break; // expected-warning {{case value not in enumerated type}}
-    default: break;
-  }
-
-  enum flag2 f = ~0x1; // no-warning
-  f = ~0x1u; // no-warning
-
-  enum flag4 h = ~0x1; // no-warning
-  h = ~0x1u; // expected-warning {{integer constant not in range of enumerated type}}
-}

Removed: cfe/branches/release_36/test/SemaCXX/attr-flag-enum-reject.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_36/test/SemaCXX/attr-flag-enum-reject.cpp?rev=226592&view=auto
==============================================================================
--- cfe/branches/release_36/test/SemaCXX/attr-flag-enum-reject.cpp (original)
+++ cfe/branches/release_36/test/SemaCXX/attr-flag-enum-reject.cpp (removed)
@@ -1,4 +0,0 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -x c++ -Wassign-enum %s
-
-enum __attribute__((flag_enum)) flag { // expected-warning {{ignored}}
-};

Modified: cfe/branches/release_36/utils/TableGen/ClangAttrEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_36/utils/TableGen/ClangAttrEmitter.cpp?rev=226593&r1=226592&r2=226593&view=diff
==============================================================================
--- cfe/branches/release_36/utils/TableGen/ClangAttrEmitter.cpp (original)
+++ cfe/branches/release_36/utils/TableGen/ClangAttrEmitter.cpp Tue Jan 20 13:27:49 2015
@@ -2185,8 +2185,7 @@ static std::string CalculateDiagnostic(c
     Namespace = 1U << 11,
     Field = 1U << 12,
     CXXMethod = 1U << 13,
-    ObjCProtocol = 1U << 14,
-    Enum = 1U << 15
+    ObjCProtocol = 1U << 14
   };
   uint32_t SubMask = 0;
 
@@ -2220,7 +2219,6 @@ static std::string CalculateDiagnostic(c
                    .Case("Namespace", Namespace)
                    .Case("Field", Field)
                    .Case("CXXMethod", CXXMethod)
-                   .Case("Enum", Enum)
                    .Default(0);
     if (!V) {
       // Something wasn't in our mapping, so be helpful and let the developer
@@ -2239,7 +2237,6 @@ static std::string CalculateDiagnostic(c
     case Var:   return "ExpectedVariable";
     case Param: return "ExpectedParameter";
     case Class: return "ExpectedClass";
-    case Enum:  return "ExpectedEnum";
     case CXXMethod:
       // FIXME: Currently, this maps to ExpectedMethod based on existing code,
       // but should map to something a bit more accurate at some point.
@@ -2393,8 +2390,6 @@ static std::string GenerateLangOptRequir
   std::string FnName = "check", Test;
   for (auto I = LangOpts.begin(), E = LangOpts.end(); I != E; ++I) {
     std::string Part = (*I)->getValueAsString("Name");
-    if ((*I)->getValueAsBit("Negated"))
-      Test += "!";
     Test += "S.LangOpts." + Part;
     if (I + 1 != E)
       Test += " || ";





More information about the llvm-branch-commits mailing list