Logo ROOT  
Reference Guide
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 llvm;
76using namespace clang;
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
1042static std::string PrepareStructorWrapper(const Decl *D, const char *wrapper_prefix, std::string &class_name)
1043{
1044 //
1045 // Get the class or namespace name.
1046 //
1047 ASTContext &Context = D->getASTContext();
1048 GetDeclName(D, Context, class_name);
1049
1050 //
1051 // Make the wrapper name.
1052 //
1053 string wrapper_name;
1054 {
1055 ostringstream buf;
1056 buf << wrapper_prefix;
1057 // const NamedDecl* ND = dyn_cast<NamedDecl>(FD);
1058 // string mn;
1059 // fInterp->maybeMangleDeclName(ND, mn);
1060 // buf << '_dtor_' << mn;
1061 buf << '_' << gWrapperSerial++;
1062 wrapper_name = buf.str();
1063 }
1064
1065 return wrapper_name;
1066}
1067
1069 ROOT::TMetaUtils::EIOCtorCategory kind, const std::string &type_name)
1070{
1071 // Make a code string that follows this pattern:
1072 //
1073 // void
1074 // unique_wrapper_ddd(void** ret, void* arena, unsigned long nary)
1075 // {
1076 // if (!arena) {
1077 // if (!nary) {
1078 // *ret = new ClassName;
1079 // }
1080 // else {
1081 // *ret = new ClassName[nary];
1082 // }
1083 // }
1084 // else {
1085 // if (!nary) {
1086 // *ret = new (arena) ClassName;
1087 // }
1088 // else {
1089 // *ret = new (arena) ClassName[nary];
1090 // }
1091 // }
1092 // }
1093 //
1094 // When I/O constructor used:
1095 //
1096 // void
1097 // unique_wrapper_ddd(void** ret, void* arena, unsigned long nary)
1098 // {
1099 // if (!arena) {
1100 // if (!nary) {
1101 // *ret = new ClassName((TRootIOCtor*)nullptr);
1102 // }
1103 // else {
1104 // char *buf = malloc(nary * sizeof(ClassName));
1105 // for (int k=0;k<nary;++k)
1106 // new (buf + k * sizeof(ClassName)) ClassName((TRootIOCtor*)nullptr);
1107 // *ret = buf;
1108 // }
1109 // }
1110 // else {
1111 // if (!nary) {
1112 // *ret = new (arena) ClassName((TRootIOCtor*)nullptr);
1113 // }
1114 // else {
1115 // for (int k=0;k<nary;++k)
1116 // new ((char *) arena + k * sizeof(ClassName)) ClassName((TRootIOCtor*)nullptr);
1117 // *ret = arena;
1118 // }
1119 // }
1120 // }
1121 //
1122 //
1123 // Note:
1124 //
1125 // If the class is of POD type, the form:
1126 //
1127 // new ClassName;
1128 //
1129 // does not initialize the object at all, and the form:
1130 //
1131 // new ClassName();
1132 //
1133 // default-initializes the object.
1134 //
1135 // We are using the form without parentheses because that is what
1136 // CINT did.
1137 //
1138 //--
1139
1141
1143
1144 auto D = info->GetDecl();
1145 auto I = gCtorWrapperStore.find(D);
1146 if (I != gCtorWrapperStore.end())
1147 return (tcling_callfunc_ctor_Wrapper_t)I->second;
1148
1149 //
1150 // Make the wrapper name.
1151 //
1152 string class_name;
1153 string wrapper_name = PrepareStructorWrapper(D, "__ctor", class_name);
1154
1155 string constr_arg;
1157 constr_arg = string("((") + type_name + "*)nullptr)";
1159 constr_arg = string("(*((") + type_name + "*)arena))";
1160
1161 //
1162 // Write the wrapper code.
1163 //
1164 int indent_level = 0;
1165 ostringstream buf;
1166 buf << "__attribute__((used)) ";
1167 buf << "extern \"C\" void ";
1168 buf << wrapper_name;
1169 buf << "(void** ret, void* arena, unsigned long nary)\n";
1170 buf << "{\n";
1171
1172 // if (!arena) {
1173 // if (!nary) {
1174 // *ret = new ClassName;
1175 // }
1176 // else {
1177 // *ret = new ClassName[nary];
1178 // }
1179 // }
1180 indent(buf, ++indent_level);
1181 buf << "if (!arena) {\n";
1182 indent(buf, ++indent_level);
1183 buf << "if (!nary) {\n";
1184 indent(buf, ++indent_level);
1185 buf << "*ret = new " << class_name << constr_arg << ";\n";
1186 indent(buf, --indent_level);
1187 buf << "}\n";
1188 indent(buf, indent_level);
1189 buf << "else {\n";
1190 indent(buf, ++indent_level);
1191 if (constr_arg.empty()) {
1192 buf << "*ret = new " << class_name << "[nary];\n";
1193 } else {
1194 buf << "char *buf = (char *) malloc(nary * sizeof(" << class_name << "));\n";
1195 indent(buf, indent_level);
1196 buf << "for (int k=0;k<nary;++k)\n";
1197 indent(buf, ++indent_level);
1198 buf << "new (buf + k * sizeof(" << class_name << ")) " << class_name << constr_arg << ";\n";
1199 indent(buf, --indent_level);
1200 buf << "*ret = buf;\n";
1201 }
1202 indent(buf, --indent_level);
1203 buf << "}\n";
1204 indent(buf, --indent_level);
1205 buf << "}\n";
1206 // else {
1207 // if (!nary) {
1208 // *ret = new (arena) ClassName;
1209 // }
1210 // else {
1211 // *ret = new (arena) ClassName[nary];
1212 // }
1213 // }
1214 indent(buf, indent_level);
1215 buf << "else {\n";
1216 indent(buf, ++indent_level);
1217 buf << "if (!nary) {\n";
1218 indent(buf, ++indent_level);
1219 buf << "*ret = new (arena) " << class_name << constr_arg << ";\n";
1220 indent(buf, --indent_level);
1221 buf << "}\n";
1222 indent(buf, indent_level);
1223 buf << "else {\n";
1224 indent(buf, ++indent_level);
1225 if (constr_arg.empty()) {
1226 buf << "*ret = new (arena) " << class_name << "[nary];\n";
1227 } else {
1228 buf << "for (int k=0;k<nary;++k)\n";
1229 indent(buf, ++indent_level);
1230 buf << "new ((char *) arena + k * sizeof(" << class_name << ")) " << class_name << constr_arg << ";\n";
1231 indent(buf, --indent_level);
1232 buf << "*ret = arena;\n";
1233 }
1234 indent(buf, --indent_level);
1235 buf << "}\n";
1236 indent(buf, --indent_level);
1237 buf << "}\n";
1238 // End wrapper.
1239 --indent_level;
1240 buf << "}\n";
1241 // Done.
1242 string wrapper(buf.str());
1243 //fprintf(stderr, "%s\n", wrapper.c_str());
1244 //
1245 // Compile the wrapper code.
1246 //
1248 /*withAccessControl=*/false);
1249 if (F) {
1250 gCtorWrapperStore.insert(make_pair(D, F));
1251 } else {
1252 ::Error("TClingCallFunc::make_ctor_wrapper",
1253 "Failed to compile\n ==== SOURCE BEGIN ====\n%s\n ==== SOURCE END ====",
1254 wrapper.c_str());
1255 }
1257}
1258
1261{
1262 // Make a code string that follows this pattern:
1263 //
1264 // void
1265 // unique_wrapper_ddd(void* obj, unsigned long nary, int withFree)
1266 // {
1267 // if (withFree) {
1268 // if (!nary) {
1269 // delete (ClassName*) obj;
1270 // }
1271 // else {
1272 // delete[] (ClassName*) obj;
1273 // }
1274 // }
1275 // else {
1276 // typedef ClassName DtorName;
1277 // if (!nary) {
1278 // ((ClassName*)obj)->~DtorName();
1279 // }
1280 // else {
1281 // for (unsigned long i = nary - 1; i > -1; --i) {
1282 // (((ClassName*)obj)+i)->~DtorName();
1283 // }
1284 // }
1285 // }
1286 // }
1287 //
1288 //--
1289
1291
1293
1294 const Decl *D = info->GetDecl();
1295 auto I = gDtorWrapperStore.find(D);
1296 if (I != gDtorWrapperStore.end())
1297 return (tcling_callfunc_dtor_Wrapper_t)I->second;
1298
1299 //
1300 // Make the wrapper name.
1301 //
1302 std::string class_name;
1303 string wrapper_name = PrepareStructorWrapper(D, "__dtor", class_name);
1304 //
1305 // Write the wrapper code.
1306 //
1307 int indent_level = 0;
1308 ostringstream buf;
1309 buf << "__attribute__((used)) ";
1310 buf << "extern \"C\" void ";
1311 buf << wrapper_name;
1312 buf << "(void* obj, unsigned long nary, int withFree)\n";
1313 buf << "{\n";
1314 // if (withFree) {
1315 // if (!nary) {
1316 // delete (ClassName*) obj;
1317 // }
1318 // else {
1319 // delete[] (ClassName*) obj;
1320 // }
1321 // }
1322 ++indent_level;
1323 indent(buf, indent_level);
1324 buf << "if (withFree) {\n";
1325 ++indent_level;
1326 indent(buf, indent_level);
1327 buf << "if (!nary) {\n";
1328 ++indent_level;
1329 indent(buf, indent_level);
1330 buf << "delete (" << class_name << "*) obj;\n";
1331 --indent_level;
1332 indent(buf, indent_level);
1333 buf << "}\n";
1334 indent(buf, indent_level);
1335 buf << "else {\n";
1336 ++indent_level;
1337 indent(buf, indent_level);
1338 buf << "delete[] (" << class_name << "*) obj;\n";
1339 --indent_level;
1340 indent(buf, indent_level);
1341 buf << "}\n";
1342 --indent_level;
1343 indent(buf, indent_level);
1344 buf << "}\n";
1345 // else {
1346 // typedef ClassName Nm;
1347 // if (!nary) {
1348 // ((Nm*)obj)->~Nm();
1349 // }
1350 // else {
1351 // for (unsigned long i = nary - 1; i > -1; --i) {
1352 // (((Nm*)obj)+i)->~Nm();
1353 // }
1354 // }
1355 // }
1356 indent(buf, indent_level);
1357 buf << "else {\n";
1358 ++indent_level;
1359 indent(buf, indent_level);
1360 buf << "typedef " << class_name << " Nm;\n";
1361 buf << "if (!nary) {\n";
1362 ++indent_level;
1363 indent(buf, indent_level);
1364 buf << "((Nm*)obj)->~Nm();\n";
1365 --indent_level;
1366 indent(buf, indent_level);
1367 buf << "}\n";
1368 indent(buf, indent_level);
1369 buf << "else {\n";
1370 ++indent_level;
1371 indent(buf, indent_level);
1372 buf << "do {\n";
1373 ++indent_level;
1374 indent(buf, indent_level);
1375 buf << "(((Nm*)obj)+(--nary))->~Nm();\n";
1376 --indent_level;
1377 indent(buf, indent_level);
1378 buf << "} while (nary);\n";
1379 --indent_level;
1380 indent(buf, indent_level);
1381 buf << "}\n";
1382 --indent_level;
1383 indent(buf, indent_level);
1384 buf << "}\n";
1385 // End wrapper.
1386 --indent_level;
1387 buf << "}\n";
1388 // Done.
1389 string wrapper(buf.str());
1390 //fprintf(stderr, "%s\n", wrapper.c_str());
1391 //
1392 // Compile the wrapper code.
1393 //
1395 /*withAccessControl=*/false);
1396 if (F) {
1397 gDtorWrapperStore.insert(make_pair(D, F));
1398 } else {
1399 ::Error("TClingCallFunc::make_dtor_wrapper",
1400 "Failed to compile\n ==== SOURCE BEGIN ====\n%s\n ==== SOURCE END ====",
1401 wrapper.c_str());
1402 }
1403
1405}
1406
1407void TClingCallFunc::exec(void *address, void *ret)
1408{
1410 const unsigned num_args = fArgVals.size();
1411 {
1413 const FunctionDecl *FD = GetDecl();
1414
1415 // FIXME: Consider the implicit this which is sometimes not passed.
1417 ::Error("TClingCallFunc::exec",
1418 "Not enough arguments provided for %s (%d instead of the minimum %d)",
1419 fMethod->Name(),
1421 return;
1422 } else if (!isa<CXXMethodDecl>(FD) && num_args > FD->getNumParams()) {
1423 ::Error("TClingCallFunc::exec",
1424 "Too many arguments provided for %s (%d instead of the minimum %d)",
1425 fMethod->Name(),
1427 return;
1428 }
1429 if (auto CXXMD = dyn_cast<CXXMethodDecl>(FD))
1430 if (!address && CXXMD && !CXXMD->isStatic() && !isa<CXXConstructorDecl>(FD)) {
1431 ::Error("TClingCallFunc::exec",
1432 "The method %s is called without an object.",
1433 fMethod->Name());
1434 return;
1435 }
1436
1437 vp_ary.reserve(num_args);
1438 for (unsigned i = 0; i < num_args; ++i) {
1439 QualType QT;
1440 // Check if we provided a this parameter.
1441 // FIXME: Currently we do not provide consistently the this pointer at
1442 // index 0 of the call arguments passed to the wrapper.
1443 // In C++ we can still call member functions which do not use it. Eg:
1444 // struct S {int Print() { return printf("a");} }; auto r1 = ((S*)0)->Print();
1445 // This works just fine even though it might be UB...
1446 bool implicitThisPassed = i == 0 && isa<CXXMethodDecl>(FD) && num_args - FD->getNumParams() == 1;
1448 QT = cast<CXXMethodDecl>(FD)->getThisType();
1449 else
1450 QT = FD->getParamDecl(i)->getType();
1451 QT = QT.getCanonicalType();
1452 if (QT->isReferenceType() || QT->isRecordType()) {
1453 // the argument is already a pointer value (points to the same thing
1454 // as the reference or pointing to object passed by value.
1455 vp_ary.push_back(fArgVals[i].getPtr());
1456 } else {
1457 // Check if arguments need readjusting. This can happen if we called
1458 // cling::Value::Create which instantiates to say double but the
1459 // function signature requires a float.
1460 ASTContext &C = FD->getASTContext();
1461 if (QT->isBuiltinType() && !C.hasSameType(QT, fArgVals[i].getType())) {
1462 switch(QT->getAs<BuiltinType>()->getKind()) {
1463 default:
1464 ROOT::TMetaUtils::Error("TClingCallFunc::exec", "Unknown builtin type!");
1465#ifndef NDEBUG
1466 QT->dump();
1467#endif // NDEBUG
1468 break;
1469#define X(type, name) \
1470 case BuiltinType::name: fArgVals[i] = cling::Value::Create(*fInterp, fArgVals[i].castAs<type>()); break;
1472#undef X
1473 }
1474 }
1475 vp_ary.push_back(fArgVals[i].getPtrAddress());
1476 }
1477 }
1478 } // End of scope holding the lock
1479 (*fWrapper)(address, (int)num_args, (void **)vp_ary.data(), ret);
1480}
1481
1482void TClingCallFunc::exec_with_valref_return(void *address, cling::Value &ret)
1483{
1484 const FunctionDecl *FD = GetDecl();
1485
1486 QualType QT;
1487 if (llvm::isa<CXXConstructorDecl>(FD)) {
1489 ASTContext &Context = FD->getASTContext();
1491 QualType ClassTy(TD->getTypeForDecl(), 0);
1492 QT = Context.getLValueReferenceType(ClassTy);
1493 ret = cling::Value(QT, *fInterp);
1494 } else {
1495 QT = FD->getReturnType().getCanonicalType();
1496 ret = cling::Value(QT, *fInterp);
1497
1498 if (QT->isRecordType() || QT->isMemberDataPointerType())
1499 return exec(address, ret.getPtr());
1500 }
1501 exec(address, ret.getPtrAddress());
1502}
1503
1505{
1507
1509 fInterp->getLookupHelper().findArgList(ArgList, exprs,
1510 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
1511 : cling::LookupHelper::NoDiagnostics);
1513 E = exprs.end(); I != E; ++I) {
1514 cling::Value val;
1515 EvaluateExpr(*fInterp, *I, val);
1516 if (!val.isValid()) {
1517 // Bad expression, all done.
1518 ::Error("TClingCallFunc::EvaluateArgList",
1519 "Bad expression in parameter %d of '%s'!",
1520 (int)(I - exprs.begin()),
1521 ArgList.c_str());
1522 return;
1523 }
1524 fArgVals.push_back(val);
1525 }
1526}
1527
1529{
1530 IFacePtr();
1531 if (!fWrapper) {
1532 ::Error("TClingCallFunc::Exec(address, interpVal)",
1533 "Called with no wrapper, not implemented!");
1534 return;
1535 }
1536 if (!interpVal || !interpVal->GetValAddr()) {
1537 exec(address, nullptr);
1538 return;
1539 }
1540 cling::Value *val = reinterpret_cast<cling::Value *>(interpVal->GetValAddr());
1541 exec_with_valref_return(address, *val);
1542}
1543
1544template <typename T>
1546{
1547 IFacePtr();
1548 if (!fWrapper) {
1549 ::Error("TClingCallFunc::ExecT",
1550 "Called with no wrapper, not implemented!");
1551 return 0;
1552 }
1553 cling::Value ret;
1554 exec_with_valref_return(address, ret);
1555 if (ret.isVoid()) {
1556 return 0;
1557 }
1558
1559 if (ret.needsManagedAllocation())
1560 ((TCling *)gCling)->RegisterTemporary(ret);
1561
1562 return ret.castAs<T>();
1563}
1564
1566{
1567 return ExecT<Longptr_t>(address);
1568}
1569
1570long long TClingCallFunc::ExecInt64(void *address)
1571{
1572 return ExecT<long long>(address);
1573}
1574
1575double TClingCallFunc::ExecDouble(void *address)
1576{
1577 return ExecT<double>(address);
1578}
1579
1580void TClingCallFunc::ExecWithArgsAndReturn(void *address, const void *args[] /*= 0*/,
1581 int nargs /*= 0*/, void *ret/*= 0*/)
1582{
1583 IFacePtr();
1584 if (!fWrapper) {
1585 ::Error("TClingCallFunc::ExecWithArgsAndReturn(address, args, ret)",
1586 "Called with no wrapper, not implemented!");
1587 return;
1588 }
1589 (*fWrapper)(address, nargs, const_cast<void **>(args), ret);
1590}
1591
1592void TClingCallFunc::ExecWithReturn(void *address, void *ret/*= 0*/)
1593{
1594 IFacePtr();
1595 if (!fWrapper) {
1596 ::Error("TClingCallFunc::ExecWithReturn(address, ret)",
1597 "Called with no wrapper, not implemented!");
1598 return;
1599 }
1600 exec(address, ret);
1601}
1602
1605 const std::string &type_name,
1606 void *address /*=0*/, unsigned long nary /*= 0UL*/)
1607{
1608 if (!info->IsValid()) {
1609 ::Error("TClingCallFunc::ExecDefaultConstructor", "Invalid class info!");
1610 return nullptr;
1611 }
1613 //if (!info->HasDefaultConstructor()) {
1614 // // FIXME: We might have a ROOT ioctor, we might
1615 // // have to check for that here.
1616 // ::Error("TClingCallFunc::ExecDefaultConstructor",
1617 // "Class has no default constructor: %s",
1618 // info->Name());
1619 // return 0;
1620 //}
1621 void *obj = nullptr;
1622 (*wrapper)(&obj, address, nary);
1623 return obj;
1624 }
1625 ::Error("TClingCallFunc::ExecDefaultConstructor", "Called with no wrapper, not implemented!");
1626 return nullptr;
1627}
1628
1629void TClingCallFunc::ExecDestructor(const TClingClassInfo *info, void *address /*=0*/,
1630 unsigned long nary /*= 0UL*/, bool withFree /*= true*/)
1631{
1632 if (!info->IsValid()) {
1633 ::Error("TClingCallFunc::ExecDestructor", "Invalid class info!");
1634 return;
1635 }
1636
1638 (*wrapper)(address, nary, withFree);
1639 return;
1640 }
1641
1642 ::Error("TClingCallFunc::ExecDestructor", "Called with no wrapper, not implemented!");
1643}
1644
1647{
1648 return new TClingMethodInfo(*fMethod);
1649}
1650
1652{
1653 fMethod.reset();
1654 fWrapper = nullptr;
1655 fDecl = nullptr;
1657 ResetArg();
1658}
1659
1661{
1662 Init();
1663 fMethod = std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(minfo));
1664}
1665
1666void TClingCallFunc::Init(std::unique_ptr<TClingMethodInfo> minfo)
1667{
1668 Init();
1669 fMethod = std::move(minfo);
1670}
1671
1673{
1674 if (!IsValid()) {
1675 return nullptr;
1676 }
1677
1678 if (!fWrapper)
1680
1681 return (void *)fWrapper.load();
1682}
1683
1685{
1686 if (!fMethod) {
1687 return false;
1688 }
1689 return fMethod->IsValid();
1690}
1691
1693{
1694 if (!IsValid()) {
1695 ::Error("TClingCallFunc::IFacePtr(kind)",
1696 "Attempt to get interface while invalid.");
1698 }
1699
1700 if (!fWrapper)
1702
1704}
1705
1706
1708{
1709 fArgVals.clear();
1710}
1711
1713{
1714 ResetArg();
1715 for (int i = 0; i < nparam; ++i) {
1716 SetArg(paramArr[i]);
1717 }
1718}
1719
1720void TClingCallFunc::SetArgs(const char *params)
1721{
1722 ResetArg();
1723 EvaluateArgList(params);
1724}
1725
1726void TClingCallFunc::SetFunc(const TClingClassInfo *info, const char *method, const char *arglist,
1728{
1729 SetFunc(info, method, arglist, false, poffset);
1730}
1731
1732void TClingCallFunc::SetFunc(const TClingClassInfo *info, const char *method, const char *arglist,
1734{
1735 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(fInterp)));
1736 if (poffset) {
1737 *poffset = 0L;
1738 }
1739 ResetArg();
1740 if (!info->IsValid()) {
1741 ::Error("TClingCallFunc::SetFunc", "Class info is invalid!");
1742 return;
1743 }
1744 if (!strcmp(arglist, ")")) {
1745 // CINT accepted a single right paren as meaning no arguments.
1746 arglist = "";
1747 }
1748 *fMethod = info->GetMethodWithArgs(method, arglist, objectIsConst, poffset);
1749 if (!fMethod->IsValid()) {
1750 //::Error("TClingCallFunc::SetFunc", "Could not find method %s(%s)", method,
1751 // arglist);
1752 return;
1753 }
1754 // FIXME: The arglist was already parsed by the lookup, we should
1755 // enhance the lookup to return the resulting expression
1756 // list so we do not need to parse it again here.
1758}
1759
1761{
1762 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(*info)));
1763 ResetArg();
1764 if (!fMethod->IsValid()) {
1765 return;
1766 }
1767}
1768
1770 const char *proto, Longptr_t *poffset,
1771 EFunctionMatchMode mode/*=kConversionMatch*/)
1772{
1774}
1775
1777 const char *proto, bool objectIsConst, Longptr_t *poffset,
1778 EFunctionMatchMode mode/*=kConversionMatch*/)
1779{
1780 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(fInterp)));
1781 if (poffset) {
1782 *poffset = 0L;
1783 }
1784 ResetArg();
1785 if (!info->IsValid()) {
1786 ::Error("TClingCallFunc::SetFuncProto", "Class info is invalid!");
1787 return;
1788 }
1789 *fMethod = info->GetMethod(method, proto, objectIsConst, poffset, mode);
1790 if (!fMethod->IsValid()) {
1791 //::Error("TClingCallFunc::SetFuncProto", "Could not find method %s(%s)",
1792 // method, proto);
1793 return;
1794 }
1795}
1796
1798 const llvm::SmallVectorImpl<clang::QualType> &proto, Longptr_t *poffset,
1799 EFunctionMatchMode mode/*=kConversionMatch*/)
1800{
1802}
1803
1805 const llvm::SmallVectorImpl<clang::QualType> &proto,
1807 EFunctionMatchMode mode/*=kConversionMatch*/)
1808{
1809 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(fInterp)));
1810 if (poffset) {
1811 *poffset = 0L;
1812 }
1813 ResetArg();
1814 if (!info->IsValid()) {
1815 ::Error("TClingCallFunc::SetFuncProto", "Class info is invalid!");
1816 return;
1817 }
1818 *fMethod = info->GetMethod(method, proto, objectIsConst, poffset, mode);
1819 if (!fMethod->IsValid()) {
1820 //::Error("TClingCallFunc::SetFuncProto", "Could not find method %s(%s)",
1821 // method, proto);
1822 return;
1823 }
1824}
1825
long Longptr_t
Definition RtypesCore.h:75
static void EvaluateExpr(cling::Interpreter &interp, const Expr *E, cling::Value &V)
static bool IsCopyConstructorDeleted(QualType QT)
static std::string PrepareStructorWrapper(const Decl *D, const char *wrapper_prefix, std::string &class_name)
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_ctor_Wrapper_t)(void **, void *, unsigned long)
void(* tcling_callfunc_Wrapper_t)(void *, int, void **, void *)
void(* tcling_callfunc_dtor_Wrapper_t)(void *, unsigned long, int)
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:185
#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
Definition TROOT.cxx:597
const char * proto
Definition civetweb.c:17535
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
tcling_callfunc_dtor_Wrapper_t make_dtor_wrapper(const TClingClassInfo *info)
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()
tcling_callfunc_ctor_Wrapper_t make_ctor_wrapper(const TClingClassInfo *, ROOT::TMetaUtils::EIOCtorCategory, const std::string &)
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,...)
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
EFunctionMatchMode