diff --git a/core/metacling/src/TClingClassInfo.cxx b/core/metacling/src/TClingClassInfo.cxx index 434996e2cb5aa..6a703d627cb1a 100644 --- a/core/metacling/src/TClingClassInfo.cxx +++ b/core/metacling/src/TClingClassInfo.cxx @@ -99,9 +99,14 @@ TClingClassInfo::TClingClassInfo(cling::Interpreter *interp, const char *name, b &type, intantiateTemplate); } } + // The lookup finds the decl if the name corresponds to a namespace or a fully defined + // class; just a type in presence of a forward declaration of a class. + // This code identifies that case and prevents that a class type is found if the name + // of a constructor is passed (see ROOT-10311). if (!decl && type) { - if (const auto *TD = type->getAsTagDecl()) { - decl = TD; + const auto *CXXRD = type->getAsCXXRecordDecl(); + if (CXXRD && !CXXRD->hasDefinition()) { + decl = CXXRD; } } SetDecl(decl); diff --git a/core/metacling/test/TClingTests.cxx b/core/metacling/test/TClingTests.cxx index 2a54d12864dd3..ec9833264f82e 100644 --- a/core/metacling/test/TClingTests.cxx +++ b/core/metacling/test/TClingTests.cxx @@ -467,4 +467,23 @@ using func0_ret_t = typename ROOT::TypeTraits::CallableTraits:: auto res = gInterpreter->Declare(expression.c_str()); EXPECT_TRUE(res); } -#endif \ No newline at end of file +#endif + +// ROOT-10311 +TEST_F(TClingTests, TClassByCtorName) +{ + auto res = gInterpreter->Declare("namespace TClassByCtorName{class Foo;};"); + EXPECT_TRUE(res); + { + ROOT::TestSupport::CheckDiagsRAII checkDiag; + checkDiag.requiredDiag(kWarning, "TClass::Init", "no dictionary for class TClassByCtorName::Foo is available", false); + EXPECT_TRUE(nullptr != TClass::GetClass("TClassByCtorName::Foo")); + } + const auto *wrongName = "TTree::TTree"; + EXPECT_TRUE(nullptr == TClass::GetClass(wrongName)); + EXPECT_TRUE(nullptr != TClass::GetClass("TTree")); + + std::string classInterpreterName; + gInterpreter->GetInterpreterTypeName(wrongName, classInterpreterName); + EXPECT_STREQ(classInterpreterName.c_str(), ""); +}