Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions core/foundation/inc/TClassEdit.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ namespace TClassEdit {
ROOT::ESTLType STLKind(std::string_view type); //Kind of stl container
inline ROOT::ESTLType STLKind(ROOT::Internal::TStringView type) { return STLKind(std::string_view(type)); }
int STLArgs (int kind); //Min number of arguments without allocator
void RemoveStd(std::string &name, size_t pos = 0);
void RemoveStd(std::string_view &name);
std::string ResolveTypedef(const char *tname, bool resolveAll = false);
std::string ShortType (const char *typeDesc, int mode);
std::string InsertStd(const char *tname);
Expand Down
4 changes: 2 additions & 2 deletions core/foundation/src/TClassEdit.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ static size_t StdLen(const std::string_view name)
/// Remove std:: and any potential inline namespace (well compiler detail
/// namespace.

static void RemoveStd(std::string &name, size_t pos = 0)
void TClassEdit::RemoveStd(std::string &name, size_t pos)
{
size_t len = StdLen({name.data()+pos,name.length()-pos});
if (len) {
Expand All @@ -124,7 +124,7 @@ static void RemoveStd(std::string &name, size_t pos = 0)
/// Remove std:: and any potential inline namespace (well compiler detail
/// namespace.

static void RemoveStd(std::string_view &name)
void TClassEdit::RemoveStd(std::string_view &name)
{
size_t len = StdLen(name);
if (len) {
Expand Down
24 changes: 23 additions & 1 deletion core/meta/src/TClass.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3047,13 +3047,35 @@ TClass *TClass::GetClass(const char *name, Bool_t load, Bool_t silent, size_t hi
}

std::string normalizedName;
Bool_t checkTable = kFALSE;

// Check if this is a fundamental type already in the typesystem to delay
// as much as possible any lookup
if (!cl) {
{
TInterpreter::SuspendAutoLoadingRAII autoloadOff(gInterpreter);
TClassEdit::GetNormalizedName(normalizedName, name);
}
std::string name_no_std = name;
TClassEdit::RemoveStd(name_no_std);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the advantage of using this name_no_std rather than the normalizedName?

auto lot = reinterpret_cast<THashTable *>(gROOT->GetListOfTypes());
auto theType = reinterpret_cast<TDataType *>(lot->THashTable::FindObject(name_no_std.c_str()));
if (theType && -1 != theType->GetType()) {
return nullptr;
} else {
{
TInterpreter::SuspendAutoLoadingRAII autoloadOff(gInterpreter);
TInterpreter::SuspendAutoParsing autoparseOff(gInterpreter);
theType = reinterpret_cast<TDataType *>(lot->FindObject(name));
}
// If it is a typedef, check that this is not a class
if (theType && -1 != theType->GetType())
return nullptr;
}
}

Bool_t checkTable = kFALSE;

if (!cl) {
// Try the normalized name.
if (normalizedName != name) {
cl = (TClass*)gROOT->GetListOfClasses()->FindObject(normalizedName.c_str());
Expand Down
24 changes: 24 additions & 0 deletions core/meta/test/testTClass.cxx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include "TClass.h"
#include "THashTable.h"
#include "TInterpreter.h"
#include "TSystem.h"

#include <ROOT/TSeq.hxx>

#include "gtest/gtest.h"

Expand All @@ -22,3 +25,24 @@ TEST(TClass, DictCheck)

EXPECT_STREQ(errMsg.c_str(), "Missing dictionary for C, ") << errMsg;
}

// This test is for issue #9029
TEST(TClass, GetClassWithFundType)
{
ProcInfo_t info;
gSystem->GetProcInfo(&info);
auto start_mem = info.fMemResident;

constexpr auto name = "std::vector<int>::value_type";
TClass *cl = nullptr;
for (auto i : ROOT::TSeqI(8192)) {
cl = TClass::GetClass(name);
i = (int)i; // avoids unused variable warning
}

gSystem->GetProcInfo(&info);
auto end_mem = info.fMemResident;

EXPECT_TRUE(nullptr == cl);
EXPECT_NEAR(start_mem, end_mem, 16384);
}