2#ifndef _CRT_SECURE_NO_WARNINGS
4#define _CRT_SECURE_NO_WARNINGS
24static inline size_t CALL_NARGS(
size_t nargs) {
return nargs & ~DIRECT_CALL; }
108static inline bool is_integral(std::string& s) {
112 }
else if (s ==
"true") {
116 return !s.empty() && std::find_if(s.begin(), s.end(), [](
unsigned char c) {
117 return !std::isdigit(c);
123 std::vector<std::string> IncludeDirs;
124 std::string ClangIncludeDir;
131static InterOpPaths cppinterop_paths() {
134 dir +=
"/cppinterop";
136 std::cerr <<
"[cppjit] CppInterOp headers not found in " << dir
138 Paths.IncludeDirs.push_back(dir);
145static bool loadDispatchAPI(
const InterOpPaths& ) {
150 std::cerr <<
"[cppjit] Failed to find libCling" << std::endl;
153 if (!Cpp::LoadDispatchAPI(libcling)) {
154 std::cerr <<
"[cppjit] Failed to load CppInterOp" << std::endl;
163acquireOrCreateInterpreter(
const InterOpPaths& Paths) {
164 if (
auto existingInterp = Cpp::GetInterpreter())
165 return existingInterp;
167 std::vector<const char*> args = {
"-std=c++17"};
168#if !(defined(__arm64__) && defined(__APPLE__))
170 args.push_back(
"-march=native");
176 std::string resourceDir = Paths.ClangIncludeDir;
177 if (resourceDir.empty())
178 resourceDir = Cpp::DetectResourceDir(
"clang-" CPPJIT_CLANG_MAJOR);
179 if (!resourceDir.empty()) {
180 args.push_back(
"-resource-dir");
181 args.push_back(resourceDir.c_str());
183 return Cpp::CreateInterpreter(args, {});
186static void configureInterpreter(
const InterOpPaths& Paths) {
188 for (
const auto&
name : bi) {
189 for (
const char*
a : {
"*",
"&",
"*&",
"[]",
"*[]"})
193 if (getenv(
"CPPJIT_DISABLE_FASTPATH"))
199 if (getenv(
"CPPJIT_OPT_LEVEL"))
200 optLevel = atoi(getenv(
"CPPJIT_OPT_LEVEL"));
203 std::ostringstream s;
204 s <<
"#pragma cling optimize " << optLevel;
205 Cpp::Process(s.str().c_str());
208 for (
const std::string& dir : Paths.IncludeDirs)
209 Cpp::AddIncludePath(dir.c_str());
210 Cpp::LoadLibrary(
"libstdc++",
true);
213static void preloadHeaders() {
214 const char* code =
"#include <algorithm>\n"
215 "#include <numeric>\n"
216 "#include <complex>\n"
217 "#include <iostream>\n"
218 "#include <string.h>\n"
219 "#include <string>\n"
220 "#include <vector>\n"
221 "#include <utility>\n"
222 "#include <memory>\n"
223 "#include <functional>\n"
226 "#include <sstream>\n"
232 "#include <chrono>\n"
234 "#if __has_include(<optional>)\n"
235 "#include <optional>\n"
237 "#include <CppInterOp/Dispatch.h>\n";
241static void defineRuntimeHelpers() {
242 Cpp::Declare(
"namespace __cppjit_internal { template<class C1, class C2>"
243 " bool is_equal(const C1& c1, const C2& c2) { return "
244 "(bool)(c1 == c2); } }",
246 Cpp::Declare(
"namespace __cppjit_internal { template<class C1, class C2>"
247 " bool is_not_equal(const C1& c1, const C2& c2) { return "
248 "(bool)(c1 != c2); } }",
252 Cpp::Declare(
"namespace __cppjit_internal { struct Sep; }",
267 static std::once_flag Once;
268 static int Loaded = 0;
269 std::call_once(Once, [] {
271 const InterOpPaths Paths = cppinterop_paths();
272 if (!loadDispatchAPI(Paths))
275 acquireOrCreateInterpreter(Paths);
276 configureInterpreter(Paths);
278 defineRuntimeHelpers();
287 char* cstr = (
char*)malloc(cppstr.size() + 1);
288 memcpy(cstr, cppstr.c_str(), cppstr.size() + 1);
297 return !Cpp::Declare(code.c_str(), silent);
306 if (klass && obj && !Cpp::IsNamespace(klass))
307 return Cpp::ObjToString(Cpp::GetQualifiedCompleteName(klass).c_str(),
326 if (Cpp::GetValueKind(
type) != Cpp::ValueKind::LValue)
330 if (Cpp::IsEnumType(nonReferenceType)) {
332 Cpp::GetIntegerTypeFromEnumType(nonReferenceType);
333 return Cpp::GetReferencedType(underlying_type,
false);
340 if (!Cpp::IsPointerType(
type))
344 if (Cpp::IsEnumType(PointeeType)) {
345 TCppType_t underlying_type = Cpp::GetIntegerTypeFromEnumType(PointeeType);
346 return Cpp::GetPointerType(underlying_type);
353 if (Cpp::IsPointerType(check_int_typedefs))
354 check_int_typedefs = Cpp::GetPointeeType(check_int_typedefs);
355 if (Cpp::IsReferenceType(check_int_typedefs))
357 Cpp::GetReferencedType(check_int_typedefs,
false);
359 if (Cpp::GetTypeAsString(check_int_typedefs) ==
"int8_t" ||
360 Cpp::GetTypeAsString(check_int_typedefs) ==
"uint8_t")
361 return check_int_typedefs;
372 if (check_int_typedefs)
377 if (Cpp::IsEnumType(canonType)) {
378 if (Cpp::GetTypeAsString(
type) !=
"std::byte")
379 return Cpp::GetIntegerTypeFromEnumType(canonType);
381 if (Cpp::HasTypeQualifier(canonType, Cpp::QualKind::Restrict)) {
382 return Cpp::RemoveTypeQualifier(canonType, Cpp::QualKind::Restrict);
391 if (check_int_typedefs)
392 return check_int_typedefs;
393 return Cpp::GetUnderlyingType(
type);
398 return Cpp::GetPointerType(
type);
403 return Cpp::GetReferencedType(
type, rvalue);
407 return Cpp::GetValueKind(
type) == Cpp::ValueKind::RValue;
411 return Cpp::GetValueKind(
type) == Cpp::ValueKind::LValue;
417 if (!Cpp::IsReferenceType(
type))
420 return Cpp::IsPointerType(nonref) &&
421 !Cpp::HasTypeQualifier(nonref, Cpp::QualKind::Const);
428 Cpp::Signedness sign;
429 bool res = Cpp::IsIntegerType(
type, &sign);
430 *is_signed = (sign == Cpp::Signedness::kSigned);
433 return Cpp::IsIntegerType(
type,
nullptr);
437 return Cpp::IsPointerType(
type);
441 return Cpp::IsFunctionPointerType(
type);
447 const char* WhiteSpace =
" \t\v\r\n";
448 std::size_t start =
line.find_first_not_of(WhiteSpace);
449 std::size_t end =
line.find_last_not_of(WhiteSpace);
450 return line.substr(start, end - start + 1);
455 std::vector<std::string>& types) {
456 std::string trimed_name =
trim(
name);
457 size_t start_pos = 0;
459 int matching_angular_brackets = 0;
460 while (end_pos < trimed_name.size()) {
461 switch (trimed_name[end_pos]) {
463 if (!matching_angular_brackets) {
464 if (end_pos > start_pos)
466 trim(trimed_name.substr(start_pos, end_pos - start_pos)));
467 start_pos = end_pos + 1;
472 matching_angular_brackets++;
476 matching_angular_brackets--;
482 if (start_pos < trimed_name.size())
483 types.push_back(
trim(trimed_name.substr(start_pos, end_pos - start_pos)));
488 std::string delim =
"::";
490 size_t end =
name.find(delim);
492 while (end != std::string::npos) {
493 curr_scope = Cpp::GetNamed(
name.substr(start, end - start), curr_scope);
494 start = end + delim.length();
495 end =
name.find(delim, start);
497 return Cpp::GetNamed(
name.substr(start, end), curr_scope);
502 auto is_valid_start = [](
unsigned char c) {
503 return std::isalpha(
c) ||
c ==
'_';
505 auto is_valid_body = [](
unsigned char c) {
506 return std::isalnum(
c) ||
c ==
'_';
508 return is_valid_start(s[0]) &&
509 std::all_of(s.begin() + 1, s.end(), is_valid_body);
514 std::vector<Cpp::TemplateArgInfo>& types,
522 if (
name ==
"<unnamed>")
528 if (
name.find(
"(anonymous namespace)") != std::string::npos)
531 auto replace_all = [](std::string& str,
const std::string& from,
532 const std::string& to) {
535 size_t start_pos = 0;
536 while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
537 str.replace(start_pos, from.length(), to);
538 start_pos += to.length();
542 std::string resolved_name =
name;
543 replace_all(resolved_name,
"std::initializer_list<",
556 types.emplace_back(
type.data);
559 if (!parent || parent == Cpp::GetGlobalScope())
569 static unsigned long long struct_count = 0;
571 "template<typename ...T> struct __cppjit_interop_AppendTypesSlow {};\n";
573 Cpp::Declare(code.c_str(),
true);
582 std::string lookup_ns;
584 for (
TCppScope_t s = parent; s && s != Cpp::GetGlobalScope();
585 s = Cpp::GetParentScope(s)) {
586 if (!Cpp::IsNamespace(s))
588 std::string qname = Cpp::GetQualifiedName(s);
589 if (!qname.empty() && qname.find(
'(') == std::string::npos) {
599 std::vector<std::string> candidates = {resolved_name};
600 if (parent && parent != Cpp::GetGlobalScope() && parent != lookup_scope &&
602 candidates.push_back(Cpp::GetQualifiedCompleteName(parent) +
603 "::" + resolved_name);
605 for (
const std::string& candidate : candidates) {
606 std::string var =
"__cppjit_interop_s" + std::to_string(struct_count++);
610 std::string decl =
"__cppjit_interop_AppendTypesSlow<" + candidate +
611 "> __attribute__((nodebug)) " + var +
";\n";
612 if (!lookup_ns.empty())
613 decl =
"namespace " + lookup_ns +
" { " + decl +
"}\n";
614 if (!Cpp::Declare(decl.c_str(),
true)) {
615 TCppType_t varN = Cpp::GetVariableType(Cpp::GetNamed(
616 var.c_str(), lookup_ns.empty() ?
nullptr : lookup_scope));
617 TCppScope_t instance_class = Cpp::GetScopeFromType(varN);
620 size_t oldSize = types.size();
621 Cpp::GetClassTemplateInstantiationArgs(instance_class, types);
622 return oldSize == types.size();
632 std::vector<std::string> individual_types;
636 for (std::string& i : individual_types) {
638 const char* integral_value =
nullptr;
641 if (!lookup_ns.empty()) {
644 std::string
id =
"__cppjit_interop_s" + std::to_string(struct_count++);
645 if (!Cpp::Declare((
"namespace " + lookup_ns +
" { using " +
id +
646 " = __typeof__(" + i +
"); }\n")
649 type = Cpp::GetCanonicalType(
650 Cpp::GetTypeFromScope(Cpp::GetNamed(
id, lookup_scope)));
652 type = GetType(i,
true);
653 if (!
type && parent &&
666 integral_value = strdup(i.c_str());
668 if (Cpp::IsEnumConstant(scope))
670 strdup(std::to_string(Cpp::GetEnumConstantValue(scope)).c_str());
671 types.emplace_back(
type.data, integral_value);
677 bool enable_slow_lookup ) {
679 if (
name ==
"<unnamed>")
696 if (
name ==
"true" ||
name ==
"false")
697 return Cpp::GetType(
"bool");
698 if (
name ==
"nullptr")
699 return Cpp::GetType(
"nullptr_t", Cpp::GetNamed(
"std"));
703 if (!enable_slow_lookup) {
704 if (
name.find(
"::") != std::string::npos)
705 throw std::runtime_error(
706 "Calling interop::GetType with qualified name '" +
name +
"'\n");
716 static std::map<std::string, TCppType_t> s_slow_type_cache;
717 auto cached = s_slow_type_cache.find(
name);
718 if (cached != s_slow_type_cache.end())
719 return cached->second;
721 static unsigned long long var_count = 0;
722 std::string
id =
"__cppjit_interop_GetType_" + std::to_string(var_count++);
723 std::string using_clause =
"using " +
id +
" = __typeof__(" +
name +
");\n";
725 if (!Cpp::Declare(using_clause.c_str(),
true)) {
727 TCppType_t lookup_ty = Cpp::GetTypeFromScope(lookup);
738 return Cpp::GetComplexType(Cpp::GetType(
name));
744 Cpp::GetTypeAsString(Cpp::GetIntegerTypeFromEnumScope(handle));
745 if (
type ==
"signed char")
752 return Cpp::GetUnderlyingScope(scope);
762 if (!parent_scope || parent_scope == Cpp::GetGlobalScope())
767 if (!parent_scope || parent_scope == Cpp::GetGlobalScope()) {
770 }
else if (
name.find(
'<') == std::string::npos) {
775 size_t start = 0, end;
776 while (curr && (end =
name.find(
"::", start)) != std::string::npos) {
777 curr = Cpp::GetScope(
name.substr(start, end - start), curr);
780 if (curr && curr != parent_scope)
786 if (
name.find(
'<') != std::string::npos) {
791 std::vector<Cpp::TemplateArgInfo> types;
793 bool added_new_type =
796 if (added_new_type && types.size() == 1) {
801 if (Cpp::IsPointerType(types[0].m_Type) ||
802 Cpp::IsReferenceType(types[0].m_Type))
804 TCppScope_t scope = Cpp::GetScopeFromType(types[0].m_Type);
810 Cpp::IsComplete(scope);
823 return Cpp::GetScopeFromType(Cpp::GetVariableType(var));
836 if (
name ==
"gROOT" &&
837 (!parent_scope || parent_scope == Cpp::GetGlobalScope())) {
839 return Cpp::GetNamed(
841 Cpp::GetNamed(
"Internal", Cpp::GetNamed(
"ROOT",
nullptr)));
849 return Cpp::GetParentScope(scope);
854 return Cpp::GetScopeFromType(
type);
859 return Cpp::GetTypeFromScope(klass);
864 return Cpp::GetGlobalScope();
870 return Cpp::IsTemplateSpecialization(handle);
874 return Cpp::IsTypedefed(handle);
880 virtual ~AutoCastRTTI() {}
888 if (!obj || !Cpp::IsClassPolymorphic(klass))
894 static const std::array<TCppScope_t, 3> stream_bases = {
906 static std::map<std::pair<const void*, const std::type_info*>,
TCppScope_t>
907 s_actual_class_cache;
908 const std::type_info* typ = &
typeid(*(AutoCastRTTI*)obj.data);
911 const auto cacheKey = std::make_pair((
const void*)klass.data, typ);
912 auto cached = s_actual_class_cache.find(cacheKey);
913 if (cached != s_actual_class_cache.end())
914 return cached->second;
923 std::string demangled_name = typ->name();
924 for (
const char* prefix : {
"class ",
"struct ",
"union ",
"enum "}) {
925 if (demangled_name.compare(0, strlen(prefix), prefix) == 0) {
926 demangled_name = demangled_name.substr(strlen(prefix));
931 std::string mangled_name = typ->name();
932 std::string demangled_name = Cpp::Demangle(mangled_name);
939 if (demangled_name.find(
"anonymous namespace") != std::string::npos)
948 p = Cpp::GetParentScope(
p))
949 if (Cpp::IsNamespace(
p) && Cpp::GetName(
p).empty())
958 if (Cpp::GetOrForceDefinition(scope)) {
959 s_actual_class_cache.emplace(cacheKey, scope);
969 return Cpp::SizeOf(klass);
976 return Cpp::GetSizeOfType(klass);
980 static std::set<std::string> s_builtins = {
"bool",
992 "unsigned long long",
997 if (s_builtins.find(
trim(type_name)) != s_builtins.end())
1000 if (strstr(type_name.c_str(),
"std::complex"))
1010 return Cpp::IsComplete(scope);
1017 return Cpp::Allocate(scope, 1);
1022 Cpp::Deallocate(scope,
instance, 1);
1030 if (!Cpp::HasDefaultConstructor(scope))
1033 Cpp::MakeFunctionCallable(Cpp::GetDefaultConstructor(scope));
1038 JC.InvokeConstructor(&
result, 1, {},
1039 arena ?
reinterpret_cast<void*
>(1)
1046 return Cpp::MakeFunctionCallable(Cpp::GetDestructor(scope));
1051 JC.InvokeDestructor(
instance.data, 0,
true);
1055 bool runRelease =
false;
1056 for (
size_t i = 0; i < nargs; ++i) {
1057 switch (args[i].fTypeCode) {
1064 vargs[i] = args[i].
fRef;
1067 vargs[i] = (
void*)&args[i].fValue.fVoidp;
1075 for (
size_t i = 0; i < nargs; ++i) {
1076 if (args[i].fTypeCode ==
'X')
1077 free(args[i].fValue.fVoidp);
1082 void* args_,
void* self,
void*
result) {
1090 if (Cpp::JitCall JC = Cpp::MakeFunctionCallable(method)) {
1092 bool runRelease =
false;
1097 runRelease =
copy_args(args, nargs, smallbuf);
1099 JC.Invoke(
result, {smallbuf, nargs}, self);
1102 std::vector<void*> buf(nargs);
1103 runRelease =
copy_args(args, nargs, buf.data());
1105 JC.Invoke(
result, {buf.data(), nargs}, self);
1116template <
typename T>
1118 size_t nargs,
void* args) {
1120 if (
WrapperCall(method, nargs, args, self.data, &t))
1122 throw std::runtime_error(
"failed to resolve function");
1127#define _IMP_CALL_PRINT_STMT(type) printf("IMP CALL with type: %s\n", #type);
1129#define _IMP_CALL_PRINT_STMT(type)
1132#define CPPJIT_IMP_CALL(typecode, rtype) \
1133 rtype interop::Call##typecode(TCppMethod_t method, TCppObject_t self, \
1134 size_t nargs, void* args) { \
1135 _IMP_CALL_PRINT_STMT(rtype) \
1136 return CallT<rtype>(method, self, nargs, args); \
1141 if (!
WrapperCall(method, nargs, args, self.data,
nullptr))
1166 void* args,
size_t*
length) {
1167 char* cstr =
nullptr;
1169 std::string* cppresult = (std::string*)malloc(
sizeof(std::string));
1170 if (
WrapperCall(method, nargs, args, self.data, (
void*)cppresult)) {
1172 *
length = cppresult->size();
1173 cppresult->std::string::~basic_string();
1176 free((
void*)cppresult);
1182 size_t nargs,
void* args) {
1183 void* obj =
nullptr;
1190 JC.InvokeDestructor(self.data, 0,
false);
1194 size_t nargs,
void* args,
1199 void* obj = ::operator
new(
size);
1200 if (
WrapperCall(method, nargs, args, self.data, obj))
1202 ::operator
delete(obj);
1209 return Cpp::GetFunctionAddress(method);
1232 return Cpp::IsNamespace(scope) || Cpp::GetGlobalScope() == scope;
1237 return Cpp::IsClass(scope);
1242 return Cpp::IsAbstract(scope);
1255 return Cpp::IsAggregate(
type);
1261 return Cpp::HasDefaultConstructor(scope);
1267 std::set<std::string>& cppnames) {
1272 Cpp::GetAllCppNames(scope, cppnames);
1276std::vector<interop::TCppScope_t>
1279 return Cpp::GetUsingNamespaces(scope);
1290 std::string::size_type pos = 0;
1291 while ((pos =
name.find(
", ", pos)) != std::string::npos)
1292 name.erase(pos + 1, 1);
1294 while ((pos =
name.find(
" *", pos)) != std::string::npos)
1297 while ((pos =
name.find(
" &", pos)) != std::string::npos)
1306 Cpp::GetCompleteName(Cpp::GetUnderlyingScope(klass)));
1317 return Cpp::IsVirtualMethod(func);
1323 return Cpp::GetNumBases(klass);
1348 std::vector<size_t> num;
1354 return *std::max_element(num.begin(), num.end()) + 1;
1359 return Cpp::GetName(Cpp::GetBaseClass(klass, ibase));
1365 return Cpp::GetBaseClass(klass, ibase);
1375 static std::map<std::pair<const void*, const void*>,
bool> s_subclass_cache;
1376 const auto cacheKey = std::make_pair(derived.data, base.data);
1377 auto cached = s_subclass_cache.find(cacheKey);
1378 if (cached != s_subclass_cache.end())
1379 return cached->second;
1380 bool result = Cpp::IsSubclass(derived, base);
1381 if (
result || (Cpp::IsComplete(derived) && Cpp::IsComplete(base)))
1382 s_subclass_cache.emplace(cacheKey,
result);
1387 "std::auto_ptr",
"std::shared_ptr",
"std::unique_ptr",
"std::weak_ptr"};
1410 std::vector<TCppMethod_t> ops;
1413 Cpp::GetOperator(scope, Cpp::Operator::OP_Arrow, ops,
1414 Cpp::OperatorArity::kBoth);
1415 if (ops.size() != 1)
1423 if (Cpp::IsTemplatedFunction(ops[0]))
1424 ops[0] = Cpp::BestOverloadFunctionMatch(ops, {}, {});
1433 return (!deref || *deref) && (!raw || *raw);
1445 static std::map<std::pair<const void*, const void*>, intptr_t>
1446 s_base_offset_cache;
1447 const auto cacheKey = std::make_pair(derived.data, base.data);
1448 auto cached = s_base_offset_cache.find(cacheKey);
1450 if (cached != s_base_offset_cache.end()) {
1457 if (!Cpp::IsComplete(derived) || !Cpp::IsComplete(base))
1458 return rerror ? (ptrdiff_t)-1 : 0;
1460 offset = Cpp::GetBaseClassOffset(derived, base);
1463 return rerror ? (ptrdiff_t)
offset : 0;
1465 s_base_offset_cache.emplace(cacheKey,
offset);
1476 methods.erase(std::remove_if(methods.begin(), methods.end(),
1478 return Cpp::IsFunctionDeleted(m);
1484 std::vector<interop::TCppMethod_t>& methods) {
1486 Cpp::GetClassMethods(scope, methods);
1490std::vector<interop::TCppMethod_t>
1493 std::vector<interop::TCppMethod_t> methods =
1494 Cpp::GetFunctionsUsingName(scope,
name);
1501 return Cpp::GetName(method);
1511 return Cpp::GetFunctionReturnType(method);
1516 TCppType_t ret = Cpp::GetCanonicalType(Cpp::GetFunctionReturnType(method));
1522 if (ret && !Cpp::IsRecordType(ret))
1523 ret = Cpp::RemoveTypeQualifier(ret,
1524 Cpp::QualKind::Const | Cpp::QualKind::Volatile);
1525 return Cpp::GetTypeAsString(ret);
1530 return Cpp::GetFunctionNumArgs(method);
1535 return Cpp::GetFunctionRequiredArgs(method);
1543 return Cpp::GetFunctionArgName(method, iarg);
1549 return Cpp::GetFunctionArgType(method, iarg);
1555 return Cpp::GetTypeAsString(Cpp::RemoveTypeQualifier(
1556 Cpp::GetFunctionArgType(method, iarg), Cpp::QualKind::Const));
1562 return Cpp::GetTypeAsString(
1563 Cpp::GetCanonicalType(Cpp::GetFunctionArgType(method, iarg)));
1572 return Cpp::GetFunctionArgDefault(method, iarg);
1577 const std::string& ) {
1610 bool show_formal_args,
1612 std::ostringstream sig;
1616 nArgs = std::min(nArgs, (
int)max_args);
1617 for (
int iarg = 0; iarg < nArgs; ++iarg) {
1620 if (show_formal_args) {
1622 if (!argname.empty())
1623 sig <<
" " << argname;
1625 if (!defvalue.empty())
1626 sig <<
" = " << defvalue;
1628 if (iarg != nArgs - 1)
1636 fn_type = Cpp::IsReferenceType(fn_type) ? Cpp::GetNonReferenceType(fn_type)
1639 Cpp::IsPointerType(fn_type) ? Cpp::GetPointeeType(fn_type) : fn_type;
1640 TCppScope_t scope = Cpp::GetScopeFromType(fn_type);
1641 std::vector<Cpp::TemplateArgInfo> args;
1642 Cpp::GetClassTemplateArgs(scope, args);
1643 assert(args.size() == 1);
1644 if (args.size() == 1)
1645 return args[0].m_Type;
1650 std::vector<TCppType_t>& arg_types) {
1651 fn_type = Cpp::IsReferenceType(fn_type) ? Cpp::GetNonReferenceType(fn_type)
1654 Cpp::IsPointerType(fn_type) ? Cpp::GetPointeeType(fn_type) : fn_type;
1655 Cpp::GetFnTypeSignature(fn_type, arg_types);
1659 return Cpp::IsSameType(typ1, typ2);
1663 typ = Cpp::IsReferenceType(typ) ? Cpp::GetNonReferenceType(typ) : typ;
1664 typ = Cpp::IsPointerType(typ) ? Cpp::GetPointeeType(typ) : typ;
1665 return Cpp::IsFunctionProtoType(typ);
1669 typ1 = Cpp::IsReferenceType(typ1) ? Cpp::GetNonReferenceType(typ1) : typ1;
1670 typ2 = Cpp::IsReferenceType(typ2) ? Cpp::GetNonReferenceType(typ2) : typ2;
1671 typ1 = Cpp::IsPointerType(typ1) ? Cpp::GetPointeeType(typ1) : typ1;
1672 typ2 = Cpp::IsPointerType(typ2) ? Cpp::GetPointeeType(typ2) : typ2;
1673 return Cpp::IsSameType(typ1, typ2);
1678 return Cpp::GetDoxygenComment(scope, strip_markers);
1685 return Cpp::IsConstMethod(method);
1689 std::vector<interop::TCppMethod_t>& methods) {
1691 Cpp::GetFunctionTemplatedDecls(scope, methods);
1697 std::vector<interop::TCppMethod_t> mc;
1698 Cpp::GetFunctionTemplatedDecls(scope, mc);
1705 std::vector<interop::TCppMethod_t> mc;
1706 Cpp::GetFunctionTemplatedDecls(scope, mc);
1708 if (imeth < mc.size())
1716 return Cpp::ExistsFunctionTemplate(
name, scope);
1720 return Cpp::IsTemplatedFunction(method);
1724 std::vector<TCppMethod_t> candidate_methods;
1725 Cpp::GetClassTemplatedMethods(
name, scope, candidate_methods);
1726 bool is_static =
true;
1727 for (
auto i : candidate_methods) {
1728 if (!Cpp::IsStaticMethod(i)) {
1737 const std::string&
name,
1738 const std::string& proto) {
1739 std::string pureName;
1740 std::string explicit_params;
1742 if ((
name.find(
"operator<") != 0) && (
name.find(
'<') != std::string::npos)) {
1743 pureName =
name.substr(0,
name.find(
'<'));
1744 size_t start =
name.find(
'<');
1745 size_t end =
name.rfind(
'>');
1746 explicit_params =
name.substr(start + 1, end - start - 1);
1753 std::vector<interop::TCppMethod_t> unresolved_candidate_methods;
1754 Cpp::GetClassTemplatedMethods(pureName, scope, unresolved_candidate_methods);
1755 if (unresolved_candidate_methods.empty() &&
name.find(
"operator") == 0) {
1761 std::vector<Cpp::TemplateArgInfo> arg_types;
1762 std::vector<Cpp::TemplateArgInfo> templ_params;
1766 cppmeth = Cpp::BestOverloadFunctionMatch(unresolved_candidate_methods,
1767 templ_params, arg_types);
1777 if (!cppmeth && !templ_params.empty()) {
1778 for (
const auto& cand : unresolved_candidate_methods) {
1779 if (Cpp::DeclRef spec = Cpp::InstantiateTemplate(
1780 TCppScope_t(cand.data), templ_params.data(), templ_params.size(),
1782 cppmeth = spec.data;
1797 std::string prefix =
"std::basic_string<";
1799 if (
n.compare(0, prefix.size(), prefix) != 0)
1801 return n.size() > prefix.size() &&
1802 (
n[prefix.size()] ==
',' ||
n[prefix.size()] ==
'>');
1806 const std::string& n2) {
1814 return "std::basic_string<wchar_t>&";
1815 return "std::basic_string<char>&";
1817 return "std::basic_string<wchar_t>&";
1818 }
else if (n1 ==
"complex") {
1819 return "std::complex<double>";
1825 const std::string& opname,
1826 std::vector<TCppMethod_t>& operators) {
1828 std::string op = opname.substr(8);
1829 Cpp::GetOperator(klass, Cpp::GetOperatorFromSpelling(op), operators,
1830 Cpp::OperatorArity::kBoth);
1834 const std::string& lc,
1835 const std::string& rc,
1836 const std::string& opname) {
1840 std::vector<TCppMethod_t> overloads;
1841 Cpp::GetOperator(scope, Cpp::GetOperatorFromSpelling(opname), overloads,
1842 Cpp::OperatorArity::kBoth);
1853 std::vector<Cpp::TemplateArgInfo> arg_types;
1854 if (
auto l = resolve_arg_type(lc_type))
1855 arg_types.emplace_back(
l.data);
1859 if (!rc_type.empty()) {
1860 if (
auto r = resolve_arg_type(rc_type))
1861 arg_types.emplace_back(
r.data);
1866 Cpp::BestOverloadFunctionMatch(overloads, {}, arg_types);
1874 return Cpp::IsFunctionDeleted(method);
1878 return Cpp::IsPublicMethod(method);
1882 return Cpp::IsProtectedMethod(method);
1886 return Cpp::IsPrivateMethod(method);
1890 return Cpp::IsConstructor(method);
1894 return Cpp::IsDestructor(method);
1898 return Cpp::IsStaticMethod(method);
1902 return Cpp::IsExplicit(method);
1907 std::vector<TCppScope_t>& datamembers) {
1909 Cpp::GetDatamembers(scope, datamembers);
1910 Cpp::GetStaticDatamembers(scope, datamembers);
1911 Cpp::GetEnumConstantDatamembers(scope, datamembers,
false);
1916 return (
bool)Cpp::LookupDatamember(
name, scope);
1920 return Cpp::IsLambdaClass(
type);
1925 std::ostringstream code;
1927 code <<
"namespace __cppjit_internal_wrap_g {\n"
1928 <<
" " <<
"std::function " <<
name
1929 <<
" = ::" << Cpp::GetQualifiedName(var) <<
";\n"
1934 name, Cpp::GetScope(
"__cppjit_internal_wrap_g",
nullptr));
1945 std::string fn_name = Cpp::GetQualifiedCompleteName(
TCppScope_t(fn.data));
1948 std::ostringstream call;
1957 std::ostringstream code;
1959 std::string
name =
"lambda_return_convert_" + std::to_string(++i);
1960 code <<
"namespace __cppjit_internal_wrap_g {\n"
1961 <<
"auto " <<
name << signature <<
"{" <<
"return std::function("
1962 << fn_name << call.str() <<
"); }\n"
1966 name, Cpp::GetScope(
"__cppjit_internal_wrap_g",
nullptr));
1975 return Cpp::GetVariableType(Cpp::GetUnderlyingScope(var));
1980 return Cpp::GetTypeAsString(
1981 Cpp::GetVariableType(Cpp::GetUnderlyingScope(scope)));
1986 return Cpp::GetTypeAsString(
type);
1991 return Cpp::GetVariableOffset(Cpp::GetUnderlyingScope(var), klass);
1996 return Cpp::IsPublicVariable(datamem);
2000 return Cpp::IsProtectedVariable(datamem);
2004 return Cpp::IsPrivateVariable(datamem);
2017 std::string fn_name = Cpp::GetQualifiedCompleteName(
TCppScope_t(fn.data));
2021 std::ostringstream call;
2030 std::ostringstream code;
2032 std::string
name =
"reduced_function_" + std::to_string(++i);
2033 code <<
"namespace __cppjit_internal_wrap_g {\n"
2034 << result_type <<
" " <<
name << signature <<
"{" <<
"return ("
2035 << result_type <<
")::" << fn_name << call.str() <<
"; }\n"
2039 name, Cpp::GetScope(
"__cppjit_internal_wrap_g",
nullptr));
2048 return Cpp::GetDimensions(
type);
2054 return Cpp::GetEnumConstants(scope);
2059 return Cpp::GetEnumConstantType(Cpp::GetUnderlyingScope(scope));
2064 return Cpp::GetEnumConstantValue(scope);
2068 Cpp::TemplateArgInfo* args,
2071 return Cpp::InstantiateTemplate(tmpl, args, args_size,
2077 Cpp::DumpScope(scope);
static Roo_reg_AGKInteg1D instance
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
R__EXTERN TVirtualMutex * gInterpreterMutex
R__EXTERN TSystem * gSystem
std::recursive_mutex fLocal
static thread_local std::vector< TVirtualMutex * > fGlobalLocked
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.
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
const char * Data() const
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
This class implements a mutex interface.
std::string trim(const std::string &line)
static std::string type_remap(const std::string &n1, const std::string &n2)
static bool is_identifier(std::string_view s)
static bool copy_args(Parameter *args, size_t nargs, void **vargs)
interop::TCppType_t int_like_type(interop::TCppType_t type)
static std::set< std::string > gSmartPtrTypes
interop::TCppScope_t GetEnumFromCompleteName(const std::string &name)
static char * cppstring_to_cstring(const std::string &cppstr)
static void release_args(Parameter *args, size_t nargs)
static bool WrapperCall(interop::TCppMethod_t method, size_t nargs, void *args_, void *self, void *result)
static std::set< std::string > g_builtins
cppjit::cpyrt::Parameter Parameter
static bool is_basic_string_of(const std::string &n, const char *charT)
static bool gEnableFastPath
static T CallT(interop::TCppMethod_t method, interop::TCppObject_t self, size_t nargs, void *args)
static void remove_deleted_methods(std::vector< interop::TCppMethod_t > &methods)
#define CPPJIT_IMP_CALL(typecode, rtype)
static Cpp::JitCall destructor_callable(interop::TCppScope_t scope)
bool split_comma_saparated_types(const std::string &name, std::vector< std::string > &types)
static size_t CALL_NARGS(size_t nargs)
static std::string cppyy_normalize_name(std::string name)
RInterOpMutex InterOpMutex
bool IsConstVar(TCppScope_t var)
TCppScope_t GetFullScope(const std::string &scope_name)
void GetDatamembers(TCppScope_t scope, std::vector< TCppScope_t > &datamembers)
Cpp::ObjectRef TCppObject_t
TCppType_t GetTypeFromScope(TCppScope_t klass)
std::string GetTypeAsString(TCppType_t type)
TCppType_t GetDatamemberType(TCppScope_t data)
TCppType_t ResolveEnumPointerType(TCppType_t type)
bool ExistsMethodTemplate(TCppScope_t scope, const std::string &name)
bool IsFunctionType(TCppType_t typ)
TCppScope_t WrapLambdaFromVariable(TCppScope_t var)
void DeallocateFunctionArgs(void *args)
bool IsBuiltin(const std::string &type_name)
void CallV(TCppMethod_t method, TCppObject_t self, size_t nargs, void *args)
std::string GetName(TCppScope_t)
std::string ToString(TCppScope_t klass, TCppObject_t obj)
bool IsClassType(TCppType_t type)
void CallDestructor(TCppScope_t type, TCppObject_t self)
bool CheckDatamember(TCppScope_t scope, const std::string &name)
TCppMethod_t GetMethodTemplate(TCppScope_t scope, const std::string &name, const std::string &proto)
bool IsTemplateInstantiation(TCppScope_t scope)
TCppMethod_t AdaptFunctionForLambdaReturn(TCppMethod_t fn)
bool IsStaticTemplate(TCppScope_t scope, const std::string &name)
bool IsConstructor(TCppMethod_t method)
std::string GetMethodArgCanonTypeAsString(TCppMethod_t method, TCppIndex_t iarg)
bool HasVirtualDestructor(TCppScope_t type)
TCppIndex_t GetNumTemplatedMethods(TCppScope_t scope, bool accept_namespace=false)
TCppScope_t GetActualClass(TCppScope_t klass, TCppObject_t obj)
void GetTemplatedMethods(TCppScope_t scope, std::vector< TCppMethod_t > &methods)
std::string ResolveName(const std::string &cppitem_name)
std::string GetMethodArgTypeAsString(TCppMethod_t method, TCppIndex_t iarg)
TCppIndex_t GetMethodReqArgs(TCppMethod_t)
bool AppendTypesSlow(const std::string &name, std::vector< Cpp::TemplateArgInfo > &types, TCppScope_t parent=nullptr)
bool IsAbstract(TCppScope_t scope)
TCppScope_t GetParentScope(TCppScope_t scope)
std::string GetMethodReturnTypeAsString(TCppMethod_t)
TCppType_t GetReferencedType(TCppType_t type, bool rvalue=false)
TCppIndex_t GetMethodNumArgs(TCppMethod_t)
bool IsStaticDatamember(TCppScope_t var)
bool IsProtectedMethod(TCppMethod_t method)
bool IsClass(TCppScope_t scope)
void Destruct(TCppScope_t scope, TCppObject_t instance)
TCppIndex_t GetNumBases(TCppScope_t klass)
TCppIndex_t CompareMethodArgType(TCppMethod_t, TCppIndex_t iarg, const std::string &req_type)
bool IsSubclass(TCppScope_t derived, TCppScope_t base)
TCppScope_t GetNamed(const std::string &scope_name, TCppScope_t parent_scope=TCppScope_t{})
intptr_t GetDatamemberOffset(TCppScope_t var, TCppScope_t klass=nullptr)
size_t SizeOfType(TCppType_t type)
Cpp::FuncRef TCppMethod_t
bool IsPublicData(TCppScope_t var)
TCppType_t GetMethodArgType(TCppMethod_t, TCppIndex_t iarg)
TCppScope_t GetBaseScope(TCppScope_t klass, TCppIndex_t ibase)
bool IsIntegerType(TCppType_t type, bool *is_signed=nullptr)
bool IsFunctionPointerType(TCppType_t type)
bool IsTypedefed(TCppScope_t scope)
bool IsPrivateMethod(TCppMethod_t method)
TCppObject_t Allocate(TCppScope_t scope)
bool IsEnumScope(TCppScope_t scope)
bool IsSimilarFnTypes(TCppType_t typ1, TCppType_t typ2)
void GetClassMethods(TCppScope_t scope, std::vector< TCppMethod_t > &methods)
TCppMethod_t GetGlobalOperator(TCppScope_t scope, const std::string &lc, const std::string &rc, const std::string &op)
TCppMethod_t ReduceReturnType(TCppMethod_t fn, TCppType_t reduce)
void * AllocateFunctionArgs(size_t nargs)
void GetClassOperators(TCppScope_t klass, const std::string &opname, std::vector< TCppMethod_t > &operators)
TCppObject_t CallO(TCppMethod_t method, TCppObject_t self, size_t nargs, void *args, TCppType_t result_type)
bool IsPointerType(TCppType_t type)
std::string GetMethodArgName(TCppMethod_t, TCppIndex_t iarg)
void GetFnTypeSig(TCppType_t fn_type, std::vector< TCppType_t > &arg_types)
TCppFuncAddr_t GetFunctionAddress(TCppMethod_t method, bool check_enabled=true)
long long GetEnumDataValue(TCppScope_t scope)
size_t SizeOf(TCppScope_t klass)
std::string GetDoxygenComment(TCppScope_t scope, bool strip_markers=true)
TCppType_t GetMethodReturnType(TCppMethod_t)
TCppType_t ResolveType(TCppType_t cppitem_name)
TCppScope_t GetUnderlyingScope(TCppScope_t scope)
std::string GetMethodSignature(TCppMethod_t, bool show_formal_args, TCppIndex_t max_args=(TCppIndex_t) -1)
bool IsExplicit(TCppMethod_t method)
TCppScope_t GetGlobalScope()
std::string GetTemplatedMethodName(TCppScope_t scope, TCppIndex_t imeth)
std::string GetFullName(TCppScope_t)
TCppScope_t GetTypeScope(TCppScope_t klass)
bool IsTemplate(TCppScope_t scope)
bool IsDestructor(TCppMethod_t method)
std::vector< TCppScope_t > GetEnumConstants(TCppScope_t scope)
bool Compile(const std::string &code, bool silent=false)
TCppType_t GetPointerType(TCppType_t type)
std::vector< TCppMethod_t > GetMethodsFromName(TCppScope_t scope, const std::string &name)
std::string ResolveEnum(TCppScope_t enum_scope)
bool IsDefaultConstructable(TCppScope_t scope)
TCppObject_t CallConstructor(TCppMethod_t method, TCppScope_t klass, size_t nargs, void *args)
bool IsDeletedMethod(TCppMethod_t method)
bool IsLValueReferenceType(TCppType_t type)
bool IsNamespace(TCppScope_t scope)
bool IsTemplatedMethod(TCppMethod_t method)
void DumpScope(TCppScope_t scope)
TCppScope_t GetScopeFromType(TCppType_t type)
TCppType_t GetFnTypeFromStdFn(TCppType_t fn_type)
std::string GetBaseName(TCppScope_t klass, TCppIndex_t ibase)
TCppType_t GetRealType(TCppType_t type)
TCppIndex_t GetNumBasesLongestBranch(TCppScope_t klass)
TCppScope_t GetScope(const std::string &scope_name, TCppScope_t parent_scope=TCppScope_t{})
TCppType_t GetEnumConstantType(TCppScope_t scope)
bool IsSameType(TCppType_t typ1, TCppType_t typ2)
bool IsEnumConstant(TCppScope_t scope)
std::string GetFinalName(TCppScope_t type)
bool IsProtectedData(TCppScope_t var)
bool IsLambdaClass(TCppType_t type)
bool IsConstMethod(TCppMethod_t)
ptrdiff_t GetBaseOffset(TCppScope_t derived, TCppScope_t base, TCppObject_t address, int direction, bool rerror=false)
TCppObject_t Construct(TCppScope_t scope, void *arena=nullptr)
bool IsPrivateData(TCppScope_t var)
void Deallocate(TCppScope_t scope, TCppObject_t instance)
bool IsMutablePtrRefType(TCppType_t type)
size_t GetFunctionArgSizeof()
bool IsVariable(TCppScope_t scope)
bool IsSmartPtr(TCppScope_t klass)
std::string GetMethodArgDefault(TCppMethod_t, TCppIndex_t iarg)
bool IsStaticMethod(TCppMethod_t method)
char * CallS(TCppMethod_t method, TCppObject_t self, size_t nargs, void *args, size_t *length)
bool IsRValueReferenceType(TCppType_t type)
TCppType_t GetComplexType(const std::string &element_type)
bool GetSmartPtrInfo(const std::string &, TCppScope_t *raw, TCppMethod_t *deref)
std::vector< TCppScope_t > GetUsingNamespaces(TCppScope_t)
bool IsPublicMethod(TCppMethod_t method)
TCppType_t GetType(const std::string &name, bool enable_slow_lookup=false)
bool IsAggregate(TCppScope_t type)
std::string GetScopedFinalName(TCppScope_t type)
void GetAllCppNames(TCppScope_t scope, std::set< std::string > &cppnames)
size_t GetFunctionArgTypeoffset()
std::string GetDatamemberTypeAsString(TCppScope_t var)
TCppType_t ResolveEnumReferenceType(TCppType_t type)
std::vector< long int > GetDimensions(TCppType_t type)
bool IsEnumType(TCppType_t type)
bool IsComplete(TCppScope_t type)
TCppScope_t InstantiateTemplate(TCppScope_t tmpl, Cpp::TemplateArgInfo *args, size_t args_size)
union cppjit::cpyrt::Parameter::Value fValue