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