Skip to content

Commit e0330cd

Browse files
committed
[Core] ROOT-9712: Properly check recursively dictionaries for tuple and array
in addition to pair and unique_ptr. If one type among unique_ptr, array and tuple is encountered, the dictionaries for its template arguments which are types are looked for. In order not to stop recursion in cases such as array<MyType**const*>, the template argument type is cleaned through the TClassEdit::ShortType routine.
1 parent 46fcef5 commit e0330cd

File tree

1 file changed

+51
-12
lines changed

1 file changed

+51
-12
lines changed

core/meta/src/TClass.cxx

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3848,20 +3848,59 @@ void TClass::GetMissingDictionariesWithRecursionCheck(TCollection& result, TColl
38483848
static TClassRef sCIString("string");
38493849
if (this == sCIString) return;
38503850

3851-
// Special treatment for pair.
3852-
if (strncmp(fName, "pair<", 5) == 0) {
3853-
GetMissingDictionariesForPairElements(result, visited, recurse);
3854-
return;
3855-
}
3851+
TClassEdit::TSplitType splitType(fName);
3852+
if (splitType.IsTemplate()) {
3853+
// We now treat special cases:
3854+
// - pair
3855+
// - unique_ptr
3856+
// - array
3857+
// - tuple
3858+
3859+
// Small helper to get the TClass instance from a classname and recursively
3860+
// investigate it
3861+
auto checkDicts = [&](const string &clName){
3862+
auto cl = TClass::GetClass(clName.c_str());
3863+
if (!cl) {
3864+
// We try to remove * and const from the type name if any
3865+
const auto clNameShortType = TClassEdit::ShortType(clName.c_str(), 1);
3866+
cl = TClass::GetClass(clNameShortType.c_str());
3867+
}
3868+
if (cl && !cl->HasDictionary()) {
3869+
cl->GetMissingDictionariesWithRecursionCheck(result, visited, recurse);
3870+
}
3871+
};
3872+
3873+
const auto &elements = splitType.fElements;
3874+
const auto &templName = elements[0];
38563875

3857-
if (TClassEdit::IsUniquePtr(fName)) {
3858-
const auto uniquePtrClName = TClassEdit::GetUniquePtrType(fName);
3859-
auto uniquePtrCl = TClass::GetClass(uniquePtrClName.c_str());
3860-
if (uniquePtrCl && !uniquePtrCl->HasDictionary()) {
3861-
uniquePtrCl->GetMissingDictionariesWithRecursionCheck(result, visited, recurse);
3876+
// Special treatment for pair.
3877+
if (templName == "pair") {
3878+
GetMissingDictionariesForPairElements(result, visited, recurse);
3879+
return;
38623880
}
3863-
return;
3864-
}
3881+
3882+
// Special treatment of unique_ptr or array
3883+
// They are treated together since they have 1 single template argument
3884+
// which is interesting when checking for missing dictionaries.
3885+
if (templName == "unique_ptr" || templName == "array") {
3886+
checkDicts(elements[1]);
3887+
return;
3888+
}
3889+
3890+
// Special treatment of tuple
3891+
// This type must be treated separately since it can have N template
3892+
// arguments which are interesting, unlike unique_ptr or array.
3893+
if (templName == "tuple") {
3894+
// -1 because the elements end with a list of the "stars", i.e. number of
3895+
// * after the type name
3896+
const auto nTemplArgs = elements.size() - 1;
3897+
// loop starts at 1 because the first element is the template name
3898+
for (auto iTemplArg = 1U; iTemplArg < nTemplArgs; ++iTemplArg) {
3899+
checkDicts(elements[iTemplArg]);
3900+
}
3901+
return;
3902+
}
3903+
} // this is not a template
38653904

38663905
if (!HasDictionary()) {
38673906
result.Add(this);

0 commit comments

Comments
 (0)