Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
clingwrapper.cxx
Go to the documentation of this file.
1// Bindings
2#include "capi.h"
3#include "cpp_cppyy.h"
4#include "callcontext.h"
5
6// ROOT
7#include "TBaseClass.h"
8#include "TClass.h"
9#include "TClassRef.h"
10#include "TClassTable.h"
11#include "TClassEdit.h"
12#include "TCollection.h"
13#include "TDataMember.h"
14#include "TDataType.h"
15#include "TEnum.h"
16#include "TEnumConstant.h"
17#include "TEnv.h"
18#include "TError.h"
19#include "TException.h"
20#include "TFunction.h"
21#include "TFunctionTemplate.h"
22#include "TGlobal.h"
23#include "THashList.h"
24#include "TInterpreter.h"
25#include "TList.h"
26#include "TListOfDataMembers.h"
27#include "TListOfEnums.h"
28#include "TMethod.h"
29#include "TMethodArg.h"
30#include "TROOT.h"
31#include "TSystem.h"
32
33// Standard
34#include <assert.h>
35#include <algorithm> // for std::count, std::remove
36#include <climits>
37#include <stdexcept>
38#include <map>
39#include <new>
40#include <set>
41#include <sstream>
42#include <signal.h>
43#include <stdlib.h> // for getenv
44#include <string.h>
45#include <typeinfo>
46
47// temp
48#include <iostream>
50// --temp
51
52
53// small number that allows use of stack for argument passing
54const int SMALL_ARGS_N = 8;
55
56// convention to pass flag for direct calls (similar to Python's vector calls)
57#define DIRECT_CALL ((size_t)1 << (8 * sizeof(size_t) - 1))
58static inline size_t CALL_NARGS(size_t nargs) {
59 return nargs & ~DIRECT_CALL;
60}
61
62// data for life time management ---------------------------------------------
63typedef std::vector<TClassRef> ClassRefs_t;
65static const ClassRefs_t::size_type GLOBAL_HANDLE = 1;
66static const ClassRefs_t::size_type STD_HANDLE = GLOBAL_HANDLE + 1;
67
68typedef std::map<std::string, ClassRefs_t::size_type> Name2ClassRefIndex_t;
70static std::map<std::string, std::string> resolved_enum_types;
71
72namespace {
73
74static inline
75Cppyy::TCppType_t find_memoized_scope(const std::string& name)
76{
77 auto icr = g_name2classrefidx.find(name);
78 if (icr != g_name2classrefidx.end())
79 return (Cppyy::TCppType_t)icr->second;
80 return (Cppyy::TCppType_t)0;
81}
82
83static inline
84std::string find_memoized_resolved_name(const std::string& name)
85{
86// resolved class types
87 Cppyy::TCppType_t klass = find_memoized_scope(name);
88 if (klass) return Cppyy::GetScopedFinalName(klass);
89
90// resolved enum types
91 auto res = resolved_enum_types.find(name);
92 if (res != resolved_enum_types.end())
93 return res->second;
94
95// unknown ...
96 return "";
97}
98
99class CallWrapper {
100public:
101 typedef const void* DeclId_t;
102
103public:
104 CallWrapper(TFunction* f) : fDecl(f->GetDeclId()), fName(f->GetName()), fTF(nullptr) {}
105 CallWrapper(DeclId_t fid, const std::string& n) : fDecl(fid), fName(n), fTF(nullptr) {}
106 ~CallWrapper() {
107 if (fTF && fDecl == fTF->GetDeclId())
108 delete fTF;
109 }
110
111public:
113 DeclId_t fDecl;
114 std::string fName;
115 TFunction* fTF;
116};
117
118}
119
120static std::vector<CallWrapper*> gWrapperHolder;
121static inline CallWrapper* new_CallWrapper(TFunction* f)
122{
123 CallWrapper* wrap = new CallWrapper(f);
124 gWrapperHolder.push_back(wrap);
125 return wrap;
126}
127
128static inline CallWrapper* new_CallWrapper(CallWrapper::DeclId_t fid, const std::string& n)
129{
130 CallWrapper* wrap = new CallWrapper(fid, n);
131 gWrapperHolder.push_back(wrap);
132 return wrap;
133}
134
135typedef std::vector<TGlobal*> GlobalVars_t;
137
138static std::set<std::string> gSTLNames;
139
140
141// data ----------------------------------------------------------------------
143
144// builtin types (including a few common STL templates as long as they live in
145// the global namespace b/c of choices upstream)
146static std::set<std::string> g_builtins =
147 {"bool", "char", "signed char", "unsigned char", "wchar_t", "short", "unsigned short",
148 "int", "unsigned int", "long", "unsigned long", "long long", "unsigned long long",
149 "float", "double", "long double", "void",
150 "allocator", "array", "basic_string", "complex", "initializer_list", "less", "list",
151 "map", "pair", "set", "vector"};
152
153// smart pointer types
154static std::set<std::string> gSmartPtrTypes =
155 {"auto_ptr", "std::auto_ptr", "shared_ptr", "std::shared_ptr",
156 "unique_ptr", "std::unique_ptr", "weak_ptr", "std::weak_ptr"};
157
158// to filter out ROOT names
159static std::set<std::string> gInitialNames;
160static std::set<std::string> gRootSOs;
161
162// configuration
163static bool gEnableFastPath = true;
164
165
166// global initialization -----------------------------------------------------
167namespace {
168
169// names copied from TUnixSystem
170#ifdef WIN32
171const int SIGBUS = 0; // simple placeholders for ones that don't exist
172const int SIGSYS = 0;
173const int SIGPIPE = 0;
174const int SIGQUIT = 0;
175const int SIGWINCH = 0;
176const int SIGALRM = 0;
177const int SIGCHLD = 0;
178const int SIGURG = 0;
179const int SIGUSR1 = 0;
180const int SIGUSR2 = 0;
181#endif
182
183static struct Signalmap_t {
184 int fCode;
185 const char *fSigName;
186} gSignalMap[kMAXSIGNALS] = { // the order of the signals should be identical
187 { SIGBUS, "bus error" }, // to the one in TSysEvtHandler.h
188 { SIGSEGV, "segmentation violation" },
189 { SIGSYS, "bad argument to system call" },
190 { SIGPIPE, "write on a pipe with no one to read it" },
191 { SIGILL, "illegal instruction" },
192 { SIGABRT, "abort" },
193 { SIGQUIT, "quit" },
194 { SIGINT, "interrupt" },
195 { SIGWINCH, "window size change" },
196 { SIGALRM, "alarm clock" },
197 { SIGCHLD, "death of a child" },
198 { SIGURG, "urgent data arrived on an I/O channel" },
199 { SIGFPE, "floating point exception" },
200 { SIGTERM, "termination signal" },
201 { SIGUSR1, "user-defined signal 1" },
202 { SIGUSR2, "user-defined signal 2" }
203};
204
205static void inline do_trace(int sig) {
206 std::cerr << " *** Break *** " << (sig < kMAXSIGNALS ? gSignalMap[sig].fSigName : "") << std::endl;
208}
209
210class TExceptionHandlerImp : public TExceptionHandler {
211public:
212 void HandleException(Int_t sig) override {
213 if (TROOT::Initialized()) {
214 if (gException) {
215 gInterpreter->RewindDictionary();
216 gInterpreter->ClearFileBusy();
217 }
218
219 if (!getenv("CPPYY_CRASH_QUIET"))
220 do_trace(sig);
221
222 // jump back, if catch point set
223 Throw(sig);
224 }
225
226 do_trace(sig);
227 gSystem->Exit(128 + sig);
228 }
229};
230
231class ApplicationStarter {
232public:
233 ApplicationStarter() {
234 // initialize ROOT early to guarantee proper order of shutdown later on (gROOT is a
235 // macro that resolves to the ROOT::GetROOT() function call)
236 (void)gROOT;
237
238 // setup dummy holders for global and std namespaces
239 assert(g_classrefs.size() == GLOBAL_HANDLE);
241 g_classrefs.push_back(TClassRef(""));
242
243 // aliases for std (setup already in pythonify)
245 g_name2classrefidx["::std"] = g_name2classrefidx["std"];
246 g_classrefs.push_back(TClassRef("std"));
247
248 // add a dummy global to refer to as null at index 0
249 g_globalvars.push_back(nullptr);
250
251 // disable fast path if requested
252 if (getenv("CPPYY_DISABLE_FASTPATH")) gEnableFastPath = false;
253
254 // fill the set of STL names
255 const char* stl_names[] = {"allocator", "auto_ptr", "bad_alloc", "bad_cast",
256 "bad_exception", "bad_typeid", "basic_filebuf", "basic_fstream", "basic_ifstream",
257 "basic_ios", "basic_iostream", "basic_istream", "basic_istringstream",
258 "basic_ofstream", "basic_ostream", "basic_ostringstream", "basic_streambuf",
259 "basic_string", "basic_stringbuf", "basic_stringstream", "binary_function",
260 "binary_negate", "bitset", "byte", "char_traits", "codecvt_byname", "codecvt", "collate",
261 "collate_byname", "compare", "complex", "ctype_byname", "ctype", "default_delete",
262 "deque", "divides", "domain_error", "equal_to", "exception", "forward_list", "fpos",
263 "function", "greater_equal", "greater", "gslice_array", "gslice", "hash", "indirect_array",
264 "integer_sequence", "invalid_argument", "ios_base", "istream_iterator", "istreambuf_iterator",
265 "istrstream", "iterator_traits", "iterator", "length_error", "less_equal", "less",
266 "list", "locale", "localedef utility", "locale utility", "logic_error", "logical_and",
267 "logical_not", "logical_or", "map", "mask_array", "mem_fun", "mem_fun_ref", "messages",
268 "messages_byname", "minus", "modulus", "money_get", "money_put", "moneypunct",
269 "moneypunct_byname", "multimap", "multiplies", "multiset", "negate", "not_equal_to",
270 "num_get", "num_put", "numeric_limits", "numpunct", "numpunct_byname",
271 "ostream_iterator", "ostreambuf_iterator", "ostrstream", "out_of_range",
272 "overflow_error", "pair", "plus", "pointer_to_binary_function",
273 "pointer_to_unary_function", "priority_queue", "queue", "range_error",
274 "raw_storage_iterator", "reverse_iterator", "runtime_error", "set", "shared_ptr",
275 "slice_array", "slice", "stack", "string", "strstream", "strstreambuf",
276 "time_get_byname", "time_get", "time_put_byname", "time_put", "unary_function",
277 "unary_negate", "unique_ptr", "underflow_error", "unordered_map", "unordered_multimap",
278 "unordered_multiset", "unordered_set", "valarray", "vector", "weak_ptr", "wstring",
279 "__hash_not_enabled"};
280 for (auto& name : stl_names)
281 gSTLNames.insert(name);
282
283 // set opt level (default to 2 if not given; Cling itself defaults to 0)
284 int optLevel = 2;
285 if (getenv("CPPYY_OPT_LEVEL")) optLevel = atoi(getenv("CPPYY_OPT_LEVEL"));
286 if (optLevel != 0) {
287 std::ostringstream s;
288 s << "#pragma cling optimize " << optLevel;
289 gInterpreter->ProcessLine(s.str().c_str());
290 }
291
292 // load frequently used headers
293 const char* code =
294 "#include <iostream>\n"
295 "#include <string>\n"
296 "#include <DllImport.h>\n" // defines R__EXTERN
297 "#include <vector>\n"
298 "#include <utility>";
299 gInterpreter->ProcessLine(code);
300
301 // create helpers for comparing thingies
302 gInterpreter->Declare(
303 "namespace __cppyy_internal { template<class C1, class C2>"
304 " bool is_equal(const C1& c1, const C2& c2) { return (bool)(c1 == c2); } }");
305 gInterpreter->Declare(
306 "namespace __cppyy_internal { template<class C1, class C2>"
307 " bool is_not_equal(const C1& c1, const C2& c2) { return (bool)(c1 != c2); } }");
308
309 // retrieve all initial (ROOT) C++ names in the global scope to allow filtering later
310 if (!getenv("CPPYY_NO_ROOT_FILTER")) {
311 gROOT->GetListOfGlobals(true); // force initialize
312 gROOT->GetListOfGlobalFunctions(true); // id.
313 std::set<std::string> initial;
315 gInitialNames = initial;
316
317#ifndef WIN32
318 gRootSOs.insert("libCore.so ");
319 gRootSOs.insert("libRIO.so ");
320 gRootSOs.insert("libThread.so ");
321 gRootSOs.insert("libMathCore.so ");
322#else
323 gRootSOs.insert("libCore.dll ");
324 gRootSOs.insert("libRIO.dll ");
325 gRootSOs.insert("libThread.dll ");
326 gRootSOs.insert("libMathCore.dll ");
327#endif
328 }
329
330 // start off with a reasonable size placeholder for wrappers
331 gWrapperHolder.reserve(1024);
332
333 // create an exception handler to process signals
334 gExceptionHandler = new TExceptionHandlerImp{};
335 }
336
337 ~ApplicationStarter() {
338 for (auto wrap : gWrapperHolder)
339 delete wrap;
340 delete gExceptionHandler; gExceptionHandler = nullptr;
341 }
342} _applicationStarter;
343
344} // unnamed namespace
345
346
347// local helpers -------------------------------------------------------------
348static inline
350{
351 assert((ClassRefs_t::size_type)scope < g_classrefs.size());
352 return g_classrefs[(ClassRefs_t::size_type)scope];
353}
354
355static inline
357 CallWrapper* wrap = ((CallWrapper*)method);
358 if (!wrap->fTF || wrap->fTF->GetDeclId() != wrap->fDecl) {
359 MethodInfo_t* mi = gInterpreter->MethodInfo_Factory(wrap->fDecl);
360 wrap->fTF = new TFunction(mi);
361 }
362 return wrap->fTF;
363}
364
365/*
366static inline
367CallWrapper::DeclId_t m2d(Cppyy::TCppMethod_t method) {
368 CallWrapper* wrap = ((CallWrapper*)method);
369 if (!wrap->fTF || wrap->fTF->GetDeclId() != wrap->fDecl) {
370 MethodInfo_t* mi = gInterpreter->MethodInfo_Factory(wrap->fDecl);
371 wrap->fTF = new TFunction(mi);
372 }
373 return wrap->fDecl;
374}
375*/
376
377static inline
378char* cppstring_to_cstring(const std::string& cppstr)
379{
380 char* cstr = (char*)malloc(cppstr.size()+1);
381 memcpy(cstr, cppstr.c_str(), cppstr.size()+1);
382 return cstr;
383}
384
385static inline
386bool match_name(const std::string& tname, const std::string fname)
387{
388// either match exactly, or match the name as template
389 if (fname.rfind(tname, 0) == 0) {
390 if ((tname.size() == fname.size()) ||
391 (tname.size() < fname.size() && fname[tname.size()] == '<'))
392 return true;
393 }
394 return false;
395}
396
397static inline
398bool is_missclassified_stl(const std::string& name)
399{
400 std::string::size_type pos = name.find('<');
401 if (pos != std::string::npos)
402 return gSTLNames.find(name.substr(0, pos)) != gSTLNames.end();
403 return gSTLNames.find(name) != gSTLNames.end();
404}
405
406
407// direct interpreter access -------------------------------------------------
408bool Cppyy::Compile(const std::string& code, bool /*silent*/)
409{
410 return gInterpreter->Declare(code.c_str());
411}
412
414{
415 if (klass && obj && !IsNamespace((TCppScope_t)klass))
416 return gInterpreter->ToString(GetScopedFinalName(klass).c_str(), (void*)obj);
417 return "";
418}
419
420
421// name to opaque C++ scope representation -----------------------------------
422std::string Cppyy::ResolveName(const std::string& cppitem_name)
423{
424// Fully resolve the given name to the final type name.
425
426// try memoized type cache, in case seen before
427 std::string memoized = find_memoized_resolved_name(cppitem_name);
428 if (!memoized.empty()) return memoized;
429
430// remove global scope '::' if present
431 std::string tclean = cppitem_name.compare(0, 2, "::") == 0 ?
432 cppitem_name.substr(2, std::string::npos) : cppitem_name;
433
434// classes (most common)
435 tclean = TClassEdit::CleanType(tclean.c_str());
436 if (tclean.empty() /* unknown, eg. an operator */) return cppitem_name;
437
438// reduce [N] to []
439 if (tclean[tclean.size()-1] == ']')
440 tclean = tclean.substr(0, tclean.rfind('[')) + "[]";
441
442 if (tclean.rfind("byte", 0) == 0 || tclean.rfind("std::byte", 0) == 0)
443 return tclean;
444
445// remove __restrict and __restrict__
446 auto pos = tclean.rfind("__restrict");
447 if (pos != std::string::npos)
448 tclean = tclean.substr(0, pos);
449
450 if (tclean.compare(0, 9, "std::byte") == 0)
451 return tclean;
452
453
454// check data types list (accept only builtins as typedefs will
455// otherwise not be resolved)
456 if (IsBuiltin(tclean)) return tclean;
457// special case for enums
458 if (IsEnum(cppitem_name))
459 return ResolveEnum(cppitem_name);
460
461// special case for clang's builtin __type_pack_element (which does not resolve)
462 pos = cppitem_name.size() > 20 ? \
463 cppitem_name.rfind("__type_pack_element", 5) : std::string::npos;
464 if (pos != std::string::npos) {
465 // shape is "[std::]__type_pack_element<index,type1,type2,...,typeN>cpd": extract
466 // first the index, and from there the indexed type; finally, restore the
467 // qualifiers
468 const char* str = cppitem_name.c_str();
469 char* endptr = nullptr;
470 unsigned long index = strtoul(str+20+pos, &endptr, 0);
471
472 std::string tmplvars{endptr};
473 auto start = tmplvars.find(',') + 1;
474 auto end = tmplvars.find(',', start);
475 while (index != 0) {
476 start = end+1;
477 end = tmplvars.find(',', start);
478 if (end == std::string::npos) end = tmplvars.rfind('>');
479 --index;
480 }
481
482 std::string resolved = tmplvars.substr(start, end-start);
483 auto cpd = tmplvars.rfind('>');
484 if (cpd != std::string::npos && cpd+1 != tmplvars.size())
485 return resolved + tmplvars.substr(cpd+1, std::string::npos);
486 return resolved;
487 }
488
489// typedefs etc. (and a couple of hacks around TClassEdit-isms, fixing of which
490// in ResolveTypedef itself is a TODO ...)
491 tclean = TClassEdit::ResolveTypedef(tclean.c_str(), true);
492 pos = 0;
493 while ((pos = tclean.find("::::", pos)) != std::string::npos) {
494 tclean.replace(pos, 4, "::");
495 pos += 2;
496 }
497
498 if (tclean.compare(0, 6, "const ") != 0)
499 return TClassEdit::ShortType(tclean.c_str(), 2);
500 return "const " + TClassEdit::ShortType(tclean.c_str(), 2);
501}
502
503
504std::string Cppyy::ResolveEnum(const std::string& enum_type)
505{
506// The underlying type of a an enum may be any kind of integer.
507// Resolve that type via a workaround (note: this function assumes
508// that the enum_type name is a valid enum type name)
509 auto res = resolved_enum_types.find(enum_type);
510 if (res != resolved_enum_types.end())
511 return res->second;
512
513// desugar the type before resolving
514 std::string et_short = TClassEdit::ShortType(enum_type.c_str(), 1);
515 if (et_short.find("(unnamed") == std::string::npos) {
516 std::ostringstream decl;
517 // TODO: now presumed fixed with https://sft.its.cern.ch/jira/browse/ROOT-6988
518 for (auto& itype : {"unsigned int"}) {
519 decl << "std::is_same<"
520 << itype
521 << ", std::underlying_type<"
522 << et_short
523 << ">::type>::value;";
524 if (gInterpreter->ProcessLine(decl.str().c_str())) {
525 // TODO: "re-sugaring" like this is brittle, but the top
526 // should be re-translated into AST-based code anyway
527 std::string resugared;
528 if (et_short.size() != enum_type.size()) {
529 auto pos = enum_type.find(et_short);
530 if (pos != std::string::npos) {
531 resugared = enum_type.substr(0, pos) + itype;
532 if (pos+et_short.size() < enum_type.size())
533 resugared += enum_type.substr(pos+et_short.size(), std::string::npos);
534 }
535 }
536 if (resugared.empty()) resugared = itype;
537 resolved_enum_types[enum_type] = resugared;
538 return resugared;
539 }
540 }
541 }
542
543// failed or anonymous ... signal upstream to special case this
544 int ipos = (int)enum_type.size()-1;
545 for (; 0 <= ipos; --ipos) {
546 char c = enum_type[ipos];
547 if (isspace(c)) continue;
548 if (isalnum(c) || c == '_' || c == '>' || c == ')') break;
549 }
550 bool isConst = enum_type.find("const ", 6) != std::string::npos;
551 std::string restype = isConst ? "const " : "";
552 restype += "internal_enum_type_t"+enum_type.substr((std::string::size_type)ipos+1, std::string::npos);
553 resolved_enum_types[enum_type] = restype;
554 return restype; // should default to some int variant
555}
556
557Cppyy::TCppScope_t Cppyy::GetScope(const std::string& sname)
558{
559// First, try cache
560 TCppType_t result = find_memoized_scope(sname);
561 if (result) return result;
562
563// Second, skip builtins before going through the more expensive steps of resolving
564// typedefs and looking up TClass
565 if (g_builtins.find(sname) != g_builtins.end())
566 return (TCppScope_t)0;
567
568// TODO: scope_name should always be final already?
569// Resolve name fully before lookup to make sure all aliases point to the same scope
570 std::string scope_name = ResolveName(sname);
571 bool bHasAlias1 = sname != scope_name;
572 if (bHasAlias1) {
573 result = find_memoized_scope(scope_name);
574 if (result) {
575 g_name2classrefidx[sname] = result;
576 return result;
577 }
578 }
579
580// both failed, but may be STL name that's missing 'std::' now, but didn't before
581 bool b_scope_name_missclassified = is_missclassified_stl(scope_name);
582 if (b_scope_name_missclassified) {
583 result = find_memoized_scope("std::"+scope_name);
584 if (result) g_name2classrefidx["std::"+scope_name] = (ClassRefs_t::size_type)result;
585 }
586 bool b_sname_missclassified = bHasAlias1 ? is_missclassified_stl(sname) : false;
587 if (b_sname_missclassified) {
588 if (!result) result = find_memoized_scope("std::"+sname);
589 if (result) g_name2classrefidx["std::"+sname] = (ClassRefs_t::size_type)result;
590 }
591
592 if (result) return result;
593
594// use TClass directly, to enable auto-loading; class may be stubbed (eg. for
595// function returns) or forward declared, leading to a non-null TClass that is
596// otherwise invalid/unusable
597 TClassRef cr(TClass::GetClass(scope_name.c_str(), true /* load */, true /* silent */));
598 if (!cr.GetClass())
599 return (TCppScope_t)0;
600
601// memoize found/created TClass
602 bool bHasAlias2 = cr->GetName() != scope_name;
603 if (bHasAlias2) {
604 result = find_memoized_scope(cr->GetName());
605 if (result) {
606 g_name2classrefidx[scope_name] = result;
607 if (bHasAlias1) g_name2classrefidx[sname] = result;
608 return result;
609 }
610 }
611
612 ClassRefs_t::size_type sz = g_classrefs.size();
613 g_name2classrefidx[scope_name] = sz;
614 if (bHasAlias1) g_name2classrefidx[sname] = sz;
615 if (bHasAlias2) g_name2classrefidx[cr->GetName()] = sz;
616// TODO: make ROOT/meta NOT remove std :/
617 if (b_scope_name_missclassified)
618 g_name2classrefidx["std::"+scope_name] = sz;
619 if (b_sname_missclassified)
620 g_name2classrefidx["std::"+sname] = sz;
621
622 g_classrefs.push_back(TClassRef(scope_name.c_str()));
623
624 return (TCppScope_t)sz;
625}
626
627bool Cppyy::IsTemplate(const std::string& template_name)
628{
629 return (bool)gInterpreter->CheckClassTemplate(template_name.c_str());
630}
631
632namespace {
633 class AutoCastRTTI {
634 public:
635 virtual ~AutoCastRTTI() {}
636 };
637}
638
640{
641 TClassRef& cr = type_from_handle(klass);
642 if (!cr.GetClass() || !obj) return klass;
643
644#ifdef _WIN64
645// Cling does not provide a consistent ImageBase address for calculating relative addresses
646// as used in Windows 64b RTTI. So, check for our own RTTI extension instead. If that fails,
647// see whether the unmangled raw_name is available (e.g. if this is an MSVC compiled rather
648// than JITed class) and pass on if it is.
649 volatile const char* raw = nullptr; // to prevent too aggressive reordering
650 try {
651 // this will filter those objects that do not have RTTI to begin with (throws)
652 AutoCastRTTI* pcst = (AutoCastRTTI*)obj;
653 raw = typeid(*pcst).raw_name();
654
655 // check the signature id (0 == absolute, 1 == relative, 2 == ours)
656 void* vfptr = *(void**)((intptr_t)obj);
657 void* meta = (void*)((intptr_t)*((void**)((intptr_t)vfptr-sizeof(void*))));
658 if (*(intptr_t*)meta == 2) {
659 // access the extra data item which is an absolute pointer to the RTTI
660 void* ptdescr = (void*)((intptr_t)meta + 4*sizeof(unsigned long)+sizeof(void*));
661 if (ptdescr && *(void**)ptdescr) {
662 auto rtti = *(std::type_info**)ptdescr;
663 raw = rtti->raw_name();
664 if (raw && raw[0] != '\0') // likely unnecessary
665 return (TCppType_t)GetScope(rtti->name());
666 }
667
668 return klass; // do not fall through if no RTTI info available
669 }
670
671 // if the raw name is the empty string (no guarantees that this is so as truly, the
672 // address is corrupt, but it is common to be empty), then there is no accessible RTTI
673 // and getting the unmangled name will crash ...
674 if (!raw)
675 return klass;
676 } catch (std::bad_typeid) {
677 return klass; // can't risk passing to ROOT/meta as it may do RTTI
678 }
679#endif
680
681 TClass* clActual = cr->GetActualClass((void*)obj);
682 // The additional check using TClass::GetClassInfo is to prevent returning classes of which the Interpreter has no info
683 if (clActual && clActual != cr.GetClass() && clActual->GetClassInfo()) {
684 auto itt = g_name2classrefidx.find(clActual->GetName());
685 if (itt != g_name2classrefidx.end())
686 return (TCppType_t)itt->second;
687 return (TCppType_t)GetScope(clActual->GetName());
688 }
689
690 return klass;
691}
692
694{
695 TClassRef& cr = type_from_handle(klass);
696 if (cr.GetClass() && cr->GetClassInfo())
697 return (size_t)gInterpreter->ClassInfo_Size(cr->GetClassInfo());
698 return (size_t)0;
699}
700
701size_t Cppyy::SizeOf(const std::string& type_name)
702{
703 TDataType* dt = gROOT->GetType(type_name.c_str());
704 if (dt) return dt->Size();
705 return SizeOf(GetScope(type_name));
706}
707
708
709bool Cppyy::IsBuiltin(const std::string& type_name)
710{
711 if (g_builtins.find(type_name) != g_builtins.end())
712 return true;
713
714 const std::string& tclean = TClassEdit::CleanType(type_name.c_str(), 1);
715 if (g_builtins.find(tclean) != g_builtins.end())
716 return true;
717
718 if (strstr(tclean.c_str(), "std::complex"))
719 return true;
720
721 return false;
722}
723
724bool Cppyy::IsComplete(const std::string& type_name)
725{
726// verify whether the dictionary of this class is fully available
727 bool b = false;
728
729 int oldEIL = gErrorIgnoreLevel;
730 gErrorIgnoreLevel = 3000;
731 TClass* klass = TClass::GetClass(TClassEdit::ShortType(type_name.c_str(), 1).c_str());
732 if (klass && klass->GetClassInfo()) // works for normal case w/ dict
733 b = gInterpreter->ClassInfo_IsLoaded(klass->GetClassInfo());
734 else { // special case for forward declared classes
735 ClassInfo_t* ci = gInterpreter->ClassInfo_Factory(type_name.c_str());
736 if (ci) {
737 b = gInterpreter->ClassInfo_IsLoaded(ci);
738 gInterpreter->ClassInfo_Delete(ci); // we own the fresh class info
739 }
740 }
741 gErrorIgnoreLevel = oldEIL;
742 return b;
743}
744
745// memory management ---------------------------------------------------------
747{
749 return (TCppObject_t)::operator new(gInterpreter->ClassInfo_Size(cr->GetClassInfo()));
750}
751
753{
754 ::operator delete(instance);
755}
756
758{
760 if (arena)
761 return (TCppObject_t)cr->New(arena, TClass::kRealNew);
762 return (TCppObject_t)cr->New(TClass::kRealNew);
763}
764
765static std::map<Cppyy::TCppType_t, bool> sHasOperatorDelete;
767{
770 cr->Destructor((void*)instance);
771 else {
772 ROOT::DelFunc_t fdel = cr->GetDelete();
773 if (fdel) fdel((void*)instance);
774 else {
775 auto ib = sHasOperatorDelete.find(type);
776 if (ib == sHasOperatorDelete.end()) {
777 TFunction *f = (TFunction *)cr->GetMethodAllAny("operator delete");
778 sHasOperatorDelete[type] = (bool)(f && (f->Property() & kIsPublic));
779 ib = sHasOperatorDelete.find(type);
780 }
781 ib->second ? cr->Destructor((void *)instance) : ::operator delete((void *)instance);
782 }
783 }
784}
785
786
787// method/function dispatching -----------------------------------------------
789{
790// TODO: method should be a callfunc, so that no mapping would be needed.
791 CallWrapper* wrap = (CallWrapper*)method;
792
793 CallFunc_t* callf = gInterpreter->CallFunc_Factory();
794 MethodInfo_t* meth = gInterpreter->MethodInfo_Factory(wrap->fDecl);
795 gInterpreter->CallFunc_SetFunc(callf, meth);
796 gInterpreter->MethodInfo_Delete(meth);
797
798 if (!(callf && gInterpreter->CallFunc_IsValid(callf))) {
799 // TODO: propagate this error to caller w/o use of Python C-API
800 /*
801 PyErr_Format(PyExc_RuntimeError, "could not resolve %s::%s(%s)",
802 const_cast<TClassRef&>(klass).GetClassName(),
803 wrap.fName, callString.c_str()); */
804 std::cerr << "TODO: report unresolved function error to Python\n";
805 if (callf) gInterpreter->CallFunc_Delete(callf);
807 }
808
809// generate the wrapper and JIT it; ignore wrapper generation errors (will simply
810// result in a nullptr that is reported upstream if necessary; often, however,
811// there is a different overload available that will do)
812 auto oldErrLvl = gErrorIgnoreLevel;
814 wrap->fFaceptr = gInterpreter->CallFunc_IFacePtr(callf);
815 gErrorIgnoreLevel = oldErrLvl;
816
817 gInterpreter->CallFunc_Delete(callf); // does not touch IFacePtr
818 return wrap->fFaceptr;
819}
820
821static inline
822bool copy_args(Parameter* args, size_t nargs, void** vargs)
823{
824 bool runRelease = false;
825 for (size_t i = 0; i < nargs; ++i) {
826 switch (args[i].fTypeCode) {
827 case 'X': /* (void*)type& with free */
828 runRelease = true;
829 case 'V': /* (void*)type& */
830 vargs[i] = args[i].fValue.fVoidp;
831 break;
832 case 'r': /* const type& */
833 vargs[i] = args[i].fRef;
834 break;
835 default: /* all other types in union */
836 vargs[i] = (void*)&args[i].fValue.fVoidp;
837 break;
838 }
839 }
840 return runRelease;
841}
842
843static inline
844void release_args(Parameter* args, size_t nargs) {
845 for (size_t i = 0; i < nargs; ++i) {
846 if (args[i].fTypeCode == 'X')
847 free(args[i].fValue.fVoidp);
848 }
849}
850
851static inline bool WrapperCall(Cppyy::TCppMethod_t method, size_t nargs, void* args_, void* self, void* result)
852{
853 Parameter* args = (Parameter*)args_;
854 //bool is_direct = nargs & DIRECT_CALL;
855 nargs = CALL_NARGS(nargs);
856
857 CallWrapper* wrap = (CallWrapper*)method;
858 const TInterpreter::CallFuncIFacePtr_t& faceptr = wrap->fFaceptr.fGeneric ? wrap->fFaceptr : GetCallFunc(method);
859 if (!faceptr.fGeneric)
860 return false; // happens with compilation error
861
863 bool runRelease = false;
864 if (nargs <= SMALL_ARGS_N) {
865 void* smallbuf[SMALL_ARGS_N];
866 if (nargs) runRelease = copy_args(args, nargs, smallbuf);
867 faceptr.fGeneric(self, (int)nargs, smallbuf, result);
868 } else {
869 std::vector<void*> buf(nargs);
870 runRelease = copy_args(args, nargs, buf.data());
871 faceptr.fGeneric(self, (int)nargs, buf.data(), result);
872 }
873 if (runRelease) release_args(args, nargs);
874 return true;
875 }
876
878 bool runRelease = false;
879 if (nargs <= SMALL_ARGS_N) {
880 void* smallbuf[SMALL_ARGS_N];
881 if (nargs) runRelease = copy_args(args, nargs, (void**)smallbuf);
882 faceptr.fCtor((void**)smallbuf, result, (unsigned long)nargs);
883 } else {
884 std::vector<void*> buf(nargs);
885 runRelease = copy_args(args, nargs, buf.data());
886 faceptr.fCtor(buf.data(), result, (unsigned long)nargs);
887 }
888 if (runRelease) release_args(args, nargs);
889 return true;
890 }
891
893 std::cerr << " DESTRUCTOR NOT IMPLEMENTED YET! " << std::endl;
894 return false;
895 }
896
897 return false;
898}
899
900template<typename T>
901static inline
902T CallT(Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, size_t nargs, void* args)
903{
904 T t{};
905 if (WrapperCall(method, nargs, args, (void*)self, &t))
906 return t;
907 return (T)-1;
908}
909
910#define CPPYY_IMP_CALL(typecode, rtype) \
911rtype Cppyy::Call##typecode(TCppMethod_t method, TCppObject_t self, size_t nargs, void* args)\
912{ \
913 return CallT<rtype>(method, self, nargs, args); \
914}
915
916void Cppyy::CallV(TCppMethod_t method, TCppObject_t self, size_t nargs, void* args)
917{
918 if (!WrapperCall(method, nargs, args, (void*)self, nullptr))
919 return /* TODO ... report error */;
920}
921
922CPPYY_IMP_CALL(B, unsigned char)
929CPPYY_IMP_CALL(D, double )
931
932void* Cppyy::CallR(TCppMethod_t method, TCppObject_t self, size_t nargs, void* args)
933{
934 void* r = nullptr;
935 if (WrapperCall(method, nargs, args, (void*)self, &r))
936 return r;
937 return nullptr;
938}
939
941 TCppMethod_t method, TCppObject_t self, size_t nargs, void* args, size_t* length)
942{
943 char* cstr = nullptr;
944 TClassRef cr("std::string");
945 std::string* cppresult = (std::string*)malloc(sizeof(std::string));
946 if (WrapperCall(method, nargs, args, self, (void*)cppresult)) {
947 cstr = cppstring_to_cstring(*cppresult);
948 *length = cppresult->size();
949 cppresult->std::string::~basic_string();
950 } else
951 *length = 0;
952 free((void*)cppresult);
953 return cstr;
954}
955
957 TCppMethod_t method, TCppType_t /* klass */, size_t nargs, void* args)
958{
959 void* obj = nullptr;
960 if (WrapperCall(method, nargs, args, nullptr, &obj))
961 return (TCppObject_t)obj;
962 return (TCppObject_t)0;
963}
964
966{
968 cr->Destructor((void*)self, true);
969}
970
972 TCppObject_t self, size_t nargs, void* args, TCppType_t result_type)
973{
974 TClassRef& cr = type_from_handle(result_type);
975 void* obj = ::operator new(gInterpreter->ClassInfo_Size(cr->GetClassInfo()));
976 if (WrapperCall(method, nargs, args, self, obj))
977 return (TCppObject_t)obj;
978 ::operator delete(obj);
979 return (TCppObject_t)0;
980}
981
983{
984 if (check_enabled && !gEnableFastPath) return (TCppFuncAddr_t)nullptr;
985 TFunction* f = m2f(method);
986
987 TCppFuncAddr_t pf = (TCppFuncAddr_t)gInterpreter->FindSym(f->GetMangledName());
988 if (pf) return pf;
989
990 int ierr = 0;
991 const char* fn = TClassEdit::DemangleName(f->GetMangledName(), ierr);
992 if (ierr || !fn)
993 return pf;
994
995 // TODO: the following attempts are all brittle and leak transactions, but
996 // each properly exposes the symbol so subsequent lookups will succeed
997 if (strstr(f->GetName(), "<")) {
998 // force explicit instantiation and try again
999 std::ostringstream sig;
1000 sig << "template " << fn << ";";
1001 gInterpreter->ProcessLine(sig.str().c_str());
1002 } else {
1003 std::ostringstream sig;
1004
1005 std::string sfn = fn;
1006 std::string::size_type pos = sfn.find('(');
1007 if (pos != std::string::npos) sfn = sfn.substr(0, pos);
1008
1009 // start cast
1010 sig << '(' << f->GetReturnTypeName() << " (";
1011
1012 // add scope for methods
1013 pos = sfn.rfind(':');
1014 if (pos != std::string::npos) {
1015 std::string scope_name = sfn.substr(0, pos-1);
1016 TCppScope_t scope = GetScope(scope_name);
1017 if (scope && !IsNamespace(scope))
1018 sig << scope_name << "::";
1019 }
1020
1021 // finalize cast
1022 sig << "*)" << GetMethodSignature(method, false)
1023 << ((f->Property() & kIsConstMethod) ? " const" : "")
1024 << ')';
1025
1026 // load address
1027 sig << '&' << sfn;
1028 gInterpreter->Calc(sig.str().c_str());
1029 }
1030
1031 return (TCppFuncAddr_t)gInterpreter->FindSym(f->GetMangledName());
1032}
1033
1034
1035// handling of function argument buffer --------------------------------------
1037{
1038 return new Parameter[nargs];
1039}
1040
1042{
1043 delete [] (Parameter*)args;
1044}
1045
1047{
1048 return sizeof(Parameter);
1049}
1050
1052{
1053 return offsetof(Parameter, fTypeCode);
1054}
1055
1056
1057// scope reflection information ----------------------------------------------
1059{
1060// Test if this scope represents a namespace.
1061 if (scope == GLOBAL_HANDLE)
1062 return true;
1063 TClassRef& cr = type_from_handle(scope);
1064 if (cr.GetClass())
1065 return cr->Property() & kIsNamespace;
1066 return false;
1067}
1068
1070{
1071// Test if this type may not be instantiated.
1072 TClassRef& cr = type_from_handle(klass);
1073 if (cr.GetClass())
1074 return cr->Property() & kIsAbstract;
1075 return false;
1076}
1077
1078bool Cppyy::IsEnum(const std::string& type_name)
1079{
1080 if (type_name.empty()) return false;
1081 std::string tn_short = TClassEdit::ShortType(type_name.c_str(), 1);
1082 if (tn_short.empty()) return false;
1083 return gInterpreter->ClassInfo_IsEnum(tn_short.c_str());
1084}
1085
1087{
1088// Test if this type is an aggregate type
1089 TClassRef& cr = type_from_handle(klass);
1090 if (cr.GetClass())
1091 return cr->ClassProperty() & kClassIsAggregate;
1092 return false;
1093}
1094
1096{
1097// Test if this type has a default constructor or is a "plain old data" type
1099 if (cr.GetClass())
1100 return cr->HasDefaultConstructor() || (cr->ClassProperty() & kClassIsAggregate);
1101 return true;
1102}
1103
1104// helpers for stripping scope names
1105static
1106std::string outer_with_template(const std::string& name)
1107{
1108// Cut down to the outer-most scope from <name>, taking proper care of templates.
1109 int tpl_open = 0;
1110 for (std::string::size_type pos = 0; pos < name.size(); ++pos) {
1111 std::string::value_type c = name[pos];
1112
1113 // count '<' and '>' to be able to skip template contents
1114 if (c == '<')
1115 ++tpl_open;
1116 else if (c == '>')
1117 --tpl_open;
1118
1119 // collect name up to "::"
1120 else if (tpl_open == 0 && \
1121 c == ':' && pos+1 < name.size() && name[pos+1] == ':') {
1122 // found the extend of the scope ... done
1123 return name.substr(0, pos-1);
1124 }
1125 }
1126
1127// whole name is apparently a single scope
1128 return name;
1129}
1130
1131static
1132std::string outer_no_template(const std::string& name)
1133{
1134// Cut down to the outer-most scope from <name>, drop templates
1135 std::string::size_type first_scope = name.find(':');
1136 if (first_scope == std::string::npos)
1137 return name.substr(0, name.find('<'));
1138 std::string::size_type first_templ = name.find('<');
1139 if (first_templ == std::string::npos)
1140 return name.substr(0, first_scope);
1141 return name.substr(0, std::min(first_templ, first_scope));
1142}
1143
1144#define FILL_COLL(type, filter) { \
1145 TIter itr{coll}; \
1146 type* obj = nullptr; \
1147 while ((obj = (type*)itr.Next())) { \
1148 const char* nm = obj->GetName(); \
1149 if (nm && nm[0] != '_' && !(obj->Property() & (filter))) { \
1150 if (gInitialNames.find(nm) == gInitialNames.end()) \
1151 cppnames.insert(nm); \
1152 }}}
1153
1154static inline
1155void cond_add(Cppyy::TCppScope_t scope, const std::string& ns_scope,
1156 std::set<std::string>& cppnames, const char* name, bool nofilter = false)
1157{
1158 if (!name || name[0] == '_' || strstr(name, ".h") != 0 || strncmp(name, "operator", 8) == 0)
1159 return;
1160
1161 if (scope == GLOBAL_HANDLE) {
1162 std::string to_add = outer_no_template(name);
1163 if ((nofilter || gInitialNames.find(to_add) == gInitialNames.end()) && !is_missclassified_stl(name))
1164 cppnames.insert(outer_no_template(name));
1165 } else if (scope == STD_HANDLE) {
1166 if (strncmp(name, "std::", 5) == 0) {
1167 name += 5;
1168#ifdef __APPLE__
1169 if (strncmp(name, "__1::", 5) == 0) name += 5;
1170#endif
1171 } else if (!is_missclassified_stl(name))
1172 return;
1173 cppnames.insert(outer_no_template(name));
1174 } else {
1175 if (strncmp(name, ns_scope.c_str(), ns_scope.size()) == 0)
1176 cppnames.insert(outer_with_template(name + ns_scope.size()));
1177 }
1178}
1179
1180void Cppyy::GetAllCppNames(TCppScope_t scope, std::set<std::string>& cppnames)
1181{
1182// Collect all known names of C++ entities under scope. This is useful for IDEs
1183// employing tab-completion, for example. Note that functions names need not be
1184// unique as they can be overloaded.
1185 TClassRef& cr = type_from_handle(scope);
1186 if (scope != GLOBAL_HANDLE && !(cr.GetClass() && cr->Property()))
1187 return;
1188
1189 std::string ns_scope = GetFinalName(scope);
1190 if (scope != GLOBAL_HANDLE) ns_scope += "::";
1191
1192// add existing values from read rootmap files if within this scope
1193 TCollection* coll = gInterpreter->GetMapfile()->GetTable();
1194 {
1195 TIter itr{coll};
1196 TEnvRec* ev = nullptr;
1197 while ((ev = (TEnvRec*)itr.Next())) {
1198 // TEnv contains rootmap entries and user-side rootmap files may be already
1199 // loaded on startup. Thus, filter on file name rather than load time.
1200 if (gRootSOs.find(ev->GetValue()) == gRootSOs.end())
1201 cond_add(scope, ns_scope, cppnames, ev->GetName(), true);
1202 }
1203 }
1204
1205// do we care about the class table or are the rootmap and list of types enough?
1206/*
1207 gClassTable->Init();
1208 const int N = gClassTable->Classes();
1209 for (int i = 0; i < N; ++i)
1210 cond_add(scope, ns_scope, cppnames, gClassTable->Next());
1211*/
1212
1213// any other types (e.g. that may have come from parsing headers)
1214 coll = gROOT->GetListOfTypes();
1215 {
1216 TIter itr{coll};
1217 TDataType* dt = nullptr;
1218 while ((dt = (TDataType*)itr.Next())) {
1219 if (!(dt->Property() & kIsFundamental)) {
1220 cond_add(scope, ns_scope, cppnames, dt->GetName());
1221 }
1222 }
1223 }
1224
1225// add functions
1226 coll = (scope == GLOBAL_HANDLE) ?
1227 gROOT->GetListOfGlobalFunctions() : cr->GetListOfMethods();
1228 {
1229 TIter itr{coll};
1230 TFunction* obj = nullptr;
1231 while ((obj = (TFunction*)itr.Next())) {
1232 const char* nm = obj->GetName();
1233 // skip templated functions, adding only the un-instantiated ones
1234 if (nm && nm[0] != '_' && strstr(nm, "<") == 0 && strncmp(nm, "operator", 8) != 0) {
1235 if (gInitialNames.find(nm) == gInitialNames.end())
1236 cppnames.insert(nm);
1237 }
1238 }
1239 }
1240
1241// add uninstantiated templates
1242 coll = (scope == GLOBAL_HANDLE) ?
1243 gROOT->GetListOfFunctionTemplates() : cr->GetListOfFunctionTemplates();
1245
1246// add (global) data members
1247 if (scope == GLOBAL_HANDLE) {
1248 coll = gROOT->GetListOfGlobals();
1250 } else {
1251 coll = cr->GetListOfDataMembers();
1253 coll = cr->GetListOfUsingDataMembers();
1255 }
1256
1257// add enums values only for user classes/namespaces
1258 if (scope != GLOBAL_HANDLE && scope != STD_HANDLE) {
1259 coll = cr->GetListOfEnums();
1261 }
1262
1263#ifdef __APPLE__
1264// special case for Apple, add version namespace '__1' entries to std
1265 if (scope == STD_HANDLE)
1266 GetAllCppNames(GetScope("std::__1"), cppnames);
1267#endif
1268}
1269
1270
1271// class reflection information ----------------------------------------------
1272std::vector<Cppyy::TCppScope_t> Cppyy::GetUsingNamespaces(TCppScope_t scope)
1273{
1274 std::vector<Cppyy::TCppScope_t> res;
1275 if (!IsNamespace(scope))
1276 return res;
1277
1278#ifdef __APPLE__
1279 if (scope == STD_HANDLE) {
1280 res.push_back(GetScope("__1"));
1281 return res;
1282 }
1283#endif
1284
1285 TClassRef& cr = type_from_handle(scope);
1286 if (!cr.GetClass() || !cr->GetClassInfo())
1287 return res;
1288
1289 const std::vector<std::string>& v = gInterpreter->GetUsingNamespaces(cr->GetClassInfo());
1290 res.reserve(v.size());
1291 for (const auto& uid : v) {
1292 Cppyy::TCppScope_t uscope = GetScope(uid);
1293 if (uscope) res.push_back(uscope);
1294 }
1295
1296 return res;
1297}
1298
1299
1300// class reflection information ----------------------------------------------
1302{
1303 if (klass == GLOBAL_HANDLE)
1304 return "";
1305 TClassRef& cr = type_from_handle(klass);
1306 std::string clName = cr->GetName();
1307// TODO: why is this template splitting needed?
1308 std::string::size_type pos = clName.substr(0, clName.find('<')).rfind("::");
1309 if (pos != std::string::npos)
1310 return clName.substr(pos+2, std::string::npos);
1311 return clName;
1312}
1313
1315{
1316 if (klass == GLOBAL_HANDLE)
1317 return "";
1318 TClassRef& cr = type_from_handle(klass);
1319 if (cr.GetClass()) {
1320 std::string name = cr->GetName();
1322 return std::string("std::")+cr->GetName();
1323 return cr->GetName();
1324 }
1325 return "";
1326}
1327
1329{
1330 TClassRef& cr = type_from_handle(klass);
1331 if (!cr.GetClass())
1332 return false;
1333
1334 TFunction* f = cr->GetMethod(("~"+GetFinalName(klass)).c_str(), "");
1335 if (f && (f->Property() & kIsVirtual))
1336 return true;
1337
1338 return false;
1339}
1340
1342{
1343 int is_complex = 1;
1344 size_t nbases = 0;
1345
1346 TClassRef& cr = type_from_handle(klass);
1347 if (cr.GetClass() && cr->GetListOfBases() != 0)
1348 nbases = GetNumBases(klass);
1349
1350 if (1 < nbases)
1351 is_complex = 1;
1352 else if (nbases == 0)
1353 is_complex = 0;
1354 else { // one base class only
1355 TBaseClass* base = (TBaseClass*)cr->GetListOfBases()->At(0);
1356 if (base->Property() & kIsVirtualBase)
1357 is_complex = 1; // TODO: verify; can be complex, need not be.
1358 else
1359 is_complex = HasComplexHierarchy(GetScope(base->GetName()));
1360 }
1361
1362 return is_complex;
1363}
1364
1366{
1367// Get the total number of base classes that this class has.
1368 TClassRef& cr = type_from_handle(klass);
1369 if (cr.GetClass() && cr->GetListOfBases() != 0)
1370 return (TCppIndex_t)cr->GetListOfBases()->GetSize();
1371 return (TCppIndex_t)0;
1372}
1373
1374////////////////////////////////////////////////////////////////////////////////
1375/// \fn Cppyy::TCppIndex_t GetLongestInheritancePath(TClass *klass)
1376/// \brief Retrieve number of base classes in the longest branch of the
1377/// inheritance tree of the input class.
1378/// \param[in] klass The class to start the retrieval process from.
1379///
1380/// This is a helper function for Cppyy::GetNumBasesLongestBranch.
1381/// Given an inheritance tree, the function assigns weight 1 to each class that
1382/// has at least one base. Starting from the input class, the function is
1383/// called recursively on all the bases. For each base the return value is one
1384/// (the weight of the base itself) plus the maximum value retrieved for their
1385/// bases in turn. For example, given the following inheritance tree:
1386///
1387/// ~~~{.cpp}
1388/// class A {}; class B: public A {};
1389/// class X {}; class Y: public X {}; class Z: public Y {};
1390/// class C: public B, Z {};
1391/// ~~~
1392///
1393/// calling this function on an instance of `C` will return 3, the steps
1394/// required to go from C to X.
1396{
1397
1398 auto directbases = klass->GetListOfBases();
1399 if (!directbases) {
1400 // This is a leaf with no bases
1401 return 0;
1402 }
1403 auto ndirectbases = directbases->GetSize();
1404 if (ndirectbases == 0) {
1405 // This is a leaf with no bases
1406 return 0;
1407 } else {
1408 // If there is at least one direct base
1409 std::vector<Cppyy::TCppIndex_t> nbases_branches;
1410 nbases_branches.reserve(ndirectbases);
1411
1412 // Traverse all direct bases of the current class and call the function
1413 // recursively
1414 for (auto baseclass : TRangeDynCast<TBaseClass>(directbases)) {
1415 if (!baseclass)
1416 continue;
1417 if (auto baseclass_tclass = baseclass->GetClassPointer()) {
1419 }
1420 }
1421
1422 // Get longest path among the direct bases of the current class
1423 auto longestbranch = std::max_element(std::begin(nbases_branches), std::end(nbases_branches));
1424
1425 // Add 1 to include the current class in the count
1426 return 1 + *longestbranch;
1427 }
1428}
1429
1430////////////////////////////////////////////////////////////////////////////////
1431/// \fn Cppyy::TCppIndex_t Cppyy::GetNumBasesLongestBranch(TCppType_t klass)
1432/// \brief Retrieve number of base classes in the longest branch of the
1433/// inheritance tree.
1434/// \param[in] klass The class to start the retrieval process from.
1435///
1436/// The function converts the input class to a `TClass *` and calls
1437/// GetLongestInheritancePath.
1439{
1440
1441 const auto &cr = type_from_handle(klass);
1442
1443 if (auto klass_tclass = cr.GetClass()) {
1445 }
1446
1447 // In any other case, return zero
1448 return 0;
1449}
1450
1452{
1454 return ((TBaseClass*)cr->GetListOfBases()->At((int)ibase))->GetName();
1455}
1456
1458{
1459 if (derived == base)
1460 return true;
1463 return derived_type->GetBaseClass(base_type) != 0;
1464}
1465
1467{
1469 const std::string& tn = cr->GetName();
1470 if (gSmartPtrTypes.find(tn.substr(0, tn.find("<"))) != gSmartPtrTypes.end())
1471 return true;
1472 return false;
1473}
1474
1476 const std::string& tname, TCppType_t* raw, TCppMethod_t* deref)
1477{
1478 const std::string& rn = ResolveName(tname);
1479 if (gSmartPtrTypes.find(rn.substr(0, rn.find("<"))) != gSmartPtrTypes.end()) {
1480 if (!raw && !deref) return true;
1481
1483 if (cr.GetClass()) {
1484 TFunction* func = cr->GetMethod("operator->", "");
1485 if (!func) {
1486 gInterpreter->UpdateListOfMethods(cr.GetClass());
1487 func = cr->GetMethod("operator->", "");
1488 }
1489 if (func) {
1490 if (deref) *deref = (TCppMethod_t)new_CallWrapper(func);
1491 if (raw) *raw = GetScope(TClassEdit::ShortType(
1492 func->GetReturnTypeNormalizedName().c_str(), 1));
1493 return (!deref || *deref) && (!raw || *raw);
1494 }
1495 }
1496 }
1497
1498 return false;
1499}
1500
1501void Cppyy::AddSmartPtrType(const std::string& type_name)
1502{
1504}
1505
1506void Cppyy::AddTypeReducer(const std::string& /*reducable*/, const std::string& /*reduced*/)
1507{
1508 // This function is deliberately left empty, because it is not used in
1509 // PyROOT, and synchronizing it with cppyy-backend upstream would require
1510 // patches to ROOT meta.
1511}
1512
1513
1514// type offsets --------------------------------------------------------------
1516 TCppObject_t address, int direction, bool rerror)
1517{
1518// calculate offsets between declared and actual type, up-cast: direction > 0; down-cast: direction < 0
1519 if (derived == base || !(base && derived))
1520 return (ptrdiff_t)0;
1521
1523 TClassRef& cb = type_from_handle(base);
1524
1525 if (!cd.GetClass() || !cb.GetClass())
1526 return (ptrdiff_t)0;
1527
1528 ptrdiff_t offset = -1;
1529 if (!(cd->GetClassInfo() && cb->GetClassInfo())) { // gInterpreter requirement
1530 // would like to warn, but can't quite determine error from intentional
1531 // hiding by developers, so only cover the case where we really should have
1532 // had a class info, but apparently don't:
1533 if (cd->IsLoaded()) {
1534 // warn to allow diagnostics
1535 std::ostringstream msg;
1536 msg << "failed offset calculation between " << cb->GetName() << " and " << cd->GetName();
1537 // TODO: propagate this warning to caller w/o use of Python C-API
1538 // PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(msg.str().c_str()));
1539 std::cerr << "Warning: " << msg.str() << '\n';
1540 }
1541
1542 // return -1 to signal caller NOT to apply offset
1543 return rerror ? (ptrdiff_t)offset : 0;
1544 }
1545
1546 offset = gInterpreter->ClassInfo_GetBaseOffset(
1547 cd->GetClassInfo(), cb->GetClassInfo(), (void*)address, direction > 0);
1548 if (offset == -1) // Cling error, treat silently
1549 return rerror ? (ptrdiff_t)offset : 0;
1550
1551 return (ptrdiff_t)(direction < 0 ? -offset : offset);
1552}
1553
1554
1555// method/function reflection information ------------------------------------
1557{
1559 return (TCppIndex_t)0; // enforce lazy
1560
1561 if (scope == GLOBAL_HANDLE)
1562 return gROOT->GetListOfGlobalFunctions(true)->GetSize();
1563
1565 if (cr.GetClass() && cr->GetListOfMethods(true)) {
1566 Cppyy::TCppIndex_t nMethods = (TCppIndex_t)cr->GetListOfMethods(false)->GetSize();
1567 if (nMethods == (TCppIndex_t)0) {
1568 std::string clName = GetScopedFinalName(scope);
1569 if (clName.find('<') != std::string::npos) {
1570 // chicken-and-egg problem: TClass does not know about methods until
1571 // instantiation, so force it
1572 std::ostringstream stmt;
1573 stmt << "template class " << clName << ";";
1574 gInterpreter->Declare(stmt.str().c_str()/*, silent = true*/);
1575
1576 // now reload the methods
1577 return (TCppIndex_t)cr->GetListOfMethods(true)->GetSize();
1578 }
1579 }
1580 return nMethods;
1581 }
1582
1583 return (TCppIndex_t)0; // unknown class?
1584}
1585
1586std::vector<Cppyy::TCppIndex_t> Cppyy::GetMethodIndicesFromName(
1587 TCppScope_t scope, const std::string& name)
1588{
1589 std::vector<TCppIndex_t> indices;
1591 if (cr.GetClass()) {
1592 gInterpreter->UpdateListOfMethods(cr.GetClass());
1593 int imeth = 0;
1594 TFunction* func = nullptr;
1595 TIter next(cr->GetListOfMethods());
1596 while ((func = (TFunction*)next())) {
1597 if (match_name(name, func->GetName())) {
1598 if (func->Property() & kIsPublic)
1599 indices.push_back((TCppIndex_t)imeth);
1600 }
1601 ++imeth;
1602 }
1603 } else if (scope == GLOBAL_HANDLE) {
1604 TCollection* funcs = gROOT->GetListOfGlobalFunctions(true);
1605
1606 // tickle deserialization
1607 if (!funcs->FindObject(name.c_str()))
1608 return indices;
1609
1610 TFunction* func = nullptr;
1611 TIter ifunc(funcs);
1612 while ((func = (TFunction*)ifunc.Next())) {
1613 if (match_name(name, func->GetName()))
1614 indices.push_back((TCppIndex_t)new_CallWrapper(func));
1615 }
1616 }
1617
1618 return indices;
1619}
1620
1622{
1624 if (cr.GetClass()) {
1625 TFunction* f = (TFunction*)cr->GetListOfMethods(false)->At((int)idx);
1626 if (f) return (Cppyy::TCppMethod_t)new_CallWrapper(f);
1627 return (Cppyy::TCppMethod_t)nullptr;
1628 }
1629
1631 return (Cppyy::TCppMethod_t)idx;
1632}
1633
1635{
1636 if (method) {
1637 const std::string& name = ((CallWrapper*)method)->fName;
1638
1639 if (name.compare(0, 8, "operator") != 0)
1640 // strip template instantiation part, if any
1641 return name.substr(0, name.find('<'));
1642 return name;
1643 }
1644 return "<unknown>";
1645}
1646
1648{
1649 if (method) {
1650 std::string name = ((CallWrapper*)method)->fName;
1651 name.erase(std::remove(name.begin(), name.end(), ' '), name.end());
1652 return name;
1653 }
1654 return "<unknown>";
1655}
1656
1658{
1659 if (method)
1660 return m2f(method)->GetMangledName();
1661 return "<unknown>";
1662}
1663
1665{
1666 if (method) {
1667 TFunction* f = m2f(method);
1668 if (f->ExtraProperty() & kIsConstructor)
1669 return "constructor";
1670 std::string restype = f->GetReturnTypeName();
1671 // TODO: this is ugly, but we can't use GetReturnTypeName() for ostreams
1672 // and maybe others, whereas GetReturnTypeNormalizedName() has proven to
1673 // be save in all cases (Note: 'int8_t' covers 'int8_t' and 'uint8_t')
1674 if (restype.find("int8_t") != std::string::npos)
1675 return restype;
1676 restype = f->GetReturnTypeNormalizedName();
1677 if (restype == "(lambda)") {
1678 std::ostringstream s;
1679 // TODO: what if there are parameters to the lambda?
1680 s << "__cling_internal::FT<decltype("
1681 << GetMethodFullName(method) << "(";
1682 for (Cppyy::TCppIndex_t i = 0; i < Cppyy::GetMethodNumArgs(method); ++i) {
1683 if (i != 0) s << ", ";
1684 s << Cppyy::GetMethodArgType(method, i) << "{}";
1685 }
1686 s << "))>::F";
1687 TClass* cl = TClass::GetClass(s.str().c_str());
1688 if (cl) return cl->GetName();
1689 // TODO: signal some type of error (or should that be upstream?
1690 }
1691 return restype;
1692 }
1693 return "<unknown>";
1694}
1695
1697{
1698 if (method)
1699 return m2f(method)->GetNargs();
1700 return 0;
1701}
1702
1704{
1705 if (method) {
1706 TFunction* f = m2f(method);
1707 return (TCppIndex_t)(f->GetNargs() - f->GetNargsOpt());
1708 }
1709 return (TCppIndex_t)0;
1710}
1711
1713{
1714 if (method) {
1715 TFunction* f = m2f(method);
1716 TMethodArg* arg = (TMethodArg*)f->GetListOfMethodArgs()->At((int)iarg);
1717 return arg->GetName();
1718 }
1719 return "<unknown>";
1720}
1721
1723{
1724 if (method) {
1725 TFunction* f = m2f(method);
1726 TMethodArg* arg = (TMethodArg*)f->GetListOfMethodArgs()->At((int)iarg);
1727 return arg->GetTypeNormalizedName();
1728 }
1729 return "<unknown>";
1730}
1731
1733{
1734 if (method) {
1735 TFunction* f = m2f(method);
1736 TMethodArg* arg = (TMethodArg *)f->GetListOfMethodArgs()->At((int)iarg);
1737 void *argqtp = gInterpreter->TypeInfo_QualTypePtr(arg->GetTypeInfo());
1738
1739 TypeInfo_t *reqti = gInterpreter->TypeInfo_Factory(req_type.c_str());
1740 void *reqqtp = gInterpreter->TypeInfo_QualTypePtr(reqti);
1741
1742 // This scoring is not based on any particular rules
1743 if (gInterpreter->IsSameType(argqtp, reqqtp))
1744 return 0; // Best match
1745 else if ((gInterpreter->IsSignedIntegerType(argqtp) && gInterpreter->IsSignedIntegerType(reqqtp)) ||
1746 (gInterpreter->IsUnsignedIntegerType(argqtp) && gInterpreter->IsUnsignedIntegerType(reqqtp)) ||
1747 (gInterpreter->IsFloatingType(argqtp) && gInterpreter->IsFloatingType(reqqtp)))
1748 return 1;
1749 else if ((gInterpreter->IsSignedIntegerType(argqtp) && gInterpreter->IsUnsignedIntegerType(reqqtp)) ||
1750 (gInterpreter->IsFloatingType(argqtp) && gInterpreter->IsUnsignedIntegerType(reqqtp)))
1751 return 2;
1752 else if ((gInterpreter->IsIntegerType(argqtp) && gInterpreter->IsIntegerType(reqqtp)))
1753 return 3;
1754 else if ((gInterpreter->IsVoidPointerType(argqtp) && gInterpreter->IsPointerType(reqqtp)))
1755 return 4;
1756 else
1757 return 10; // Penalize heavily for no possible match
1758 }
1759 return INT_MAX; // Method is not valid
1760}
1761
1763{
1764 if (method) {
1765 TFunction* f = m2f(method);
1766 TMethodArg* arg = (TMethodArg*)f->GetListOfMethodArgs()->At((int)iarg);
1767 const char* def = arg->GetDefault();
1768 if (def)
1769 return def;
1770 }
1771
1772 return "";
1773}
1774
1776{
1777 TFunction* f = m2f(method);
1778 if (f) {
1779 std::ostringstream sig;
1780 sig << "(";
1781 int nArgs = f->GetNargs();
1782 if (maxargs != (TCppIndex_t)-1) nArgs = std::min(nArgs, (int)maxargs);
1783 for (int iarg = 0; iarg < nArgs; ++iarg) {
1784 TMethodArg* arg = (TMethodArg*)f->GetListOfMethodArgs()->At(iarg);
1785 sig << arg->GetFullTypeName();
1786 if (show_formalargs) {
1787 const char* argname = arg->GetName();
1788 if (argname && argname[0] != '\0') sig << " " << argname;
1789 const char* defvalue = arg->GetDefault();
1790 if (defvalue && defvalue[0] != '\0') sig << " = " << defvalue;
1791 }
1792 if (iarg != nArgs-1) sig << (show_formalargs ? ", " : ",");
1793 }
1794 sig << ")";
1795 return sig.str();
1796 }
1797 return "<unknown>";
1798}
1799
1801{
1802 std::string scName = GetScopedFinalName(scope);
1803 TFunction* f = m2f(method);
1804 if (f) {
1805 std::ostringstream sig;
1806 sig << f->GetReturnTypeName() << " "
1807 << scName << "::" << f->GetName();
1809 return sig.str();
1810 }
1811 return "<unknown>";
1812}
1813
1815{
1816 if (method) {
1817 TFunction* f = m2f(method);
1818 return f->Property() & kIsConstMethod;
1819 }
1820 return false;
1821}
1822
1824{
1826 return (TCppIndex_t)0; // enforce lazy
1827
1828 if (scope == GLOBAL_HANDLE) {
1829 TCollection* coll = gROOT->GetListOfFunctionTemplates();
1830 if (coll) return (TCppIndex_t)coll->GetSize();
1831 } else {
1833 if (cr.GetClass()) {
1834 TCollection* coll = cr->GetListOfFunctionTemplates(true);
1835 if (coll) return (TCppIndex_t)coll->GetSize();
1836 }
1837 }
1838
1839// failure ...
1840 return (TCppIndex_t)0;
1841}
1842
1844{
1846 return ((THashList*)gROOT->GetListOfFunctionTemplates())->At((int)imeth)->GetName();
1847 else {
1849 if (cr.GetClass())
1850 return cr->GetListOfFunctionTemplates(false)->At((int)imeth)->GetName();
1851 }
1852
1853// failure ...
1854 assert(!"should not be called unless GetNumTemplatedMethods() succeeded");
1855 return "";
1856}
1857
1859{
1861 return false;
1862
1864 if (cr.GetClass()) {
1865 TFunctionTemplate* f = (TFunctionTemplate*)cr->GetListOfFunctionTemplates(false)->At((int)imeth);
1866 return f->ExtraProperty() & kIsConstructor;
1867 }
1868
1869 return false;
1870}
1871
1873{
1875 return (bool)gROOT->GetFunctionTemplate(name.c_str());
1876 else {
1878 if (cr.GetClass())
1879 return (bool)cr->GetFunctionTemplate(name.c_str());
1880 }
1881
1882// failure ...
1883 return false;
1884}
1885
1887{
1889 if (cr.GetClass()) {
1890 TFunction* f = (TFunction*)cr->GetListOfMethods(false)->At((int)idx);
1891 if (f && strstr(f->GetName(), "<")) return true;
1892 return false;
1893 }
1894
1896 if (((CallWrapper*)idx)->fName.find('<') != std::string::npos) return true;
1897 return false;
1898}
1899
1900// helpers for Cppyy::GetMethodTemplate()
1901static std::map<TDictionary::DeclId_t, CallWrapper*> gMethodTemplates;
1902
1904 TCppScope_t scope, const std::string& name, const std::string& proto)
1905{
1906// There is currently no clean way of extracting a templated method out of ROOT/meta
1907// for a variety of reasons, none of them fundamental. The game played below is to
1908// first get any pre-existing functions already managed by ROOT/meta, but if that fails,
1909// to do an explicit lookup that ignores the prototype (i.e. the full name should be
1910// enough), and finally to ignore the template arguments part of the name as this fails
1911// in cling if there are default parameters.
1912// It would be possible to get the prototype from the created functions and use that to
1913// do a new lookup, after which ROOT/meta will manage the function. However, neither
1914// TFunction::GetPrototype() nor TFunction::GetSignature() is of the proper form, so
1915// we'll/ manage the new TFunctions instead and will assume that they are cached on the
1916// calling side to prevent multiple creations.
1917 TFunction* func = nullptr; ClassInfo_t* cl = nullptr;
1919 func = gROOT->GetGlobalFunctionWithPrototype(name.c_str(), proto.c_str());
1920 if (func && name.back() == '>' && name != func->GetName())
1921 func = nullptr; // happens if implicit conversion matches the overload
1922 } else {
1924 if (cr.GetClass()) {
1925 func = cr->GetMethodWithPrototype(name.c_str(), proto.c_str());
1926 if (!func) {
1927 cl = cr->GetClassInfo();
1928 // try base classes to cover a common 'using' case (TODO: this is stupid and misses
1929 // out on base classes; fix that with improved access to Cling)
1931 for (TCppIndex_t i = 0; i < nbases; ++i) {
1933 if (base.GetClass()) {
1934 func = base->GetMethodWithPrototype(name.c_str(), proto.c_str());
1935 if (func) break;
1936 }
1937 }
1938 }
1939 }
1940 }
1941
1942 if (!func && name.back() == '>' && (cl || scope == (cppyy_scope_t)GLOBAL_HANDLE)) {
1943 // try again, ignoring proto in case full name is complete template
1944 auto declid = gInterpreter->GetFunction(cl, name.c_str());
1945 if (declid) {
1946 auto existing = gMethodTemplates.find(declid);
1947 if (existing == gMethodTemplates.end()) {
1948 auto cw = new_CallWrapper(declid, name);
1949 existing = gMethodTemplates.insert(std::make_pair(declid, cw)).first;
1950 }
1951 return (TCppMethod_t)existing->second;
1952 }
1953 }
1954
1955 if (func) {
1956 // make sure we didn't match a non-templated overload
1957 if (func->ExtraProperty() & kIsTemplateSpec)
1958 return (TCppMethod_t)new_CallWrapper(func);
1959
1960 // disregard this non-templated method as it will be considered when appropriate
1961 return (TCppMethod_t)nullptr;
1962 }
1963
1964// try again with template arguments removed from name, if applicable
1965 if (name.back() == '>') {
1966 auto pos = name.find('<');
1967 if (pos != std::string::npos) {
1969 if (cppmeth) {
1970 // allow if requested template names match up to the result
1971 const std::string& alt = GetMethodFullName(cppmeth);
1972 if (name.size() < alt.size() && alt.find('<') == pos) {
1973 const std::string& partial = name.substr(pos, name.size()-1-pos);
1974 if (strncmp(partial.c_str(), alt.substr(pos, alt.size()-1-pos).c_str(), partial.size()) == 0)
1975 return cppmeth;
1976 }
1977 }
1978 }
1979 }
1980
1981// failure ...
1982 return (TCppMethod_t)nullptr;
1983}
1984
1985static inline
1986std::string type_remap(const std::string& n1, const std::string& n2)
1987{
1988// Operator lookups of (C++ string, Python str) should succeeded, for the combos of
1989// string/str, wstring/str, string/unicode and wstring/unicode; since C++ does not have a
1990// operator+(std::string, std::wstring), we'll have to look up the same type and rely on
1991// the converters in CPyCppyy/_cppyy.
1992 if (n1 == "str") {
1993 if (n2 == "std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >")
1994 return n2; // match like for like
1995 return "std::string"; // probably best bet
1996 } else if (n1 == "float")
1997 return "double"; // debatable, but probably intended
1998 return n1;
1999}
2000
2002 TCppType_t scope, const std::string& lc, const std::string& rc, const std::string& opname)
2003{
2004// Find a global operator function with a matching signature; prefer by-ref, but
2005// fall back on by-value if that fails.
2006 std::string lcname1 = TClassEdit::CleanType(lc.c_str());
2007 const std::string& rcname = rc.empty() ? rc : type_remap(TClassEdit::CleanType(rc.c_str()), lcname1);
2008 const std::string& lcname = type_remap(lcname1, rcname);
2009
2010 std::string proto = lcname + "&" + (rc.empty() ? rc : (", " + rcname + "&"));
2012 TFunction* func = gROOT->GetGlobalFunctionWithPrototype(opname.c_str(), proto.c_str());
2013 if (func) return (TCppIndex_t)new_CallWrapper(func);
2014 proto = lcname + (rc.empty() ? rc : (", " + rcname));
2015 func = gROOT->GetGlobalFunctionWithPrototype(opname.c_str(), proto.c_str());
2016 if (func) return (TCppIndex_t)new_CallWrapper(func);
2017 } else {
2019 if (cr.GetClass()) {
2020 TFunction* func = cr->GetMethodWithPrototype(opname.c_str(), proto.c_str());
2021 if (func) return (TCppIndex_t)cr->GetListOfMethods()->IndexOf(func);
2022 proto = lcname + (rc.empty() ? rc : (", " + rcname));
2023 func = cr->GetMethodWithPrototype(opname.c_str(), proto.c_str());
2024 if (func) return (TCppIndex_t)cr->GetListOfMethods()->IndexOf(func);
2025 }
2026 }
2027
2028// failure ...
2029 return (TCppIndex_t)-1;
2030}
2031
2032// method properties ---------------------------------------------------------
2034{
2035 if (method) {
2036 TFunction* f = m2f(method);
2037 return f->Property() & kIsPublic;
2038 }
2039 return false;
2040}
2041
2043{
2044 if (method) {
2045 TFunction* f = m2f(method);
2046 return f->Property() & kIsProtected;
2047 }
2048 return false;
2049}
2050
2052{
2053 if (method) {
2054 TFunction* f = m2f(method);
2055 return f->ExtraProperty() & kIsConstructor;
2056 }
2057 return false;
2058}
2059
2061{
2062 if (method) {
2063 TFunction* f = m2f(method);
2064 return f->ExtraProperty() & kIsDestructor;
2065 }
2066 return false;
2067}
2068
2070{
2071 if (method) {
2072 TFunction* f = m2f(method);
2073 return f->Property() & kIsStatic;
2074 }
2075 return false;
2076}
2077
2078// data member reflection information ----------------------------------------
2080{
2082 return (TCppIndex_t)0; // enforce lazy
2083
2084 if (scope == GLOBAL_HANDLE)
2085 return gROOT->GetListOfGlobals(true)->GetSize();
2086
2088 if (cr.GetClass() && cr->GetListOfDataMembers())
2089 return cr->GetListOfDataMembers()->GetSize();
2090
2091 return (TCppIndex_t)0; // unknown class?
2092}
2093
2095{
2096 if (!cr.GetClass() || !cr->GetListOfDataMembers())
2097 return nullptr;
2098
2099 int numDMs = cr->GetListOfDataMembers()->GetSize();
2100 if ((int)idata < numDMs)
2101 return (TDataMember*)cr->GetListOfDataMembers()->At((int)idata);
2102 return (TDataMember*)cr->GetListOfUsingDataMembers()->At((int)idata - numDMs);
2103}
2104
2106{
2108 if (cr.GetClass()) {
2110 return m->GetName();
2111 }
2114 return gbl->GetName();
2115}
2116
2118{
2119 if (scope == GLOBAL_HANDLE) {
2121 std::string fullType = gbl->GetFullTypeName();
2122
2123 if ((int)gbl->GetArrayDim()) {
2124 std::ostringstream s;
2125 for (int i = 0; i < (int)gbl->GetArrayDim(); ++i)
2126 s << '[' << gbl->GetMaxIndex(i) << ']';
2127 fullType.append(s.str());
2128 }
2129 return fullType;
2130 }
2131
2133 if (cr.GetClass()) {
2135 // TODO: fix this upstream. Usually, we want m->GetFullTypeName(), because it does
2136 // not resolve typedefs, but it looses scopes for inner classes/structs, so in that
2137 // case m->GetTrueTypeName() should be used (this also cleans up the cases where
2138 // the "full type" retains spurious "struct" or "union" in the name).
2139 std::string fullType = m->GetFullTypeName();
2140 if (fullType != m->GetTrueTypeName()) {
2141 const std::string& trueName = m->GetTrueTypeName();
2142 if (fullType.find("::") == std::string::npos && trueName.find("::") != std::string::npos)
2144 }
2145
2146 if ((int)m->GetArrayDim()) {
2147 std::ostringstream s;
2148 for (int i = 0; i < (int)m->GetArrayDim(); ++i)
2149 s << '[' << m->GetMaxIndex(i) << ']';
2150 fullType.append(s.str());
2151 }
2152 return fullType;
2153 }
2154
2155 return "<unknown>";
2156}
2157
2159{
2160 if (scope == GLOBAL_HANDLE) {
2162 if (!gbl->GetAddress() || gbl->GetAddress() == (void*)-1) {
2163 // CLING WORKAROUND: make sure variable is loaded
2164 intptr_t addr = (intptr_t)gInterpreter->ProcessLine((std::string("&")+gbl->GetName()+";").c_str());
2165 if (gbl->GetAddress() && gbl->GetAddress() != (void*)-1)
2166 return (intptr_t)gbl->GetAddress(); // now loaded!
2167 return addr; // last resort ...
2168 }
2169 return (intptr_t)gbl->GetAddress();
2170 }
2171
2173 if (cr.GetClass()) {
2175 // CLING WORKAROUND: the following causes templates to be instantiated first within the proper
2176 // scope, making the lookup succeed and preventing spurious duplicate instantiations later. Also,
2177 // if the variable is not yet loaded, pull it in through gInterpreter.
2178 if (m->Property() & kIsStatic) {
2179 if (strchr(cr->GetName(), '<'))
2180 gInterpreter->ProcessLine(((std::string)cr->GetName()+"::"+m->GetName()+";").c_str());
2181 if ((intptr_t)m->GetOffsetCint() == (intptr_t)-1)
2182 return (intptr_t)gInterpreter->ProcessLine((std::string("&")+cr->GetName()+"::"+m->GetName()+";").c_str());
2183 }
2184 return (intptr_t)m->GetOffsetCint(); // yes, CINT (GetOffset() is both wrong
2185 // and caches that wrong result!
2186 }
2187
2188 return (intptr_t)-1;
2189}
2190
2192{
2193 if (scope == GLOBAL_HANDLE) {
2194 TGlobal* gb = (TGlobal*)gROOT->GetListOfGlobals(false /* load */)->FindObject(name.c_str());
2195 if (!gb) gb = (TGlobal*)gROOT->GetListOfGlobals(true /* load */)->FindObject(name.c_str());
2196 if (!gb) {
2197 // some enums are not loaded as they are not considered part of
2198 // the global scope, but of the enum scope; get them w/o checking
2199 TDictionary::DeclId_t did = gInterpreter->GetDataMember(nullptr, name.c_str());
2200 if (did) {
2201 DataMemberInfo_t* t = gInterpreter->DataMemberInfo_Factory(did, nullptr);
2202 ((TListOfDataMembers*)gROOT->GetListOfGlobals())->Get(t, true);
2203 gb = (TGlobal*)gROOT->GetListOfGlobals(false /* load */)->FindObject(name.c_str());
2204 }
2205 }
2206
2207 if (gb && strcmp(gb->GetFullTypeName(), "(lambda)") == 0) {
2208 // lambdas use a compiler internal closure type, so we wrap
2209 // them, then return the wrapper's type
2210 // TODO: this current leaks the std::function; also, if possible,
2211 // should instantiate through TClass rather then ProcessLine
2212 std::ostringstream s;
2213 s << "auto __cppyy_internal_wrap_" << name << " = "
2214 "new __cling_internal::FT<decltype(" << name << ")>::F"
2215 "{" << name << "};";
2216 gInterpreter->ProcessLine(s.str().c_str());
2217 TGlobal* wrap = (TGlobal*)gROOT->GetListOfGlobals(true)->FindObject(
2218 ("__cppyy_internal_wrap_"+name).c_str());
2219 if (wrap && wrap->GetAddress()) gb = wrap;
2220 }
2221
2222 if (gb) {
2223 // TODO: do we ever need a reverse lookup?
2224 g_globalvars.push_back(gb);
2225 return TCppIndex_t(g_globalvars.size() - 1);
2226 }
2227
2228 } else {
2230 if (cr.GetClass()) {
2231 TDataMember* dm =
2232 (TDataMember*)cr->GetListOfDataMembers()->FindObject(name.c_str());
2233 // TODO: turning this into an index is silly ...
2234 if (dm) return (TCppIndex_t)cr->GetListOfDataMembers()->IndexOf(dm);
2235 dm = (TDataMember*)cr->GetListOfUsingDataMembers()->FindObject(name.c_str());
2236 if (dm)
2237 return (TCppIndex_t)cr->GetListOfDataMembers()->IndexOf(dm)
2238 + cr->GetListOfDataMembers()->GetSize();
2239 }
2240 }
2241
2242 return (TCppIndex_t)-1;
2243}
2244
2245
2246// data member properties ----------------------------------------------------
2248{
2249 if (scope == GLOBAL_HANDLE)
2250 return true;
2252 if (cr->Property() & kIsNamespace)
2253 return true;
2255 return m->Property() & kIsPublic;
2256}
2257
2259{
2260 if (scope == GLOBAL_HANDLE)
2261 return true;
2263 if (cr->Property() & kIsNamespace)
2264 return true;
2266 return m->Property() & kIsProtected;
2267}
2268
2270{
2271 if (scope == GLOBAL_HANDLE)
2272 return true;
2274 if (cr->Property() & kIsNamespace)
2275 return true;
2277 return m->Property() & kIsStatic;
2278}
2279
2281{
2282 if (scope == GLOBAL_HANDLE) {
2284 return gbl->Property() & kIsConstant;
2285 }
2287 if (cr.GetClass()) {
2289 return m->Property() & kIsConstant;
2290 }
2291 return false;
2292}
2293
2295{
2296// TODO: currently, ROOT/meta does not properly distinguish between variables of enum
2297// type, and values of enums. The latter are supposed to be const. This code relies on
2298// odd features (bugs?) to figure out the difference, but this should really be fixed
2299// upstream and/or deserves a new API.
2300
2301 if (scope == GLOBAL_HANDLE) {
2303
2304 // make use of an oddity: enum global variables do not have their kIsStatic bit
2305 // set, whereas enum global values do
2306 return (gbl->Property() & kIsEnum) && (gbl->Property() & kIsStatic);
2307 }
2308
2310 if (cr.GetClass()) {
2312 std::string ti = m->GetTypeName();
2313
2314 // can't check anonymous enums by type name, so just accept them as enums
2315 if (ti.rfind("(unnamed)") != std::string::npos)
2316 return m->Property() & kIsEnum;
2317
2318 // since there seems to be no distinction between data of enum type and enum values,
2319 // check the list of constants for the type to see if there's a match
2320 if (ti.rfind(cr->GetName(), 0) != std::string::npos) {
2321 std::string::size_type s = strlen(cr->GetName())+2;
2322 if (s < ti.size()) {
2323 TEnum* ee = ((TListOfEnums*)cr->GetListOfEnums())->GetObject(ti.substr(s, std::string::npos).c_str());
2324 if (ee) return ee->GetConstant(m->GetName());
2325 }
2326 }
2327 }
2328
2329// this default return only means that the data will be writable, not that it will
2330// be unreadable or otherwise misrepresented
2331 return false;
2332}
2333
2335{
2336 if (scope == GLOBAL_HANDLE) {
2338 return gbl->GetMaxIndex(dimension);
2339 }
2341 if (cr.GetClass()) {
2343 return m->GetMaxIndex(dimension);
2344 }
2345 return -1;
2346}
2347
2348
2349// enum properties -----------------------------------------------------------
2351{
2352 if (scope == GLOBAL_HANDLE)
2353 return (TCppEnum_t)gROOT->GetListOfEnums(kTRUE)->FindObject(enum_name.c_str());
2354
2356 if (cr.GetClass())
2357 return (TCppEnum_t)cr->GetListOfEnums(kTRUE)->FindObject(enum_name.c_str());
2358
2359 return (TCppEnum_t)0;
2360}
2361
2363{
2364 return (TCppIndex_t)((TEnum*)etype)->GetConstants()->GetSize();
2365}
2366
2368{
2369 return ((TEnumConstant*)((TEnum*)etype)->GetConstants()->At(idata))->GetName();
2370}
2371
2373{
2374 TEnumConstant* ecst = (TEnumConstant*)((TEnum*)etype)->GetConstants()->At(idata);
2375 return (long long)ecst->GetValue();
2376}
2377
2378
2379//- C-linkage wrappers -------------------------------------------------------
2380
2381extern "C" {
2382/* direct interpreter access ---------------------------------------------- */
2383int cppyy_compile(const char* code) {
2384 return Cppyy::Compile(code);
2385}
2386
2387
2388/* name to opaque C++ scope representation -------------------------------- */
2392
2396
2400
2404
2408
2409size_t cppyy_size_of_type(const char* type_name) {
2410 return Cppyy::SizeOf(type_name);
2411}
2412
2413
2414/* memory management ------------------------------------------------------ */
2418
2422
2426
2430
2431
2432/* method/function dispatching -------------------------------------------- */
2433/* Exception types:
2434 1: default (unknown exception)
2435 2: standard exception
2436*/
2437#define CPPYY_HANDLE_EXCEPTION \
2438 catch (std::exception& e) { \
2439 cppyy_exctype_t* etype = (cppyy_exctype_t*)((Parameter*)args+nargs); \
2440 *etype = (cppyy_exctype_t)2; \
2441 *((char**)(etype+1)) = cppstring_to_cstring(e.what()); \
2442 } \
2443 catch (...) { \
2444 cppyy_exctype_t* etype = (cppyy_exctype_t*)((Parameter*)args+nargs); \
2445 *etype = (cppyy_exctype_t)1; \
2446 *((char**)(etype+1)) = \
2447 cppstring_to_cstring("unhandled, unknown C++ exception"); \
2448 }
2449
2451 try {
2452 Cppyy::CallV(method, (void*)self, nargs, args);
2454}
2455
2456unsigned char cppyy_call_b(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) {
2457 try {
2458 return (unsigned char)Cppyy::CallB(method, (void*)self, nargs, args);
2460 return (unsigned char)-1;
2461}
2462
2464 try {
2465 return (char)Cppyy::CallC(method, (void*)self, nargs, args);
2467 return (char)-1;
2468}
2469
2471 try {
2472 return (short)Cppyy::CallH(method, (void*)self, nargs, args);
2474 return (short)-1;
2475}
2476
2478 try {
2479 return (int)Cppyy::CallI(method, (void*)self, nargs, args);
2481 return (int)-1;
2482}
2483
2485 try {
2486 return (long)Cppyy::CallL(method, (void*)self, nargs, args);
2488 return (long)-1;
2489}
2490
2492 try {
2493 return (long long)Cppyy::CallLL(method, (void*)self, nargs, args);
2495 return (long long)-1;
2496}
2497
2499 try {
2500 return (float)Cppyy::CallF(method, (void*)self, nargs, args);
2502 return (float)-1;
2503}
2504
2506 try {
2507 return (double)Cppyy::CallD(method, (void*)self, nargs, args);
2509 return (double)-1;
2510}
2511
2513 try {
2514 return (long double)Cppyy::CallLD(method, (void*)self, nargs, args);
2516 return (long double)-1;
2517}
2518
2520 return (double)cppyy_call_ld(method, self, nargs, args);
2521}
2522
2524 try {
2525 return (void*)Cppyy::CallR(method, (void*)self, nargs, args);
2527 return (void*)nullptr;
2528}
2529
2531 cppyy_method_t method, cppyy_object_t self, int nargs, void* args, size_t* lsz) {
2532 try {
2533 return Cppyy::CallS(method, (void*)self, nargs, args, lsz);
2535 return (char*)nullptr;
2536}
2537
2545
2549
2551 int nargs, void* args, cppyy_type_t result_type) {
2552 try {
2553 return cppyy_object_t(Cppyy::CallO(method, (void*)self, nargs, args, result_type));
2555 return (cppyy_object_t)0;
2556}
2557
2561
2562
2563/* handling of function argument buffer ----------------------------------- */
2565// for calls through C interface, require extra space for reporting exceptions
2566 return malloc(nargs*sizeof(Parameter)+sizeof(cppyy_exctype_t)+sizeof(char**));
2567}
2568
2570 free(args);
2571}
2572
2574 return (size_t)Cppyy::GetFunctionArgSizeof();
2575}
2576
2580
2581
2582/* scope reflection information ------------------------------------------- */
2586
2588 return (int)Cppyy::IsTemplate(template_name);
2589}
2590
2594
2595int cppyy_is_enum(const char* type_name) {
2596 return (int)Cppyy::IsEnum(type_name);
2597}
2598
2602
2603const char** cppyy_get_all_cpp_names(cppyy_scope_t scope, size_t* count) {
2604 std::set<std::string> cppnames;
2606 const char** c_cppnames = (const char**)malloc(cppnames.size()*sizeof(const char*));
2607 int i = 0;
2608 for (const auto& name : cppnames) {
2610 ++i;
2611 }
2612 *count = cppnames.size();
2613 return c_cppnames;
2614}
2615
2616
2617/* namespace reflection information --------------------------------------- */
2619 const std::vector<Cppyy::TCppScope_t>& uv = Cppyy::GetUsingNamespaces((Cppyy::TCppScope_t)scope);
2620
2621 if (uv.empty())
2622 return (cppyy_index_t*)nullptr;
2623
2624 cppyy_scope_t* llresult = (cppyy_scope_t*)malloc(sizeof(cppyy_scope_t)*(uv.size()+1));
2625 for (int i = 0; i < (int)uv.size(); ++i) llresult[i] = uv[i];
2626 llresult[uv.size()] = (cppyy_scope_t)0;
2627 return llresult;
2628}
2629
2630
2631/* class reflection information ------------------------------------------- */
2635
2639
2643
2647
2651
2655
2659
2661 return (int)Cppyy::IsSubtype(derived, base);
2662}
2663
2667
2669 return (int)Cppyy::GetSmartPtrInfo(name, raw, deref);
2670}
2671
2675
2676
2677/* calculate offsets between declared and actual type, up-cast: direction > 0; down-cast: direction < 0 */
2679 return (ptrdiff_t)Cppyy::GetBaseOffset(derived, base, (void*)address, direction, 0);
2680}
2681
2682
2683/* method/function reflection information --------------------------------- */
2687
2689{
2690 std::vector<cppyy_index_t> result = Cppyy::GetMethodIndicesFromName(scope, name);
2691
2692 if (result.empty())
2693 return (cppyy_index_t*)nullptr;
2694
2696 for (int i = 0; i < (int)result.size(); ++i) llresult[i] = result[i];
2697 llresult[result.size()] = -1;
2698 return llresult;
2699}
2700
2704
2708
2712
2716
2720
2724
2728
2732
2736
2740
2744
2748
2753
2757
2761
2765
2769
2773
2777
2781
2785
2786
2787/* method properties ------------------------------------------------------ */
2791
2795
2799
2803
2807
2808
2809/* data member reflection information ------------------------------------- */
2813
2817
2821
2825
2829
2830
2831
2832/* data member properties ------------------------------------------------- */
2836
2840
2844
2848
2852
2856
2857
2858/* misc helpers ----------------------------------------------------------- */
2861 int result = gSystem->Load(lib_name);
2862 return (void*)(result == 0 /* success */ || result == 1 /* already loaded */);
2863}
2864
2865#if defined(_MSC_VER)
2866long long cppyy_strtoll(const char* str) {
2867 return _strtoi64(str, NULL, 0);
2868}
2869
2870extern "C" {
2871unsigned long long cppyy_strtoull(const char* str) {
2872 return _strtoui64(str, NULL, 0);
2873}
2874}
2875#else
2876long long cppyy_strtoll(const char* str) {
2877 return strtoll(str, NULL, 0);
2878}
2879
2880extern "C" {
2881unsigned long long cppyy_strtoull(const char* str) {
2882 return strtoull(str, NULL, 0);
2883}
2884}
2885#endif
2886
2887void cppyy_free(void* ptr) {
2888 free(ptr);
2889}
2890
2891cppyy_object_t cppyy_charp2stdstring(const char* str, size_t sz) {
2892 return (cppyy_object_t)new std::string(str, sz);
2893}
2894
2895const char* cppyy_stdstring2charp(cppyy_object_t ptr, size_t* lsz) {
2896 *lsz = ((std::string*)ptr)->size();
2897 return ((std::string*)ptr)->data();
2898}
2899
2901 return (cppyy_object_t)new std::string(*(std::string*)ptr);
2902}
2903
2905 return (double)*(long double*)p;
2906}
2907
2908void cppyy_double2longdouble(double d, void* p) {
2909 *(long double*)p = d;
2910}
2911
2913 return (int)(*(std::vector<bool>*)ptr)[idx];
2914}
2915
2917 (*(std::vector<bool>*)ptr)[idx] = (bool)value;
2918}
2919
2920} // end C-linkage wrappers
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
static Roo_reg_AGKInteg1D instance
int Int_t
Definition RtypesCore.h:45
long double LongDouble_t
Definition RtypesCore.h:61
long long Long64_t
Definition RtypesCore.h:69
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
@ kMAXSIGNALS
Definition Rtypes.h:59
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
@ kIsDestructor
@ kIsTemplateSpec
@ kIsConstructor
@ kClassIsAggregate
@ kClassHasExplicitDtor
@ kClassHasImplicitDtor
@ kIsPublic
Definition TDictionary.h:75
@ kIsConstant
Definition TDictionary.h:88
@ kIsConstMethod
Definition TDictionary.h:96
@ kIsEnum
Definition TDictionary.h:68
@ kIsPrivate
Definition TDictionary.h:77
@ kIsFundamental
Definition TDictionary.h:70
@ kIsAbstract
Definition TDictionary.h:71
@ kIsStatic
Definition TDictionary.h:80
@ kIsProtected
Definition TDictionary.h:76
@ kIsVirtual
Definition TDictionary.h:72
@ kIsNamespace
Definition TDictionary.h:95
@ kIsVirtualBase
Definition TDictionary.h:89
constexpr Int_t kFatal
Definition TError.h:50
Int_t gErrorIgnoreLevel
Error handling routines.
Definition TError.cxx:31
R__EXTERN TExceptionHandler * gExceptionHandler
Definition TException.h:79
R__EXTERN ExceptionContext_t * gException
Definition TException.h:69
R__EXTERN void Throw(int code)
If an exception context has been set (using the TRY and RETRY macros) jump back to where it was set.
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h req_type
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void funcs
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
Definition TGX11.cxx:110
#define gInterpreter
#define gROOT
Definition TROOT.h:406
R__EXTERN TSystem * gSystem
Definition TSystem.h:572
static struct Signalmap_t gSignalMap[kMAXSIGNALS]
size_t cppyy_scope_t
Definition capi.h:12
cppyy_scope_t cppyy_type_t
Definition capi.h:13
intptr_t cppyy_method_t
Definition capi.h:15
size_t cppyy_index_t
Definition capi.h:17
void * cppyy_object_t
Definition capi.h:14
unsigned long cppyy_exctype_t
Definition capi.h:20
void * cppyy_funcaddr_t
Definition capi.h:18
const char * proto
Definition civetweb.c:17535
#define free
Definition civetweb.c:1539
#define malloc
Definition civetweb.c:1536
const_iterator end() const
Each class (see TClass) has a linked list of its base class(es).
Definition TBaseClass.h:33
Long_t Property() const override
Get property description word. For meaning of bits see EProperty.
TClassRef is used to implement a permanent reference to a TClass object.
Definition TClassRef.h:29
TClass * GetClass() const
Definition TClassRef.h:67
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:84
TList * GetListOfUsingDataMembers(Bool_t load=kTRUE)
Return list containing the TDataMembers of using declarations of a class.
Definition TClass.cxx:3883
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition TClass.cxx:5087
TMethod * GetMethod(const char *method, const char *params, Bool_t objectIsConst=kFALSE)
Find the best method (if there is one) matching the parameters.
Definition TClass.cxx:4508
TMethod * GetMethodWithPrototype(const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
Find the method with a given prototype.
Definition TClass.cxx:4553
void Destructor(void *obj, Bool_t dtorOnly=kFALSE)
Explicitly call destructor for object.
Definition TClass.cxx:5509
TList * GetListOfFunctionTemplates(Bool_t load=kTRUE)
Return TListOfFunctionTemplates for a class.
Definition TClass.cxx:3895
TList * GetListOfEnums(Bool_t load=kTRUE)
Return a list containing the TEnums of a class.
Definition TClass.cxx:3783
TList * GetListOfMethods(Bool_t load=kTRUE)
Return list containing the TMethods of a class.
Definition TClass.cxx:3909
TList * GetListOfDataMembers(Bool_t load=kTRUE)
Return list containing the TDataMembers of a class.
Definition TClass.cxx:3867
@ kRealNew
Definition TClass.h:110
TList * GetListOfBases()
Return list containing the TBaseClass(es) of a class.
Definition TClass.cxx:3733
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition TClass.cxx:6021
ClassInfo_t * GetClassInfo() const
Definition TClass.h:440
Long_t ClassProperty() const
Return the C++ property of this class, eg.
Definition TClass.cxx:2497
Long_t Property() const override
Returns the properties of the TClass as a bit field stored as a Long_t value.
Definition TClass.cxx:6195
Bool_t HasDefaultConstructor(Bool_t testio=kFALSE) const
Return true if we have access to a constructor usable for I/O.
Definition TClass.cxx:7543
TMethod * GetMethodAllAny(const char *method)
Return pointer to method without looking at parameters.
Definition TClass.cxx:4481
ROOT::DelFunc_t GetDelete() const
Return the wrapper around delete ThisObject.
Definition TClass.cxx:7613
TClass * GetActualClass(const void *object) const
Return a pointer to the real class of the object.
Definition TClass.cxx:2708
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition TClass.cxx:3069
Collection abstract base class.
Definition TCollection.h:65
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
All ROOT classes may have RTTI (run time type identification) support added.
Definition TDataMember.h:31
Basic data type descriptor (datatype information is obtained from CINT).
Definition TDataType.h:44
Int_t GetType() const
Definition TDataType.h:68
Long_t Property() const override
Get property description word. For meaning of bits see EProperty.
Int_t Size() const
Get size of basic typedef'ed type.
const void * DeclId_t
The TEnumConstant class implements the constants of the enum type.
The TEnum class implements the enum type.
Definition TEnum.h:33
Definition TEnv.h:86
const char * GetValue() const
Definition TEnv.h:110
const char * GetName() const override
Returns name of object.
Definition TEnv.h:109
Dictionary for function template This class describes one single function template.
Global functions class (global functions are obtained from CINT).
Definition TFunction.h:30
Long_t Property() const override
Get property description word. For meaning of bits see EProperty.
Long_t ExtraProperty() const
Get property description word. For meaning of bits see EProperty.
std::string GetReturnTypeNormalizedName() const
Get the normalized name of the return type.
Global variables class (global variables are obtained from CINT).
Definition TGlobal.h:28
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition THashList.h:34
A collection of TDataMember objects designed for fast access given a DeclId_t and for keep track of T...
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:355
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition TMethodArg.h:36
const char * GetFullTypeName() const
Get full type description of method argument, e.g.: "class TDirectory*".
TypeInfo_t * GetTypeInfo() const
Get the TypeInfo of the method argument.
const char * GetDefault() const
Get default value of method argument.
std::string GetTypeNormalizedName() const
Get the normalized name of the return type.
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:456
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:420
static Bool_t Initialized()
Return kTRUE if the TROOT object has been initialized.
Definition TROOT.cxx:2910
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition TSystem.cxx:1857
virtual void Exit(int code, Bool_t mode=kTRUE)
Exit the application.
Definition TSystem.cxx:716
virtual void StackTrace()
Print a stack trace.
Definition TSystem.cxx:734
char * cppyy_method_mangled_name(cppyy_method_t method)
int cppyy_is_staticdata(cppyy_type_t type, cppyy_index_t datamember_index)
int cppyy_vectorbool_getitem(cppyy_object_t ptr, int idx)
int cppyy_has_virtual_destructor(cppyy_type_t type)
int cppyy_is_publicmethod(cppyy_method_t method)
void * cppyy_call_r(cppyy_method_t method, cppyy_object_t self, int nargs, void *args)
cppyy_object_t cppyy_constructor(cppyy_method_t method, cppyy_type_t klass, int nargs, void *args)
void * cppyy_load_dictionary(const char *lib_name)
static void cond_add(Cppyy::TCppScope_t scope, const std::string &ns_scope, std::set< std::string > &cppnames, const char *name, bool nofilter=false)
size_t cppyy_function_arg_typeoffset()
int cppyy_exists_method_template(cppyy_scope_t scope, const char *name)
int cppyy_get_num_templated_methods(cppyy_scope_t scope)
char * cppyy_call_s(cppyy_method_t method, cppyy_object_t self, int nargs, void *args, size_t *lsz)
char * cppyy_resolve_enum(const char *enum_type)
cppyy_object_t cppyy_charp2stdstring(const char *str, size_t sz)
static Name2ClassRefIndex_t g_name2classrefidx
int cppyy_is_constructor(cppyy_method_t method)
int cppyy_is_enum_data(cppyy_scope_t scope, cppyy_index_t idata)
#define FILL_COLL(type, filter)
char * cppyy_scoped_final_name(cppyy_type_t type)
int cppyy_num_bases(cppyy_type_t type)
const int SMALL_ARGS_N
static std::string outer_with_template(const std::string &name)
cppyy_method_t cppyy_get_method_template(cppyy_scope_t scope, const char *name, const char *proto)
static std::string outer_no_template(const std::string &name)
int cppyy_is_smartptr(cppyy_type_t type)
static std::string type_remap(const std::string &n1, const std::string &n2)
static std::map< Cppyy::TCppType_t, bool > sHasOperatorDelete
long long cppyy_strtoll(const char *str)
static std::set< std::string > gRootSOs
int cppyy_is_subtype(cppyy_type_t derived, cppyy_type_t base)
static TClassRef & type_from_handle(Cppyy::TCppScope_t scope)
double cppyy_call_nld(cppyy_method_t method, cppyy_object_t self, int nargs, void *args)
void cppyy_free(void *ptr)
int cppyy_smartptr_info(const char *name, cppyy_type_t *raw, cppyy_method_t *deref)
unsigned long long cppyy_strtoull(const char *str)
char * cppyy_method_arg_type(cppyy_method_t method, int arg_index)
cppyy_object_t cppyy_stdstring2stdstring(cppyy_object_t ptr)
char * cppyy_base_name(cppyy_type_t type, int base_index)
cppyy_scope_t * cppyy_get_using_namespaces(cppyy_scope_t scope)
static bool copy_args(Parameter *args, size_t nargs, void **vargs)
int cppyy_num_bases_longest_branch(cppyy_type_t type)
static TInterpreter::CallFuncIFacePtr_t GetCallFunc(Cppyy::TCppMethod_t method)
int cppyy_is_publicdata(cppyy_type_t type, cppyy_index_t datamember_index)
CPyCppyy::Parameter Parameter
intptr_t cppyy_datamember_offset(cppyy_scope_t scope, int datamember_index)
char * cppyy_datamember_type(cppyy_scope_t scope, int datamember_index)
static bool is_missclassified_stl(const std::string &name)
std::map< std::string, ClassRefs_t::size_type > Name2ClassRefIndex_t
void cppyy_destructor(cppyy_type_t klass, cppyy_object_t self)
static const ClassRefs_t::size_type STD_HANDLE
char cppyy_call_c(cppyy_method_t method, cppyy_object_t self, int nargs, void *args)
ptrdiff_t cppyy_base_offset(cppyy_type_t derived, cppyy_type_t base, cppyy_object_t address, int direction)
long double cppyy_call_ld(cppyy_method_t method, cppyy_object_t self, int nargs, void *args)
int cppyy_is_const_data(cppyy_scope_t scope, cppyy_index_t idata)
const char ** cppyy_get_all_cpp_names(cppyy_scope_t scope, size_t *count)
void cppyy_call_v(cppyy_method_t method, cppyy_object_t self, int nargs, void *args)
static std::set< std::string > gSmartPtrTypes
double cppyy_longdouble2double(void *p)
int cppyy_method_req_args(cppyy_method_t method)
int cppyy_is_staticmethod(cppyy_method_t method)
static GlobalVars_t g_globalvars
cppyy_index_t * cppyy_method_indices_from_name(cppyy_scope_t scope, const char *name)
static char * cppstring_to_cstring(const std::string &cppstr)
char * cppyy_method_signature(cppyy_method_t method, int show_formalargs)
int cppyy_is_abstract(cppyy_type_t type)
static void release_args(Parameter *args, size_t nargs)
int cppyy_call_i(cppyy_method_t method, cppyy_object_t self, int nargs, void *args)
static std::set< std::string > g_builtins
unsigned char cppyy_call_b(cppyy_method_t method, cppyy_object_t self, int nargs, void *args)
int cppyy_is_template(const char *template_name)
char * cppyy_method_result_type(cppyy_method_t method)
cppyy_type_t cppyy_actual_class(cppyy_type_t klass, cppyy_object_t obj)
int cppyy_is_templated_constructor(cppyy_scope_t scope, cppyy_index_t imeth)
char * cppyy_method_name(cppyy_method_t method)
int cppyy_is_protectedmethod(cppyy_method_t method)
char * cppyy_final_name(cppyy_type_t type)
char * cppyy_get_templated_method_name(cppyy_scope_t scope, cppyy_index_t imeth)
char * cppyy_method_full_name(cppyy_method_t method)
long cppyy_call_l(cppyy_method_t method, cppyy_object_t self, int nargs, void *args)
void cppyy_double2longdouble(double d, void *p)
void cppyy_deallocate_function_args(void *args)
int cppyy_method_is_template(cppyy_scope_t scope, cppyy_index_t idx)
static std::vector< CallWrapper * > gWrapperHolder
static bool gEnableFastPath
void cppyy_destruct(cppyy_type_t type, cppyy_object_t self)
int cppyy_is_enum(const char *type_name)
size_t cppyy_size_of_type(const char *type_name)
int cppyy_is_destructor(cppyy_method_t method)
cppyy_object_t cppyy_allocate(cppyy_type_t type)
char * cppyy_datamember_name(cppyy_scope_t scope, int datamember_index)
cppyy_object_t cppyy_construct(cppyy_type_t type)
static ClassRefs_t g_classrefs(1)
static bool WrapperCall(Cppyy::TCppMethod_t method, size_t nargs, void *args_, void *self, void *result)
static std::map< std::string, std::string > resolved_enum_types
int cppyy_is_namespace(cppyy_scope_t scope)
cppyy_object_t cppyy_call_o(cppyy_method_t method, cppyy_object_t self, int nargs, void *args, cppyy_type_t result_type)
long long cppyy_call_ll(cppyy_method_t method, cppyy_object_t self, int nargs, void *args)
cppyy_scope_t cppyy_get_scope(const char *scope_name)
void cppyy_vectorbool_setitem(cppyy_object_t ptr, int idx, int value)
static size_t CALL_NARGS(size_t nargs)
static CallWrapper * new_CallWrapper(TFunction *f)
void cppyy_add_smartptr_type(const char *type_name)
void * cppyy_allocate_function_args(int nargs)
float cppyy_call_f(cppyy_method_t method, cppyy_object_t self, int nargs, void *args)
short cppyy_call_h(cppyy_method_t method, cppyy_object_t self, int nargs, void *args)
int cppyy_is_protecteddata(cppyy_type_t type, cppyy_index_t datamember_index)
static std::set< std::string > gSTLNames
static const ClassRefs_t::size_type GLOBAL_HANDLE
int cppyy_get_dimension_size(cppyy_scope_t scope, cppyy_index_t idata, int dimension)
char * cppyy_method_signature_max(cppyy_method_t method, int show_formalargs, int maxargs)
double cppyy_call_d(cppyy_method_t method, cppyy_object_t self, int nargs, void *args)
int cppyy_num_methods(cppyy_scope_t scope)
char * cppyy_method_prototype(cppyy_scope_t scope, cppyy_method_t method, int show_formalargs)
std::vector< TGlobal * > GlobalVars_t
char * cppyy_resolve_name(const char *cppitem_name)
cppyy_method_t cppyy_get_method(cppyy_scope_t scope, cppyy_index_t idx)
std::vector< TClassRef > ClassRefs_t
size_t cppyy_function_arg_sizeof()
int cppyy_is_const_method(cppyy_method_t method)
static std::map< TDictionary::DeclId_t, CallWrapper * > gMethodTemplates
int cppyy_num_datamembers(cppyy_scope_t scope)
#define CPPYY_HANDLE_EXCEPTION
size_t cppyy_size_of_klass(cppyy_type_t klass)
static bool match_name(const std::string &tname, const std::string fname)
int cppyy_datamember_index(cppyy_scope_t scope, const char *name)
cppyy_index_t cppyy_get_global_operator(cppyy_scope_t scope, cppyy_scope_t lc, cppyy_scope_t rc, const char *op)
static TFunction * m2f(Cppyy::TCppMethod_t method)
void cppyy_deallocate(cppyy_type_t type, cppyy_object_t self)
const char * cppyy_stdstring2charp(cppyy_object_t ptr, size_t *lsz)
int cppyy_compile(const char *code)
int cppyy_is_aggregate(cppyy_type_t type)
static TDataMember * GetDataMemberByIndex(TClassRef cr, int idata)
#define CPPYY_IMP_CALL(typecode, rtype)
int cppyy_method_num_args(cppyy_method_t method)
static std::set< std::string > gInitialNames
char * cppyy_method_arg_default(cppyy_method_t method, int arg_index)
static T CallT(Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, size_t nargs, void *args)
cppyy_funcaddr_t cppyy_function_address(cppyy_method_t method)
int cppyy_has_complex_hierarchy(cppyy_type_t type)
Cppyy::TCppIndex_t GetLongestInheritancePath(TClass *klass)
Retrieve number of base classes in the longest branch of the inheritance tree of the input class.
char * cppyy_method_arg_name(cppyy_method_t method, int arg_index)
const Int_t n
Definition legend1.C:16
#define I(x, y, z)
#define H(x, y, z)
size_t TCppIndex_t
Definition cpp_cppyy.h:24
RPY_EXPORTED TCppIndex_t GetNumTemplatedMethods(TCppScope_t scope, bool accept_namespace=false)
RPY_EXPORTED std::string GetMethodMangledName(TCppMethod_t)
RPY_EXPORTED TCppObject_t CallO(TCppMethod_t method, TCppObject_t self, size_t nargs, void *args, TCppType_t result_type)
RPY_EXPORTED int CallI(TCppMethod_t method, TCppObject_t self, size_t nargs, void *args)
RPY_EXPORTED TCppIndex_t CompareMethodArgType(TCppMethod_t, TCppIndex_t iarg, const std::string &req_type)
RPY_EXPORTED ptrdiff_t GetBaseOffset(TCppType_t derived, TCppType_t base, TCppObject_t address, int direction, bool rerror=false)
RPY_EXPORTED void DeallocateFunctionArgs(void *args)
RPY_EXPORTED bool IsEnumData(TCppScope_t scope, TCppIndex_t idata)
RPY_EXPORTED unsigned char CallB(TCppMethod_t method, TCppObject_t self, size_t nargs, void *args)
RPY_EXPORTED Long64_t CallLL(TCppMethod_t method, TCppObject_t self, size_t nargs, void *args)
RPY_EXPORTED bool IsAbstract(TCppType_t type)
RPY_EXPORTED size_t SizeOf(TCppType_t klass)
RPY_EXPORTED TCppObject_t CallConstructor(TCppMethod_t method, TCppType_t type, size_t nargs, void *args)
intptr_t TCppMethod_t
Definition cpp_cppyy.h:22
RPY_EXPORTED void * AllocateFunctionArgs(size_t nargs)
RPY_EXPORTED bool IsDefaultConstructable(TCppType_t type)
RPY_EXPORTED bool IsTemplate(const std::string &template_name)
RPY_EXPORTED TCppIndex_t GetMethodReqArgs(TCppMethod_t)
RPY_EXPORTED bool IsEnum(const std::string &type_name)
RPY_EXPORTED std::vector< TCppIndex_t > GetMethodIndicesFromName(TCppScope_t scope, const std::string &name)
RPY_EXPORTED bool ExistsMethodTemplate(TCppScope_t scope, const std::string &name)
RPY_EXPORTED TCppIndex_t GetNumDatamembers(TCppScope_t scope, bool accept_namespace=false)
RPY_EXPORTED std::string ToString(TCppType_t klass, TCppObject_t obj)
RPY_EXPORTED std::string GetMethodName(TCppMethod_t)
RPY_EXPORTED bool IsConstData(TCppScope_t scope, TCppIndex_t idata)
RPY_EXPORTED void AddSmartPtrType(const std::string &)
RPY_EXPORTED bool Compile(const std::string &code, bool silent=false)
RPY_EXPORTED void CallDestructor(TCppType_t type, TCppObject_t self)
RPY_EXPORTED TCppScope_t gGlobalScope
Definition cpp_cppyy.h:53
RPY_EXPORTED bool IsProtectedData(TCppScope_t scope, TCppIndex_t idata)
RPY_EXPORTED std::string GetMethodSignature(TCppMethod_t, bool show_formalargs, TCppIndex_t maxargs=(TCppIndex_t) -1)
RPY_EXPORTED int GetDimensionSize(TCppScope_t scope, TCppIndex_t idata, int dimension)
RPY_EXPORTED bool IsSubtype(TCppType_t derived, TCppType_t base)
RPY_EXPORTED TCppMethod_t GetMethodTemplate(TCppScope_t scope, const std::string &name, const std::string &proto)
void * TCppObject_t
Definition cpp_cppyy.h:21
RPY_EXPORTED bool IsConstructor(TCppMethod_t method)
RPY_EXPORTED TCppIndex_t GetNumMethods(TCppScope_t scope, bool accept_namespace=false)
RPY_EXPORTED TCppObject_t Construct(TCppType_t type, void *arena=nullptr)
RPY_EXPORTED bool GetSmartPtrInfo(const std::string &, TCppType_t *raw, TCppMethod_t *deref)
RPY_EXPORTED char CallC(TCppMethod_t method, TCppObject_t self, size_t nargs, void *args)
RPY_EXPORTED std::string GetMethodArgName(TCppMethod_t, TCppIndex_t iarg)
RPY_EXPORTED double CallD(TCppMethod_t method, TCppObject_t self, size_t nargs, void *args)
RPY_EXPORTED size_t GetFunctionArgTypeoffset()
RPY_EXPORTED TCppObject_t Allocate(TCppType_t type)
RPY_EXPORTED void Destruct(TCppType_t type, TCppObject_t instance)
RPY_EXPORTED std::string ResolveName(const std::string &cppitem_name)
TCppScope_t TCppType_t
Definition cpp_cppyy.h:19
RPY_EXPORTED void AddTypeReducer(const std::string &reducable, const std::string &reduced)
RPY_EXPORTED std::string ResolveEnum(const std::string &enum_type)
RPY_EXPORTED long long GetEnumDataValue(TCppEnum_t, TCppIndex_t idata)
RPY_EXPORTED bool IsAggregate(TCppType_t type)
RPY_EXPORTED TCppIndex_t GetMethodNumArgs(TCppMethod_t)
RPY_EXPORTED TCppType_t GetActualClass(TCppType_t klass, TCppObject_t obj)
RPY_EXPORTED std::string GetBaseName(TCppType_t type, TCppIndex_t ibase)
RPY_EXPORTED bool IsNamespace(TCppScope_t scope)
void * TCppEnum_t
Definition cpp_cppyy.h:20
RPY_EXPORTED float CallF(TCppMethod_t method, TCppObject_t self, size_t nargs, void *args)
RPY_EXPORTED std::string GetScopedFinalName(TCppType_t type)
RPY_EXPORTED void Deallocate(TCppType_t type, TCppObject_t instance)
RPY_EXPORTED bool IsPublicData(TCppScope_t scope, TCppIndex_t idata)
RPY_EXPORTED std::string GetMethodArgType(TCppMethod_t, TCppIndex_t iarg)
RPY_EXPORTED long CallL(TCppMethod_t method, TCppObject_t self, size_t nargs, void *args)
RPY_EXPORTED void * CallR(TCppMethod_t method, TCppObject_t self, size_t nargs, void *args)
RPY_EXPORTED std::string GetEnumDataName(TCppEnum_t, TCppIndex_t idata)
RPY_EXPORTED void GetAllCppNames(TCppScope_t scope, std::set< std::string > &cppnames)
RPY_EXPORTED bool IsComplete(const std::string &type_name)
RPY_EXPORTED bool IsBuiltin(const std::string &type_name)
RPY_EXPORTED bool IsStaticMethod(TCppMethod_t method)
RPY_EXPORTED TCppIndex_t GetDatamemberIndex(TCppScope_t scope, const std::string &name)
RPY_EXPORTED void CallV(TCppMethod_t method, TCppObject_t self, size_t nargs, void *args)
RPY_EXPORTED LongDouble_t CallLD(TCppMethod_t method, TCppObject_t self, size_t nargs, void *args)
RPY_EXPORTED bool IsStaticData(TCppScope_t scope, TCppIndex_t idata)
RPY_EXPORTED std::string GetDatamemberType(TCppScope_t scope, TCppIndex_t idata)
RPY_EXPORTED TCppMethod_t GetMethod(TCppScope_t scope, TCppIndex_t imeth)
RPY_EXPORTED bool IsDestructor(TCppMethod_t method)
RPY_EXPORTED bool IsSmartPtr(TCppType_t type)
RPY_EXPORTED std::string GetTemplatedMethodName(TCppScope_t scope, TCppIndex_t imeth)
RPY_EXPORTED size_t GetFunctionArgSizeof()
RPY_EXPORTED TCppScope_t GetScope(const std::string &scope_name)
RPY_EXPORTED bool HasVirtualDestructor(TCppType_t type)
RPY_EXPORTED bool IsConstMethod(TCppMethod_t)
RPY_EXPORTED bool HasComplexHierarchy(TCppType_t type)
RPY_EXPORTED std::vector< TCppScope_t > GetUsingNamespaces(TCppScope_t)
size_t TCppScope_t
Definition cpp_cppyy.h:18
RPY_EXPORTED bool IsTemplatedConstructor(TCppScope_t scope, TCppIndex_t imeth)
RPY_EXPORTED TCppIndex_t GetGlobalOperator(TCppType_t scope, const std::string &lc, const std::string &rc, const std::string &op)
RPY_EXPORTED TCppFuncAddr_t GetFunctionAddress(TCppMethod_t method, bool check_enabled=true)
RPY_EXPORTED TCppIndex_t GetNumEnumData(TCppEnum_t)
RPY_EXPORTED TCppIndex_t GetNumBases(TCppType_t type)
RPY_EXPORTED TCppIndex_t GetNumBasesLongestBranch(TCppType_t type)
Retrieve number of base classes in the longest branch of the inheritance tree.
RPY_EXPORTED std::string GetMethodPrototype(TCppScope_t scope, TCppMethod_t, bool show_formalargs)
RPY_EXPORTED std::string GetMethodResultType(TCppMethod_t)
RPY_EXPORTED std::string GetFinalName(TCppType_t type)
RPY_EXPORTED char * CallS(TCppMethod_t method, TCppObject_t self, size_t nargs, void *args, size_t *length)
RPY_EXPORTED std::string GetMethodArgDefault(TCppMethod_t, TCppIndex_t iarg)
RPY_EXPORTED bool IsMethodTemplate(TCppScope_t scope, TCppIndex_t imeth)
RPY_EXPORTED std::string GetDatamemberName(TCppScope_t scope, TCppIndex_t idata)
RPY_EXPORTED bool IsPublicMethod(TCppMethod_t method)
RPY_EXPORTED intptr_t GetDatamemberOffset(TCppScope_t scope, TCppIndex_t idata)
void * TCppFuncAddr_t
Definition cpp_cppyy.h:25
RPY_EXPORTED std::string GetMethodFullName(TCppMethod_t)
RPY_EXPORTED short CallH(TCppMethod_t method, TCppObject_t self, size_t nargs, void *args)
RPY_EXPORTED bool IsProtectedMethod(TCppMethod_t method)
RPY_EXPORTED TCppEnum_t GetEnum(TCppScope_t scope, const std::string &enum_name)
void(* DelFunc_t)(void *)
Definition Rtypes.h:116
std::string ResolveTypedef(const char *tname, bool resolveAll=false)
std::string CleanType(const char *typeDesc, int mode=0, const char **tail=nullptr)
Cleanup type description, redundant blanks removed and redundant tail ignored return *tail = pointer ...
std::string ShortType(const char *typeDesc, int mode)
Return the absolute type of typeDesc.
char * DemangleName(const char *mangled_name, int &errorCode)
Definition TClassEdit.h:208
#define RPY_EXTERN
union CPyCppyy::Parameter::Value fValue
const char * fSigName
TMarker m
Definition textangle.C:8