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 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
82// Caches of the JIT-compiled call, constructor and destructor wrappers, keyed on
83// the declaration they were generated for. They are globals of libCling on
84// purpose: a function-local static would register its destructor on first use,
85// which for the destructor wrappers can be in the middle of the user's program,
86// i.e. after ROOT registered its atexit handlers. The cache would then be
87// destroyed before TROOT::EndOfProcessCleanups() releases the remaining objects
88// (e.g. a TTree branch of a class without compiled dictionary), and the lookup
89// of the destructor wrapper would run on a dead map, see
90// https://github.com/root-project/root/issues/23728.
94
95static
96inline
97void
98indent(ostringstream &buf, int indent_level)
99{
100 for (int i = 0; i < indent_level; ++i) {
101 buf << kIndentString;
102 }
103}
104
105static
106void
107EvaluateExpr(cling::Interpreter &interp, const Expr *E, cling::Value &V)
108{
109 // Evaluate an Expr* and return its cling::Value
110 ASTContext &C = interp.getCI()->getASTContext();
111 clang::Expr::EvalResult evalRes;
112 if (E->EvaluateAsInt(evalRes, C, /*AllowSideEffects*/Expr::SE_NoSideEffects)) {
113 // FIXME: Find the right type or make sure we have an interface to update
114 // the clang::Type in the cling::Value
115 APSInt res = evalRes.Val.getInt();
116 // IntTy or maybe better E->getType()?
117 V = cling::Value(C.IntTy, interp);
118 // We must use the correct signedness otherwise the zero extension
119 // fails if the actual type is strictly less than long long.
120 if (res.isSigned())
121 V.setLongLong(res.getSExtValue());
122 else
123 V.setULongLong(res.getZExtValue());
124 return;
125 }
126 // TODO: Build a wrapper around the expression to avoid decompilation and
127 // compilation and other string operations.
128 PrintingPolicy Policy(C.getPrintingPolicy());
129 Policy.SuppressTagKeyword = true;
130 Policy.SuppressUnwrittenScope = false;
131 Policy.SuppressInitializers = false;
132 Policy.AnonymousTagLocations = false;
133 string buf;
134 raw_string_ostream out(buf);
135 E->printPretty(out, /*Helper=*/nullptr, Policy, /*Indentation=*/0);
136 out << ';'; // no value printing
137 out.flush();
138 // Evaluate() will set V to invalid if evaluation fails.
139 interp.evaluate(buf, V);
140}
141
143{
144 // This function is non-const to use caching overload of GetDecl()!
145 return GetDecl()->getMinRequiredArguments();
146}
147
148void *TClingCallFunc::compile_wrapper(const string &wrapper_name, const string &wrapper,
149 bool withAccessControl/*=true*/)
150{
151 return fInterp->compileFunction(wrapper_name, wrapper, false /*ifUnique*/,
153}
154
155static void GetTypeAsString(QualType QT, string& type_name, ASTContext &C,
156 PrintingPolicy Policy) {
157
158 // FIXME: Take the code here https://github.com/root-project/root/blob/550fb2644f3c07d1db72b9b4ddc4eba5a99ddc12/interpreter/cling/lib/Utils/AST.cpp#L316-L350
159 // to make hist/histdrawv7/test/histhistdrawv7testUnit work into
160 // QualTypeNames.h in clang
161 //type_name = clang::TypeName::getFullyQualifiedName(QT, C, Policy);
162 cling::utils::Transform::Config Config;
163 QT = cling::utils::Transform::GetPartiallyDesugaredType(C, QT, Config, /*fullyQualify=*/true);
164 QT.getAsStringInternal(type_name, Policy);
165}
166
167static void GetDeclName(const clang::Decl *D, ASTContext &Context, std::string &name)
168{
169 // Helper to extract a fully qualified name from a Decl
170
171 PrintingPolicy Policy(Context.getPrintingPolicy());
172 Policy.SuppressTagKeyword = true;
173 Policy.SuppressUnwrittenScope = true;
174 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
175 // This is a class, struct, or union member.
176 QualType QT(TD->getTypeForDecl(), 0);
177 GetTypeAsString(QT, name, Context, Policy);
178 } else if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
179 // This is a namespace member.
180 raw_string_ostream stream(name);
181 ND->getNameForDiagnostic(stream, Policy, /*Qualified=*/true);
182 stream.flush();
183 }
184}
185
186void TClingCallFunc::collect_type_info(QualType &QT, ostringstream &typedefbuf, std::ostringstream &callbuf,
188 bool forArgument)
189{
190 //
191 // Collect information about type type of a function parameter
192 // needed for building the wrapper function.
193 //
194 const FunctionDecl *FD = GetDecl();
195 ASTContext &C = FD->getASTContext();
196 PrintingPolicy Policy(C.getPrintingPolicy());
198 if (QT->isRecordType() && forArgument) {
199 GetTypeAsString(QT, type_name, C, Policy);
200 return;
201 }
202 if (QT->isFunctionPointerType()) {
203 string fp_typedef_name;
204 {
205 ostringstream nm;
206 nm << "FP" << gWrapperSerial++;
207 type_name = nm.str();
208 raw_string_ostream OS(fp_typedef_name);
209 QT.print(OS, Policy, type_name);
210 OS.flush();
211 }
213 typedefbuf << "typedef " << fp_typedef_name << ";\n";
214 return;
215 } else if (QT->isMemberPointerType()) {
216 string mp_typedef_name;
217 {
218 ostringstream nm;
219 nm << "MP" << gWrapperSerial++;
220 type_name = nm.str();
221 raw_string_ostream OS(mp_typedef_name);
222 QT.print(OS, Policy, type_name);
223 OS.flush();
224 }
226 typedefbuf << "typedef " << mp_typedef_name << ";\n";
227 return;
228 } else if (QT->isPointerType()) {
229 isPointer = true;
230 QT = cast<clang::PointerType>(QT)->getPointeeType();
231 } else if (QT->isReferenceType()) {
232 if (QT->isRValueReferenceType()) refType = kRValueReference;
234 QT = cast<ReferenceType>(QT)->getPointeeType();
235 }
236 // Fall through for the array type to deal with reference/pointer ro array type.
237 if (QT->isArrayType()) {
238 string ar_typedef_name;
239 {
240 ostringstream ar;
241 ar << "AR" << gWrapperSerial++;
242 type_name = ar.str();
243 raw_string_ostream OS(ar_typedef_name);
244 QT.print(OS, Policy, type_name);
245 OS.flush();
246 }
248 typedefbuf << "typedef " << ar_typedef_name << ";\n";
249 return;
250 }
251 GetTypeAsString(QT, type_name, C, Policy);
252}
253
254static bool IsCopyConstructorDeleted(QualType QT)
255{
256 CXXRecordDecl *RD = QT->getAsCXXRecordDecl();
257 if (!RD) {
258 // For types that are not C++ records (such as PODs), we assume that they are copyable, ie their copy constructor
259 // is not deleted.
260 return false;
261 }
262
263 RD = RD->getDefinition();
264 assert(RD && "expecting a definition");
265
266 if (RD->hasSimpleCopyConstructor())
267 return false;
268
269 for (auto *Ctor : RD->ctors()) {
270 if (Ctor->isCopyConstructor()) {
271 return Ctor->isDeleted();
272 }
273 }
274
275 assert(0 && "did not find a copy constructor?");
276 // Should never happen and the return value is somewhat arbitrary, but we did not see a deleted copy ctor. The user
277 // will be told if the generated code doesn't compile.
278 return false;
279}
280
281void TClingCallFunc::make_narg_ctor(const unsigned N, ostringstream &typedefbuf,
282 ostringstream &callbuf, const string &class_name,
283 int indent_level)
284{
285 // Make a code string that follows this pattern:
286 //
287 // new ClassName(args...)
288 //
289 const FunctionDecl *FD = GetDecl();
290
291 callbuf << "new " << class_name << "(";
292
293 // IsCopyConstructorDeleted could trigger deserialization of decls.
294 cling::Interpreter::PushTransactionRAII RAII(fInterp);
295
296 for (unsigned i = 0U; i < N; ++i) {
297 const ParmVarDecl *PVD = FD->getParamDecl(i);
298 QualType Ty = PVD->getType();
299 QualType QT = Ty.getCanonicalType();
300 string type_name;
302 bool isPointer = false;
305 if (i) {
306 callbuf << ',';
307 if (i % 2) {
308 callbuf << ' ';
309 } else {
310 callbuf << "\n";
312 }
313 }
314 if (refType != kNotReference) {
315 callbuf << "(" << type_name.c_str() <<
316 (refType == kLValueReference ? "&" : "&&") << ")*(" << type_name.c_str() << "*)args["
317 << i << "]";
318 } else if (isPointer) {
319 callbuf << "*(" << type_name.c_str() << "**)args["
320 << i << "]";
321 } else {
322 // By-value construction: Figure out if the type can be copy-constructed. This is tricky and cannot be done in
323 // a fully reliable way, also because std::vector<T> always defines a copy constructor, even if the type T is
324 // only moveable. As a heuristic, we only check if the copy constructor is deleted, or would be if implicit.
325 bool Move = IsCopyConstructorDeleted(QT);
326 if (Move) {
327 callbuf << "static_cast<" << type_name << "&&>(";
328 }
329 callbuf << "*(" << type_name.c_str() << "*)args[" << i << "]";
330 if (Move) {
331 callbuf << ")";
332 }
333 }
334 }
335 callbuf << ")";
336}
337
338void TClingCallFunc::make_narg_call(const std::string &return_type, const unsigned N, ostringstream &typedefbuf,
339 ostringstream &callbuf, const string &class_name, int indent_level)
340{
341 //
342 // Make a code string that follows this pattern:
343 //
344 // ((<class>*)obj)-><method>(*(<arg-i-type>*)args[i], ...)
345 //
346 const FunctionDecl *FD = GetDecl();
347
348 // Sometimes it's necessary that we cast the function we want to call first
349 // to its explicit function type before calling it. This is supposed to prevent
350 // that we accidentially ending up in a function that is not the one we're
351 // supposed to call here (e.g. because the C++ function lookup decides to take
352 // another function that better fits).
353 // This method has some problems, e.g. when we call a function with default
354 // arguments and we don't provide all arguments, we would fail with this pattern.
355 // Same applies with member methods which seem to cause parse failures even when
356 // we supply the object parameter.
357 // Therefore we only use it in cases where we know it works and set this variable
358 // to true when we do.
359 bool ShouldCastFunction = !isa<CXXMethodDecl>(FD) && N == FD->getNumParams();
360 if (ShouldCastFunction) {
361 callbuf << "(";
362 callbuf << "(";
363 callbuf << return_type << " (&)";
364 {
365 callbuf << "(";
366 for (unsigned i = 0U; i < N; ++i) {
367 if (i) {
368 callbuf << ',';
369 if (i % 2) {
370 callbuf << ' ';
371 } else {
372 callbuf << "\n";
374 }
375 }
376 const ParmVarDecl *PVD = FD->getParamDecl(i);
377 QualType Ty = PVD->getType();
378 QualType QT = Ty.getCanonicalType();
379 std::string arg_type;
380 ASTContext &C = FD->getASTContext();
381 GetTypeAsString(QT, arg_type, C, C.getPrintingPolicy());
382 callbuf << arg_type;
383 }
384 if (FD->isVariadic())
385 callbuf << ", ...";
386 callbuf << ")";
387 }
388
389 callbuf << ")";
390 }
391
393 // This is a class, struct, or union member.
394 if (MD->isConst())
395 callbuf << "((const " << class_name << "*)obj)->";
396 else
397 callbuf << "((" << class_name << "*)obj)->";
398 } else if (const NamedDecl *ND =
400 // This is a namespace member.
401 (void) ND;
402 callbuf << class_name << "::";
403 }
404 // callbuf << fMethod->Name() << "(";
405 {
406 std::string name;
407 {
408 llvm::raw_string_ostream stream(name);
409 FD->getNameForDiagnostic(stream, FD->getASTContext().getPrintingPolicy(), /*Qualified=*/false);
410 }
411 callbuf << name;
412 }
413 if (ShouldCastFunction) callbuf << ")";
414
415 callbuf << "(";
416
417 // IsCopyConstructorDeleted could trigger deserialization of decls.
418 cling::Interpreter::PushTransactionRAII RAII(fInterp);
419
420 for (unsigned i = 0U; i < N; ++i) {
421 const ParmVarDecl *PVD = FD->getParamDecl(i);
422 QualType Ty = PVD->getType();
423 QualType QT = Ty.getCanonicalType();
424 string type_name;
426 bool isPointer = false;
428
429 if (i) {
430 callbuf << ',';
431 if (i % 2) {
432 callbuf << ' ';
433 } else {
434 callbuf << "\n";
436 }
437 }
438
439 if (refType != kNotReference) {
440 callbuf << "(" << type_name.c_str() <<
441 (refType == kLValueReference ? "&" : "&&") << ")*(" << type_name.c_str() << "*)args["
442 << i << "]";
443 } else if (isPointer) {
444 callbuf << "*(" << type_name.c_str() << "**)args["
445 << i << "]";
446 } else {
447 // By-value construction: Figure out if the type can be copy-constructed. This is tricky and cannot be done in
448 // a fully reliable way, also because std::vector<T> always defines a copy constructor, even if the type T is
449 // only moveable. As a heuristic, we only check if the copy constructor is deleted, or would be if implicit.
450 bool Move = IsCopyConstructorDeleted(QT);
451 if (Move) {
452 callbuf << "static_cast<" << type_name << "&&>(";
453 }
454 callbuf << "*(" << type_name.c_str() << "*)args[" << i << "]";
455 if (Move) {
456 callbuf << ")";
457 }
458 }
459 }
460 callbuf << ")";
461}
462
463void TClingCallFunc::make_narg_ctor_with_return(const unsigned N, const string &class_name,
464 ostringstream &buf, int indent_level)
465{
466 // Make a code string that follows this pattern:
467 //
468 // if (ret) {
469 // (*(ClassName**)ret) = new ClassName(args...);
470 // }
471 // else {
472 // new ClassName(args...);
473 // }
474 //
475 indent(buf, indent_level);
476 buf << "if (ret) {\n";
477 ++indent_level;
478 {
479 ostringstream typedefbuf;
480 ostringstream callbuf;
481 //
482 // Write the return value assignment part.
483 //
485 callbuf << "(*(" << class_name << "**)ret) = ";
486 //
487 // Write the actual new expression.
488 //
490 //
491 // End the new expression statement.
492 //
493 callbuf << ";\n";
495 callbuf << "return;\n";
496 //
497 // Output the whole new expression and return statement.
498 //
499 buf << typedefbuf.str() << callbuf.str();
500 }
501 --indent_level;
502 for (int i = 0; i < indent_level; ++i) {
503 buf << kIndentString;
504 }
505 buf << "}\n";
506 for (int i = 0; i < indent_level; ++i) {
507 buf << kIndentString;
508 }
509 buf << "else {\n";
510 ++indent_level;
511 {
512 ostringstream typedefbuf;
513 ostringstream callbuf;
514 for (int i = 0; i < indent_level; ++i) {
516 }
518 callbuf << ";\n";
519 for (int i = 0; i < indent_level; ++i) {
521 }
522 callbuf << "return;\n";
523 buf << typedefbuf.str() << callbuf.str();
524 }
525 --indent_level;
526 for (int i = 0; i < indent_level; ++i) {
527 buf << kIndentString;
528 }
529 buf << "}\n";
530}
531
532///////////////////////////////////////////////////////////////////////////////
533// Returns the DeclContext corresponding to fMethod's Decl.
534// \Note that this might be a FunctionDecl or a UsingShadowDecl; we use the
535// DeclContext of the UsingShadowDecl e.g. for constructing a derived class
536// object, even if invoking a function made available by a using declaration
537// of a constructor of a base class (ROOT-11010).
538
539const clang::DeclContext *TClingCallFunc::GetDeclContext() const {
540 return fMethod->GetDecl()->getDeclContext();
541}
542
544{
545 const FunctionDecl *FD = GetDecl();
546 assert(FD && "generate_wrapper called without a function decl!");
547 //
548 // Get the class or namespace name.
549 //
550 string class_name;
551 ASTContext &Context = FD->getASTContext();
552 const clang::DeclContext *DC = GetDeclContext();
554 //
555 // Check to make sure that we can
556 // instantiate and codegen this function.
557 //
558 bool needInstantiation = false;
559 const FunctionDecl *Definition = nullptr;
560 if (!FD->isDefined(Definition)) {
561 FunctionDecl::TemplatedKind TK = FD->getTemplatedKind();
562 switch (TK) {
563 case FunctionDecl::TK_NonTemplate: {
564 // Ordinary function, not a template specialization.
565 // Note: This might be ok, the body might be defined
566 // in a library, and all we have seen is the
567 // header file.
568 //::Error("TClingCallFunc::make_wrapper",
569 // "Cannot make wrapper for a function which is "
570 // "declared but not defined!");
571 // return 0;
572 } break;
573 case FunctionDecl::TK_FunctionTemplate: {
574 // This decl is actually a function template,
575 // not a function at all.
576 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a function template!");
577 return 0;
578 } break;
579 case FunctionDecl::TK_MemberSpecialization: {
580 // This function is the result of instantiating an ordinary
581 // member function of a class template, or of instantiating
582 // an ordinary member function of a class member of a class
583 // template, or of specializing a member function template
584 // of a class template, or of specializing a member function
585 // template of a class member of a class template.
586 if (!FD->isTemplateInstantiation()) {
587 // We are either TSK_Undeclared or
588 // TSK_ExplicitSpecialization.
589 // Note: This might be ok, the body might be defined
590 // in a library, and all we have seen is the
591 // header file.
592 //::Error("TClingCallFunc::make_wrapper",
593 // "Cannot make wrapper for a function template "
594 // "explicit specialization which is declared "
595 // "but not defined!");
596 // return 0;
597 break;
598 }
599 const FunctionDecl *Pattern = FD->getTemplateInstantiationPattern();
600 if (!Pattern) {
601 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a member function "
602 "instantiation with no pattern!");
603 return 0;
604 }
605 FunctionDecl::TemplatedKind PTK = Pattern->getTemplatedKind();
606 TemplateSpecializationKind PTSK = Pattern->getTemplateSpecializationKind();
607 if (
608 // The pattern is an ordinary member function.
609 (PTK == FunctionDecl::TK_NonTemplate) ||
610 // The pattern is an explicit specialization, and
611 // so is not a template.
612 ((PTK != FunctionDecl::TK_FunctionTemplate) &&
614 // Note: This might be ok, the body might be defined
615 // in a library, and all we have seen is the
616 // header file.
617 break;
618 } else if (!Pattern->hasBody()) {
619 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a member function "
620 "instantiation with no body!");
621 return 0;
622 }
623 if (FD->isImplicitlyInstantiable()) {
624 needInstantiation = true;
625 }
626 } break;
627 case FunctionDecl::TK_FunctionTemplateSpecialization: {
628 // This function is the result of instantiating a function
629 // template or possibly an explicit specialization of a
630 // function template. Could be a namespace scope function or a
631 // member function.
632 if (!FD->isTemplateInstantiation()) {
633 // We are either TSK_Undeclared or
634 // TSK_ExplicitSpecialization.
635 // Note: This might be ok, the body might be defined
636 // in a library, and all we have seen is the
637 // header file.
638 //::Error("TClingCallFunc::make_wrapper",
639 // "Cannot make wrapper for a function template "
640 // "explicit specialization which is declared "
641 // "but not defined!");
642 // return 0;
643 break;
644 }
645 const FunctionDecl *Pattern = FD->getTemplateInstantiationPattern();
646 if (!Pattern) {
647 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a function template"
648 "instantiation with no pattern!");
649 return 0;
650 }
651 FunctionDecl::TemplatedKind PTK = Pattern->getTemplatedKind();
652 TemplateSpecializationKind PTSK = Pattern->getTemplateSpecializationKind();
653 if (
654 // The pattern is an ordinary member function.
655 (PTK == FunctionDecl::TK_NonTemplate) ||
656 // The pattern is an explicit specialization, and
657 // so is not a template.
658 ((PTK != FunctionDecl::TK_FunctionTemplate) &&
660 // Note: This might be ok, the body might be defined
661 // in a library, and all we have seen is the
662 // header file.
663 break;
664 }
665 if (!Pattern->hasBody()) {
666 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a function template"
667 "instantiation with no body!");
668 return 0;
669 }
670 if (FD->isImplicitlyInstantiable()) {
671 needInstantiation = true;
672 }
673 } break;
674 case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
675 // This function is the result of instantiating or
676 // specializing a member function of a class template,
677 // or a member function of a class member of a class template,
678 // or a member function template of a class template, or a
679 // member function template of a class member of a class
680 // template where at least some part of the function is
681 // dependent on a template argument.
682 if (!FD->isTemplateInstantiation()) {
683 // We are either TSK_Undeclared or
684 // TSK_ExplicitSpecialization.
685 // Note: This might be ok, the body might be defined
686 // in a library, and all we have seen is the
687 // header file.
688 //::Error("TClingCallFunc::make_wrapper",
689 // "Cannot make wrapper for a dependent function "
690 // "template explicit specialization which is declared "
691 // "but not defined!");
692 // return 0;
693 break;
694 }
695 const FunctionDecl *Pattern = FD->getTemplateInstantiationPattern();
696 if (!Pattern) {
697 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a dependent function template"
698 "instantiation with no pattern!");
699 return 0;
700 }
701 FunctionDecl::TemplatedKind PTK = Pattern->getTemplatedKind();
702 TemplateSpecializationKind PTSK = Pattern->getTemplateSpecializationKind();
703 if (
704 // The pattern is an ordinary member function.
705 (PTK == FunctionDecl::TK_NonTemplate) ||
706 // The pattern is an explicit specialization, and
707 // so is not a template.
708 ((PTK != FunctionDecl::TK_FunctionTemplate) &&
710 // Note: This might be ok, the body might be defined
711 // in a library, and all we have seen is the
712 // header file.
713 break;
714 }
715 if (!Pattern->hasBody()) {
716 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a dependent function template"
717 "instantiation with no body!");
718 return 0;
719 }
720 if (FD->isImplicitlyInstantiable()) {
721 needInstantiation = true;
722 }
723 } break;
724 default: {
725 // Will only happen if clang implementation changes.
726 // Protect ourselves in case that happens.
727 ::Error("TClingCallFunc::make_wrapper", "Unhandled template kind!");
728 return 0;
729 } break;
730 }
731 // We do not set needInstantiation to true in these cases:
732 //
733 // isInvalidDecl()
734 // TSK_Undeclared
735 // TSK_ExplicitInstantiationDefinition
736 // TSK_ExplicitSpecialization && !getClassScopeSpecializationPattern()
737 // TSK_ExplicitInstantiationDeclaration &&
738 // getTemplateInstantiationPattern() &&
739 // PatternDecl->hasBody() &&
740 // !PatternDecl->isInlined()
741 //
742 // Set it true in these cases:
743 //
744 // TSK_ImplicitInstantiation
745 // TSK_ExplicitInstantiationDeclaration && (!getPatternDecl() ||
746 // !PatternDecl->hasBody() || PatternDecl->isInlined())
747 //
748 }
749 if (needInstantiation) {
750 clang::FunctionDecl *FDmod = const_cast<clang::FunctionDecl *>(FD);
751 clang::Sema &S = fInterp->getSema();
752 // Could trigger deserialization of decls.
753 cling::Interpreter::PushTransactionRAII RAII(fInterp);
754 S.InstantiateFunctionDefinition(SourceLocation(), FDmod,
755 /*Recursive=*/true,
756 /*DefinitionRequired=*/true);
757 if (!FD->isDefined(Definition)) {
758 ::Error("TClingCallFunc::make_wrapper", "Failed to force template instantiation!");
759 return 0;
760 }
761 }
762 if (Definition) {
763 FunctionDecl::TemplatedKind TK = Definition->getTemplatedKind();
764 switch (TK) {
765 case FunctionDecl::TK_NonTemplate: {
766 // Ordinary function, not a template specialization.
767 if (Definition->isDeleted()) {
768 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a deleted function!");
769 return 0;
770 } else if (Definition->isLateTemplateParsed()) {
771 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a late template parsed "
772 "function!");
773 return 0;
774 }
775 // else if (Definition->isDefaulted()) {
776 // // Might not have a body, but we can still use it.
777 //}
778 // else {
779 // // Has a body.
780 //}
781 } break;
782 case FunctionDecl::TK_FunctionTemplate: {
783 // This decl is actually a function template,
784 // not a function at all.
785 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a function template!");
786 return 0;
787 } break;
788 case FunctionDecl::TK_MemberSpecialization: {
789 // This function is the result of instantiating an ordinary
790 // member function of a class template or of a member class
791 // of a class template.
792 if (Definition->isDeleted()) {
793 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a deleted member function "
794 "of a specialization!");
795 return 0;
796 } else if (Definition->isLateTemplateParsed()) {
797 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a late template parsed "
798 "member function of a specialization!");
799 return 0;
800 }
801 // else if (Definition->isDefaulted()) {
802 // // Might not have a body, but we can still use it.
803 //}
804 // else {
805 // // Has a body.
806 //}
807 } break;
808 case FunctionDecl::TK_FunctionTemplateSpecialization: {
809 // This function is the result of instantiating a function
810 // template or possibly an explicit specialization of a
811 // function template. Could be a namespace scope function or a
812 // member function.
813 if (Definition->isDeleted()) {
814 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a deleted function "
815 "template specialization!");
816 return 0;
817 } else if (Definition->isLateTemplateParsed()) {
818 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a late template parsed "
819 "function template specialization!");
820 return 0;
821 }
822 // else if (Definition->isDefaulted()) {
823 // // Might not have a body, but we can still use it.
824 //}
825 // else {
826 // // Has a body.
827 //}
828 } break;
829 case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
830 // This function is the result of instantiating or
831 // specializing a member function of a class template,
832 // or a member function of a class member of a class template,
833 // or a member function template of a class template, or a
834 // member function template of a class member of a class
835 // template where at least some part of the function is
836 // dependent on a template argument.
837 if (Definition->isDeleted()) {
838 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a deleted dependent function "
839 "template specialization!");
840 return 0;
841 } else if (Definition->isLateTemplateParsed()) {
842 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a late template parsed "
843 "dependent function template specialization!");
844 return 0;
845 }
846 // else if (Definition->isDefaulted()) {
847 // // Might not have a body, but we can still use it.
848 //}
849 // else {
850 // // Has a body.
851 //}
852 } break;
853 default: {
854 // Will only happen if clang implementation changes.
855 // Protect ourselves in case that happens.
856 ::Error("TClingCallFunc::make_wrapper", "Unhandled template kind!");
857 return 0;
858 } break;
859 }
860 }
862 unsigned num_params = FD->getNumParams();
863 //
864 // Make the wrapper name.
865 //
866 {
867 ostringstream buf;
868 buf << "__cf";
869 // const NamedDecl* ND = dyn_cast<NamedDecl>(FD);
870 // string mn;
871 // fInterp->maybeMangleDeclName(ND, mn);
872 // buf << '_' << mn;
873 buf << '_' << gWrapperSerial++;
874 wrapper_name = buf.str();
875 }
876 //
877 // Write the wrapper code.
878 // FIXME: this should be synthesized into the AST!
879 //
880 int indent_level = 0;
881 ostringstream buf;
882 buf << "#pragma clang diagnostic push\n"
883 "#pragma clang diagnostic ignored \"-Wformat-security\"\n"
884 "__attribute__((used)) "
885 "__attribute__((annotate(\"__cling__ptrcheck(off)\")))\n"
886 "extern \"C\" void ";
887 buf << wrapper_name;
888 buf << "(void* obj, int nargs, void** args, void* ret)\n"
889 "{\n";
890 ++indent_level;
891 if (min_args == num_params) {
892 // No parameters with defaults.
894 } else {
895 // We need one function call clause compiled for every
896 // possible number of arguments per call.
897 for (unsigned N = min_args; N <= num_params; ++N) {
898 indent(buf, indent_level);
899 buf << "if (nargs == " << N << ") {\n";
900 ++indent_level;
902 --indent_level;
903 indent(buf, indent_level);
904 buf << "}\n";
905 }
906 }
907 --indent_level;
908 buf << "}\n"
909 "#pragma clang diagnostic pop";
910 wrapper = buf.str();
911 return 1;
912}
913
914void TClingCallFunc::make_narg_call_with_return(const unsigned N, const string &class_name,
915 ostringstream &buf, int indent_level)
916{
917 // Make a code string that follows this pattern:
918 //
919 // if (ret) {
920 // new (ret) (return_type) ((class_name*)obj)->func(args...);
921 // }
922 // else {
923 // (void)(((class_name*)obj)->func(args...));
924 // }
925 //
926 const FunctionDecl *FD = GetDecl();
928 if (N <= 1 && llvm::isa<UsingShadowDecl>(GetFunctionOrShadowDecl())) {
929 auto SpecMemKind = fInterp->getSema().getSpecialMember(CD);
930 if ((N == 0 && SpecMemKind == clang::Sema::CXXDefaultConstructor) ||
931 (N == 1 &&
932 (SpecMemKind == clang::Sema::CXXCopyConstructor || SpecMemKind == clang::Sema::CXXMoveConstructor))) {
933 // Using declarations cannot inject special members; do not call them
934 // as such. This might happen by using `Base(Base&, int = 12)`, which
935 // is fine to be called as `Derived d(someBase, 42)` but not as
936 // copy constructor of `Derived`.
937 return;
938 }
939 }
941 return;
942 }
943 QualType QT = FD->getReturnType().getCanonicalType();
944 if (QT->isVoidType()) {
945 ostringstream typedefbuf;
946 ostringstream callbuf;
949 callbuf << ";\n";
951 callbuf << "return;\n";
952 buf << typedefbuf.str() << callbuf.str();
953 } else {
954 indent(buf, indent_level);
955
956 string type_name;
958 bool isPointer = false;
959
960 buf << "if (ret) {\n";
961 ++indent_level;
962 {
963 ostringstream typedefbuf;
964 ostringstream callbuf;
965 //
966 // Write the placement part of the placement new.
967 //
969 callbuf << "new (ret) ";
972 //
973 // Write the type part of the placement new.
974 //
975 callbuf << "(" << type_name.c_str();
976 if (refType != kNotReference) {
977 callbuf << "*) (&";
978 type_name += "&";
979 } else if (isPointer) {
980 callbuf << "*) (";
981 type_name += "*";
982 } else {
983 callbuf << ") (";
984 }
985 //
986 // Write the actual function call.
987 //
989 //
990 // End the placement new.
991 //
992 callbuf << ");\n";
994 callbuf << "return;\n";
995 //
996 // Output the whole placement new expression and return statement.
997 //
998 buf << typedefbuf.str() << callbuf.str();
999 }
1000 --indent_level;
1001 indent(buf, indent_level);
1002 buf << "}\n";
1003 indent(buf, indent_level);
1004 buf << "else {\n";
1005 ++indent_level;
1006 {
1007 ostringstream typedefbuf;
1008 ostringstream callbuf;
1010 callbuf << "(void)(";
1012 callbuf << ");\n";
1014 callbuf << "return;\n";
1015 buf << typedefbuf.str() << callbuf.str();
1016 }
1017 --indent_level;
1018 indent(buf, indent_level);
1019 buf << "}\n";
1020 }
1021}
1022
1024{
1026
1027 const Decl *D = GetFunctionOrShadowDecl();
1028
1029 auto I = gWrapperStore.find(D);
1030 if (I != gWrapperStore.end())
1031 return (tcling_callfunc_Wrapper_t)I->second;
1032
1033 string wrapper_name;
1034 string wrapper;
1035
1036 if (get_wrapper_code(wrapper_name, wrapper) == 0) return nullptr;
1037
1038 //fprintf(stderr, "%s\n", wrapper.c_str());
1039 //
1040 // Compile the wrapper code.
1041 //
1043 if (F) {
1044 gWrapperStore.insert(make_pair(D, F));
1045 } else {
1046 ::Error("TClingCallFunc::make_wrapper",
1047 "Failed to compile\n ==== SOURCE BEGIN ====\n%s\n ==== SOURCE END ====",
1048 wrapper.c_str());
1049 }
1051}
1052
1053static std::string PrepareStructorWrapper(const Decl *D, const char *wrapper_prefix, std::string &class_name)
1054{
1055 //
1056 // Get the class or namespace name.
1057 //
1058 ASTContext &Context = D->getASTContext();
1059 GetDeclName(D, Context, class_name);
1060
1061 //
1062 // Make the wrapper name.
1063 //
1064 string wrapper_name;
1065 {
1066 ostringstream buf;
1067 buf << wrapper_prefix;
1068 // const NamedDecl* ND = dyn_cast<NamedDecl>(FD);
1069 // string mn;
1070 // fInterp->maybeMangleDeclName(ND, mn);
1071 // buf << '_dtor_' << mn;
1072 buf << '_' << gWrapperSerial++;
1073 wrapper_name = buf.str();
1074 }
1075
1076 return wrapper_name;
1077}
1078
1080 ROOT::TMetaUtils::EIOCtorCategory kind, const std::string &type_name)
1081{
1082 // Make a code string that follows this pattern:
1083 //
1084 // void
1085 // unique_wrapper_ddd(void** ret, void* arena, unsigned long nary)
1086 // {
1087 // if (!arena) {
1088 // if (!nary) {
1089 // *ret = new ClassName;
1090 // }
1091 // else {
1092 // *ret = new ClassName[nary];
1093 // }
1094 // }
1095 // else {
1096 // if (!nary) {
1097 // *ret = new (arena) ClassName;
1098 // }
1099 // else {
1100 // *ret = new (arena) ClassName[nary];
1101 // }
1102 // }
1103 // }
1104 //
1105 // When I/O constructor used:
1106 //
1107 // void
1108 // unique_wrapper_ddd(void** ret, void* arena, unsigned long nary)
1109 // {
1110 // if (!arena) {
1111 // if (!nary) {
1112 // *ret = new ClassName((TRootIOCtor*)nullptr);
1113 // }
1114 // else {
1115 // char *buf = malloc(nary * sizeof(ClassName));
1116 // for (int k=0;k<nary;++k)
1117 // new (buf + k * sizeof(ClassName)) ClassName((TRootIOCtor*)nullptr);
1118 // *ret = buf;
1119 // }
1120 // }
1121 // else {
1122 // if (!nary) {
1123 // *ret = new (arena) ClassName((TRootIOCtor*)nullptr);
1124 // }
1125 // else {
1126 // for (int k=0;k<nary;++k)
1127 // new ((char *) arena + k * sizeof(ClassName)) ClassName((TRootIOCtor*)nullptr);
1128 // *ret = arena;
1129 // }
1130 // }
1131 // }
1132 //
1133 //
1134 // Note:
1135 //
1136 // If the class is of POD type, the form:
1137 //
1138 // new ClassName;
1139 //
1140 // does not initialize the object at all, and the form:
1141 //
1142 // new ClassName();
1143 //
1144 // default-initializes the object.
1145 //
1146 // We are using the form without parentheses because that is what
1147 // CINT did.
1148 //
1149 //--
1150
1152
1153 auto D = info->GetDecl();
1154 auto I = gCtorWrapperStore.find(D);
1155 if (I != gCtorWrapperStore.end())
1156 return (tcling_callfunc_ctor_Wrapper_t)I->second;
1157
1158 //
1159 // Make the wrapper name.
1160 //
1161 string class_name;
1162 string wrapper_name = PrepareStructorWrapper(D, "__ctor", class_name);
1163
1164 string constr_arg;
1166 constr_arg = string("((") + type_name + "*)nullptr)";
1168 constr_arg = string("(*((") + type_name + "*)arena))";
1169
1170 //
1171 // Write the wrapper code.
1172 //
1173 int indent_level = 0;
1174 ostringstream buf;
1175 buf << "__attribute__((used)) ";
1176 buf << "extern \"C\" void ";
1177 buf << wrapper_name;
1178 buf << "(void** ret, void* arena, unsigned long nary)\n";
1179 buf << "{\n";
1180
1181 // if (!arena) {
1182 // if (!nary) {
1183 // *ret = new ClassName;
1184 // }
1185 // else {
1186 // *ret = new ClassName[nary];
1187 // }
1188 // }
1189 indent(buf, ++indent_level);
1190 buf << "if (!arena) {\n";
1191 indent(buf, ++indent_level);
1192 buf << "if (!nary) {\n";
1193 indent(buf, ++indent_level);
1194 buf << "*ret = new " << class_name << constr_arg << ";\n";
1195 indent(buf, --indent_level);
1196 buf << "}\n";
1197 indent(buf, indent_level);
1198 buf << "else {\n";
1199 indent(buf, ++indent_level);
1200 if (constr_arg.empty()) {
1201 buf << "*ret = new " << class_name << "[nary];\n";
1202 } else {
1203 buf << "char *buf = (char *) malloc(nary * sizeof(" << class_name << "));\n";
1204 indent(buf, indent_level);
1205 buf << "for (int k=0;k<nary;++k)\n";
1206 indent(buf, ++indent_level);
1207 buf << "new (buf + k * sizeof(" << class_name << ")) " << class_name << constr_arg << ";\n";
1208 indent(buf, --indent_level);
1209 buf << "*ret = buf;\n";
1210 }
1211 indent(buf, --indent_level);
1212 buf << "}\n";
1213 indent(buf, --indent_level);
1214 buf << "}\n";
1215 // else {
1216 // if (!nary) {
1217 // *ret = new (arena) ClassName;
1218 // }
1219 // else {
1220 // *ret = new (arena) ClassName[nary];
1221 // }
1222 // }
1223 indent(buf, indent_level);
1224 buf << "else {\n";
1225 indent(buf, ++indent_level);
1226 buf << "if (!nary) {\n";
1227 indent(buf, ++indent_level);
1228 buf << "*ret = new (arena) " << class_name << constr_arg << ";\n";
1229 indent(buf, --indent_level);
1230 buf << "}\n";
1231 indent(buf, indent_level);
1232 buf << "else {\n";
1233 indent(buf, ++indent_level);
1234 if (constr_arg.empty()) {
1235 buf << "*ret = new (arena) " << class_name << "[nary];\n";
1236 } else {
1237 buf << "for (int k=0;k<nary;++k)\n";
1238 indent(buf, ++indent_level);
1239 buf << "new ((char *) arena + k * sizeof(" << class_name << ")) " << class_name << constr_arg << ";\n";
1240 indent(buf, --indent_level);
1241 buf << "*ret = arena;\n";
1242 }
1243 indent(buf, --indent_level);
1244 buf << "}\n";
1245 indent(buf, --indent_level);
1246 buf << "}\n";
1247 // End wrapper.
1248 --indent_level;
1249 buf << "}\n";
1250 // Done.
1251 string wrapper(buf.str());
1252 //fprintf(stderr, "%s\n", wrapper.c_str());
1253 //
1254 // Compile the wrapper code.
1255 //
1257 /*withAccessControl=*/false);
1258 if (F) {
1259 gCtorWrapperStore.insert(make_pair(D, F));
1260 } else {
1261 ::Error("TClingCallFunc::make_ctor_wrapper",
1262 "Failed to compile\n ==== SOURCE BEGIN ====\n%s\n ==== SOURCE END ====",
1263 wrapper.c_str());
1264 }
1266}
1267
1270{
1271 // Make a code string that follows this pattern:
1272 //
1273 // void
1274 // unique_wrapper_ddd(void* obj, unsigned long nary, int withFree)
1275 // {
1276 // if (withFree) {
1277 // if (!nary) {
1278 // delete (ClassName*) obj;
1279 // }
1280 // else {
1281 // delete[] (ClassName*) obj;
1282 // }
1283 // }
1284 // else {
1285 // typedef ClassName DtorName;
1286 // if (!nary) {
1287 // ((ClassName*)obj)->~DtorName();
1288 // }
1289 // else {
1290 // for (unsigned long i = nary - 1; i > -1; --i) {
1291 // (((ClassName*)obj)+i)->~DtorName();
1292 // }
1293 // }
1294 // }
1295 // }
1296 //
1297 //--
1298
1300
1301 const Decl *D = info->GetDecl();
1302 auto I = gDtorWrapperStore.find(D);
1303 if (I != gDtorWrapperStore.end())
1304 return (tcling_callfunc_dtor_Wrapper_t)I->second;
1305
1306 //
1307 // Make the wrapper name.
1308 //
1309 std::string class_name;
1310 string wrapper_name = PrepareStructorWrapper(D, "__dtor", class_name);
1311 //
1312 // Write the wrapper code.
1313 //
1314 int indent_level = 0;
1315 ostringstream buf;
1316 buf << "__attribute__((used)) ";
1317 buf << "extern \"C\" void ";
1318 buf << wrapper_name;
1319 buf << "(void* obj, unsigned long nary, int withFree)\n";
1320 buf << "{\n";
1321 // if (withFree) {
1322 // if (!nary) {
1323 // delete (ClassName*) obj;
1324 // }
1325 // else {
1326 // delete[] (ClassName*) obj;
1327 // }
1328 // }
1329 ++indent_level;
1330 indent(buf, indent_level);
1331 buf << "if (withFree) {\n";
1332 ++indent_level;
1333 indent(buf, indent_level);
1334 buf << "if (!nary) {\n";
1335 ++indent_level;
1336 indent(buf, indent_level);
1337 buf << "delete (" << class_name << "*) obj;\n";
1338 --indent_level;
1339 indent(buf, indent_level);
1340 buf << "}\n";
1341 indent(buf, indent_level);
1342 buf << "else {\n";
1343 ++indent_level;
1344 indent(buf, indent_level);
1345 buf << "delete[] (" << class_name << "*) obj;\n";
1346 --indent_level;
1347 indent(buf, indent_level);
1348 buf << "}\n";
1349 --indent_level;
1350 indent(buf, indent_level);
1351 buf << "}\n";
1352 // else {
1353 // typedef ClassName Nm;
1354 // if (!nary) {
1355 // ((Nm*)obj)->~Nm();
1356 // }
1357 // else {
1358 // for (unsigned long i = nary - 1; i > -1; --i) {
1359 // (((Nm*)obj)+i)->~Nm();
1360 // }
1361 // }
1362 // }
1363 indent(buf, indent_level);
1364 buf << "else {\n";
1365 ++indent_level;
1366 indent(buf, indent_level);
1367 buf << "typedef " << class_name << " Nm;\n";
1368 buf << "if (!nary) {\n";
1369 ++indent_level;
1370 indent(buf, indent_level);
1371 buf << "((Nm*)obj)->~Nm();\n";
1372 --indent_level;
1373 indent(buf, indent_level);
1374 buf << "}\n";
1375 indent(buf, indent_level);
1376 buf << "else {\n";
1377 ++indent_level;
1378 indent(buf, indent_level);
1379 buf << "do {\n";
1380 ++indent_level;
1381 indent(buf, indent_level);
1382 buf << "(((Nm*)obj)+(--nary))->~Nm();\n";
1383 --indent_level;
1384 indent(buf, indent_level);
1385 buf << "} while (nary);\n";
1386 --indent_level;
1387 indent(buf, indent_level);
1388 buf << "}\n";
1389 --indent_level;
1390 indent(buf, indent_level);
1391 buf << "}\n";
1392 // End wrapper.
1393 --indent_level;
1394 buf << "}\n";
1395 // Done.
1396 string wrapper(buf.str());
1397 //fprintf(stderr, "%s\n", wrapper.c_str());
1398 //
1399 // Compile the wrapper code.
1400 //
1402 /*withAccessControl=*/false);
1403 if (F) {
1404 gDtorWrapperStore.insert(make_pair(D, F));
1405 } else {
1406 ::Error("TClingCallFunc::make_dtor_wrapper",
1407 "Failed to compile\n ==== SOURCE BEGIN ====\n%s\n ==== SOURCE END ====",
1408 wrapper.c_str());
1409 }
1410
1412}
1413
1414void TClingCallFunc::exec(void *address, void *ret)
1415{
1417 const unsigned num_args = fArgVals.size();
1418 {
1420 const FunctionDecl *FD = GetDecl();
1421
1422 // FIXME: Consider the implicit this which is sometimes not passed.
1424 ::Error("TClingCallFunc::exec",
1425 "Not enough arguments provided for %s (%d instead of the minimum %d)",
1426 fMethod->Name(),
1428 return;
1429 } else if (!isa<CXXMethodDecl>(FD) && num_args > FD->getNumParams()) {
1430 ::Error("TClingCallFunc::exec",
1431 "Too many arguments provided for %s (%d instead of the minimum %d)",
1432 fMethod->Name(),
1434 return;
1435 }
1436 if (auto CXXMD = dyn_cast<CXXMethodDecl>(FD))
1437 if (!address && CXXMD && !CXXMD->isStatic() && !isa<CXXConstructorDecl>(FD)) {
1438 ::Error("TClingCallFunc::exec",
1439 "The method %s is called without an object.",
1440 fMethod->Name());
1441 return;
1442 }
1443
1444 vp_ary.reserve(num_args);
1445 for (unsigned i = 0; i < num_args; ++i) {
1446 QualType QT;
1447 // Check if we provided a this parameter.
1448 // FIXME: Currently we do not provide consistently the this pointer at
1449 // index 0 of the call arguments passed to the wrapper.
1450 // In C++ we can still call member functions which do not use it. Eg:
1451 // struct S {int Print() { return printf("a");} }; auto r1 = ((S*)0)->Print();
1452 // This works just fine even though it might be UB...
1453 bool implicitThisPassed = i == 0 && isa<CXXMethodDecl>(FD) && num_args - FD->getNumParams() == 1;
1455 QT = cast<CXXMethodDecl>(FD)->getThisType();
1456 else
1457 QT = FD->getParamDecl(i)->getType();
1458 QT = QT.getCanonicalType();
1459 if (QT->isReferenceType() || QT->isRecordType()) {
1460 // the argument is already a pointer value (points to the same thing
1461 // as the reference or pointing to object passed by value.
1462 vp_ary.push_back(fArgVals[i].getPtr());
1463 } else {
1464 // Check if arguments need readjusting. This can happen if we called
1465 // cling::Value::Create which instantiates to say double but the
1466 // function signature requires a float.
1467 ASTContext &C = FD->getASTContext();
1468 if (QT->isBuiltinType() && !C.hasSameType(QT, fArgVals[i].getType())) {
1469 switch(QT->getAs<BuiltinType>()->getKind()) {
1470 default:
1471 ROOT::TMetaUtils::Error("TClingCallFunc::exec", "Unknown builtin type!");
1472#ifndef NDEBUG
1473 QT->dump();
1474#endif // NDEBUG
1475 break;
1476#define X(type, name) \
1477 case BuiltinType::name: fArgVals[i] = cling::Value::Create(*fInterp, fArgVals[i].castAs<type>()); break;
1479#undef X
1480 }
1481 }
1482 vp_ary.push_back(fArgVals[i].getPtrAddress());
1483 }
1484 }
1485 } // End of scope holding the lock
1486 (*fWrapper)(address, (int)num_args, (void **)vp_ary.data(), ret);
1487}
1488
1489void TClingCallFunc::exec_with_valref_return(void *address, cling::Value &ret)
1490{
1491 const FunctionDecl *FD = GetDecl();
1492
1493 QualType QT;
1494 if (llvm::isa<CXXConstructorDecl>(FD)) {
1496 ASTContext &Context = FD->getASTContext();
1498 QualType ClassTy(TD->getTypeForDecl(), 0);
1499 QT = Context.getLValueReferenceType(ClassTy);
1500 ret = cling::Value(QT, *fInterp);
1501 } else {
1502 QT = FD->getReturnType().getCanonicalType();
1503 ret = cling::Value(QT, *fInterp);
1504
1505 if (QT->isRecordType() || QT->isMemberDataPointerType())
1506 return exec(address, ret.getPtr());
1507 }
1508 exec(address, ret.getPtrAddress());
1509}
1510
1512{
1514
1516 fInterp->getLookupHelper().findArgList(ArgList, exprs,
1517 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
1518 : cling::LookupHelper::NoDiagnostics);
1520 E = exprs.end(); I != E; ++I) {
1521 cling::Value val;
1522 EvaluateExpr(*fInterp, *I, val);
1523 if (!val.isValid()) {
1524 // Bad expression, all done.
1525 ::Error("TClingCallFunc::EvaluateArgList",
1526 "Bad expression in parameter %d of '%s'!",
1527 (int)(I - exprs.begin()),
1528 ArgList.c_str());
1529 return;
1530 }
1531 fArgVals.push_back(val);
1532 }
1533}
1534
1536{
1537 IFacePtr();
1538 if (!fWrapper) {
1539 ::Error("TClingCallFunc::Exec(address, interpVal)",
1540 "Called with no wrapper, not implemented!");
1541 return;
1542 }
1543 if (!interpVal || !interpVal->GetValAddr()) {
1544 exec(address, nullptr);
1545 return;
1546 }
1547 cling::Value *val = reinterpret_cast<cling::Value *>(interpVal->GetValAddr());
1548 exec_with_valref_return(address, *val);
1549}
1550
1551template <typename T>
1553{
1554 IFacePtr();
1555 if (!fWrapper) {
1556 ::Error("TClingCallFunc::ExecT",
1557 "Called with no wrapper, not implemented!");
1558 return 0;
1559 }
1560 cling::Value ret;
1561 exec_with_valref_return(address, ret);
1562 if (ret.isVoid()) {
1563 return 0;
1564 }
1565
1566 if (ret.needsManagedAllocation())
1567 ((TCling *)gCling)->RegisterTemporary(ret);
1568
1569 return ret.castAs<T>();
1570}
1571
1573{
1574 return ExecT<Longptr_t>(address);
1575}
1576
1577long long TClingCallFunc::ExecInt64(void *address)
1578{
1579 return ExecT<long long>(address);
1580}
1581
1582double TClingCallFunc::ExecDouble(void *address)
1583{
1584 return ExecT<double>(address);
1585}
1586
1587void TClingCallFunc::ExecWithArgsAndReturn(void *address, const void *args[] /*= 0*/,
1588 int nargs /*= 0*/, void *ret/*= 0*/)
1589{
1590 IFacePtr();
1591 if (!fWrapper) {
1592 ::Error("TClingCallFunc::ExecWithArgsAndReturn(address, args, ret)",
1593 "Called with no wrapper, not implemented!");
1594 return;
1595 }
1596 (*fWrapper)(address, nargs, const_cast<void **>(args), ret);
1597}
1598
1599void TClingCallFunc::ExecWithReturn(void *address, void *ret/*= 0*/)
1600{
1601 IFacePtr();
1602 if (!fWrapper) {
1603 ::Error("TClingCallFunc::ExecWithReturn(address, ret)",
1604 "Called with no wrapper, not implemented!");
1605 return;
1606 }
1607 exec(address, ret);
1608}
1609
1612 const std::string &type_name,
1613 void *address /*=0*/, unsigned long nary /*= 0UL*/)
1614{
1615 if (!info->IsValid()) {
1616 ::Error("TClingCallFunc::ExecDefaultConstructor", "Invalid class info!");
1617 return nullptr;
1618 }
1620 //if (!info->HasDefaultConstructor()) {
1621 // // FIXME: We might have a ROOT ioctor, we might
1622 // // have to check for that here.
1623 // ::Error("TClingCallFunc::ExecDefaultConstructor",
1624 // "Class has no default constructor: %s",
1625 // info->Name());
1626 // return 0;
1627 //}
1628 void *obj = nullptr;
1629 (*wrapper)(&obj, address, nary);
1630 return obj;
1631 }
1632 ::Error("TClingCallFunc::ExecDefaultConstructor", "Called with no wrapper, not implemented!");
1633 return nullptr;
1634}
1635
1636void TClingCallFunc::ExecDestructor(const TClingClassInfo *info, void *address /*=0*/,
1637 unsigned long nary /*= 0UL*/, bool withFree /*= true*/)
1638{
1639 if (!info->IsValid()) {
1640 ::Error("TClingCallFunc::ExecDestructor", "Invalid class info!");
1641 return;
1642 }
1643
1645 (*wrapper)(address, nary, withFree);
1646 return;
1647 }
1648
1649 ::Error("TClingCallFunc::ExecDestructor", "Called with no wrapper, not implemented!");
1650}
1651
1654{
1655 return new TClingMethodInfo(*fMethod);
1656}
1657
1659{
1660 fMethod.reset();
1661 fWrapper = nullptr;
1662 fDecl = nullptr;
1664 ResetArg();
1665}
1666
1668{
1669 Init();
1670 fMethod = std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(minfo));
1671}
1672
1673void TClingCallFunc::Init(std::unique_ptr<TClingMethodInfo> minfo)
1674{
1675 Init();
1676 fMethod = std::move(minfo);
1677}
1678
1680{
1681 if (!IsValid()) {
1682 return nullptr;
1683 }
1684
1685 if (!fWrapper)
1687
1688 return (void *)fWrapper.load();
1689}
1690
1692{
1693 if (!fMethod) {
1694 return false;
1695 }
1696 return fMethod->IsValid();
1697}
1698
1700{
1701 if (!IsValid()) {
1702 ::Error("TClingCallFunc::IFacePtr(kind)",
1703 "Attempt to get interface while invalid.");
1705 }
1706
1707 if (!fWrapper)
1709
1711}
1712
1713
1715{
1716 fArgVals.clear();
1717}
1718
1720{
1721 ResetArg();
1722 for (int i = 0; i < nparam; ++i) {
1723 SetArg(paramArr[i]);
1724 }
1725}
1726
1727void TClingCallFunc::SetArgs(const char *params)
1728{
1729 ResetArg();
1730 EvaluateArgList(params);
1731}
1732
1733void TClingCallFunc::SetFunc(const TClingClassInfo *info, const char *method, const char *arglist,
1735{
1736 SetFunc(info, method, arglist, false, poffset);
1737}
1738
1739void TClingCallFunc::SetFunc(const TClingClassInfo *info, const char *method, const char *arglist,
1741{
1742 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(fInterp)));
1743 if (poffset) {
1744 *poffset = 0L;
1745 }
1746 ResetArg();
1747 if (!info->IsValid()) {
1748 ::Error("TClingCallFunc::SetFunc", "Class info is invalid!");
1749 return;
1750 }
1751 if (!strcmp(arglist, ")")) {
1752 // CINT accepted a single right paren as meaning no arguments.
1753 arglist = "";
1754 }
1755 *fMethod = info->GetMethodWithArgs(method, arglist, objectIsConst, poffset);
1756 if (!fMethod->IsValid()) {
1757 //::Error("TClingCallFunc::SetFunc", "Could not find method %s(%s)", method,
1758 // arglist);
1759 return;
1760 }
1761 // FIXME: The arglist was already parsed by the lookup, we should
1762 // enhance the lookup to return the resulting expression
1763 // list so we do not need to parse it again here.
1765}
1766
1768{
1769 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(*info)));
1770 ResetArg();
1771 if (!fMethod->IsValid()) {
1772 return;
1773 }
1774}
1775
1777 const char *proto, Longptr_t *poffset,
1778 EFunctionMatchMode mode/*=kConversionMatch*/)
1779{
1780 SetFuncProto(info, method, proto, false, poffset, mode);
1781}
1782
1784 const char *proto, bool objectIsConst, Longptr_t *poffset,
1785 EFunctionMatchMode mode/*=kConversionMatch*/)
1786{
1787 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(fInterp)));
1788 if (poffset) {
1789 *poffset = 0L;
1790 }
1791 ResetArg();
1792 if (!info->IsValid()) {
1793 ::Error("TClingCallFunc::SetFuncProto", "Class info is invalid!");
1794 return;
1795 }
1796 *fMethod = info->GetMethod(method, proto, objectIsConst, poffset, mode);
1797 if (!fMethod->IsValid()) {
1798 //::Error("TClingCallFunc::SetFuncProto", "Could not find method %s(%s)",
1799 // method, proto);
1800 return;
1801 }
1802}
1803
1805 const llvm::SmallVectorImpl<clang::QualType> &proto, Longptr_t *poffset,
1806 EFunctionMatchMode mode/*=kConversionMatch*/)
1807{
1808 SetFuncProto(info, method, proto, false, poffset, mode);
1809}
1810
1812 const llvm::SmallVectorImpl<clang::QualType> &proto,
1814 EFunctionMatchMode mode/*=kConversionMatch*/)
1815{
1816 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(fInterp)));
1817 if (poffset) {
1818 *poffset = 0L;
1819 }
1820 ResetArg();
1821 if (!info->IsValid()) {
1822 ::Error("TClingCallFunc::SetFuncProto", "Class info is invalid!");
1823 return;
1824 }
1825 *fMethod = info->GetMethod(method, proto, objectIsConst, poffset, mode);
1826 if (!fMethod->IsValid()) {
1827 //::Error("TClingCallFunc::SetFuncProto", "Could not find method %s(%s)",
1828 // method, proto);
1829 return;
1830 }
1831}
1832
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 map< const Decl *, void * > gCtorWrapperStore
static void GetDeclName(const clang::Decl *D, ASTContext &Context, std::string &name)
static const string kIndentString(" ")
static void indent(ostringstream &buf, int indent_level)
static map< const Decl *, void * > gDtorWrapperStore
static map< const Decl *, void * > gWrapperStore
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:622
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