Skip to content

Commit 196f230

Browse files
authored
Template fix patch based on updated InterOp API (#93)
1 parent f4d000d commit 196f230

File tree

2 files changed

+60
-117
lines changed

2 files changed

+60
-117
lines changed

clingwrapper/src/clingwrapper.cxx

Lines changed: 57 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,10 @@ bool Cppyy::IsClassType(TCppType_t type) {
462462
// returns true if no new type was added.
463463
bool Cppyy::AppendTypesSlow(const std::string &name,
464464
std::vector<Cpp::TemplateArgInfo>& types) {
465+
466+
// Add no new type if string is empty
467+
if (name.empty()) return true;
468+
465469
// Try going via Cppyy::GetType first.
466470
if (Cppyy::TCppType_t type = GetType(name, /*enable_slow_lookup=*/true)) {
467471
types.push_back(type);
@@ -1308,9 +1312,9 @@ ptrdiff_t Cppyy::GetBaseOffset(TCppScope_t derived, TCppScope_t base,
13081312
// return (TCppIndex_t)0; // unknown class?
13091313
// }
13101314

1311-
std::vector<Cppyy::TCppMethod_t> Cppyy::GetClassMethods(TCppScope_t scope)
1315+
void Cppyy::GetClassMethods(TCppScope_t scope, std::vector<Cppyy::TCppMethod_t> &methods)
13121316
{
1313-
return Cpp::GetClassMethods(scope);
1317+
Cpp::GetClassMethods(scope, methods);
13141318
}
13151319

13161320
std::vector<Cppyy::TCppScope_t> Cppyy::GetMethodsFromName(
@@ -1400,7 +1404,8 @@ std::string Cppyy::GetMethodArgDefault(TCppMethod_t method, TCppIndex_t iarg)
14001404

14011405
std::string Cppyy::GetMethodSignature(TCppMethod_t method, bool show_formal_args, TCppIndex_t max_args)
14021406
{
1403-
return Cpp::GetFunctionSignature(method);
1407+
// FIXME : Doesn't work for template functions as it does in cling
1408+
return Cpp::GetFunctionSignature(method);
14041409
}
14051410

14061411
std::string Cppyy::GetMethodPrototype(TCppMethod_t method, bool show_formal_args)
@@ -1416,40 +1421,23 @@ bool Cppyy::IsConstMethod(TCppMethod_t method)
14161421
return Cpp::IsConstMethod(method);
14171422
}
14181423

1419-
// Cppyy::TCppIndex_t Cppyy::GetNumTemplatedMethods(TCppScope_t scope, bool accept_namespace)
1420-
// {
1421-
// if (!accept_namespace && IsNamespace(scope))
1422-
// return (TCppIndex_t)0; // enforce lazy
1423-
//
1424-
// if (scope == GLOBAL_HANDLE) {
1425-
// TCollection* coll = gROOT->GetListOfFunctionTemplates();
1426-
// if (coll) return (TCppIndex_t)coll->GetSize();
1427-
// } else {
1428-
// TClassRef& cr = type_from_handle(scope);
1429-
// if (cr.GetClass()) {
1430-
// TCollection* coll = cr->GetListOfFunctionTemplates(true);
1431-
// if (coll) return (TCppIndex_t)coll->GetSize();
1432-
// }
1433-
// }
1434-
//
1435-
// // failure ...
1436-
// return (TCppIndex_t)0;
1437-
// }
1438-
//
1439-
// std::string Cppyy::GetTemplatedMethodName(TCppScope_t scope, TCppIndex_t imeth)
1440-
// {
1441-
// if (scope == (TCppScope_t)GLOBAL_HANDLE)
1442-
// return ((THashList*)gROOT->GetListOfFunctionTemplates())->At((int)imeth)->GetName();
1443-
// else {
1444-
// TClassRef& cr = type_from_handle(scope);
1445-
// if (cr.GetClass())
1446-
// return cr->GetListOfFunctionTemplates(false)->At((int)imeth)->GetName();
1447-
// }
1448-
//
1449-
// // failure ...
1450-
// assert(!"should not be called unless GetNumTemplatedMethods() succeeded");
1451-
// return "";
1452-
// }
1424+
Cppyy::TCppIndex_t Cppyy::GetNumTemplatedMethods(TCppScope_t scope, bool accept_namespace)
1425+
{
1426+
std::vector<Cppyy::TCppMethod_t> mc;
1427+
Cpp::GetFunctionTemplatedDecls(scope, mc);
1428+
return mc.size();
1429+
}
1430+
1431+
std::string Cppyy::GetTemplatedMethodName(TCppScope_t scope, TCppIndex_t imeth)
1432+
{
1433+
std::vector<Cppyy::TCppMethod_t> mc;
1434+
Cpp::GetFunctionTemplatedDecls(scope, mc);
1435+
1436+
if (imeth < mc.size()) return GetMethodName(mc[imeth]);
1437+
1438+
return "";
1439+
}
1440+
14531441
//
14541442
// bool Cppyy::IsTemplatedConstructor(TCppScope_t scope, TCppIndex_t imeth)
14551443
// {
@@ -1495,85 +1483,40 @@ bool Cppyy::IsTemplatedMethod(TCppMethod_t method)
14951483
Cppyy::TCppMethod_t Cppyy::GetMethodTemplate(
14961484
TCppScope_t scope, const std::string& name, const std::string& proto)
14971485
{
1498-
#ifdef PRINT_DEBUG
1499-
printf("========== GMT: %s; %s\n", name.c_str(), proto.c_str());
1500-
#endif
1501-
// // There is currently no clean way of extracting a templated method out of ROOT/meta
1502-
// // for a variety of reasons, none of them fundamental. The game played below is to
1503-
// // first get any pre-existing functions already managed by ROOT/meta, but if that fails,
1504-
// // to do an explicit lookup that ignores the prototype (i.e. the full name should be
1505-
// // enough), and finally to ignore the template arguments part of the name as this fails
1506-
// // in cling if there are default parameters.
1507-
// TFunction* func = nullptr; ClassInfo_t* cl = nullptr;
1508-
// if (scope == (cppyy_scope_t)GLOBAL_HANDLE) {
1509-
// func = gROOT->GetGlobalFunctionWithPrototype(name.c_str(), proto.c_str());
1510-
// if (func && name.back() == '>') {
1511-
// // make sure that all template parameters match (more are okay, e.g. defaults or
1512-
// // ones derived from the arguments or variadic templates)
1513-
// if (!template_compare(name, func->GetName()))
1514-
// func = nullptr; // happens if implicit conversion matches the overload
1515-
// }
1516-
// } else {
1517-
// TClassRef& cr = type_from_handle(scope);
1518-
// if (cr.GetClass()) {
1519-
// func = cr->GetMethodWithPrototype(name.c_str(), proto.c_str());
1520-
// if (!func) {
1521-
// cl = cr->GetClassInfo();
1522-
// // try base classes to cover a common 'using' case (TODO: this is stupid and misses
1523-
// // out on base classes; fix that with improved access to Cling)
1524-
// TCppIndex_t nbases = GetNumBases(scope);
1525-
// for (TCppIndex_t i = 0; i < nbases; ++i) {
1526-
// TClassRef& base = type_from_handle(GetScope(GetBaseName(scope, i)));
1527-
// if (base.GetClass()) {
1528-
// func = base->GetMethodWithPrototype(name.c_str(), proto.c_str());
1529-
// if (func) break;
1530-
// }
1531-
// }
1532-
// }
1533-
// }
1534-
// }
1535-
//
1536-
// if (!func && name.back() == '>' && (cl || scope == (cppyy_scope_t)GLOBAL_HANDLE)) {
1537-
// // try again, ignoring proto in case full name is complete template
1538-
// auto declid = gInterpreter->GetFunction(cl, name.c_str());
1539-
// if (declid) {
1540-
// auto existing = gMethodTemplates.find(declid);
1541-
// if (existing == gMethodTemplates.end()) {
1542-
// auto cw = new_CallWrapper(declid, name);
1543-
// existing = gMethodTemplates.insert(std::make_pair(declid, cw)).first;
1544-
// }
1545-
// return (TCppMethod_t)existing->second;
1546-
// }
1547-
// }
1548-
//
1549-
// if (func) {
1550-
// // make sure we didn't match a non-templated overload
1551-
// if (func->ExtraProperty() & kIsTemplateSpec)
1552-
// return (TCppMethod_t)new_CallWrapper(func);
1553-
//
1554-
// // disregard this non-templated method as it will be considered when appropriate
1555-
// return (TCppMethod_t)nullptr;
1556-
// }
1557-
//
1558-
// // try again with template arguments removed from name, if applicable
1559-
// if (name.back() == '>') {
1560-
// auto pos = name.find('<');
1561-
// if (pos != std::string::npos) {
1562-
// TCppMethod_t cppmeth = GetMethodTemplate(scope, name.substr(0, pos), proto);
1563-
// if (cppmeth) {
1564-
// // allow if requested template names match up to the result
1565-
// const std::string& alt = GetMethodFullName(cppmeth);
1566-
// if (name.size() < alt.size() && alt.find('<') == pos) {
1567-
// if (template_compare(name, alt))
1568-
// return cppmeth;
1569-
// }
1570-
// }
1571-
// }
1572-
// }
1486+
std::string pureName;
1487+
std::string explicit_params;
1488+
1489+
if (name.find('<') != std::string::npos) {
1490+
pureName = name.substr(0, name.find('<'));
1491+
size_t start = name.find('<');
1492+
size_t end = name.find('>');
1493+
explicit_params = name.substr(start + 1, end - start - 1);
1494+
}
1495+
1496+
else pureName = name;
1497+
1498+
std::vector<Cppyy::TCppMethod_t> unresolved_candidate_methods;
1499+
Cpp::GetClassTemplatedMethods(pureName, scope,
1500+
unresolved_candidate_methods);
1501+
1502+
// CPyCppyy assumes that we attempt instantiation here
1503+
std::vector<Cpp::TemplateArgInfo> arg_types;
1504+
std::vector<Cpp::TemplateArgInfo> templ_params;
1505+
Cppyy::AppendTypesSlow(proto, arg_types);
1506+
Cppyy::AppendTypesSlow(explicit_params, templ_params);
1507+
1508+
Cppyy::TCppMethod_t cppmeth = Cpp::BestTemplateFunctionMatch(unresolved_candidate_methods, templ_params, arg_types);
1509+
1510+
if(!cppmeth){
1511+
return nullptr;
1512+
}
1513+
1514+
return cppmeth;
1515+
1516+
// if it fails, use Sema to propogate info about why it failed (DeductionInfo)
15731517

1574-
// failure ...
1575-
return (TCppMethod_t)nullptr;
15761518
}
1519+
15771520
//
15781521
// static inline
15791522
// std::string type_remap(const std::string& n1, const std::string& n2)

clingwrapper/src/cpp_cppyy.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ namespace Cppyy {
254254

255255
// // method/function reflection information ------------------------------------
256256
RPY_EXPORTED
257-
std::vector<TCppMethod_t> GetClassMethods(TCppScope_t scope);
257+
void GetClassMethods(TCppScope_t scope, std::vector<TCppMethod_t> &methods);
258258
RPY_EXPORTED
259259
std::vector<TCppScope_t> GetMethodsFromName(TCppScope_t scope,
260260
const std::string& name);
@@ -294,9 +294,9 @@ namespace Cppyy {
294294
bool IsConstMethod(TCppMethod_t);
295295

296296
RPY_EXPORTED
297-
TCppIndex_t GetNumTemplatedMethods(TCppScope_t scope, bool accept_namespace = false) { assert(0 && "GetNumTemplatedMethods"); return 0; }
297+
TCppIndex_t GetNumTemplatedMethods(TCppScope_t scope, bool accept_namespace = false);
298298
RPY_EXPORTED
299-
std::string GetTemplatedMethodName(TCppScope_t scope, TCppIndex_t imeth) { assert(0 && "GetTemplatedMethodName"); return 0; }
299+
std::string GetTemplatedMethodName(TCppScope_t scope, TCppIndex_t imeth);
300300
RPY_EXPORTED
301301
bool IsTemplatedConstructor(TCppScope_t scope, TCppIndex_t imeth) { assert(0 && "IsTemplatedConstructor"); return 0; }
302302
RPY_EXPORTED

0 commit comments

Comments
 (0)