Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TClingCallFunc.cxx
Go to the documentation of this file.
1// root/core/meta
2// vim: sw=3
3// Author: Paul Russo 30/07/2012
4// Author: Vassil Vassilev 9/02/2013
5
6/*************************************************************************
7 * Copyright (C) 1995-2023, Rene Brun and Fons Rademakers. *
8 * All rights reserved. *
9 * *
10 * For the licensing terms see $ROOTSYS/LICENSE. *
11 * For the list of contributors see $ROOTSYS/README/CREDITS. *
12 *************************************************************************/
13
14/** \class TClingCallFunc
15Emulation of the CINT CallFunc class.
16
17The CINT C++ interpreter provides an interface for calling
18functions through the generated wrappers in dictionaries with
19the CallFunc class. This class provides the same functionality,
20using an interface as close as possible to CallFunc but the
21function metadata and calling service comes from the Cling
22C++ interpreter and the Clang C++ compiler, not CINT.
23*/
24
25#include "TClingCallFunc.h"
26
27#include "TClingClassInfo.h"
28#include "TClingMethodInfo.h"
29#include "TClingUtils.h"
30
31#include "TError.h"
32#include "TCling.h"
33
34#include "TInterpreter.h"
35
36#include "cling/Interpreter/CompilationOptions.h"
37#include "cling/Interpreter/Interpreter.h"
38#include "cling/Interpreter/LookupHelper.h"
39#include "cling/Interpreter/Transaction.h"
40#include "cling/Interpreter/Value.h"
41#include "cling/Utils/AST.h"
42
43#include "clang/AST/ASTContext.h"
44#include "clang/AST/Decl.h"
45#include "clang/AST/DeclCXX.h"
46#include "clang/AST/GlobalDecl.h"
47#include "clang/AST/PrettyPrinter.h"
48#include "clang/AST/QualTypeNames.h"
49#include "clang/AST/RecordLayout.h"
50#include "clang/AST/Type.h"
51#include "clang/Frontend/CompilerInstance.h"
52#include "clang/Lex/Preprocessor.h"
53#include "clang/Sema/Sema.h"
54#include "clang/Sema/Lookup.h"
55
56#include "llvm/ADT/APInt.h"
57#include "llvm/ExecutionEngine/ExecutionEngine.h"
58#include "llvm/ExecutionEngine/GenericValue.h"
59#include "llvm/Support/Casting.h"
60#include "llvm/Support/raw_ostream.h"
61#include "llvm/IR/LLVMContext.h"
62#include "llvm/IR/DerivedTypes.h"
63#include "llvm/IR/Function.h"
64#include "llvm/IR/GlobalValue.h"
65#include "llvm/IR/Module.h"
66#include "llvm/IR/Type.h"
67
68#include "clang/Sema/SemaInternal.h"
69
70#include <map>
71#include <string>
72#include <sstream>
73
74using namespace ROOT;
75using namespace llvm;
76using namespace clang;
77using 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 vp_ary.reserve(num_args);
1425 for (unsigned i = 0; i < num_args; ++i) {
1426 QualType QT;
1427 // Check if we provided a this parameter.
1428 // FIXME: Currently we do not provide consistently the this pointer at
1429 // index 0 of the call arguments passed to the wrapper.
1430 // In C++ we can still call member functions which do not use it. Eg:
1431 // struct S {int Print() { return printf("a");} }; auto r1 = ((S*)0)->Print();
1432 // This works just fine even though it might be UB...
1433 bool implicitThisPassed = i == 0 && isa<CXXMethodDecl>(FD) && num_args - FD->getNumParams() == 1;
1434 if (implicitThisPassed)
1435 QT = cast<CXXMethodDecl>(FD)->getThisType();
1436 else
1437 QT = FD->getParamDecl(i)->getType();
1438 QT = QT.getCanonicalType();
1439 if (QT->isReferenceType() || QT->isRecordType()) {
1440 // the argument is already a pointer value (points to the same thing
1441 // as the reference or pointing to object passed by value.
1442 vp_ary.push_back(fArgVals[i].getPtr());
1443 } else {
1444 // Check if arguments need readjusting. This can happen if we called
1445 // cling::Value::Create which instantiates to say double but the
1446 // function signature requires a float.
1447 ASTContext &C = FD->getASTContext();
1448 if (QT->isBuiltinType() && !C.hasSameType(QT, fArgVals[i].getType())) {
1449 switch(QT->getAs<BuiltinType>()->getKind()) {
1450 default:
1451 ROOT::TMetaUtils::Error("TClingCallFunc::exec", "Unknown builtin type!");
1452#ifndef NDEBUG
1453 QT->dump();
1454#endif // NDEBUG
1455 break;
1456#define X(type, name) \
1457 case BuiltinType::name: fArgVals[i] = cling::Value::Create(*fInterp, fArgVals[i].castAs<type>()); break;
1458 CLING_VALUE_BUILTIN_TYPES
1459#undef X
1460 }
1461 }
1462 vp_ary.push_back(fArgVals[i].getPtrAddress());
1463 }
1464 }
1465 } // End of scope holding the lock
1466 (*fWrapper)(address, (int)num_args, (void **)vp_ary.data(), ret);
1467}
1468
1469void TClingCallFunc::exec_with_valref_return(void *address, cling::Value &ret)
1470{
1471 const FunctionDecl *FD = GetDecl();
1472
1473 QualType QT;
1474 if (llvm::isa<CXXConstructorDecl>(FD)) {
1476 ASTContext &Context = FD->getASTContext();
1477 const TypeDecl *TD = dyn_cast<TypeDecl>(GetDeclContext());
1478 QualType ClassTy(TD->getTypeForDecl(), 0);
1479 QT = Context.getLValueReferenceType(ClassTy);
1480 ret = cling::Value(QT, *fInterp);
1481 } else {
1482 QT = FD->getReturnType().getCanonicalType();
1483 ret = cling::Value(QT, *fInterp);
1484
1485 if (QT->isRecordType() || QT->isMemberDataPointerType())
1486 return exec(address, ret.getPtr());
1487 }
1488 exec(address, ret.getPtrAddress());
1489}
1490
1491void TClingCallFunc::EvaluateArgList(const string &ArgList)
1492{
1494
1495 SmallVector<Expr *, 4> exprs;
1496 fInterp->getLookupHelper().findArgList(ArgList, exprs,
1497 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
1498 : cling::LookupHelper::NoDiagnostics);
1499 for (SmallVectorImpl<Expr *>::const_iterator I = exprs.begin(),
1500 E = exprs.end(); I != E; ++I) {
1501 cling::Value val;
1502 EvaluateExpr(*fInterp, *I, val);
1503 if (!val.isValid()) {
1504 // Bad expression, all done.
1505 ::Error("TClingCallFunc::EvaluateArgList",
1506 "Bad expression in parameter %d of '%s'!",
1507 (int)(I - exprs.begin()),
1508 ArgList.c_str());
1509 return;
1510 }
1511 fArgVals.push_back(val);
1512 }
1513}
1514
1515void TClingCallFunc::Exec(void *address, TInterpreterValue *interpVal/*=0*/)
1516{
1517 IFacePtr();
1518 if (!fWrapper) {
1519 ::Error("TClingCallFunc::Exec(address, interpVal)",
1520 "Called with no wrapper, not implemented!");
1521 return;
1522 }
1523 if (!interpVal || !interpVal->GetValAddr()) {
1524 exec(address, nullptr);
1525 return;
1526 }
1527 cling::Value *val = reinterpret_cast<cling::Value *>(interpVal->GetValAddr());
1528 exec_with_valref_return(address, *val);
1529}
1530
1531template <typename T>
1533{
1534 IFacePtr();
1535 if (!fWrapper) {
1536 ::Error("TClingCallFunc::ExecT",
1537 "Called with no wrapper, not implemented!");
1538 return 0;
1539 }
1540 cling::Value ret;
1541 exec_with_valref_return(address, ret);
1542 if (ret.isVoid()) {
1543 return 0;
1544 }
1545
1546 if (ret.needsManagedAllocation())
1547 ((TCling *)gCling)->RegisterTemporary(ret);
1548
1549 return ret.castAs<T>();
1550}
1551
1553{
1554 return ExecT<Longptr_t>(address);
1555}
1556
1557long long TClingCallFunc::ExecInt64(void *address)
1558{
1559 return ExecT<long long>(address);
1560}
1561
1562double TClingCallFunc::ExecDouble(void *address)
1563{
1564 return ExecT<double>(address);
1565}
1566
1567void TClingCallFunc::ExecWithArgsAndReturn(void *address, const void *args[] /*= 0*/,
1568 int nargs /*= 0*/, void *ret/*= 0*/)
1569{
1570 IFacePtr();
1571 if (!fWrapper) {
1572 ::Error("TClingCallFunc::ExecWithArgsAndReturn(address, args, ret)",
1573 "Called with no wrapper, not implemented!");
1574 return;
1575 }
1576 (*fWrapper)(address, nargs, const_cast<void **>(args), ret);
1577}
1578
1579void TClingCallFunc::ExecWithReturn(void *address, void *ret/*= 0*/)
1580{
1581 IFacePtr();
1582 if (!fWrapper) {
1583 ::Error("TClingCallFunc::ExecWithReturn(address, ret)",
1584 "Called with no wrapper, not implemented!");
1585 return;
1586 }
1587 exec(address, ret);
1588}
1589
1592 const std::string &type_name,
1593 void *address /*=0*/, unsigned long nary /*= 0UL*/)
1594{
1595 if (!info->IsValid()) {
1596 ::Error("TClingCallFunc::ExecDefaultConstructor", "Invalid class info!");
1597 return nullptr;
1598 }
1599 tcling_callfunc_ctor_Wrapper_t wrapper = nullptr;
1600 {
1602 auto D = info->GetDecl();
1603 //if (!info->HasDefaultConstructor()) {
1604 // // FIXME: We might have a ROOT ioctor, we might
1605 // // have to check for that here.
1606 // ::Error("TClingCallFunc::ExecDefaultConstructor",
1607 // "Class has no default constructor: %s",
1608 // info->Name());
1609 // return 0;
1610 //}
1611 auto I = gCtorWrapperStore.find(D);
1612 if (I != gCtorWrapperStore.end()) {
1613 wrapper = (tcling_callfunc_ctor_Wrapper_t) I->second;
1614 } else {
1615 wrapper = make_ctor_wrapper(info, kind, type_name);
1616 }
1617 }
1618 if (!wrapper) {
1619 ::Error("TClingCallFunc::ExecDefaultConstructor",
1620 "Called with no wrapper, not implemented!");
1621 return nullptr;
1622 }
1623 void *obj = nullptr;
1624 (*wrapper)(&obj, address, nary);
1625 return obj;
1626}
1627
1628void TClingCallFunc::ExecDestructor(const TClingClassInfo *info, void *address /*=0*/,
1629 unsigned long nary /*= 0UL*/, bool withFree /*= true*/)
1630{
1631 if (!info->IsValid()) {
1632 ::Error("TClingCallFunc::ExecDestructor", "Invalid class info!");
1633 return;
1634 }
1635
1636 tcling_callfunc_dtor_Wrapper_t wrapper = nullptr;
1637 {
1639 const Decl *D = info->GetDecl();
1640 map<const Decl *, void *>::iterator I = gDtorWrapperStore.find(D);
1641 if (I != gDtorWrapperStore.end()) {
1642 wrapper = (tcling_callfunc_dtor_Wrapper_t) I->second;
1643 } else {
1644 wrapper = make_dtor_wrapper(info);
1645 }
1646 }
1647 if (!wrapper) {
1648 ::Error("TClingCallFunc::ExecDestructor",
1649 "Called with no wrapper, not implemented!");
1650 return;
1651 }
1652 (*wrapper)(address, nary, withFree);
1653}
1654
1657{
1658 return new TClingMethodInfo(*fMethod);
1659}
1660
1662{
1663 fMethod.reset();
1664 fWrapper = nullptr;
1665 fDecl = nullptr;
1667 ResetArg();
1668}
1669
1671{
1672 Init();
1673 fMethod = std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(minfo));
1674}
1675
1676void TClingCallFunc::Init(std::unique_ptr<TClingMethodInfo> minfo)
1677{
1678 Init();
1679 fMethod = std::move(minfo);
1680}
1681
1683{
1684 if (!IsValid()) {
1685 return nullptr;
1686 }
1687 if (!fWrapper) {
1688 const Decl *decl = GetFunctionOrShadowDecl();
1689
1691 // check if another thread already did it
1692 if (!fWrapper) {
1693 map<const Decl *, void *>::iterator I = gWrapperStore.find(decl);
1694 if (I != gWrapperStore.end()) {
1696 } else {
1698 }
1699 }
1700 }
1701 return (void *)fWrapper.load();
1702}
1703
1705{
1706 if (!fMethod) {
1707 return false;
1708 }
1709 return fMethod->IsValid();
1710}
1711
1713{
1714 if (!IsValid()) {
1715 ::Error("TClingCallFunc::IFacePtr(kind)",
1716 "Attempt to get interface while invalid.");
1718 }
1719 if (!fWrapper) {
1720 const Decl *decl = GetFunctionOrShadowDecl();
1721
1723 // check if another thread already did it
1724 if (!fWrapper) {
1725 map<const Decl *, void *>::iterator I = gWrapperStore.find(decl);
1726 if (I != gWrapperStore.end()) {
1728 } else {
1730 }
1731 }
1732 }
1734}
1735
1736
1738{
1739 fArgVals.clear();
1740}
1741
1742void TClingCallFunc::SetArgArray(Longptr_t *paramArr, int nparam)
1743{
1744 ResetArg();
1745 for (int i = 0; i < nparam; ++i) {
1746 SetArg(paramArr[i]);
1747 }
1748}
1749
1750void TClingCallFunc::SetArgs(const char *params)
1751{
1752 ResetArg();
1753 EvaluateArgList(params);
1754}
1755
1756void TClingCallFunc::SetFunc(const TClingClassInfo *info, const char *method, const char *arglist,
1757 Longptr_t *poffset)
1758{
1759 SetFunc(info, method, arglist, false, poffset);
1760}
1761
1762void TClingCallFunc::SetFunc(const TClingClassInfo *info, const char *method, const char *arglist,
1763 bool objectIsConst, Longptr_t *poffset)
1764{
1765 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(fInterp)));
1766 if (poffset) {
1767 *poffset = 0L;
1768 }
1769 ResetArg();
1770 if (!info->IsValid()) {
1771 ::Error("TClingCallFunc::SetFunc", "Class info is invalid!");
1772 return;
1773 }
1774 if (!strcmp(arglist, ")")) {
1775 // CINT accepted a single right paren as meaning no arguments.
1776 arglist = "";
1777 }
1778 *fMethod = info->GetMethodWithArgs(method, arglist, objectIsConst, poffset);
1779 if (!fMethod->IsValid()) {
1780 //::Error("TClingCallFunc::SetFunc", "Could not find method %s(%s)", method,
1781 // arglist);
1782 return;
1783 }
1784 // FIXME: The arglist was already parsed by the lookup, we should
1785 // enhance the lookup to return the resulting expression
1786 // list so we do not need to parse it again here.
1787 EvaluateArgList(arglist);
1788}
1789
1791{
1792 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(*info)));
1793 ResetArg();
1794 if (!fMethod->IsValid()) {
1795 return;
1796 }
1797}
1798
1799void TClingCallFunc::SetFuncProto(const TClingClassInfo *info, const char *method,
1800 const char *proto, Longptr_t *poffset,
1801 EFunctionMatchMode mode/*=kConversionMatch*/)
1802{
1803 SetFuncProto(info, method, proto, false, poffset, mode);
1804}
1805
1806void TClingCallFunc::SetFuncProto(const TClingClassInfo *info, const char *method,
1807 const char *proto, bool objectIsConst, Longptr_t *poffset,
1808 EFunctionMatchMode mode/*=kConversionMatch*/)
1809{
1810 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(fInterp)));
1811 if (poffset) {
1812 *poffset = 0L;
1813 }
1814 ResetArg();
1815 if (!info->IsValid()) {
1816 ::Error("TClingCallFunc::SetFuncProto", "Class info is invalid!");
1817 return;
1818 }
1819 *fMethod = info->GetMethod(method, proto, objectIsConst, poffset, mode);
1820 if (!fMethod->IsValid()) {
1821 //::Error("TClingCallFunc::SetFuncProto", "Could not find method %s(%s)",
1822 // method, proto);
1823 return;
1824 }
1825}
1826
1827void TClingCallFunc::SetFuncProto(const TClingClassInfo *info, const char *method,
1828 const llvm::SmallVectorImpl<clang::QualType> &proto, Longptr_t *poffset,
1829 EFunctionMatchMode mode/*=kConversionMatch*/)
1830{
1831 SetFuncProto(info, method, proto, false, poffset, mode);
1832}
1833
1834void TClingCallFunc::SetFuncProto(const TClingClassInfo *info, const char *method,
1835 const llvm::SmallVectorImpl<clang::QualType> &proto,
1836 bool objectIsConst, Longptr_t *poffset,
1837 EFunctionMatchMode mode/*=kConversionMatch*/)
1838{
1839 Init(std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(fInterp)));
1840 if (poffset) {
1841 *poffset = 0L;
1842 }
1843 ResetArg();
1844 if (!info->IsValid()) {
1845 ::Error("TClingCallFunc::SetFuncProto", "Class info is invalid!");
1846 return;
1847 }
1848 *fMethod = info->GetMethod(method, proto, objectIsConst, poffset, mode);
1849 if (!fMethod->IsValid()) {
1850 //::Error("TClingCallFunc::SetFuncProto", "Could not find method %s(%s)",
1851 // method, proto);
1852 return;
1853 }
1854}
1855
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:185
#define N
Option_t Option_t TPoint TPoint const char mode
char name[80]
Definition TGX11.cxx:110
R__EXTERN TVirtualMutex * gInterpreterMutex
#define R__LOCKGUARD_CLING(mutex)
R__EXTERN TInterpreter * gCling
Int_t gDebug
Definition TROOT.cxx:597
const char * proto
Definition civetweb.c:17536
void * ExecDefaultConstructor(const TClingClassInfo *info, ROOT::TMetaUtils::EIOCtorCategory kind, const std::string &type_name, void *address=nullptr, unsigned long nary=0UL)
void ExecWithReturn(void *address, void *ret=nullptr)
void exec_with_valref_return(void *address, cling::Value &ret)
std::unique_ptr< TClingMethodInfo > fMethod
Current method, we own.
void collect_type_info(clang::QualType &QT, std::ostringstream &typedefbuf, std::ostringstream &callbuf, std::string &type_name, EReferenceType &refType, bool &isPointer, int indent_level, bool forArgument)
void SetArgs(const char *args)
size_t fMinRequiredArguments
Number of required arguments.
T ExecT(void *address)
size_t CalculateMinRequiredArguments()
double ExecDouble(void *address)
void SetArgArray(Longptr_t *argArr, int narg)
tcling_callfunc_Wrapper_t make_wrapper()
bool IsValid() const
tcling_callfunc_dtor_Wrapper_t make_dtor_wrapper(const TClingClassInfo *info)
void ExecDestructor(const TClingClassInfo *info, void *address=nullptr, unsigned long nary=0UL, bool withFree=true)
Longptr_t ExecInt(void *address)
const clang::DeclContext * GetDeclContext() const
void * compile_wrapper(const std::string &wrapper_name, const std::string &wrapper, bool withAccessControl=true)
void SetFuncProto(const TClingClassInfo *info, const char *method, const char *proto, Longptr_t *poffset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
TInterpreter::CallFuncIFacePtr_t IFacePtr()
void exec(void *address, void *ret)
std::atomic< tcling_callfunc_Wrapper_t > fWrapper
Pointer to compiled wrapper, we do not own.
void make_narg_ctor(const unsigned N, std::ostringstream &typedefbuf, std::ostringstream &callbuf, const std::string &class_name, int indent_level)
void SetFunc(const TClingClassInfo *info, const char *method, const char *arglist, Longptr_t *poffset)
const clang::FunctionDecl * GetDecl()
void EvaluateArgList(const std::string &ArgList)
const clang::Decl * GetFunctionOrShadowDecl() const
void ExecWithArgsAndReturn(void *address, const void *args[]=0, int nargs=0, void *ret=0)
void Exec(void *address, TInterpreterValue *interpVal=0)
TClingMethodInfo * FactoryMethod() const
int get_wrapper_code(std::string &wrapper_name, std::string &wrapper)
size_t GetMinRequiredArguments()
tcling_callfunc_ctor_Wrapper_t make_ctor_wrapper(const TClingClassInfo *, ROOT::TMetaUtils::EIOCtorCategory, const std::string &)
void SetArg(T arg)
long long ExecInt64(void *address)
cling::Interpreter * fInterp
Cling interpreter, we do not own.
void make_narg_call(const std::string &return_type, const unsigned N, std::ostringstream &typedefbuf, std::ostringstream &callbuf, const std::string &class_name, int indent_level)
const clang::FunctionDecl * fDecl
Decl for the method.
void make_narg_call_with_return(const unsigned N, const std::string &class_name, std::ostringstream &buf, int indent_level)
llvm::SmallVector< cling::Value, 8 > fArgVals
Stored function arguments, we own.
void make_narg_ctor_with_return(const unsigned N, const std::string &class_name, std::ostringstream &buf, int indent_level)
Emulation of the CINT ClassInfo class.
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 Error(const char *location, const char *fmt,...)
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
EFunctionMatchMode