Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TClingCallFunc.h
Go to the documentation of this file.
1// root/core/meta
2// vim: sw=3
3// Author: Paul Russo 30/07/2012
4
5/*************************************************************************
6 * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers. *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 *************************************************************************/
12
13#ifndef ROOT_CallFunc
14#define ROOT_CallFunc
15
16//////////////////////////////////////////////////////////////////////////
17// //
18// TClingCallFunc //
19// //
20// Emulation of the CINT CallFunc class. //
21// //
22// The CINT C++ interpreter provides an interface for calling //
23// functions through the generated wrappers in dictionaries with //
24// the CallFunc class. This class provides the same functionality, //
25// using an interface as close as possible to CallFunc but the //
26// function metadata and calling service comes from the Cling //
27// C++ interpreter and the Clang C++ compiler, not CINT. //
28// //
29//////////////////////////////////////////////////////////////////////////
30
31#include "TClingUtils.h"
32#include "TClingMethodInfo.h"
33#include "TInterpreter.h"
34
35#include "cling/Interpreter/Value.h"
36
37#include "clang/AST/ASTContext.h"
38#include "llvm/ADT/SmallVector.h"
39
40namespace clang {
41class BuiltinType;
42class CXXMethodDecl;
43class DeclContext;
44class Expr;
45class FunctionDecl;
46}
47
48namespace cling {
49class Interpreter;
50}
51
52class TClingClassInfo;
55
56typedef void (*tcling_callfunc_Wrapper_t)(void*, int, void**, void*);
57typedef void (*tcling_callfunc_ctor_Wrapper_t)(void**, void*, unsigned long);
58typedef void (*tcling_callfunc_dtor_Wrapper_t)(void*, unsigned long, int);
59
61
62private:
63
64 /// Cling interpreter, we do *not* own.
65 cling::Interpreter* fInterp;
66 /// Current method, we own.
67 std::unique_ptr<TClingMethodInfo> fMethod;
68 /// Decl for the method
69 const clang::FunctionDecl *fDecl = nullptr;
70 /// Number of required arguments
72 /// Pointer to compiled wrapper, we do *not* own.
73 std::atomic<tcling_callfunc_Wrapper_t> fWrapper;
74 /// Stored function arguments, we own.
75 mutable llvm::SmallVector<cling::Value, 8> fArgVals;
76
77private:
82 };
83
84 using ExecWithRetFunc_t = std::function<void(void* address, cling::Value &ret)>;
85
86 void* compile_wrapper(const std::string& wrapper_name,
87 const std::string& wrapper,
88 bool withAccessControl = true);
89
90 void collect_type_info(clang::QualType& QT, std::ostringstream& typedefbuf,
91 std::ostringstream& callbuf, std::string& type_name,
92 EReferenceType& refType, bool& isPointer, int indent_level,
93 bool forArgument);
94
95 void make_narg_call(const std::string &return_type, const unsigned N, std::ostringstream &typedefbuf,
96 std::ostringstream &callbuf, const std::string &class_name, int indent_level);
97
98 void make_narg_ctor(const unsigned N, std::ostringstream& typedefbuf,
99 std::ostringstream& callbuf,
100 const std::string& class_name, int indent_level);
101
102 void make_narg_call_with_return(const unsigned N,
103 const std::string& class_name,
104 std::ostringstream& buf, int indent_level);
105
106 void make_narg_ctor_with_return(const unsigned N,
107 const std::string& class_name,
108 std::ostringstream& buf, int indent_level);
109
111
114
117
118 void exec(void* address, void* ret);
119
120 void exec_with_valref_return(void* address,
121 cling::Value& ret);
122 void EvaluateArgList(const std::string& ArgList);
123
125
127 if (fMinRequiredArguments == (size_t)-1)
130 }
131
132 // Implemented in source file.
133 template <typename T>
134 T ExecT(void* address);
135
136
137public:
138
139 ~TClingCallFunc() = default;
140
141 explicit TClingCallFunc(cling::Interpreter *interp)
142 : fInterp(interp), fWrapper(0)
143 {
144 fMethod = std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(interp));
145 }
146
147 explicit TClingCallFunc(const TClingMethodInfo &minfo)
148 : fInterp(minfo.GetInterpreter()), fWrapper(0)
149
150 {
151 fMethod = std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(minfo));
152 }
153
155 : fInterp(rhs.fInterp), fWrapper(rhs.fWrapper.load()), fArgVals(rhs.fArgVals)
156 {
157 fMethod = std::unique_ptr<TClingMethodInfo>(new TClingMethodInfo(*rhs.fMethod));
158 }
159
161
162 void* ExecDefaultConstructor(const TClingClassInfo* info,
164 const std::string &type_name,
165 void* address = nullptr, unsigned long nary = 0UL);
166 void ExecDestructor(const TClingClassInfo* info, void* address = nullptr,
167 unsigned long nary = 0UL, bool withFree = true);
168 void ExecWithReturn(void* address, void *ret = nullptr);
169 void ExecWithArgsAndReturn(void* address,
170 const void* args[] = 0,
171 int nargs = 0,
172 void* ret = 0);
173 void Exec(void* address, TInterpreterValue* interpVal = 0);
174 Longptr_t ExecInt(void* address);
175 long long ExecInt64(void* address);
176 double ExecDouble(void* address);
178 void IgnoreExtraArgs(bool ignore) { /*FIXME Remove that interface */ }
179 void Init();
180 void Init(const TClingMethodInfo&);
181 void Init(std::unique_ptr<TClingMethodInfo>);
182 void Invoke(cling::Value* result = 0) const;
183 void* InterfaceMethod();
184 bool IsValid() const;
186 const clang::DeclContext *GetDeclContext() const;
187
188 int get_wrapper_code(std::string &wrapper_name, std::string &wrapper);
189
190 const clang::FunctionDecl *GetDecl() {
192 if (!fDecl)
193 fDecl = fMethod->GetTargetFunctionDecl();
194 return fDecl;
195 }
196 const clang::FunctionDecl* GetDecl() const {
197 if (fDecl)
198 return fDecl;
199 return fMethod->GetTargetFunctionDecl();
200 }
201 const clang::Decl *GetFunctionOrShadowDecl() const {
202 return fMethod->GetDecl();
203 }
204 void ResetArg();
205 template<typename T, std::enable_if_t<std::is_fundamental<T>::value, bool> = true>
206 void SetArg(T arg) {
207 cling::Value ArgValue = cling::Value::Create(*fInterp, arg);
208 // T can be different from the actual parameter of the underlying function.
209 // If we know already the function signature, make sure we create the
210 // cling::Value with the proper type and representation to avoid
211 // re-adjusting at the time we execute.
212 if (const clang::FunctionDecl* FD = GetDecl()) {
213 // FIXME: We need to think how to handle the implicit this pointer.
214 // See the comment in TClingCallFunc::exec.
215 if (!llvm::isa<clang::CXXMethodDecl>(FD)) {
216 clang::QualType QT = FD->getParamDecl(fArgVals.size())->getType();
217 QT = QT.getCanonicalType();
218 clang::ASTContext &C = FD->getASTContext();
219 if (QT->isBuiltinType() && !C.hasSameType(QT, ArgValue.getType())) {
220 switch(QT->getAs<clang::BuiltinType>()->getKind()) {
221 default:
222 ROOT::TMetaUtils::Error("TClingCallFunc::SetArg", "Unknown builtin type!");
223#ifndef NDEBUG
224 QT->dump();
225#endif // NDEBUG
226 break;
227#define X(type, name) \
228 case clang::BuiltinType::name: \
229 ArgValue = cling::Value::Create(*fInterp, (type)arg); \
230 break;
231 CLING_VALUE_BUILTIN_TYPES
232#undef X
233 }
234 }
235 }
236 }
237 fArgVals.push_back(ArgValue);
238 }
239 void SetArgArray(Longptr_t* argArr, int narg);
240 void SetArgs(const char* args);
241 void SetFunc(const TClingClassInfo* info, const char* method,
242 const char* arglist, Longptr_t* poffset);
243 void SetFunc(const TClingClassInfo* info, const char* method,
244 const char* arglist, bool objectIsConst, Longptr_t* poffset);
245 void SetFunc(const TClingMethodInfo* info);
246 void SetFuncProto(const TClingClassInfo* info, const char* method,
247 const char* proto, Longptr_t* poffset,
249 void SetFuncProto(const TClingClassInfo* info, const char* method,
250 const char* proto, bool objectIsConst, Longptr_t* poffset,
252 void SetFuncProto(const TClingClassInfo* info, const char* method,
253 const llvm::SmallVectorImpl<clang::QualType>& proto,
254 Longptr_t* poffset,
256 void SetFuncProto(const TClingClassInfo* info, const char* method,
257 const llvm::SmallVectorImpl<clang::QualType>& proto,
258 bool objectIsConst, Longptr_t* poffset,
260};
261
262#endif // ROOT_CallFunc
long Longptr_t
Definition RtypesCore.h:82
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)
#define N
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char mode
R__EXTERN TVirtualMutex * gInterpreterMutex
#define R__LOCKGUARD_CLING(mutex)
const char * proto
Definition civetweb.c:17536
Emulation of the CINT CallFunc class.
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)
const clang::FunctionDecl * GetDecl() const
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)
TClingCallFunc(const TClingMethodInfo &minfo)
~TClingCallFunc()=default
std::function< void(void *address, cling::Value &ret)> ExecWithRetFunc_t
void ExecDestructor(const TClingClassInfo *info, void *address=nullptr, unsigned long nary=0UL, bool withFree=true)
Longptr_t ExecInt(void *address)
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)
TClingCallFunc(cling::Interpreter *interp)
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 Invoke(cling::Value *result=0) const
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)
TClingCallFunc(const TClingCallFunc &rhs)
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 IgnoreExtraArgs(bool ignore)
void SetArg(T arg)
TClingCallFunc & operator=(const TClingCallFunc &rhs)=delete
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.
void Error(const char *location, const char *fmt,...)
EFunctionMatchMode
@ kConversionMatch