75 struct TStatusBitsChecker::Registry::Info {
77 Info(
const Info &) =
default;
78 Info(Info &&) =
default;
80 Info(TClass &o, std::string &&n,
bool intentionalDup) : fOwner(&o), fConstantName(n), fIntentionalDup(intentionalDup)
87 std::string fConstantName;
88 bool fIntentionalDup =
false;
92 TStatusBitsChecker::Registry::Registry() =
default;
95 TStatusBitsChecker::Registry::~Registry() =
default;
99 UChar_t TStatusBitsChecker::ConvertToBit(Long64_t constant, TClass &classRef,
const char *constantName)
103 Error(
"TStatusBitsChecker::ConvertBit",
"In %s the value of %s is %lld which was not produced by BIT macro.",
104 classRef.GetName(), constantName, constant);
109 double fraction = std::frexp(constant, &backshift);
116 if (backshift < 0 || std::abs(0.5 - fraction) > 0.00001f) {
117 Error(
"TStatusBitsChecker::ConvertBit",
"In %s the value of %s is %lld which was not produced by BIT macro.",
118 classRef.GetName(), constantName, constant);
122 if (backshift > 24) {
123 Error(
"TStatusBitsChecker::ConvertBit",
"In %s the value of %s is %lld (>23) which is ignored by SetBit.",
124 classRef.GetName(), constantName, constant);
135 void TStatusBitsChecker::Registry::RegisterBits(TClass &classRef )
137 TEnum *eStatusBits = (TEnum *)classRef.GetListOfEnums()->FindObject(
"EStatusBits");
138 TEnum *exceptionBits = (TEnum *)classRef.GetListOfEnums()->FindObject(
"EStatusBitsDupExceptions");
142 for (
auto constant : TRangeStaticCast<TEnumConstant>(*eStatusBits->GetConstants())) {
145 bool intentionalDup = exceptionBits && exceptionBits->GetConstant(constant->GetName());
147 auto value = constant->GetValue();
148 auto bit = ConvertToBit(value, classRef, constant->GetName());
152 for (
auto reg : fRegister[bit]) {
153 if (reg.fOwner == &classRef) {
161 fRegister[bit].emplace_back(classRef, std::string(constant->GetName()), intentionalDup);
166 TList *lb = classRef.GetListOfBases();
168 for (
auto base : TRangeStaticCast<TBaseClass>(*lb)) {
169 TClass *bcl = base->GetClassPointer();
181 bool TStatusBitsChecker::Registry::Check(TClass &classRef,
bool verbose )
183 RegisterBits(classRef);
186 for (
auto cursor : fRegister) {
187 for (
auto constant : cursor.second) {
188 Printf(
"Bit %3d declared in %s as %s", cursor.first, constant.fOwner->GetName(),
189 constant.fConstantName.c_str());
194 bool issuedHeader =
false;
196 for (
auto cursor : fRegister) {
197 unsigned int nDuplicate = 0;
198 for (
auto constant : cursor.second) {
199 if (!constant.fIntentionalDup)
202 if (nDuplicate > 1) {
204 Error(
"TStatusBitsChecker",
"In %s class hierarchy, there are duplicates bits:", classRef.GetName());
207 for (
auto constant : cursor.second) {
208 if (!constant.fIntentionalDup) {
209 Error(
"TStatusBitsChecker",
" Bit %3d used in %s as %s", cursor.first, constant.fOwner->GetName(),
210 constant.fConstantName.c_str());
224 bool TStatusBitsChecker::Check(TClass &classRef,
bool verbose )
226 return Registry().Check(classRef, verbose);
233 bool TStatusBitsChecker::Check(
const char *classname,
bool verbose)
235 TClass *cl = TClass::GetClass(classname);
237 return Check(*cl, verbose);
247 bool TStatusBitsChecker::CheckAllClasses(
bool verbosity )
254 std::set<std::string> rootLibs;
255 TList classesDeclFileNotFound;
256 TList classesImplFileNotFound;
258 Int_t totalNumberOfClasses = gClassTable->Classes();
259 for (Int_t i = 0; i < totalNumberOfClasses; i++) {
262 const char *cname = gClassTable->Next();
268 TClass *classPtr = TClass::GetClass((
const char *)cname, kTRUE);
272 result = Check(*classPtr, verbosity) && result;