Logo ROOT  
Reference Guide
TClingMethodInfo.cxx
Go to the documentation of this file.
1// @(#)root/core/meta:$Id$
2// Author: Paul Russo 30/07/2012
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TClingMethodInfo
13Emulation of the CINT MethodInfo class.
14
15The CINT C++ interpreter provides an interface to metadata about
16a function through the MethodInfo class. This class provides the
17same functionality, using an interface as close as possible to
18MethodInfo but the typedef metadata comes from the Clang C++
19compiler, not CINT.
20*/
21
22#include "TClingMethodInfo.h"
23
24#include "TClingCallFunc.h"
25#include "TClingClassInfo.h"
26#include "TClingMethodArgInfo.h"
27#include "TDictionary.h"
28#include "TClingTypeInfo.h"
29#include "TError.h"
30#include "TClingUtils.h"
31#include "TCling.h"
32#include "ThreadLocalStorage.h"
33
34#include "cling/Interpreter/Interpreter.h"
35#include "cling/Interpreter/LookupHelper.h"
36#include "cling/Utils/AST.h"
37
38#include "clang/AST/ASTContext.h"
39#include "clang/AST/Decl.h"
40#include "clang/AST/DeclCXX.h"
41#include "clang/AST/DeclTemplate.h"
42#include "clang/AST/ExprCXX.h"
43#include "clang/AST/GlobalDecl.h"
44#include "clang/AST/Mangle.h"
45#include "clang/AST/PrettyPrinter.h"
46#include "clang/AST/Type.h"
47#include "clang/Basic/IdentifierTable.h"
48#include "clang/Sema/Lookup.h"
49#include "clang/Sema/Sema.h"
50#include "clang/Sema/Template.h"
51#include "clang/Sema/TemplateDeduction.h"
52
53#include "llvm/Support/Casting.h"
54#include "llvm/Support/raw_ostream.h"
55
56#include <string>
57
58using namespace clang;
59
61 TClingDeclInfo(rhs),
62 fInterp(rhs.fInterp),
63 fContexts(rhs.fContexts),
64 fFirstTime(rhs.fFirstTime),
65 fContextIdx(rhs.fContextIdx),
66 fIter(rhs.fIter),
67 fTitle(rhs.fTitle),
68 fTemplateSpec(rhs.fTemplateSpec)
69{
70}
71
72
74 if (this == &rhs)
75 return *this;
76
78 fInterp = rhs.fInterp;
79 fContexts = rhs.fContexts;
82 fIter = rhs.fIter;
83 fTitle = rhs.fTitle;
85
86 return *this;
87}
88
89
90TClingMethodInfo::TClingMethodInfo(cling::Interpreter *interp,
92 : TClingDeclInfo(nullptr), fInterp(interp), fFirstTime(true), fContextIdx(0U), fTitle(""),
93 fTemplateSpec(0)
94{
96
97 if (!ci || !ci->IsValid()) {
98 return;
99 }
100 clang::CXXRecordDecl *cxxdecl = llvm::dyn_cast<clang::CXXRecordDecl>(const_cast<clang::Decl*>(ci->GetDecl()));
101 if (cxxdecl) {
102 // Make sure we have an entry for all the implicit function.
103
104 // Could trigger deserialization of decls.
105 cling::Interpreter::PushTransactionRAII RAII(interp);
106
107 fInterp->getSema().ForceDeclarationOfImplicitMembers(cxxdecl);
108 }
109 clang::DeclContext *dc =
110 llvm::cast<clang::DeclContext>(const_cast<clang::Decl*>(ci->GetDecl()));
111 dc->collectAllContexts(fContexts);
112 // Could trigger deserialization of decls.
113 cling::Interpreter::PushTransactionRAII RAII(interp);
114 fIter = dc->decls_begin();
115 InternalNext();
116 fFirstTime = true;
117}
118
119TClingMethodInfo::TClingMethodInfo(cling::Interpreter *interp,
120 const clang::FunctionDecl *FD)
121 : TClingDeclInfo(FD), fInterp(interp), fFirstTime(true), fContextIdx(0U), fTitle(""),
122 fTemplateSpec(0)
123{
124
125}
126
128{
129 delete fTemplateSpec;
130}
131
133{
134 if (!IsValid()) {
135 return TDictionary::DeclId_t();
136 }
137 return (const clang::Decl*)(GetMethodDecl()->getCanonicalDecl());
138}
139
140const clang::FunctionDecl *TClingMethodInfo::GetMethodDecl() const
141{
142 return cast_or_null<FunctionDecl>(GetDecl());
143}
144
146{
147 signature = "(";
148 if (!IsValid()) {
149 signature += ")";
150 return;
151 }
152
154 TClingMethodArgInfo arg(fInterp, this);
155
156 int idx = 0;
157 while (arg.Next()) {
158 if (idx) {
159 signature += ", ";
160 }
161 signature += arg.Type()->Name();
162 if (arg.Name() && strlen(arg.Name())) {
163 signature += " ";
164 signature += arg.Name();
165 }
166 if (arg.DefaultValue()) {
167 signature += " = ";
168 signature += arg.DefaultValue();
169 }
170 ++idx;
171 }
172 auto decl = GetMethodDecl();
173 if (decl && decl->isVariadic())
174 signature += ",...";
175
176 signature += ")";
177}
178
179void TClingMethodInfo::Init(const clang::FunctionDecl *decl)
180{
181 fContexts.clear();
182 fFirstTime = true;
183 fContextIdx = 0U;
184 fIter = clang::DeclContext::decl_iterator();
185 fTemplateSpec = 0;
186 fDecl = decl;
187}
188
189void *TClingMethodInfo::InterfaceMethod(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
190{
191 if (!IsValid()) {
192 return 0;
193 }
195 TClingCallFunc cf(fInterp,normCtxt);
196 cf.SetFunc(this);
197 return cf.InterfaceMethod();
198}
199
200const clang::Decl* TClingMethodInfo::GetDeclSlow() const
201{
202 if (fTemplateSpec) {
203 return fTemplateSpec;
204 }
205 return *fIter;
206}
207
209{
210 if (!IsValid()) {
211 return -1;
212 }
213 const clang::FunctionDecl *fd = GetMethodDecl();
214 unsigned num_params = fd->getNumParams();
215 // Truncate cast to fit cint interface.
216 return static_cast<int>(num_params);
217}
218
220{
221 if (!IsValid()) {
222 return -1;
223 }
224 const clang::FunctionDecl *fd = GetMethodDecl();
225 unsigned num_params = fd->getNumParams();
226 unsigned min_args = fd->getMinRequiredArguments();
227 unsigned defaulted_params = num_params - min_args;
228 // Truncate cast to fit cint interface.
229 return static_cast<int>(defaulted_params);
230}
231
232/*
233static bool HasUnexpandedParameterPack(clang::QualType QT, clang::Sema& S) {
234 if (llvm::isa<PackExpansionType>(*QT)) {
235 // We are not going to expand the pack here...
236 return true;
237 }
238 SmallVector<UnexpandedParameterPack, 4> Unexpanded;
239 S.collectUnexpandedParameterPacks (QT, Unexpanded);
240
241 return !Unexpanded.empty();
242}
243 */
244
245static const clang::FunctionDecl *
246GetOrInstantiateFuncTemplateWithDefaults(clang::FunctionTemplateDecl* FTDecl,
247 clang::Sema& S,
248 const cling::LookupHelper& LH) {
249 // Force instantiation if it doesn't exist yet, by looking it up.
250 using namespace clang;
251
252 auto templateParms = FTDecl->getTemplateParameters();
253 if (templateParms->containsUnexpandedParameterPack())
254 return nullptr;
255
256 if (templateParms->getMinRequiredArguments() > 0)
257 return nullptr;
258
259 if (templateParms->size() > 0) {
260 NamedDecl *arg0 = *templateParms->begin();
261 if (arg0->isTemplateParameterPack())
262 return nullptr;
263 if (auto TTP = dyn_cast<TemplateTypeParmDecl>(*templateParms->begin())) {
264 if (!TTP->hasDefaultArgument())
265 return nullptr;
266 } else if (auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(
267 *templateParms->begin())) {
268 if (!NTTP->hasDefaultArgument())
269 return nullptr;
270 } else {
271 // TemplateTemplateParmDecl, pack
272 return nullptr;
273 }
274 }
275
276 FunctionDecl *templatedDecl = FTDecl->getTemplatedDecl();
277 Decl *declCtxDecl = dyn_cast<Decl>(FTDecl->getDeclContext());
278
279 // We have a function template
280 // template <class X = int, int i = 7> void func(int a0, X a1[i], X::type a2[i])
281 // which has defaults for all its template parameters `X` and `i`. To
282 // instantiate it we have to do a lookup, which in turn needs the function
283 // argument types, e.g. `int[12]`.
284 // If the function argument type is dependent (a1 and a2) we need to
285 // substitute the types first, using the template arguments derived from the
286 // template parameters' defaults.
287 llvm::SmallVector<TemplateArgument, 8> defaultTemplateArgs(templateParms->size());
288 for (int iParam = 0, nParams = templateParms->size(); iParam < nParams; ++iParam) {
289 const NamedDecl* templateParm = templateParms->getParam(iParam);
290 if (templateParm->isTemplateParameterPack()) {
291 // shouldn't end up here
292 assert(0 && "unexpected template parameter pack");
293 return nullptr;
294 } if (auto TTP = dyn_cast<TemplateTypeParmDecl>(templateParm)) {
295 if (!TTP->hasDefaultArgument())
296 return nullptr;
297 defaultTemplateArgs[iParam] = TemplateArgument(TTP->getDefaultArgument());
298 } else if (auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(templateParm)) {
299 if (!NTTP->hasDefaultArgument())
300 return nullptr;
301 defaultTemplateArgs[iParam] = TemplateArgument(NTTP->getDefaultArgument());
302 } else if (auto TTP = dyn_cast<TemplateTemplateParmDecl>(templateParm)) {
303 if (!TTP->hasDefaultArgument())
304 return nullptr;
305 defaultTemplateArgs[iParam] = TemplateArgument(TTP->getDefaultArgument().getArgument());
306 } else {
307 // shouldn't end up here
308 assert(0 && "unexpected template parameter kind");
309 return nullptr;
310 }
311 }
312
313 // Now substitute the dependent function parameter types given defaultTemplateArgs.
314 llvm::SmallVector<QualType, 8> paramTypes;
315 // Provide an instantiation context that suppresses errors:
316 // DeducedTemplateArgumentSubstitution! (ROOT-8422)
317 SmallVector<DeducedTemplateArgument, 4> DeducedArgs;
318 sema::TemplateDeductionInfo Info{SourceLocation()};
319
320 Sema::InstantiatingTemplate Inst(S, Info.getLocation(), FTDecl,
321 defaultTemplateArgs,
322 Sema::CodeSynthesisContext::DeducedTemplateArgumentSubstitution,
323 Info);
324
325 // Collect the function arguments of the templated function, substituting
326 // dependent types as possible.
327 TemplateArgumentList templArgList(TemplateArgumentList::OnStack, defaultTemplateArgs);
328 MultiLevelTemplateArgumentList MLTAL{templArgList};
329 for (const clang::ParmVarDecl *param: templatedDecl->parameters()) {
330 QualType paramType = param->getOriginalType();
331
332 // If the function type is dependent, try to resolve it through the class's
333 // template arguments. If that fails, skip this function.
334 if (paramType->isDependentType()) {
335 /*if (HasUnexpandedParameterPack(paramType, S)) {
336 // We are not going to expand the pack here...
337 skip = true;
338 break;
339 }*/
340
341 paramType = S.SubstType(paramType, MLTAL, SourceLocation(),
342 templatedDecl->getDeclName());
343
344 if (paramType.isNull() || paramType->isDependentType()) {
345 // Even after resolving the types through the surrounding template
346 // this argument type is still dependent: do not look it up.
347 return nullptr;
348 }
349 }
350 paramTypes.push_back(paramType);
351 }
352
353 return LH.findFunctionProto(declCtxDecl, FTDecl->getNameAsString(),
354 paramTypes, LH.NoDiagnostics,
355 templatedDecl->getType().isConstQualified());
356}
357
359{
360
361 assert(!fDecl && "This is not an iterator!");
362
363 fNameCache.clear(); // invalidate the cache.
364
365 if (!fFirstTime && !*fIter) {
366 // Iterator is already invalid.
367 return 0;
368 }
369 while (true) {
370 // If we had fTemplateSpec we don't need it anymore, but advance
371 // to the next decl.
372 fTemplateSpec = nullptr;
373
374 // Advance to the next decl.
375 if (fFirstTime) {
376 // The cint semantics are weird.
377 fFirstTime = false;
378 }
379 else {
380 ++fIter;
381 }
382 // Fix it if we have gone past the end of the current decl context.
383 while (!*fIter) {
384 ++fContextIdx;
385 if (fContextIdx >= fContexts.size()) {
386 // Iterator is now invalid.
387 return 0;
388 }
389 clang::DeclContext *dc = fContexts[fContextIdx];
390 // Could trigger deserialization of decls.
391
392 cling::Interpreter::PushTransactionRAII RAII(fInterp);
393 fIter = dc->decls_begin();
394 if (*fIter) {
395 // Good, a non-empty context.
396 break;
397 }
398 }
399
400 if (const auto templateDecl = llvm::dyn_cast<clang::FunctionTemplateDecl>(*fIter)) {
401 // Instantiation below can trigger deserialization.
402 cling::Interpreter::PushTransactionRAII RAII(fInterp);
403
404 // If this function template can be instantiated without template
405 // arguments then it's worth having it. This commonly happens for
406 // enable_if'ed functions.
408 fInterp->getLookupHelper());
409 if (fTemplateSpec && fTemplateSpec->isDeleted())
410 fTemplateSpec = nullptr;
411 if (fTemplateSpec)
412 return 1;
413 }
414
415 // Return if this decl is a function or method.
416 if (auto *FD = llvm::dyn_cast<clang::FunctionDecl>(*fIter)) {
417 if (!FD->isDeleted())
418 // Iterator is now valid.
419 return 1;
420 }
421
422 // Collect internal `__cling_N5xxx' inline namespaces; they will be traversed later
423 if (auto NS = dyn_cast<NamespaceDecl>(*fIter)) {
424 if (NS->getDeclContext()->isTranslationUnit() && NS->isInlineNamespace())
425 fContexts.push_back(NS);
426 }
427// if (clang::FunctionDecl *fdecl = llvm::dyn_cast<clang::FunctionDecl>(*fIter)) {
428// if (fdecl->getAccess() == clang::AS_public || fdecl->getAccess() == clang::AS_none) {
429// // Iterator is now valid.
430// return 1;
431// }
432// }
433 }
434}
435
437{
438 return InternalNext();
439}
440
442{
443 if (!IsValid()) {
444 return 0L;
445 }
446 long property = 0L;
447 property |= kIsCompiled;
448 const clang::FunctionDecl *fd = GetMethodDecl();
449 if (fd->isConstexpr())
450 property |= kIsConstexpr;
451 switch (fd->getAccess()) {
452 case clang::AS_public:
453 property |= kIsPublic;
454 break;
455 case clang::AS_protected:
456 property |= kIsProtected;
457 break;
458 case clang::AS_private:
459 property |= kIsPrivate;
460 break;
461 case clang::AS_none:
462 if (fd->getDeclContext()->isNamespace())
463 property |= kIsPublic;
464 break;
465 default:
466 // IMPOSSIBLE
467 break;
468 }
469 if (fd->getStorageClass() == clang::SC_Static) {
470 property |= kIsStatic;
471 }
472 clang::QualType qt = fd->getReturnType().getCanonicalType();
473 if (qt.isConstQualified()) {
474 property |= kIsConstant;
475 }
476 while (1) {
477 if (qt->isArrayType()) {
478 qt = llvm::cast<clang::ArrayType>(qt)->getElementType();
479 continue;
480 }
481 else if (qt->isReferenceType()) {
482 property |= kIsReference;
483 qt = llvm::cast<clang::ReferenceType>(qt)->getPointeeType();
484 continue;
485 }
486 else if (qt->isPointerType()) {
487 property |= kIsPointer;
488 if (qt.isConstQualified()) {
489 property |= kIsConstPointer;
490 }
491 qt = llvm::cast<clang::PointerType>(qt)->getPointeeType();
492 continue;
493 }
494 else if (qt->isMemberPointerType()) {
495 qt = llvm::cast<clang::MemberPointerType>(qt)->getPointeeType();
496 continue;
497 }
498 break;
499 }
500 if (qt.isConstQualified()) {
501 property |= kIsConstant;
502 }
503 if (const clang::CXXMethodDecl *md =
504 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
505 if (md->getTypeQualifiers() & clang::Qualifiers::Const) {
506 property |= kIsConstant | kIsConstMethod;
507 }
508 if (md->isVirtual()) {
509 property |= kIsVirtual;
510 }
511 if (md->isPure()) {
512 property |= kIsPureVirtual;
513 }
514 if (const clang::CXXConstructorDecl *cd =
515 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
516 if (cd->isExplicit()) {
517 property |= kIsExplicit;
518 }
519 }
520 else if (const clang::CXXConversionDecl *cd =
521 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
522 if (cd->isExplicit()) {
523 property |= kIsExplicit;
524 }
525 }
526 }
527 return property;
528}
529
531{
532 // Return the property not already defined in Property
533 // See TDictionary's EFunctionProperty
534 if (!IsValid()) {
535 return 0L;
536 }
537 long property = 0;
538 const clang::FunctionDecl *fd = GetMethodDecl();
539 if (fd->isOverloadedOperator())
540 property |= kIsOperator;
541 if (llvm::isa<clang::CXXConversionDecl>(fd))
542 property |= kIsConversion;
543 if (llvm::isa<clang::CXXConstructorDecl>(fd))
544 property |= kIsConstructor;
545 if (llvm::isa<clang::CXXDestructorDecl>(fd))
546 property |= kIsDestructor;
547 if (fd->isInlined())
548 property |= kIsInlined;
549 return property;
550}
551
553{
554 TTHREAD_TLS_DECL_ARG( TClingTypeInfo, ti, fInterp );
555 if (!IsValid()) {
556 ti.Init(clang::QualType());
557 return &ti;
558 }
559 if (llvm::isa<clang::CXXConstructorDecl>(GetMethodDecl())) {
560 // CINT claims that constructors return the class object.
561 const clang::TypeDecl* ctorClass = llvm::dyn_cast_or_null<clang::TypeDecl>
562 (GetMethodDecl()->getDeclContext());
563 if (!ctorClass) {
564 Error("TClingMethodInfo::Type", "Cannot find DeclContext for constructor!");
565 } else {
566 clang::QualType qt(ctorClass->getTypeForDecl(), 0);
567 ti.Init(qt);
568 }
569 } else {
570 clang::QualType qt = GetMethodDecl()->getReturnType();
571 ti.Init(qt);
572 }
573 return &ti;
574}
575
577{
578 if (!IsValid()) {
579 return "";
580 }
581 std::string mangled_name;
582 mangled_name.clear();
583 const FunctionDecl* D = GetMethodDecl();
584
586 cling::Interpreter::PushTransactionRAII RAII(fInterp);
587 GlobalDecl GD;
588 if (const CXXConstructorDecl* Ctor = dyn_cast<CXXConstructorDecl>(D))
589 GD = GlobalDecl(Ctor, Ctor_Complete);
590 else if (const CXXDestructorDecl* Dtor = dyn_cast<CXXDestructorDecl>(D))
591 GD = GlobalDecl(Dtor, Dtor_Deleting);
592 else
593 GD = GlobalDecl(D);
594
595 cling::utils::Analyze::maybeMangleDeclName(GD, mangled_name);
596 return mangled_name;
597}
598
600{
601 if (!IsValid()) {
602 return 0;
603 }
604 TTHREAD_TLS_DECL( std::string, buf );
605 buf.clear();
606 buf += Type()->Name();
607 buf += ' ';
608 if (const clang::TypeDecl *td = llvm::dyn_cast<clang::TypeDecl>(GetMethodDecl()->getDeclContext())) {
609 std::string name;
610 clang::QualType qualType(td->getTypeForDecl(),0);
611 ROOT::TMetaUtils::GetFullyQualifiedTypeName(name,qualType,*fInterp);
612 buf += name;
613 buf += "::";
614 } else if (const clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(GetMethodDecl()->getDeclContext())) {
615 std::string name;
616 clang::PrintingPolicy policy(GetMethodDecl()->getASTContext().getPrintingPolicy());
617 llvm::raw_string_ostream stream(name);
618 nd->getNameForDiagnostic(stream, policy, /*Qualified=*/true);
619 stream.flush();
620 buf += name;
621 buf += "::";
622 }
623 buf += Name();
624
625 TString signature;
626 CreateSignature(signature);
627 buf += signature;
628
629 if (const clang::CXXMethodDecl *md =
630 llvm::dyn_cast<clang::CXXMethodDecl>( GetMethodDecl())) {
631 if (md->getTypeQualifiers() & clang::Qualifiers::Const) {
632 buf += " const";
633 }
634 }
635 return buf.c_str();
636}
637
639{
640 if (!IsValid()) {
641 return 0;
642 }
643 if (!fNameCache.empty())
644 return fNameCache.c_str();
645
646 ((TCling*)gCling)->GetFunctionName(GetMethodDecl(), fNameCache);
647 return fNameCache.c_str();
648}
649
650const char *TClingMethodInfo::TypeName() const
651{
652 if (!IsValid()) {
653 // FIXME: Cint does not check!
654 return 0;
655 }
656 return Type()->Name();
657}
658
660{
661 if (!IsValid()) {
662 return 0;
663 }
664
665 //NOTE: We can't use it as a cache due to the "thoughtful" self iterator
666 //if (fTitle.size())
667 // return fTitle.c_str();
668
669 // Try to get the comment either from the annotation or the header file if present
670
671 // Iterate over the redeclarations, we can have multiple definitions in the
672 // redecl chain (came from merging of pcms).
673 const FunctionDecl *FD = GetMethodDecl();
674
676
677 // Could trigger deserialization of decls.
678 cling::Interpreter::PushTransactionRAII RAII(fInterp);
679 if (const FunctionDecl *AnnotFD
680 = ROOT::TMetaUtils::GetAnnotatedRedeclarable(FD)) {
681 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
682 fTitle = A->getAnnotation().str();
683 return fTitle.c_str();
684 }
685 }
686 if (!FD->isFromASTFile()) {
687 // Try to get the comment from the header file if present
688 // but not for decls from AST file, where rootcling would have
689 // created an annotation
690 fTitle = ROOT::TMetaUtils::GetComment(*FD).str();
691 }
692
693 return fTitle.c_str();
694}
695
static const clang::FunctionDecl * GetOrInstantiateFuncTemplateWithDefaults(clang::FunctionTemplateDecl *FTDecl, clang::Sema &S, const cling::LookupHelper &LH)
@ kIsDestructor
Definition: TDictionary.h:125
@ kIsConversion
Definition: TDictionary.h:124
@ kIsInlined
Definition: TDictionary.h:127
@ kIsConstructor
Definition: TDictionary.h:123
@ kIsOperator
Definition: TDictionary.h:126
@ kIsPublic
Definition: TDictionary.h:74
@ kIsConstexpr
Definition: TDictionary.h:90
@ kIsPointer
Definition: TDictionary.h:77
@ kIsConstant
Definition: TDictionary.h:86
@ kIsConstMethod
Definition: TDictionary.h:93
@ kIsReference
Definition: TDictionary.h:81
@ kIsPrivate
Definition: TDictionary.h:76
@ kIsConstPointer
Definition: TDictionary.h:88
@ kIsCompiled
Definition: TDictionary.h:85
@ kIsStatic
Definition: TDictionary.h:79
@ kIsExplicit
Definition: TDictionary.h:91
@ kIsProtected
Definition: TDictionary.h:75
@ kIsVirtual
Definition: TDictionary.h:72
@ kIsPureVirtual
Definition: TDictionary.h:73
void Info(const char *location, const char *msgfmt,...)
void Error(const char *location, const char *msgfmt,...)
char name[80]
Definition: TGX11.cxx:109
R__EXTERN TVirtualMutex * gInterpreterMutex
Definition: TInterpreter.h:40
R__EXTERN TInterpreter * gCling
Definition: TInterpreter.h:556
Binding & operator=(OUT(*fun)(void))
#define R__LOCKGUARD(mutex)
Emulation of the CINT CallFunc class.
void SetFunc(const TClingClassInfo *info, const char *method, const char *arglist, long *poffset)
void * InterfaceMethod()
Emulation of the CINT ClassInfo class.
const clang::Decl * fDecl
virtual const char * Name()
virtual bool IsValid() const
std::string fNameCache
virtual const clang::Decl * GetDecl() const
Emulation of the CINT MethodInfo class.
const char * DefaultValue() const
const TClingTypeInfo * Type() const
Emulation of the CINT MethodInfo class.
const char * Name() override
clang::DeclContext::decl_iterator fIter
TClingMethodInfo & operator=(const TClingMethodInfo &in)
std::string GetMangledName() const
const char * TypeName() const
void * InterfaceMethod(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
unsigned int fContextIdx
const clang::Decl * GetDecl() const override
const char * GetPrototype()
void Init(const clang::FunctionDecl *)
const clang::FunctionDecl * GetMethodDecl() const
long ExtraProperty() const
const clang::Decl * GetDeclSlow() const
llvm::SmallVector< clang::DeclContext *, 2 > fContexts
TClingMethodInfo(cling::Interpreter *interp)
void CreateSignature(TString &signature) const
std::string fTitle
const char * Title()
TDictionary::DeclId_t GetDeclId() const
cling::Interpreter * fInterp
TClingTypeInfo * Type() const
const clang::FunctionDecl * fTemplateSpec
Emulation of the CINT TypeInfo class.
const char * Name() const
This class defines an interface to the cling C++ interpreter.
Definition: TCling.h:99
const void * DeclId_t
Definition: TDictionary.h:209
Basic string class.
Definition: TString.h:131
static double A[]
RooArgSet S(const RooAbsArg &v1)
static constexpr double L