diff --git a/core/metacling/src/TCling.cxx b/core/metacling/src/TCling.cxx index f2b7ce1c8e744..a8922b29c5649 100644 --- a/core/metacling/src/TCling.cxx +++ b/core/metacling/src/TCling.cxx @@ -8414,7 +8414,7 @@ const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const { TClingMethodInfo* info = (TClingMethodInfo*) minfo; - return info->GetPrototype(*fNormalizedCtxt); + return info->GetPrototype(); } //////////////////////////////////////////////////////////////////////////////// @@ -8422,7 +8422,7 @@ const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const { TClingMethodInfo* info = (TClingMethodInfo*) minfo; - return info->Name(*fNormalizedCtxt); + return info->Name(); } //////////////////////////////////////////////////////////////////////////////// diff --git a/core/metacling/src/TClingCallFunc.cxx b/core/metacling/src/TClingCallFunc.cxx index 92c96215c0634..e310b3a579392 100644 --- a/core/metacling/src/TClingCallFunc.cxx +++ b/core/metacling/src/TClingCallFunc.cxx @@ -1483,7 +1483,7 @@ void TClingCallFunc::exec(void *address, void *ret) if (num_args < GetMinRequiredArguments()) { ::Error("TClingCallFunc::exec", "Not enough arguments provided for %s (%d instead of the minimum %d)", - fMethod->Name(ROOT::TMetaUtils::TNormalizedCtxt(fInterp->getLookupHelper())), + fMethod->Name(), num_args, (int)GetMinRequiredArguments()); return; } @@ -1492,7 +1492,7 @@ void TClingCallFunc::exec(void *address, void *ret) && !dyn_cast(FD)) { ::Error("TClingCallFunc::exec", "The method %s is called without an object.", - fMethod->Name(ROOT::TMetaUtils::TNormalizedCtxt(fInterp->getLookupHelper()))); + fMethod->Name()); return; } vh_ary.reserve(num_args); diff --git a/core/metacling/src/TClingMethodInfo.cxx b/core/metacling/src/TClingMethodInfo.cxx index 0dbf27a29817c..7937cadec52bc 100644 --- a/core/metacling/src/TClingMethodInfo.cxx +++ b/core/metacling/src/TClingMethodInfo.cxx @@ -83,14 +83,14 @@ class TClingMethodInfo::SpecIterator }; TClingMethodInfo::TClingMethodInfo(const TClingMethodInfo &rhs) : + TClingGenericInfo(rhs), fInterp(rhs.fInterp), fContexts(rhs.fContexts), fFirstTime(rhs.fFirstTime), fContextIdx(rhs.fContextIdx), fIter(rhs.fIter), fTitle(rhs.fTitle), - fTemplateSpecIter(nullptr), - fSingleDecl(rhs.fSingleDecl) + fTemplateSpecIter(nullptr) { if (rhs.fTemplateSpecIter) { // The SpecIterator query the decl. @@ -102,8 +102,8 @@ TClingMethodInfo::TClingMethodInfo(const TClingMethodInfo &rhs) : TClingMethodInfo::TClingMethodInfo(cling::Interpreter *interp, TClingClassInfo *ci) - : fInterp(interp), fFirstTime(true), fContextIdx(0U), fTitle(""), - fTemplateSpecIter(0), fSingleDecl(0) + : TClingGenericInfo(nullptr), fInterp(interp), fFirstTime(true), fContextIdx(0U), fTitle(""), + fTemplateSpecIter(0) { R__LOCKGUARD(gInterpreterMutex); @@ -131,8 +131,8 @@ TClingMethodInfo::TClingMethodInfo(cling::Interpreter *interp, TClingMethodInfo::TClingMethodInfo(cling::Interpreter *interp, const clang::FunctionDecl *FD) - : fInterp(interp), fFirstTime(true), fContextIdx(0U), fTitle(""), - fTemplateSpecIter(0), fSingleDecl(FD) + : TClingGenericInfo(FD), fInterp(interp), fFirstTime(true), fContextIdx(0U), fTitle(""), + fTemplateSpecIter(0) { } @@ -152,17 +152,7 @@ TDictionary::DeclId_t TClingMethodInfo::GetDeclId() const const clang::FunctionDecl *TClingMethodInfo::GetMethodDecl() const { - if (!IsValid()) { - return 0; - } - - if (fSingleDecl) - return fSingleDecl; - - if (fTemplateSpecIter) - return *(*fTemplateSpecIter); - - return llvm::dyn_cast(*fIter); + return cast_or_null(GetDecl()); } void TClingMethodInfo::CreateSignature(TString &signature) const @@ -203,7 +193,7 @@ void TClingMethodInfo::Init(const clang::FunctionDecl *decl) fIter = clang::DeclContext::decl_iterator(); delete fTemplateSpecIter; fTemplateSpecIter = 0; - fSingleDecl = decl; + fDecl = decl; } void *TClingMethodInfo::InterfaceMethod(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const @@ -217,7 +207,7 @@ void *TClingMethodInfo::InterfaceMethod(const ROOT::TMetaUtils::TNormalizedCtxt return cf.InterfaceMethod(); } -bool TClingMethodInfo::IsValidSlow() const +const clang::Decl* TClingMethodInfo::GetDeclSlow() const { if (fTemplateSpecIter) { // Could trigger deserialization of decls. @@ -374,7 +364,9 @@ static void InstantiateFuncTemplateWithDefaults(clang::FunctionTemplateDecl* FTD int TClingMethodInfo::InternalNext() { - assert(!fSingleDecl && "This is not an iterator!"); + assert(!fDecl && "This is not an iterator!"); + + fNameCache = {}; // invalidate the cache. if (!fFirstTime && !*fIter) { // Iterator is already invalid. @@ -619,7 +611,7 @@ std::string TClingMethodInfo::GetMangledName() const return mangled_name; } -const char *TClingMethodInfo::GetPrototype(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const +const char *TClingMethodInfo::GetPrototype() { if (!IsValid()) { return 0; @@ -643,7 +635,7 @@ const char *TClingMethodInfo::GetPrototype(const ROOT::TMetaUtils::TNormalizedCt buf += name; buf += "::"; } - buf += Name(normCtxt); + buf += Name(); buf += '('; TClingMethodArgInfo arg(fInterp, this); int idx = 0; @@ -672,14 +664,16 @@ const char *TClingMethodInfo::GetPrototype(const ROOT::TMetaUtils::TNormalizedCt return buf.c_str(); } -const char *TClingMethodInfo::Name(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const +const char *TClingMethodInfo::Name() { if (!IsValid()) { return 0; } - TTHREAD_TLS_DECL( std::string, buf ); - ((TCling*)gCling)->GetFunctionName(GetMethodDecl(),buf); - return buf.c_str(); + if (!fNameCache.empty()) + return fNameCache.c_str(); + + ((TCling*)gCling)->GetFunctionName(GetMethodDecl(), fNameCache); + return fNameCache.c_str(); } const char *TClingMethodInfo::TypeName() const diff --git a/core/metacling/src/TClingMethodInfo.h b/core/metacling/src/TClingMethodInfo.h index 8b7f50bf1c2f9..e81c5ea51d00e 100644 --- a/core/metacling/src/TClingMethodInfo.h +++ b/core/metacling/src/TClingMethodInfo.h @@ -26,6 +26,8 @@ // // ////////////////////////////////////////////////////////////////////////// +#include "TClingGenericInfo.h" + #include "TString.h" #include "TDictionary.h" @@ -49,7 +51,7 @@ namespace ROOT { class TClingClassInfo; class TClingTypeInfo; -class TClingMethodInfo { +class TClingMethodInfo final : public TClingGenericInfo { private: class SpecIterator; @@ -60,14 +62,13 @@ class TClingMethodInfo { clang::DeclContext::decl_iterator fIter; // Our iterator. std::string fTitle; // The meta info for the method. SpecIterator *fTemplateSpecIter; // Iter over template specialization. [We own] - const clang::FunctionDecl *fSingleDecl; // The single member - bool IsValidSlow() const; + const clang::Decl* GetDeclSlow() const; public: explicit TClingMethodInfo(cling::Interpreter *interp) - : fInterp(interp), fFirstTime(true), fContextIdx(0U), fTitle(""), - fTemplateSpecIter(0), fSingleDecl(0) {} + : TClingGenericInfo(nullptr), fInterp(interp), fFirstTime(true), fContextIdx(0U), fTitle(""), + fTemplateSpecIter(0) {} TClingMethodInfo(const TClingMethodInfo&); @@ -83,9 +84,11 @@ class TClingMethodInfo { void CreateSignature(TString &signature) const; void Init(const clang::FunctionDecl *); void *InterfaceMethod(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const; - bool IsValid() const { - if (fSingleDecl) return fSingleDecl; - return IsValidSlow(); + + const clang::Decl *GetDecl() const override { + if (const clang::Decl* SingleDecl = TClingGenericInfo::GetDecl()) + return SingleDecl; + return GetDeclSlow(); } int NArg() const; int NDefaultArg() const; @@ -95,8 +98,8 @@ class TClingMethodInfo { long ExtraProperty() const; TClingTypeInfo *Type() const; std::string GetMangledName() const; - const char *GetPrototype(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const; - const char *Name(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const; + const char *GetPrototype(); + const char *Name() override; const char *TypeName() const; const char *Title(); };