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