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"
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"
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"
68#include "clang/Sema/SemaInternal.h"
77using std::string, std::map, std::ostringstream, std::make_pair;
102 clang::Expr::EvalResult
evalRes;
103 if (E->EvaluateAsInt(
evalRes, C, Expr::SE_NoSideEffects)) {
108 V = cling::Value(C.IntTy,
interp);
112 V.setLongLong(res.getSExtValue());
114 V.setULongLong(res.getZExtValue());
120 Policy.SuppressTagKeyword =
true;
121 Policy.SuppressUnwrittenScope =
false;
122 Policy.SuppressInitializers =
false;
123 Policy.AnonymousTagLocations =
false;
125 raw_string_ostream out(buf);
126 E->printPretty(out,
nullptr, Policy, 0);
136 return GetDecl()->getMinRequiredArguments();
153 cling::utils::Transform::Config Config;
154 QT = cling::utils::Transform::GetPartiallyDesugaredType(C,
QT, Config,
true);
174 if (
QT->isFunctionPointerType()) {
189 }
else if (
QT->isMemberPointerType()) {
204 }
else if (
QT->isPointerType()) {
207 }
else if (
QT->isReferenceType()) {
213 if (
QT->isArrayType()) {
243 for (
unsigned i = 0U; i <
N; ++i) {
245 QualType
Ty =
PVD->getType();
246 QualType
QT =
Ty.getCanonicalType();
305 for (
unsigned i = 0U; i <
N; ++i) {
318 QualType
Ty =
PVD->getType();
319 QualType
QT =
Ty.getCanonicalType();
325 if (
FD->isVariadic())
349 llvm::raw_string_ostream stream(
name);
350 FD->getNameForDiagnostic(stream,
FD->getASTContext().getPrintingPolicy(),
false);
357 for (
unsigned i = 0U; i <
N; ++i) {
359 QualType
Ty =
PVD->getType();
360 QualType
QT =
Ty.getCanonicalType();
409 buf <<
"if (ret) {\n";
477 return fMethod->GetDecl()->getDeclContext();
483 assert(
FD &&
"generate_wrapper called without a function decl!");
493 QualType
QT(
TD->getTypeForDecl(), 0);
498 ND->getNameForDiagnostic(stream, Policy,
true);
508 FunctionDecl::TemplatedKind
TK =
FD->getTemplatedKind();
510 case FunctionDecl::TK_NonTemplate: {
520 case FunctionDecl::TK_FunctionTemplate: {
523 ::Error(
"TClingCallFunc::make_wrapper",
"Cannot make wrapper for a function template!");
526 case FunctionDecl::TK_MemberSpecialization: {
533 if (!
FD->isTemplateInstantiation()) {
548 ::Error(
"TClingCallFunc::make_wrapper",
"Cannot make wrapper for a member function "
549 "instantiation with no pattern!");
552 FunctionDecl::TemplatedKind
PTK =
Pattern->getTemplatedKind();
556 (
PTK == FunctionDecl::TK_NonTemplate) ||
559 ((
PTK != FunctionDecl::TK_FunctionTemplate) &&
565 }
else if (!
Pattern->hasBody()) {
566 ::Error(
"TClingCallFunc::make_wrapper",
"Cannot make wrapper for a member function "
567 "instantiation with no body!");
570 if (
FD->isImplicitlyInstantiable()) {
574 case FunctionDecl::TK_FunctionTemplateSpecialization: {
579 if (!
FD->isTemplateInstantiation()) {
594 ::Error(
"TClingCallFunc::make_wrapper",
"Cannot make wrapper for a function template"
595 "instantiation with no pattern!");
598 FunctionDecl::TemplatedKind
PTK =
Pattern->getTemplatedKind();
602 (
PTK == FunctionDecl::TK_NonTemplate) ||
605 ((
PTK != FunctionDecl::TK_FunctionTemplate) &&
613 ::Error(
"TClingCallFunc::make_wrapper",
"Cannot make wrapper for a function template"
614 "instantiation with no body!");
617 if (
FD->isImplicitlyInstantiable()) {
621 case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
629 if (!
FD->isTemplateInstantiation()) {
644 ::Error(
"TClingCallFunc::make_wrapper",
"Cannot make wrapper for a dependent function template"
645 "instantiation with no pattern!");
648 FunctionDecl::TemplatedKind
PTK =
Pattern->getTemplatedKind();
652 (
PTK == FunctionDecl::TK_NonTemplate) ||
655 ((
PTK != FunctionDecl::TK_FunctionTemplate) &&
663 ::Error(
"TClingCallFunc::make_wrapper",
"Cannot make wrapper for a dependent function template"
664 "instantiation with no body!");
667 if (
FD->isImplicitlyInstantiable()) {
674 ::Error(
"TClingCallFunc::make_wrapper",
"Unhandled template kind!");
697 clang::FunctionDecl *
FDmod =
const_cast<clang::FunctionDecl *
>(
FD);
698 clang::Sema &S =
fInterp->getSema();
700 cling::Interpreter::PushTransactionRAII
RAII(
fInterp);
705 ::Error(
"TClingCallFunc::make_wrapper",
"Failed to force template instantiation!");
710 FunctionDecl::TemplatedKind
TK =
Definition->getTemplatedKind();
712 case FunctionDecl::TK_NonTemplate: {
715 ::Error(
"TClingCallFunc::make_wrapper",
"Cannot make wrapper for a deleted function!");
717 }
else if (
Definition->isLateTemplateParsed()) {
718 ::Error(
"TClingCallFunc::make_wrapper",
"Cannot make wrapper for a late template parsed "
729 case FunctionDecl::TK_FunctionTemplate: {
732 ::Error(
"TClingCallFunc::make_wrapper",
"Cannot make wrapper for a function template!");
735 case FunctionDecl::TK_MemberSpecialization: {
740 ::Error(
"TClingCallFunc::make_wrapper",
"Cannot make wrapper for a deleted member function "
741 "of a specialization!");
743 }
else if (
Definition->isLateTemplateParsed()) {
744 ::Error(
"TClingCallFunc::make_wrapper",
"Cannot make wrapper for a late template parsed "
745 "member function of a specialization!");
755 case FunctionDecl::TK_FunctionTemplateSpecialization: {
761 ::Error(
"TClingCallFunc::make_wrapper",
"Cannot make wrapper for a deleted function "
762 "template specialization!");
764 }
else if (
Definition->isLateTemplateParsed()) {
765 ::Error(
"TClingCallFunc::make_wrapper",
"Cannot make wrapper for a late template parsed "
766 "function template specialization!");
776 case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
785 ::Error(
"TClingCallFunc::make_wrapper",
"Cannot make wrapper for a deleted dependent function "
786 "template specialization!");
788 }
else if (
Definition->isLateTemplateParsed()) {
789 ::Error(
"TClingCallFunc::make_wrapper",
"Cannot make wrapper for a late template parsed "
790 "dependent function template specialization!");
803 ::Error(
"TClingCallFunc::make_wrapper",
"Unhandled template kind!");
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 ";
835 buf <<
"(void* obj, int nargs, void** args, void* ret)\n"
848 buf <<
"if (nargs == " <<
N <<
") {\n";
860 "#pragma clang diagnostic pop";
881 if ((
N == 0 &&
SpecMemKind == clang::Sema::CXXDefaultConstructor) ||
894 QualType
QT =
FD->getReturnType().getCanonicalType();
895 if (
QT->isVoidType()) {
917 buf <<
"if (ret) {\n";
1012 ::Error(
"TClingCallFunc::make_wrapper",
1013 "Failed to compile\n ==== SOURCE BEGIN ====\n%s\n ==== SOURCE END ====",
1092 Policy.SuppressTagKeyword =
true;
1093 Policy.SuppressUnwrittenScope =
true;
1100 QualType
QT(
TD->getTypeForDecl(), 0);
1105 ND->getNameForDiagnostic(stream, Policy,
true);
1136 buf <<
"__attribute__((used)) ";
1137 buf <<
"extern \"C\" void ";
1139 buf <<
"(void** ret, void* arena, unsigned long nary)\n";
1151 buf <<
"if (!arena) {\n";
1153 buf <<
"if (!nary) {\n";
1162 buf <<
"*ret = new " <<
class_name <<
"[nary];\n";
1164 buf <<
"char *buf = (char *) malloc(nary * sizeof(" <<
class_name <<
"));\n";
1166 buf <<
"for (int k=0;k<nary;++k)\n";
1170 buf <<
"*ret = buf;\n";
1187 buf <<
"if (!nary) {\n";
1196 buf <<
"*ret = new (arena) " <<
class_name <<
"[nary];\n";
1198 buf <<
"for (int k=0;k<nary;++k)\n";
1202 buf <<
"*ret = arena;\n";
1222 ::Error(
"TClingCallFunc::make_ctor_wrapper",
1223 "Failed to compile\n ==== SOURCE BEGIN ====\n%s\n ==== SOURCE END ====",
1261 Policy.SuppressTagKeyword =
true;
1262 Policy.SuppressUnwrittenScope =
true;
1269 QualType
QT(
TD->getTypeForDecl(), 0);
1274 ND->getNameForDiagnostic(stream, Policy,
true);
1296 buf <<
"__attribute__((used)) ";
1297 buf <<
"extern \"C\" void ";
1299 buf <<
"(void* obj, unsigned long nary, int withFree)\n";
1311 buf <<
"if (withFree) {\n";
1314 buf <<
"if (!nary) {\n";
1317 buf <<
"delete (" <<
class_name <<
"*) obj;\n";
1325 buf <<
"delete[] (" <<
class_name <<
"*) obj;\n";
1348 buf <<
"if (!nary) {\n";
1351 buf <<
"((Nm*)obj)->~Nm();\n";
1362 buf <<
"(((Nm*)obj)+(--nary))->~Nm();\n";
1365 buf <<
"} while (nary);\n";
1386 ::Error(
"TClingCallFunc::make_dtor_wrapper",
1387 "Failed to compile\n ==== SOURCE BEGIN ====\n%s\n ==== SOURCE END ====",
1404 ::Error(
"TClingCallFunc::exec",
1405 "Not enough arguments provided for %s (%d instead of the minimum %d)",
1410 ::Error(
"TClingCallFunc::exec",
1411 "Too many arguments provided for %s (%d instead of the minimum %d)",
1418 ::Error(
"TClingCallFunc::exec",
1419 "The method %s is called without an object.",
1425 for (
unsigned i = 0; i <
num_args; ++i) {
1437 QT =
FD->getParamDecl(i)->getType();
1438 QT =
QT.getCanonicalType();
1439 if (
QT->isReferenceType() ||
QT->isRecordType()) {
1448 if (
QT->isBuiltinType() && !C.hasSameType(
QT,
fArgVals[i].getType())) {
1456#define X(type, name) \
1457 case BuiltinType::name: fArgVals[i] = cling::Value::Create(*fInterp, fArgVals[i].castAs<type>()); break;
1474 if (llvm::isa<CXXConstructorDecl>(
FD)) {
1478 QualType
ClassTy(
TD->getTypeForDecl(), 0);
1479 QT = Context.getLValueReferenceType(
ClassTy);
1482 QT =
FD->getReturnType().getCanonicalType();
1485 if (
QT->isRecordType() ||
QT->isMemberDataPointerType())
1486 return exec(address,
ret.getPtr());
1488 exec(address,
ret.getPtrAddress());
1497 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
1498 : cling::LookupHelper::NoDiagnostics);
1503 if (!val.isValid()) {
1505 ::Error(
"TClingCallFunc::EvaluateArgList",
1506 "Bad expression in parameter %d of '%s'!",
1519 ::Error(
"TClingCallFunc::Exec(address, interpVal)",
1520 "Called with no wrapper, not implemented!");
1524 exec(address,
nullptr);
1527 cling::Value *val =
reinterpret_cast<cling::Value *
>(
interpVal->GetValAddr());
1531template <
typename T>
1536 ::Error(
"TClingCallFunc::ExecT",
1537 "Called with no wrapper, not implemented!");
1546 if (
ret.needsManagedAllocation())
1549 return ret.castAs<T>();
1572 ::Error(
"TClingCallFunc::ExecWithArgsAndReturn(address, args, ret)",
1573 "Called with no wrapper, not implemented!");
1576 (*fWrapper)(address,
nargs,
const_cast<void **
>(args),
ret);
1583 ::Error(
"TClingCallFunc::ExecWithReturn(address, ret)",
1584 "Called with no wrapper, not implemented!");
1593 void *address ,
unsigned long nary )
1595 if (!
info->IsValid()) {
1596 ::Error(
"TClingCallFunc::ExecDefaultConstructor",
"Invalid class info!");
1602 auto D =
info->GetDecl();
1619 ::Error(
"TClingCallFunc::ExecDefaultConstructor",
1620 "Called with no wrapper, not implemented!");
1623 void *obj =
nullptr;
1624 (*wrapper)(&obj, address,
nary);
1631 if (!
info->IsValid()) {
1632 ::Error(
"TClingCallFunc::ExecDestructor",
"Invalid class info!");
1648 ::Error(
"TClingCallFunc::ExecDestructor",
1649 "Called with no wrapper, not implemented!");
1715 ::Error(
"TClingCallFunc::IFacePtr(kind)",
1716 "Attempt to get interface while invalid.");
1745 for (
int i = 0; i <
nparam; ++i) {
1770 if (!
info->IsValid()) {
1771 ::Error(
"TClingCallFunc::SetFunc",
"Class info is invalid!");
1815 if (!
info->IsValid()) {
1816 ::Error(
"TClingCallFunc::SetFuncProto",
"Class info is invalid!");
1835 const llvm::SmallVectorImpl<clang::QualType> &
proto,
1844 if (!
info->IsValid()) {
1845 ::Error(
"TClingCallFunc::SetFuncProto",
"Class info is invalid!");
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)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Option_t Option_t TPoint TPoint const char mode
R__EXTERN TVirtualMutex * gInterpreterMutex
#define R__LOCKGUARD_CLING(mutex)
R__EXTERN TInterpreter * gCling
const_iterator begin() const
const_iterator end() const
void * ExecDefaultConstructor(const TClingClassInfo *info, ROOT::TMetaUtils::EIOCtorCategory kind, const std::string &type_name, void *address=nullptr, unsigned long nary=0UL)
void ExecWithReturn(void *address, void *ret=nullptr)
void exec_with_valref_return(void *address, cling::Value &ret)
std::unique_ptr< TClingMethodInfo > fMethod
Current method, we own.
void collect_type_info(clang::QualType &QT, std::ostringstream &typedefbuf, std::ostringstream &callbuf, std::string &type_name, EReferenceType &refType, bool &isPointer, int indent_level, bool forArgument)
void SetArgs(const char *args)
size_t fMinRequiredArguments
Number of required arguments.
size_t CalculateMinRequiredArguments()
double ExecDouble(void *address)
void SetArgArray(Longptr_t *argArr, int narg)
tcling_callfunc_Wrapper_t make_wrapper()
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 &)
long long ExecInt64(void *address)
cling::Interpreter * fInterp
Cling interpreter, we do not own.
void make_narg_call(const std::string &return_type, const unsigned N, std::ostringstream &typedefbuf, std::ostringstream &callbuf, const std::string &class_name, int indent_level)
const clang::FunctionDecl * fDecl
Decl for the method.
void make_narg_call_with_return(const unsigned N, const std::string &class_name, std::ostringstream &buf, int indent_level)
llvm::SmallVector< cling::Value, 8 > fArgVals
Stored function arguments, we own.
void make_narg_ctor_with_return(const unsigned N, const std::string &class_name, std::ostringstream &buf, int indent_level)
Emulation of the CINT ClassInfo class.
Emulation of the CINT MethodInfo class.
This class defines an interface to the cling C++ interpreter.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...