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-2022, 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 namespace std;
78
79static unsigned long long gWrapperSerial = 0LL;
80static const string kIndentString(" ");
81
82static map<const Decl *, void *> gWrapperStore;
83static map<const Decl *, void *> gCtorWrapperStore;
84static map<const Decl *, void *> gDtorWrapperStore;
85
86static
87inline
88void
89indent(ostringstream &buf, int indent_level)
90{
91 for (int i = 0; i < indent_level; ++i) {
92 buf << kIndentString;
93 }
94}
95
96static
97void
98EvaluateExpr(cling::Interpreter &interp, const Expr *E, cling::Value &V)
99{
100 // Evaluate an Expr* and return its cling::Value
101 ASTContext &C = interp.getCI()->getASTContext();
102 clang::Expr::EvalResult evalRes;
103 if (E->EvaluateAsInt(evalRes, C, /*AllowSideEffects*/Expr::SE_NoSideEffects)) {
104 APSInt res = evalRes.Val.getInt();
105 // IntTy or maybe better E->getType()?
106 V = cling::Value(C.IntTy, interp);
107 // We must use the correct signedness otherwise the zero extension
108 // fails if the actual type is strictly less than long long.
109 if (res.isSigned())
110 V.getLL() = res.getSExtValue();
111 else
112 V.getULL() = res.getZExtValue();
113 return;
114 }
115 // TODO: Build a wrapper around the expression to avoid decompilation and
116 // compilation and other string operations.
117 PrintingPolicy Policy(C.getPrintingPolicy());
118 Policy.SuppressTagKeyword = true;
119 Policy.SuppressUnwrittenScope = false;
120 Policy.SuppressInitializers = false;
121 Policy.AnonymousTagLocations = false;
122 string buf;
123 raw_string_ostream out(buf);
124 E->printPretty(out, /*Helper=*/0, Policy, /*Indentation=*/0);
125 out << ';'; // no value printing
126 out.flush();
127 // Evaluate() will set V to invalid if evaluation fails.
128 interp.evaluate(buf, V);
129}
130
132{
133 // This function is non-const to use caching overload of GetDecl()!
134 return GetDecl()->getMinRequiredArguments();
135}
136
137void *TClingCallFunc::compile_wrapper(const string &wrapper_name, const string &wrapper,
138 bool withAccessControl/*=true*/)
139{
140 return fInterp->compileFunction(wrapper_name, wrapper, false /*ifUnique*/,
141 withAccessControl);
142}
143
144static void GetTypeAsString(QualType QT, string& type_name, ASTContext &C,
145 PrintingPolicy Policy) {
146
147 // FIXME: Take the code here https://github.com/root-project/root/blob/550fb2644f3c07d1db72b9b4ddc4eba5a99ddc12/interpreter/cling/lib/Utils/AST.cpp#L316-L350
148 // to make hist/histdrawv7/test/histhistdrawv7testUnit work into
149 // QualTypeNames.h in clang
150 //type_name = clang::TypeName::getFullyQualifiedName(QT, C, Policy);
151 cling::utils::Transform::Config Config;
152 QT = cling::utils::Transform::GetPartiallyDesugaredType(C, QT, Config, /*fullyQualify=*/true);
153 QT.getAsStringInternal(type_name, Policy);
154}
155
156void TClingCallFunc::collect_type_info(QualType &QT, ostringstream &typedefbuf, std::ostringstream &callbuf,
157 string &type_name, EReferenceType &refType, bool &isPointer, int indent_level,
158 bool forArgument)
159{
160 //
161 // Collect information about type type of a function parameter
162 // needed for building the wrapper function.
163 //
164 const FunctionDecl *FD = GetDecl();
165 ASTContext &C = FD->getASTContext();
166 PrintingPolicy Policy(C.getPrintingPolicy());
167 refType = kNotReference;
168 if (QT->isRecordType() && forArgument) {
169 GetTypeAsString(QT, type_name, C, Policy);
170 return;
171 }
172 if (QT->isFunctionPointerType()) {
173 string fp_typedef_name;
174 {
175 ostringstream nm;
176 nm << "FP" << gWrapperSerial++;
177 type_name = nm.str();
178 raw_string_ostream OS(fp_typedef_name);
179 QT.print(OS, Policy, type_name);
180 OS.flush();
181 }
182 for (int i = 0; i < indent_level; ++i) {
183 typedefbuf << kIndentString;
184 }
185 typedefbuf << "typedef " << fp_typedef_name << ";\n";
186 return;
187 } else if (QT->isMemberPointerType()) {
188 string mp_typedef_name;
189 {
190 ostringstream nm;
191 nm << "MP" << gWrapperSerial++;
192 type_name = nm.str();
193 raw_string_ostream OS(mp_typedef_name);
194 QT.print(OS, Policy, type_name);
195 OS.flush();
196 }
197 for (int i = 0; i < indent_level; ++i) {
198 typedefbuf << kIndentString;
199 }
200 typedefbuf << "typedef " << mp_typedef_name << ";\n";
201 return;
202 } else if (QT->isPointerType()) {
203 isPointer = true;
204 QT = cast<clang::PointerType>(QT)->getPointeeType();
205 } else if (QT->isReferenceType()) {
206 if (QT->isRValueReferenceType()) refType = kRValueReference;
207 else refType = kLValueReference;
208 QT = cast<ReferenceType>(QT)->getPointeeType();
209 }
210 // Fall through for the array type to deal with reference/pointer ro array type.
211 if (QT->isArrayType()) {
212 string ar_typedef_name;
213 {
214 ostringstream ar;
215 ar << "AR" << gWrapperSerial++;
216 type_name = ar.str();
217 raw_string_ostream OS(ar_typedef_name);
218 QT.print(OS, Policy, type_name);
219 OS.flush();
220 }
221 for (int i = 0; i < indent_level; ++i) {
222 typedefbuf << kIndentString;
223 }
224 typedefbuf << "typedef " << ar_typedef_name << ";\n";
225 return;
226 }
227 GetTypeAsString(QT, type_name, C, Policy);
228}
229
230void TClingCallFunc::make_narg_ctor(const unsigned N, ostringstream &typedefbuf,
231 ostringstream &callbuf, const string &class_name,
232 int indent_level)
233{
234 // Make a code string that follows this pattern:
235 //
236 // new ClassName(args...)
237 //
238 const FunctionDecl *FD = GetDecl();
239
240 callbuf << "new " << class_name << "(";
241 for (unsigned i = 0U; i < N; ++i) {
242 const ParmVarDecl *PVD = FD->getParamDecl(i);
243 QualType Ty = PVD->getType();
244 QualType QT = Ty.getCanonicalType();
245 string type_name;
247 bool isPointer = false;
248 collect_type_info(QT, typedefbuf, callbuf, type_name,
249 refType, isPointer, indent_level, true);
250 if (i) {
251 callbuf << ',';
252 if (i % 2) {
253 callbuf << ' ';
254 } else {
255 callbuf << "\n";
256 for (int j = 0; j <= indent_level; ++j) {
257 callbuf << kIndentString;
258 }
259 }
260 }
261 if (refType != kNotReference) {
262 callbuf << "(" << type_name.c_str() <<
263 (refType == kLValueReference ? "&" : "&&") << ")*(" << type_name.c_str() << "*)args["
264 << i << "]";
265 } else if (isPointer) {
266 callbuf << "*(" << type_name.c_str() << "**)args["
267 << i << "]";
268 } else {
269 callbuf << "*(" << type_name.c_str() << "*)args[" << i << "]";
270 }
271 }
272 callbuf << ")";
273}
274
275void TClingCallFunc::make_narg_call(const std::string &return_type, const unsigned N, ostringstream &typedefbuf,
276 ostringstream &callbuf, const string &class_name, int indent_level)
277{
278 //
279 // Make a code string that follows this pattern:
280 //
281 // ((<class>*)obj)-><method>(*(<arg-i-type>*)args[i], ...)
282 //
283 const FunctionDecl *FD = GetDecl();
284
285 // Sometimes it's necessary that we cast the function we want to call first
286 // to its explicit function type before calling it. This is supposed to prevent
287 // that we accidentially ending up in a function that is not the one we're
288 // supposed to call here (e.g. because the C++ function lookup decides to take
289 // another function that better fits).
290 // This method has some problems, e.g. when we call a function with default
291 // arguments and we don't provide all arguments, we would fail with this pattern.
292 // Same applies with member methods which seem to cause parse failures even when
293 // we supply the object parameter.
294 // Therefore we only use it in cases where we know it works and set this variable
295 // to true when we do.
296 bool ShouldCastFunction = !isa<CXXMethodDecl>(FD) && N == FD->getNumParams();
297 if (ShouldCastFunction) {
298 callbuf << "(";
299 callbuf << "(";
300 callbuf << return_type << " (&)";
301 {
302 callbuf << "(";
303 for (unsigned i = 0U; i < N; ++i) {
304 if (i) {
305 callbuf << ',';
306 if (i % 2) {
307 callbuf << ' ';
308 } else {
309 callbuf << "\n";
310 for (int j = 0; j <= indent_level; ++j) {
311 callbuf << kIndentString;
312 }
313 }
314 }
315 const ParmVarDecl *PVD = FD->getParamDecl(i);
316 QualType Ty = PVD->getType();
317 QualType QT = Ty.getCanonicalType();
318 std::string arg_type;
319 ASTContext &C = FD->getASTContext();
320 GetTypeAsString(QT, arg_type, C, C.getPrintingPolicy());
321 callbuf << arg_type;
322 }
323 if (FD->isVariadic())
324 callbuf << ", ...";
325 callbuf << ")";
326 }
327
328 callbuf << ")";
329 }
330
331 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
332 // This is a class, struct, or union member.
333 if (MD->isConst())
334 callbuf << "((const " << class_name << "*)obj)->";
335 else
336 callbuf << "((" << class_name << "*)obj)->";
337 } else if (const NamedDecl *ND =
338 dyn_cast<NamedDecl>(GetDeclContext())) {
339 // This is a namespace member.
340 (void) ND;
341 callbuf << class_name << "::";
342 }
343 // callbuf << fMethod->Name() << "(";
344 {
345 std::string name;
346 {
347 llvm::raw_string_ostream stream(name);
348 FD->getNameForDiagnostic(stream, FD->getASTContext().getPrintingPolicy(), /*Qualified=*/false);
349 }
350 callbuf << name;
351 }
352 if (ShouldCastFunction) callbuf << ")";
353
354 callbuf << "(";
355 for (unsigned i = 0U; i < N; ++i) {
356 const ParmVarDecl *PVD = FD->getParamDecl(i);
357 QualType Ty = PVD->getType();
358 QualType QT = Ty.getCanonicalType();
359 string type_name;
361 bool isPointer = false;
362 collect_type_info(QT, typedefbuf, callbuf, type_name, refType, isPointer, indent_level, true);
363
364 if (i) {
365 callbuf << ',';
366 if (i % 2) {
367 callbuf << ' ';
368 } else {
369 callbuf << "\n";
370 for (int j = 0; j <= indent_level; ++j) {
371 callbuf << kIndentString;
372 }
373 }
374 }
375
376 if (refType != kNotReference) {
377 callbuf << "(" << type_name.c_str() <<
378 (refType == kLValueReference ? "&" : "&&") << ")*(" << type_name.c_str() << "*)args["
379 << i << "]";
380 } else if (isPointer) {
381 callbuf << "*(" << type_name.c_str() << "**)args["
382 << i << "]";
383 } else {
384 // pointer falls back to non-pointer case; the argument preserves
385 // the "pointerness" (i.e. doesn't reference the value).
386 callbuf << "*(" << type_name.c_str() << "*)args[" << i << "]";
387 }
388 }
389 callbuf << ")";
390}
391
392void TClingCallFunc::make_narg_ctor_with_return(const unsigned N, const string &class_name,
393 ostringstream &buf, int indent_level)
394{
395 // Make a code string that follows this pattern:
396 //
397 // if (ret) {
398 // (*(ClassName**)ret) = new ClassName(args...);
399 // }
400 // else {
401 // new ClassName(args...);
402 // }
403 //
404 for (int i = 0; i < indent_level; ++i) {
405 buf << kIndentString;
406 }
407 buf << "if (ret) {\n";
408 ++indent_level;
409 {
410 ostringstream typedefbuf;
411 ostringstream callbuf;
412 //
413 // Write the return value assignment part.
414 //
415 for (int i = 0; i < indent_level; ++i) {
416 callbuf << kIndentString;
417 }
418 callbuf << "(*(" << class_name << "**)ret) = ";
419 //
420 // Write the actual new expression.
421 //
422 make_narg_ctor(N, typedefbuf, callbuf, class_name, indent_level);
423 //
424 // End the new expression statement.
425 //
426 callbuf << ";\n";
427 for (int i = 0; i < indent_level; ++i) {
428 callbuf << kIndentString;
429 }
430 callbuf << "return;\n";
431 //
432 // Output the whole new expression and return statement.
433 //
434 buf << typedefbuf.str() << callbuf.str();
435 }
436 --indent_level;
437 for (int i = 0; i < indent_level; ++i) {
438 buf << kIndentString;
439 }
440 buf << "}\n";
441 for (int i = 0; i < indent_level; ++i) {
442 buf << kIndentString;
443 }
444 buf << "else {\n";
445 ++indent_level;
446 {
447 ostringstream typedefbuf;
448 ostringstream callbuf;
449 for (int i = 0; i < indent_level; ++i) {
450 callbuf << kIndentString;
451 }
452 make_narg_ctor(N, typedefbuf, callbuf, class_name, indent_level);
453 callbuf << ";\n";
454 for (int i = 0; i < indent_level; ++i) {
455 callbuf << kIndentString;
456 }
457 callbuf << "return;\n";
458 buf << typedefbuf.str() << callbuf.str();
459 }
460 --indent_level;
461 for (int i = 0; i < indent_level; ++i) {
462 buf << kIndentString;
463 }
464 buf << "}\n";
465}
466
467///////////////////////////////////////////////////////////////////////////////
468// Returns the DeclContext corresponding to fMethod's Decl.
469// \Note that this might be a FunctionDecl or a UsingShadowDecl; we use the
470// DeclContext of the UsingShadowDecl e.g. for constructing a derived class
471// object, even if invoking a function made available by a using declaration
472// of a constructor of a base class (ROOT-11010).
473
474const clang::DeclContext *TClingCallFunc::GetDeclContext() const {
475 return fMethod->GetDecl()->getDeclContext();
476}
477
478int TClingCallFunc::get_wrapper_code(std::string &wrapper_name, std::string &wrapper)
479{
480 const FunctionDecl *FD = GetDecl();
481 assert(FD && "generate_wrapper called without a function decl!");
482 ASTContext &Context = FD->getASTContext();
483 PrintingPolicy Policy(Context.getPrintingPolicy());
484 //
485 // Get the class or namespace name.
486 //
487 string class_name;
488 const clang::DeclContext *DC = GetDeclContext();
489 if (const TypeDecl *TD = dyn_cast<TypeDecl>(DC)) {
490 // This is a class, struct, or union member.
491 QualType QT(TD->getTypeForDecl(), 0);
492 GetTypeAsString(QT, class_name, Context, Policy);
493 } else if (const NamedDecl *ND = dyn_cast<NamedDecl>(DC)) {
494 // This is a namespace member.
495 raw_string_ostream stream(class_name);
496 ND->getNameForDiagnostic(stream, Policy, /*Qualified=*/true);
497 stream.flush();
498 }
499 //
500 // Check to make sure that we can
501 // instantiate and codegen this function.
502 //
503 bool needInstantiation = false;
504 const FunctionDecl *Definition = 0;
505 if (!FD->isDefined(Definition)) {
506 FunctionDecl::TemplatedKind TK = FD->getTemplatedKind();
507 switch (TK) {
508 case FunctionDecl::TK_NonTemplate: {
509 // Ordinary function, not a template specialization.
510 // Note: This might be ok, the body might be defined
511 // in a library, and all we have seen is the
512 // header file.
513 //::Error("TClingCallFunc::make_wrapper",
514 // "Cannot make wrapper for a function which is "
515 // "declared but not defined!");
516 // return 0;
517 } break;
518 case FunctionDecl::TK_FunctionTemplate: {
519 // This decl is actually a function template,
520 // not a function at all.
521 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a function template!");
522 return 0;
523 } break;
524 case FunctionDecl::TK_MemberSpecialization: {
525 // This function is the result of instantiating an ordinary
526 // member function of a class template, or of instantiating
527 // an ordinary member function of a class member of a class
528 // template, or of specializing a member function template
529 // of a class template, or of specializing a member function
530 // template of a class member of a class template.
531 if (!FD->isTemplateInstantiation()) {
532 // We are either TSK_Undeclared or
533 // TSK_ExplicitSpecialization.
534 // Note: This might be ok, the body might be defined
535 // in a library, and all we have seen is the
536 // header file.
537 //::Error("TClingCallFunc::make_wrapper",
538 // "Cannot make wrapper for a function template "
539 // "explicit specialization which is declared "
540 // "but not defined!");
541 // return 0;
542 break;
543 }
544 const FunctionDecl *Pattern = FD->getTemplateInstantiationPattern();
545 if (!Pattern) {
546 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a member function "
547 "instantiation with no pattern!");
548 return 0;
549 }
550 FunctionDecl::TemplatedKind PTK = Pattern->getTemplatedKind();
551 TemplateSpecializationKind PTSK = Pattern->getTemplateSpecializationKind();
552 if (
553 // The pattern is an ordinary member function.
554 (PTK == FunctionDecl::TK_NonTemplate) ||
555 // The pattern is an explicit specialization, and
556 // so is not a template.
557 ((PTK != FunctionDecl::TK_FunctionTemplate) &&
558 ((PTSK == TSK_Undeclared) || (PTSK == TSK_ExplicitSpecialization)))) {
559 // Note: This might be ok, the body might be defined
560 // in a library, and all we have seen is the
561 // header file.
562 break;
563 } else if (!Pattern->hasBody()) {
564 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a member function "
565 "instantiation with no body!");
566 return 0;
567 }
568 if (FD->isImplicitlyInstantiable()) {
569 needInstantiation = true;
570 }
571 } break;
572 case FunctionDecl::TK_FunctionTemplateSpecialization: {
573 // This function is the result of instantiating a function
574 // template or possibly an explicit specialization of a
575 // function template. Could be a namespace scope function or a
576 // member function.
577 if (!FD->isTemplateInstantiation()) {
578 // We are either TSK_Undeclared or
579 // TSK_ExplicitSpecialization.
580 // Note: This might be ok, the body might be defined
581 // in a library, and all we have seen is the
582 // header file.
583 //::Error("TClingCallFunc::make_wrapper",
584 // "Cannot make wrapper for a function template "
585 // "explicit specialization which is declared "
586 // "but not defined!");
587 // return 0;
588 break;
589 }
590 const FunctionDecl *Pattern = FD->getTemplateInstantiationPattern();
591 if (!Pattern) {
592 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a function template"
593 "instantiation with no pattern!");
594 return 0;
595 }
596 FunctionDecl::TemplatedKind PTK = Pattern->getTemplatedKind();
597 TemplateSpecializationKind PTSK = Pattern->getTemplateSpecializationKind();
598 if (
599 // The pattern is an ordinary member function.
600 (PTK == FunctionDecl::TK_NonTemplate) ||
601 // The pattern is an explicit specialization, and
602 // so is not a template.
603 ((PTK != FunctionDecl::TK_FunctionTemplate) &&
604 ((PTSK == TSK_Undeclared) || (PTSK == TSK_ExplicitSpecialization)))) {
605 // Note: This might be ok, the body might be defined
606 // in a library, and all we have seen is the
607 // header file.
608 break;
609 }
610 if (!Pattern->hasBody()) {
611 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a function template"
612 "instantiation with no body!");
613 return 0;
614 }
615 if (FD->isImplicitlyInstantiable()) {
616 needInstantiation = true;
617 }
618 } break;
619 case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
620 // This function is the result of instantiating or
621 // specializing a member function of a class template,
622 // or a member function of a class member of a class template,
623 // or a member function template of a class template, or a
624 // member function template of a class member of a class
625 // template where at least some part of the function is
626 // dependent on a template argument.
627 if (!FD->isTemplateInstantiation()) {
628 // We are either TSK_Undeclared or
629 // TSK_ExplicitSpecialization.
630 // Note: This might be ok, the body might be defined
631 // in a library, and all we have seen is the
632 // header file.
633 //::Error("TClingCallFunc::make_wrapper",
634 // "Cannot make wrapper for a dependent function "
635 // "template explicit specialization which is declared "
636 // "but not defined!");
637 // return 0;
638 break;
639 }
640 const FunctionDecl *Pattern = FD->getTemplateInstantiationPattern();
641 if (!Pattern) {
642 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a dependent function template"
643 "instantiation with no pattern!");
644 return 0;
645 }
646 FunctionDecl::TemplatedKind PTK = Pattern->getTemplatedKind();
647 TemplateSpecializationKind PTSK = Pattern->getTemplateSpecializationKind();
648 if (
649 // The pattern is an ordinary member function.
650 (PTK == FunctionDecl::TK_NonTemplate) ||
651 // The pattern is an explicit specialization, and
652 // so is not a template.
653 ((PTK != FunctionDecl::TK_FunctionTemplate) &&
654 ((PTSK == TSK_Undeclared) || (PTSK == TSK_ExplicitSpecialization)))) {
655 // Note: This might be ok, the body might be defined
656 // in a library, and all we have seen is the
657 // header file.
658 break;
659 }
660 if (!Pattern->hasBody()) {
661 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a dependent function template"
662 "instantiation with no body!");
663 return 0;
664 }
665 if (FD->isImplicitlyInstantiable()) {
666 needInstantiation = true;
667 }
668 } break;
669 default: {
670 // Will only happen if clang implementation changes.
671 // Protect ourselves in case that happens.
672 ::Error("TClingCallFunc::make_wrapper", "Unhandled template kind!");
673 return 0;
674 } break;
675 }
676 // We do not set needInstantiation to true in these cases:
677 //
678 // isInvalidDecl()
679 // TSK_Undeclared
680 // TSK_ExplicitInstantiationDefinition
681 // TSK_ExplicitSpecialization && !getClassScopeSpecializationPattern()
682 // TSK_ExplicitInstantiationDeclaration &&
683 // getTemplateInstantiationPattern() &&
684 // PatternDecl->hasBody() &&
685 // !PatternDecl->isInlined()
686 //
687 // Set it true in these cases:
688 //
689 // TSK_ImplicitInstantiation
690 // TSK_ExplicitInstantiationDeclaration && (!getPatternDecl() ||
691 // !PatternDecl->hasBody() || PatternDecl->isInlined())
692 //
693 }
694 if (needInstantiation) {
695 clang::FunctionDecl *FDmod = const_cast<clang::FunctionDecl *>(FD);
696 clang::Sema &S = fInterp->getSema();
697 // Could trigger deserialization of decls.
698 cling::Interpreter::PushTransactionRAII RAII(fInterp);
699 S.InstantiateFunctionDefinition(SourceLocation(), FDmod,
700 /*Recursive=*/true,
701 /*DefinitionRequired=*/true);
702 if (!FD->isDefined(Definition)) {
703 ::Error("TClingCallFunc::make_wrapper", "Failed to force template instantiation!");
704 return 0;
705 }
706 }
707 if (Definition) {
708 FunctionDecl::TemplatedKind TK = Definition->getTemplatedKind();
709 switch (TK) {
710 case FunctionDecl::TK_NonTemplate: {
711 // Ordinary function, not a template specialization.
712 if (Definition->isDeleted()) {
713 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a deleted function!");
714 return 0;
715 } else if (Definition->isLateTemplateParsed()) {
716 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a late template parsed "
717 "function!");
718 return 0;
719 }
720 // else if (Definition->isDefaulted()) {
721 // // Might not have a body, but we can still use it.
722 //}
723 // else {
724 // // Has a body.
725 //}
726 } break;
727 case FunctionDecl::TK_FunctionTemplate: {
728 // This decl is actually a function template,
729 // not a function at all.
730 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a function template!");
731 return 0;
732 } break;
733 case FunctionDecl::TK_MemberSpecialization: {
734 // This function is the result of instantiating an ordinary
735 // member function of a class template or of a member class
736 // of a class template.
737 if (Definition->isDeleted()) {
738 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a deleted member function "
739 "of a specialization!");
740 return 0;
741 } else if (Definition->isLateTemplateParsed()) {
742 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a late template parsed "
743 "member function of a specialization!");
744 return 0;
745 }
746 // else if (Definition->isDefaulted()) {
747 // // Might not have a body, but we can still use it.
748 //}
749 // else {
750 // // Has a body.
751 //}
752 } break;
753 case FunctionDecl::TK_FunctionTemplateSpecialization: {
754 // This function is the result of instantiating a function
755 // template or possibly an explicit specialization of a
756 // function template. Could be a namespace scope function or a
757 // member function.
758 if (Definition->isDeleted()) {
759 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a deleted function "
760 "template specialization!");
761 return 0;
762 } else if (Definition->isLateTemplateParsed()) {
763 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a late template parsed "
764 "function template specialization!");
765 return 0;
766 }
767 // else if (Definition->isDefaulted()) {
768 // // Might not have a body, but we can still use it.
769 //}
770 // else {
771 // // Has a body.
772 //}
773 } break;
774 case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
775 // This function is the result of instantiating or
776 // specializing a member function of a class template,
777 // or a member function of a class member of a class template,
778 // or a member function template of a class template, or a
779 // member function template of a class member of a class
780 // template where at least some part of the function is
781 // dependent on a template argument.
782 if (Definition->isDeleted()) {
783 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a deleted dependent function "
784 "template specialization!");
785 return 0;
786 } else if (Definition->isLateTemplateParsed()) {
787 ::Error("TClingCallFunc::make_wrapper", "Cannot make wrapper for a late template parsed "
788 "dependent function template specialization!");
789 return 0;
790 }
791 // else if (Definition->isDefaulted()) {
792 // // Might not have a body, but we can still use it.
793 //}
794 // else {
795 // // Has a body.
796 //}
797 } break;
798 default: {
799 // Will only happen if clang implementation changes.
800 // Protect ourselves in case that happens.
801 ::Error("TClingCallFunc::make_wrapper", "Unhandled template kind!");
802 return 0;
803 } break;
804 }
805 }
806 unsigned min_args = GetMinRequiredArguments();
807 unsigned num_params = FD->getNumParams();
808 //
809 // Make the wrapper name.
810 //
811 {
812 ostringstream buf;
813 buf << "__cf";
814 // const NamedDecl* ND = dyn_cast<NamedDecl>(FD);
815 // string mn;
816 // fInterp->maybeMangleDeclName(ND, mn);
817 // buf << '_' << mn;
818 buf << '_' << gWrapperSerial++;
819 wrapper_name = buf.str();
820 }
821 //
822 // Write the wrapper code.
823 // FIXME: this should be synthesized into the AST!
824 //
825 int indent_level = 0;
826 ostringstream buf;
827 buf << "#pragma clang diagnostic push\n"
828 "#pragma clang diagnostic ignored \"-Wformat-security\"\n"
829 "__attribute__((used)) "
830 "__attribute__((annotate(\"__cling__ptrcheck(off)\")))\n"
831 "extern \"C\" void ";
832 buf << wrapper_name;
833 buf << "(void* obj, int nargs, void** args, void* ret)\n"
834 "{\n";
835 ++indent_level;
836 if (min_args == num_params) {
837 // No parameters with defaults.
838 make_narg_call_with_return(num_params, class_name, buf, indent_level);
839 } else {
840 // We need one function call clause compiled for every
841 // possible number of arguments per call.
842 for (unsigned N = min_args; N <= num_params; ++N) {
843 for (int i = 0; i < indent_level; ++i) {
844 buf << kIndentString;
845 }
846 buf << "if (nargs == " << N << ") {\n";
847 ++indent_level;
848 make_narg_call_with_return(N, class_name, buf, indent_level);
849 --indent_level;
850 for (int i = 0; i < indent_level; ++i) {
851 buf << kIndentString;
852 }
853 buf << "}\n";
854 }
855 }
856 --indent_level;
857 buf << "}\n"
858 "#pragma clang diagnostic pop";
859 wrapper = buf.str();
860 return 1;
861}
862
863void TClingCallFunc::make_narg_call_with_return(const unsigned N, const string &class_name,
864 ostringstream &buf, int indent_level)
865{
866 // Make a code string that follows this pattern:
867 //
868 // if (ret) {
869 // new (ret) (return_type) ((class_name*)obj)->func(args...);
870 // }
871 // else {
872 // (void)(((class_name*)obj)->func(args...));
873 // }
874 //
875 const FunctionDecl *FD = GetDecl();
876 if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) {
877 if (N <= 1 && llvm::isa<UsingShadowDecl>(GetFunctionOrShadowDecl())) {
878 auto SpecMemKind = fInterp->getSema().getSpecialMember(CD);
879 if ((N == 0 && SpecMemKind == clang::Sema::CXXDefaultConstructor) ||
880 (N == 1 &&
881 (SpecMemKind == clang::Sema::CXXCopyConstructor || SpecMemKind == clang::Sema::CXXMoveConstructor))) {
882 // Using declarations cannot inject special members; do not call them
883 // as such. This might happen by using `Base(Base&, int = 12)`, which
884 // is fine to be called as `Derived d(someBase, 42)` but not as
885 // copy constructor of `Derived`.
886 return;
887 }
888 }
889 make_narg_ctor_with_return(N, class_name, buf, indent_level);
890 return;
891 }
892 QualType QT = FD->getReturnType().getCanonicalType();
893 if (QT->isVoidType()) {
894 ostringstream typedefbuf;
895 ostringstream callbuf;
896 for (int i = 0; i < indent_level; ++i) {
897 callbuf << kIndentString;
898 }
899 make_narg_call("void", N, typedefbuf, callbuf, class_name, indent_level);
900 callbuf << ";\n";
901 for (int i = 0; i < indent_level; ++i) {
902 callbuf << kIndentString;
903 }
904 callbuf << "return;\n";
905 buf << typedefbuf.str() << callbuf.str();
906 } else {
907 for (int i = 0; i < indent_level; ++i) {
908 buf << kIndentString;
909 }
910
911 string type_name;
913 bool isPointer = false;
914
915 buf << "if (ret) {\n";
916 ++indent_level;
917 {
918 ostringstream typedefbuf;
919 ostringstream callbuf;
920 //
921 // Write the placement part of the placement new.
922 //
923 for (int i = 0; i < indent_level; ++i) {
924 callbuf << kIndentString;
925 }
926 callbuf << "new (ret) ";
927 collect_type_info(QT, typedefbuf, callbuf, type_name,
928 refType, isPointer, indent_level, false);
929 //
930 // Write the type part of the placement new.
931 //
932 callbuf << "(" << type_name.c_str();
933 if (refType != kNotReference) {
934 callbuf << "*) (&";
935 type_name += "&";
936 } else if (isPointer) {
937 callbuf << "*) (";
938 type_name += "*";
939 } else {
940 callbuf << ") (";
941 }
942 //
943 // Write the actual function call.
944 //
945 make_narg_call(type_name, N, typedefbuf, callbuf, class_name, indent_level);
946 //
947 // End the placement new.
948 //
949 callbuf << ");\n";
950 for (int i = 0; i < indent_level; ++i) {
951 callbuf << kIndentString;
952 }
953 callbuf << "return;\n";
954 //
955 // Output the whole placement new expression and return statement.
956 //
957 buf << typedefbuf.str() << callbuf.str();
958 }
959 --indent_level;
960 for (int i = 0; i < indent_level; ++i) {
961 buf << kIndentString;
962 }
963 buf << "}\n";
964 for (int i = 0; i < indent_level; ++i) {
965 buf << kIndentString;
966 }
967 buf << "else {\n";
968 ++indent_level;
969 {
970 ostringstream typedefbuf;
971 ostringstream callbuf;
972 for (int i = 0; i < indent_level; ++i) {
973 callbuf << kIndentString;
974 }
975 callbuf << "(void)(";
976 make_narg_call(type_name, N, typedefbuf, callbuf, class_name, indent_level);
977 callbuf << ");\n";
978 for (int i = 0; i < indent_level; ++i) {
979 callbuf << kIndentString;
980 }
981 callbuf << "return;\n";
982 buf << typedefbuf.str() << callbuf.str();
983 }
984 --indent_level;
985 for (int i = 0; i < indent_level; ++i) {
986 buf << kIndentString;
987 }
988 buf << "}\n";
989 }
990}
991
993{
995
996 const Decl *D = GetFunctionOrShadowDecl();
997 string wrapper_name;
998 string wrapper;
999
1000 if (get_wrapper_code(wrapper_name, wrapper) == 0) return 0;
1001
1002 //fprintf(stderr, "%s\n", wrapper.c_str());
1003 //
1004 // Compile the wrapper code.
1005 //
1006 void *F = compile_wrapper(wrapper_name, wrapper);
1007 if (F) {
1008 gWrapperStore.insert(make_pair(D, F));
1009 } else {
1010 ::Error("TClingCallFunc::make_wrapper",
1011 "Failed to compile\n ==== SOURCE BEGIN ====\n%s\n ==== SOURCE END ====",
1012 wrapper.c_str());
1013 }
1015}
1016
1018 ROOT::TMetaUtils::EIOCtorCategory kind, const std::string &type_name)
1019{
1020 // Make a code string that follows this pattern:
1021 //
1022 // void
1023 // unique_wrapper_ddd(void** ret, void* arena, unsigned long nary)
1024 // {
1025 // if (!arena) {
1026 // if (!nary) {
1027 // *ret = new ClassName;
1028 // }
1029 // else {
1030 // *ret = new ClassName[nary];
1031 // }
1032 // }
1033 // else {
1034 // if (!nary) {
1035 // *ret = new (arena) ClassName;
1036 // }
1037 // else {
1038 // *ret = new (arena) ClassName[nary];
1039 // }
1040 // }
1041 // }
1042 //
1043 // When I/O constructor used:
1044 //
1045 // void
1046 // unique_wrapper_ddd(void** ret, void* arena, unsigned long nary)
1047 // {
1048 // if (!arena) {
1049 // if (!nary) {
1050 // *ret = new ClassName((TRootIOCtor*)nullptr);
1051 // }
1052 // else {
1053 // char *buf = malloc(nary * sizeof(ClassName));
1054 // for (int k=0;k<nary;++k)
1055 // new (buf + k * sizeof(ClassName)) ClassName((TRootIOCtor*)nullptr);
1056 // *ret = buf;
1057 // }
1058 // }
1059 // else {
1060 // if (!nary) {
1061 // *ret = new (arena) ClassName((TRootIOCtor*)nullptr);
1062 // }
1063 // else {
1064 // for (int k=0;k<nary;++k)
1065 // new ((char *) arena + k * sizeof(ClassName)) ClassName((TRootIOCtor*)nullptr);
1066 // *ret = arena;
1067 // }
1068 // }
1069 // }
1070 //
1071 //
1072 // Note:
1073 //
1074 // If the class is of POD type, the form:
1075 //
1076 // new ClassName;
1077 //
1078 // does not initialize the object at all, and the form:
1079 //
1080 // new ClassName();
1081 //
1082 // default-initializes the object.
1083 //
1084 // We are using the form without parentheses because that is what
1085 // CINT did.
1086 //
1087 //--
1088 ASTContext &Context = info->GetDecl()->getASTContext();
1089 PrintingPolicy Policy(Context.getPrintingPolicy());
1090 Policy.SuppressTagKeyword = true;
1091 Policy.SuppressUnwrittenScope = true;
1092 //
1093 // Get the class or namespace name.
1094 //
1095 string class_name;
1096 if (const TypeDecl *TD = dyn_cast<TypeDecl>(info->GetDecl())) {
1097 // This is a class, struct, or union member.
1098 QualType QT(TD->getTypeForDecl(), 0);
1099 GetTypeAsString(QT, class_name, Context, Policy);
1100 } else if (const NamedDecl *ND = dyn_cast<NamedDecl>(info->GetDecl())) {
1101 // This is a namespace member.
1102 raw_string_ostream stream(class_name);
1103 ND->getNameForDiagnostic(stream, Policy, /*Qualified=*/true);
1104 stream.flush();
1105 }
1106
1107
1108 //
1109 // Make the wrapper name.
1110 //
1111 string wrapper_name;
1112 {
1113 ostringstream buf;
1114 buf << "__ctor";
1115 //const NamedDecl* ND = dyn_cast<NamedDecl>(FD);
1116 //string mn;
1117 //fInterp->maybeMangleDeclName(ND, mn);
1118 //buf << '_dtor_' << mn;
1119 buf << '_' << gWrapperSerial++;
1120 wrapper_name = buf.str();
1121 }
1122
1123 string constr_arg;
1125 constr_arg = string("((") + type_name + "*)nullptr)";
1127 constr_arg = string("(*((") + type_name + "*)arena))";
1128
1129 //
1130 // Write the wrapper code.
1131 //
1132 int indent_level = 0;
1133 ostringstream buf;
1134 buf << "__attribute__((used)) ";
1135 buf << "extern \"C\" void ";
1136 buf << wrapper_name;
1137 buf << "(void** ret, void* arena, unsigned long nary)\n";
1138 buf << "{\n";
1139
1140 // if (!arena) {
1141 // if (!nary) {
1142 // *ret = new ClassName;
1143 // }
1144 // else {
1145 // *ret = new ClassName[nary];
1146 // }
1147 // }
1148 indent(buf, ++indent_level);
1149 buf << "if (!arena) {\n";
1150 indent(buf, ++indent_level);
1151 buf << "if (!nary) {\n";
1152 indent(buf, ++indent_level);
1153 buf << "*ret = new " << class_name << constr_arg << ";\n";
1154 indent(buf, --indent_level);
1155 buf << "}\n";
1156 indent(buf, indent_level);
1157 buf << "else {\n";
1158 indent(buf, ++indent_level);
1159 if (constr_arg.empty()) {
1160 buf << "*ret = new " << class_name << "[nary];\n";
1161 } else {
1162 buf << "char *buf = (char *) malloc(nary * sizeof(" << class_name << "));\n";
1163 indent(buf, indent_level);
1164 buf << "for (int k=0;k<nary;++k)\n";
1165 indent(buf, ++indent_level);
1166 buf << "new (buf + k * sizeof(" << class_name << ")) " << class_name << constr_arg << ";\n";
1167 indent(buf, --indent_level);
1168 buf << "*ret = buf;\n";
1169 }
1170 indent(buf, --indent_level);
1171 buf << "}\n";
1172 indent(buf, --indent_level);
1173 buf << "}\n";
1174 // else {
1175 // if (!nary) {
1176 // *ret = new (arena) ClassName;
1177 // }
1178 // else {
1179 // *ret = new (arena) ClassName[nary];
1180 // }
1181 // }
1182 indent(buf, indent_level);
1183 buf << "else {\n";
1184 indent(buf, ++indent_level);
1185 buf << "if (!nary) {\n";
1186 indent(buf, ++indent_level);
1187 buf << "*ret = new (arena) " << class_name << constr_arg << ";\n";
1188 indent(buf, --indent_level);
1189 buf << "}\n";
1190 indent(buf, indent_level);
1191 buf << "else {\n";
1192 indent(buf, ++indent_level);
1193 if (constr_arg.empty()) {
1194 buf << "*ret = new (arena) " << class_name << "[nary];\n";
1195 } else {
1196 buf << "for (int k=0;k<nary;++k)\n";
1197 indent(buf, ++indent_level);
1198 buf << "new ((char *) arena + k * sizeof(" << class_name << ")) " << class_name << constr_arg << ";\n";
1199 indent(buf, --indent_level);
1200 buf << "*ret = arena;\n";
1201 }
1202 indent(buf, --indent_level);
1203 buf << "}\n";
1204 indent(buf, --indent_level);
1205 buf << "}\n";
1206 // End wrapper.
1207 --indent_level;
1208 buf << "}\n";
1209 // Done.
1210 string wrapper(buf.str());
1211 //fprintf(stderr, "%s\n", wrapper.c_str());
1212 //
1213 // Compile the wrapper code.
1214 //
1215 void *F = compile_wrapper(wrapper_name, wrapper,
1216 /*withAccessControl=*/false);
1217 if (F) {
1218 gCtorWrapperStore.insert(make_pair(info->GetDecl(), F));
1219 } else {
1220 ::Error("TClingCallFunc::make_ctor_wrapper",
1221 "Failed to compile\n ==== SOURCE BEGIN ====\n%s\n ==== SOURCE END ====",
1222 wrapper.c_str());
1223 }
1225}
1226
1229{
1230 // Make a code string that follows this pattern:
1231 //
1232 // void
1233 // unique_wrapper_ddd(void* obj, unsigned long nary, int withFree)
1234 // {
1235 // if (withFree) {
1236 // if (!nary) {
1237 // delete (ClassName*) obj;
1238 // }
1239 // else {
1240 // delete[] (ClassName*) obj;
1241 // }
1242 // }
1243 // else {
1244 // typedef ClassName DtorName;
1245 // if (!nary) {
1246 // ((ClassName*)obj)->~DtorName();
1247 // }
1248 // else {
1249 // for (unsigned long i = nary - 1; i > -1; --i) {
1250 // (((ClassName*)obj)+i)->~DtorName();
1251 // }
1252 // }
1253 // }
1254 // }
1255 //
1256 //--
1257 ASTContext &Context = info->GetDecl()->getASTContext();
1258 PrintingPolicy Policy(Context.getPrintingPolicy());
1259 Policy.SuppressTagKeyword = true;
1260 Policy.SuppressUnwrittenScope = true;
1261 //
1262 // Get the class or namespace name.
1263 //
1264 string class_name;
1265 if (const TypeDecl *TD = dyn_cast<TypeDecl>(info->GetDecl())) {
1266 // This is a class, struct, or union member.
1267 QualType QT(TD->getTypeForDecl(), 0);
1268 GetTypeAsString(QT, class_name, Context, Policy);
1269 } else if (const NamedDecl *ND = dyn_cast<NamedDecl>(info->GetDecl())) {
1270 // This is a namespace member.
1271 raw_string_ostream stream(class_name);
1272 ND->getNameForDiagnostic(stream, Policy, /*Qualified=*/true);
1273 stream.flush();
1274 }
1275 //
1276 // Make the wrapper name.
1277 //
1278 string wrapper_name;
1279 {
1280 ostringstream buf;
1281 buf << "__dtor";
1282 //const NamedDecl* ND = dyn_cast<NamedDecl>(FD);
1283 //string mn;
1284 //fInterp->maybeMangleDeclName(ND, mn);
1285 //buf << '_dtor_' << mn;
1286 buf << '_' << gWrapperSerial++;
1287 wrapper_name = buf.str();
1288 }
1289 //
1290 // Write the wrapper code.
1291 //
1292 int indent_level = 0;
1293 ostringstream buf;
1294 buf << "__attribute__((used)) ";
1295 buf << "extern \"C\" void ";
1296 buf << wrapper_name;
1297 buf << "(void* obj, unsigned long nary, int withFree)\n";
1298 buf << "{\n";
1299 // if (withFree) {
1300 // if (!nary) {
1301 // delete (ClassName*) obj;
1302 // }
1303 // else {
1304 // delete[] (ClassName*) obj;
1305 // }
1306 // }
1307 ++indent_level;
1308 indent(buf, indent_level);
1309 buf << "if (withFree) {\n";
1310 ++indent_level;
1311 indent(buf, indent_level);
1312 buf << "if (!nary) {\n";
1313 ++indent_level;
1314 indent(buf, indent_level);
1315 buf << "delete (" << class_name << "*) obj;\n";
1316 --indent_level;
1317 indent(buf, indent_level);
1318 buf << "}\n";
1319 indent(buf, indent_level);
1320 buf << "else {\n";
1321 ++indent_level;
1322 indent(buf, indent_level);
1323 buf << "delete[] (" << class_name << "*) obj;\n";
1324 --indent_level;
1325 indent(buf, indent_level);
1326 buf << "}\n";
1327 --indent_level;
1328 indent(buf, indent_level);
1329 buf << "}\n";
1330 // else {
1331 // typedef ClassName Nm;
1332 // if (!nary) {
1333 // ((Nm*)obj)->~Nm();
1334 // }
1335 // else {
1336 // for (unsigned long i = nary - 1; i > -1; --i) {
1337 // (((Nm*)obj)+i)->~Nm();
1338 // }
1339 // }
1340 // }
1341 indent(buf, indent_level);
1342 buf << "else {\n";
1343 ++indent_level;
1344 indent(buf, indent_level);
1345 buf << "typedef " << class_name << " Nm;\n";
1346 buf << "if (!nary) {\n";
1347 ++indent_level;
1348 indent(buf, indent_level);
1349 buf << "((Nm*)obj)->~Nm();\n";
1350 --indent_level;
1351 indent(buf, indent_level);
1352 buf << "}\n";
1353 indent(buf, indent_level);
1354 buf << "else {\n";
1355 ++indent_level;
1356 indent(buf, indent_level);
1357 buf << "do {\n";
1358 ++indent_level;
1359 indent(buf, indent_level);
1360 buf << "(((Nm*)obj)+(--nary))->~Nm();\n";
1361 --indent_level;
1362 indent(buf, indent_level);
1363 buf << "} while (nary);\n";
1364 --indent_level;
1365 indent(buf, indent_level);
1366 buf << "}\n";
1367 --indent_level;
1368 indent(buf, indent_level);
1369 buf << "}\n";
1370 // End wrapper.
1371 --indent_level;
1372 buf << "}\n";
1373 // Done.
1374 string wrapper(buf.str());
1375 //fprintf(stderr, "%s\n", wrapper.c_str());
1376 //
1377 // Compile the wrapper code.
1378 //
1379 void *F = compile_wrapper(wrapper_name, wrapper,
1380 /*withAccessControl=*/false);
1381 if (F) {
1382 gDtorWrapperStore.insert(make_pair(info->GetDecl(), F));
1383 } else {
1384 ::Error("TClingCallFunc::make_dtor_wrapper",
1385 "Failed to compile\n ==== SOURCE BEGIN ====\n%s\n ==== SOURCE END ====",
1386 wrapper.c_str());
1387 }
1388
1390}
1391
1393public:
1394 union {
1395 long double ldbl;
1396 double dbl;
1397 float flt;
1398 //__uint128_t ui128;
1399 //__int128_t i128;
1400 unsigned long long ull;
1401 long long ll;
1402 unsigned long ul;
1403 long l;
1404 unsigned int ui;
1405 int i;
1406 unsigned short us;
1407 short s;
1408 //char32_t c32;
1409 //char16_t c16;
1410 //unsigned wchar_t uwc; - non-standard
1411 wchar_t wc;
1412 unsigned char uc;
1413 signed char sc;
1414 char c;
1415 bool b;
1416 void *vp;
1417 } u;
1418};
1419
1420void TClingCallFunc::exec(void *address, void *ret)
1421{
1422 SmallVector<ValHolder, 8> vh_ary;
1423 SmallVector<void *, 8> vp_ary;
1424
1425 unsigned num_args = fArgVals.size();
1426 {
1428
1429 const FunctionDecl *FD = GetDecl();
1430
1431 //
1432 // Convert the arguments from cling::Value to their
1433 // actual type and store them in a holder for passing to the
1434 // wrapper function by pointer to value.
1435 //
1436 unsigned num_params = FD->getNumParams();
1437
1438 if (num_args < GetMinRequiredArguments()) {
1439 ::Error("TClingCallFunc::exec",
1440 "Not enough arguments provided for %s (%d instead of the minimum %d)",
1441 fMethod->Name(),
1442 num_args, (int)GetMinRequiredArguments());
1443 return;
1444 }
1445 if (address == 0 && dyn_cast<CXXMethodDecl>(FD)
1446 && !(dyn_cast<CXXMethodDecl>(FD))->isStatic()
1447 && !dyn_cast<CXXConstructorDecl>(FD)) {
1448 ::Error("TClingCallFunc::exec",
1449 "The method %s is called without an object.",
1450 fMethod->Name());
1451 return;
1452 }
1453 vh_ary.reserve(num_args);
1454 vp_ary.reserve(num_args);
1455 for (unsigned i = 0U; i < num_args; ++i) {
1456 QualType Ty;
1457 if (i < num_params) {
1458 const ParmVarDecl *PVD = FD->getParamDecl(i);
1459 Ty = PVD->getType();
1460 } else {
1461 Ty = fArgVals[i].getType();
1462 }
1463 QualType QT = Ty.getCanonicalType();
1464 if (const BuiltinType *BT = dyn_cast<BuiltinType>(QT.getTypePtr())) {
1465 ValHolder vh;
1466 switch (BT->getKind()) {
1467 // Unsigned Types
1468 case BuiltinType::Bool: vh.u.b = fArgVals[i].simplisticCastAs<bool>();
1469 break;
1470 case BuiltinType::Char_U: vh.u.c = fArgVals[i].simplisticCastAs<char>();
1471 break;
1472 case BuiltinType::UChar: vh.u.uc = fArgVals[i].simplisticCastAs<unsigned char>();
1473 break;
1474 case BuiltinType::WChar_U: vh.u.wc = fArgVals[i].simplisticCastAs<wchar_t>();
1475 break;
1476 case BuiltinType::Char16: //vh.u.c16 = fArgVals[i].simplisticCastAs<char16_t>();
1477 break;
1478 case BuiltinType::Char32: //vh.u.c32 = fArgVals[i].simplisticCastAs<char32_t>();
1479 break;
1480 case BuiltinType::UShort: vh.u.us = fArgVals[i].simplisticCastAs<unsigned short>();
1481 break;
1482 case BuiltinType::UInt: vh.u.ui = fArgVals[i].simplisticCastAs<unsigned int>();
1483 break;
1484 case BuiltinType::ULong: vh.u.ul = fArgVals[i].simplisticCastAs<unsigned long>();
1485 break;
1486 case BuiltinType::ULongLong: vh.u.ull = fArgVals[i].simplisticCastAs<unsigned long long>();
1487 break;
1488 // Signed Types
1489 case BuiltinType::Char_S: vh.u.c = fArgVals[i].simplisticCastAs<char>();
1490 break;
1491 case BuiltinType::SChar: vh.u.sc = fArgVals[i].simplisticCastAs<signed char>();
1492 break;
1493 case BuiltinType::WChar_S: vh.u.wc = fArgVals[i].simplisticCastAs<wchar_t>();
1494 break;
1495 case BuiltinType::Short: vh.u.s = fArgVals[i].simplisticCastAs<short>();
1496 break;
1497 case BuiltinType::Int: vh.u.i = fArgVals[i].simplisticCastAs<int>();
1498 break;
1499 case BuiltinType::Long: vh.u.l = fArgVals[i].simplisticCastAs<long>();
1500 break;
1501 case BuiltinType::LongLong: vh.u.ll = fArgVals[i].simplisticCastAs<long long>();
1502 break;
1503 case BuiltinType::Float: vh.u.flt = fArgVals[i].simplisticCastAs<float>();
1504 break;
1505 case BuiltinType::Double: vh.u.dbl = fArgVals[i].simplisticCastAs<double>();
1506 break;
1507 case BuiltinType::LongDouble: vh.u.ldbl = fArgVals[i].simplisticCastAs<long double>();
1508 break;
1509 case BuiltinType::NullPtr: vh.u.vp = fArgVals[i].getPtr();
1510 break;
1511 default:
1512 // Thee should be no others. This is here in case
1513 // this changes in the future.
1514 ::Error("TClingCallFunc::exec(void*)",
1515 "Unhandled builtin type '%s'",
1516 BT->getTypeClassName());
1517 QT->dump();
1518 return;
1519 }
1520 vh_ary.push_back(vh);
1521 vp_ary.push_back(&vh_ary.back());
1522 } else if (QT->isReferenceType() || QT->isRecordType()) {
1523 // the argument is already a pointer value (points to the same thing
1524 // as the reference or pointing to object passed by value.
1525 vp_ary.push_back((void *) fArgVals[i].simplisticCastAs<unsigned long long>());
1526 } else if (QT->isPointerType() || QT->isArrayType() || QT->isMemberPointerType()) {
1527 ValHolder vh;
1528 vh.u.vp = (void *) fArgVals[i].simplisticCastAs<unsigned long long>();
1529 vh_ary.push_back(vh);
1530 vp_ary.push_back(&vh_ary.back());
1531 } else if (QT->isEnumeralType()) {
1532 // FIXME: Handle isScopedEnumeralType ()
1533 // FIXME:We may need to worry about the underlying type of the enum
1534 ValHolder vh;
1535 vh.u.i = fArgVals[i].simplisticCastAs<int>();
1536 vh_ary.push_back(vh);
1537 vp_ary.push_back(&vh_ary.back());
1538 } else {
1539 ::Error("TClingCallFunc::exec(void*)",
1540 "Invalid type '%s'", QT->getTypeClassName());
1541 QT->dump();
1542 return;
1543 }
1544 }
1545 } // End of scope holding the lock
1546 (*fWrapper)(address, (int)num_args, (void **)vp_ary.data(), ret);
1547}
1548
1549template <typename T>
1550void TClingCallFunc::execWithLL(void *address, cling::Value *val)
1551{
1552 T ret; // leave uninit for valgrind's sake!
1553 exec(address, &ret);
1554 val->getLL() = ret;
1555}
1556
1557template <typename T>
1558void TClingCallFunc::execWithULL(void *address, cling::Value *val)
1559{
1560 T ret; // leave uninit for valgrind's sake!
1561 exec(address, &ret);
1562 val->getULL() = ret;
1563}
1564
1565// Handle integral types.
1566template <class T>
1568{
1569 ret = cling::Value::Create<T>(QT.getAsOpaquePtr(), *fInterp);
1570 static_assert(std::is_integral<T>::value, "Must be called with integral T");
1571 if (std::is_signed<T>::value)
1572 return [this](void* address, cling::Value& ret) { execWithLL<T>(address, &ret); };
1573 else
1574 return [this](void* address, cling::Value& ret) { execWithULL<T>(address, &ret); };
1575}
1576
1577// Handle builtin types.
1579TClingCallFunc::InitRetAndExecBuiltin(QualType QT, const clang::BuiltinType *BT, cling::Value &ret) {
1580 switch (BT->getKind()) {
1581 case BuiltinType::Void: {
1582 ret = cling::Value::Create<void>(QT.getAsOpaquePtr(), *fInterp);
1583 return [this](void* address, cling::Value& ret) { exec(address, 0); };
1584 break;
1585 }
1586
1587 //
1588 // Unsigned Types
1589 //
1590 case BuiltinType::Bool:
1591 return InitRetAndExecIntegral<bool>(QT, ret);
1592 break;
1593 case BuiltinType::Char_U: // char on targets where it is unsigned
1594 case BuiltinType::UChar:
1595 return InitRetAndExecIntegral<char>(QT, ret);
1596 break;
1597 case BuiltinType::WChar_U:
1598 return InitRetAndExecIntegral<wchar_t>(QT, ret);
1599 break;
1600 case BuiltinType::Char16:
1601 ::Error("TClingCallFunc::InitRetAndExecBuiltin",
1602 "Invalid type 'char16_t'!");
1603 return {};
1604 break;
1605 case BuiltinType::Char32:
1606 ::Error("TClingCallFunc::InitRetAndExecBuiltin",
1607 "Invalid type 'char32_t'!");
1608 return {};
1609 break;
1610 case BuiltinType::UShort:
1611 return InitRetAndExecIntegral<unsigned short>(QT, ret);
1612 break;
1613 case BuiltinType::UInt:
1614 return InitRetAndExecIntegral<unsigned int>(QT, ret);
1615 break;
1616 case BuiltinType::ULong:
1617 return InitRetAndExecIntegral<unsigned long>(QT, ret);
1618 break;
1619 case BuiltinType::ULongLong:
1620 return InitRetAndExecIntegral<unsigned long long>(QT, ret);
1621 break;
1622 case BuiltinType::UInt128: {
1623 ::Error("TClingCallFunc::InitRetAndExecBuiltin",
1624 "Invalid type '__uint128_t'!");
1625 return {};
1626 }
1627 break;
1628
1629 //
1630 // Signed Types
1631 //
1632 case BuiltinType::Char_S: // char on targets where it is signed
1633 case BuiltinType::SChar:
1634 return InitRetAndExecIntegral<signed char>(QT, ret);
1635 break;
1636 case BuiltinType::WChar_S:
1637 // wchar_t on targets where it is signed.
1638 // The standard doesn't allow to specify signednedd of wchar_t
1639 // thus this maps simply to wchar_t.
1640 return InitRetAndExecIntegral<wchar_t>(QT, ret);
1641 break;
1642 case BuiltinType::Short:
1643 return InitRetAndExecIntegral<short>(QT, ret);
1644 break;
1645 case BuiltinType::Int:
1646 return InitRetAndExecIntegral<int>(QT, ret);
1647 break;
1648 case BuiltinType::Long:
1649 return InitRetAndExecIntegral<long>(QT, ret);
1650 break;
1651 case BuiltinType::LongLong:
1652 return InitRetAndExecIntegral<long long>(QT, ret);
1653 break;
1654 case BuiltinType::Int128:
1655 ::Error("TClingCallFunc::InitRetAndExecBuiltin",
1656 "Invalid type '__int128_t'!");
1657 return {};
1658 break;
1659 case BuiltinType::Half:
1660 // half in OpenCL, __fp16 in ARM NEON
1661 ::Error("TClingCallFunc::InitRetAndExecBuiltin",
1662 "Invalid type 'Half'!");
1663 return {};
1664 break;
1665 case BuiltinType::Float: {
1666 ret = cling::Value::Create<float>(QT.getAsOpaquePtr(), *fInterp);
1667 return [this](void* address, cling::Value& ret) { exec(address, &ret.getFloat()); };
1668 break;
1669 }
1670 case BuiltinType::Double: {
1671 ret = cling::Value::Create<double>(QT.getAsOpaquePtr(), *fInterp);
1672 return [this](void* address, cling::Value& ret) { exec(address, &ret.getDouble()); };
1673 break;
1674 }
1675 case BuiltinType::LongDouble: {
1676 ret = cling::Value::Create<long double>(QT.getAsOpaquePtr(), *fInterp);
1677 return [this](void* address, cling::Value& ret) { exec(address, &ret.getLongDouble()); };
1678 break;
1679 }
1680 //
1681 // Language-Specific Types
1682 //
1683 case BuiltinType::NullPtr:
1684 // C++11 nullptr
1685 ::Error("TClingCallFunc::InitRetAndExecBuiltin",
1686 "Invalid type 'nullptr'!");
1687 return {};
1688 break;
1689 default:
1690 break;
1691 }
1692 return {};
1693}
1694
1695
1697TClingCallFunc::InitRetAndExecNoCtor(clang::QualType QT, cling::Value &ret) {
1698 if (QT->isReferenceType()) {
1699 ret = cling::Value(QT, *fInterp);
1700 return [this](void* address, cling::Value& ret) { exec(address, &ret.getPtr()); };
1701 } else if (QT->isMemberPointerType()) {
1702 const MemberPointerType *MPT = QT->getAs<MemberPointerType>();
1703 if (MPT && MPT->isMemberDataPointer()) {
1704 // A member data pointer is a actually a struct with one
1705 // member of ptrdiff_t, the offset from the base of the object
1706 // storage to the storage for the designated data member.
1707 // But that's not relevant: we use it as a non-builtin, allocated
1708 // type.
1709 ret = cling::Value(QT, *fInterp);
1710 return [this](void* address, cling::Value& ret) { exec(address, ret.getPtr()); };
1711 }
1712 // We are a function member pointer.
1713 ret = cling::Value(QT, *fInterp);
1714 return [this](void* address, cling::Value& ret) { exec(address, &ret.getPtr()); };
1715 } else if (QT->isPointerType() || QT->isArrayType()) {
1716 // Note: ArrayType is an illegal function return value type.
1717 ret = cling::Value::Create<void*>(QT.getAsOpaquePtr(), *fInterp);
1718 return [this](void* address, cling::Value& ret) { exec(address, &ret.getPtr()); };
1719 } else if (QT->isRecordType()) {
1720 ret = cling::Value(QT, *fInterp);
1721 return [this](void* address, cling::Value& ret) { exec(address, ret.getPtr()); };
1722 } else if (const EnumType *ET = dyn_cast<EnumType>(&*QT)) {
1723 // Note: We may need to worry about the underlying type
1724 // of the enum here.
1725 (void) ET;
1726 ret = cling::Value(QT, *fInterp);
1727 return [this](void* address, cling::Value& ret) { execWithLL<int>(address, &ret); };
1728 } else if (const BuiltinType *BT = dyn_cast<BuiltinType>(&*QT)) {
1729 return InitRetAndExecBuiltin(QT, BT, ret);
1730 }
1731 ::Error("TClingCallFunc::exec_with_valref_return",
1732 "Unrecognized return type!");
1733 QT->dump();
1734 return {};
1735}
1736
1738TClingCallFunc::InitRetAndExec(const clang::FunctionDecl *FD, cling::Value &ret) {
1739 if (llvm::isa<CXXConstructorDecl>(FD)) {
1740 ASTContext &Context = FD->getASTContext();
1741 const TypeDecl *TD = dyn_cast<TypeDecl>(GetDeclContext());
1742 QualType ClassTy(TD->getTypeForDecl(), 0);
1743 QualType QT = Context.getLValueReferenceType(ClassTy);
1744 ret = cling::Value(QT, *fInterp);
1745 // Store the new()'ed address in getPtr()
1746 return [this](void* address, cling::Value& ret) { exec(address, &ret.getPtr()); };
1747 } else {
1748 QualType QT = FD->getReturnType().getCanonicalType();
1749 return InitRetAndExecNoCtor(QT, ret);
1750 }
1751}
1752
1753void TClingCallFunc::exec_with_valref_return(void *address, cling::Value *ret)
1754{
1755 if (!ret) {
1756 exec(address, 0);
1757 return;
1758 }
1759 std::function<void(void*, cling::Value&)> execFunc;
1760
1761 /* Release lock during user function execution*/
1762 {
1764 execFunc = InitRetAndExec(GetDecl(), *ret);
1765 }
1766
1767 if (execFunc)
1768 execFunc(address, *ret);
1769 return;
1770}
1771
1772void TClingCallFunc::EvaluateArgList(const string &ArgList)
1773{
1775
1776 SmallVector<Expr *, 4> exprs;
1777 fInterp->getLookupHelper().findArgList(ArgList, exprs,
1778 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
1779 : cling::LookupHelper::NoDiagnostics);
1780 for (SmallVectorImpl<Expr *>::const_iterator I = exprs.begin(),
1781 E = exprs.end(); I != E; ++I) {
1782 cling::Value val;
1783 EvaluateExpr(*fInterp, *I, val);
1784 if (!val.isValid()) {
1785 // Bad expression, all done.
1786 ::Error("TClingCallFunc::EvaluateArgList",
1787 "Bad expression in parameter %d of '%s'!",
1788 (int)(I - exprs.begin()),
1789 ArgList.c_str());
1790 return;
1791 }
1792 fArgVals.push_back(val);
1793 }
1794}
1795
1796void TClingCallFunc::Exec(void *address, TInterpreterValue *interpVal/*=0*/)
1797{
1798 IFacePtr();
1799 if (!fWrapper) {
1800 ::Error("TClingCallFunc::Exec(address, interpVal)",
1801 "Called with no wrapper, not implemented!");
1802 return;
1803 }
1804 if (!interpVal) {
1805 exec(address, 0);
1806 return;
1807 }
1808 cling::Value *val = reinterpret_cast<cling::Value *>(interpVal->GetValAddr());
1809 exec_with_valref_return(address, val);
1810}
1811
1812template <typename T>
1814{
1815 IFacePtr();
1816 if (!fWrapper) {
1817 ::Error("TClingCallFunc::ExecT",
1818 "Called with no wrapper, not implemented!");
1819 return 0;
1820 }
1821 cling::Value ret;
1822 exec_with_valref_return(address, &ret);
1823 if (ret.isVoid()) {
1824 return 0;
1825 }
1826
1827 if (ret.needsManagedAllocation())
1828 ((TCling *)gCling)->RegisterTemporary(ret);
1829 return ret.simplisticCastAs<T>();
1830}
1831
1833{
1834 return ExecT<Longptr_t>(address);
1835}
1836
1837long long TClingCallFunc::ExecInt64(void *address)
1838{
1839 return ExecT<long long>(address);
1840}
1841
1842double TClingCallFunc::ExecDouble(void *address)
1843{
1844 return ExecT<double>(address);
1845}
1846
1847void TClingCallFunc::ExecWithArgsAndReturn(void *address, const void *args[] /*= 0*/,
1848 int nargs /*= 0*/, void *ret/*= 0*/)
1849{
1850 IFacePtr();
1851 if (!fWrapper) {
1852 ::Error("TClingCallFunc::ExecWithArgsAndReturn(address, args, ret)",
1853 "Called with no wrapper, not implemented!");
1854 return;
1855 }
1856 (*fWrapper)(address, nargs, const_cast<void **>(args), ret);
1857}
1858
1859void TClingCallFunc::ExecWithReturn(void *address, void *ret/*= 0*/)
1860{
1861 IFacePtr();
1862 if (!fWrapper) {
1863 ::Error("TClingCallFunc::ExecWithReturn(address, ret)",
1864 "Called with no wrapper, not implemented!");
1865 return;
1866 }
1867 exec(address, ret);
1868}
1869
1872 const std::string &type_name,
1873 void *address /*=0*/, unsigned long nary /*= 0UL*/)
1874{
1875 if (!info->IsValid()) {
1876 ::Error("TClingCallFunc::ExecDefaultConstructor", "Invalid class info!");
1877 return nullptr;
1878 }
1879 tcling_callfunc_ctor_Wrapper_t wrapper = nullptr;
1880 {
1882 auto D = info->GetDecl();
1883 //if (!info->HasDefaultConstructor()) {
1884 // // FIXME: We might have a ROOT ioctor, we might
1885 // // have to check for that here.
1886 // ::Error("TClingCallFunc::ExecDefaultConstructor",
1887 // "Class has no default constructor: %s",
1888 // info->Name());
1889 // return 0;
1890 //}
1891 auto I = gCtorWrapperStore.find(D);
1892 if (I != gCtorWrapperStore.end()) {
1893 wrapper = (tcling_callfunc_ctor_Wrapper_t) I->second;
1894 } else {
1895 wrapper = make_ctor_wrapper(info, kind, type_name);
1896 }
1897 }
1898 if (!wrapper) {
1899 ::Error("TClingCallFunc::ExecDefaultConstructor",
1900 "Called with no wrapper, not implemented!");
1901 return nullptr;
1902 }
1903 void *obj = 0;
1904 (*wrapper)(&obj, address, nary);
1905 return obj;
1906}
1907
1908void TClingCallFunc::ExecDestructor(const TClingClassInfo *info, void *address /*=0*/,
1909 unsigned long nary /*= 0UL*/, bool withFree /*= true*/)
1910{
1911 if (!info->IsValid()) {
1912 ::Error("TClingCallFunc::ExecDestructor", "Invalid class info!");
1913 return;
1914 }
1915
1917 {
1919 const Decl *D = info->GetDecl();
1920 map<const Decl *, void *>::iterator I = gDtorWrapperStore.find(D);
1921 if (I != gDtorWrapperStore.end()) {
1922 wrapper = (tcling_callfunc_dtor_Wrapper_t) I->second;
1923 } else {
1924 wrapper = make_dtor_wrapper(info);
1925 }
1926 }
1927 if (!wrapper) {
1928 ::Error("TClingCallFunc::ExecDestructor",
1929 "Called with no wrapper, not implemented!");
1930 return;
1931 }
1932 (*wrapper)(address, nary, withFree);
1933}
1934
1937{
1938 return new TClingMethodInfo(*fMethod);
1939}
1940
1942{
1943 fMethod.reset();
1944 fWrapper = 0;
1945 fDecl = nullptr;
1947 ResetArg();
1948}
1949
1951{
1952 Init();
1953 fMethod = std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(minfo));
1954}
1955
1956void TClingCallFunc::Init(std::unique_ptr<TClingMethodInfo> minfo)
1957{
1958 Init();
1959 fMethod = std::move(minfo);
1960}
1961
1963{
1964 if (!IsValid()) {
1965 return 0;
1966 }
1967 if (!fWrapper) {
1968 const Decl *decl = GetFunctionOrShadowDecl();
1969
1971 // check if another thread already did it
1972 if (!fWrapper) {
1973 map<const Decl *, void *>::iterator I = gWrapperStore.find(decl);
1974 if (I != gWrapperStore.end()) {
1976 } else {
1978 }
1979 }
1980 }
1981 return (void *)fWrapper.load();
1982}
1983
1985{
1986 if (!fMethod) {
1987 return false;
1988 }
1989 return fMethod->IsValid();
1990}
1991
1993{
1994 if (!IsValid()) {
1995 ::Error("TClingCallFunc::IFacePtr(kind)",
1996 "Attempt to get interface while invalid.");
1998 }
1999 if (!fWrapper) {
2000 const Decl *decl = GetFunctionOrShadowDecl();
2001
2003 // check if another thread already did it
2004 if (!fWrapper) {
2005 map<const Decl *, void *>::iterator I = gWrapperStore.find(decl);
2006 if (I != gWrapperStore.end()) {
2008 } else {
2010 }
2011 }
2012 }
2014}
2015
2016
2018{
2019 fArgVals.clear();
2020}
2021
2022void TClingCallFunc::SetArg(unsigned long param)
2023{
2024 const ASTContext &C = fInterp->getCI()->getASTContext();
2025 fArgVals.push_back(cling::Value(C.UnsignedLongTy, *fInterp));
2026 fArgVals.back().getLL() = param;
2027}
2028
2030{
2031 const ASTContext &C = fInterp->getCI()->getASTContext();
2032 fArgVals.push_back(cling::Value(C.LongTy, *fInterp));
2033 fArgVals.back().getLL() = param;
2034}
2035
2036void TClingCallFunc::SetArg(float param)
2037{
2038 const ASTContext &C = fInterp->getCI()->getASTContext();
2039 fArgVals.push_back(cling::Value(C.FloatTy, *fInterp));
2040 fArgVals.back().getFloat() = param;
2041}
2042
2043void TClingCallFunc::SetArg(double param)
2044{
2045 const ASTContext &C = fInterp->getCI()->getASTContext();
2046 fArgVals.push_back(cling::Value(C.DoubleTy, *fInterp));
2047 fArgVals.back().getDouble() = param;
2048}
2049
2050void TClingCallFunc::SetArg(long long param)
2051{
2052 const ASTContext &C = fInterp->getCI()->getASTContext();
2053 fArgVals.push_back(cling::Value(C.LongLongTy, *fInterp));
2054 fArgVals.back().getLL() = param;
2055}
2056
2057void TClingCallFunc::SetArg(unsigned long long param)
2058{
2059 const ASTContext &C = fInterp->getCI()->getASTContext();
2060 fArgVals.push_back(cling::Value(C.UnsignedLongLongTy, *fInterp));
2061 fArgVals.back().getULL() = param;
2062}
2063
2064void TClingCallFunc::SetArgArray(Longptr_t *paramArr, int nparam)
2065{
2066 ResetArg();
2067 for (int i = 0; i < nparam; ++i) {
2068 SetArg(paramArr[i]);
2069 }
2070}
2071
2072void TClingCallFunc::SetArgs(const char *params)
2073{
2074 ResetArg();
2075 EvaluateArgList(params);
2076}
2077
2078void TClingCallFunc::SetFunc(const TClingClassInfo *info, const char *method, const char *arglist,
2079 Longptr_t *poffset)
2080{
2081 SetFunc(info, method, arglist, false, poffset);
2082}
2083
2084void TClingCallFunc::SetFunc(const TClingClassInfo *info, const char *method, const char *arglist,
2085 bool objectIsConst, Longptr_t *poffset)
2086{
2087 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(fInterp)));
2088 if (poffset) {
2089 *poffset = 0L;
2090 }
2091 ResetArg();
2092 if (!info->IsValid()) {
2093 ::Error("TClingCallFunc::SetFunc", "Class info is invalid!");
2094 return;
2095 }
2096 if (!strcmp(arglist, ")")) {
2097 // CINT accepted a single right paren as meaning no arguments.
2098 arglist = "";
2099 }
2100 *fMethod = info->GetMethodWithArgs(method, arglist, objectIsConst, poffset);
2101 if (!fMethod->IsValid()) {
2102 //::Error("TClingCallFunc::SetFunc", "Could not find method %s(%s)", method,
2103 // arglist);
2104 return;
2105 }
2106 // FIXME: The arglist was already parsed by the lookup, we should
2107 // enhance the lookup to return the resulting expression
2108 // list so we do not need to parse it again here.
2109 EvaluateArgList(arglist);
2110}
2111
2113{
2114 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(*info)));
2115 ResetArg();
2116 if (!fMethod->IsValid()) {
2117 return;
2118 }
2119}
2120
2121void TClingCallFunc::SetFuncProto(const TClingClassInfo *info, const char *method,
2122 const char *proto, Longptr_t *poffset,
2123 EFunctionMatchMode mode/*=kConversionMatch*/)
2124{
2125 SetFuncProto(info, method, proto, false, poffset, mode);
2126}
2127
2128void TClingCallFunc::SetFuncProto(const TClingClassInfo *info, const char *method,
2129 const char *proto, bool objectIsConst, Longptr_t *poffset,
2130 EFunctionMatchMode mode/*=kConversionMatch*/)
2131{
2132 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(fInterp)));
2133 if (poffset) {
2134 *poffset = 0L;
2135 }
2136 ResetArg();
2137 if (!info->IsValid()) {
2138 ::Error("TClingCallFunc::SetFuncProto", "Class info is invalid!");
2139 return;
2140 }
2141 *fMethod = info->GetMethod(method, proto, objectIsConst, poffset, mode);
2142 if (!fMethod->IsValid()) {
2143 //::Error("TClingCallFunc::SetFuncProto", "Could not find method %s(%s)",
2144 // method, proto);
2145 return;
2146 }
2147}
2148
2149void TClingCallFunc::SetFuncProto(const TClingClassInfo *info, const char *method,
2150 const llvm::SmallVectorImpl<clang::QualType> &proto, Longptr_t *poffset,
2151 EFunctionMatchMode mode/*=kConversionMatch*/)
2152{
2153 SetFuncProto(info, method, proto, false, poffset, mode);
2154}
2155
2156void TClingCallFunc::SetFuncProto(const TClingClassInfo *info, const char *method,
2157 const llvm::SmallVectorImpl<clang::QualType> &proto,
2158 bool objectIsConst, Longptr_t *poffset,
2159 EFunctionMatchMode mode/*=kConversionMatch*/)
2160{
2161 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(fInterp)));
2162 if (poffset) {
2163 *poffset = 0L;
2164 }
2165 ResetArg();
2166 if (!info->IsValid()) {
2167 ::Error("TClingCallFunc::SetFuncProto", "Class info is invalid!");
2168 return;
2169 }
2170 *fMethod = info->GetMethod(method, proto, objectIsConst, poffset, mode);
2171 if (!fMethod->IsValid()) {
2172 //::Error("TClingCallFunc::SetFuncProto", "Could not find method %s(%s)",
2173 // method, proto);
2174 return;
2175 }
2176}
2177
long Longptr_t
Definition RtypesCore.h:82
static void EvaluateExpr(cling::Interpreter &interp, const Expr *E, cling::Value &V)
static void GetTypeAsString(QualType QT, string &type_name, ASTContext &C, PrintingPolicy Policy)
static unsigned long long gWrapperSerial
static map< const Decl *, void * > gCtorWrapperStore
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)
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:197
#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:585
const char * proto
Definition civetweb.c:17502
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)
std::unique_ptr< TClingMethodInfo > fMethod
Current method, we own.
ExecWithRetFunc_t InitRetAndExec(const clang::FunctionDecl *FD, cling::Value &ret)
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()
ExecWithRetFunc_t InitRetAndExecNoCtor(clang::QualType QT, cling::Value &ret)
bool IsValid() const
tcling_callfunc_dtor_Wrapper_t make_dtor_wrapper(const TClingClassInfo *info)
std::function< void(void *address, cling::Value &ret)> ExecWithRetFunc_t
void ExecDestructor(const TClingClassInfo *info, void *address=nullptr, unsigned long nary=0UL, bool withFree=true)
Longptr_t ExecInt(void *address)
void execWithLL(void *address, cling::Value *val)
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 exec_with_valref_return(void *address, cling::Value *ret)
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 execWithULL(void *address, cling::Value *val)
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
ExecWithRetFunc_t InitRetAndExecIntegral(clang::QualType QT, cling::Value &ret)
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 &)
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)
void SetArg(long arg)
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)
ExecWithRetFunc_t InitRetAndExecBuiltin(clang::QualType QT, const clang::BuiltinType *BT, cling::Value &ret)
Emulation of the CINT ClassInfo class.
TClingMethodInfo GetMethodWithArgs(const char *fname, const char *arglist, Longptr_t *poffset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch, EInheritanceMode imode=kWithInheritance) const
TClingMethodInfo GetMethod(const char *fname) const
virtual bool IsValid() const
virtual const clang::Decl * GetDecl() const
Emulation of the CINT MethodInfo class.
This class defines an interface to the cling C++ interpreter.
Definition TCling.h:102
virtual const void * GetValAddr() const =0
long double ldbl
unsigned long ul
union ValHolder::@28 u
unsigned long long ull
unsigned int ui
signed char sc
unsigned short us
unsigned char uc
#define F(x, y, z)
#define I(x, y, z)
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
EFunctionMatchMode