summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp31
1 files changed, 13 insertions, 18 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index e01e53397fe..141f35a6a0e 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -14014,25 +14014,23 @@ static void CheckForDuplicateEnumValues(Sema &S, ArrayRef<Decl *> Elements,
}
}
-bool
-Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val,
- bool AllowMask) const {
+bool Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val,
+ bool AllowMask) const {
assert(ED->hasAttr<FlagEnumAttr>() && "looking for value in non-flag enum");
+ assert(ED->isCompleteDefinition() && "expected enum definition");
auto R = FlagBitsCache.insert(std::make_pair(ED, llvm::APInt()));
llvm::APInt &FlagBits = R.first->second;
if (R.second) {
for (auto *E : ED->enumerators()) {
- const auto &Val = E->getInitVal();
+ const auto &EVal = E->getInitVal();
// Only single-bit enumerators introduce new flag values.
- if (Val.isPowerOf2())
- FlagBits = FlagBits.zextOrSelf(Val.getBitWidth()) | Val;
+ if (EVal.isPowerOf2())
+ FlagBits = FlagBits.zextOrSelf(EVal.getBitWidth()) | EVal;
}
}
- llvm::APInt FlagMask = ~FlagBits.zextOrTrunc(Val.getBitWidth());
-
// 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
@@ -14041,11 +14039,8 @@ Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val,
// 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 & Val) ||
- (AllowMask && !(FlagMask & ~Val)))
- return true;
-
- return false;
+ llvm::APInt FlagMask = ~FlagBits.zextOrTrunc(Val.getBitWidth());
+ return !(FlagMask & Val) || (AllowMask && !(FlagMask & ~Val));
}
void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
@@ -14261,6 +14256,11 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
ECD->setType(NewTy);
}
+ Enum->completeDefinition(BestType, BestPromotionType,
+ NumPositiveBits, NumNegativeBits);
+
+ CheckForDuplicateEnumValues(*this, Elements, Enum, EnumType);
+
if (Enum->hasAttr<FlagEnumAttr>()) {
for (Decl *D : Elements) {
EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(D);
@@ -14274,11 +14274,6 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
}
}
- Enum->completeDefinition(BestType, BestPromotionType,
- NumPositiveBits, NumNegativeBits);
-
- CheckForDuplicateEnumValues(*this, Elements, Enum, EnumType);
-
// Now that the enum type is defined, ensure it's not been underaligned.
if (Enum->hasAttrs())
CheckAlignasUnderalignment(Enum);
OpenPOWER on IntegriCloud