diff --git a/clang/include/clang/AST/DependenceFlags.h b/clang/include/clang/AST/DependenceFlags.h --- a/clang/include/clang/AST/DependenceFlags.h +++ b/clang/include/clang/AST/DependenceFlags.h @@ -36,7 +36,6 @@ }; }; using ExprDependence = ExprDependenceScope::ExprDependence; -static constexpr unsigned ExprDependenceBits = 5; struct TypeDependenceScope { enum TypeDependence : uint8_t { @@ -62,7 +61,6 @@ }; }; using TypeDependence = TypeDependenceScope::TypeDependence; -static constexpr unsigned TypeDependenceBits = 4; #define LLVM_COMMON_DEPENDENCE(NAME) \ struct NAME##Scope { \ @@ -78,8 +76,7 @@ LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Dependent) \ }; \ }; \ - using NAME = NAME##Scope::NAME; \ - static constexpr unsigned NAME##Bits = 3; + using NAME = NAME##Scope::NAME; LLVM_COMMON_DEPENDENCE(NestedNameSpecifierDependence) LLVM_COMMON_DEPENDENCE(TemplateNameDependence) diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -21,6 +21,7 @@ #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitmaskEnum.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator.h" @@ -310,9 +311,9 @@ unsigned ValueKind : 2; unsigned ObjectKind : 3; - unsigned /*ExprDependence*/ Dependent : ExprDependenceBits; + unsigned /*ExprDependence*/ Dependent : llvm::BitWidth; }; - enum { NumExprBits = NumStmtBits + 5 + ExprDependenceBits }; + enum { NumExprBits = NumStmtBits + 5 + llvm::BitWidth }; class ConstantExprBitfields { friend class ASTStmtReader; diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -1467,7 +1467,7 @@ unsigned TC : 8; /// Store information on the type dependency. - /*TypeDependence*/ unsigned Dependence : TypeDependenceBits; + unsigned Dependence : llvm::BitWidth; /// True if the cache (i.e. the bitfields here starting with /// 'Cache') is valid. @@ -1496,7 +1496,7 @@ return CachedLocalOrUnnamed; } }; - enum { NumTypeBits = 8 + TypeDependenceBits + 6 }; + enum { NumTypeBits = 8 + llvm::BitWidth + 6 }; protected: // These classes allow subclasses to somewhat cleanly pack bitfields diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -50,6 +50,7 @@ #include "clang/Lex/Token.h" #include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ASTRecordReader.h" +#include "llvm/ADT/BitmaskEnum.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" @@ -107,7 +108,7 @@ /// The number of record fields required for the Expr class /// itself. static const unsigned NumExprFields = - NumStmtFields + ExprDependenceBits + 3; + NumStmtFields + llvm::BitWidth + 3; /// Read and initialize a ExplicitTemplateArgumentList structure. void ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args, diff --git a/llvm/include/llvm/ADT/BitmaskEnum.h b/llvm/include/llvm/ADT/BitmaskEnum.h --- a/llvm/include/llvm/ADT/BitmaskEnum.h +++ b/llvm/include/llvm/ADT/BitmaskEnum.h @@ -94,6 +94,10 @@ return U; } +constexpr unsigned bitWidth(uint64_t Value) { + return Value ? 1 + bitWidth(Value >> 1) : 0; +} + template ::value>> E operator~(E Val) { return static_cast(~Underlying(Val) & Mask()); @@ -139,6 +143,10 @@ // Enable bitmask enums in namespace ::llvm and all nested namespaces. LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); +template ::value>> +constexpr unsigned BitWidth = BitmaskEnumDetail::bitWidth(uint64_t{ + static_cast>( + E::LLVM_BITMASK_LARGEST_ENUMERATOR)}); } // namespace llvm