diff --git a/src/cpyrt/CPPMethod.cxx b/src/cpyrt/CPPMethod.cxx index 0221f836..faca0da7 100644 --- a/src/cpyrt/CPPMethod.cxx +++ b/src/cpyrt/CPPMethod.cxx @@ -525,7 +525,21 @@ int cpyrt::CPPMethod::GetPriority() { // prefer more derived classes const std::string& clean_name = TypeManip::clean_type(aname, false); - interop::TCppScope_t scope = interop::GetScope(clean_name); + interop::TCppScope_t scope = nullptr; + if (clean_name.find('<') != std::string::npos && + clean_name.find("initializer_list") == std::string::npos) { + // Resolving a template name from its spelling declares new code in + // the interpreter on every call, so take the class from the argument + // type instead, and force its definition like GetScope() does. + // GetScope() deliberately resolves std::initializer_list as + // std::vector, which the ranking relies on, so those still go + // through GetScope(). + scope = interop::GetScopeFromType(interop::GetUnderlyingType( + interop::GetMethodArgType(fMethod, iarg))); + if (scope) + interop::IsComplete(scope); + } else + scope = interop::GetScope(clean_name); if (scope) priority += static_cast(interop::GetNumBasesLongestBranch(scope)); diff --git a/src/interop/cppjit_interop.h b/src/interop/cppjit_interop.h index 59c1a95b..ca6980c8 100644 --- a/src/interop/cppjit_interop.h +++ b/src/interop/cppjit_interop.h @@ -57,6 +57,8 @@ std::string ResolveName(const std::string& cppitem_name); RPY_EXPORTED TCppType_t ResolveType(TCppType_t cppitem_name); RPY_EXPORTED +TCppType_t GetUnderlyingType(TCppType_t type); +RPY_EXPORTED TCppType_t ResolveEnumReferenceType(TCppType_t type); RPY_EXPORTED TCppType_t ResolveEnumPointerType(TCppType_t type); diff --git a/src/interop/interop_wrapper.cxx b/src/interop/interop_wrapper.cxx index d26697c8..b8945e07 100644 --- a/src/interop/interop_wrapper.cxx +++ b/src/interop/interop_wrapper.cxx @@ -729,6 +729,11 @@ interop::TCppScope_t interop::GetScopeFromType(TCppType_t type) { return Cpp::GetScopeFromType(type); } +interop::TCppType_t interop::GetUnderlyingType(TCppType_t type) { + std::lock_guard Lock(InterOpMutex); + return Cpp::GetUnderlyingType(type); +} + interop::TCppType_t interop::GetTypeFromScope(TCppScope_t klass) { std::lock_guard Lock(InterOpMutex); return Cpp::GetTypeFromScope(klass);