Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TClingCallFunc.cxx
Go to the documentation of this file.
1// root/core/meta
2// vim: sw=3
3// Author: Paul Russo 30/07/2012
4// Author: Vassil Vassilev 9/02/2013
5
6/*************************************************************************
7 * Copyright (C) 1995-2023, Rene Brun and Fons Rademakers. *
8 * All rights reserved. *
9 * *
10 * For the licensing terms see $ROOTSYS/LICENSE. *
11 * For the list of contributors see $ROOTSYS/README/CREDITS. *
12 *************************************************************************/
13
14/** \class TClingCallFunc
15Emulation of the CINT CallFunc class.
16
17The CINT C++ interpreter provides an interface for calling
18functions through the generated wrappers in dictionaries with
19the CallFunc class. This class provides the same functionality,
20using an interface as close as possible to CallFunc but the
21function metadata and calling service comes from the Cling
22C++ interpreter and the Clang C++ compiler, not CINT.
23*/
24
25#include "TClingCallFunc.h"
26
27#include "TClingClassInfo.h"
28#include "TClingMethodInfo.h"
29#include "TClingUtils.h"
30
31#include "TError.h"
32#include "TCling.h"
33
34#include "TInterpreter.h"
35
36#include "cling/Interpreter/CompilationOptions.h"
37#include "cling/Interpreter/Interpreter.h"
38#include "cling/Interpreter/LookupHelper.h"
39#include "cling/Interpreter/Transaction.h"
40#include "cling/Interpreter/Value.h"
41#include "cling/Utils/AST.h"
42
43#include "clang/AST/ASTContext.h"
44#include "clang/AST/Decl.h"
45#include "clang/AST/DeclCXX.h"
46#include "clang/AST/GlobalDecl.h"
47#include "clang/AST/PrettyPrinter.h"
48#include "clang/AST/QualTypeNames.h"
49#include "clang/AST/RecordLayout.h"
50#include "clang/AST/Type.h"
51#include "clang/Frontend/CompilerInstance.h"
52#include "clang/Lex/Preprocessor.h"
53#include "clang/Sema/Sema.h"
54#include "clang/Sema/Lookup.h"
55
56#include "llvm/ADT/APInt.h"
57#include "llvm/ExecutionEngine/ExecutionEngine.h"
58#include "llvm/ExecutionEngine/GenericValue.h"
59#include "llvm/Support/Casting.h"
60#include "llvm/Support/raw_ostream.h"
61#include "llvm/IR/LLVMContext.h"
62#include "llvm/IR/DerivedTypes.h"
63#include "llvm/IR/Function.h"
64#include "llvm/IR/GlobalValue.h"
65#include "llvm/IR/Module.h"
66#include "llvm/IR/Type.h"
67
68#include "clang/Sema/SemaInternal.h"
69
70#include <map>
71#include <string>
72#include <sstream>
73
74using namespace ROOT;
75using namespace clang;
76using llvm::APSInt, llvm::raw_string_ostream;
77using std::string, std::map, std::ostringstream, std::make_pair;
78
79static unsigned long long gWrapperSerial = 0LL;
80static const string kIndentString(" ");
81
82static
83inline
84void
85indent(ostringstream &buf, int indent_level)
86{
87 for (int i = 0; i < indent_level; ++i) {
88 buf << kIndentString;
89 }
90}
91
92static
93void
94EvaluateExpr(cling::Interpreter &interp, const Expr *E, cling::Value &V)
95{
96 // Evaluate an Expr* and return its cling::Value
97 ASTContext &C = interp.getCI()->getASTContext();
98 clang::Expr::EvalResult evalRes;
99 if (E->EvaluateAsInt(evalRes, C, /*AllowSideEffects*/Expr::SE_NoSideEffects)) {
100 // FIXME: Find the right type or make sure we have an interface to update
101 // the clang::Type in the cling::Value
102 APSInt res = evalRes.Val.getInt();
103 // IntTy or maybe better E->getType()?
104 V = cling::Value(C.IntTy, interp);
105 // We must use the correct signedness otherwise the zero extension
106 // fails if the actual type is strictly less than long long.
107 if (res.isSigned())
108 V.setLongLong(res.getSExtValue());
109 else
110 V.setULongLong(res.getZExtValue());
111 return;
112 }
113 // TODO: Build a wrapper around the expression to avoid decompilation and
114 // compilation and other string operations.
115 PrintingPolicy Policy(C.getPrintingPolicy());
116 Policy.SuppressTagKeyword = true;
117 Policy.SuppressUnwrittenScope = false;
118 Policy.SuppressInitializers = false;
119 Policy.AnonymousTagLocations = false;
120 string buf;
121 raw_string_ostream out(buf);
122 E->printPretty(out, /*Helper=*/nullptr, Policy, /*Indentation=*/0);
123 out << ';'; // no value printing
124 out.flush();
125 // Evaluate() will set V to invalid if evaluation fails.
126 interp.evaluate(buf, V);
127}
128
130{
131 // This function is non-const to use caching overload of GetDecl()!
132 return GetDecl()->getMinRequiredArguments();
133}
134
135void *TClingCallFunc::compile_wrapper(const string &wrapper_name, const string &wrapper,
136 bool withAccessControl/*=true*/)
137{
138 return fInterp->compileFunction(wrapper_name, wrapper, false /*ifUnique*/,
140}
141
142static void GetTypeAsString(QualType QT, string& type_name, ASTContext &C,
143 PrintingPolicy Policy) {
144
145 // FIXME: Take the code here https://github.com/root-project/root/blob/550fb2644f3c07d1db72b9b4ddc4eba5a99ddc12/interpreter/cling/lib/Utils/AST.cpp#L316-L350
146 // to make hist/histdrawv7/test/histhistdrawv7testUnit work into
147 // QualTypeNames.h in clang
148 //type_name = clang::TypeName::getFullyQualifiedName(QT, C, Policy);
149 cling::utils::Transform::Config Config;
150 QT = cling::utils::Transform::GetPartiallyDesugaredType(C, QT, Config, /*fullyQualify=*/true);
151 QT.getAsStringInternal(type_name, Policy);
152}
153
154static void GetDeclName(const clang::Decl *D, ASTContext &Context, std::string &name)
155{
156 // Helper to extract a fully qualified name from a Decl
157
158 PrintingPolicy Policy(Context.getPrintingPolicy());
159 Policy.SuppressTagKeyword = true;
160 Policy.SuppressUnwrittenScope = true;
161 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
162 // This is a class, struct, or union member.
163 QualType QT(TD->getTypeForDecl(), 0);
164 GetTypeAsString(QT, name, Context, Policy);
165 } else if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
166 // This is a namespace member.
167 raw_string_ostream stream(name);
168 ND->getNameForDiagnostic(stream, Policy, /*Qualified=*/true);
169 stream.flush();
170 }
171}
172
173void TClingCallFunc::collect_type_info(QualType &QT, ostringstream &typedefbuf, std::ostringstream &callbuf,
175 bool forArgument)
176{
177 //
178 // Collect information about type type of a function parameter
179 // needed for building the wrapper function.
180 //
181 const FunctionDecl *FD = GetDecl();
182 ASTContext &C = FD->getASTContext();
183 PrintingPolicy Policy(C.getPrintingPolicy());
185 if (QT->isRecordType() && forArgument) {
186 GetTypeAsString(QT, type_name, C, Policy);
187 return;
188 }
189 if (QT->isFunctionPointerType()) {
190 string fp_typedef_name;
191 {
192 ostringstream nm;
193 nm << "FP" << gWrapperSerial++;
194 type_name = nm.str();
195 raw_string_ostream OS(fp_typedef_name);
196 QT.print(OS, Policy, type_name);
197 OS.flush();
198 }
200 typedefbuf << "typedef " << fp_typedef_name << ";\n";
201 return;
202 } else if (QT->isMemberPointerType()) {
203 string mp_typedef_name;
204 {
205 ostringstream nm;
206 nm << "MP" << gWrapperSerial++;
207 type_name = nm.str();
208 raw_string_ostream OS(mp_typedef_name);
209 QT.print(OS, Policy, type_name);
210 OS.flush();
211 }
213 typedefbuf << "typedef " << mp_typedef_name << ";\n";
214 return;
215 } else if (QT->isPointerType()) {
216 isPointer = true;
217 QT = cast<clang::PointerType>(QT)->getPointeeType();
218 } else if (QT->isReferenceType()) {
219 if (QT->isRValueReferenceType()) refType = kRValueReference;
221 QT = cast<ReferenceType>(QT)->getPointeeType();
222 }
223 // Fall through for the array type to deal with reference/pointer ro array type.
224 if (QT->isArrayType()) {
225 string ar_typedef_name;
226 {
227 ostringstream ar;
228 ar << "AR" << gWrapperSerial++;
229 type_name = ar.str();
230 raw_string_ostream OS(ar_typedef_name);
231 QT.print(OS, Policy, type_name);
232 OS.flush();
233 }
235 typedefbuf << "typedef " << ar_typedef_name << ";\n";
236 return;
237 }
238 GetTypeAsString(QT, type_name, C, Policy);
239}
240
241static bool IsCopyConstructorDeleted(QualType QT)
242{
243 CXXRecordDecl *RD = QT->getAsCXXRecordDecl();
244 if (!RD) {
245 // For types that are not C++ records (such as PODs), we assume that they are copyable, ie their copy constructor
246 // is not deleted.
247 return false;
248 }
249
250 RD = RD->getDefinition();
251 assert(RD && "expecting a definition");
252
253 if (RD->hasSimpleCopyConstructor())
254 return false;
255
256 for (auto *Ctor : RD->ctors()) {
257 if (Ctor->isCopyConstructor()) {
258 return Ctor->isDeleted();
259 }
260 }
261
262 assert(0 && "did not find a copy constructor?");
263 // Should never happen and the return value is somewhat arbitrary, but we did not see a deleted copy ctor. The user
264 // will be told if the generated code doesn't compile.
265 return false;
266}
267
268void TClingCallFunc::make_narg_ctor(const unsigned N, ostringstream &typedefbuf,
269 ostringstream &callbuf, const string &class_name,
270 int indent_level)
271{
272 // Make a code string that follows this pattern:
273 //
274 // new ClassName(args...)
275 //
276 const FunctionDecl *FD = GetDecl();
277
278 callbuf << "new " << class_name << "(";
279
280 // IsCopyConstructorDeleted could trigger deserialization of decls.
281 cling::Interpreter::PushTransactionRAII RAII(fInterp);
282
283 for (unsigned i = 0U; i < N; ++i) {
284 const ParmVarDecl *PVD = FD->getParamDecl(i);
285 QualType Ty = PVD->getType();
286 QualType QT = Ty.getCanonicalType();
287 string type_name;
289 bool isPointer = false;
292 if (i) {
293 callbuf << ',';
294 if (i % 2) {
295 callbuf << ' ';
296 } else {
297 callbuf << "\n";
299 }
300 }
301 if (refType != kNotReference) {
302 callbuf << "(" << type_name.c_str() <<
303 (refType == kLValueReference ? "&" : "&&") << ")*(" << type_name.c_str() << "*)args["
304 << i << "]";
305 } else if (isPointer) {
306 callbuf << "*(" << type_name.c_str() << "**)args["
307 << i << "]";
308 } else {
309 // By-value construction: Figure out if the type can be copy-constructed. This is tricky and cannot be done in
310 // a fully reliable way, also because std::vector<T> always defines a copy constructor, even if the type T is
311 // only moveable. As a heuristic, we only check if the copy constructor is deleted, or would be if implicit.
312 bool Move = IsCopyConstructorDeleted(QT);
313 if (Move) {
314 callbuf << "static_cast<" << type_name << "&&>(";
315 }
316 callbuf << "*(" << type_name.c_str() << "*)args[" << i << "]";
317 if (Move) {
318 callbuf << ")";
319 }
320 }
321 }
322 callbuf << ")";
323}
324
325void TClingCallFunc::make_narg_call(const std::string &return_type, const unsigned N, ostringstream &typedefbuf,
326 ostringstream &callbuf, const string &class_name, int indent_level)
327{
328 //
329 // Make a code string that follows this pattern:
330 //
331 // ((<class>*)obj)-><method>(*(<arg-i-type>*)args[i], ...)
332 //
333 const FunctionDecl *FD = GetDecl();
334
335 // Sometimes it's necessary that we cast the function we want to call first
336 // to its explicit function type before calling it. This is supposed to prevent
337 // that we accidentially ending up in a function that is not the one we're
338 // supposed to call here (e.g. because the C++ function lookup decides to take
339 // another function that better fits).
340 // This method has some problems, e.g. when we call a function with default
341 // arguments and we don't provide all arguments, we would fail with this pattern.
342 // Same applies with member methods which seem to cause parse failures even when
343 // we supply the object parameter.
344 // Therefore we only use it in cases where we know it works and set this variable
345 // to true when we do.
346 bool ShouldCastFunction = !isa<CXXMethodDecl>(FD) && N == FD->getNumParams();
347 if (ShouldCastFunction) {
348 callbuf << "(";
349 callbuf << "(";
350 callbuf << return_type << " (&)";
351 {
352 callbuf << "(";
353 for (unsigned i = 0U; i < N; ++i) {
354 if (i) {
355 callbuf << ',';
356 if (i % 2) {
357 callbuf << ' ';
358 } else {
359 callbuf << "\n";
361 }
362 }
363 const ParmVarDecl *PVD = FD->getParamDecl(i);
364 QualType Ty = PVD->getType();
365 QualType QT = Ty.getCanonicalType();
366 std::string arg_type;
367 ASTContext &C = FD->getASTContext();
368 GetTypeAsString(QT, arg_type, C, C.getPrintingPolicy());
369 callbuf << arg_type;
370 }
371 if (FD->isVariadic())
372 callbuf << ", ...";
373 callbuf << ")";
374 }
375
376 callbuf << ")";
377 }
378
380 // This is a class, struct, or union member.
381 if (MD->isConst())
382 callbuf << "((const " << class_name << "*)obj)->";
383 else
384 callbuf << "((" << class_name << "*)obj)->";
385 } else if (const NamedDecl *ND =
387 // This is a namespace member.
388 (void) ND;
389 callbuf << class_name << "::";
390 }
391 // callbuf << fMethod->Name() << "(";
392 {
393 std::string name;
394 {
395 llvm::raw_string_ostream stream(name);
396 FD->getNameForDiagnostic(stream, FD->getASTContext().getPrintingPolicy(), /*Qualified=*/false);
397 }
398 callbuf << name;
399 }
400 if (ShouldCastFunction) callbuf << ")";
401
402 callbuf << "(";
403
404 // IsCopyConstructorDeleted could trigger deserialization of decls.
405 cling::Interpreter::PushTransactionRAII RAII(fInterp);
406
407 for (unsigned i = 0U; i < N; ++i) {
408 const ParmVarDecl *PVD = FD->getParamDecl(i);
409 QualType Ty = PVD->getType();
410 QualType QT = Ty.getCanonicalType();
411 string type_name;
413 bool isPointer = false;
415
416 if (i) {
417 callbuf << ',';
418 if (i % 2) {
419 callbuf << ' ';
420 } else {
421 callbuf << "\n";
423 }
424 }
425
426 if (refType != kNotReference) {
427 callbuf << "(" << type_name.c_str() <<
428 (refType == kLValueReference ? "&" : "&&") << ")*(" << type_name.c_str() << "*)args["
429 << i << "]";
430 } else if (isPointer) {
431 callbuf << "*(" << type_name.c_str() << "**)args["
432 << i << "]";
433 } else {
434 // By-value construction: Figure out if the type can be copy-constructed. This is tricky and cannot be done in
435 // a fully reliable way, also because std::vector<T> always defines a copy constructor, even if the type T is
436 // only moveable. As a heuristic, we only check if the copy constructor is deleted, or would be if implicit.
437 bool Move = IsCopyConstructorDeleted(QT);
438 if (Move) {
439 callbuf << "static_cast<" << type_name << "&&>(";
440 }
441 callbuf << "*(" << type_name.c_str() << "*)args[" << i << "]";
442 if (Move) {
443 callbuf << ")";
444 }
445 }
446 }
447 callbuf << ")";
448}
449
450void TClingCallFunc::make_narg_ctor_with_return(const unsigned N, const string &class_name,
451 ostringstream &buf, int indent_level)
452{
453 // Make a code string that follows this pattern:
454 //
455 // if (ret) {
456 // (*(ClassName**)ret) = new ClassName(args...);
457 // }
458 // else {
459 // new ClassName(args...);
460 // }
461 //
462 indent(buf, indent_level);
463 buf << "if (ret) {\n";
464 ++indent_level;
465 {
466 ostringstream typedefbuf;
467 ostringstream callbuf;
468 //
469 // Write the return value assignment part.
470 //
472 callbuf << "(*(" << class_name << "**)ret) = ";
473 //
474 // Write the actual new expression.
475 //
477 //
478 // End the new expression statement.
479 //
480 callbuf << ";\n";
482 callbuf << "return;\n";
483 //
484 // Output the whole new expression and return statement.
485 //
486 buf << typedefbuf.str() << callbuf.str();
487 }
488 --indent_level;
489 for (int i = 0; i < indent_level; ++i) {
490 buf << kIndentString;
491 }
492 buf << "}\n";
493 for (int i = 0; i < indent_level; ++i) {
494 buf << kIndentString;
495 }
496 buf << "else {\n";
497 ++indent_level;
498 {
499 ostringstream typedefbuf;
500 ostringstream callbuf;
501 for (int i = 0; i < indent_level; ++i) {
503 }
505 callbuf << ";\n";
506 for (int i = 0; i < indent_level; ++i) {
508 }
509 callbuf << "return;\n";
510 buf << typedefbuf.str() << callbuf.str();
511 }
512 --indent_level;
513 for (int i = 0; i < indent_level; ++i) {
514 buf << kIndentString;
515 }
516 buf << "}\n";
517}
518
519///////////////////////////////////////////////////////////////////////////////
520// Returns the DeclContext corresponding to fMethod's Decl.
521// \Note that this might be a FunctionDecl or a UsingShadowDecl; we use the
522// DeclContext of the UsingShadowDecl e.g. for constructing a derived class
523// object, even if invoking a function made available by a using declaration
524// of a constructor of a base class (ROOT-11010).
525
526const clang::DeclContext *TClingCallFunc::GetDeclContext() const {
527 return fMethod->GetDecl()->getDeclContext();
528}
529
531{
532 const FunctionDecl *FD = GetDecl();
533 assert(FD && "generate_wrapper called without a function decl!");
534 //
535 // Get the class or namespace name.
536 //
537 string class_name;
538 ASTContext &Context = FD->getASTContext();
539 const clang::DeclContext *DC = GetDeclContext();
541 //
542 // Check to make sure that we can
543 // instantiate and codegen this function.
544 //
545 bool needInstantiation = false;
546 const FunctionDecl *Definition = nullptr;
547 if (!FD->isDefined(Definition)) {
548 FunctionDecl::TemplatedKind TK = FD->getTemplatedKind();
549 switch (TK) {
550 case FunctionDecl::TK_NonTemplate: {
551 // Ordinary function, not a template specialization.
552 // Note: This might be ok, the body might be defined
553 // in a library, and all we have seen is the
554 // header file.
555 //::Error("TClingCallFunc::make_wrapper",
556 // "Cannot make wrapper for a function which is "
557 // "declared but not defined!");
558 // return 0;
559 } break;
560 case FunctionDecl::TK_FunctionTemplate: {
561 // This decl is actually a function template,
562 // not a function at all.
563 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a function template!");
564 return 0;
565 } break;
566 case FunctionDecl::TK_MemberSpecialization: {
567 // This function is the result of instantiating an ordinary
568 // member function of a class template, or of instantiating
569 // an ordinary member function of a class member of a class
570 // template, or of specializing a member function template
571 // of a class template, or of specializing a member function
572 // template of a class member of a class template.
573 if (!FD->isTemplateInstantiation()) {
574 // We are either TSK_Undeclared or
575 // TSK_ExplicitSpecialization.
576 // Note: This might be ok, the body might be defined
577 // in a library, and all we have seen is the
578 // header file.
579 //::Error("TClingCallFunc::make_wrapper",
580 // "Cannot make wrapper for a function template "
581 // "explicit specialization which is declared "
582 // "but not defined!");
583 // return 0;
584 break;
585 }
586 const FunctionDecl *Pattern = FD->getTemplateInstantiationPattern();
587 if (!Pattern) {
588 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a member function "
589 "instantiation with no pattern!");
590 return 0;
591 }
592 FunctionDecl::TemplatedKind PTK = Pattern->getTemplatedKind();
593 TemplateSpecializationKind PTSK = Pattern->getTemplateSpecializationKind();
594 if (
595 // The pattern is an ordinary member function.
596 (PTK == FunctionDecl::TK_NonTemplate) ||
597 // The pattern is an explicit specialization, and
598 // so is not a template.
599 ((PTK != FunctionDecl::TK_FunctionTemplate) &&
601 // Note: This might be ok, the body might be defined
602 // in a library, and all we have seen is the
603 // header file.
604 break;
605 } else if (!Pattern->hasBody()) {
606 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a member function "
607 "instantiation with no body!");
608 return 0;
609 }
610 if (FD->isImplicitlyInstantiable()) {
611 needInstantiation = true;
612 }
613 } break;
614 case FunctionDecl::TK_FunctionTemplateSpecialization: {
615 // This function is the result of instantiating a function
616 // template or possibly an explicit specialization of a
617 // function template. Could be a namespace scope function or a
618 // member function.
619 if (!FD->isTemplateInstantiation()) {
620 // We are either TSK_Undeclared or
621 // TSK_ExplicitSpecialization.
622 // Note: This might be ok, the body might be defined
623 // in a library, and all we have seen is the
624 // header file.
625 //::Error("TClingCallFunc::make_wrapper",
626 // "Cannot make wrapper for a function template "
627 // "explicit specialization which is declared "
628 // "but not defined!");
629 // return 0;
630 break;
631 }
632 const FunctionDecl *Pattern = FD->getTemplateInstantiationPattern();
633 if (!Pattern) {
634 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a function template"
635 "instantiation with no pattern!");
636 return 0;
637 }
638 FunctionDecl::TemplatedKind PTK = Pattern->getTemplatedKind();
639 TemplateSpecializationKind PTSK = Pattern->getTemplateSpecializationKind();
640 if (
641 // The pattern is an ordinary member function.
642 (PTK == FunctionDecl::TK_NonTemplate) ||
643 // The pattern is an explicit specialization, and
644 // so is not a template.
645 ((PTK != FunctionDecl::TK_FunctionTemplate) &&
647 // Note: This might be ok, the body might be defined
648 // in a library, and all we have seen is the
649 // header file.
650 break;
651 }
652 if (!Pattern->hasBody()) {
653 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a function template"
654 "instantiation with no body!");
655 return 0;
656 }
657 if (FD->isImplicitlyInstantiable()) {
658 needInstantiation = true;
659 }
660 } break;
661 case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
662 // This function is the result of instantiating or
663 // specializing a member function of a class template,
664 // or a member function of a class member of a class template,
665 // or a member function template of a class template, or a
666 // member function template of a class member of a class
667 // template where at least some part of the function is
668 // dependent on a template argument.
669 if (!FD->isTemplateInstantiation()) {
670 // We are either TSK_Undeclared or
671 // TSK_ExplicitSpecialization.
672 // Note: This might be ok, the body might be defined
673 // in a library, and all we have seen is the
674 // header file.
675 //::Error("TClingCallFunc::make_wrapper",
676 // "Cannot make wrapper for a dependent function "
677 // "template explicit specialization which is declared "
678 // "but not defined!");
679 // return 0;
680 break;
681 }
682 const FunctionDecl *Pattern = FD->getTemplateInstantiationPattern();
683 if (!Pattern) {
684 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a dependent function template"
685 "instantiation with no pattern!");
686 return 0;
687 }
688 FunctionDecl::TemplatedKind PTK = Pattern->getTemplatedKind();
689 TemplateSpecializationKind PTSK = Pattern->getTemplateSpecializationKind();
690 if (
691 // The pattern is an ordinary member function.
692 (PTK == FunctionDecl::TK_NonTemplate) ||
693 // The pattern is an explicit specialization, and
694 // so is not a template.
695 ((PTK != FunctionDecl::TK_FunctionTemplate) &&
697 // Note: This might be ok, the body might be defined
698 // in a library, and all we have seen is the
699 // header file.
700 break;
701 }
702 if (!Pattern->hasBody()) {
703 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a dependent function template"
704 "instantiation with no body!");
705 return 0;
706 }
707 if (FD->isImplicitlyInstantiable()) {
708 needInstantiation = true;
709 }
710 } break;
711 default: {
712 // Will only happen if clang implementation changes.
713 // Protect ourselves in case that happens.
714 ::Error("TClingCallFunc::make_wrapper", "Unhandled template kind!");
715 return 0;
716 } break;
717 }
718 // We do not set needInstantiation to true in these cases:
719 //
720 // isInvalidDecl()
721 // TSK_Undeclared
722 // TSK_ExplicitInstantiationDefinition
723 // TSK_ExplicitSpecialization && !getClassScopeSpecializationPattern()
724 // TSK_ExplicitInstantiationDeclaration &&
725 // getTemplateInstantiationPattern() &&
726 // PatternDecl->hasBody() &&
727 // !PatternDecl->isInlined()
728 //
729 // Set it true in these cases:
730 //
731 // TSK_ImplicitInstantiation
732 // TSK_ExplicitInstantiationDeclaration && (!getPatternDecl() ||
733 // !PatternDecl->hasBody() || PatternDecl->isInlined())
734 //
735 }
736 if (needInstantiation) {
737 clang::FunctionDecl *FDmod = const_cast<clang::FunctionDecl *>(FD);
738 clang::Sema &S = fInterp->getSema();
739 // Could trigger deserialization of decls.
740 cling::Interpreter::PushTransactionRAII RAII(fInterp);
741 S.InstantiateFunctionDefinition(SourceLocation(), FDmod,
742 /*Recursive=*/true,
743 /*DefinitionRequired=*/true);
744 if (!FD->isDefined(Definition)) {
745 ::Error("TClingCallFunc::make_wrapper", "Failed to force template instantiation!");
746 return 0;
747 }
748 }
749 if (Definition) {
750 FunctionDecl::TemplatedKind TK = Definition->getTemplatedKind();
751 switch (TK) {
752 case FunctionDecl::TK_NonTemplate: {
753 // Ordinary function, not a template specialization.
754 if (Definition->isDeleted()) {
755 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a deleted function!");
756 return 0;
757 } else if (Definition->isLateTemplateParsed()) {
758 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a late template parsed "
759 "function!");
760 return 0;
761 }
762 // else if (Definition->isDefaulted()) {
763 // // Might not have a body, but we can still use it.
764 //}
765 // else {
766 // // Has a body.
767 //}
768 } break;
769 case FunctionDecl::TK_FunctionTemplate: {
770 // This decl is actually a function template,
771 // not a function at all.
772 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a function template!");
773 return 0;
774 } break;
775 case FunctionDecl::TK_MemberSpecialization: {
776 // This function is the result of instantiating an ordinary
777 // member function of a class template or of a member class
778 // of a class template.
779 if (Definition->isDeleted()) {
780 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a deleted member function "
781 "of a specialization!");
782 return 0;
783 } else if (Definition->isLateTemplateParsed()) {
784 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a late template parsed "
785 "member function of a specialization!");
786 return 0;
787 }
788 // else if (Definition->isDefaulted()) {
789 // // Might not have a body, but we can still use it.
790 //}
791 // else {
792 // // Has a body.
793 //}
794 } break;
795 case FunctionDecl::TK_FunctionTemplateSpecialization: {
796 // This function is the result of instantiating a function
797 // template or possibly an explicit specialization of a
798 // function template. Could be a namespace scope function or a
799 // member function.
800 if (Definition->isDeleted()) {
801 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a deleted function "
802 "template specialization!");
803 return 0;
804 } else if (Definition->isLateTemplateParsed()) {
805 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a late template parsed "
806 "function template specialization!");
807 return 0;
808 }
809 // else if (Definition->isDefaulted()) {
810 // // Might not have a body, but we can still use it.
811 //}
812 // else {
813 // // Has a body.
814 //}
815 } break;
816 case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
817 // This function is the result of instantiating or
818 // specializing a member function of a class template,
819 // or a member function of a class member of a class template,
820 // or a member function template of a class template, or a
821 // member function template of a class member of a class
822 // template where at least some part of the function is
823 // dependent on a template argument.
824 if (Definition->isDeleted()) {
825 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a deleted dependent function "
826 "template specialization!");
827 return 0;
828 } else if (Definition->isLateTemplateParsed()) {
829 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a late template parsed "
830 "dependent function template specialization!");
831 return 0;
832 }
833 // else if (Definition->isDefaulted()) {
834 // // Might not have a body, but we can still use it.
835 //}
836 // else {
837 // // Has a body.
838 //}
839 } break;
840 default: {
841 // Will only happen if clang implementation changes.
842 // Protect ourselves in case that happens.
843 ::Error("TClingCallFunc::make_wrapper", "Unhandled template kind!");
844 return 0;
845 } break;
846 }
847 }
849 unsigned num_params = FD->getNumParams();
850 //
851 // Make the wrapper name.
852 //
853 {
854 ostringstream buf;
855 buf << "__cf";
856 // const NamedDecl* ND = dyn_cast<NamedDecl>(FD);
857 // string mn;
858 // fInterp->maybeMangleDeclName(ND, mn);
859 // buf << '_' << mn;
860 buf << '_' << gWrapperSerial++;
861 wrapper_name = buf.str();
862 }
863 //
864 // Write the wrapper code.
865 // FIXME: this should be synthesized into the AST!
866 //
867 int indent_level = 0;
868 ostringstream buf;
869 buf << "#pragma clang diagnostic push\n"
870 "#pragma clang diagnostic ignored \"-Wformat-security\"\n"
871 "__attribute__((used)) "
872 "__attribute__((annotate(\"__cling__ptrcheck(off)\")))\n"
873 "extern \"C\" void ";
874 buf << wrapper_name;
875 buf << "(void* obj, int nargs, void** args, void* ret)\n"
876 "{\n";
877 ++indent_level;
878 if (min_args == num_params) {
879 // No parameters with defaults.
881 } else {
882 // We need one function call clause compiled for every
883 // possible number of arguments per call.
884 for (unsigned N = min_args; N <= num_params; ++N) {
885 indent(buf, indent_level);
886 buf << "if (nargs == " << N << ") {\n";
887 ++indent_level;
889 --indent_level;
890 indent(buf, indent_level);
891 buf << "}\n";
892 }
893 }
894 --indent_level;
895 buf << "}\n"
896 "#pragma clang diagnostic pop";
897 wrapper = buf.str();
898 return 1;
899}
900
901void TClingCallFunc::make_narg_call_with_return(const unsigned N, const string &class_name,
902 ostringstream &buf, int indent_level)
903{
904 // Make a code string that follows this pattern:
905 //
906 // if (ret) {
907 // new (ret) (return_type) ((class_name*)obj)->func(args...);
908 // }
909 // else {
910 // (void)(((class_name*)obj)->func(args...));
911 // }
912 //
913 const FunctionDecl *FD = GetDecl();
915 if (N <= 1 && llvm::isa<UsingShadowDecl>(GetFunctionOrShadowDecl())) {
916 auto SpecMemKind = fInterp->getSema().getSpecialMember(CD);
917 if ((N == 0 && SpecMemKind == clang::Sema::CXXDefaultConstructor) ||
918 (N == 1 &&
919 (SpecMemKind == clang::Sema::CXXCopyConstructor || SpecMemKind == clang::Sema::CXXMoveConstructor))) {
920 // Using declarations cannot inject special members; do not call them
921 // as such. This might happen by using `Base(Base&, int = 12)`, which
922 // is fine to be called as `Derived d(someBase, 42)` but not as
923 // copy constructor of `Derived`.
924 return;
925 }
926 }
928 return;
929 }
930 QualType QT = FD->getReturnType().getCanonicalType();
931 if (QT->isVoidType()) {
932 ostringstream typedefbuf;
933 ostringstream callbuf;
936 callbuf << ";\n";
938 callbuf << "return;\n";
939 buf << typedefbuf.str() << callbuf.str();
940 } else {
941 indent(buf, indent_level);
942
943 string type_name;
945 bool isPointer = false;
946
947 buf << "if (ret) {\n";
948 ++indent_level;
949 {
950 ostringstream typedefbuf;
951 ostringstream callbuf;
952 //
953 // Write the placement part of the placement new.
954 //
956 callbuf << "new (ret) ";
959 //
960 // Write the type part of the placement new.
961 //
962 callbuf << "(" << type_name.c_str();
963 if (refType != kNotReference) {
964 callbuf << "*) (&";
965 type_name += "&";
966 } else if (isPointer) {
967 callbuf << "*) (";
968 type_name += "*";
969 } else {
970 callbuf << ") (";
971 }
972 //
973 // Write the actual function call.
974 //
976 //
977 // End the placement new.
978 //
979 callbuf << ");\n";
981 callbuf << "return;\n";
982 //
983 // Output the whole placement new expression and return statement.
984 //
985 buf << typedefbuf.str() << callbuf.str();
986 }
987 --indent_level;
988 indent(buf, indent_level);
989 buf << "}\n";
990 indent(buf, indent_level);
991 buf << "else {\n";
992 ++indent_level;
993 {
994 ostringstream typedefbuf;
995 ostringstream callbuf;
997 callbuf << "(void)(";
999 callbuf << ");\n";
1001 callbuf << "return;\n";
1002 buf << typedefbuf.str() << callbuf.str();
1003 }
1004 --indent_level;
1005 indent(buf, indent_level);
1006 buf << "}\n";
1007 }
1008}
1009
1011{
1013
1015
1016 const Decl *D = GetFunctionOrShadowDecl();
1017
1018 auto I = gWrapperStore.find(D);
1019 if (I != gWrapperStore.end())
1020 return (tcling_callfunc_Wrapper_t)I->second;
1021
1022 string wrapper_name;
1023 string wrapper;
1024
1025 if (get_wrapper_code(wrapper_name, wrapper) == 0) return nullptr;
1026
1027 //fprintf(stderr, "%s\n", wrapper.c_str());
1028 //
1029 // Compile the wrapper code.
1030 //
1032 if (F) {
1033 gWrapperStore.insert(make_pair(D, F));
1034 } else {
1035 ::Error("TClingCallFunc::make_wrapper",
1036 "Failed to compile\n ==== SOURCE BEGIN ====\n%s\n ==== SOURCE END ====",
1037 wrapper.c_str());
1038 }
1040}
1041
1042void TClingCallFunc::exec(void *address, void *ret)
1043{
1045 const unsigned num_args = fArgVals.size();
1046 {
1048 const FunctionDecl *FD = GetDecl();
1049
1050 // FIXME: Consider the implicit this which is sometimes not passed.
1052 ::Error("TClingCallFunc::exec",
1053 "Not enough arguments provided for %s (%d instead of the minimum %d)",
1054 fMethod->Name(),
1056 return;
1057 } else if (!isa<CXXMethodDecl>(FD) && num_args > FD->getNumParams()) {
1058 ::Error("TClingCallFunc::exec",
1059 "Too many arguments provided for %s (%d instead of the minimum %d)",
1060 fMethod->Name(),
1062 return;
1063 }
1064 if (auto CXXMD = dyn_cast<CXXMethodDecl>(FD))
1065 if (!address && CXXMD && !CXXMD->isStatic() && !isa<CXXConstructorDecl>(FD)) {
1066 ::Error("TClingCallFunc::exec",
1067 "The method %s is called without an object.",
1068 fMethod->Name());
1069 return;
1070 }
1071
1072 vp_ary.reserve(num_args);
1073 for (unsigned i = 0; i < num_args; ++i) {
1074 QualType QT;
1075 // Check if we provided a this parameter.
1076 // FIXME: Currently we do not provide consistently the this pointer at
1077 // index 0 of the call arguments passed to the wrapper.
1078 // In C++ we can still call member functions which do not use it. Eg:
1079 // struct S {int Print() { return printf("a");} }; auto r1 = ((S*)0)->Print();
1080 // This works just fine even though it might be UB...
1081 bool implicitThisPassed = i == 0 && isa<CXXMethodDecl>(FD) && num_args - FD->getNumParams() == 1;
1083 QT = cast<CXXMethodDecl>(FD)->getThisType();
1084 else
1085 QT = FD->getParamDecl(i)->getType();
1086 QT = QT.getCanonicalType();
1087 if (QT->isReferenceType() || QT->isRecordType()) {
1088 // the argument is already a pointer value (points to the same thing
1089 // as the reference or pointing to object passed by value.
1090 vp_ary.push_back(fArgVals[i].getPtr());
1091 } else {
1092 // Check if arguments need readjusting. This can happen if we called
1093 // cling::Value::Create which instantiates to say double but the
1094 // function signature requires a float.
1095 ASTContext &C = FD->getASTContext();
1096 if (QT->isBuiltinType() && !C.hasSameType(QT, fArgVals[i].getType())) {
1097 switch(QT->getAs<BuiltinType>()->getKind()) {
1098 default:
1099 ROOT::TMetaUtils::Error("TClingCallFunc::exec", "Unknown builtin type!");
1100#ifndef NDEBUG
1101 QT->dump();
1102#endif // NDEBUG
1103 break;
1104#define X(type, name) \
1105 case BuiltinType::name: fArgVals[i] = cling::Value::Create(*fInterp, fArgVals[i].castAs<type>()); break;
1107#undef X
1108 }
1109 }
1110 vp_ary.push_back(fArgVals[i].getPtrAddress());
1111 }
1112 }
1113 } // End of scope holding the lock
1114 (*fWrapper)(address, (int)num_args, (void **)vp_ary.data(), ret);
1115}
1116
1117void TClingCallFunc::exec_with_valref_return(void *address, cling::Value &ret)
1118{
1119 const FunctionDecl *FD = GetDecl();
1120
1121 QualType QT;
1122 if (llvm::isa<CXXConstructorDecl>(FD)) {
1124 ASTContext &Context = FD->getASTContext();
1126 QualType ClassTy(TD->getTypeForDecl(), 0);
1127 QT = Context.getLValueReferenceType(ClassTy);
1128 ret = cling::Value(QT, *fInterp);
1129 } else {
1130 QT = FD->getReturnType().getCanonicalType();
1131 ret = cling::Value(QT, *fInterp);
1132
1133 if (QT->isRecordType() || QT->isMemberDataPointerType())
1134 return exec(address, ret.getPtr());
1135 }
1136 exec(address, ret.getPtrAddress());
1137}
1138
1140{
1142
1144 fInterp->getLookupHelper().findArgList(ArgList, exprs,
1145 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
1146 : cling::LookupHelper::NoDiagnostics);
1148 E = exprs.end(); I != E; ++I) {
1149 cling::Value val;
1150 EvaluateExpr(*fInterp, *I, val);
1151 if (!val.isValid()) {
1152 // Bad expression, all done.
1153 ::Error("TClingCallFunc::EvaluateArgList",
1154 "Bad expression in parameter %d of '%s'!",
1155 (int)(I - exprs.begin()),
1156 ArgList.c_str());
1157 return;
1158 }
1159 fArgVals.push_back(val);
1160 }
1161}
1162
1164{
1165 IFacePtr();
1166 if (!fWrapper) {
1167 ::Error("TClingCallFunc::Exec(address, interpVal)",
1168 "Called with no wrapper, not implemented!");
1169 return;
1170 }
1171 if (!interpVal || !interpVal->GetValAddr()) {
1172 exec(address, nullptr);
1173 return;
1174 }
1175 cling::Value *val = reinterpret_cast<cling::Value *>(interpVal->GetValAddr());
1176 exec_with_valref_return(address, *val);
1177}
1178
1179template <typename T>
1181{
1182 IFacePtr();
1183 if (!fWrapper) {
1184 ::Error("TClingCallFunc::ExecT",
1185 "Called with no wrapper, not implemented!");
1186 return 0;
1187 }
1188 cling::Value ret;
1189 exec_with_valref_return(address, ret);
1190 if (ret.isVoid()) {
1191 return 0;
1192 }
1193
1194 if (ret.needsManagedAllocation())
1195 ((TCling *)gCling)->RegisterTemporary(ret);
1196
1197 return ret.castAs<T>();
1198}
1199
1201{
1202 return ExecT<Longptr_t>(address);
1203}
1204
1205long long TClingCallFunc::ExecInt64(void *address)
1206{
1207 return ExecT<long long>(address);
1208}
1209
1210double TClingCallFunc::ExecDouble(void *address)
1211{
1212 return ExecT<double>(address);
1213}
1214
1215void TClingCallFunc::ExecWithArgsAndReturn(void *address, const void *args[] /*= 0*/,
1216 int nargs /*= 0*/, void *ret/*= 0*/)
1217{
1218 IFacePtr();
1219 if (!fWrapper) {
1220 ::Error("TClingCallFunc::ExecWithArgsAndReturn(address, args, ret)",
1221 "Called with no wrapper, not implemented!");
1222 return;
1223 }
1224 (*fWrapper)(address, nargs, const_cast<void **>(args), ret);
1225}
1226
1227void TClingCallFunc::ExecWithReturn(void *address, void *ret/*= 0*/)
1228{
1229 IFacePtr();
1230 if (!fWrapper) {
1231 ::Error("TClingCallFunc::ExecWithReturn(address, ret)",
1232 "Called with no wrapper, not implemented!");
1233 return;
1234 }
1235 exec(address, ret);
1236}
1237
1240 const std::string &type_name,
1241 void *address /*=0*/, unsigned long nary /*= 0UL*/)
1242{
1243 if (!info->IsValid()) {
1244 ::Error("TClingCallFunc::ExecDefaultConstructor", "Invalid class info!");
1245 return nullptr;
1246 }
1247 // this function's clients assume nary = 0 for operator new and nary > 0 for array new. JitCall expects
1248 // the number of objects you want to construct; nary = 1 constructs a single object
1249 // This handles this difference in semantics
1250 if (nary == 0)
1251 nary = 1;
1252
1253 clang::Decl *D = const_cast<clang::Decl *>(info->GetDecl());
1254
1255 if (Cpp::IsClass(D) || Cpp::IsConstructor(D)) {
1257 return Cpp::Construct(D, address, nary);
1258 }
1259
1260 ::Error("TClingCallFunc::ExecDefaultConstructor", "ClassInfo missing a valid Scope/Constructor");
1261 return nullptr;
1262}
1263
1264void TClingCallFunc::ExecDestructor(const TClingClassInfo *info, void *address /*=0*/,
1265 unsigned long nary /*= 0UL*/, bool withFree /*= true*/)
1266{
1267 if (!info->IsValid()) {
1268 ::Error("TClingCallFunc::ExecDestructor", "Invalid class info!");
1269 return;
1270 }
1271
1273
1274 if (Cpp::Destruct(address, info->GetDecl(), nary, withFree))
1275 return;
1276
1277 ::Error("TClingCallFunc::ExecDestructor", "Called with no wrapper, not implemented!");
1278}
1279
1282{
1283 return new TClingMethodInfo(*fMethod);
1284}
1285
1287{
1288 fMethod.reset();
1289 fWrapper = nullptr;
1290 fDecl = nullptr;
1292 ResetArg();
1293}
1294
1296{
1297 Init();
1298 fMethod = std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(minfo));
1299}
1300
1301void TClingCallFunc::Init(std::unique_ptr<TClingMethodInfo> minfo)
1302{
1303 Init();
1304 fMethod = std::move(minfo);
1305}
1306
1308{
1309 if (!IsValid()) {
1310 return nullptr;
1311 }
1312
1313 if (!fWrapper)
1315
1316 return (void *)fWrapper.load();
1317}
1318
1320{
1321 if (!fMethod) {
1322 return false;
1323 }
1324 return fMethod->IsValid();
1325}
1326
1328{
1329 if (!IsValid()) {
1330 ::Error("TClingCallFunc::IFacePtr(kind)",
1331 "Attempt to get interface while invalid.");
1333 }
1334
1335 if (!fWrapper)
1337
1339}
1340
1341
1343{
1344 fArgVals.clear();
1345}
1346
1348{
1349 ResetArg();
1350 for (int i = 0; i < nparam; ++i) {
1351 SetArg(paramArr[i]);
1352 }
1353}
1354
1355void TClingCallFunc::SetArgs(const char *params)
1356{
1357 ResetArg();
1358 EvaluateArgList(params);
1359}
1360
1361void TClingCallFunc::SetFunc(const TClingClassInfo *info, const char *method, const char *arglist,
1363{
1364 SetFunc(info, method, arglist, false, poffset);
1365}
1366
1367void TClingCallFunc::SetFunc(const TClingClassInfo *info, const char *method, const char *arglist,
1369{
1370 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(fInterp)));
1371 if (poffset) {
1372 *poffset = 0L;
1373 }
1374 ResetArg();
1375 if (!info->IsValid()) {
1376 ::Error("TClingCallFunc::SetFunc", "Class info is invalid!");
1377 return;
1378 }
1379 if (!strcmp(arglist, ")")) {
1380 // CINT accepted a single right paren as meaning no arguments.
1381 arglist = "";
1382 }
1383 *fMethod = info->GetMethodWithArgs(method, arglist, objectIsConst, poffset);
1384 if (!fMethod->IsValid()) {
1385 //::Error("TClingCallFunc::SetFunc", "Could not find method %s(%s)", method,
1386 // arglist);
1387 return;
1388 }
1389 // FIXME: The arglist was already parsed by the lookup, we should
1390 // enhance the lookup to return the resulting expression
1391 // list so we do not need to parse it again here.
1393}
1394
1396{
1397 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(*info)));
1398 ResetArg();
1399 if (!fMethod->IsValid()) {
1400 return;
1401 }
1402}
1403
1405 const char *proto, Longptr_t *poffset,
1406 EFunctionMatchMode mode/*=kConversionMatch*/)
1407{
1409}
1410
1412 const char *proto, bool objectIsConst, Longptr_t *poffset,
1413 EFunctionMatchMode mode/*=kConversionMatch*/)
1414{
1415 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(fInterp)));
1416 if (poffset) {
1417 *poffset = 0L;
1418 }
1419 ResetArg();
1420 if (!info->IsValid()) {
1421 ::Error("TClingCallFunc::SetFuncProto", "Class info is invalid!");
1422 return;
1423 }
1424 *fMethod = info->GetMethod(method, proto, objectIsConst, poffset, mode);
1425 if (!fMethod->IsValid()) {
1426 //::Error("TClingCallFunc::SetFuncProto", "Could not find method %s(%s)",
1427 // method, proto);
1428 return;
1429 }
1430}
1431
1433 const llvm::SmallVectorImpl<clang::QualType> &proto, Longptr_t *poffset,
1434 EFunctionMatchMode mode/*=kConversionMatch*/)
1435{
1437}
1438
1440 const llvm::SmallVectorImpl<clang::QualType> &proto,
1442 EFunctionMatchMode mode/*=kConversionMatch*/)
1443{
1444 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(fInterp)));
1445 if (poffset) {
1446 *poffset = 0L;
1447 }
1448 ResetArg();
1449 if (!info->IsValid()) {
1450 ::Error("TClingCallFunc::SetFuncProto", "Class info is invalid!");
1451 return;
1452 }
1453 *fMethod = info->GetMethod(method, proto, objectIsConst, poffset, mode);
1454 if (!fMethod->IsValid()) {
1455 //::Error("TClingCallFunc::SetFuncProto", "Could not find method %s(%s)",
1456 // method, proto);
1457 return;
1458 }
1459}
1460
long Longptr_t
Integer large enough to hold a pointer (platform-dependent)
Definition RtypesCore.h:89
static void EvaluateExpr(cling::Interpreter &interp, const Expr *E, cling::Value &V)
static bool IsCopyConstructorDeleted(QualType QT)
static void GetTypeAsString(QualType QT, string &type_name, ASTContext &C, PrintingPolicy Policy)
static unsigned long long gWrapperSerial
static void GetDeclName(const clang::Decl *D, ASTContext &Context, std::string &name)
static const string kIndentString(" ")
static void indent(ostringstream &buf, int indent_level)
void(* tcling_callfunc_Wrapper_t)(void *, int, void **, void *)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
#define N
Option_t Option_t TPoint TPoint const char mode
char name[80]
Definition TGX11.cxx:110
R__EXTERN TVirtualMutex * gInterpreterMutex
#define R__LOCKGUARD_CLING(mutex)
R__EXTERN TInterpreter * gCling
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:627
const char * proto
Definition civetweb.c:18822
const_iterator begin() const
const_iterator end() const
void * ExecDefaultConstructor(const TClingClassInfo *info, ROOT::TMetaUtils::EIOCtorCategory kind, const std::string &type_name, void *address=nullptr, unsigned long nary=0UL)
void ExecWithReturn(void *address, void *ret=nullptr)
void exec_with_valref_return(void *address, cling::Value &ret)
std::unique_ptr< TClingMethodInfo > fMethod
Current method, we own.
void collect_type_info(clang::QualType &QT, std::ostringstream &typedefbuf, std::ostringstream &callbuf, std::string &type_name, EReferenceType &refType, bool &isPointer, int indent_level, bool forArgument)
void SetArgs(const char *args)
size_t fMinRequiredArguments
Number of required arguments.
T ExecT(void *address)
size_t CalculateMinRequiredArguments()
double ExecDouble(void *address)
void SetArgArray(Longptr_t *argArr, int narg)
tcling_callfunc_Wrapper_t make_wrapper()
bool IsValid() const
void ExecDestructor(const TClingClassInfo *info, void *address=nullptr, unsigned long nary=0UL, bool withFree=true)
Longptr_t ExecInt(void *address)
const clang::DeclContext * GetDeclContext() const
void * compile_wrapper(const std::string &wrapper_name, const std::string &wrapper, bool withAccessControl=true)
void SetFuncProto(const TClingClassInfo *info, const char *method, const char *proto, Longptr_t *poffset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
TInterpreter::CallFuncIFacePtr_t IFacePtr()
void exec(void *address, void *ret)
std::atomic< tcling_callfunc_Wrapper_t > fWrapper
Pointer to compiled wrapper, we do not own.
void make_narg_ctor(const unsigned N, std::ostringstream &typedefbuf, std::ostringstream &callbuf, const std::string &class_name, int indent_level)
void SetFunc(const TClingClassInfo *info, const char *method, const char *arglist, Longptr_t *poffset)
const clang::FunctionDecl * GetDecl()
void EvaluateArgList(const std::string &ArgList)
const clang::Decl * GetFunctionOrShadowDecl() const
void ExecWithArgsAndReturn(void *address, const void *args[]=0, int nargs=0, void *ret=0)
void Exec(void *address, TInterpreterValue *interpVal=0)
TClingMethodInfo * FactoryMethod() const
int get_wrapper_code(std::string &wrapper_name, std::string &wrapper)
size_t GetMinRequiredArguments()
void SetArg(T arg)
long long ExecInt64(void *address)
cling::Interpreter * fInterp
Cling interpreter, we do not own.
void make_narg_call(const std::string &return_type, const unsigned N, std::ostringstream &typedefbuf, std::ostringstream &callbuf, const std::string &class_name, int indent_level)
const clang::FunctionDecl * fDecl
Decl for the method.
void make_narg_call_with_return(const unsigned N, const std::string &class_name, std::ostringstream &buf, int indent_level)
llvm::SmallVector< cling::Value, 8 > fArgVals
Stored function arguments, we own.
void make_narg_ctor_with_return(const unsigned N, const std::string &class_name, std::ostringstream &buf, int indent_level)
Emulation of the CINT ClassInfo class.
Emulation of the CINT MethodInfo class.
This class defines an interface to the cling C++ interpreter.
Definition TCling.h:102
#define F(x, y, z)
#define I(x, y, z)
void Error(const char *location, const char *fmt,...)
Namespace for new ROOT classes and functions.
EFunctionMatchMode