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