Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
TCling.cxx
Go to the documentation of this file.
1// @(#)root/meta:$Id$
2// vim: sw=3 ts=3 expandtab foldmethod=indent
3
4/*************************************************************************
5 * Copyright (C) 1995-2012, 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 TCling
13
14This class defines an interface to the cling C++ interpreter.
15
16Cling is a full ANSI compliant C++-11 interpreter based on
17clang/LLVM technology.
18*/
19
20#include "TCling.h"
21
23
24#include "TClingBaseClassInfo.h"
25#include "TClingCallFunc.h"
26#include "TClingClassInfo.h"
28#include "TClingMethodArgInfo.h"
29#include "TClingMethodInfo.h"
31#include "TClingTypedefInfo.h"
32#include "TClingTypeInfo.h"
33#include "TClingValue.h"
34
35#include "TROOT.h"
36#include "TApplication.h"
37#include "TGlobal.h"
38#include "TDataType.h"
39#include "TClass.h"
40#include "TClassEdit.h"
41#include "TClassTable.h"
42#include "TClingCallbacks.h"
43#include "TClingDiagnostics.h"
44#include "TBaseClass.h"
45#include "TDataMember.h"
46#include "TMemberInspector.h"
47#include "TMethod.h"
48#include "TMethodArg.h"
49#include "TFunctionTemplate.h"
50#include "TObjArray.h"
51#include "TObjString.h"
52#include "TString.h"
53#include "THashList.h"
54#include "TVirtualPad.h"
55#include "TSystem.h"
56#include "TVirtualMutex.h"
57#include "TError.h"
58#include "TEnv.h"
59#include "TEnum.h"
60#include "TEnumConstant.h"
61#include "THashTable.h"
63#include "RConfigure.h"
64#include "compiledata.h"
65#include "strlcpy.h"
66#include "snprintf.h"
67#include "TClingUtils.h"
70#include "TListOfDataMembers.h"
71#include "TListOfEnums.h"
73#include "TListOfFunctions.h"
75#include "TMemFile.h"
76#include "TProtoClass.h"
77#include "TStreamerInfo.h" // This is here to avoid to use the plugin manager
78#include "ThreadLocalStorage.h"
79#include "TFile.h"
80#include "TKey.h"
81#include "ClingRAII.h"
82
83#include "clang/AST/ASTContext.h"
84#include "clang/AST/Decl.h"
85#include "clang/AST/DeclarationName.h"
86#include "clang/AST/GlobalDecl.h"
87#include "clang/AST/RecordLayout.h"
88#include "clang/AST/DeclVisitor.h"
89#include "clang/AST/RecursiveASTVisitor.h"
90#include "clang/AST/Type.h"
91#include "clang/Basic/SourceLocation.h"
92#include "clang/Basic/Specifiers.h"
93#include "clang/Basic/TargetInfo.h"
94#include "clang/CodeGen/ModuleBuilder.h"
95#include "clang/Frontend/CompilerInstance.h"
96#include "clang/Frontend/FrontendDiagnostic.h"
97#include "clang/Lex/HeaderSearch.h"
98#include "clang/Lex/Preprocessor.h"
99#include "clang/Lex/PreprocessorOptions.h"
100#include "clang/Parse/Parser.h"
101#include "clang/Sema/Lookup.h"
102#include "clang/Sema/Sema.h"
103#include "clang/Serialization/ASTReader.h"
104#include "clang/Serialization/GlobalModuleIndex.h"
105
106#include "cling/Interpreter/ClangInternalState.h"
107#include "cling/Interpreter/DynamicLibraryManager.h"
108#include "cling/Interpreter/Interpreter.h"
109#include "cling/Interpreter/LookupHelper.h"
110#include "cling/Interpreter/Value.h"
111#include "cling/Interpreter/Transaction.h"
112#include "cling/MetaProcessor/MetaProcessor.h"
113#include "cling/Utils/AST.h"
114#include "cling/Utils/ParserStateRAII.h"
115#include "cling/Utils/SourceNormalization.h"
116#include "cling/Interpreter/Exception.h"
117
118#include <CppInterOp/CppInterOp.h>
119
120#include "llvm/IR/GlobalValue.h"
121#include "llvm/IR/Module.h"
122
123#include "llvm/Support/DynamicLibrary.h"
124#include "llvm/Support/raw_ostream.h"
125#include "llvm/Support/Path.h"
126#include "llvm/Support/Process.h"
127#include "llvm/Object/ELFObjectFile.h"
128#include "llvm/Object/ObjectFile.h"
129#include "llvm/Object/SymbolicFile.h"
130#include "llvm/Support/FileSystem.h"
131
132#include <algorithm>
133#include <iostream>
134#include <cassert>
135#include <map>
136#include <set>
137#include <stdexcept>
138#include <cstdint>
139#include <fstream>
140#include <sstream>
141#include <string>
142#include <tuple>
143#include <typeinfo>
144#include <unordered_map>
145#include <unordered_set>
146#include <utility>
147#include <vector>
148#include <functional>
149#include <optional>
150
151#ifndef R__WIN32
152#include <cxxabi.h>
153#define R__DLLEXPORT __attribute__ ((visibility ("default")))
154#include <sys/stat.h>
155#endif
156#include <climits>
157#include <cstdio>
158
159#ifdef __APPLE__
160#include <dlfcn.h>
161#include <mach-o/dyld.h>
162#include <mach-o/loader.h>
163#endif // __APPLE__
164
165#ifdef R__UNIX
166#include <dlfcn.h>
167#endif
168
169#if defined(R__LINUX) || defined(R__FBSD)
170# ifndef _GNU_SOURCE
171# define _GNU_SOURCE
172# endif
173# include <link.h> // dl_iterate_phdr()
174#endif
175
176#if defined(__CYGWIN__)
177#include <sys/cygwin.h>
178#define HMODULE void *
179extern "C" {
180 __declspec(dllimport) void * __stdcall GetCurrentProcess();
181 __declspec(dllimport) bool __stdcall EnumProcessModules(void *, void **, unsigned long, unsigned long *);
182 __declspec(dllimport) unsigned long __stdcall GetModuleFileNameExW(void *, void *, wchar_t *, unsigned long);
183}
184#endif
185
186// Fragment copied from LLVM's raw_ostream.cpp
187#if defined(_MSC_VER)
188#ifndef STDIN_FILENO
189# define STDIN_FILENO 0
190#endif
191#ifndef STDOUT_FILENO
192# define STDOUT_FILENO 1
193#endif
194#ifndef STDERR_FILENO
195# define STDERR_FILENO 2
196#endif
197#ifndef R__WIN32
198//#if defined(HAVE_UNISTD_H)
199# include <unistd.h>
200//#endif
201#else
202#include "Windows4Root.h"
203#include <Psapi.h>
204#include <direct.h>
205#undef GetModuleFileName
206#define RTLD_DEFAULT ((void *)::GetModuleHandle(NULL))
207#define dlsym(library, function_name) ::GetProcAddress((HMODULE)library, function_name)
208#define dlopen(library_name, flags) ::LoadLibraryA(library_name)
209#define dlclose(library) ::FreeLibrary((HMODULE)library)
210#define R__DLLEXPORT __declspec(dllexport)
211#endif
212#endif
213
214//______________________________________________________________________________
215// These functions are helpers for debugging issues with non-LLVMDEV builds.
216//
217R__DLLEXPORT clang::DeclContext* TCling__DEBUG__getDeclContext(clang::Decl* D) {
218 return D->getDeclContext();
219}
220R__DLLEXPORT clang::NamespaceDecl* TCling__DEBUG__DCtoNamespace(clang::DeclContext* DC) {
221 return llvm::dyn_cast<clang::NamespaceDecl>(DC);
222}
223R__DLLEXPORT clang::RecordDecl* TCling__DEBUG__DCtoRecordDecl(clang::DeclContext* DC) {
224 return llvm::dyn_cast<clang::RecordDecl>(DC);
225}
226R__DLLEXPORT void TCling__DEBUG__dump(clang::DeclContext* DC) {
227 return DC->dumpDeclContext();
228}
229R__DLLEXPORT void TCling__DEBUG__dump(clang::Decl* D) {
230 return D->dump();
231}
232R__DLLEXPORT void TCling__DEBUG__dump(clang::FunctionDecl* FD) {
233 return FD->dump();
234}
236 return ((clang::Decl*)D)->dump();
237}
239 if (clang::NamedDecl* ND = llvm::dyn_cast<clang::NamedDecl>(D)) {
240 std::string name;
241 {
242 llvm::raw_string_ostream OS(name);
243 ND->getNameForDiagnostic(OS, D->getASTContext().getPrintingPolicy(),
244 true /*Qualified*/);
245 }
246 printf("%s\n", name.c_str());
247 }
248}
249//______________________________________________________________________________
250// These functions are helpers for testing issues directly rather than
251// relying on side effects.
252// This is used for the test for ROOT-7462/ROOT-6070
254 return D->isInvalidDecl();
255}
256R__DLLEXPORT bool TCling__TEST_isInvalidDecl(ClassInfo_t *input) {
257 TClingClassInfo *info( (TClingClassInfo*) input);
258 assert(info && info->IsValid());
259 return info->GetDecl()->isInvalidDecl();
260}
261
262using std::string, std::vector;
263using namespace clang;
264using namespace ROOT;
265
266namespace {
267 static const std::string gInterpreterClassDef = R"ICF(
268#undef ClassDef
269#define ClassDef(name, id) \
270_ClassDefInterp_(name,id,virtual,) \
271static int DeclFileLine() { return __LINE__; }
272#undef ClassDefNV
273#define ClassDefNV(name, id) \
274_ClassDefInterp_(name,id,,) \
275static int DeclFileLine() { return __LINE__; }
276#undef ClassDefOverride
277#define ClassDefOverride(name, id) \
278_ClassDefInterp_(name,id,,override) \
279static int DeclFileLine() { return __LINE__; }
280)ICF";
281
282 static const std::string gNonInterpreterClassDef = R"ICF(
283#define __ROOTCLING__ 1
284#undef ClassDef
285#define ClassDef(name,id) \
286_ClassDefOutline_(name,id,virtual,) \
287static int DeclFileLine() { return __LINE__; }
288#undef ClassDefNV
289#define ClassDefNV(name, id)\
290_ClassDefOutline_(name,id,,)\
291static int DeclFileLine() { return __LINE__; }
292#undef ClassDefOverride
293#define ClassDefOverride(name, id)\
294_ClassDefOutline_(name,id,,override)\
295static int DeclFileLine() { return __LINE__; }
296)ICF";
297
298// The macros below use ::Error, so let's ensure it is included
299 static const std::string gClassDefInterpMacro = R"ICF(
300#include "TError.h"
301
302#define _ClassDefInterp_(name,id,virtual_keyword, overrd) \
303private: \
304public: \
305 static TClass *Class() { static TClass* sIsA = 0; if (!sIsA) sIsA = TClass::GetClass(#name); return sIsA; } \
306 static const char *Class_Name() { return #name; } \
307 virtual_keyword Bool_t CheckTObjectHashConsistency() const overrd { \
308 static std::atomic<UChar_t> recurseBlocker(0); \
309 if (R__likely(recurseBlocker >= 2)) { \
310 return ::ROOT::Internal::THashConsistencyHolder<decltype(*this)>::fgHashConsistency; \
311 } else if (recurseBlocker == 1) { \
312 return false; \
313 } else if (recurseBlocker++ == 0) { \
314 ::ROOT::Internal::THashConsistencyHolder<decltype(*this)>::fgHashConsistency = \
315 ::ROOT::Internal::HasConsistentHashMember(_QUOTE_(name)) || \
316 ::ROOT::Internal::HasConsistentHashMember(*IsA()); \
317 ++recurseBlocker; \
318 return ::ROOT::Internal::THashConsistencyHolder<decltype(*this)>::fgHashConsistency; \
319 } \
320 return false; /* unreachable */ \
321 } \
322 static Version_t Class_Version() { return id; } \
323 static TClass *Dictionary() { return 0; } \
324 virtual_keyword TClass *IsA() const overrd { return name::Class(); } \
325 virtual_keyword void ShowMembers(TMemberInspector&insp) const overrd { ::ROOT::Class_ShowMembers(name::Class(), this, insp); } \
326 virtual_keyword void Streamer(TBuffer&) overrd { ::Error("Streamer", "Cannot stream interpreted class."); } \
327 void StreamerNVirtual(TBuffer&ClassDef_StreamerNVirtual_b) { name::Streamer(ClassDef_StreamerNVirtual_b); } \
328 static const char *DeclFileName() { return __FILE__; } \
329 static int ImplFileLine() { return 0; } \
330 static const char *ImplFileName() { return __FILE__; }
331)ICF";
332}
334
335// The functions are used to bridge cling/clang/llvm compiled with no-rtti and
336// ROOT (which uses rtti)
337
338////////////////////////////////////////////////////////////////////////////////
339/// Print a StackTrace!
340
341extern "C"
343 gSystem->StackTrace();
344}
345
346////////////////////////////////////////////////////////////////////////////////
347/// Load a library.
348
349extern "C" int TCling__LoadLibrary(const char *library)
350{
351 gCling->RegisterAutoLoadedLibrary(library);
352 return gSystem->Load(library, "", false);
353}
354
355////////////////////////////////////////////////////////////////////////////////
356/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
357
358extern "C" void TCling__RestoreInterpreterMutex(void *delta)
359{
360 ((TCling*)gCling)->ApplyToInterpreterMutex(delta);
361}
362
363////////////////////////////////////////////////////////////////////////////////
364/// Lookup libraries in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH with mangled_name,
365/// which is extracted by error messages we get from callback from cling. Return true
366/// when the missing library was autoloaded.
367
368extern "C" bool TCling__LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
369{
370 return ((TCling*)gCling)->LibraryLoadingFailed(errmessage, libStem, permanent, resolved);
371}
372
373////////////////////////////////////////////////////////////////////////////////
374/// Reset the interpreter lock to the state it had before interpreter-related
375/// calls happened.
376
378{
379 return ((TCling*)gCling)->RewindInterpreterMutex();
380}
381
382////////////////////////////////////////////////////////////////////////////////
383/// Lock the interpreter.
384
386{
387 if (gInterpreterMutex) {
388 gInterpreterMutex->Lock();
389 }
390 return nullptr;
391}
392
393////////////////////////////////////////////////////////////////////////////////
394/// Unlock the interpreter.
395
397{
398 if (gInterpreterMutex) {
399 gInterpreterMutex->UnLock();
400 }
401}
402
403////////////////////////////////////////////////////////////////////////////////
404/// Update TClingClassInfo for a class (e.g. upon seeing a definition).
405
406static void TCling__UpdateClassInfo(const NamedDecl* TD)
407{
408 static Bool_t entered = kFALSE;
409 static vector<const NamedDecl*> updateList;
410 Bool_t topLevel;
411
412 if (entered) topLevel = kFALSE;
413 else {
414 entered = kTRUE;
415 topLevel = kTRUE;
416 }
417 if (topLevel) {
418 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(TD);
419 } else {
420 // If we are called indirectly from within another call to
421 // TCling::UpdateClassInfo, we delay the update until the dictionary loading
422 // is finished (i.e. when we return to the top level TCling::UpdateClassInfo).
423 // This allows for the dictionary to be fully populated when we actually
424 // update the TClass object. The updating of the TClass sometimes
425 // (STL containers and when there is an emulated class) forces the building
426 // of the TClass object's real data (which needs the dictionary info).
427 updateList.push_back(TD);
428 }
429 if (topLevel) {
430 while (!updateList.empty()) {
431 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(updateList.back());
432 updateList.pop_back();
433 }
434 entered = kFALSE;
435 }
436}
437
438void TCling::UpdateEnumConstants(TEnum* enumObj, TClass* cl) const {
439 const clang::Decl* D = static_cast<const clang::Decl*>(enumObj->GetDeclId());
440 if(const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(D)) {
441 // Add the constants to the enum type.
442 for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin(),
443 EDE = ED->enumerator_end(); EDI != EDE; ++EDI) {
444 // Get name of the enum type.
445 std::string constbuf;
446 if (const NamedDecl* END = llvm::dyn_cast<NamedDecl>(*EDI)) {
447 PrintingPolicy Policy((*EDI)->getASTContext().getPrintingPolicy());
448 llvm::raw_string_ostream stream(constbuf);
449 // Don't trigger fopen of the source file to count lines:
450 Policy.AnonymousTagLocations = false;
451 (END)->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
452 }
453 const char* constantName = constbuf.c_str();
454
455 // Get value of the constant.
456 Long64_t value;
457 const llvm::APSInt valAPSInt = (*EDI)->getInitVal();
458 if (valAPSInt.isSigned()) {
459 value = valAPSInt.getSExtValue();
460 } else {
461 value = valAPSInt.getZExtValue();
462 }
463
464 // Create the TEnumConstant or update it if existing
465 TEnumConstant* enumConstant = nullptr;
466 TClingClassInfo* tcCInfo = (TClingClassInfo*)(cl ? cl->GetClassInfo() : nullptr);
467 TClingDataMemberInfo* tcDmInfo = new TClingDataMemberInfo(GetInterpreterImpl(), *EDI, tcCInfo);
468 DataMemberInfo_t* dmInfo = (DataMemberInfo_t*) tcDmInfo;
469 if (TObject* encAsTObj = enumObj->GetConstants()->FindObject(constantName)){
470 ((TEnumConstant*)encAsTObj)->Update(dmInfo);
471 } else {
472 enumConstant = new TEnumConstant(dmInfo, constantName, value, enumObj);
473 }
474
475 // Add the global constants to the list of Globals.
476 if (!cl) {
477 TCollection* globals = gROOT->GetListOfGlobals(false);
478 if (!globals->FindObject(constantName)) {
479 globals->Add(enumConstant);
480 }
481 }
482 }
483 }
484}
485
486TEnum* TCling::CreateEnum(void *VD, TClass *cl) const
487{
488 // Handle new enum declaration for either global and nested enums.
489
490 // Create the enum type.
491 TEnum* enumType = nullptr;
492 const clang::Decl* D = static_cast<const clang::Decl*>(VD);
493 std::string buf;
494 if (const EnumDecl* ED = llvm::dyn_cast<EnumDecl>(D)) {
495 // Get name of the enum type.
496 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
497 llvm::raw_string_ostream stream(buf);
498 // Don't trigger fopen of the source file to count lines:
499 Policy.AnonymousTagLocations = false;
500 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
501 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
502 }
503 if (buf.empty()) {
504 return nullptr;
505 }
506 const char* name = buf.c_str();
507 enumType = new TEnum(name, VD, cl);
508 UpdateEnumConstants(enumType, cl);
509
510 return enumType;
511}
512
513void TCling::HandleNewDecl(const void* DV, bool isDeserialized, std::set<TClass*> &modifiedTClasses) {
514 // Handle new declaration.
515 // Record the modified class, struct and namespaces in 'modifiedTClasses'.
516
517 const clang::Decl* D = static_cast<const clang::Decl*>(DV);
518
519 if (!D->isCanonicalDecl() && !isa<clang::NamespaceDecl>(D)
520 && !dyn_cast<clang::RecordDecl>(D)) return;
521
522 if (isa<clang::FunctionDecl>(D->getDeclContext())
523 || isa<clang::TagDecl>(D->getDeclContext()))
524 return;
525
526 // Don't list templates.
527 if (const clang::CXXRecordDecl* RD = dyn_cast<clang::CXXRecordDecl>(D)) {
528 if (RD->getDescribedClassTemplate())
529 return;
530 } else if (const clang::FunctionDecl* FD = dyn_cast<clang::FunctionDecl>(D)) {
531 if (FD->getDescribedFunctionTemplate())
532 return;
533 }
534
535 if (const RecordDecl *TD = dyn_cast<RecordDecl>(D)) {
536 if (TD->isCanonicalDecl() || TD->isThisDeclarationADefinition())
538 }
539 else if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
540
541 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
542 // Mostly just for EnumDecl (the other TagDecl are handled
543 // by the 'RecordDecl' if statement.
545 } else if (const NamespaceDecl* NSD = dyn_cast<NamespaceDecl>(D)) {
547 }
548
549 // We care about declarations on the global scope.
550 if (!isa<TranslationUnitDecl>(ND->getDeclContext()))
551 return;
552
553 // Enums are lazyly created, thus we don not need to handle them here.
554 if (isa<EnumDecl>(ND))
555 return;
556
557 // ROOT says that global is enum(lazylycreated)/var/field declared on the global
558 // scope.
559 if (!(isa<VarDecl>(ND)))
560 return;
561
562 // Skip if already in the list.
563 if (gROOT->GetListOfGlobals()->FindObject(ND->getNameAsString().c_str()))
564 return;
565
566 // Put the global constants and global enums in the corresponding lists.
567 gROOT->GetListOfGlobals()->Add(new TGlobal((DataMemberInfo_t *)
569 cast<ValueDecl>(ND), nullptr)));
570 }
571}
572
573extern "C"
575{
576 // We are sure in this context of the type of the interpreter
577 normCtxt = &( (TCling*) gInterpreter)->GetNormalizedContext();
578}
579
580extern "C"
581void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter*) {
582 ((TCling*)gCling)->UpdateListsOnCommitted(T);
583}
584
585extern "C"
586void TCling__UpdateListsOnUnloaded(const cling::Transaction &T) {
587 ((TCling*)gCling)->UpdateListsOnUnloaded(T);
588}
589
590extern "C"
591void TCling__InvalidateGlobal(const clang::Decl *D) {
592 ((TCling*)gCling)->InvalidateGlobal(D);
593}
594
595extern "C"
596void TCling__TransactionRollback(const cling::Transaction &T) {
597 ((TCling*)gCling)->TransactionRollback(T);
598}
599
600extern "C" void TCling__LibraryLoadedRTTI(const void* dyLibHandle,
601 const char* canonicalName) {
602 ((TCling*)gCling)->LibraryLoaded(dyLibHandle, canonicalName);
603}
604
605extern "C" void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
606{
607 ((TCling *)gCling)->RegisterRdictForLoadPCM(pcmFileNameFullPath, pcmContent);
608}
609
610extern "C" void TCling__LibraryUnloadedRTTI(const void* dyLibHandle,
611 const char* canonicalName) {
612 ((TCling*)gCling)->LibraryUnloaded(dyLibHandle, canonicalName);
613}
614
615
616extern "C"
617TObject* TCling__GetObjectAddress(const char *Name, void *&LookupCtx) {
618 return ((TCling*)gCling)->GetObjectAddress(Name, LookupCtx);
619}
620
621extern "C" const Decl* TCling__GetObjectDecl(TObject *obj) {
622 return ((TClingClassInfo*)obj->IsA()->GetClassInfo())->GetDecl();
623}
624
625extern "C" R__DLLEXPORT TInterpreter *CreateInterpreter(void* interpLibHandle,
626 const char* argv[])
627{
628 auto tcling = new TCling("C++", "cling C++ Interpreter", argv, interpLibHandle);
629
630 return tcling;
631}
632
634{
635 delete interp;
636}
637
638// Load library containing specified class. Returns 0 in case of error
639// and 1 in case if success.
640extern "C" int TCling__AutoLoadCallback(const char* className)
641{
642 return ((TCling*)gCling)->AutoLoad(className);
643}
644
645extern "C" int TCling__AutoParseCallback(const char* className)
646{
647 return ((TCling*)gCling)->AutoParse(className);
648}
649
650extern "C" const char* TCling__GetClassSharedLibs(const char* className, bool skipCore)
651{
652 return ((TCling*)gCling)->GetClassSharedLibs(className, skipCore);
654
655// Returns 0 for failure 1 for success
656extern "C" int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
657{
658 return ((TCling*)gCling)->IsAutoLoadNamespaceCandidate(nsDecl);
659}
660
661extern "C" int TCling__CompileMacro(const char *fileName, const char *options)
662{
663 string file(fileName);
664 string opt(options);
665 return gSystem->CompileMacro(file.c_str(), opt.c_str());
666}
667
668extern "C" void TCling__SplitAclicMode(const char* fileName, string &mode,
669 string &args, string &io, string &fname)
670{
671 string file(fileName);
672 TString f, amode, arguments, aclicio;
673 f = gSystem->SplitAclicMode(file.c_str(), amode, arguments, aclicio);
674 mode = amode.Data(); args = arguments.Data();
675 io = aclicio.Data(); fname = f.Data();
676}
677
678//______________________________________________________________________________
679//
680//
681//
682
683#ifdef R__WIN32
684extern "C" {
685 char *__unDName(char *demangled, const char *mangled, int out_len,
686 void * (* pAlloc )(size_t), void (* pFree )(void *),
687 unsigned short int flags);
688}
689#endif
690
691////////////////////////////////////////////////////////////////////////////////
692/// Find a template decl within N nested namespaces, 0<=N<inf
693/// Assumes 1 and only 1 template present and 1 and only 1 entity contained
694/// by the namespace. Example: `ns1::ns2::..::%nsN::%myTemplate`
695/// Returns nullptr in case of error
696
697static clang::ClassTemplateDecl* FindTemplateInNamespace(clang::Decl* decl)
698{
699 using namespace clang;
700 if (NamespaceDecl* nsd = llvm::dyn_cast<NamespaceDecl>(decl)){
701 return FindTemplateInNamespace(*nsd->decls_begin());
702 }
703
704 if (ClassTemplateDecl* ctd = llvm::dyn_cast<ClassTemplateDecl>(decl)){
705 return ctd;
706 }
707
708 return nullptr; // something went wrong.
709}
710
711//______________________________________________________________________________
712//
713//
714//
715
716int TCling_GenerateDictionary(const std::vector<std::string> &classes,
717 const std::vector<std::string> &headers,
718 const std::vector<std::string> &fwdDecls,
719 const std::vector<std::string> &unknown)
720{
721 //This function automatically creates the "LinkDef.h" file for templated
722 //classes then executes CompileMacro on it.
723 //The name of the file depends on the class name, and it's not generated again
724 //if the file exist.
725 if (classes.empty()) {
726 return 0;
727 }
728 // Use the name of the first class as the main name.
729 const std::string& className = classes[0];
730 //(0) prepare file name
731 TString fileName = "AutoDict_";
732 std::string::const_iterator sIt;
733 for (sIt = className.begin(); sIt != className.end(); ++sIt) {
734 if (*sIt == '<' || *sIt == '>' ||
735 *sIt == ' ' || *sIt == '*' ||
736 *sIt == ',' || *sIt == '&' ||
737 *sIt == ':') {
738 fileName += '_';
739 }
740 else {
741 fileName += *sIt;
742 }
743 }
744 if (classes.size() > 1) {
745 Int_t chk = 0;
746 std::vector<std::string>::const_iterator it = classes.begin();
747 while ((++it) != classes.end()) {
748 for (UInt_t cursor = 0; cursor != it->length(); ++cursor) {
749 chk = chk * 3 + it->at(cursor);
750 }
751 }
752 fileName += TString::Format("_%u", chk);
753 }
754 fileName += ".cxx";
755 if (gSystem->AccessPathName(fileName) != 0) {
756 //file does not exist
757 //(1) prepare file data
758 // If STL, also request iterators' operators.
759 // vector is special: we need to check whether
760 // vector::iterator is a typedef to pointer or a
761 // class.
762 static const std::set<std::string> sSTLTypes {
763 "vector","list","forward_list","deque","map","unordered_map","multimap",
764 "unordered_multimap","set","unordered_set","multiset","unordered_multiset",
765 "queue","priority_queue","stack","iterator"};
766 std::vector<std::string>::const_iterator it;
767 std::string fileContent("");
768 for (it = headers.begin(); it != headers.end(); ++it) {
769 fileContent += "#include \"" + *it + "\"\n";
770 }
771 for (it = unknown.begin(); it != unknown.end(); ++it) {
772 TClass* cl = TClass::GetClass(it->c_str());
773 if (cl && cl->GetDeclFileName()) {
774 TString header = gSystem->BaseName(cl->GetDeclFileName());
775 TString dir = gSystem->GetDirName(cl->GetDeclFileName());
776 TString dirbase(gSystem->BaseName(dir));
777 while (dirbase.Length() && dirbase != "."
778 && dirbase != "include" && dirbase != "inc"
779 && dirbase != "prec_stl") {
780 gSystem->PrependPathName(dirbase, header);
781 dir = gSystem->GetDirName(dir);
782 }
783 fileContent += TString("#include \"") + header + "\"\n";
784 }
785 }
786 for (it = fwdDecls.begin(); it != fwdDecls.end(); ++it) {
787 fileContent += "class " + *it + ";\n";
788 }
789 fileContent += "#ifdef __CLING__ \n";
790 fileContent += "#pragma link C++ nestedclasses;\n";
791 fileContent += "#pragma link C++ nestedtypedefs;\n";
792 for (it = classes.begin(); it != classes.end(); ++it) {
793 std::string n(*it);
794 size_t posTemplate = n.find('<');
795 std::set<std::string>::const_iterator iSTLType = sSTLTypes.end();
796 if (posTemplate != std::string::npos) {
797 n.erase(posTemplate, std::string::npos);
798 if (n.compare(0, 5, "std::") == 0) {
799 n.erase(0, 5);
800 }
801 iSTLType = sSTLTypes.find(n);
802 }
803 fileContent += "#pragma link C++ class ";
804 fileContent += *it + "+;\n" ;
805 if (iSTLType == sSTLTypes.end()) {
806 // Not an STL class; we need to allow the I/O of contained
807 // classes (now that we have a dictionary for them).
808 fileContent += "#pragma link C++ class " + *it + "::*+;\n" ;
809 }
810 }
811 fileContent += "#endif\n";
812 //end(1)
813 //(2) prepare the file
814 FILE* filePointer;
815 filePointer = fopen(fileName, "w");
816 if (filePointer == nullptr) {
817 //can't open a file
818 return 1;
819 }
820 //end(2)
821 //write data into the file
822 fprintf(filePointer, "%s", fileContent.c_str());
823 fclose(filePointer);
824 }
825 //(3) checking if we can compile a macro, if not then cleaning
826 Int_t oldErrorIgnoreLevel = gErrorIgnoreLevel;
827 gErrorIgnoreLevel = kWarning; // no "Info: creating library..."
828 Int_t ret = gSystem->CompileMacro(fileName, "k");
829 gErrorIgnoreLevel = oldErrorIgnoreLevel;
830 if (ret == 0) { //can't compile a macro
831 return 2;
832 }
833 //end(3)
834 return 0;
835}
836
837int TCling_GenerateDictionary(const std::string& className,
838 const std::vector<std::string> &headers,
839 const std::vector<std::string> &fwdDecls,
840 const std::vector<std::string> &unknown)
841{
842 //This function automatically creates the "LinkDef.h" file for templated
843 //classes then executes CompileMacro on it.
844 //The name of the file depends on the class name, and it's not generated again
845 //if the file exist.
846 std::vector<std::string> classes;
847 classes.push_back(className);
848 return TCling_GenerateDictionary(classes, headers, fwdDecls, unknown);
849}
850
851//______________________________________________________________________________
852//
853//
854//
855
856// It is a "fantom" method to synchronize user keyboard input
857// and ROOT prompt line (for WIN32)
858const char* fantomline = "TRint::EndOfLineAction();";
859
860//______________________________________________________________________________
861//
862//
863//
864
865void* TCling::fgSetOfSpecials = nullptr;
866
867//______________________________________________________________________________
868//
869// llvm error handler through exceptions; see also cling/UserInterface
870//
871namespace {
872 // Handle fatal llvm errors by throwing an exception.
873 // Yes, throwing exceptions in error handlers is bad.
874 // Doing nothing is pretty terrible, too.
875 void exceptionErrorHandler(void * /*user_data*/,
876 const char *reason,
877 bool /*gen_crash_diag*/) {
878 throw std::runtime_error(std::string(">>> Interpreter compilation error:\n") + reason);
879 }
880}
881
882//______________________________________________________________________________
883//
884//
885//
886
887////////////////////////////////////////////////////////////////////////////////
888
889namespace{
890 // An instance of this class causes the diagnostics of clang to be suppressed
891 // during its lifetime
892 class clangDiagSuppr {
893 public:
894 clangDiagSuppr(clang::DiagnosticsEngine& diag): fDiagEngine(diag){
895 fOldDiagValue = fDiagEngine.getIgnoreAllWarnings();
896 fDiagEngine.setIgnoreAllWarnings(true);
897 }
898
899 ~clangDiagSuppr() {
900 fDiagEngine.setIgnoreAllWarnings(fOldDiagValue);
901 }
902 private:
903 clang::DiagnosticsEngine& fDiagEngine;
904 bool fOldDiagValue;
905 };
906
907}
908
909////////////////////////////////////////////////////////////////////////////////
910/// Allow calling autoparsing from TMetaUtils
911bool TClingLookupHelper__AutoParse(const char *cname)
912{
913 return gCling->AutoParse(cname);
914}
915
916////////////////////////////////////////////////////////////////////////////////
917/// Try hard to avoid looking up in the Cling database as this could enduce
918/// an unwanted autoparsing.
919
920bool TClingLookupHelper__ExistingTypeCheck(const std::string &tname,
921 std::string &result)
922{
923 result.clear();
924
925 unsigned long offset = 0;
926 if (strncmp(tname.c_str(), "const ", 6) == 0) {
927 offset = 6;
928 }
929 unsigned long end = tname.length();
930 while( end && (tname[end-1]=='&' || tname[end-1]=='*' || tname[end-1]==']') ) {
931 if ( tname[end-1]==']' ) {
932 --end;
933 while ( end && tname[end-1]!='[' ) --end;
934 }
935 --end;
936 }
937 std::string innerbuf;
938 const char *inner;
939 if (end != tname.length()) {
940 innerbuf = tname.substr(offset,end-offset);
941 inner = innerbuf.c_str();
942 } else {
943 inner = tname.c_str()+offset;
944 }
945
946 //if (strchr(tname.c_str(),'[')!=0) fprintf(stderr,"DEBUG: checking on %s vs %s %lu %lu\n",tname.c_str(),inner,offset,end);
947 if (gROOT->GetListOfClasses()->FindObject(inner)
948 || TClassTable::Check(inner,result) ) {
949 // This is a known class.
950 return true;
951 }
952
953 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
954 TDataType *type = (TDataType *)typeTable->THashTable::FindObject( inner );
955 if (type) {
956 // This is a raw type and an already loaded typedef.
957 const char *newname = type->GetFullTypeName();
958 if (type->GetType() == kLong64_t) {
959 newname = "Long64_t";
960 } else if (type->GetType() == kULong64_t) {
961 newname = "ULong64_t";
962 }
963 if (strcmp(inner,newname) == 0) {
964 return true;
965 }
966 if (offset) result = "const ";
967 result += newname;
968 if ( end != tname.length() ) {
969 result += tname.substr(end,tname.length()-end);
970 }
971 if (result == tname) result.clear();
972 return true;
973 }
974
975 // Check if the name is an enumerator
976 const auto lastPos = TClassEdit::GetUnqualifiedName(inner);
977 if (lastPos != inner) // Main switch: case 1 - scoped enum, case 2 global enum
978 {
979 // We have a scope
980 const auto enName = lastPos;
981 const auto scopeNameSize = (lastPos - inner) / sizeof(decltype(*lastPos)) - 2;
982 std::string scopeName{inner, scopeNameSize};
983 // Check if the scope is in the list of classes
984 if (auto scope = static_cast<TClass *>(gROOT->GetListOfClasses()->FindObject(scopeName.c_str()))) {
985 auto enumTable = dynamic_cast<const THashList *>(scope->GetListOfEnums(false));
986 if (enumTable && enumTable->THashList::FindObject(enName))
987 return true;
988 }
989 // It may still be in one of the loaded protoclasses
990 else if (auto scope = static_cast<TProtoClass *>(gClassTable->GetProtoNorm(scopeName.c_str()))) {
991 auto listOfEnums = scope->GetListOfEnums();
992 if (listOfEnums) { // it could be null: no enumerators in the protoclass
993 auto enumTable = dynamic_cast<const THashList *>(listOfEnums);
994 if (enumTable && enumTable->THashList::FindObject(enName))
995 return true;
996 }
997 }
998 } else
999 {
1000 // We don't have any scope: this could only be a global enum
1001 auto enumTable = dynamic_cast<const THashList *>(gROOT->GetListOfEnums());
1002 if (enumTable && enumTable->THashList::FindObject(inner)) return true;
1003 }
1004
1005 if (gCling->GetClassSharedLibs(inner))
1006 {
1007 // This is a class name.
1008 return true;
1009 }
1010
1011 return false;
1012}
1013
1014////////////////////////////////////////////////////////////////////////////////
1015/// Check if the class name is present in TClassTable.
1016///
1017/// \param[in] tname class name to check.
1018/// \param[out] result If a class name has an alternative name registered in
1019/// TClassTable, it will be copied into this string.
1020bool TClingLookupHelper__CheckInClassTable(const std::string &tname, std::string &result)
1021{
1022 result.clear();
1023
1024 if (gROOT->GetListOfClasses()->FindObject(tname.c_str()) || TClassTable::Check(tname.c_str(), result)) {
1025 // This is a known class.
1026 return true;
1027 }
1028
1029 return false;
1030}
1031
1032////////////////////////////////////////////////////////////////////////////////
1033
1038
1039////////////////////////////////////////////////////////////////////////////////
1040
1042{
1043 return fContent.c_str();
1044}
1045
1046////////////////////////////////////////////////////////////////////////////////
1047/// Append string to the storage if not added already.
1048
1049inline bool TCling::TUniqueString::Append(const std::string& str)
1050{
1051 bool notPresent = fLinesHashSet.emplace(fHashFunc(str)).second;
1052 if (notPresent){
1053 fContent+=str;
1054 }
1055 return notPresent;
1056}
1057
1058std::string TCling::ToString(const char* type, void* obj)
1059{
1060 return fInterpreter->toString(type, obj);
1061}
1062
1063////////////////////////////////////////////////////////////////////////////////
1064///\returns true if the module was loaded.
1065static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
1066{
1067 // When starting up ROOT, cling would load all modulemap files on the include
1068 // paths. However, in a ROOT session, it is very common to run aclic which
1069 // will invoke rootcling and possibly produce a modulemap and a module in
1070 // the current folder.
1071 //
1072 // Before failing, try loading the modulemap in the current folder and try
1073 // loading the requested module from it.
1074 std::string currentDir = gSystem->WorkingDirectory();
1075 assert(!currentDir.empty());
1076 gCling->RegisterPrebuiltModulePath(currentDir);
1077 if (gDebug > 2)
1078 ::Info("TCling::__LoadModule", "Preloading module %s. \n",
1079 ModuleName.c_str());
1080
1081 return interp.loadModule(ModuleName, /*Complain=*/true);
1082}
1083
1084////////////////////////////////////////////////////////////////////////////////
1085/// Loads the C++ modules that we require to run any ROOT program. This is just
1086/// supposed to make a C++ module from a modulemap available to the interpreter.
1087static void LoadModules(const std::vector<std::string> &modules, cling::Interpreter &interp)
1088{
1089 for (const auto &modName : modules)
1090 LoadModule(modName, interp);
1091}
1092
1093static bool IsFromRootCling() {
1094 // rootcling also uses TCling for generating the dictionary ROOT files.
1095 const static bool foundSymbol = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
1096 return foundSymbol;
1097}
1098
1099/// Checks if there is an ASTFile on disk for the given module \c M.
1100static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName = nullptr)
1101{
1102 const HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
1103
1104 std::string ModuleFileName;
1105 if (!HSOpts.PrebuiltModulePaths.empty())
1106 // Load the module from *only* in the prebuilt module path.
1107 ModuleFileName = PP.getHeaderSearchInfo().getPrebuiltModuleFileName(M->Name);
1108 if (FullFileName)
1109 *FullFileName = ModuleFileName;
1110
1111 return !ModuleFileName.empty();
1112}
1113
1114static bool HaveFullGlobalModuleIndex = false;
1115static GlobalModuleIndex *loadGlobalModuleIndex(cling::Interpreter &interp)
1116{
1117 CompilerInstance &CI = *interp.getCI();
1118 Preprocessor &PP = CI.getPreprocessor();
1119 auto ModuleManager = CI.getASTReader();
1120 assert(ModuleManager);
1121 // StringRef ModuleIndexPath = HSI.getModuleCachePath();
1122 // HeaderSearch& HSI = PP.getHeaderSearchInfo();
1123 // HSI.setModuleCachePath(TROOT::GetSharedLibDir().Data());
1124 std::string ModuleIndexPath = TROOT::GetSharedLibDir().Data();
1125 if (ModuleIndexPath.empty())
1126 return nullptr;
1127 // Get an existing global index. This loads it if not already loaded.
1128 ModuleManager->resetForReload();
1129 ModuleManager->loadGlobalIndex();
1130 GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex();
1131
1132 // For finding modules needing to be imported for fixit messages,
1133 // we need to make the global index cover all modules, so we do that here.
1134 if (!GlobalIndex && !HaveFullGlobalModuleIndex) {
1135 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1136 bool RecreateIndex = false;
1137 for (ModuleMap::module_iterator I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1138 Module *TheModule = I->second;
1139 // We want the index only of the prebuilt modules.
1140 if (!HasASTFileOnDisk(TheModule, PP))
1141 continue;
1142 LoadModule(TheModule->Name, interp);
1143 RecreateIndex = true;
1144 }
1145 if (RecreateIndex) {
1146 cling::Interpreter::PushTransactionRAII deserRAII(&interp);
1147 clang::GlobalModuleIndex::UserDefinedInterestingIDs IDs;
1148
1149 struct DefinitionFinder : public RecursiveASTVisitor<DefinitionFinder> {
1150 DefinitionFinder(clang::GlobalModuleIndex::UserDefinedInterestingIDs& IDs,
1151 clang::TranslationUnitDecl* TU) : DefinitionIDs(IDs) {
1152 TraverseDecl(TU);
1153 }
1154 bool VisitNamedDecl(NamedDecl *ND) {
1155 if (!ND->isFromASTFile())
1156 return true;
1157 if (!ND->getIdentifier())
1158 return true;
1159
1160 if (ND->getAccess() == AS_protected || ND->getAccess() == AS_private)
1161 return true;
1162
1163 if (TagDecl *TD = llvm::dyn_cast<TagDecl>(ND)) {
1164 if (TD->isCompleteDefinition())
1165 Register(TD);
1166 } else if (NamespaceDecl *NSD = llvm::dyn_cast<NamespaceDecl>(ND)) {
1167 Register(NSD, /*AddSingleEntry=*/ false);
1168 }
1169 else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(ND))
1170 Register(TND);
1171 // FIXME: Add the rest...
1172 return true; // continue decending
1173 }
1174 private:
1175 clang::GlobalModuleIndex::UserDefinedInterestingIDs &DefinitionIDs;
1176 void Register(const NamedDecl* ND, bool AddSingleEntry = true) {
1177 assert(ND->isFromASTFile());
1178 // FIXME: All decls should have an owning module once rootcling
1179 // updates its generated decls from within the LookupHelper & co.
1180 if (!ND->hasOwningModule()) {
1181#ifndef NDEBUG
1182 SourceManager &SM = ND->getASTContext().getSourceManager();
1183 SourceLocation Loc = ND->getLocation();
1184 OptionalFileEntryRef FE = SM.getFileEntryRefForID(SM.getFileID(Loc));
1185 (void)FE;
1186 assert(FE->getName().contains("input_line_"));
1187#endif
1188 return;
1189 }
1190
1191 Module *OwningModule = ND->getOwningModule()->getTopLevelModule();
1192 assert(OwningModule);
1193 assert(!ND->getName().empty() && "Empty name");
1194 if (AddSingleEntry && DefinitionIDs.count(ND->getName()))
1195 return;
1196 // FIXME: The FileEntry in not stable to serialize.
1197 // FIXME: We might end up with many times with the same module.
1198 // FIXME: We might end up two modules containing a definition.
1199 // FIXME: What do we do if no definition is found.
1200 DefinitionIDs[ND->getName()].push_back(OwningModule->getASTFile());
1201 }
1202 };
1203 DefinitionFinder defFinder(IDs, CI.getASTContext().getTranslationUnitDecl());
1204
1205 llvm::cantFail(GlobalModuleIndex::writeIndex(CI.getFileManager(),
1206 CI.getPCHContainerReader(),
1207 ModuleIndexPath,
1208 &IDs));
1209 ModuleManager->resetForReload();
1210 ModuleManager->loadGlobalIndex();
1211 GlobalIndex = ModuleManager->getGlobalIndex();
1212 }
1214 }
1215 return GlobalIndex;
1216}
1217
1218static void RegisterCxxModules(cling::Interpreter &clingInterp)
1219{
1220 if (!clingInterp.getCI()->getLangOpts().Modules)
1221 return;
1222
1223 // Loading of a module might deserialize.
1224 cling::Interpreter::PushTransactionRAII deserRAII(&clingInterp);
1225
1226 // Setup core C++ modules if we have any to setup.
1227
1228 // Load libc and stl first.
1229 // Load vcruntime module for windows
1230#ifdef R__WIN32
1231 LoadModule("vcruntime", clingInterp);
1232 LoadModule("services", clingInterp);
1233#endif
1234
1235#ifdef R__MACOSX
1236 LoadModule("Darwin", clingInterp);
1237#else
1238 LoadModule("libc", clingInterp);
1239#endif
1240 LoadModule("std", clingInterp);
1241
1242 LoadModule("_Builtin_intrinsics", clingInterp);
1243
1244 // Load core modules
1245 // This should be vector in order to be able to pass it to LoadModules
1246 std::vector<std::string> CoreModules = {"ROOT_Foundation_C",
1247 "ROOT_Config",
1248 "ROOT_Rtypes",
1249 "ROOT_Foundation_Stage1_NoRTTI",
1250 "Core",
1251 "Rint",
1252 "RIO"};
1253
1254 LoadModules(CoreModules, clingInterp);
1255
1256 // Take this branch only from ROOT because we don't need to preload modules in rootcling
1257 if (!IsFromRootCling()) {
1258 std::vector<std::string> CommonModules = {"MathCore"};
1259 LoadModules(CommonModules, clingInterp);
1260
1261 // These modules should not be preloaded but they fix issues.
1262 // FIXME: Hist is not a core module but is very entangled to MathCore and
1263 // causes issues.
1264 std::vector<std::string> FIXMEModules = {"Hist"};
1265 clang::CompilerInstance &CI = *clingInterp.getCI();
1266 clang::Preprocessor &PP = CI.getPreprocessor();
1267 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1268 if (MMap.findModule("RInterface"))
1269 FIXMEModules.push_back("RInterface");
1270
1271 LoadModules(FIXMEModules, clingInterp);
1272
1273 GlobalModuleIndex *GlobalIndex = nullptr;
1274 loadGlobalModuleIndex(clingInterp);
1275 // FIXME: The ASTReader still calls loadGlobalIndex and loads the file
1276 // We should investigate how to suppress it completely.
1277 GlobalIndex = CI.getASTReader()->getGlobalIndex();
1278
1279 llvm::StringSet<> KnownModuleFileNames;
1280 if (GlobalIndex)
1281 GlobalIndex->getKnownModuleFileNames(KnownModuleFileNames);
1282
1283 std::vector<std::string> PendingModules;
1284 PendingModules.reserve(256);
1285 for (auto I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1286 clang::Module *M = I->second;
1287 assert(M);
1288
1289 // We want to load only already created modules.
1290 std::string FullASTFilePath;
1291 if (!HasASTFileOnDisk(M, PP, &FullASTFilePath))
1292 continue;
1293
1294 if (GlobalIndex && KnownModuleFileNames.count(FullASTFilePath))
1295 continue;
1296
1297 if (M->IsUnimportable)
1298 continue;
1299
1300 if (GlobalIndex)
1301 LoadModule(M->Name, clingInterp);
1302 else {
1303 // FIXME: We may be able to remove those checks as cling::loadModule
1304 // checks if a module was alredy loaded.
1305 if (std::find(CoreModules.begin(), CoreModules.end(), M->Name) != CoreModules.end())
1306 continue; // This is a core module which was already loaded.
1307
1308 // Load system modules now and delay the other modules after we have
1309 // loaded all system ones.
1310 if (M->IsSystem)
1311 LoadModule(M->Name, clingInterp);
1312 else
1313 PendingModules.push_back(M->Name);
1314 }
1315 }
1316 LoadModules(PendingModules, clingInterp);
1317 }
1318
1319 // Check that the gROOT macro was exported by any core module.
1320 assert(clingInterp.getMacro("gROOT") && "Couldn't load gROOT macro?");
1321
1322 // `ERROR` and `PI` are from loading R related modules, which conflict with
1323 // user's code.
1324 clingInterp.declare(R"CODE(
1325#ifdef PI
1326# undef PI
1327#endif
1328#ifdef ERROR
1329# undef ERROR
1330#endif
1331 )CODE");
1332}
1333
1334static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
1335{
1336 std::string PreIncludes;
1337 bool hasCxxModules = clingInterp.getCI()->getLangOpts().Modules;
1338
1339 // For the list to also include string, we have to include it now.
1340 // rootcling does parts already if needed, e.g. genreflex does not want using
1341 // namespace std.
1342 if (IsFromRootCling()) {
1343 PreIncludes += "#include \"RtypesCore.h\"\n";
1344 } else {
1345 if (!hasCxxModules)
1346 PreIncludes += "#include \"Rtypes.h\"\n";
1347
1348 PreIncludes += gClassDefInterpMacro + "\n"
1349 + gInterpreterClassDef + "\n"
1350 "#undef ClassImp\n" // bw compatibility
1351 "#define ClassImp(X);\n"; // bw compatibility
1352 }
1353 if (!hasCxxModules)
1354 PreIncludes += "#include <string>\n";
1355
1356 // We must include it even when we have modules because it is marked as
1357 // textual in the modulemap due to the nature of the assert header.
1358#ifndef R__WIN32
1359 PreIncludes += "#include <cassert>\n";
1360#endif
1361 PreIncludes += "using namespace std;\n";
1362 clingInterp.declare(PreIncludes);
1363}
1364
1365////////////////////////////////////////////////////////////////////////////////
1366/// Initialize the cling interpreter interface.
1367/// \param name name for TInterpreter
1368/// \param title title for TInterpreter
1369/// \param argv - array of arguments passed to the cling::Interpreter constructor
1370/// e.g. `-DFOO=bar`. The last element of the array must be `nullptr`.
1371/// \param interpLibHandle handle to interpreter library
1372
1373TCling::TCling(const char *name, const char *title, const char* const argv[], void *interpLibHandle)
1374: TInterpreter(name, title), fGlobalsListSerial(-1), fMapfile(nullptr),
1375 fRootmapFiles(nullptr), fLockProcessLine(true), fNormalizedCtxt(nullptr), fLookupHelper(nullptr),
1376 fPrevLoadedDynLibInfo(nullptr), fClingCallbacks(nullptr), fAutoLoadCallBack(nullptr),
1378{
1379 fPrompt[0] = 0;
1380 const bool fromRootCling = IsFromRootCling();
1381
1382 fCxxModulesEnabled = false;
1383#ifdef R__USE_CXXMODULES
1384 fCxxModulesEnabled = true;
1385#endif
1386
1387 llvm::install_fatal_error_handler(&exceptionErrorHandler);
1388
1389 fTemporaries = new std::vector<cling::Value>();
1390
1391 std::vector<std::string> clingArgsStorage;
1392 clingArgsStorage.push_back("cling4root");
1393 for (const char* const* arg = argv; *arg; ++arg)
1394 clingArgsStorage.push_back(*arg);
1395
1396 // rootcling sets its arguments through TROOT::GetExtraInterpreterArgs().
1397 if (!fromRootCling) {
1399
1400 // Add -I early so ASTReader can find the headers.
1401 std::string interpInclude(TROOT::GetEtcDir().Data());
1402 clingArgsStorage.push_back("-I" + interpInclude);
1403
1404 // Add include path to etc/cling.
1405 clingArgsStorage.push_back("-I" + interpInclude + "/cling");
1406
1407 // Add include path to etc/cling.
1408 clingArgsStorage.push_back("-I" + interpInclude + "/cling/plugins/include");
1409
1410 // Add the root include directory and etc/ to list searched by default.
1411 clingArgsStorage.push_back(std::string(("-I" + TROOT::GetIncludeDir()).Data()));
1412
1413 // Add the current path to the include path
1414 // TCling::AddIncludePath(".");
1415
1416 // Attach the PCH (unless we have C++ modules enabled which provide the
1417 // same functionality).
1418 if (!fCxxModulesEnabled) {
1419 std::string pchFilename = interpInclude + "/allDict.cxx.pch";
1420 if (gSystem->Getenv("ROOT_PCH")) {
1421 pchFilename = gSystem->Getenv("ROOT_PCH");
1422 }
1423
1424 clingArgsStorage.push_back("-include-pch");
1425 clingArgsStorage.push_back(pchFilename);
1426 }
1427
1428 clingArgsStorage.push_back("-Wno-undefined-inline");
1429 clingArgsStorage.push_back("-fsigned-char");
1430 clingArgsStorage.push_back("-fsized-deallocation");
1431 // The -O1 optimization flag has nasty side effects on Windows (32 and 64 bit)
1432 // See the GitHub issues #9809 and #9944
1433 // TODO: to be reviewed after the upgrade of LLVM & Clang
1434#ifndef _MSC_VER
1435 clingArgsStorage.push_back("-O1");
1436 // Disable optimized register allocation which is turned on automatically
1437 // by -O1, but seems to require -O2 to not explode in run time.
1438 clingArgsStorage.push_back("-mllvm");
1439 clingArgsStorage.push_back("-optimize-regalloc=0");
1440#endif
1441
1442#ifdef CLING_WITH_ADAPTIVECPP
1443 std::string acppInclude(TROOT::GetIncludeDir() + "/AdaptiveCpp");
1444
1445 clingArgsStorage.push_back("-isystem");
1446 clingArgsStorage.push_back(acppInclude);
1447 clingArgsStorage.push_back("-mllvm");
1448 clingArgsStorage.push_back("-acpp-sscp");
1449#endif
1450 }
1451
1452 // Process externally passed arguments if present.
1453 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv("EXTRA_CLING_ARGS");
1454 if (EnvOpt.has_value()) {
1455 StringRef Env(*EnvOpt);
1456 while (!Env.empty()) {
1457 StringRef Arg;
1458 std::tie(Arg, Env) = Env.split(' ');
1459 clingArgsStorage.push_back(Arg.str());
1460 }
1461 }
1462
1463 auto GetEnvVarPath = [](const std::string &EnvVar, std::vector<std::string> &Paths) {
1464 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv(EnvVar);
1465 if (EnvOpt.has_value()) {
1466 StringRef Env(*EnvOpt);
1467 while (!Env.empty()) {
1468 StringRef Arg;
1469 std::tie(Arg, Env) = Env.split(ROOT::FoundationUtils::GetEnvPathSeparator());
1470 if (std::find(Paths.begin(), Paths.end(), Arg.str()) == Paths.end())
1471 Paths.push_back(Arg.str());
1472 }
1473 }
1474 };
1475
1476 if (fCxxModulesEnabled) {
1477 std::vector<std::string> Paths;
1478 // ROOT usually knows better where its libraries are. This way we can
1479 // discover modules without having to should thisroot.sh and should fix
1480 // gnuinstall.
1481 Paths.push_back(TROOT::GetSharedLibDir().Data());
1482 GetEnvVarPath("CLING_PREBUILT_MODULE_PATH", Paths);
1483 std::string EnvVarPath;
1484 for (const std::string& P : Paths)
1486 // FIXME: We should make cling -fprebuilt-module-path work.
1487 gSystem->Setenv("CLING_PREBUILT_MODULE_PATH", EnvVarPath.c_str());
1488 }
1489
1490 // FIXME: This only will enable frontend timing reports.
1491 EnvOpt = llvm::sys::Process::GetEnv("ROOT_CLING_TIMING");
1492 if (EnvOpt.has_value())
1493 clingArgsStorage.push_back("-ftime-report");
1494
1495 // Add the overlay file. Note that we cannot factor it out for both root
1496 // and rootcling because rootcling activates modules only if -cxxmodule
1497 // flag is passed.
1498 if (fCxxModulesEnabled && !fromRootCling) {
1499 // For now we prefer rootcling to enumerate explicitly its modulemaps.
1500 std::vector<std::string> ModuleMaps;
1501 std::string ModuleMapSuffix = ROOT::FoundationUtils::GetPathSeparator() + "ROOT.modulemap";
1502 ModuleMaps.push_back(TROOT::GetIncludeDir().Data() + ModuleMapSuffix);
1503 GetEnvVarPath("CLING_MODULEMAP_FILES", ModuleMaps);
1504
1505 std::string cwd = gSystem->WorkingDirectory();
1506 // Give highest precedence of the modulemap in the cwd if any.
1507 if (llvm::sys::fs::exists(cwd + ModuleMapSuffix))
1508 ModuleMaps.push_back(cwd + ModuleMapSuffix);
1509
1510 for (const std::string& M : ModuleMaps)
1511 clingArgsStorage.push_back("-fmodule-map-file=" + M);
1512
1513 std::string ModulesCachePath;
1514 EnvOpt = llvm::sys::Process::GetEnv("CLING_MODULES_CACHE_PATH");
1515 if (EnvOpt.has_value()){
1516 StringRef Env(*EnvOpt);
1517 assert(llvm::sys::fs::exists(Env) && "Path does not exist!");
1518 ModulesCachePath = Env.str();
1519 } else {
1520 ModulesCachePath = TROOT::GetSharedLibDir();
1521 }
1522
1523 clingArgsStorage.push_back("-fmodules-cache-path=" + ModulesCachePath);
1524 }
1525
1526 std::vector<const char*> interpArgs;
1527 for (std::vector<std::string>::const_iterator iArg = clingArgsStorage.begin(),
1528 eArg = clingArgsStorage.end(); iArg != eArg; ++iArg)
1529 interpArgs.push_back(iArg->c_str());
1530
1531 // Activate C++ modules support. If we are running within rootcling, it's up
1532 // to rootcling to set this flag depending on whether it wants to produce
1533 // C++ modules.
1534 TString vfsArg;
1535 if (fCxxModulesEnabled) {
1536 if (!fromRootCling) {
1537 // We only set this flag, rest is done by the CIFactory.
1538 interpArgs.push_back("-fmodules");
1539 interpArgs.push_back("-fno-implicit-module-maps");
1540 // We should never build modules during runtime, so let's enable the
1541 // module build remarks from clang to make it easier to spot when we do
1542 // this by accident.
1543 interpArgs.push_back("-Rmodule-build");
1544 }
1545 // ROOT implements its AutoLoading upon module's link directives. We
1546 // generate module A { header "A.h" link "A.so" export * } where ROOT's
1547 // facilities use the link directive to dynamically load the relevant
1548 // library. So, we need to suppress clang's default autolink behavior.
1549 interpArgs.push_back("-fno-autolink");
1550 }
1551
1552#ifdef R__FAST_MATH
1553 // Same setting as in rootcling_impl.cxx.
1554 interpArgs.push_back("-ffast-math");
1555#endif
1556
1557 TString llvmResourceDir = TROOT::GetEtcDir() + "/cling";
1558 // Add statically injected extra arguments, usually coming from rootcling.
1559 for (const char** extraArgs = TROOT::GetExtraInterpreterArgs();
1560 extraArgs && *extraArgs; ++extraArgs) {
1561 if (!strcmp(*extraArgs, "-resource-dir")) {
1562 // Take the next arg as the llvm resource directory.
1563 llvmResourceDir = *(++extraArgs);
1564 } else {
1565 interpArgs.push_back(*extraArgs);
1566 }
1567 }
1568
1569 std::vector<std::string> _empty;
1570 auto args = TROOT::AddExtraInterpreterArgs(_empty);
1571 for (const auto &arg: args)
1572 interpArgs.emplace_back(arg.c_str());
1573
1574 // Add the Rdict module file extension.
1575 cling::Interpreter::ModuleFileExtensions extensions;
1576 EnvOpt = llvm::sys::Process::GetEnv("ROOTDEBUG_RDICT");
1577 if (!EnvOpt.has_value())
1578 extensions.push_back(std::make_shared<TClingRdictModuleFileExtension>());
1579
1580 fInterpreter = std::make_unique<cling::Interpreter>(interpArgs.size(),
1581 &(interpArgs[0]),
1582 llvmResourceDir, extensions,
1583 interpLibHandle);
1584
1585 if (!fInterpreter->getCI()) { // Compiler instance could not be created. See https://its.cern.ch/jira/browse/ROOT-10239
1586 return;
1587 }
1588
1589 // Tell CppInterOp that the cling::Interpreter instance is managed externally by ROOT
1590 // Sets the interpreter by passing the fInterpreter handle as soon as TCling is initialized
1591 Cpp::UseExternalInterpreter((Cpp::TInterp_t*)fInterpreter.get());
1592
1593 // Don't check whether modules' files exist.
1594 fInterpreter->getCI()->getPreprocessorOpts().DisablePCHOrModuleValidation =
1595 DisableValidationForModuleKind::All;
1596
1597 // Until we can disable AutoLoading during Sema::CorrectTypo() we have
1598 // to disable spell checking.
1599 fInterpreter->getCI()->getLangOpts().SpellChecking = false;
1600
1601 // Sync modules on/off between clang and us: clang turns it on for C++ >= 20.
1602 auto isModulesArg = [](const char* arg) { return !strcmp(arg, "-fmodules"); };
1603 bool hasModulesArg = std::find_if(interpArgs.begin(), interpArgs.end(), isModulesArg) != interpArgs.end();
1604 fInterpreter->getCI()->getLangOpts().Modules = hasModulesArg;
1605
1606 // We need stream that doesn't close its file descriptor, thus we are not
1607 // using llvm::outs. Keeping file descriptor open we will be able to use
1608 // the results in pipes (Savannah #99234).
1609 static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO, /*ShouldClose*/false);
1610 fMetaProcessor = std::make_unique<cling::MetaProcessor>(*fInterpreter, fMPOuts);
1611
1614
1615 // We are now ready (enough is loaded) to init the list of opaque typedefs.
1621
1622 // Disallow auto-parsing in rootcling
1623 fIsAutoParsingSuspended = fromRootCling;
1624
1625 ResetAll();
1626
1627 // Enable dynamic lookup
1628 if (!fromRootCling) {
1629 fInterpreter->enableDynamicLookup();
1630 }
1631
1632 // Enable ClinG's DefinitionShadower for ROOT.
1633 fInterpreter->getRuntimeOptions().AllowRedefinition = 1;
1634 auto &Policy = const_cast<clang::PrintingPolicy &>(fInterpreter->getCI()->getASTContext().getPrintingPolicy());
1635 // Print 'a<b<c> >' rather than 'a<b<c>>'.
1636 // FIXME: We should probably switch to the default printing policy setting
1637 // after adjusting tons of reference files.
1638 Policy.SplitTemplateClosers = true;
1639 // Keep default templare arguments, required for dictionary generation.
1640 Policy.SuppressDefaultTemplateArgs = false;
1641
1642
1643 // Attach cling callbacks last; they might need TROOT::fInterpreter
1644 // and should thus not be triggered during the equivalent of
1645 // TROOT::fInterpreter = new TCling;
1646 std::unique_ptr<TClingCallbacks>
1647 clingCallbacks(new TClingCallbacks(GetInterpreterImpl(), /*hasCodeGen*/ !fromRootCling));
1648 fClingCallbacks = clingCallbacks.get();
1649 fClingCallbacks->SetAutoParsingSuspended(fIsAutoParsingSuspended);
1650 fInterpreter->setCallbacks(std::move(clingCallbacks));
1651
1652 if (!fromRootCling) {
1653 cling::DynamicLibraryManager& DLM = *fInterpreter->getDynamicLibraryManager();
1654 // Make sure cling looks into ROOT's libdir, even if not part of LD_LIBRARY_PATH
1655 // e.g. because of an RPATH build.
1656 DLM.addSearchPath(TROOT::GetSharedLibDir().Data(), /*isUser=*/true,
1657 /*prepend=*/true);
1658 auto ShouldPermanentlyIgnore = [](llvm::StringRef FileName) -> bool{
1659 llvm::StringRef stem = llvm::sys::path::stem(FileName);
1660 return stem.starts_with("libNew") || stem.starts_with("libcppyy_backend");
1661 };
1662 // Initialize the dyld for AutoloadLibraryGenerator.
1663 DLM.initializeDyld(ShouldPermanentlyIgnore);
1665}
1666
1667
1668////////////////////////////////////////////////////////////////////////////////
1669/// Destroy the interpreter interface.
1670
1672{
1673 // ROOT's atexit functions require the interepreter to be available.
1674 // Run them before shutting down.
1675 if (!IsFromRootCling())
1676 GetInterpreterImpl()->runAtExitFuncs();
1677 fIsShuttingDown = true;
1678 delete fMapfile;
1679 delete fRootmapFiles;
1680 delete fTemporaries;
1681 delete fNormalizedCtxt;
1683 gCling = nullptr;
1684}
1685
1686////////////////////////////////////////////////////////////////////////////////
1687/// Initialize the interpreter, once TROOT::fInterpreter is set.
1688
1689void TCling::Initialize()
1690{
1691 if (!fClingCallbacks) // Compiler instance could not be created. See https://its.cern.ch/jira/browse/ROOT-10239
1692 return;
1694
1695 // We are set up. Enable ROOT's AutoLoading.
1696 if (IsFromRootCling())
1697 return;
1698
1699 // Read the rules before enabling the auto loading to not inadvertently
1700 // load the libraries for the classes concerned even-though the user is
1701 // *not* using them.
1702 // Note this call must happen before the first call to LoadLibraryMap.
1703 assert(GetRootMapFiles() == nullptr && "Must be called before LoadLibraryMap!");
1704 TClass::ReadRules(); // Read the default customization rules ...
1705
1707 SetClassAutoLoading(true);
1708}
1709
1710void TCling::ShutDown()
1711{
1713 ResetGlobals();
1714}
1715
1716////////////////////////////////////////////////////////////////////////////////
1717/// Helper to initialize TVirtualStreamerInfo's factor early.
1718/// Use static initialization to insure only one TStreamerInfo is created.
1719static bool R__InitStreamerInfoFactory()
1720{
1721 // Use lambda since SetFactory return void.
1722 auto setFactory = []() {
1724 return kTRUE;
1725 };
1726 static bool doneFactory = setFactory();
1727 return doneFactory; // avoid unused variable warning.
1728}
1729
1730////////////////////////////////////////////////////////////////////////////////
1731/// Register Rdict data for future loading by LoadPCM;
1732
1733void TCling::RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
1734{
1735 if (IsFromRootCling())
1736 return;
1737
1738 if (llvm::sys::fs::exists(pcmFileNameFullPath)) {
1739 ::Error("TCling::RegisterRdictForLoadPCM", "Rdict '%s' is both in Module extension and in File system.", pcmFileNameFullPath.c_str());
1740 return;
1741 }
1742
1743 // The pcmFileNameFullPath must be resolved already because we cannot resolve
1744 // a link to a non-existent file.
1745 fPendingRdicts[pcmFileNameFullPath] = *pcmContent;
1746}
1747
1748////////////////////////////////////////////////////////////////////////////////
1749/// Tries to load a PCM from TFile; returns true on success.
1750/// The caller of this function should be holding the ROOT Write lock.
1751
1752void TCling::LoadPCMImpl(TFile &pcmFile)
1753{
1754 auto listOfKeys = pcmFile.GetListOfKeys();
1755
1756 // This is an empty pcm
1757 if (listOfKeys && ((listOfKeys->GetSize() == 0) || // Nothing here, or
1758 ((listOfKeys->GetSize() == 1) && // only one, and
1759 !strcmp(((TKey *)listOfKeys->At(0))->GetName(), "EMPTY") // name is EMPTY
1760 ))) {
1761 return;
1762 }
1763
1764 TObjArray *protoClasses;
1765 if (gDebug > 1)
1766 ::Info("TCling::LoadPCMImpl", "reading protoclasses for %s \n", pcmFile.GetName());
1767
1768 TObjArray *enums;
1769 pcmFile.GetObject("__Enums", enums);
1770 if (enums) {
1771 // Cache the pointers
1772 auto listOfGlobals = gROOT->GetListOfGlobals();
1773 auto listOfEnums = dynamic_cast<THashList *>(gROOT->GetListOfEnums());
1774 // Loop on enums and then on enum constants
1775 for (auto selEnum : *enums) {
1776 const char *enumScope = selEnum->GetTitle();
1777 const char *enumName = selEnum->GetName();
1778 if (strcmp(enumScope, "") == 0) {
1779 // This is a global enum and is added to the
1780 // list of enums and its constants to the list of globals
1781 if (!listOfEnums->THashList::FindObject(enumName)) {
1782 ((TEnum *)selEnum)->SetClass(nullptr);
1783 listOfEnums->Add(selEnum);
1784 }
1785 for (auto enumConstant : *static_cast<TEnum *>(selEnum)->GetConstants()) {
1786 if (!listOfGlobals->FindObject(enumConstant)) {
1787 listOfGlobals->Add(enumConstant);
1788 }
1789 }
1790 } else {
1791 // This enum is in a namespace. A TClass entry is bootstrapped if
1792 // none exists yet and the enum is added to it
1793 TClass *nsTClassEntry = TClass::GetClass(enumScope);
1794 if (!nsTClassEntry) {
1795 nsTClassEntry = new TClass(enumScope, 0, TClass::kNamespaceForMeta, true);
1796 }
1797 auto listOfEnums = nsTClassEntry->fEnums.load();
1798 if (!listOfEnums) {
1799 if ((kIsClass | kIsStruct | kIsUnion) & nsTClassEntry->Property()) {
1800 // For this case, the list will be immutable once constructed
1801 // (i.e. in this case, by the end of this routine).
1802 listOfEnums = nsTClassEntry->fEnums = new TListOfEnums(nsTClassEntry);
1803 } else {
1804 // namespaces can have enums added to them
1805 listOfEnums = nsTClassEntry->fEnums = new TListOfEnumsWithLock(nsTClassEntry);
1806 }
1807 }
1808 if (listOfEnums && !listOfEnums->THashList::FindObject(enumName)) {
1809 ((TEnum *)selEnum)->SetClass(nsTClassEntry);
1810 listOfEnums->Add(selEnum);
1811 }
1812 }
1813 }
1814 enums->Clear();
1815 delete enums;
1816 }
1817
1818 pcmFile.GetObject("__ProtoClasses", protoClasses);
1819
1820 if (protoClasses) {
1821 for (auto obj : *protoClasses) {
1822 TProtoClass *proto = (TProtoClass *)obj;
1824 }
1825 // Now that all TClass-es know how to set them up we can update
1826 // existing TClasses, which might cause the creation of e.g. TBaseClass
1827 // objects which in turn requires the creation of TClasses, that could
1828 // come from the PCH, but maybe later in the loop. Instead of resolving
1829 // a dependency graph the addition to the TClassTable above allows us
1830 // to create these dependent TClasses as needed below.
1831 for (auto proto : *protoClasses) {
1832 if (TClass *existingCl = (TClass *)gROOT->GetListOfClasses()->FindObject(proto->GetName())) {
1833 // We have an existing TClass object. It might be emulated
1834 // or interpreted; we now have more information available.
1835 // Make that available.
1836 if (existingCl->GetState() != TClass::kHasTClassInit) {
1837 DictFuncPtr_t dict = gClassTable->GetDict(proto->GetName());
1838 if (!dict) {
1839 ::Error("TCling::LoadPCM", "Inconsistent TClassTable for %s", proto->GetName());
1840 } else {
1841 // This will replace the existing TClass.
1842 TClass *ncl = (*dict)();
1843 if (ncl)
1844 ncl->PostLoadCheck();
1845 }
1846 }
1847 }
1848 }
1849
1850 protoClasses->Clear(); // Ownership was transferred to TClassTable.
1851 delete protoClasses;
1852 }
1853
1854 TObjArray *dataTypes;
1855 pcmFile.GetObject("__Typedefs", dataTypes);
1856 if (dataTypes) {
1857 for (auto typedf : *dataTypes)
1858 gROOT->GetListOfTypes()->Add(typedf);
1859 dataTypes->Clear(); // Ownership was transferred to TListOfTypes.
1860 delete dataTypes;
1862}
1863
1864////////////////////////////////////////////////////////////////////////////////
1865/// Tries to load a rdict PCM, issues diagnostics if it fails.
1866/// The caller of this function should be holding the ROOT Write lock.
1867
1868void TCling::LoadPCM(std::string pcmFileNameFullPath)
1869{
1870 SuspendAutoLoadingRAII autoloadOff(this);
1871 SuspendAutoParsing autoparseOff(this);
1872 assert(!pcmFileNameFullPath.empty());
1873 assert(llvm::sys::path::is_absolute(pcmFileNameFullPath));
1874
1875 // Easier to work with the ROOT interfaces.
1876 TString pcmFileName = pcmFileNameFullPath;
1877
1878 // Prevent the ROOT-PCMs hitting this during auto-load during
1879 // JITting - which will cause recursive compilation.
1880 // Avoid to call the plugin manager at all.
1882
1884 llvm::SaveAndRestore<Int_t> SaveGDebug(gDebug);
1885 if (gDebug > 5) {
1886 gDebug -= 5;
1887 ::Info("TCling::LoadPCM", "Loading ROOT PCM %s", pcmFileName.Data());
1888 } else {
1889 gDebug = 0;
1890 }
1891
1892 if (llvm::sys::fs::is_symlink_file(pcmFileNameFullPath))
1893 pcmFileNameFullPath = ROOT::TMetaUtils::GetRealPath(pcmFileNameFullPath);
1894
1895 auto pendingRdict = fPendingRdicts.find(pcmFileNameFullPath);
1896 if (pendingRdict != fPendingRdicts.end()) {
1897 llvm::StringRef pcmContent = pendingRdict->second;
1898 TMemFile::ZeroCopyView_t range{pcmContent.data(), pcmContent.size()};
1899 std::string RDictFileOpts = pcmFileNameFullPath + "?filetype=pcm";
1900 TMemFile pcmMemFile(RDictFileOpts.c_str(), range);
1901
1902 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
1903 LoadPCMImpl(pcmMemFile);
1904 // Currently the module file are never unloaded (even if the library is
1905 // unloaded) and, of course, never reloaded.
1906 // Consequently, we must NOT remove the `pendingRdict` from the list
1907 // of pending dictionary, otherwise if a library is unloaded and then
1908 // reload we will be unable to update properly the TClass object
1909 // (because we wont be able to load the rootpcm file by executing the
1910 // above lines)
1911
1912 return;
1913 }
1914
1915 if (!llvm::sys::fs::exists(pcmFileNameFullPath)) {
1916 ::Error("TCling::LoadPCM", "ROOT PCM %s file does not exist",
1917 pcmFileNameFullPath.data());
1918 if (!fPendingRdicts.empty())
1919 for (const auto &rdict : fPendingRdicts)
1920 ::Info("TCling::LoadPCM", "In-memory ROOT PCM candidate %s\n",
1921 rdict.first.c_str());
1922 return;
1923 }
1924
1925 if (!gROOT->IsRootFile(pcmFileName)) {
1926 Fatal("LoadPCM", "The file %s is not a ROOT as was expected\n", pcmFileName.Data());
1927 return;
1928 }
1929 TFile pcmFile(pcmFileName + "?filetype=pcm", "READ");
1930 LoadPCMImpl(pcmFile);
1931}
1932
1933//______________________________________________________________________________
1934
1935namespace {
1936 using namespace clang;
1937
1938 class ExtLexicalStorageAdder: public RecursiveASTVisitor<ExtLexicalStorageAdder>{
1939 // This class is to be considered an helper for autoparsing.
1940 // It visits the AST and marks all classes (in all of their redeclarations)
1941 // with the setHasExternalLexicalStorage method.
1942 public:
1943 bool VisitRecordDecl(clang::RecordDecl* rcd){
1944 if (gDebug > 2)
1945 Info("ExtLexicalStorageAdder",
1946 "Adding external lexical storage to class %s",
1947 rcd->getNameAsString().c_str());
1948 auto reDeclPtr = rcd->getMostRecentDecl();
1949 do {
1950 reDeclPtr->setHasExternalLexicalStorage();
1951 } while ((reDeclPtr = reDeclPtr->getPreviousDecl()));
1952
1953 return false;
1954 }
1955 };
1957
1958}
1959
1960////////////////////////////////////////////////////////////////////////////////
1961///\returns true if the module map was loaded, false on error or if the map was
1962/// already loaded.
1963bool TCling::RegisterPrebuiltModulePath(const std::string &FullPath,
1964 const std::string &ModuleMapName /*= "module.modulemap"*/) const
1965{
1966 assert(llvm::sys::path::is_absolute(FullPath));
1967 Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
1968 FileManager &FM = PP.getFileManager();
1969 // FIXME: In a ROOT session we can add an include path (through .I /inc/path)
1970 // We should look for modulemap files there too.
1971 if (auto DE = FM.getOptionalDirectoryRef(FullPath)) {
1972 HeaderSearch &HS = PP.getHeaderSearchInfo();
1973 HeaderSearchOptions &HSOpts = HS.getHeaderSearchOpts();
1974 const auto &ModPaths = HSOpts.PrebuiltModulePaths;
1975 bool pathExists = std::find(ModPaths.begin(), ModPaths.end(), FullPath) != ModPaths.end();
1976 if (!pathExists)
1977 HSOpts.AddPrebuiltModulePath(FullPath);
1978 // We cannot use HS.lookupModuleMapFile(DE, /*IsFramework*/ false);
1979 // because its internal call to getFile has CacheFailure set to true.
1980 // In our case, modulemaps can appear any time due to ACLiC.
1981 // Code copied from HS.lookupModuleMapFile.
1982 llvm::SmallString<256> ModuleMapFileName(DE->getName());
1983 llvm::sys::path::append(ModuleMapFileName, ModuleMapName);
1984 if (auto FE = FM.getOptionalFileRef(ModuleMapFileName, /*openFile*/ false,
1985 /*CacheFailure*/ false)) {
1986 if (!HS.loadModuleMapFile(*FE, /*IsSystem*/ false))
1987 return true;
1988 Error("RegisterPrebuiltModulePath", "Could not load modulemap in %s", ModuleMapFileName.c_str());
1990 }
1991 return false;
1992}
1993
1994////////////////////////////////////////////////////////////////////////////////
1995/// List of dicts that have the PCM information already in the PCH.
1996static const std::unordered_set<std::string> gIgnoredPCMNames = {"libCore",
1997 "libRint",
1998 "libThread",
1999 "libRIO",
2000 "libImt",
2001 "libMultiProc",
2002 "libcomplexDict",
2003 "libdequeDict",
2004 "liblistDict",
2005 "libforward_listDict",
2006 "libvectorDict",
2007 "libmapDict",
2008 "libmultimap2Dict",
2009 "libmap2Dict",
2010 "libmultimapDict",
2011 "libsetDict",
2012 "libmultisetDict",
2013 "libunordered_setDict",
2014 "libunordered_multisetDict",
2015 "libunordered_mapDict",
2016 "libunordered_multimapDict",
2017 "libvalarrayDict",
2018 "G__GenVector32",
2019 "G__Smatrix32"};
2020
2021static void PrintDlError(const char *dyLibName, const char *modulename)
2022{
2023#ifdef R__WIN32
2024 char dyLibError[1000];
2025 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
2026 dyLibError, sizeof(dyLibError), NULL);
2027#else
2028 const char *dyLibError = dlerror();
2029#endif
2030 ::Error("TCling::RegisterModule", "Cannot open shared library %s for dictionary %s:\n %s", dyLibName, modulename,
2031 (dyLibError) ? dyLibError : "");
2032}
2033
2034////////////////////////////////////////////////////////////////////////////////
2035// Update all the TClass registered in fClassesToUpdate
2036
2038{
2039 while (!fClassesToUpdate.empty()) {
2040 TClass *oldcl = fClassesToUpdate.back().first;
2041 // If somehow the TClass has already been loaded (maybe it was registered several time),
2042 // we skip it. Otherwise, the existing TClass is in mode kInterpreted, kEmulated or
2043 // maybe even kForwardDeclared and needs to replaced.
2044 if (oldcl->GetState() != TClass::kHasTClassInit) {
2045 // if (gDebug > 2) Info("RegisterModule", "Forcing TClass init for %s", oldcl->GetName());
2046 DictFuncPtr_t dict = fClassesToUpdate.back().second;
2047 fClassesToUpdate.pop_back();
2048 // Calling func could manipulate the list so, let maintain the list
2049 // then call the dictionary function.
2050 TClass *ncl = dict();
2051 if (ncl) ncl->PostLoadCheck();
2052 } else {
2053 fClassesToUpdate.pop_back();
2054 }
2055 }
2056}
2057////////////////////////////////////////////////////////////////////////////////
2058/// Inject the module named "modulename" into cling; load all headers.
2059/// headers is a 0-terminated array of header files to `#include` after
2060/// loading the module. The module is searched for in all $LD_LIBRARY_PATH
2061/// entries (or %PATH% on Windows).
2062/// This function gets called by the static initialization of dictionary
2063/// libraries.
2064/// The payload code is injected "as is" in the interpreter.
2065/// The value of 'triggerFunc' is used to find the shared library location.
2066/// The caller of this function should be holding the ROOT Write lock.
2067
2068void TCling::RegisterModule(const char* modulename,
2069 const char** headers,
2070 const char** includePaths,
2071 const char* payloadCode,
2072 const char* fwdDeclsCode,
2073 void (*triggerFunc)(),
2074 const FwdDeclArgsToKeepCollection_t& fwdDeclsArgToSkip,
2075 const char** classesHeaders,
2076 Bool_t lateRegistration /*=false*/,
2077 Bool_t hasCxxModule /*=false*/)
2078{
2079 const bool fromRootCling = IsFromRootCling();
2080 // We need the dictionary initialization but we don't want to inject the
2081 // declarations into the interpreter, except for those we really need for
2082 // I/O; see rootcling.cxx after the call to TCling__GetInterpreter().
2083 if (fromRootCling) return;
2084
2085 // When we cannot provide a module for the library we should enable header
2086 // parsing. This 'mixed' mode ensures gradual migration to modules.
2087 llvm::SaveAndRestore<bool> SaveHeaderParsing(fHeaderParsingOnDemand);
2088 fHeaderParsingOnDemand = !hasCxxModule;
2089
2090 // Treat Aclic Libs in a special way. Do not delay the parsing.
2091 bool hasHeaderParsingOnDemand = fHeaderParsingOnDemand;
2092 bool isACLiC = strstr(modulename, "_ACLiC_dict") != nullptr;
2093 if (hasHeaderParsingOnDemand && isACLiC) {
2094 if (gDebug>1)
2095 Info("TCling::RegisterModule",
2096 "Header parsing on demand is active but this is an Aclic library. Disabling it for this library.");
2097 hasHeaderParsingOnDemand = false;
2098 }
2099
2100
2101 // Make sure we relookup symbols that were search for before we loaded
2102 // their autoparse information. We could be more subtil and remove only
2103 // the failed one or only the one in this module, but for now this is
2104 // better than nothing.
2105 fLookedUpClasses.clear();
2106
2107 // Make sure we do not set off AutoLoading or autoparsing during the
2108 // module registration!
2109 SuspendAutoLoadingRAII autoLoadOff(this);
2110
2111 for (const char** inclPath = includePaths; *inclPath; ++inclPath) {
2112 TCling::AddIncludePath(*inclPath);
2113 }
2114 cling::Transaction* T = nullptr;
2115 // Put the template decls and the number of arguments to skip in the TNormalizedCtxt
2116 for (auto& fwdDeclArgToSkipPair : fwdDeclsArgToSkip){
2117 const std::string& fwdDecl = fwdDeclArgToSkipPair.first;
2118 const int nArgsToSkip = fwdDeclArgToSkipPair.second;
2119 auto compRes = fInterpreter->declare(fwdDecl.c_str(), &T);
2120 assert(cling::Interpreter::kSuccess == compRes &&
2121 "A fwd declaration could not be compiled");
2122 if (compRes!=cling::Interpreter::kSuccess){
2123 Warning("TCling::RegisterModule",
2124 "Problems in declaring string '%s' were encountered.",
2125 fwdDecl.c_str()) ;
2126 continue;
2127 }
2128
2129 // Drill through namespaces recursively until the template is found
2130 if(ClassTemplateDecl* TD = FindTemplateInNamespace(T->getFirstDecl().getSingleDecl())){
2131 fNormalizedCtxt->AddTemplAndNargsToKeep(TD->getCanonicalDecl(), nArgsToSkip);
2132 }
2133
2134 }
2135
2136 // FIXME: Remove #define __ROOTCLING__ once PCMs are there.
2137 // This is used to give Sema the same view on ACLiC'ed files (which
2138 // are then #included through the dictionary) as rootcling had.
2139 TString code = gNonInterpreterClassDef;
2140 if (payloadCode)
2141 code += payloadCode;
2142
2143 std::string dyLibName = cling::DynamicLibraryManager::getSymbolLocation(triggerFunc);
2144 assert(!llvm::sys::fs::is_symlink_file(dyLibName));
2145
2146 if (dyLibName.empty()) {
2147 ::Error("TCling::RegisterModule", "Dictionary trigger function for %s not found", modulename);
2148 return;
2149 }
2150
2151 // The triggerFunc may not be in a shared object but in an executable.
2152 bool isSharedLib = cling::DynamicLibraryManager::isSharedLibrary(dyLibName);
2153
2154 bool wasDlopened = false;
2155
2156 // If this call happens after dlopen has finished (i.e. late registration)
2157 // there is no need to dlopen the library recursively. See ROOT-8437 where
2158 // the dyLibName would correspond to the binary.
2159 if (!lateRegistration) {
2160
2161 if (isSharedLib) {
2162 // We need to open the dictionary shared library, to resolve symbols
2163 // requested by the JIT from it: as the library is currently being dlopen'ed,
2164 // its symbols are not yet reachable from the process.
2165 // Recursive dlopen seems to work just fine.
2166 void* dyLibHandle = dlopen(dyLibName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
2167 if (dyLibHandle) {
2168 fRegisterModuleDyLibs.push_back(dyLibHandle);
2169 wasDlopened = true;
2170 } else {
2171 PrintDlError(dyLibName.c_str(), modulename);
2172 }
2173 }
2174 } // if (!lateRegistration)
2175
2176 if (hasHeaderParsingOnDemand && fwdDeclsCode){
2177 // We now parse the forward declarations. All the classes are then modified
2178 // in order for them to have an external lexical storage.
2179 std::string fwdDeclsCodeLessEnums;
2180 {
2181 // Search for enum forward decls and only declare them if no
2182 // declaration exists yet.
2183 std::string fwdDeclsLine;
2184 std::istringstream fwdDeclsCodeStr(fwdDeclsCode);
2185 std::vector<std::string> scopes;
2186 while (std::getline(fwdDeclsCodeStr, fwdDeclsLine)) {
2187 const auto enumPos = fwdDeclsLine.find("enum __attribute__((annotate(\"");
2188 // We check if the line contains a fwd declaration of an enum
2189 if (enumPos != std::string::npos) {
2190 // We clear the scopes which we may have carried from a previous iteration
2191 scopes.clear();
2192 // We check if the enum is not in a scope. If yes, save its name
2193 // and the names of the enclosing scopes.
2194 if (enumPos != 0) {
2195 // it's enclosed in namespaces. We need to understand what they are
2196 auto nsPos = fwdDeclsLine.find("namespace");
2197 R__ASSERT(nsPos < enumPos && "Inconsistent enum and enclosing scope parsing!");
2198 while (nsPos < enumPos && nsPos != std::string::npos) {
2199 // we have a namespace, let's put it in the collection of scopes
2200 const auto nsNameStart = nsPos + 10;
2201 const auto nsNameEnd = fwdDeclsLine.find('{', nsNameStart);
2202 const auto nsName = fwdDeclsLine.substr(nsNameStart, nsNameEnd - nsNameStart);
2203 scopes.push_back(nsName);
2204 nsPos = fwdDeclsLine.find("namespace", nsNameEnd);
2205 }
2206 }
2207 clang::DeclContext* DC = nullptr;
2208 for (auto &&aScope: scopes) {
2209 DC = cling::utils::Lookup::Namespace(&fInterpreter->getSema(), aScope.c_str(), DC);
2210 if (!DC) {
2211 // No decl context means we have to fwd declare the enum.
2212 break;
2213 }
2214 }
2215 if (scopes.empty() || DC) {
2216 // We know the scope; let's look for the enum. For that, look
2217 // for the *last* closing parentheses of an attribute because
2218 // there can be multiple.
2219 size_t posEnumName = fwdDeclsLine.rfind("\"))) ");
2220 R__ASSERT(posEnumName != std::string::npos && "Inconsistent enum fwd decl!");
2221 posEnumName += 5; // skip "\"))) "
2222 while (isspace(fwdDeclsLine[posEnumName]))
2223 ++posEnumName;
2224 size_t posEnumNameEnd = fwdDeclsLine.find(" : ", posEnumName);
2225 R__ASSERT(posEnumNameEnd != std::string::npos && "Inconsistent enum fwd decl (end)!");
2226 while (isspace(fwdDeclsLine[posEnumNameEnd]))
2227 --posEnumNameEnd;
2228 // posEnumNameEnd now points to the last character of the name.
2229
2230 std::string enumName = fwdDeclsLine.substr(posEnumName,
2231 posEnumNameEnd - posEnumName + 1);
2232
2233 if (clang::NamedDecl* enumDecl
2234 = cling::utils::Lookup::Named(&fInterpreter->getSema(),
2235 enumName.c_str(), DC)) {
2236 // We have an existing enum decl (forward or definition);
2237 // skip this.
2238 R__ASSERT(llvm::dyn_cast<clang::EnumDecl>(enumDecl) && "not an enum decl!");
2239 (void)enumDecl;
2240 continue;
2241 }
2242 }
2243 }
2244
2245 fwdDeclsCodeLessEnums += fwdDeclsLine + "\n";
2246 }
2247 }
2248
2249 if (!fwdDeclsCodeLessEnums.empty()){ // Avoid the overhead if nothing is to be declared
2250 auto compRes = fInterpreter->declare(fwdDeclsCodeLessEnums, &T);
2251 assert(cling::Interpreter::kSuccess == compRes &&
2252 "The forward declarations could not be compiled");
2253 if (compRes!=cling::Interpreter::kSuccess){
2254 Warning("TCling::RegisterModule",
2255 "Problems in compiling forward declarations for module %s: '%s'",
2256 modulename, fwdDeclsCodeLessEnums.c_str()) ;
2257 }
2258 else if (T){
2259 // Loop over all decls in the transaction and go through them all
2260 // to mark them properly.
2261 // In order to do that, we first iterate over all the DelayedCallInfos
2262 // within the transaction. Then we loop over all Decls in the DeclGroupRef
2263 // contained in the DelayedCallInfos. For each decl, we traverse.
2264 ExtLexicalStorageAdder elsa;
2265 for (auto dciIt = T->decls_begin();dciIt!=T->decls_end();dciIt++){
2266 cling::Transaction::DelayCallInfo& dci = *dciIt;
2267 for(auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) {
2268 clang::Decl* declPtr = *dit;
2269 elsa.TraverseDecl(declPtr);
2270 }
2271 }
2272 }
2273 }
2274
2275 // Now we register all the headers necessary for the class
2276 // Typical format of the array:
2277 // {"A", "classes.h", "@",
2278 // "vector<A>", "vector", "@",
2279 // "myClass", payloadCode, "@",
2280 // nullptr};
2281
2282 std::string temp;
2283 for (const char** classesHeader = classesHeaders; *classesHeader; ++classesHeader) {
2284 temp=*classesHeader;
2285
2286 size_t theTemplateHash = 0;
2287 bool addTemplate = false;
2288 size_t posTemplate = temp.find('<');
2289 if (posTemplate != std::string::npos) {
2290 // Add an entry for the template itself.
2291 std::string templateName = temp.substr(0, posTemplate);
2292 theTemplateHash = fStringHashFunction(templateName);
2293 addTemplate = true;
2294 }
2295 size_t theHash = fStringHashFunction(temp);
2296 classesHeader++;
2297 for (const char** classesHeader_inner = classesHeader; 0!=strcmp(*classesHeader_inner,"@"); ++classesHeader_inner,++classesHeader){
2298 // This is done in order to distinguish headers from files and from the payloadCode
2299 if (payloadCode == *classesHeader_inner ){
2300 fPayloads.insert(theHash);
2301 if (addTemplate) fPayloads.insert(theTemplateHash);
2302 }
2303 if (gDebug > 2)
2304 Info("TCling::RegisterModule",
2305 "Adding a header for %s", temp.c_str());
2306 fClassesHeadersMap[theHash].push_back(*classesHeader_inner);
2307 if (addTemplate) {
2308 if (fClassesHeadersMap.find(theTemplateHash) == fClassesHeadersMap.end()) {
2309 fClassesHeadersMap[theTemplateHash].push_back(*classesHeader_inner);
2310 }
2311 addTemplate = false;
2312 }
2313 }
2314 }
2315 }
2316
2317 clang::Sema &TheSema = fInterpreter->getSema();
2318
2319 bool ModuleWasSuccessfullyLoaded = false;
2320 if (hasCxxModule) {
2321 std::string ModuleName = modulename;
2322 if (llvm::StringRef(modulename).starts_with("lib"))
2323 ModuleName = llvm::StringRef(modulename).substr(3).str();
2324
2325 // In case we are directly loading the library via gSystem->Load() without
2326 // specifying the relevant include paths we should try loading the
2327 // modulemap next to the library location.
2328 clang::Preprocessor &PP = TheSema.getPreprocessor();
2329 std::string ModuleMapName;
2330 if (isACLiC)
2331 ModuleMapName = ModuleName + ".modulemap";
2332 else
2333 ModuleMapName = "module.modulemap";
2334 RegisterPrebuiltModulePath(llvm::sys::path::parent_path(dyLibName).str(),
2335 ModuleMapName);
2336
2337 // FIXME: We should only complain for modules which we know to exist. For example, we should not complain about
2338 // modules such as GenVector32 because it needs to fall back to GenVector.
2339 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2340 ModuleWasSuccessfullyLoaded = LoadModule(ModuleName, *fInterpreter);
2341 if (!ModuleWasSuccessfullyLoaded) {
2342 // Only report if we found the module in the modulemap.
2343 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
2344 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
2345 if (moduleMap.findModule(ModuleName))
2346 Info("TCling::RegisterModule", "Module %s in modulemap failed to load.", ModuleName.c_str());
2347 }
2348 }
2349
2350 if (gIgnoredPCMNames.find(modulename) == gIgnoredPCMNames.end()) {
2351 llvm::SmallString<256> pcmFileNameFullPath(dyLibName);
2352 // The path dyLibName might not be absolute. This can happen if dyLibName
2353 // is linked to an executable in the same folder.
2354 llvm::sys::fs::make_absolute(pcmFileNameFullPath);
2355 llvm::sys::path::remove_filename(pcmFileNameFullPath);
2356 llvm::sys::path::append(pcmFileNameFullPath,
2358 LoadPCM(pcmFileNameFullPath.str().str());
2359 }
2360
2361 { // scope within which diagnostics are de-activated
2362 // For now we disable diagnostics because we saw them already at
2363 // dictionary generation time. That won't be an issue with the PCMs.
2364
2365 clangDiagSuppr diagSuppr(TheSema.getDiagnostics());
2366
2367#if defined(R__MUST_REVISIT)
2368#if R__MUST_REVISIT(6,2)
2369 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
2370#endif
2371#endif
2372
2373 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand){
2374 SuspendAutoParsing autoParseRaii(this);
2375
2376 const cling::Transaction* watermark = fInterpreter->getLastTransaction();
2377 cling::Interpreter::CompilationResult compRes = fInterpreter->parseForModule(code.Data());
2378 if (isACLiC) {
2379 // Register an unload point.
2380 fMetaProcessor->registerUnloadPoint(watermark, headers[0]);
2381 }
2382
2383 assert(cling::Interpreter::kSuccess == compRes &&
2384 "Payload code of a dictionary could not be parsed correctly.");
2385 if (compRes!=cling::Interpreter::kSuccess) {
2386 Warning("TCling::RegisterModule",
2387 "Problems declaring payload for module %s.", modulename) ;
2388 }
2389 }
2390 }
2391
2392 // Now that all the header have been registered/compiled, let's
2393 // make sure to 'reset' the TClass that have a class init in this module
2394 // but already had their type information available (using information/header
2395 // loaded from other modules or from class rules or from opening a TFile
2396 // or from loading header in a way that did not provoke the loading of
2397 // the library we just loaded).
2399
2400 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand) {
2401 // __ROOTCLING__ might be pulled in through PCH
2402 fInterpreter->declare("#ifdef __ROOTCLING__\n"
2403 "#undef __ROOTCLING__\n"
2404 + gInterpreterClassDef +
2405 "#endif");
2406 }
2407
2408 if (wasDlopened) {
2409 assert(isSharedLib);
2410 void* dyLibHandle = fRegisterModuleDyLibs.back();
2411 fRegisterModuleDyLibs.pop_back();
2412 dlclose(dyLibHandle);
2413 }
2414}
2415
2417 clang::CompilerInstance& CI = *GetInterpreterImpl()->getCI();
2418 ASTContext &C = CI.getASTContext();
2419
2420 // Do not do anything if we have no global module index.
2421 // FIXME: This is mostly to real with false positives in the TTabCom
2422 // interface for non-modules.
2423 if (!fCxxModulesEnabled)
2424 return;
2425
2426 if (IdentifierInfoLookup *External = C.Idents.getExternalIdentifierLookup()) {
2427 std::unique_ptr<IdentifierIterator> Iter(External->getIdentifiers());
2428 for (llvm::StringRef Ident = Iter->Next(); !Ident.empty(); Ident = Iter->Next()) {
2429 std::string I = Ident.str();
2430 if (!Idents.Contains(I.data()))
2431 Idents.Add(new TObjString(I.c_str()));
2432 }
2433 }
2434}
2436
2437////////////////////////////////////////////////////////////////////////////////
2438/// Register classes that already existed prior to their dictionary loading
2439/// and that already had a ClassInfo (and thus would not be refresh via
2440/// UpdateClassInfo.
2441
2443{
2444 fClassesToUpdate.push_back(std::make_pair(oldcl,dict));
2445}
2446
2447////////////////////////////////////////////////////////////////////////////////
2448/// If the dictionary is loaded, we can remove the class from the list
2449/// (otherwise the class might be loaded twice).
2450
2451void TCling::UnRegisterTClassUpdate(const TClass *oldcl)
2452{
2453 typedef std::vector<std::pair<TClass*,DictFuncPtr_t> >::iterator iterator;
2454 iterator stop = fClassesToUpdate.end();
2455 for(iterator i = fClassesToUpdate.begin();
2456 i != stop;
2457 ++i)
2458 {
2459 if ( i->first == oldcl ) {
2460 fClassesToUpdate.erase(i);
2461 return;
2462 }
2463 }
2464}
2465
2466
2467////////////////////////////////////////////////////////////////////////////////
2468/// Let cling process a command line.
2469///
2470/// If the command is executed and the error is 0, then the return value
2471/// is the int value corresponding to the result of the executed command
2472/// (float and double return values will be truncated).
2473///
2475// Method for handling the interpreter exceptions.
2476// the MetaProcessor is passing in as argument to teh function, because
2477// cling::Interpreter::CompilationResult is a nested class and it cannot be
2478// forward declared, thus this method cannot be a static member function
2479// of TCling.
2480
2481static int HandleInterpreterException(cling::MetaProcessor* metaProcessor,
2482 const char* input_line,
2483 cling::Interpreter::CompilationResult& compRes,
2484 cling::Value* result)
2485{
2486 try {
2487 return metaProcessor->process(input_line, compRes, result);
2488 }
2489 catch (cling::InterpreterException& ex)
2490 {
2491 Error("HandleInterpreterException", "%s\n%s", ex.what(), "Execution of your code was aborted.");
2492 ex.diagnose();
2493 compRes = cling::Interpreter::kFailure;
2494 }
2495 return 0;
2496}
2497
2498////////////////////////////////////////////////////////////////////////////////
2499
2500bool TCling::DiagnoseIfInterpreterException(const std::exception &e) const
2501{
2502 if (auto ie = dynamic_cast<const cling::InterpreterException*>(&e)) {
2503 ie->diagnose();
2504 return true;
2505 }
2506 return false;
2507}
2508
2509////////////////////////////////////////////////////////////////////////////////
2510
2511Longptr_t TCling::ProcessLine(const char* line, EErrorCode* error/*=0*/)
2512{
2513 // Copy the passed line, it comes from a static buffer in TApplication
2514 // which can be reentered through the Cling evaluation routines,
2515 // which would overwrite the static buffer and we would forget what we
2516 // were doing.
2517 //
2518 TString sLine(line);
2519 if (strstr(line,fantomline)) {
2520 // End-Of-Line action
2521 // See the comment (copied from above):
2522 // It is a "fantom" method to synchronize user keyboard input
2523 // and ROOT prompt line (for WIN32)
2524 // and is implemented by
2525 if (gApplication) {
2526 if (gApplication->IsCmdThread()) {
2528 gROOT->SetLineIsProcessing();
2529
2531
2532 gROOT->SetLineHasBeenProcessed();
2533 }
2534 }
2535 return 0;
2536 }
2537
2539 gGlobalMutex->Lock();
2540 if (!gInterpreterMutex)
2542 gGlobalMutex->UnLock();
2543 }
2545 gROOT->SetLineIsProcessing();
2546
2547 struct InterpreterFlagsRAII {
2548 cling::Interpreter* fInterpreter;
2549 bool fWasDynamicLookupEnabled;
2550
2551 InterpreterFlagsRAII(cling::Interpreter* interp):
2552 fInterpreter(interp),
2553 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2554 {
2555 fInterpreter->enableDynamicLookup(true);
2556 }
2557 ~InterpreterFlagsRAII() {
2558 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2559 gROOT->SetLineHasBeenProcessed();
2560 }
2561 } interpreterFlagsRAII(GetInterpreterImpl());
2562
2563 // A non-zero returned value means the given line was
2564 // not a complete statement.
2565 int indent = 0;
2566 // This will hold the resulting value of the evaluation the given line.
2567 cling::Value result;
2568 cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess;
2569 if (!strncmp(sLine.Data(), ".L", 2) || !strncmp(sLine.Data(), ".x", 2) ||
2570 !strncmp(sLine.Data(), ".X", 2)) {
2571 // If there was a trailing "+", then CINT compiled the code above,
2572 // and we will need to strip the "+" before passing the line to cling.
2573 TString mod_line(sLine);
2574 TString aclicMode;
2575 TString arguments;
2576 TString io;
2577 TString fname = gSystem->SplitAclicMode(sLine.Data() + 3,
2578 aclicMode, arguments, io);
2579 if (aclicMode.Length()) {
2580 // Remove the leading '+'
2581 R__ASSERT(aclicMode[0]=='+' && "ACLiC mode must start with a +");
2582 aclicMode[0]='k'; // We always want to keep the .so around.
2583 if (aclicMode[1]=='+') {
2584 // We have a 2nd +
2585 aclicMode[1]='f'; // We want to force the recompilation.
2586 }
2587 if (!gSystem->CompileMacro(fname,aclicMode)) {
2588 // ACLiC failed.
2589 compRes = cling::Interpreter::kFailure;
2590 } else {
2591 if (strncmp(sLine.Data(), ".L", 2) != 0) {
2592 // if execution was requested.
2593
2594 if (arguments.Length() == 0) {
2595 arguments = "()";
2596 }
2597 // We need to remove the extension.
2598 Ssiz_t ext = fname.Last('.');
2599 if (ext != kNPOS) {
2600 fname.Remove(ext);
2601 }
2602 const char *function = gSystem->BaseName(fname);
2603 mod_line = function + arguments + io;
2604 indent = HandleInterpreterException(GetMetaProcessorImpl(), mod_line, compRes, &result);
2605 }
2606 }
2607 } else if (cling::DynamicLibraryManager::isSharedLibrary(fname.Data()) &&
2608 strncmp(sLine.Data(), ".L", 2) != 0) { // .x *.so or *.dll
2609 if (gSystem->Load(fname) < 0) {
2610 // Loading failed.
2611 compRes = cling::Interpreter::kFailure;
2612 } else {
2613 if (arguments.Length() == 0) {
2614 arguments = "()";
2615 }
2616 // We need to remove the extension. (*.so or *.dll)
2617 Ssiz_t ext = fname.Last('.');
2618 if (ext != kNPOS) {
2619 fname.Remove(ext);
2620 }
2621 // Now we try to find the 'main' function to run within this shared library
2622 // We distinguish two cases: a library.so with a function library(args),
2623 // or a precompiled ACLiC macro (macro_C.so) with a function macro(args).
2624 // Only in the second case, we need to strip the suffix _C or _cpp from fname.
2625 if (!gInterpreter->GetFunction(nullptr, gSystem->BaseName(fname))) { // AcLiC macro
2626 // We need to remove the automatically appended _ extension when compiling (macro_C from macro.C)
2627 ext = fname.Last('_');
2628 if (ext != kNPOS) {
2629 fname.Remove(ext);
2630 }
2631 }
2632 const char *function = gSystem->BaseName(fname);
2633 mod_line = function + arguments + io;
2634 indent = HandleInterpreterException(GetMetaProcessorImpl(), mod_line, compRes, &result);
2635 }
2636 } else {
2637 // neither ACLiC nor run shared-library (.x)
2638 size_t unnamedMacroOpenCurly;
2639 {
2640 std::string code;
2641 std::string codeline;
2642 // Windows requires std::ifstream::binary to properly handle
2643 // CRLF and LF line endings
2644 std::ifstream in(fname, std::ifstream::binary);
2645 while (in) {
2646 std::getline(in, codeline);
2647 code += codeline + "\n";
2648 }
2649 unnamedMacroOpenCurly
2650 = cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
2651 }
2652
2653 fCurExecutingMacros.push_back(fname);
2654 if (unnamedMacroOpenCurly != std::string::npos) {
2655 compRes = fMetaProcessor->readInputFromFile(fname.Data(), &result,
2656 unnamedMacroOpenCurly);
2657 } else {
2658 // No DynLookup for .x, .L of named macros.
2659 fInterpreter->enableDynamicLookup(false);
2660 indent = HandleInterpreterException(GetMetaProcessorImpl(), mod_line, compRes, &result);
2661 }
2662 fCurExecutingMacros.pop_back();
2663 }
2664 } // .L / .X / .x
2665 else {
2666 if (0!=strncmp(sLine.Data(), ".autodict ",10) && sLine != ".autodict") {
2667 // explicitly ignore .autodict without having to support it
2668 // in cling.
2669
2670 // Turn off autoparsing if this is an include directive
2671 bool isInclusionDirective = sLine.Contains("\n#include") || sLine.BeginsWith("#include");
2672 if (isInclusionDirective) {
2673 SuspendAutoParsing autoParseRaii(this);
2674 indent = HandleInterpreterException(GetMetaProcessorImpl(), sLine, compRes, &result);
2675 } else {
2676 indent = HandleInterpreterException(GetMetaProcessorImpl(), sLine, compRes, &result);
2677 }
2678 }
2679 }
2680 if (result.isValid())
2681 RegisterTemporary(result);
2682 if (indent) {
2683 if (error)
2684 *error = kProcessing;
2685 return 0;
2686 }
2687 if (error) {
2688 switch (compRes) {
2689 case cling::Interpreter::kSuccess: *error = kNoError; break;
2690 case cling::Interpreter::kFailure: *error = kRecoverable; break;
2691 case cling::Interpreter::kMoreInputExpected: *error = kProcessing; break;
2692 }
2693 }
2694 if (compRes == cling::Interpreter::kSuccess
2695 && result.isValid()
2696 && !result.isVoid())
2697 {
2698 return result.castAs<Longptr_t>();
2700 return 0;
2701}
2702
2703////////////////////////////////////////////////////////////////////////////////
2704/// No-op; see TRint instead.
2705
2706void TCling::PrintIntro()
2707{
2708}
2710////////////////////////////////////////////////////////////////////////////////
2711/// Print information about the interpreter.
2712///\param[in] option Selects the type of information to print.
2713///
2714/// List of currently support options:
2715/// - autoparsed: Print the list of classes that triggered autoparsing.
2716void TCling::Print(Option_t *option) const
2717{
2718 if (option && *option) {
2719 if (!strcmp(option, "autoparsed")) {
2720 std::cout << "Auto parsed classes:" << std::endl;
2721 for (auto & cls : fAutoParseClasses) {
2722 std::cout << " " << cls << std::endl;
2723 }
2724 } else if (!strcmp(option, "autoloaded")) {
2725 std::cout << "Auto loaded libraries:" << std::endl;
2726 for (auto & lib : fAutoLoadedLibraries) {
2727 std::cout << " " << lib << std::endl;
2728 }
2729 } else {
2730 ::Error("TCling::Print", "Unknown option '%s'", option);
2731 }
2732 } else {
2733 ::Info("TCling::Print", "No options specified");
2734 }
2735}
2736
2737
2738////////////////////////////////////////////////////////////////////////////////
2739/// \brief Add a directory to the list of directories in which the
2740/// interpreter looks for include files.
2741/// \param[in] path The path to the directory.
2742/// \note Only one path item can be specified at a time, i.e. "path1:path2" is
2743/// \b NOT supported.
2744/// \warning Only the path to the directory should be specified, without
2745/// prepending the \c -I prefix, i.e.
2746/// <tt>gCling->AddIncludePath("/path/to/my/includes")</tt>. If the
2747/// \c -I prefix is used it will be ignored.
2748void TCling::AddIncludePath(const char *path)
2749{
2751 // Favorite source of annoyance: gSystem->AddIncludePath() needs "-I",
2752 // gCling->AddIncludePath() does not! Work around that inconsistency:
2753 if (path[0] == '-' && path[1] == 'I')
2754 path += 2;
2755 TString sPath(path);
2756 gSystem->ExpandPathName(sPath);
2757#ifdef _MSC_VER
2758 if (sPath.BeginsWith("/")) {
2759 char drive[3];
2760 snprintf(drive, 3, "%c:", _getdrive() + 'A' - 1);
2761 sPath.Prepend(drive);
2762 }
2763#endif
2764 fInterpreter->AddIncludePath(sPath.Data());
2765}
2766
2767////////////////////////////////////////////////////////////////////////////////
2768/// Visit all members over members, recursing over base classes.
2769
2770void TCling::InspectMembers(TMemberInspector& insp, const void* obj,
2771 const TClass* cl, Bool_t isTransient)
2772{
2776 }
2777
2778 if (!cl || cl->GetCollectionProxy()) {
2779 // We do not need to investigate the content of the STL
2780 // collection, they are opaque to us (and details are
2781 // uninteresting).
2782 return;
2783 }
2784
2785 static const TClassRef clRefString("std::string");
2786 if (clRefString == cl) {
2787 // We stream std::string without going through members..
2788 return;
2789 }
2790
2791 if (TClassEdit::IsStdArray(cl->GetName())) {
2792 // We treat std arrays as C arrays
2793 return;
2794 }
2795
2796 const char* cobj = (const char*) obj; // for ptr arithmetics
2797
2798 // Treat the case of std::complex in a special manner. We want to enforce
2799 // the layout of a stl implementation independent class, which is the
2800 // complex as implemented in ROOT5.
2801
2802 // A simple lambda to simplify the code
2803 auto inspInspect = [&] (ptrdiff_t offset){
2804 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_real", cobj, isTransient);
2805 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_imag", cobj + offset, isTransient);
2806 };
2807
2808 auto complexType = TClassEdit::GetComplexType(cl->GetName());
2809 switch(complexType) {
2811 {
2812 break;
2813 }
2815 {
2816 inspInspect(sizeof(float));
2817 return;
2818 }
2820 {
2821 inspInspect(sizeof(double));
2822 return;
2823 }
2825 {
2826 inspInspect(sizeof(int));
2827 return;
2828 }
2830 {
2831 inspInspect(sizeof(long));
2832 return;
2833 }
2834 }
2835
2836 static clang::PrintingPolicy
2837 printPol(fInterpreter->getCI()->getLangOpts());
2838 if (printPol.Indentation) {
2839 // not yet initialized
2840 printPol.Indentation = 0;
2841 printPol.SuppressInitializers = true;
2842 }
2843
2844 const char* clname = cl->GetName();
2845 // Printf("Inspecting class %s\n", clname);
2846
2847 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2848 const clang::Decl *scopeDecl = nullptr;
2849 const clang::Type *recordType = nullptr;
2850
2851 if (cl->GetClassInfo()) {
2852 TClingClassInfo * clingCI = (TClingClassInfo *)cl->GetClassInfo();
2853 scopeDecl = clingCI->GetDecl();
2854 recordType = clingCI->GetType();
2855 } else {
2856 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2857 // Diags will complain about private classes:
2858 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2859 &recordType);
2860 }
2861 if (!scopeDecl) {
2862 Error("InspectMembers", "Cannot find Decl for class %s", clname);
2863 return;
2864 }
2865 const clang::CXXRecordDecl* recordDecl
2866 = llvm::dyn_cast<const clang::CXXRecordDecl>(scopeDecl);
2867 if (!recordDecl) {
2868 Error("InspectMembers", "Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2869 return;
2870 }
2871
2872 {
2873 // Force possible deserializations first. We need to have no pending
2874 // Transaction when passing control flow to the inspector below (ROOT-7779).
2875 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2876
2877 astContext.getASTRecordLayout(recordDecl);
2878
2879 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2880 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2881 }
2882
2883 const clang::ASTRecordLayout& recLayout
2884 = astContext.getASTRecordLayout(recordDecl);
2885
2886 // TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
2887 // if (proxy && ( proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated ) ) {
2888 // Error("InspectMembers","The TClass for %s has an emulated proxy but we are looking at a compiled version of the collection!\n",
2889 // cl->GetName());
2890 // }
2891 if (cl->Size() != recLayout.getSize().getQuantity()) {
2892 Error("InspectMembers","TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2893 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2894 }
2895
2896 unsigned iNField = 0;
2897 // iterate over fields
2898 // FieldDecls are non-static, else it would be a VarDecl.
2899 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2900 eField = recordDecl->field_end(); iField != eField;
2901 ++iField, ++iNField) {
2902
2903
2904 clang::QualType memberQT = iField->getType();
2905 if (recordType) {
2906 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2907 memberQT = ROOT::TMetaUtils::ReSubstTemplateArg(memberQT, recordType);
2908 }
2909 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2910 if (memberQT.isNull()) {
2911 std::string memberName;
2912 llvm::raw_string_ostream stream(memberName);
2913 // Don't trigger fopen of the source file to count lines:
2914 printPol.AnonymousTagLocations = false;
2915 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2916 stream.flush();
2917 Error("InspectMembers",
2918 "Cannot retrieve QualType for member %s while inspecting class %s",
2919 memberName.c_str(), clname);
2920 continue; // skip member
2921 }
2922 const clang::Type* memType = memberQT.getTypePtr();
2923 if (!memType) {
2924 std::string memberName;
2925 llvm::raw_string_ostream stream(memberName);
2926 // Don't trigger fopen of the source file to count lines:
2927 printPol.AnonymousTagLocations = false;
2928 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2929 stream.flush();
2930 Error("InspectMembers",
2931 "Cannot retrieve Type for member %s while inspecting class %s",
2932 memberName.c_str(), clname);
2933 continue; // skip member
2934 }
2935
2936 const clang::Type* memNonPtrType = memType;
2937 Bool_t ispointer = false;
2938 if (memNonPtrType->isPointerType()) {
2939 ispointer = true;
2940 clang::QualType ptrQT
2941 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2942 if (recordType) {
2943 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2944 ptrQT = ROOT::TMetaUtils::ReSubstTemplateArg(ptrQT, recordType);
2945 }
2946 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2947 if (ptrQT.isNull()) {
2948 std::string memberName;
2949 llvm::raw_string_ostream stream(memberName);
2950 // Don't trigger fopen of the source file to count lines:
2951 printPol.AnonymousTagLocations = false;
2952 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2953 stream.flush();
2954 Error("InspectMembers",
2955 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2956 memberName.c_str(), clname);
2957 continue; // skip member
2958 }
2959 memNonPtrType = ptrQT.getTypePtr();
2960 }
2961
2962 // assemble array size(s): "[12][4][]"
2963 llvm::SmallString<8> arraySize;
2964 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2965 unsigned arrLevel = 0;
2966 bool haveErrorDueToArray = false;
2967 while (arrType) {
2968 ++arrLevel;
2969 arraySize += '[';
2970 const clang::ConstantArrayType* constArrType =
2971 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2972 if (constArrType) {
2973 constArrType->getSize().toStringUnsigned(arraySize);
2974 }
2975 arraySize += ']';
2976 clang::QualType subArrQT = arrType->getElementType();
2977 if (subArrQT.isNull()) {
2978 std::string memberName;
2979 llvm::raw_string_ostream stream(memberName);
2980 // Don't trigger fopen of the source file to count lines:
2981 printPol.AnonymousTagLocations = false;
2982 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2983 stream.flush();
2984 Error("InspectMembers",
2985 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
2986 arrLevel, subArrQT.getAsString(printPol).c_str(),
2987 memberName.c_str(), clname);
2988 haveErrorDueToArray = true;
2989 break;
2990 }
2991 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
2992 }
2993 if (haveErrorDueToArray) {
2994 continue; // skip member
2995 }
2996
2997 // construct member name
2998 std::string fieldName;
2999 if (memType->isPointerType()) {
3000 fieldName = "*";
3001 }
3002
3003 // Check if this field has a custom ioname, if not, just use the one of the decl
3004 std::string ioname(iField->getName());
3005 ROOT::TMetaUtils::ExtractAttrPropertyFromName(**iField,"ioname",ioname);
3006 fieldName += ioname;
3007 fieldName += arraySize;
3008
3009 // get member offset
3010 // NOTE currently we do not support bitfield and do not support
3011 // member that are not aligned on 'bit' boundaries.
3012 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
3013 ptrdiff_t fieldOffset = offset.getQuantity();
3014
3015 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fBits[2]", fBits);
3016 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fName", &fName);
3017 // R__insp.InspectMember(fName, "fName.");
3018 // R__insp.Inspect(R__cl, R__insp.GetParent(), "*fClass", &fClass);
3019
3020 // If the class has a custom streamer and the type of the filed is a
3021 // private enum, struct or class, skip it.
3022 if (!insp.IsTreatingNonAccessibleTypes()){
3023 auto iFiledQtype = iField->getType();
3024 if (auto tagDecl = iFiledQtype->getAsTagDecl()){
3025 auto declAccess = tagDecl->getAccess();
3026 if (declAccess == AS_private || declAccess == AS_protected) {
3027 continue;
3028 }
3029 }
3030 }
3031
3032 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
3033
3034 if (!ispointer) {
3035 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
3036 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
3037 // nested objects get an extra call to InspectMember
3038 // R__insp.InspectMember("FileStat_t", (void*)&fFileStat, "fFileStat.", false);
3039 std::string sFieldRecName;
3040 if (!ROOT::TMetaUtils::ExtractAttrPropertyFromName(*fieldRecDecl,"iotype",sFieldRecName)){
3042 clang::QualType(memNonPtrType,0),
3043 *fInterpreter,
3045 }
3046
3047 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
3048 // if we can not find the member (which should not really happen),
3049 // let's consider it transient.
3050 Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();
3051 if (!mbr || !mbr->IsPersistent())
3053 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
3054 (fieldName + '.').c_str(), transient);
3055 if (!mbr || !mbr->IsPersistent())
3057
3058 }
3059 }
3060 } // loop over fields
3061
3062 // inspect bases
3063 // TNamed::ShowMembers(R__insp);
3064 unsigned iNBase = 0;
3065 for (clang::CXXRecordDecl::base_class_const_iterator iBase
3066 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
3067 iBase != eBase; ++iBase, ++iNBase) {
3068 clang::QualType baseQT = iBase->getType();
3069 if (baseQT.isNull()) {
3070 Error("InspectMembers",
3071 "Cannot find QualType for base number %d while inspecting class %s",
3072 iNBase, clname);
3073 continue;
3074 }
3075 const clang::CXXRecordDecl* baseDecl
3076 = baseQT->getAsCXXRecordDecl();
3077 if (!baseDecl) {
3078 Error("InspectMembers",
3079 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
3080 iNBase, clname);
3081 continue;
3082 }
3083 TClass* baseCl=nullptr;
3084 std::string sBaseName;
3085 // Try with the DeclId
3086 std::vector<TClass*> foundClasses;
3087 TClass::GetClass(static_cast<DeclId_t>(baseDecl), foundClasses);
3088 if (foundClasses.size()==1){
3089 baseCl=foundClasses[0];
3090 } else {
3091 // Try with the normalised Name, as a fallback
3092 if (!baseCl){
3094 baseQT,
3095 *fInterpreter,
3097 baseCl = TClass::GetClass(sBaseName.c_str());
3098 }
3099 }
3100
3101 if (!baseCl){
3102 std::string qualNameForDiag;
3103 ROOT::TMetaUtils::GetQualifiedName(qualNameForDiag, *baseDecl);
3104 Error("InspectMembers",
3105 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
3106 continue;
3107 }
3108
3109 int64_t baseOffset;
3110 if (iBase->isVirtual()) {
3112 if (!isTransient) {
3113 Error("InspectMembers",
3114 "Base %s of class %s is virtual but no object provided",
3115 sBaseName.c_str(), clname);
3116 }
3118 } else {
3119 // We have an object to determine the vbase offset.
3120 TClingClassInfo* ci = (TClingClassInfo*)cl->GetClassInfo();
3121 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
3122 if (ci && baseCi) {
3123 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
3124 true /*isDerivedObj*/);
3125 if (baseOffset == -1) {
3126 Error("InspectMembers",
3127 "Error calculating offset of virtual base %s of class %s",
3128 sBaseName.c_str(), clname);
3129 }
3130 } else {
3131 Error("InspectMembers",
3132 "Cannot calculate offset of virtual base %s of class %s",
3133 sBaseName.c_str(), clname);
3134 continue;
3135 }
3136 }
3137 } else {
3138 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
3139 }
3140 // TOFIX: baseCl can be null here!
3141 if (baseCl->IsLoaded()) {
3142 // For loaded class, CallShowMember will (especially for TObject)
3143 // call the virtual ShowMember rather than the class specific version
3144 // resulting in an infinite recursion.
3145 InspectMembers(insp, cobj + baseOffset, baseCl, isTransient);
3146 } else {
3147 baseCl->CallShowMembers(cobj + baseOffset,
3148 insp, isTransient);
3150 } // loop over bases
3151}
3152
3153////////////////////////////////////////////////////////////////////////////////
3154/// Check if constructor exited correctly, ie the instance is in a valid state
3155/// \return true if there is a compiler instance available, false otherwise
3156bool TCling::IsValid() const
3157{
3158 return fInterpreter->getCI() != nullptr;
3159}
3160
3161////////////////////////////////////////////////////////////////////////////////
3162/// Reset the interpreter internal state in case a previous action was not correctly
3163/// terminated.
3164
3167 // No-op there is not equivalent state (to be cleared) in Cling.
3168}
3169
3170////////////////////////////////////////////////////////////////////////////////
3171/// Delete existing temporary values.
3172
3173void TCling::ClearStack()
3174{
3175 // No-op for cling due to cling::Value.
3176}
3177
3178////////////////////////////////////////////////////////////////////////////////
3179/// Declare code to the interpreter, without any of the interpreter actions
3180/// that could trigger a re-interpretation of the code. I.e. make cling
3181/// behave like a compiler: no dynamic lookup, no input wrapping for
3182/// subsequent execution, no automatic provision of declarations but just a
3183/// plain `#include`.
3184/// Returns true on success, false on failure.
3185
3186bool TCling::Declare(const char* code)
3187{
3189
3190 SuspendAutoLoadingRAII autoLoadOff(this);
3191 SuspendAutoParsing autoParseRaii(this);
3192
3193 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
3194 fInterpreter->enableDynamicLookup(false);
3195 bool oldRawInput = fInterpreter->isRawInputEnabled();
3196 fInterpreter->enableRawInput(true);
3197
3198 Bool_t ret = LoadText(code);
3199
3200 fInterpreter->enableRawInput(oldRawInput);
3201 fInterpreter->enableDynamicLookup(oldDynLookup);
3202 return ret;
3203}
3204
3205////////////////////////////////////////////////////////////////////////////////
3206/// It calls a "fantom" method to synchronize user keyboard input
3207/// and ROOT prompt line.
3208
3212}
3213
3214// This static function is a hop of TCling::IsLibraryLoaded, which is taking a lock and calling
3215// into this function. This is because we wanted to avoid a duplication in TCling::IsLoaded, which
3216// was already taking a lock.
3217static Bool_t s_IsLibraryLoaded(const char* libname, cling::Interpreter* fInterpreter)
3218{
3219 // Check shared library.
3220 TString tLibName(libname);
3221 if (gSystem->FindDynamicLibrary(tLibName, kTRUE))
3222 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
3223 return false;
3224}
3225
3226Bool_t TCling::IsLibraryLoaded(const char* libname) const
3227{
3229 return s_IsLibraryLoaded(libname, GetInterpreterImpl());
3230}
3231
3232////////////////////////////////////////////////////////////////////////////////
3233/// Return true if ROOT has cxxmodules pcm for a given library name.
3234// FIXME: We need to be able to support lazy loading of pcm generated by ACLiC.
3235Bool_t TCling::HasPCMForLibrary(const char *libname) const
3236{
3237 llvm::StringRef ModuleName(libname);
3238 ModuleName = llvm::sys::path::stem(ModuleName);
3239 ModuleName.consume_front("lib");
3240
3241 // FIXME: In case when the modulemap is not yet loaded we will return the
3242 // wrong result. Consider a call to HasPCMForLibrary(../test/libEvent.so)
3243 // We will only load the modulemap for libEvent.so after we dlopen libEvent
3244 // which may happen after calling this interface. Maybe we should also check
3245 // if there is a Event.pcm file and a module.modulemap, load it and return
3246 // true.
3247 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
3248 clang::Module *M = moduleMap.findModule(ModuleName);
3249 return M && !M->IsUnimportable && M->getASTFile();
3250}
3251
3252////////////////////////////////////////////////////////////////////////////////
3253/// Return true if the file has already been loaded by cint.
3254/// We will try in this order:
3255/// actual filename
3256/// filename as a path relative to
3257/// the include path
3258/// the shared library path
3259
3260Bool_t TCling::IsLoaded(const char* filename) const
3261{
3263
3264 //FIXME: if we use llvm::sys::fs::make_absolute all this can go away. See
3265 // cling::DynamicLibraryManager.
3266
3267 std::string file_name = filename;
3268 size_t at = std::string::npos;
3269 while ((at = file_name.find("/./")) != std::string::npos)
3270 file_name.replace(at, 3, "/");
3271
3272 std::string filesStr = "";
3273 llvm::raw_string_ostream filesOS(filesStr);
3274 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3275 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
3276 filesOS.flush();
3277
3278 llvm::SmallVector<llvm::StringRef, 100> files;
3279 llvm::StringRef(filesStr).split(files, "\n");
3280
3281 std::set<std::string> fileMap;
3282 llvm::StringRef file_name_ref(file_name);
3283 // Fill fileMap; return early on exact match.
3284 for (llvm::SmallVector<llvm::StringRef, 100>::const_iterator
3285 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
3286 if ((*iF) == file_name_ref) return kTRUE; // exact match
3287 fileMap.insert(iF->str());
3288 }
3289
3290 if (fileMap.empty()) return kFALSE;
3291
3292 // Check MacroPath.
3293 TString sFilename(file_name.c_str());
3294 if (gSystem->FindFile(TROOT::GetMacroPath(), sFilename, kReadPermission)
3295 && fileMap.count(sFilename.Data())) {
3296 return kTRUE;
3297 }
3298
3299 // Check IncludePath.
3300 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
3301 incPath.Append(":").Prepend(" "); // to match " -I" (note leading ' ')
3302 incPath.ReplaceAll(" -I", ":"); // of form :dir1 :dir2:dir3
3303 while (incPath.Index(" :") != -1) {
3304 incPath.ReplaceAll(" :", ":");
3305 }
3306 incPath.Prepend(".:");
3307 sFilename = file_name.c_str();
3308 if (gSystem->FindFile(incPath, sFilename, kReadPermission)
3309 && fileMap.count(sFilename.Data())) {
3310 return kTRUE;
3311 }
3312
3313 // Check shared library.
3314 if (s_IsLibraryLoaded(file_name.c_str(), GetInterpreterImpl()))
3315 return kTRUE;
3316
3317 //FIXME: We must use the cling::Interpreter::lookupFileOrLibrary iface.
3318 clang::ConstSearchDirIterator *CurDir = nullptr;
3319 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
3320 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
3321 auto FE = HS.LookupFile(file_name.c_str(),
3322 clang::SourceLocation(),
3323 /*isAngled*/ false,
3324 /*FromDir*/ nullptr, CurDir,
3325 clang::ArrayRef<std::pair<clang::OptionalFileEntryRef,
3326 clang::DirectoryEntryRef>>(),
3327 /*SearchPath*/ nullptr,
3328 /*RelativePath*/ nullptr,
3329 /*RequestingModule*/ nullptr,
3330 /*SuggestedModule*/ nullptr,
3331 /*IsMapped*/ nullptr,
3332 /*IsFrameworkFound*/ nullptr,
3333 /*SkipCache*/ false,
3334 /*BuildSystemModule*/ false,
3335 /*OpenFile*/ false,
3336 /*CacheFail*/ false);
3337 if (FE) {
3338 // check in the source manager if the file is actually loaded
3339 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3340 // this works only with header (and source) files...
3341 clang::FileID FID = SM.translateFile(*FE);
3342 if (!FID.isInvalid() && FID.getHashValue() == 0)
3343 return kFALSE;
3344 else {
3345 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
3346 if (SLocE.isFile() && !SLocE.getFile().getContentCache().getBufferIfLoaded())
3347 return kFALSE;
3348 if (!FID.isInvalid())
3349 return kTRUE;
3350 }
3351 // ...then check shared library again, but with full path now
3352 sFilename = FE->getName().str();
3353 if (gSystem->FindDynamicLibrary(sFilename, kTRUE)
3354 && fileMap.count(sFilename.Data())) {
3355 return kTRUE;
3356 }
3357 }
3358 return kFALSE;
3359}
3360
3361
3362#if defined(R__MACOSX)
3363
3364////////////////////////////////////////////////////////////////////////////////
3365/// Check if lib is in the dynamic linker cache, returns true if it is, and if so,
3366/// modifies the library file name parameter `lib` from `/usr/lib/libFOO.dylib`
3367/// to `-lFOO` such that it can be passed to the linker.
3368/// This is a unique feature of macOS 11.
3369
3370static bool R__UpdateLibFileForLinking(TString &lib)
3371{
3372 const char *mapfile = nullptr;
3373#if __x86_64__
3374 mapfile = "/System/Library/dyld/dyld_shared_cache_x86_64.map";
3375#elif __arm64__
3376 mapfile = "/System/Library/dyld/dyld_shared_cache_arm64e.map";
3377#else
3378 #error unsupported architecture
3379#endif
3380 if (std::ifstream cacheMap{mapfile}) {
3381 std::string line;
3382 while (getline(cacheMap, line)) {
3383 if (line.find(lib) != std::string::npos) {
3384 lib.ReplaceAll("/usr/lib/lib","-l");
3385 lib.ReplaceAll(".dylib","");
3386 return true;
3387 }
3388 }
3389 return false;
3390 }
3391 return false;
3392}
3393#endif // R__MACOSX
3394
3395#if defined (R__LINUX) || defined (R__FBSD)
3396
3397////////////////////////////////////////////////////////////////////////////////
3398/// Callback for dl_iterate_phdr(), see `man dl_iterate_phdr`.
3399/// Collects opened libraries.
3400
3401static int callback_for_dl_iterate_phdr(struct dl_phdr_info *info, size_t size, void *data)
3402{
3403 // This function is called through UpdateListOfLoadedSharedLibraries() which is locked.
3404 static std::unordered_set<decltype(info->dlpi_addr)> sKnownLoadedLibBaseAddrs;
3405
3406 auto newLibs = static_cast<std::vector<std::string>*>(data);
3407 if (!sKnownLoadedLibBaseAddrs.count(info->dlpi_addr)) {
3408 // Skip \0, "", and kernel pseudo-libs linux-vdso.so.1 or linux-gate.so.1
3409 if (info->dlpi_name && info->dlpi_name[0]
3410#if defined(R__FBSD)
3411 //skip the executable (with null addr)
3412 && info->dlpi_addr
3413 //has no path
3414 && strncmp(info->dlpi_name, "[vdso]", 6)
3415 //the linker does not like to be mmapped
3416 //causes a crash in cling::DynamicLibraryManager::loadLibrary())
3417 //with error message "mmap of entire address space failed: Cannot allocate memory"
3418 && strncmp(info->dlpi_name, "/libexec/ld-elf.so.1", 20)
3419#endif
3420 && strncmp(info->dlpi_name, "linux-vdso.so", 13)
3421 && strncmp(info->dlpi_name, "linux-vdso32.so", 15)
3422 && strncmp(info->dlpi_name, "linux-vdso64.so", 15)
3423 && strncmp(info->dlpi_name, "linux-gate.so", 13))
3424 newLibs->emplace_back(info->dlpi_name);
3425 sKnownLoadedLibBaseAddrs.insert(info->dlpi_addr);
3426 }
3427 // No matter what the doc says, return != 0 means "stop the iteration".
3428 return 0;
3430
3431#endif // R__LINUX || R__FBSD
3432
3433
3434////////////////////////////////////////////////////////////////////////////////
3435
3437{
3438#if defined(R__WIN32) || defined(__CYGWIN__)
3439 HMODULE hModules[1024];
3440 void *hProcess;
3441 unsigned long cbModules;
3442 unsigned int i;
3443 hProcess = (void *)::GetCurrentProcess();
3444 ::EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbModules);
3445 // start at 1 to skip the executable itself
3446 for (i = 1; i < (cbModules / sizeof(void *)); i++) {
3447 static const int bufsize = 260;
3448 wchar_t winname[bufsize];
3449 char posixname[bufsize];
3450 ::GetModuleFileNameExW(hProcess, hModules[i], winname, bufsize);
3451#if defined(__CYGWIN__)
3452 cygwin_conv_path(CCP_WIN_W_TO_POSIX, winname, posixname, bufsize);
3453#else
3454 std::wstring wpath = winname;
3455 std::replace(wpath.begin(), wpath.end(), '\\', '/');
3456 string path(wpath.begin(), wpath.end());
3457 strncpy(posixname, path.c_str(), bufsize);
3458#endif
3459 if (!fSharedLibs.Contains(posixname)) {
3460 RegisterLoadedSharedLibrary(posixname);
3461 }
3462 }
3463#elif defined(R__MACOSX)
3464 // fPrevLoadedDynLibInfo stores the *next* image index to look at
3465 uint32_t imageIndex = (uint32_t) (size_t) fPrevLoadedDynLibInfo;
3466
3467 while (const mach_header* mh = _dyld_get_image_header(imageIndex)) {
3468 // Skip non-dylibs
3469 if (mh->filetype == MH_DYLIB) {
3470 if (const char* imageName = _dyld_get_image_name(imageIndex)) {
3471 RegisterLoadedSharedLibrary(imageName);
3472 }
3473 }
3474
3475 ++imageIndex;
3476 }
3477 fPrevLoadedDynLibInfo = (void*)(size_t)imageIndex;
3478#elif defined(R__LINUX) || defined(R__FBSD)
3479 // fPrevLoadedDynLibInfo is unused on Linux.
3481
3482 std::vector<std::string> newLibs;
3483 dl_iterate_phdr(callback_for_dl_iterate_phdr, &newLibs);
3484 for (auto &&lib: newLibs)
3485 RegisterLoadedSharedLibrary(lib.c_str());
3486#else
3487 Error("TCling::UpdateListOfLoadedSharedLibraries",
3488 "Platform not supported!");
3489#endif
3490}
3491
3492namespace {
3493template <int N>
3494static bool StartsWithStrLit(const char *haystack, const char (&needle)[N]) {
3495 return !strncmp(haystack, needle, N - 1);
3496}
3497}
3498
3499////////////////////////////////////////////////////////////////////////////////
3500/// Register that a library was autoloaded either to provide a 'missing' symbol
3501/// or to provide a class (see TClass::GetClass and TROOT::LoadClass).
3502void TCling::RegisterAutoLoadedLibrary(const char *libname)
3503{
3504 fAutoLoadedLibraries.insert(libname);
3505}
3506
3507////////////////////////////////////////////////////////////////////////////////
3508/// Register a new shared library name with the interpreter; add it to
3509/// fSharedLibs.
3510
3511void TCling::RegisterLoadedSharedLibrary(const char* filename)
3512{
3513 // Ignore NULL filenames, aka "the process".
3514 if (!filename) return;
3515
3516 // Tell the interpreter that this library is available; all libraries can be
3517 // used to resolve symbols.
3518 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3519 if (!DLM->isLibraryLoaded(filename)) {
3520 DLM->loadLibrary(filename, true /*permanent*/, true /*resolved*/);
3521 }
3522
3523#if defined(R__MACOSX)
3524 // Check that this is not a system library that does not exist on disk.
3525 auto lenFilename = strlen(filename);
3526 auto isInMacOSSystemDir = [](const char *fn) {
3527 return StartsWithStrLit(fn, "/usr/lib/") || StartsWithStrLit(fn, "/System/Library/");
3528 };
3529 if (!strcmp(filename, "cl_kernels") // yepp, no directory
3530
3531 // These we should not link with (e.g. because they forward to .tbd):
3532 || StartsWithStrLit(filename, "/usr/lib/system/")
3533 || StartsWithStrLit(filename, "/usr/lib/libc++")
3534 || StartsWithStrLit(filename, "/System/Library/Frameworks/")
3535 || StartsWithStrLit(filename, "/System/Library/PrivateFrameworks/")
3536 || StartsWithStrLit(filename, "/System/Library/CoreServices/")
3537 || StartsWithStrLit(filename, "/usr/lib/libSystem")
3538 || StartsWithStrLit(filename, "/usr/lib/libstdc++")
3539 || StartsWithStrLit(filename, "/usr/lib/libicucore")
3540 || StartsWithStrLit(filename, "/usr/lib/libbsm")
3541 || StartsWithStrLit(filename, "/usr/lib/libobjc")
3542 || StartsWithStrLit(filename, "/usr/lib/libresolv")
3543 || StartsWithStrLit(filename, "/usr/lib/libauto")
3544 || StartsWithStrLit(filename, "/usr/lib/libcups")
3545 || StartsWithStrLit(filename, "/usr/lib/libDiagnosticMessagesClient")
3546 || StartsWithStrLit(filename, "/usr/lib/liblangid")
3547 || StartsWithStrLit(filename, "/usr/lib/libCRFSuite")
3548 || StartsWithStrLit(filename, "/usr/lib/libpam")
3549 || StartsWithStrLit(filename, "/usr/lib/libOpenScriptingUtil")
3550 || StartsWithStrLit(filename, "/usr/lib/libextension")
3551 || StartsWithStrLit(filename, "/usr/lib/libAudioToolboxUtility")
3552 || StartsWithStrLit(filename, "/usr/lib/liboah")
3553 || StartsWithStrLit(filename, "/usr/lib/libRosetta")
3554 || StartsWithStrLit(filename, "/usr/lib/libCoreEntitlements")
3555 || StartsWithStrLit(filename, "/usr/lib/libssl.")
3556 || StartsWithStrLit(filename, "/usr/lib/libcrypto.")
3557
3558 // The system lib is likely in macOS's blob.
3559 || (isInMacOSSystemDir(filename) && gSystem->AccessPathName(filename))
3560
3561 // "Link against the umbrella framework 'System.framework' instead"
3562 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_kernel")
3563 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_platform")
3564 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_pthread")
3565
3566 // "cannot link directly with dylib/framework, your binary is not an allowed client of
3567 // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
3568 // SDKs/MacOSX.sdk/usr/lib/libAudioToolboxUtility.tbd for architecture x86_64
3569 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4, ".tbd")))
3570 return;
3571 TString sFileName(filename);
3572 R__UpdateLibFileForLinking(sFileName);
3573 filename = sFileName.Data();
3574#elif defined(__CYGWIN__)
3575 // Check that this is not a system library
3576 static const int bufsize = 260;
3577 char posixwindir[bufsize];
3578 char *windir = std::getenv("WINDIR");
3579 if (windir)
3580 cygwin_conv_path(CCP_WIN_A_TO_POSIX, windir, posixwindir, bufsize);
3581 else
3582 snprintf(posixwindir, sizeof(posixwindir), "/Windows/");
3583 if (strstr(filename, posixwindir) ||
3584 strstr(filename, "/usr/bin/cyg"))
3585 return;
3586#elif defined(R__WIN32)
3587 if (strstr(filename, "/Windows/"))
3588 return;
3589#elif defined (R__LINUX)
3590 if (strstr(filename, "/ld-linux")
3591 || strstr(filename, "linux-gnu/")
3592 || strstr(filename, "/libstdc++.")
3593 || strstr(filename, "/libgcc")
3594 || strstr(filename, "/libc.")
3595 || strstr(filename, "/libdl.")
3596 || strstr(filename, "/libm."))
3597 return;
3598#endif
3599 // Update string of available libraries.
3600 if (!fSharedLibs.IsNull()) {
3601 fSharedLibs.Append(" ");
3602 }
3603 fSharedLibs.Append(filename);
3605
3606////////////////////////////////////////////////////////////////////////////////
3607/// Load a library file in cling's memory.
3608/// if 'system' is true, the library is never unloaded.
3609/// Return 0 on success, -1 on failure.
3610
3611Int_t TCling::Load(const char* filename, Bool_t system)
3612{
3613 assert(!IsFromRootCling() && "Trying to load library from rootcling!");
3614
3615 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3617 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3618 std::string canonLib = DLM->lookupLibrary(filename);
3619 cling::DynamicLibraryManager::LoadLibResult res
3620 = cling::DynamicLibraryManager::kLoadLibNotFound;
3621 if (!canonLib.empty()) {
3622 if (system)
3623 res = DLM->loadLibrary(filename, system, true);
3624 else {
3625 // For the non system libs, we'd like to be able to unload them.
3626 // FIXME: Here we lose the information about kLoadLibAlreadyLoaded case.
3627 cling::Interpreter::CompilationResult compRes;
3628 HandleInterpreterException(GetMetaProcessorImpl(), Form(".L %s", canonLib.c_str()), compRes, /*cling::Value*/nullptr);
3629 if (compRes == cling::Interpreter::kSuccess)
3630 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3631 }
3632 }
3633
3634 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3636 }
3637 switch (res) {
3638 case cling::DynamicLibraryManager::kLoadLibSuccess: return 0;
3639 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return 1;
3640 default: break;
3642 return -1;
3643}
3644
3645////////////////////////////////////////////////////////////////////////////////
3646/// Load a macro file in cling's memory.
3647
3648void TCling::LoadMacro(const char* filename, EErrorCode* error)
3650 ProcessLine(Form(".L %s", filename), error);
3651}
3652
3653////////////////////////////////////////////////////////////////////////////////
3654/// Let cling process a command line asynch.
3655
3656Longptr_t TCling::ProcessLineAsynch(const char* line, EErrorCode* error)
3657{
3658 return ProcessLine(line, error);
3659}
3660
3661////////////////////////////////////////////////////////////////////////////////
3662/// Let cling process a command line synchronously, i.e we are waiting
3663/// it will be finished.
3664
3665Longptr_t TCling::ProcessLineSynch(const char* line, EErrorCode* error)
3666{
3668 if (gApplication) {
3669 if (gApplication->IsCmdThread()) {
3670 return ProcessLine(line, error);
3671 }
3672 return 0;
3673 }
3674 return ProcessLine(line, error);
3675}
3676
3677////////////////////////////////////////////////////////////////////////////////
3678/// Directly execute an executable statement (e.g. "func()", "3+5", etc.
3679/// however not declarations, like "Int_t x;").
3680
3681Longptr_t TCling::Calc(const char* line, EErrorCode* error)
3682{
3683#ifdef R__WIN32
3684 // Test on ApplicationImp not being 0 is needed because only at end of
3685 // TApplication ctor the IsLineProcessing flag is set to 0, so before
3686 // we can not use it.
3687 if (gApplication && gApplication->GetApplicationImp()) {
3688 while (gROOT->IsLineProcessing() && !gApplication) {
3689 Warning("Calc", "waiting for cling thread to free");
3690 gSystem->Sleep(500);
3691 }
3692 gROOT->SetLineIsProcessing();
3693 }
3694#endif // R__WIN32
3696 if (error) {
3697 *error = TInterpreter::kNoError;
3698 }
3699 cling::Value valRef;
3700 cling::Interpreter::CompilationResult cr = cling::Interpreter::kFailure;
3701 try {
3702 cr = fInterpreter->evaluate(line, valRef);
3703 }
3704 catch (cling::InterpreterException& ex)
3705 {
3706 Error("Calc", "%s.\n%s", ex.what(), "Evaluation of your expression was aborted.");
3707 ex.diagnose();
3708 cr = cling::Interpreter::kFailure;
3709 }
3710
3711 if (cr != cling::Interpreter::kSuccess) {
3712 // Failure in compilation.
3713 if (error) {
3714 // Note: Yes these codes are weird.
3716 }
3717 return 0L;
3718 }
3719 if (!valRef.isValid()) {
3720 // Failure at runtime.
3721 if (error) {
3722 // Note: Yes these codes are weird.
3723 *error = TInterpreter::kDangerous;
3724 }
3725 return 0L;
3726 }
3727
3728 if (valRef.isVoid()) {
3729 return 0;
3730 }
3731
3732 RegisterTemporary(valRef);
3733#ifdef R__WIN32
3734 if (gApplication && gApplication->GetApplicationImp()) {
3735 gROOT->SetLineHasBeenProcessed();
3736 }
3737#endif // R__WIN32
3738 return valRef.castAs<Longptr_t>();
3739}
3740
3741////////////////////////////////////////////////////////////////////////////////
3742/// Set a getline function to call when input is needed.
3743
3744void TCling::SetGetline(const char * (*getlineFunc)(const char* prompt),
3745 void (*histaddFunc)(const char* line))
3746{
3747 // If cling offers a replacement for G__pause(), it would need to
3748 // also offer a way to customize at least the history recording.
3749
3750#if defined(R__MUST_REVISIT)
3751#if R__MUST_REVISIT(6,2)
3752 Warning("SetGetline","Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3753#endif
3754#endif
3755}
3756
3757////////////////////////////////////////////////////////////////////////////////
3758/// Helper function to increase the internal Cling count of transactions
3759/// that change the AST.
3760
3761Bool_t TCling::HandleNewTransaction(const cling::Transaction &T)
3762{
3764
3765 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3766 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3767 || T.macros_begin() != T.macros_end()
3768 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3770 return true;
3771 }
3772 return false;
3773}
3774
3775////////////////////////////////////////////////////////////////////////////////
3776/// Delete object from cling symbol table so it can not be used anymore.
3777/// cling objects are always on the heap.
3778
3780{
3781 // NOTE: When replacing the mutex by a ReadWrite mutex, we **must**
3782 // put in place the Read/Write part here. Keeping the write lock
3783 // here is 'catasptrophic' for scaling as it means that ALL calls
3784 // to RecursiveRemove will take the write lock and performance
3785 // of many threads trying to access the write lock at the same
3786 // time is relatively bad.
3788 // Note that fgSetOfSpecials is supposed to be updated by TClingCallbacks::tryFindROOTSpecialInternal
3789 // (but isn't at the moment).
3790 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3791 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3792 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3794 DeleteGlobal(obj);
3795 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3796 }
3798}
3799
3800////////////////////////////////////////////////////////////////////////////////
3801/// Pressing Ctrl+C should forward here. In the case where we have had
3802/// continuation requested we must reset it.
3803
3804void TCling::Reset()
3805{
3806 fMetaProcessor->cancelContinuation();
3807 // Reset the Cling state to the state saved by the last call to
3808 // TCling::SaveContext().
3809#if defined(R__MUST_REVISIT)
3810#if R__MUST_REVISIT(6,2)
3812 Warning("Reset","Cling should support the equivalent of scratch_upto(&fDictPos)");
3813#endif
3814#endif
3815}
3816
3817////////////////////////////////////////////////////////////////////////////////
3818/// Reset the Cling state to its initial state.
3819
3820void TCling::ResetAll()
3821{
3822#if defined(R__MUST_REVISIT)
3823#if R__MUST_REVISIT(6,2)
3825 Warning("ResetAll","Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3826#endif
3827#endif
3828}
3830////////////////////////////////////////////////////////////////////////////////
3831/// Reset in Cling the list of global variables to the state saved by the last
3832/// call to TCling::SaveGlobalsContext().
3833///
3834/// Note: Right now, all we do is run the global destructors.
3835
3837{
3839 // TODO:
3840 // Here we should iterate over the transactions (N-3) and revert.
3841 // N-3 because the first three internal to cling.
3842
3843 fInterpreter->runAndRemoveStaticDestructors();
3844}
3845
3846////////////////////////////////////////////////////////////////////////////////
3847/// Reset the Cling 'user' global objects/variables state to the state saved by the last
3848/// call to TCling::SaveGlobalsContext().
3849
3850void TCling::ResetGlobalVar(void* obj)
3851{
3852#if defined(R__MUST_REVISIT)
3853#if R__MUST_REVISIT(6,2)
3855 Warning("ResetGlobalVar","Cling should support the equivalent of resetglobalvar(obj)");
3856#endif
3857#endif
3859
3860////////////////////////////////////////////////////////////////////////////////
3861/// Rewind Cling dictionary to the point where it was before executing
3862/// the current macro. This function is typically called after SEGV or
3863/// ctlr-C after doing a longjmp back to the prompt.
3864
3866{
3867#if defined(R__MUST_REVISIT)
3868#if R__MUST_REVISIT(6,2)
3870 Warning("RewindDictionary","Cling should provide a way to revert transaction similar to rewinddictionary()");
3871#endif
3872#endif
3873}
3874
3875////////////////////////////////////////////////////////////////////////////////
3876/// Delete obj from Cling symbol table so it cannot be accessed anymore.
3877/// Returns 1 in case of success and 0 in case object was not in table.
3878
3879Int_t TCling::DeleteGlobal(void* obj)
3880{
3881#if defined(R__MUST_REVISIT)
3882#if R__MUST_REVISIT(6,2)
3884 Warning("DeleteGlobal","Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3885#endif
3886#endif
3887 return 0;
3888}
3889
3890////////////////////////////////////////////////////////////////////////////////
3891/// Undeclare obj called name.
3892/// Returns 1 in case of success, 0 for failure.
3893
3895{
3896#if defined(R__MUST_REVISIT)
3897#if R__MUST_REVISIT(6,2)
3898 Warning("DeleteVariable","should do more that just reseting the value to zero");
3899#endif
3900#endif
3901
3903 llvm::StringRef srName(name);
3904 const char* unscopedName = name;
3905 llvm::StringRef::size_type posScope = srName.rfind("::");
3906 const clang::DeclContext* declCtx = nullptr;
3907 if (posScope != llvm::StringRef::npos) {
3908 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3909 const clang::Decl* scopeDecl
3910 = lh.findScope(srName.substr(0, posScope),
3911 cling::LookupHelper::WithDiagnostics);
3912 if (!scopeDecl) {
3913 Error("DeleteVariable", "Cannot find enclosing scope for variable %s",
3914 name);
3915 return 0;
3916 }
3917 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3918 if (!declCtx) {
3919 Error("DeleteVariable",
3920 "Enclosing scope for variable %s is not a declaration context",
3921 name);
3922 return 0;
3923 }
3924 unscopedName += posScope + 2;
3925 }
3926 // Could trigger deserialization of decls.
3927 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
3928 clang::NamedDecl* nVarDecl
3929 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3930 if (!nVarDecl) {
3931 Error("DeleteVariable", "Unknown variable %s", name);
3932 return 0;
3933 }
3934 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3935 if (!varDecl) {
3936 Error("DeleteVariable", "Entity %s is not a variable", name);
3937 return 0;
3938 }
3939
3940 clang::QualType qType = varDecl->getType();
3941 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3942 // Cannot set a reference's address to nullptr; the JIT can place it
3943 // into read-only memory (ROOT-7100).
3944 if (type->isPointerType()) {
3945 int** ppInt = (int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
3946 // set pointer to invalid.
3947 if (ppInt) *ppInt = nullptr;
3949 return 1;
3950}
3951
3952////////////////////////////////////////////////////////////////////////////////
3953/// Save the current Cling state.
3954
3956{
3957#if defined(R__MUST_REVISIT)
3958#if R__MUST_REVISIT(6,2)
3960 Warning("SaveContext","Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
3961#endif
3962#endif
3963}
3964
3965////////////////////////////////////////////////////////////////////////////////
3966/// Save the current Cling state of global objects.
3967
3969{
3970#if defined(R__MUST_REVISIT)
3971#if R__MUST_REVISIT(6,2)
3973 Warning("SaveGlobalsContext","Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
3974#endif
3975#endif
3976}
3977
3978////////////////////////////////////////////////////////////////////////////////
3979/// No op: see TClingCallbacks (used to update the list of globals)
3980
3984
3985////////////////////////////////////////////////////////////////////////////////
3986/// No op: see TClingCallbacks (used to update the list of global functions)
3987
3991
3992////////////////////////////////////////////////////////////////////////////////
3993/// No op: see TClingCallbacks (used to update the list of types)
3999////////////////////////////////////////////////////////////////////////////////
4000/// Check in what order the member of a tuple are layout.
4001enum class ETupleOrdering {
4005};
4011};
4014{
4015 Double_t _1;
4016 Int_t _0;
4017};
4018
4020{
4021 std::tuple<int,double> value;
4024
4025 size_t offset0 = ((char*)&(std::get<0>(value))) - ((char*)&value);
4026 size_t offset1 = ((char*)&(std::get<1>(value))) - ((char*)&value);
4027
4028 size_t ascOffset0 = ((char*)&(asc._0)) - ((char*)&asc);
4029 size_t ascOffset1 = ((char*)&(asc._1)) - ((char*)&asc);
4030
4031 size_t desOffset0 = ((char*)&(des._0)) - ((char*)&des);
4032 size_t desOffset1 = ((char*)&(des._1)) - ((char*)&des);
4033
4034 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
4036 } else if (offset0 == desOffset0 && offset1 == desOffset1) {
4038 } else {
4040 }
4041}
4042
4043static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh, Bool_t silent)
4044{
4045 TClassEdit::TSplitType tupleContent(classname);
4046 std::string alternateName = "TEmulatedTuple";
4047 alternateName.append( classname + 5 );
4048
4049 std::string fullname = "ROOT::Internal::" + alternateName;
4050 if (lh.findScope(fullname, cling::LookupHelper::NoDiagnostics,
4051 /*resultType*/nullptr, /* intantiateTemplate= */ false))
4052 return fullname;
4053
4054 {
4055 // Check if we can produce the tuple
4056 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
4057 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
4058 auto deleter = [](TypeInfo_t *type) {
4059 gInterpreter->TypeInfo_Delete(type);
4060 };
4061 std::unique_ptr<TypeInfo_t, decltype(deleter)> type{ gInterpreter->TypeInfo_Factory(), deleter };
4062 while (iter != theEnd) {
4063 gInterpreter->TypeInfo_Init(type.get(), iter->c_str());
4064 if (gInterpreter->TypeInfo_Property(type.get()) & kIsNotReacheable) {
4065 if (!silent)
4066 Error("Load","Could not declare alternate type for %s since %s (or one of its context) is private or protected",
4067 classname, iter->c_str());
4068 return "";
4069 }
4070 ++iter;
4071 }
4072 }
4073
4074 std::string guard_name;
4075 ROOT::TMetaUtils::GetCppName(guard_name,alternateName.c_str());
4076 std::ostringstream guard;
4077 guard << "ROOT_INTERNAL_TEmulated_";
4078 guard << guard_name;
4079
4080 std::ostringstream alternateTuple;
4081 std::ostringstream initializers;
4082
4083 alternateTuple << "#ifndef " << guard.str() << "\n";
4084 alternateTuple << "#define " << guard.str() << "\n";
4085 alternateTuple << "namespace ROOT { namespace Internal {\n";
4086 alternateTuple << "template <class... Types> struct TEmulatedTuple;\n";
4087 alternateTuple << "template <> struct " << alternateName << " {\n";
4088
4089 // This could also be a compile time choice ...
4090 switch(IsTupleAscending()) {
4092 unsigned int nMember = 0;
4093 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
4094 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
4095 auto sep = ':';
4096 while (iter != theEnd) {
4097 alternateTuple << " " << *iter << " _" << nMember << ";\n";
4098 initializers << " " << sep << " _" << nMember << "(std::get<" << nMember << ">(std::forward<Tuple>(t)))\n";
4099 ++iter;
4100 ++nMember;
4101 sep = ',';
4102 }
4103 break;
4104 }
4106 unsigned int nMember = tupleContent.fElements.size() - 3;
4107 auto iter = tupleContent.fElements.rbegin() + 1; // skip the 'stars'.
4108 auto theEnd = tupleContent.fElements.rend() - 1; // Skip the template name (tuple).
4109 auto sep = ':';
4110 while (iter != theEnd) {
4111 alternateTuple << " " << *iter << " _" << nMember << ";\n";
4112 initializers << " " << sep << " _" << nMember << "(std::get<" << nMember << ">(std::forward<Tuple>(t)))\n";
4113 ++iter;
4114 --nMember;
4115 sep = ',';
4116 }
4117 break;
4118 }
4120 Fatal("TCling::SetClassInfo::AlternateTuple",
4121 "Layout of std::tuple on this platform is unexpected.");
4122 break;
4123 }
4124 }
4125
4126 // default constructor
4127 alternateTuple << " TEmulatedTuple() = default;\n";
4128
4129 // constructor from other tuple-like types, like std::tuple
4130 alternateTuple << " template <typename Tuple>\n";
4131 alternateTuple << " TEmulatedTuple(Tuple&& t)\n";
4132 alternateTuple << initializers.str();
4133 alternateTuple << " {}\n";
4134
4135 alternateTuple << "};\n";
4136 alternateTuple << "}}\n";
4137 alternateTuple << "#endif\n";
4138 if (!gCling->Declare(alternateTuple.str().c_str()))
4139 {
4140 // Declare is not silent (yet?), so add an explicit error message
4141 // to indicate the consequence of the syntax errors.
4142 Error("Load","Could not declare %s",alternateName.c_str());
4143 return "";
4144 }
4145 alternateName = "ROOT::Internal::" + alternateName;
4146 return alternateName;
4148
4149////////////////////////////////////////////////////////////////////////////////
4150/// Set pointer to the TClingClassInfo in TClass.
4151/// If 'reload' is true, (attempt to) generate a new ClassInfo even if we
4152/// already have one.
4153
4154void TCling::SetClassInfo(TClass* cl, Bool_t reload, Bool_t silent)
4155{
4156 // We are shutting down, there is no point in reloading, it only triggers
4157 // redundant deserializations.
4158 if (fIsShuttingDown) {
4159 // Remove the decl_id from the DeclIdToTClass map
4160 if (cl->fClassInfo) {
4162 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4163 // Test again as another thread may have set fClassInfo to nullptr.
4164 if (TClinginfo) {
4165 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4166 }
4167 delete TClinginfo;
4168 cl->fClassInfo = nullptr;
4169 }
4170 return;
4171 }
4172
4174 if (cl->fClassInfo && !reload) {
4175 return;
4176 }
4177 //Remove the decl_id from the DeclIdToTClass map
4178 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4179 if (TClinginfo) {
4180 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4181 }
4182 delete TClinginfo;
4183 cl->fClassInfo = nullptr;
4184 std::string name(cl->GetName());
4185
4186 auto SetWithoutClassInfoState = [](TClass *cl)
4187 {
4188 if (cl->fState != TClass::kHasTClassInit) {
4189 if (cl->fStreamerInfo->GetEntries() != 0) {
4191 } else {
4193 }
4194 }
4195 };
4196 // Handle the special case of 'tuple' where we ignore the real implementation
4197 // details and just overlay a 'simpler'/'simplistic' version that is easy
4198 // for the I/O to understand and handle.
4199 if (strncmp(cl->GetName(),"tuple<",std::char_traits<char>::length("tuple<"))==0) {
4200 if (!reload)
4201 name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper(), silent);
4202 if (reload || name.empty()) {
4203 // We could not generate the alternate
4204 SetWithoutClassInfoState(cl);
4205 return;
4206 }
4207 }
4208
4209 bool instantiateTemplate = !cl->TestBit(TClass::kUnloading);
4210 // FIXME: Rather than adding an option to the TClingClassInfo, we should consider combining code
4211 // that is currently in the caller (like SetUnloaded) that disable AutoLoading and AutoParsing and
4212 // code is in the callee (disabling template instantiation) and end up with a more explicit class:
4213 // TClingClassInfoReadOnly.
4214 TClingClassInfo* info = new TClingClassInfo(GetInterpreterImpl(), name.c_str(), instantiateTemplate);
4215 if (!info->IsValid()) {
4216 SetWithoutClassInfoState(cl);
4217 delete info;
4218 return;
4219 }
4220 cl->fClassInfo = (ClassInfo_t*)info; // Note: We are transferring ownership here.
4221 // In case a class contains an external enum, the enum will be seen as a
4222 // class. We must detect this special case and make the class a Zombie.
4223 // Here we assume that a class has at least one method.
4224 // We can NOT call TClass::Property from here, because this method
4225 // assumes that the TClass is well formed to do a lot of information
4226 // caching. The method SetClassInfo (i.e. here) is usually called during
4227 // the building phase of the TClass, hence it is NOT well formed yet.
4228 Bool_t zombieCandidate = kFALSE;
4229 if (
4230 info->IsValid() &&
4231 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
4232 ) {
4233 zombieCandidate = kTRUE;
4234 }
4235 if (!info->IsLoaded()) {
4236 if (info->Property() & (kIsNamespace)) {
4237 // Namespaces can have info but no corresponding CINT dictionary
4238 // because they are auto-created if one of their contained
4239 // classes has a dictionary.
4240 zombieCandidate = kTRUE;
4241 }
4242 // this happens when no dictionary is available
4243 delete info;
4244 cl->fClassInfo = nullptr;
4245 }
4246 if (zombieCandidate && !cl->GetCollectionType()) {
4247 cl->MakeZombie();
4248 }
4249 // If we reach here, the info was valid (See early returns).
4250 if (cl->fState != TClass::kHasTClassInit) {
4251 if (cl->fClassInfo) {
4253 } else {
4254// if (TClassEdit::IsSTLCont(cl->GetName()) {
4255// There will be an emulated collection proxy, is that the same?
4256// cl->fState = TClass::kEmulated;
4257// } else {
4258 if (cl->fStreamerInfo->GetEntries() != 0) {
4260 } else {
4262 }
4263// }
4264 }
4265 }
4266 if (cl->fClassInfo) {
4267 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
4268 }
4269}
4270
4271////////////////////////////////////////////////////////////////////////////////
4272/// Checks if an entity with the specified name is defined in Cling.
4273/// Returns kUnknown if the entity is not defined.
4274/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
4275/// Returns kKnown if the entity is defined.
4276///
4277/// By default, structs, namespaces, classes, enums and unions are looked for.
4278/// If the flag isClassOrNamespaceOnly is true, classes, structs and
4279/// namespaces only are considered. I.e. if the name is an enum or a union,
4280/// the returned value is false.
4281///
4282/// In the case where the class is not loaded and belongs to a namespace
4283/// or is nested, looking for the full class name is outputting a lots of
4284/// (expected) error messages. Currently the only way to avoid this is to
4285/// specifically check that each level of nesting is already loaded.
4286/// In case of templates the idea is that everything between the outer
4287/// '<' and '>' has to be skipped, e.g.: `aap<pippo<noot>::klaas>::a_class`
4288
4290TCling::CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly /* = kFALSE*/)
4291{
4293 static const char *anonEnum = "anonymous enum ";
4294 static const int cmplen = strlen(anonEnum);
4295
4296 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
4297 return kUnknown;
4298 }
4299
4300 // Do not turn on the AutoLoading if it is globally off.
4301 autoload = autoload && IsClassAutoLoadingEnabled();
4302
4303 // Avoid the double search below in case the name is a fundamental type
4304 // or typedef to a fundamental type.
4305 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
4306 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
4307
4308 if (fundType && fundType->GetType() < TVirtualStreamerInfo::kObject
4309 && fundType->GetType() > 0) {
4310 // Fundamental type, no a class.
4311 return kUnknown;
4312 }
4313
4314 // Migrated from within TClass::GetClass
4315 // If we want to know if a class or a namespace with this name exists in the
4316 // interpreter and this is an enum in the type system, before or after loading
4317 // according to the autoload function argument, return kUnknown.
4318 if (isClassOrNamespaceOnly && TEnum::GetEnum(name, autoload ? TEnum::kAutoload : TEnum::kNone))
4319 return kUnknown;
4320
4321 const char *classname = name;
4322
4323 // RAII to suspend and restore auto-loading and auto-parsing based on some external conditions.
4324 class MaybeSuspendAutoLoadParse {
4325 int fStoreAutoLoad = 0;
4326 int fStoreAutoParse = 0;
4327 bool fSuspendedAutoParse = false;
4328 public:
4329 MaybeSuspendAutoLoadParse(int autoload) {
4330 fStoreAutoLoad = ((TCling*)gCling)->SetClassAutoLoading(autoload);
4331 }
4332
4333 void SuspendAutoParsing() {
4334 fSuspendedAutoParse = true;
4335 fStoreAutoParse = ((TCling*)gCling)->SetSuspendAutoParsing(true);
4336 }
4337
4338 ~MaybeSuspendAutoLoadParse() {
4339 if (fSuspendedAutoParse)
4340 ((TCling*)gCling)->SetSuspendAutoParsing(fStoreAutoParse);
4341 ((TCling*)gCling)->SetClassAutoLoading(fStoreAutoLoad);
4342 }
4343 };
4344
4345 MaybeSuspendAutoLoadParse autoLoadParseRAII( autoload );
4346 if (TClassEdit::IsStdPair(classname) || TClassEdit::IsStdPairBase(classname))
4347 autoLoadParseRAII.SuspendAutoParsing();
4348
4349 // First we want to check whether the decl exist, but _without_
4350 // generating any template instantiation. However, the lookup
4351 // still will create a forward declaration of the class template instance
4352 // if it exist. In this case, the return value of findScope will still
4353 // be zero but the type will be initialized.
4354 // Note in the corresponding code in ROOT 5, CINT was not instantiating
4355 // this forward declaration.
4356 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4357 const clang::Type *type = nullptr;
4358 const clang::Decl *decl
4359 = lh.findScope(classname,
4360 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4361 : cling::LookupHelper::NoDiagnostics,
4362 &type, /* intantiateTemplate= */ false );
4363 if (!decl) {
4364 std::string buf = TClassEdit::InsertStd(classname);
4365 decl = lh.findScope(buf,
4366 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4367 : cling::LookupHelper::NoDiagnostics,
4368 &type,false);
4369 }
4370
4371 if (type) {
4372 // If decl==0 and the type is valid, then we have a forward declaration.
4373 if (!decl) {
4374 // If we have a forward declaration for a class template instantiation,
4375 // we want to ignore it if it was produced/induced by the call to
4376 // findScope, however we can not distinguish those from the
4377 // instantiation induce by 'soft' use (and thus also induce by the
4378 // same underlying code paths)
4379 // ['soft' use = use not requiring a complete definition]
4380 // So to reduce the amount of disruption to the existing code we
4381 // would just ignore those for STL collection, for which we really
4382 // need to have the compiled collection proxy (and thus the TClass
4383 // bootstrap).
4384 clang::ClassTemplateSpecializationDecl *tmpltDecl =
4385 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
4386 (type->getAsCXXRecordDecl());
4387 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
4388 // Since the point of instantiation is invalid, we 'guess' that
4389 // the 'instantiation' of the forwarded type appended in
4390 // findscope.
4391 if (ROOT::TMetaUtils::IsSTLCont(*tmpltDecl)) {
4392 // For STL Collection we return kUnknown.
4393 return kUnknown;
4394 }
4395 }
4396 }
4398 if (!tci.IsValid()) {
4399 return kUnknown;
4400 }
4401 auto propertiesMask = isClassOrNamespaceOnly ? kIsClass | kIsStruct | kIsNamespace :
4403
4404 if (tci.Property() & propertiesMask) {
4405 bool hasClassDefInline = false;
4406 if (isClassOrNamespaceOnly) {
4407 // We do not need to check for ClassDefInline when this is called from
4408 // TClass::Init, we only do it for the call from TClass::GetClass.
4409 auto hasDictionary = tci.GetMethod("Dictionary", "", false, nullptr, ROOT::kExactMatch);
4410 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, nullptr, ROOT::kExactMatch);
4411
4412 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
4413 int lineNumber = 0;
4414 bool success = false;
4415 std::tie(success, lineNumber) =
4416 ROOT::TMetaUtils::GetTrivialIntegralReturnValue(implLineFunc.GetAsFunctionDecl(), *fInterpreter);
4417 hasClassDefInline = success && (lineNumber == -1);
4418 }
4419 }
4420
4421 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
4422 // , hasClassDefInline);
4423
4424 // We are now sure that the entry is not in fact an autoload entry.
4425 if (hasClassDefInline)
4426 return kWithClassDefInline;
4427 else
4428 return kKnown;
4429 } else {
4430 // We are now sure that the entry is not in fact an autoload entry.
4431 return kUnknown;
4432 }
4433 }
4434
4435 if (decl)
4436 return kKnown;
4437 else
4438 return kUnknown;
4439
4440 // Setting up iterator part of TClingTypedefInfo is too slow.
4441 // Copy the lookup code instead:
4442 /*
4443 TClingTypedefInfo t(fInterpreter, name);
4444 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
4445 delete[] classname;
4446 return kTRUE;
4447 }
4448 */
4449
4450// const clang::Decl *decl = lh.findScope(name);
4451// if (!decl) {
4452// std::string buf = TClassEdit::InsertStd(name);
4453// decl = lh.findScope(buf);
4454// }
4456// return (decl);
4457}
4458
4459////////////////////////////////////////////////////////////////////////////////
4460/// Return true if there is a class template by the given name ...
4461
4463{
4464 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4465 // Interpreter transaction ahead, needs locking
4467 const clang::Decl *decl
4468 = lh.findClassTemplate(name,
4469 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4470 : cling::LookupHelper::NoDiagnostics);
4471 if (!decl) {
4472 std::string strname = "std::";
4473 strname += name;
4474 decl = lh.findClassTemplate(strname,
4475 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4476 : cling::LookupHelper::NoDiagnostics);
4478 return nullptr != decl;
4479}
4480
4481////////////////////////////////////////////////////////////////////////////////
4482/// Create list of pointers to base class(es) for TClass cl.
4483
4485{
4487 if (cl->fBase) {
4488 return;
4489 }
4490 // Ignore the base class (e.g. `std::_Complex_base` on Windows)
4492 cl->fBase = new TList();
4493 return;
4494 }
4495 TClingClassInfo *tci = (TClingClassInfo *)cl->GetClassInfo();
4496 if (!tci) return;
4497 TClingBaseClassInfo t(GetInterpreterImpl(), tci);
4498 TList *listOfBase = new TList;
4499 while (t.Next()) {
4500 // if name cannot be obtained no use to put in list
4501 if (t.IsValid() && t.Name()) {
4502 TClingBaseClassInfo *a = new TClingBaseClassInfo(t);
4503 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
4504 }
4505 }
4506 // Now that is complete, publish it.
4507 cl->fBase = listOfBase;
4508}
4509
4510////////////////////////////////////////////////////////////////////////////////
4511/// Create list of pointers to enums for TClass cl.
4512
4513void TCling::LoadEnums(TListOfEnums& enumList) const
4514{
4516
4517 const Decl * D;
4518 TClass* cl = enumList.GetClass();
4519 if (cl) {
4520 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4521 }
4522 else {
4523 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4524 }
4525 // Iterate on the decl of the class and get the enums.
4526 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4527 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4528 // Collect all contexts of the namespace.
4529 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4530 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4531 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(), declEnd = allDeclContexts.end();
4532 declIter != declEnd; ++declIter) {
4533 // Iterate on all decls for each context.
4534 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4535 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4536 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4537 // Get name of the enum type.
4538 std::string buf;
4539 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4540 llvm::raw_string_ostream stream(buf);
4541 // Don't trigger fopen of the source file to count lines:
4542 Policy.AnonymousTagLocations = false;
4543 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
4544 stream.flush();
4545 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
4546 if (!buf.empty()) {
4547 const char* name = buf.c_str();
4548 // Add the enum to the list of loaded enums.
4549 enumList.Get(ED, name);
4550 }
4551 }
4552 }
4554 }
4555}
4556
4557////////////////////////////////////////////////////////////////////////////////
4558/// Create list of pointers to function templates for TClass cl.
4559
4561{
4563
4564 const Decl * D;
4565 TListOfFunctionTemplates* funcTempList;
4566 if (cl) {
4567 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4568 funcTempList = (TListOfFunctionTemplates*)cl->GetListOfFunctionTemplates(false);
4569 }
4570 else {
4571 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4572 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4573 }
4574 // Iterate on the decl of the class and get the enums.
4575 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4576 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4577 // Collect all contexts of the namespace.
4578 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4579 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4580 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(),
4581 declEnd = allDeclContexts.end(); declIter != declEnd; ++declIter) {
4582 // Iterate on all decls for each context.
4583 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4584 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4585 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4586 funcTempList->Get(FTD);
4587 }
4588 }
4590 }
4591}
4592
4593////////////////////////////////////////////////////////////////////////////////
4594/// Get the scopes representing using declarations of namespace
4595
4596std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4597{
4598 TClingClassInfo *ci = (TClingClassInfo*)cl;
4599 return ci->GetUsingNamespaces();
4601
4602////////////////////////////////////////////////////////////////////////////////
4603/// Create list of pointers to data members for TClass cl.
4604/// This is now a nop. The creation and updating is handled in
4605/// TListOfDataMembers.
4606
4608{
4610
4611////////////////////////////////////////////////////////////////////////////////
4612/// Create list of pointers to methods for TClass cl.
4613/// This is now a nop. The creation and updating is handled in
4614/// TListOfFunctions.
4615
4616void TCling::CreateListOfMethods(TClass* cl) const
4617{
4619
4620////////////////////////////////////////////////////////////////////////////////
4621/// Update the list of pointers to method for TClass cl
4622/// This is now a nop. The creation and updating is handled in
4623/// TListOfFunctions.
4624
4625void TCling::UpdateListOfMethods(TClass* cl) const
4626{
4628
4629////////////////////////////////////////////////////////////////////////////////
4630/// Update the list of pointers to data members for TClass cl
4631/// This is now a nop. The creation and updating is handled in
4632/// TListOfDataMembers.
4633
4635{
4636}
4637
4638////////////////////////////////////////////////////////////////////////////////
4639/// Create list of pointers to method arguments for TMethod m.
4640
4642{
4644 if (m->fMethodArgs) {
4645 return;
4646 }
4647 TList *arglist = new TList;
4648 TClingMethodArgInfo t(GetInterpreterImpl(), (TClingMethodInfo*)m->fInfo);
4649 while (t.Next()) {
4650 if (t.IsValid()) {
4651 TClingMethodArgInfo* a = new TClingMethodArgInfo(t);
4652 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4653 }
4654 }
4655 m->fMethodArgs = arglist;
4656}
4657
4658////////////////////////////////////////////////////////////////////////////////
4659/// Return whether we are waiting for more input either because the collected
4660/// input contains unbalanced braces or last seen token was a `\` (backslash-newline)
4661
4662Int_t TCling::GetMore() const
4663{
4664 return fMetaProcessor->awaitingMoreInput();
4666
4667////////////////////////////////////////////////////////////////////////////////
4668/// Generate a TClass for the given class.
4669/// Since the caller has already check the ClassInfo, let it give use the
4670/// result (via the value of emulation) rather than recalculate it.
4671
4672TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4673{
4674// For now the following line would lead to the (unwanted) instantiation
4675// of class template. This could/would need to be resurrected only if
4676// we re-introduce so sort of automatic instantiation. However this would
4677// have to include carefull look at the template parameter to avoid
4678// creating instance we can not really use (if the parameter are only forward
4679// declaration or do not have all the necessary interfaces).
4680
4681 // TClingClassInfo tci(fInterpreter, classname);
4682 // if (1 || !tci.IsValid()) {
4683
4684 Version_t version = 1;
4685 if (TClassEdit::IsSTLCont(classname)) {
4686 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4687 }
4689 TClass *cl = new TClass(classname, version, silent);
4690 if (!emulation) {
4691 // Set the class version if the class is versioned.
4692 // Note that we cannot just call CLASS::Class_Version() as we might not have
4693 // an execution engine (when invoked from rootcling).
4694
4695 // Do not call cl->GetClassVersion(), it has side effects!
4696 Version_t oldvers = cl->fClassVersion;
4697 if (oldvers == version && cl->GetClassInfo()) {
4698 // We have a version and it might need an update.
4699 TClingClassInfo* cli = (TClingClassInfo*)cl->GetClassInfo();
4700 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4701 // Namespaces don't have class versions.
4702 return cl;
4703 }
4704 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", nullptr /*poffset*/,
4707 if (!mi.IsValid()) {
4708 if (cl->TestBit(TClass::kIsTObject)) {
4709 Error("GenerateTClass",
4710 "Cannot find %s::Class_Version()! Class version might be wrong.",
4711 cl->GetName());
4712 }
4713 return cl;
4714 }
4715 Version_t newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4716 *fInterpreter);
4717 if (newvers == -1) {
4718 // Didn't manage to determine the class version from the AST.
4719 // Use runtime instead.
4720 if ((mi.Property() & kIsStatic)
4721 && !fInterpreter->isInSyntaxOnlyMode()) {
4722 // This better be a static function.
4723 TClingCallFunc callfunc(GetInterpreterImpl());
4724 callfunc.SetFunc(&mi);
4725 newvers = callfunc.ExecInt(nullptr);
4726 } else {
4727 Error("GenerateTClass",
4728 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4729 cl->GetName());
4730 }
4731 }
4732 if (newvers != oldvers) {
4733 cl->fClassVersion = newvers;
4734 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4735 }
4736 }
4737 }
4738
4739 return cl;
4740
4741// } else {
4742// return GenerateTClass(&tci,silent);
4743// }
4744}
4745
4746#if 0
4747////////////////////////////////////////////////////////////////////////////////
4748
4749static void GenerateTClass_GatherInnerIncludes(cling::Interpreter *interp, TString &includes,TClingClassInfo *info)
4750{
4751 includes += info->FileName();
4752
4753 const clang::ClassTemplateSpecializationDecl *templateCl
4754 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4755 if (templateCl) {
4756 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4757 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4758 if (arg.getKind() == clang::TemplateArgument::Type) {
4759 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4760
4761 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4762 // We really need a header file.
4763 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4764 if (argdecl) {
4765 includes += ";";
4766 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4767 GenerateTClass_GatherInnerIncludes(interp, includes, &subinfo);
4768 } else {
4769 std::string Result;
4770 llvm::raw_string_ostream OS(Result);
4771 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4772 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4773 }
4774 }
4775 }
4776 }
4778}
4779#endif
4780
4781////////////////////////////////////////////////////////////////////////////////
4782/// Generate a TClass for the given class.
4783
4784TClass *TCling::GenerateTClass(ClassInfo_t *classinfo, Bool_t silent /* = kFALSE */)
4785{
4786 TClingClassInfo *info = (TClingClassInfo*)classinfo;
4787 if (!info || !info->IsValid()) {
4788 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4789 return nullptr;
4790 }
4791 // We are in the case where we have AST nodes for this class.
4792 TClass *cl = nullptr;
4793 std::string classname;
4794 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4795 if (TClassEdit::IsSTLCont(classname)) {
4796#if 0
4797 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4798 // We need to build up the list of required headers, by
4799 // looking at each template arguments.
4800 TString includes;
4801 GenerateTClass_GatherInnerIncludes(fInterpreter,includes,info);
4802
4803 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4804 // 0 means success.
4805 cl = TClass::LoadClass(classnam.c_str(), silent);
4806 if (cl == 0) {
4807 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4808 }
4809 }
4810#endif
4811 if (cl == nullptr) {
4812 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4813 cl = new TClass(classinfo, version, nullptr, nullptr, -1, -1, silent);
4814 }
4815 } else {
4816 // For regular class, just create a TClass on the fly ...
4817 // Not quite useful yet, but that what CINT used to do anyway.
4818 cl = new TClass(classinfo, 1, nullptr, nullptr, -1, -1, silent);
4819 }
4820 // Add the new TClass to the map of declid and TClass*.
4821 if (cl) {
4822 TClass::AddClassToDeclIdMap(((TClingClassInfo*)classinfo)->GetDeclId(), cl);
4823 }
4824 return cl;
4825}
4826
4827////////////////////////////////////////////////////////////////////////////////
4828/// Generate the dictionary for the C++ classes listed in the first
4829/// argument (in a semi-colon separated list).
4830/// 'includes' contains a semi-colon separated list of file to
4831/// `#include` in the dictionary.
4832/// For example:
4833/// ~~~ {.cpp}
4834/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4835/// ~~~
4836/// or
4837/// ~~~ {.cpp}
4838/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4839/// ~~~
4840
4841Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4842{
4843 if (classes == nullptr || classes[0] == 0) {
4844 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4845 return 0;
4846 }
4847 // Split the input list
4848 std::vector<std::string> listClasses;
4849 for (
4850 const char* current = classes, *prev = classes;
4851 *current != 0;
4852 ++current
4853 ) {
4854 if (*current == ';') {
4855 listClasses.push_back(std::string(prev, current - prev));
4856 prev = current + 1;
4857 }
4858 else if (*(current + 1) == 0) {
4859 listClasses.push_back(std::string(prev, current + 1 - prev));
4860 prev = current + 1;
4861 }
4862 }
4863 std::vector<std::string> listIncludes;
4864 if (!includes)
4865 includes = "";
4866 for (
4867 const char* current = includes, *prev = includes;
4868 *current != 0;
4869 ++current
4870 ) {
4871 if (*current == ';') {
4872 listIncludes.push_back(std::string(prev, current - prev));
4873 prev = current + 1;
4874 }
4875 else if (*(current + 1) == 0) {
4876 listIncludes.push_back(std::string(prev, current + 1 - prev));
4877 prev = current + 1;
4878 }
4879 }
4880 // Generate the temporary dictionary file
4881 return !TCling_GenerateDictionary(listClasses, listIncludes,
4882 std::vector<std::string>(), std::vector<std::string>());
4883}
4884
4885////////////////////////////////////////////////////////////////////////////////
4886/// Return pointer to cling Decl of global/static variable that is located
4887/// at the address given by addr.
4888
4889TInterpreter::DeclId_t TCling::GetDataMember(ClassInfo_t *opaque_cl, const char *name) const
4890{
4892 DeclId_t d;
4893 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4894
4895 // Could trigger deserialization of decls.
4896 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4897
4898 if (cl) {
4899 d = cl->GetDataMember(name);
4900 // We check if the decl of the data member has an annotation which indicates
4901 // an ioname.
4902 // In case this is true, if the name requested is not the ioname, we
4903 // return 0, as if the member did not exist. In some sense we override
4904 // the information in the TClassInfo instance, isolating the typesystem in
4905 // TClass from the one in the AST.
4906 if (const ValueDecl* decl = (const ValueDecl*) d){
4907 std::string ioName;
4908 bool hasIoName = ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"ioname",ioName);
4909 if (hasIoName && ioName != name) return nullptr;
4910 }
4911 return d;
4912 }
4913 // We are looking up for something on the TU scope.
4914 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
4915 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
4916 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
4917 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
4918 // are only fulfilling ROOT's understanding for a Data Member.
4919 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
4920 // similar as below.
4921 using namespace clang;
4922 Sema& SemaR = fInterpreter->getSema();
4923 DeclarationName DName = &SemaR.Context.Idents.get(name);
4924
4925 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
4926 RedeclarationKind::ForExternalRedeclaration);
4927
4928 cling::utils::Lookup::Named(&SemaR, R);
4929
4930 LookupResult::Filter F = R.makeFilter();
4931 // Filter the data-member looking decls.
4932 while (F.hasNext()) {
4933 NamedDecl *D = F.next();
4934 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) ||
4935 isa<IndirectFieldDecl>(D))
4936 continue;
4937 F.erase();
4938 }
4939 F.done();
4940
4941 if (R.isSingleResult())
4942 return R.getFoundDecl();
4943 return nullptr;
4944}
4945
4946////////////////////////////////////////////////////////////////////////////////
4947/// Return pointer to cling Decl of global/static variable that is located
4948/// at the address given by addr.
4949
4950TInterpreter::DeclId_t TCling::GetEnum(TClass *cl, const char *name) const
4951{
4953
4954 const clang::Decl* possibleEnum = nullptr;
4955 // FInd the context of the decl.
4956 if (cl) {
4958 if (cci) {
4959 const clang::DeclContext* dc = nullptr;
4960 if (const clang::Decl* D = cci->GetDecl()) {
4961 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
4962 dc = dyn_cast<clang::RecordDecl>(D);
4963 }
4964 }
4965 if (dc) {
4966 // If it is a data member enum.
4967 // Could trigger deserialization of decls.
4968 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4969 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
4970 } else {
4971 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
4972 }
4973 }
4974 } else {
4975 // If it is a global enum.
4976 // Could trigger deserialization of decls.
4977 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4978 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
4979 }
4980 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
4981 && isa<clang::EnumDecl>(possibleEnum)) {
4982 return possibleEnum;
4984 return nullptr;
4985}
4986
4987////////////////////////////////////////////////////////////////////////////////
4988/// Return pointer to cling DeclId for a global value
4989
4990TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
4991{
4992 if (!gv) return nullptr;
4993
4994 llvm::StringRef mangled_name = gv->getName();
4995
4996 int err = 0;
4997 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.str().c_str(), err);
4998 if (err) {
4999 if (err == -2) {
5000 // It might simply be an unmangled global name.
5001 DeclId_t d;
5002 TClingClassInfo gcl(GetInterpreterImpl());
5003 d = gcl.GetDataMember(mangled_name.str().c_str());
5004 return d;
5005 }
5006 return nullptr;
5007 }
5008
5009 std::string scopename(demangled_name_c);
5010 free(demangled_name_c);
5011
5012 //
5013 // Separate out the class or namespace part of the
5014 // function name.
5015 //
5016 std::string dataname;
5017
5018 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
5019 scopename.erase(0, sizeof("typeinfo for ")-1);
5020 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
5021 scopename.erase(0, sizeof("vtable for ")-1);
5022 } else {
5023 // See if it is a function
5024 std::string::size_type pos = scopename.rfind('(');
5025 if (pos != std::string::npos) {
5026 return nullptr;
5027 }
5028 // Separate the scope and member name
5029 pos = scopename.rfind(':');
5030 if (pos != std::string::npos) {
5031 if ((pos != 0) && (scopename[pos-1] == ':')) {
5032 dataname = scopename.substr(pos+1);
5033 scopename.erase(pos-1);
5034 }
5035 } else {
5036 scopename.clear();
5037 dataname = scopename;
5038 }
5039 }
5040 //fprintf(stderr, "name: '%s'\n", name.c_str());
5041 // Now we have the class or namespace name, so do the lookup.
5042
5043
5044 DeclId_t d;
5045 if (scopename.size()) {
5046 TClingClassInfo cl(GetInterpreterImpl(), scopename.c_str());
5047 d = cl.GetDataMember(dataname.c_str());
5048 }
5049 else {
5050 TClingClassInfo gcl(GetInterpreterImpl());
5051 d = gcl.GetDataMember(dataname.c_str());
5053 return d;
5054}
5055
5056////////////////////////////////////////////////////////////////////////////////
5057/// NOT IMPLEMENTED.
5058
5060{
5061 Error("GetDataMemberWithValue()", "not implemented");
5062 return nullptr;
5063}
5064
5065////////////////////////////////////////////////////////////////////////////////
5066/// Return pointer to cling DeclId for a data member with a given name.
5067
5069{
5070 // NOT IMPLEMENTED.
5071 Error("GetDataMemberAtAddr()", "not implemented");
5072 return nullptr;
5074
5075////////////////////////////////////////////////////////////////////////////////
5076/// Return the cling mangled name for a method of a class with parameters
5077/// params (params is a string of actual arguments, not formal ones). If the
5078/// class is 0 the global function list will be searched.
5079
5080TString TCling::GetMangledName(TClass* cl, const char* method,
5081 const char* params, Bool_t objectIsConst /* = kFALSE */)
5082{
5085 if (cl) {
5086 Longptr_t offset;
5087 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
5088 &offset);
5089 }
5090 else {
5091 TClingClassInfo gcl(GetInterpreterImpl());
5092 Longptr_t offset;
5093 func.SetFunc(&gcl, method, params, &offset);
5094 }
5095 TClingMethodInfo* mi = (TClingMethodInfo*) func.FactoryMethod();
5096 if (!mi) return "";
5097 TString mangled_name( mi->GetMangledName() );
5098 delete mi;
5099 return mangled_name;
5101
5102////////////////////////////////////////////////////////////////////////////////
5103/// Return the cling mangled name for a method of a class with a certain
5104/// prototype, i.e. "char*,int,float". If the class is 0 the global function
5105/// list will be searched.
5106
5107TString TCling::GetMangledNameWithPrototype(TClass* cl, const char* method,
5108 const char* proto, Bool_t objectIsConst /* = kFALSE */,
5109 EFunctionMatchMode mode /* = kConversionMatch */)
5110{
5112 if (cl) {
5113 return ((TClingClassInfo*)cl->GetClassInfo())->
5114 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
5115 }
5116 TClingClassInfo gcl(GetInterpreterImpl());
5117 return gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
5119
5120////////////////////////////////////////////////////////////////////////////////
5121/// Return pointer to cling interface function for a method of a class with
5122/// parameters params (params is a string of actual arguments, not formal
5123/// ones). If the class is 0 the global function list will be searched.
5124
5125void* TCling::GetInterfaceMethod(TClass* cl, const char* method,
5126 const char* params, Bool_t objectIsConst /* = kFALSE */)
5127{
5130 if (cl) {
5131 Longptr_t offset;
5132 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
5133 &offset);
5134 }
5135 else {
5136 TClingClassInfo gcl(GetInterpreterImpl());
5137 Longptr_t offset;
5138 func.SetFunc(&gcl, method, params, &offset);
5139 }
5140 return (void*) func.InterfaceMethod();
5141}
5142
5143////////////////////////////////////////////////////////////////////////////////
5144/// Return pointer to cling interface function for a method of a class with
5145/// a certain name.
5146
5147TInterpreter::DeclId_t TCling::GetFunction(ClassInfo_t *opaque_cl, const char* method)
5148{
5150 DeclId_t f;
5151 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5152 if (cl) {
5153 f = cl->GetMethod(method).GetDeclId();
5154 }
5155 else {
5156 TClingClassInfo gcl(GetInterpreterImpl());
5157 f = gcl.GetMethod(method).GetDeclId();
5158 }
5159 return f;
5160
5161}
5162
5163////////////////////////////////////////////////////////////////////////////////
5164/// Insert overloads of name in cl to res.
5165
5166void TCling::GetFunctionOverloads(ClassInfo_t *cl, const char *funcname,
5167 std::vector<DeclId_t>& res) const
5168{
5169 clang::Sema& S = fInterpreter->getSema();
5170 clang::ASTContext& Ctx = S.Context;
5171 const clang::Decl* CtxDecl
5172 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
5173 Ctx.getTranslationUnitDecl();
5174 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
5175 const clang::DeclContext* DeclCtx = RecDecl;
5176
5177 if (!DeclCtx)
5178 DeclCtx = dyn_cast<clang::NamespaceDecl>(CtxDecl);
5179 if (!DeclCtx) return;
5180
5181 clang::DeclarationName DName;
5182 // The DeclarationName is funcname, unless it's a ctor or dtor.
5183 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
5184
5185 if (RecDecl) {
5186 if (RecDecl->getNameAsString() == funcname) {
5187 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5188 DName = Ctx.DeclarationNames.getCXXConstructorName(Ctx.getCanonicalType(QT));
5189 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
5190 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5191 DName = Ctx.DeclarationNames.getCXXDestructorName(Ctx.getCanonicalType(QT));
5192 } else {
5193 DName = &Ctx.Idents.get(funcname);
5194 }
5195 } else {
5196 DName = &Ctx.Idents.get(funcname);
5197 }
5198
5199 // NotForRedeclaration: we want to find names in inline namespaces etc.
5200 clang::LookupResult R(S, DName, clang::SourceLocation(), Sema::LookupOrdinaryName,
5201 RedeclarationKind::NotForRedeclaration);
5202 R.suppressDiagnostics(); // else lookup with NotForRedeclaration will check access etc
5203 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
5204 if (R.empty()) return;
5205 R.resolveKind();
5206 res.reserve(res.size() + (R.end() - R.begin()));
5207 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
5208 IR != ER; ++IR) {
5209 if (const clang::FunctionDecl* FD
5210 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
5211 if (!FD->getDescribedFunctionTemplate()) {
5212 res.push_back(FD);
5213 }
5214 } else if (const auto *USD = llvm::dyn_cast<const clang::UsingShadowDecl>(*IR)) {
5215 // FIXME: multi-level using
5216 if (llvm::isa<clang::FunctionDecl>(USD->getTargetDecl())) {
5217 res.push_back(USD);
5218 }
5219 }
5220 }
5222
5223////////////////////////////////////////////////////////////////////////////////
5224/// Return pointer to cling interface function for a method of a class with
5225/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5226/// function list will be searched.
5227
5228void* TCling::GetInterfaceMethodWithPrototype(TClass* cl, const char* method,
5229 const char* proto,
5230 Bool_t objectIsConst /* = kFALSE */,
5231 EFunctionMatchMode mode /* = kConversionMatch */)
5232{
5234 void* f;
5235 if (cl) {
5236 f = ((TClingClassInfo*)cl->GetClassInfo())->
5237 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5238 }
5239 else {
5240 TClingClassInfo gcl(GetInterpreterImpl());
5241 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5242 }
5243 return f;
5245
5246////////////////////////////////////////////////////////////////////////////////
5247/// Return pointer to cling DeclId for a method of a class with
5248/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5249/// function list will be searched.
5250
5251TInterpreter::DeclId_t TCling::GetFunctionWithValues(ClassInfo_t *opaque_cl, const char* method,
5252 const char* params,
5253 Bool_t objectIsConst /* = kFALSE */)
5254{
5256 DeclId_t f;
5257 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5258 if (cl) {
5259 f = cl->GetMethodWithArgs(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5260 }
5261 else {
5262 TClingClassInfo gcl(GetInterpreterImpl());
5263 f = gcl.GetMethod(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5264 }
5265 return f;
5267
5268////////////////////////////////////////////////////////////////////////////////
5269/// Return pointer to cling interface function for a method of a class with
5270/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5271/// function list will be searched.
5272
5273TInterpreter::DeclId_t TCling::GetFunctionWithPrototype(ClassInfo_t *opaque_cl, const char* method,
5274 const char* proto,
5275 Bool_t objectIsConst /* = kFALSE */,
5276 EFunctionMatchMode mode /* = kConversionMatch */)
5277{
5279 DeclId_t f;
5280 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5281 if (cl) {
5282 f = cl->GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5283 }
5284 else {
5285 TClingClassInfo gcl(GetInterpreterImpl());
5286 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5287 }
5288 return f;
5289}
5290
5291////////////////////////////////////////////////////////////////////////////////
5292/// Return pointer to cling interface function for a method of a class with
5293/// a certain name.
5294
5295TInterpreter::DeclId_t TCling::GetFunctionTemplate(ClassInfo_t *opaque_cl, const char* name)
5296{
5298 DeclId_t f;
5299 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5300 if (cl) {
5301 f = cl->GetFunctionTemplate(name);
5302 }
5303 else {
5304 TClingClassInfo gcl(GetInterpreterImpl());
5305 f = gcl.GetFunctionTemplate(name);
5306 }
5307 return f;
5308
5309}
5310
5311////////////////////////////////////////////////////////////////////////////////
5312/// The 'name' is known to the interpreter, this function returns
5313/// the internal version of this name (usually just resolving typedefs)
5314/// This is used in particular to synchronize between the name used
5315/// by rootcling and by the run-time environment (TClass)
5316/// Return 0 if the name is not known.
5317
5318void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
5319{
5320 output.clear();
5321
5323
5325 if (!cl.IsValid()) {
5326 return ;
5327 }
5328 if (full) {
5329 cl.FullName(output,*fNormalizedCtxt);
5330 return;
5331 }
5332 // Well well well, for backward compatibility we need to act a bit too
5333 // much like CINT.
5335 splitname.ShortType(output, TClassEdit::kDropStd );
5336
5337 return;
5338}
5339
5340////////////////////////////////////////////////////////////////////////////////
5341/// Execute a global function with arguments params.
5342///
5343/// FIXME: The cint-based version of this code does not check if the
5344/// SetFunc() call works, and does not do any real checking
5345/// for errors from the Exec() call. It did fetch the most
5346/// recent cint security error and return that in error, but
5347/// this does not really translate well to cling/clang. We
5348/// should enhance these interfaces so that we can report
5349/// compilation and runtime errors properly.
5350
5351void TCling::Execute(const char* function, const char* params, int* error)
5352{
5354 if (error) {
5355 *error = TInterpreter::kNoError;
5356 }
5358 Longptr_t offset = 0L;
5360 func.SetFunc(&cl, function, params, &offset);
5361 func.Exec(nullptr);
5362}
5363
5364////////////////////////////////////////////////////////////////////////////////
5365/// Execute a method from class cl with arguments params.
5366///
5367/// FIXME: The cint-based version of this code does not check if the
5368/// SetFunc() call works, and does not do any real checking
5369/// for errors from the Exec() call. It did fetch the most
5370/// recent cint security error and return that in error, but
5371/// this does not really translate well to cling/clang. We
5372/// should enhance these interfaces so that we can report
5373/// compilation and runtime errors properly.
5374
5375void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5376 const char* params, Bool_t objectIsConst, int* error)
5377{
5379 if (error) {
5380 *error = TInterpreter::kNoError;
5381 }
5382 // If the actual class of this object inherits 2nd (or more) from TObject,
5383 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5384 // hence gInterpreter->Execute will improperly correct the offset.
5385 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5386 Longptr_t offset = 0L;
5388 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst, &offset);
5389 void* address = (void*)((Longptr_t)addr + offset);
5390 func.Exec(address);
5391}
5392
5393////////////////////////////////////////////////////////////////////////////////
5394
5395void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5396 const char* params, int* error)
5397{
5398 Execute(obj,cl,method,params,false,error);
5399}
5400
5401////////////////////////////////////////////////////////////////////////////////
5402/// Execute a method from class cl with the arguments in array params
5403/// (params[0] ... params[n] = array of TObjString parameters).
5404/// Convert the TObjArray array of TObjString parameters to a character
5405/// string of comma separated parameters.
5406/// The parameters of type 'char' are enclosed in double quotes and all
5407/// internal quotes are escaped.
5408
5409void TCling::Execute(TObject* obj, TClass* cl, TMethod* method,
5410 TObjArray* params, int* error)
5411{
5412 if (!method) {
5413 Error("Execute", "No method was defined");
5414 return;
5415 }
5416 TList* argList = method->GetListOfMethodArgs();
5417 // Check number of actual parameters against of expected formal ones
5418
5419 Int_t nparms = argList->LastIndex() + 1;
5420 Int_t argc = params ? params->GetEntries() : 0;
5421
5422 if (argc > nparms) {
5423 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
5424 return;
5425 }
5426 if (nparms != argc) {
5427 // Let's see if the 'missing' argument are all defaulted.
5428 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
5429 assert(nparms > 0);
5430
5431 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
5432 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5433 // There is a default value for the first missing
5434 // argument, so we are fine.
5435 } else {
5436 Int_t firstDefault = -1;
5437 for (Int_t i = 0; i < nparms; i ++) {
5438 arg = (TMethodArg *) argList->At( i );
5439 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5440 firstDefault = i;
5441 break;
5442 }
5443 }
5444 if (firstDefault >= 0) {
5445 Error("Execute","Too few arguments to call %s, got only %d but expected at least %d and at most %d.",method->GetName(),argc,firstDefault,nparms);
5446 } else {
5447 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
5448 }
5449 return;
5450 }
5451 }
5452
5453 const char* listpar = "";
5454 TString complete(10);
5455 if (params) {
5456 // Create a character string of parameters from TObjArray
5457 TIter next(params);
5458 for (Int_t i = 0; i < argc; i ++) {
5459 TMethodArg* arg = (TMethodArg*) argList->At(i);
5461 TObjString* nxtpar = (TObjString*) next();
5462 if (i) {
5463 complete += ',';
5464 }
5465 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
5466 TString chpar('\"');
5467 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
5468 // At this point we have to check if string contains \\"
5469 // and apply some more sophisticated parser. Not implemented yet!
5470 complete += chpar;
5471 complete += '\"';
5472 }
5473 else {
5474 complete += nxtpar->String();
5475 }
5476 }
5477 listpar = complete.Data();
5478 }
5479
5480 // And now execute it.
5482 if (error) {
5483 *error = TInterpreter::kNoError;
5484 }
5485 // If the actual class of this object inherits 2nd (or more) from TObject,
5486 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5487 // hence gInterpreter->Execute will improperly correct the offset.
5488 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5490 TClingMethodInfo *minfo = (TClingMethodInfo*)method->fInfo;
5491 func.Init(*minfo);
5492 func.SetArgs(listpar);
5493 // Now calculate the 'this' pointer offset for the method
5494 // when starting from the class described by cl.
5495 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetTargetFunctionDecl());
5496 Longptr_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
5497 void* address = (void*)((Longptr_t)addr + offset);
5498 func.Exec(address);
5499}
5500
5501////////////////////////////////////////////////////////////////////////////////
5502
5503void TCling::ExecuteWithArgsAndReturn(TMethod* method, void* address,
5504 const void* args[] /*=0*/,
5505 int nargs /*=0*/,
5506 void* ret/*= 0*/) const
5507{
5508 if (!method) {
5509 Error("ExecuteWithArgsAndReturn", "No method was defined");
5510 return;
5511 }
5512
5513 TClingMethodInfo* minfo = (TClingMethodInfo*) method->fInfo;
5514 TClingCallFunc func(*minfo);
5515 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5516}
5517
5518////////////////////////////////////////////////////////////////////////////////
5519/// Execute a cling macro.
5520
5521Longptr_t TCling::ExecuteMacro(const char* filename, EErrorCode* error)
5522{
5524 fCurExecutingMacros.push_back(filename);
5525 Longptr_t result = TApplication::ExecuteFile(filename, (int*)error);
5526 fCurExecutingMacros.pop_back();
5527 return result;
5528}
5529
5530////////////////////////////////////////////////////////////////////////////////
5531/// Return the file name of the current un-included interpreted file.
5532/// See the documentation for GetCurrentMacroName().
5533
5534const char* TCling::GetTopLevelMacroName() const
5535{
5536 Warning("GetTopLevelMacroName", "Must change return type!");
5537 return fCurExecutingMacros.empty() ? nullptr : fCurExecutingMacros.back();
5538}
5539
5540////////////////////////////////////////////////////////////////////////////////
5541/// Return the file name of the currently interpreted file,
5542/// included or not. Example to illustrate the difference between
5543/// GetCurrentMacroName() and GetTopLevelMacroName():
5544/// ~~~ {.cpp}
5545/// void inclfile() {
5546/// std::cout << "In inclfile.C" << std::endl;
5547/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5548/// TCling::GetCurrentMacroName() << std::endl;
5549/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5550/// TCling::GetTopLevelMacroName() << std::endl;
5551/// }
5552/// ~~~
5553/// ~~~ {.cpp}
5554/// void mymacro() {
5555/// std::cout << "In mymacro.C" << std::endl;
5556/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5557/// TCling::GetCurrentMacroName() << std::endl;
5558/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5559/// TCling::GetTopLevelMacroName() << std::endl;
5560/// std::cout << " Now calling inclfile..." << std::endl;
5561/// gInterpreter->ProcessLine(".x inclfile.C");
5562/// }
5563/// ~~~
5564/// Running mymacro.C will print:
5565///
5566/// ~~~ {.cpp}
5567/// root [0] .x mymacro.C
5568/// ~~~
5569/// In mymacro.C
5570/// ~~~ {.cpp}
5571/// TCling::GetCurrentMacroName() returns ./mymacro.C
5572/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5573/// ~~~
5574/// Now calling inclfile...
5575/// In inclfile.h
5576/// ~~~ {.cpp}
5577/// TCling::GetCurrentMacroName() returns inclfile.C
5578/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5579/// ~~~
5580
5581const char* TCling::GetCurrentMacroName() const
5582{
5583#if defined(R__MUST_REVISIT)
5584#if R__MUST_REVISIT(6,0)
5585 Warning("GetCurrentMacroName", "Must change return type!");
5586#endif
5587#endif
5588 return fCurExecutingMacros.empty() ? nullptr : fCurExecutingMacros.back();
5590
5591////////////////////////////////////////////////////////////////////////////////
5592/// Return the absolute type of typeDesc.
5593/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
5594/// You need to use the result immediately before it is being overwritten.
5595
5596const char* TCling::TypeName(const char* typeDesc)
5597{
5598 TTHREAD_TLS_DECL(std::string,t);
5599
5600 if (!strstr(typeDesc, "(*)(")) {
5601 const char *s = strchr(typeDesc, ' ');
5602 const char *template_start = strchr(typeDesc, '<');
5603 if (!strcmp(typeDesc, "long long")) {
5604 t = typeDesc;
5605 }
5606 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5607 t = typeDesc;
5608 }
5609 // s is the position of the second 'word' (if any)
5610 // except in the case of templates where there will be a space
5611 // just before any closing '>': eg.
5612 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5613 else if (s && (template_start == nullptr || (s < template_start))) {
5614 t = s + 1;
5615 }
5616 else {
5617 t = typeDesc;
5618 }
5619 }
5620 else {
5621 t = typeDesc;
5622 }
5623 auto l = t.length();
5624 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&'))
5625 --l;
5626 t.resize(l);
5627 return t.c_str(); // NOLINT
5628}
5629
5630static bool requiresRootMap(const char* rootmapfile)
5631{
5632 assert(rootmapfile && *rootmapfile);
5633
5634 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5635 libName.consume_back(".rootmap");
5636
5637 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5638}
5640////////////////////////////////////////////////////////////////////////////////
5641/// Read and parse a rootmapfile in its new format, and return 0 in case of
5642/// success, -1 if the file has already been read, and -3 in case its format
5643/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5644/// error.
5645
5646int TCling::ReadRootmapFile(const char *rootmapfile, TUniqueString *uniqueString)
5647{
5648 if (!(rootmapfile && *rootmapfile))
5649 return 0;
5650
5651 if (!requiresRootMap(rootmapfile))
5652 return 0; // success
5653
5654 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5655 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5656
5657 std::string rootmapfileNoBackslash(rootmapfile);
5658#ifdef _MSC_VER
5659 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5660#endif
5661 // Add content of a specific rootmap file
5662 if (fRootmapFiles->FindObject(rootmapfileNoBackslash.c_str()))
5663 return -1;
5664
5665 // Line 1 is `{ decls }`
5666 std::string lineDirective = std::string("\n#line 2 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n";
5667
5668 std::ifstream file(rootmapfileNoBackslash);
5669 std::string line;
5670 line.reserve(200);
5671 std::string lib_name;
5672 line.reserve(100);
5673 bool newFormat = false;
5674 while (getline(file, line, '\n')) {
5675 if (!newFormat && (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5676 file.close();
5677 return -3; // old format
5678 }
5679 newFormat = true;
5680
5681 if (line.compare(0, 9, "{ decls }") == 0) {
5682 // forward declarations
5683
5684 while (getline(file, line, '\n')) {
5685 if (line[0] == '[')
5686 break;
5687 if (!uniqueString) {
5688 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5689 rootmapfileNoBackslash.c_str());
5690 return -4;
5691 }
5692 if (!lineDirective.empty())
5693 uniqueString->Append(lineDirective);
5694 uniqueString->Append(line + '\n');
5695 }
5696 }
5697 const char firstChar = line[0];
5698 if (firstChar == '[') {
5699 // new section (library)
5700 auto brpos = line.find(']');
5701 if (brpos == string::npos)
5702 continue;
5703 lib_name = line.substr(1, brpos - 1);
5704 // Remove spaces at the beginning and at the end of the library name
5705 lib_name.erase(lib_name.find_last_not_of(' ') + 1);
5706 lib_name.erase(0, lib_name.find_first_not_of(' '));
5707 if (gDebug > 3) {
5708 TString lib_nameTstr(lib_name.c_str());
5709 TObjArray *tokens = lib_nameTstr.Tokenize(" ");
5710 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5711 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5712 if (wlib) {
5713 Info("ReadRootmapFile", "%s: New section for %s", rootmapfile, lib_nameTstr.Data());
5714 } else {
5715 Info("ReadRootmapFile", "%s: Section for %s (library does not exist)", rootmapfile, lib_nameTstr.Data());
5716 }
5717 delete[] wlib;
5718 delete tokens;
5719 }
5720 } else {
5721 auto keyLenIt = keyLenMap.find(firstChar);
5722 if (keyLenIt == keyLenMap.end())
5723 continue;
5724 unsigned int keyLen = keyLenIt->second;
5725 // Do not make a copy, just start after the key
5726 const char *keyname = line.c_str() + keyLen;
5727 if (gDebug > 6)
5728 Info("ReadRootmapFile", "%s: class %s in %s", rootmapfile, keyname, lib_name.c_str());
5729 TEnvRec *isThere = fMapfile->Lookup(keyname);
5730 if (isThere) {
5731 if (lib_name != isThere->GetValue()) { // the same key for two different libs
5732 if (firstChar == 'n') {
5733 if (gDebug > 3)
5734 Info("ReadRootmapFile",
5735 "While processing %s, namespace %s was found to be associated to %s although it is already "
5736 "associated to %s",
5737 rootmapfile, keyname, lib_name.c_str(), isThere->GetValue());
5738 } else if (firstChar == 'h') { // it is a header: add the libname to the list of libs to be loaded.
5739 lib_name += " ";
5740 lib_name += isThere->GetValue();
5741 fMapfile->SetValue(keyname, lib_name.c_str());
5742 } else if (!TClassEdit::IsSTLCont(keyname)) {
5743 Warning("ReadRootmapFile",
5744 "While processing %s, %s %s was found to be associated to %s although it is already "
5745 "associated to %s",
5746 rootmapfile, line.substr(0, keyLen - 1).c_str(), keyname, lib_name.c_str(),
5747 isThere->GetValue());
5748 }
5749 } else { // the same key for the same lib
5750 if (gDebug > 3)
5751 Info("ReadRootmapFile", "While processing %s, key %s was found to be already defined for %s",
5752 rootmapfile, keyname, lib_name.c_str());
5753 }
5754 } else {
5755 fMapfile->SetValue(keyname, lib_name.c_str());
5756 }
5757 }
5758 }
5759 file.close();
5760 return 0;
5761}
5762
5763////////////////////////////////////////////////////////////////////////////////
5764/// Create a resource table and read the (possibly) three resource files,
5765/// i.e. `$ROOTSYS/etc/system<name>` (or `ROOTETCDIR/system<name>`), `$HOME/<name>`
5766/// and `$PWD/<name>`. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You
5767/// can read additional user defined resource files by creating additional TEnv
5768/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5769/// the `$HOME/<name>` resource file will be skipped. This might be useful in
5770/// case the home directory resides on an automounted remote file system
5771/// and one wants to avoid the file system from being mounted.
5772
5773void TCling::InitRootmapFile(const char *name)
5774{
5775 assert(requiresRootMap(name) && "We have a module!");
5776
5777 if (!requiresRootMap(name))
5778 return;
5779
5780 Bool_t ignore = fMapfile->IgnoreDuplicates(kFALSE);
5781
5782 fMapfile->SetRcName(name);
5783
5784 TString sname = "system";
5785 sname += name;
5786 TString temp_sname = sname;
5787 const char *s1 = gSystem->PrependPathName(TROOT::GetEtcDir(), temp_sname);
5788
5790 if (ret == -3) // old format
5791 fMapfile->ReadFile(s1, kEnvGlobal);
5792 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5793 TString temp_name = name;
5794 const char *s2 = gSystem->PrependPathName(gSystem->HomeDirectory(), temp_name);
5795 ret = ReadRootmapFile(s2);
5796 if (ret == -3) // old format
5797 fMapfile->ReadFile(s2, kEnvUser);
5798 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
5800 if (ret == -3) // old format
5801 fMapfile->ReadFile(name, kEnvLocal);
5802 }
5803 } else {
5805 if (ret == -3) // old format
5806 fMapfile->ReadFile(name, kEnvLocal);
5807 }
5808 fMapfile->IgnoreDuplicates(ignore);
5809}
5810
5811
5812namespace {
5813 using namespace clang;
5814
5815 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5816 // This class is to be considered an helper for AutoLoading.
5817 // It is a recursive visitor is used to inspect namespaces and specializations
5818 // coming from forward declarations in rootmaps and to set the external visible
5819 // storage flag for them.
5820 public:
5821 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5822 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5823 // We want to enable the external lookup for this namespace
5824 // because it may shadow the lookup of other names contained
5825 // in that namespace
5826
5827 nsDecl->setHasExternalVisibleStorage();
5828 fNSSet.insert(nsDecl);
5829 return true;
5830 }
5831 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl* specDecl) {
5832 // We want to enable the external lookup for this specialization
5833 // because we can provide a definition for it!
5834 if (specDecl->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
5835 //SpecSet.insert(specDecl);
5836 specDecl->setHasExternalLexicalStorage();
5837
5838 // No need to recurse. On the contrary, recursing is actively harmful:
5839 // NOTE: must not recurse to prevent this visitor from triggering loading from
5840 // the external AST source (i.e. autoloading). This would be triggered right here,
5841 // before autoloading is even set up, as rootmap file parsing happens before that.
5842 // Even if autoloading is off and has no effect, triggering loading from external
5843 // AST source resets the flag setHasExternalLexicalStorage(), hiding this specialization
5844 // from subsequent autoloads!
5845 return false;
5846 }
5847 private:
5848 std::unordered_set<const NamespaceDecl*>& fNSSet;
5849 };
5850}
5851
5852////////////////////////////////////////////////////////////////////////////////
5853/// Load map between class and library. If rootmapfile is specified a
5854/// specific rootmap file can be added (typically used by ACLiC).
5855/// In case of error -1 is returned, 0 otherwise.
5856/// The interpreter uses this information to automatically load the shared
5857/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5858
5859Int_t TCling::LoadLibraryMap(const char* rootmapfile)
5860{
5861 if (rootmapfile && *rootmapfile && !requiresRootMap(rootmapfile))
5862 return 0;
5863
5865
5866 // open the [system].rootmap files
5867 if (!fMapfile) {
5868 fMapfile = new TEnv();
5869 fMapfile->IgnoreDuplicates(kTRUE);
5871 fRootmapFiles->SetOwner();
5872 InitRootmapFile(".rootmap");
5873 }
5874
5875 // Prepare a list of all forward declarations for cling
5876 // For some experiments it is easily as big as 500k characters. To be on the
5877 // safe side, we go for 1M.
5878 TUniqueString uniqueString(1048576);
5879
5880 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5881 // A rootmap file must end with the string ".rootmap".
5882 TString ldpath = gSystem->GetDynamicPath();
5883 if (ldpath != fRootmapLoadPath) {
5884 fRootmapLoadPath = ldpath;
5885#ifdef WIN32
5886 TObjArray* paths = ldpath.Tokenize(";");
5887#else
5888 TObjArray* paths = ldpath.Tokenize(":");
5889#endif
5890 TString d;
5891 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5892 d = ((TObjString *)paths->At(i))->GetString();
5893 // check if directory already scanned
5894 Int_t skip = 0;
5895 for (Int_t j = 0; j < i; j++) {
5896 TString pd = ((TObjString *)paths->At(j))->GetString();
5897 if (pd == d) {
5898 skip++;
5899 break;
5900 }
5901 }
5902 if (!skip) {
5903 void* dirp = gSystem->OpenDirectory(d);
5904 if (dirp) {
5905 if (gDebug > 3) {
5906 Info("LoadLibraryMap", "%s", d.Data());
5907 }
5908 const char* f1;
5909 while ((f1 = gSystem->GetDirEntry(dirp))) {
5910 TString f = f1;
5911 if (f.EndsWith(".rootmap")) {
5912 TString p;
5913 p = d + "/" + f;
5914 if (!gSystem->AccessPathName(p, kReadPermission)) {
5915 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
5916 if (gDebug > 4) {
5917 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
5918 }
5919 Int_t ret = ReadRootmapFile(p, &uniqueString);
5920
5921 if (ret == 0)
5922 fRootmapFiles->Add(new TNamed(gSystem->BaseName(f), p.Data()));
5923 if (ret == -3) {
5924 // old format
5925 fMapfile->ReadFile(p, kEnvGlobal);
5926 fRootmapFiles->Add(new TNamed(f, p));
5927 }
5928 }
5929 // else {
5930 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
5931 // fRootmapFiles->FindObject(f)->ls();
5932 // }
5933 }
5934 }
5935 if (f.BeginsWith("rootmap")) {
5936 TString p;
5937 p = d + "/" + f;
5938 FileStat_t stat;
5939 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
5940 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
5941 }
5942 }
5943 }
5944 }
5945 gSystem->FreeDirectory(dirp);
5946 }
5947 }
5948 delete paths;
5949 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
5950 return -1;
5951 }
5952 }
5953 if (rootmapfile && *rootmapfile) {
5954 Int_t res = ReadRootmapFile(rootmapfile, &uniqueString);
5955 if (res == 0) {
5956 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
5957 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
5958 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5959 }
5960 else if (res == -3) {
5961 // old format
5962 Bool_t ignore = fMapfile->IgnoreDuplicates(kFALSE);
5963 fMapfile->ReadFile(rootmapfile, kEnvGlobal);
5964 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5965 fMapfile->IgnoreDuplicates(ignore);
5966 }
5967 }
5968 TEnvRec* rec;
5969 TIter next(fMapfile->GetTable());
5970 while ((rec = (TEnvRec*) next())) {
5971 TString cls = rec->GetName();
5972 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5973 // get the first lib from the list of lib and dependent libs
5974 TString libs = rec->GetValue();
5975 if (libs == "") {
5976 continue;
5977 }
5978 TString delim(" ");
5979 TObjArray* tokens = libs.Tokenize(delim);
5980 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5981 // convert "@@" to "::", we used "@@" because TEnv
5982 // considers "::" a terminator
5983 cls.Remove(0, 8);
5984 cls.ReplaceAll("@@", "::");
5985 // convert "-" to " ", since class names may have
5986 // blanks and TEnv considers a blank a terminator
5987 cls.ReplaceAll("-", " ");
5988 if (gDebug > 6) {
5989 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
5990 if (wlib) {
5991 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
5992 }
5993 else {
5994 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
5995 }
5996 delete[] wlib;
5997 }
5998 delete tokens;
5999 }
6000 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
6001 cls.Remove(0, 8);
6002 // convert "-" to " ", since class names may have
6003 // blanks and TEnv considers a blank a terminator
6004 cls.ReplaceAll("-", " ");
6005 fInterpreter->declare(cls.Data());
6006 }
6007 }
6008
6009 // Process the forward declarations collected
6010 cling::Transaction* T = nullptr;
6011 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
6012 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
6013
6014 if (compRes!=cling::Interpreter::kSuccess){
6015 Warning("LoadLibraryMap",
6016 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
6017 }
6018
6019 if (T) {
6020 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
6021 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
6022 if (declIt->m_DGR.isSingleDecl()) {
6023 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
6024 if (clang::isa<TagDecl>(D) || clang::isa<NamespaceDecl>(D)) {
6025 evsAdder.TraverseDecl(D);
6026 }
6027 }
6028 }
6029 }
6030 }
6031
6032 // clear duplicates
6033
6034 return 0;
6035}
6037////////////////////////////////////////////////////////////////////////////////
6038/// Scan again along the dynamic path for library maps. Entries for the loaded
6039/// shared libraries are unloaded first. This can be useful after reseting
6040/// the dynamic path through TSystem::SetDynamicPath()
6041/// In case of error -1 is returned, 0 otherwise.
6042
6044{
6047 return 0;
6049
6050////////////////////////////////////////////////////////////////////////////////
6051/// Reload the library map entries coming from all the loaded shared libraries,
6052/// after first unloading the current ones.
6053/// In case of error -1 is returned, 0 otherwise.
6054
6056{
6057 const TString sharedLibLStr = GetSharedLibs();
6058 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
6059 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
6060 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
6061 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
6062 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
6063 const Int_t ret = UnloadLibraryMap(sharedLibBaseStr);
6064 if (ret < 0) {
6065 continue;
6066 }
6067 TString rootMapBaseStr = sharedLibBaseStr;
6068 if (sharedLibBaseStr.EndsWith(".dll")) {
6069 rootMapBaseStr.ReplaceAll(".dll", "");
6070 }
6071 else if (sharedLibBaseStr.EndsWith(".DLL")) {
6072 rootMapBaseStr.ReplaceAll(".DLL", "");
6073 }
6074 else if (sharedLibBaseStr.EndsWith(".so")) {
6075 rootMapBaseStr.ReplaceAll(".so", "");
6076 }
6077 else if (sharedLibBaseStr.EndsWith(".sl")) {
6078 rootMapBaseStr.ReplaceAll(".sl", "");
6079 }
6080 else if (sharedLibBaseStr.EndsWith(".dl")) {
6081 rootMapBaseStr.ReplaceAll(".dl", "");
6082 }
6083 else if (sharedLibBaseStr.EndsWith(".a")) {
6084 rootMapBaseStr.ReplaceAll(".a", "");
6085 }
6086 else {
6087 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
6088 delete sharedLibL;
6089 return -1;
6090 }
6091 rootMapBaseStr += ".rootmap";
6092 const char* rootMap = gSystem->Which(gSystem->GetDynamicPath(), rootMapBaseStr);
6093 if (!rootMap) {
6094 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
6095 delete[] rootMap;
6096 delete sharedLibL;
6097 return -1;
6098 }
6099 const Int_t status = LoadLibraryMap(rootMap);
6100 if (status < 0) {
6101 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
6102 delete[] rootMap;
6103 delete sharedLibL;
6104 return -1;
6105 }
6106 delete[] rootMap;
6107 }
6108 delete sharedLibL;
6109 return 0;
6110}
6111
6112////////////////////////////////////////////////////////////////////////////////
6113/// Unload the library map entries coming from all the loaded shared libraries.
6114/// Returns 0 if succesful
6115
6117{
6118 const TString sharedLibLStr = GetSharedLibs();
6119 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
6120 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
6121 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
6122 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
6123 UnloadLibraryMap(sharedLibBaseStr);
6124 }
6125 delete sharedLibL;
6126 return 0;
6128
6129////////////////////////////////////////////////////////////////////////////////
6130/// Unload library map entries coming from the specified library.
6131/// Returns -1 in case no entries for the specified library were found,
6132/// 0 otherwise.
6133
6134Int_t TCling::UnloadLibraryMap(const char* library)
6135{
6136 if (!fMapfile || !library || !*library) {
6137 return 0;
6138 }
6139 TString libname(library);
6140 Ssiz_t idx = libname.Last('.');
6141 if (idx != kNPOS) {
6142 libname.Remove(idx);
6143 }
6144 size_t len = libname.Length();
6145 TEnvRec *rec;
6146 TIter next(fMapfile->GetTable());
6148 Int_t ret = 0;
6149 while ((rec = (TEnvRec *) next())) {
6150 TString cls = rec->GetName();
6151 if (cls.Length() > 2) {
6152 // get the first lib from the list of lib and dependent libs
6153 TString libs = rec->GetValue();
6154 if (libs == "") {
6155 continue;
6156 }
6157 TString delim(" ");
6158 TObjArray* tokens = libs.Tokenize(delim);
6159 const char* lib = ((TObjString *)tokens->At(0))->GetName();
6160 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
6161 // convert "@@" to "::", we used "@@" because TEnv
6162 // considers "::" a terminator
6163 cls.Remove(0, 8);
6164 cls.ReplaceAll("@@", "::");
6165 // convert "-" to " ", since class names may have
6166 // blanks and TEnv considers a blank a terminator
6167 cls.ReplaceAll("-", " ");
6168 }
6169 if (!strncmp(lib, libname.Data(), len)) {
6170 if (fMapfile->GetTable()->Remove(rec) == nullptr) {
6171 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
6172 ret = -1;
6173 }
6174 }
6175 delete tokens;
6176 }
6177 }
6178 if (ret >= 0) {
6179 TString library_rootmap(library);
6180 if (!library_rootmap.EndsWith(".rootmap"))
6181 library_rootmap.Append(".rootmap");
6182 TNamed* mfile = nullptr;
6183 while ((mfile = (TNamed *)fRootmapFiles->FindObject(library_rootmap))) {
6184 fRootmapFiles->Remove(mfile);
6185 delete mfile;
6186 }
6187 fRootmapFiles->Compress();
6188 }
6189 return ret;
6190}
6191
6192////////////////////////////////////////////////////////////////////////////////
6193/// Register the AutoLoading information for a class.
6194/// libs is a space separated list of libraries.
6195
6196Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
6197{
6198 if (!cls || !*cls)
6199 return 0;
6200
6201 TString key = TString("Library.") + cls;
6202 // convert "::" to "@@", we used "@@" because TEnv
6203 // considers "::" a terminator
6204 key.ReplaceAll("::", "@@");
6205 // convert "-" to " ", since class names may have
6206 // blanks and TEnv considers a blank a terminator
6207 key.ReplaceAll(" ", "-");
6208
6210 if (!fMapfile) {
6211 fMapfile = new TEnv();
6213
6216
6217 InitRootmapFile(".rootmap");
6218 }
6219 //fMapfile->SetValue(key, libs);
6220 fMapfile->SetValue(cls, libs);
6221 return 1;
6222}
6223
6224////////////////////////////////////////////////////////////////////////////////
6225/// Demangle the name (from the typeinfo) and then request the class
6226/// via the usual name based interface (TClass::GetClass).
6227
6228TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
6229{
6230 int err = 0;
6231 char* demangled_name = TClassEdit::DemangleTypeIdName(typeinfo, err);
6232 if (err) return nullptr;
6233 TClass* theClass = TClass::GetClass(demangled_name, load, kTRUE);
6234 free(demangled_name);
6235 return theClass;
6236}
6237
6238////////////////////////////////////////////////////////////////////////////////
6239/// Load library containing the specified class. Returns 0 in case of error
6240/// and 1 in case if success.
6241
6242Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
6243{
6244 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6245
6246 int err = 0;
6247 char* demangled_name_c = TClassEdit::DemangleTypeIdName(typeinfo, err);
6248 if (err) {
6249 return 0;
6250 }
6251
6252 std::string demangled_name(demangled_name_c);
6253 free(demangled_name_c);
6254
6255 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
6256 // shortened name.
6257 TClassEdit::TSplitType splitname( demangled_name.c_str(), (TClassEdit::EModType)(TClassEdit::kLong64 | TClassEdit::kDropStd) );
6258 splitname.ShortType(demangled_name, TClassEdit::kDropStlDefault | TClassEdit::kDropStd);
6259
6260 // No need to worry about typedef, they aren't any ... but there are
6261 // inlined namespaces ...
6262
6263 Int_t result = AutoLoad(demangled_name.c_str());
6264 if (result == 0) {
6265 demangled_name = TClassEdit::GetLong64_Name(demangled_name);
6266 result = AutoLoad(demangled_name.c_str(), knowDictNotLoaded);
6268
6269 return result;
6270}
6271
6272////////////////////////////////////////////////////////////////////////////////
6273// Get the list of 'published'/'known' library for the class and load them.
6274Int_t TCling::ShallowAutoLoadImpl(const char *cls)
6275{
6276 Int_t status = 0;
6277
6278 // lookup class to find list of dependent libraries
6279 TString deplibs = gCling->GetClassSharedLibs(cls);
6280 if (!deplibs.IsNull()) {
6281 TString delim(" ");
6282 TObjArray* tokens = deplibs.Tokenize(delim);
6283 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
6284 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
6285 if (gROOT->LoadClass(cls, deplib) == 0) {
6286 if (gDebug > 0) {
6287 gCling->Info("TCling::AutoLoad",
6288 "loaded dependent library %s for %s", deplib, cls);
6289 }
6290 }
6291 else {
6292 gCling->Error("TCling::AutoLoad",
6293 "failure loading dependent library %s for %s",
6294 deplib, cls);
6295 }
6296 }
6297 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6298 if (lib && lib[0]) {
6299 if (gROOT->LoadClass(cls, lib) == 0) {
6300 if (gDebug > 0) {
6301 gCling->Info("TCling::AutoLoad",
6302 "loaded library %s for %s", lib, cls);
6303 }
6304 status = 1;
6305 }
6306 else {
6307 gCling->Error("TCling::AutoLoad",
6308 "failure loading library %s for %s", lib, cls);
6309 }
6310 }
6311 delete tokens;
6312 }
6313
6314 return status;
6316
6317////////////////////////////////////////////////////////////////////////////////
6318// Iterate through the data member of the class (either through the TProtoClass
6319// or through Cling) and trigger, recursively, the loading the necessary libraries.
6320// \note `cls` is expected to be already normalized!
6321// \returns 1 on success.
6322Int_t TCling::DeepAutoLoadImpl(const char *cls, std::unordered_set<std::string> &visited,
6323 bool nameIsNormalized)
6324{
6325 // Try to insert; if insertion failed because the entry existed, DeepAutoLoadImpl()
6326 // has previously (within the same call to `AutoLoad()`) tried to load this class
6327 // and we are done, whether success or not, as it won't work better now than before,
6328 // because there is no additional information now compared to before.
6329 if (!visited.insert(std::string(cls)).second)
6330 return 1;
6331
6332 if (ShallowAutoLoadImpl(cls) == 0) {
6333 // If ShallowAutoLoadImpl() has an error, we have an error.
6334 return 0;
6335 }
6336
6337 // Now look through the TProtoClass to load the required library/dictionary
6338 if (TProtoClass *proto = nameIsNormalized ? TClassTable::GetProtoNorm(cls) : TClassTable::GetProto(cls)) {
6339 for (auto element : proto->GetData()) {
6340 if (element->IsBasic())
6341 continue;
6342 const char *subtypename = element->GetTypeName();
6343 if (!TClassTable::GetDictNorm(subtypename)) {
6344 // Failure to load a dictionary is not (quite) a failure load
6345 // the top-level library. If we return false here, then
6346 // we would end up in a situation where the library and thus
6347 // the dictionary is loaded for "cls" but the TClass is
6348 // not created and/or marked as unavailable (in case where
6349 // AutoLoad is called from TClass::GetClass).
6350 DeepAutoLoadImpl(subtypename, visited, true /*normalized*/);
6351 }
6352 }
6353 return 1;
6354 }
6355
6356 // We found no TProtoClass for cls.
6357 auto classinfo = gInterpreter->ClassInfo_Factory(cls);
6358 if (classinfo && gInterpreter->ClassInfo_IsValid(classinfo)
6359 && !(gInterpreter->ClassInfo_Property(classinfo) & kIsEnum))
6360 {
6361 DataMemberInfo_t *memberinfo = gInterpreter->DataMemberInfo_Factory(classinfo, TDictionary::EMemberSelection::kNoUsingDecls);
6362 while (gInterpreter->DataMemberInfo_Next(memberinfo)) {
6363 if (gInterpreter->DataMemberInfo_TypeProperty(memberinfo) & ::kIsFundamental)
6364 continue;
6365 auto membertypename = TClassEdit::GetLong64_Name(gInterpreter->TypeName(gInterpreter->DataMemberInfo_TypeTrueName(memberinfo)));
6366 if (!TClassTable::GetDictNorm(membertypename.c_str())) {
6367 // Failure to load a dictionary is not (quite) a failure load
6368 // the top-level library. See detailed comment in the TProtoClass
6369 // branch (above).
6370 (void)DeepAutoLoadImpl(membertypename.c_str(), visited, true /*normalized*/);
6371 }
6372 }
6373 gInterpreter->DataMemberInfo_Delete(memberinfo);
6374 }
6375 gInterpreter->ClassInfo_Delete(classinfo);
6376 return 1;
6377}
6378
6379////////////////////////////////////////////////////////////////////////////////
6380/// Load library containing the specified class. Returns 0 in case of error
6381/// and 1 in case if success.
6382
6383Int_t TCling::AutoLoad(const char *cls, Bool_t knowDictNotLoaded /* = kFALSE */)
6384{
6385 // Prevent update to IsClassAutoloading between our check and our actions.
6387
6388 // TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
6389 // rootcling (in *_rdict.pcm file generation) it is a no op.
6390 // FIXME: We should avoid calling autoload when we know we are not supposed
6391 // to and transform this check into an assert.
6393 // Never load any library from rootcling/genreflex.
6394 if (gDebug > 2) {
6395 Info("TCling::AutoLoad", "Explicitly disabled (the class name is %s)", cls);
6396 }
6397 return 0;
6398 }
6399
6400 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6401
6403
6404 if (!knowDictNotLoaded && gClassTable->GetDictNorm(cls)) {
6405 // The library is already loaded as the class's dictionary is known.
6406 // Return success.
6407 // Note: the name (cls) is expected to be normalized as it comes either
6408 // from a callbacks (that can/should calculate the normalized name from the
6409 // decl) or from TClass::GetClass (which does also calculate the normalized
6410 // name).
6411 return 1;
6412 }
6413
6414 if (gDebug > 2) {
6415 Info("TCling::AutoLoad",
6416 "Trying to autoload for %s", cls);
6417 }
6418
6419 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
6420 if (gDebug > 2) {
6421 Info("TCling::AutoLoad",
6422 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
6423 }
6424 return 0;
6425 }
6426 // Prevent the recursion when the library dictionary are loaded.
6427 SuspendAutoLoadingRAII autoLoadOff(this);
6428 // Try using externally provided callback first.
6429 if (fAutoLoadCallBack) {
6430 int success = (*(AutoLoadCallBack_t)fAutoLoadCallBack)(cls);
6431 if (success)
6432 return success;
6433 }
6434
6435 // During the 'Deep' part of the search we will call GetClassSharedLibsForModule
6436 // (when module are enabled) which might end up calling AutoParsing but
6437 // that should only be for the cases where the library has no generated pcm
6438 // and in that case a rootmap should be available.
6439 // This avoids a very costly operation (for generally no gain) but reduce the
6440 // quality of the search (i.e. bad in case of library with no pcm and no rootmap
6441 // file).
6442 TInterpreter::SuspendAutoParsing autoParseRaii(this);
6443 std::unordered_set<std::string> visited;
6444 return DeepAutoLoadImpl(cls, visited, false /*normalized*/);
6445}
6446
6447////////////////////////////////////////////////////////////////////////////////
6448/// Parse the payload or header.
6449
6450static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
6451 Bool_t header,
6452 cling::Interpreter *interpreter)
6453{
6454 std::string code = gNonInterpreterClassDef ;
6455 if (!header) {
6456 // This is the complete header file content and not the
6457 // name of a header.
6458 code += what;
6459
6460 } else {
6461 code += ("#include \"");
6462 code += what;
6463 code += "\"\n";
6464 }
6465 code += ("#ifdef __ROOTCLING__\n"
6466 "#undef __ROOTCLING__\n"
6467 + gInterpreterClassDef +
6468 "#endif");
6469
6470 cling::Interpreter::CompilationResult cr;
6471 {
6472 // scope within which diagnostics are de-activated
6473 // For now we disable diagnostics because we saw them already at
6474 // dictionary generation time. That won't be an issue with the PCMs.
6475
6476 Sema &SemaR = interpreter->getSema();
6477 ROOT::Internal::ParsingStateRAII parsingStateRAII(interpreter->getParser(), SemaR);
6478 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
6479
6480 #if defined(R__MUST_REVISIT)
6481 #if R__MUST_REVISIT(6,2)
6482 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
6483 #endif
6484 #endif
6485
6486 cr = interpreter->parseForModule(code);
6487 }
6488 return cr;
6489}
6490
6491////////////////////////////////////////////////////////////////////////////////
6492/// Helper routine for TCling::AutoParse implementing the actual call to the
6493/// parser and looping over template parameters (if
6494/// any) and when they don't have a registered header to autoparse,
6495/// recurse over their template parameters.
6496///
6497/// Returns the number of header parsed.
6498
6499UInt_t TCling::AutoParseImplRecurse(const char *cls, bool topLevel)
6500{
6501 // We assume the lock has already been taken.
6502 // R__LOCKGUARD(gInterpreterMutex);
6503
6504 Int_t nHheadersParsed = 0;
6505 unsigned long offset = 0;
6506 if (strncmp(cls, "const ", 6) == 0) {
6507 offset = 6;
6508 }
6509
6510 // Loop on the possible autoparse keys
6511 bool skipFirstEntry = false;
6512 std::vector<std::string> autoparseKeys;
6513 if (strchr(cls, '<')) {
6514 int nestedLoc = 0;
6515 TClassEdit::GetSplit(cls + offset, autoparseKeys, nestedLoc, TClassEdit::kDropTrailStar);
6516 // Check if we can skip the name of the template in the autoparses
6517 // Take all the scopes one by one. If all of them are in the AST, we do not
6518 // need to autoparse for that particular template.
6519 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
6520 // autoparseKeys[0] is empty when the input is not a template instance.
6521 // The case strchr(cls, '<') != 0 but still not a template instance can
6522 // happens 'just' for string (GetSplit replaces the template by the short name
6523 // and then use that for thew splitting)
6524 TString templateName(autoparseKeys[0]);
6525 auto tokens = templateName.Tokenize("::");
6526 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
6527 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
6528 if (TClassEdit::IsStdClass(cls + offset))
6529 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
6530 auto nTokens = tokens->GetEntriesFast();
6531 for (Int_t tk = 0; tk < nTokens; ++tk) {
6532 auto scopeObj = tokens->UncheckedAt(tk);
6533 auto scopeName = ((TObjString*) scopeObj)->String().Data();
6534 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
6535 // Check if we have multiple nodes in the AST with this name
6536 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
6537 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
6538 if (!previousScopeAsContext) break; // this is not a context
6539 }
6540 delete tokens;
6541 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
6542 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
6543 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
6544 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
6545 skipFirstEntry = templatedDecl->hasDefinition();
6546 }
6547 }
6548 }
6549
6550 }
6551 }
6552 if (topLevel) autoparseKeys.emplace_back(cls);
6553
6554 for (const auto & apKeyStr : autoparseKeys) {
6555 if (skipFirstEntry) {
6556 skipFirstEntry=false;
6557 continue;
6558 }
6559 if (apKeyStr.empty()) continue;
6560 const char *apKey = apKeyStr.c_str();
6561 std::size_t normNameHash(fStringHashFunction(apKey));
6562 // If the class was not looked up
6563 if (gDebug > 1) {
6564 Info("TCling::AutoParse",
6565 "Starting autoparse for %s\n", apKey);
6566 }
6567 if (fLookedUpClasses.insert(normNameHash).second) {
6568 auto const &iter = fClassesHeadersMap.find(normNameHash);
6569 if (iter != fClassesHeadersMap.end()) {
6570 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
6571 fTransactionHeadersMap.insert({T,normNameHash});
6572 auto const &hNamesPtrs = iter->second;
6573 if (gDebug > 1) {
6574 Info("TCling::AutoParse",
6575 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
6576 }
6577 for (auto & hName : hNamesPtrs) {
6578 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
6579 if (0 != fPayloads.count(normNameHash)) {
6580 float initRSSval=0.f, initVSIZEval=0.f;
6581 (void) initRSSval; // Avoid unused var warning
6582 (void) initVSIZEval;
6583 if (gDebug > 0) {
6584 Info("AutoParse",
6585 "Parsing full payload for %s", apKey);
6586 ProcInfo_t info;
6587 gSystem->GetProcInfo(&info);
6588 initRSSval = 1e-3*info.fMemResident;
6589 initVSIZEval = 1e-3*info.fMemVirtual;
6590 }
6591 auto cRes = ExecAutoParse(hName, kFALSE, GetInterpreterImpl());
6592 if (cRes != cling::Interpreter::kSuccess) {
6593 if (hName[0] == '\n')
6594 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
6595 } else {
6596 fParsedPayloadsAddresses.insert(hName);
6597 nHheadersParsed++;
6598 if (gDebug > 0){
6599 ProcInfo_t info;
6600 gSystem->GetProcInfo(&info);
6601 float endRSSval = 1e-3*info.fMemResident;
6602 float endVSIZEval = 1e-3*info.fMemVirtual;
6603 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6604 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6605 }
6606 }
6607 } else if (!IsLoaded(hName)) {
6608 if (gDebug > 0) {
6609 Info("AutoParse",
6610 "Parsing single header %s", hName);
6611 }
6612 auto cRes = ExecAutoParse(hName, kTRUE, GetInterpreterImpl());
6613 if (cRes != cling::Interpreter::kSuccess) {
6614 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
6615 } else {
6616 nHheadersParsed++;
6617 }
6618 }
6619 }
6620 }
6621 else {
6622 // There is no header registered for this class, if this a
6623 // template, it will be instantiated if/when it is requested
6624 // and if we do no load/parse its components we might end up
6625 // not using an eventual specialization.
6626 if (strchr(apKey, '<')) {
6627 nHheadersParsed += AutoParseImplRecurse(apKey, false);
6628 }
6629 }
6630 }
6631 }
6632
6633 if (nHheadersParsed) {
6634 // Register that we did autoparsing for this class.
6635 fAutoParseClasses.insert(cls);
6636 if (gDebug)
6637 Info("AutoParse", "Parsed %d headers for %s", nHheadersParsed, cls);
6638 }
6639 return nHheadersParsed;
6641}
6642
6643////////////////////////////////////////////////////////////////////////////////
6644/// Parse the headers relative to the class
6645/// Returns 1 in case of success, 0 in case of failure
6646
6647Int_t TCling::AutoParse(const char *cls)
6648{
6649 if (llvm::StringRef(cls).contains("(lambda)"))
6650 return 0;
6651
6654 return AutoLoad(cls);
6655 } else {
6656 return 0;
6657 }
6658 }
6659
6661
6662 if (gDebug > 1) {
6663 Info("TCling::AutoParse",
6664 "Trying to autoparse for %s", cls);
6665 }
6666
6667 // The catalogue of headers is in the dictionary
6668 if (fClingCallbacks->IsAutoLoadingEnabled()
6669 && !gClassTable->GetDictNorm(cls)) {
6670 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
6671 ROOT::Internal::ParsingStateRAII parsingStateRAII(fInterpreter->getParser(),
6672 fInterpreter->getSema());
6673 AutoLoad(cls, true /*knowDictNotLoaded*/);
6674 }
6675
6676 // Prevent the recursion when the library dictionary are loaded.
6677 SuspendAutoLoadingRAII autoLoadOff(this);
6678
6679 // No recursive header parsing on demand; we require headers to be standalone.
6680 SuspendAutoParsing autoParseRAII(this);
6681
6682 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
6683
6686 return nHheadersParsed > 0 ? 1 : 0;
6687}
6688
6689// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6690// Try to solve the problem by AutoLoading. Return true when AutoLoading success, return
6691// false if not.
6692bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6693{
6694 StringRef errMsg(errmessage);
6695 if (errMsg.contains("undefined symbol: ")) {
6696 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6697 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6698 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6699 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6700 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6701 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6702 return true;
6703 } else {
6704 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6705 if ( ((TCling*)gCling)->LazyFunctionCreatorAutoload(errmessage))
6706 return true;
6707 }
6709 return false;
6710}
6711
6712////////////////////////////////////////////////////////////////////////////////
6713/// Autoload a library based on a missing symbol.
6714
6715void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {
6716 std::string dlsym_mangled_name = ROOT::TMetaUtils::DemangleNameForDlsym(mangled_name);
6717
6718 // We have already loaded the library.
6719 if (void* Addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name))
6720 return Addr;
6721
6722 const cling::DynamicLibraryManager &DLM = *GetInterpreterImpl()->getDynamicLibraryManager();
6724
6725 auto LibLoader = [](const std::string& LibName) -> bool {
6726 if (gSystem->Load(LibName.c_str(), "", false) < 0) {
6727 ::Error("TCling__LazyFunctionCreatorAutoloadForModule",
6728 "Failed to load library %s", LibName.c_str());
6729 return false;
6730 }
6731 return true; //success.
6732 };
6733
6734 std::string libName = DLM.searchLibrariesForSymbol(mangled_name,
6735 /*searchSystem=*/ true);
6736
6737 assert(!llvm::StringRef(libName).starts_with("libNew") && "We must not resolve symbols from libNew!");
6738
6739 if (libName.empty())
6740 return nullptr;
6741
6742 if (!LibLoader(libName))
6743 return nullptr;
6745 fAutoLoadedLibraries.insert(libName);
6746 return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name);
6747}
6748
6749////////////////////////////////////////////////////////////////////////////////
6750
6751Bool_t TCling::IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
6753 return fNSFromRootmaps.count(nsDecl) != 0;
6754}
6755
6756////////////////////////////////////////////////////////////////////////////////
6757/// Internal function. Actually do the update of the ClassInfo when seeing
6758// new TagDecl or NamespaceDecl.
6759void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6760{
6761
6763 if (cci) {
6764 // If we only had a forward declaration then update the
6765 // TClingClassInfo with the definition if we have it now.
6766 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6767 if (!oldDef || (def && def != oldDef)) {
6768 cl->ResetCaches();
6770 if (def) {
6771 if (cci->GetType()) {
6772 // It's a tag decl, not a namespace decl.
6773 cci->Init(*cci->GetType());
6775 } else {
6776 Error("RefreshClassInfo", "Should not need to update the classInfo a non type decl: %s", oldDef->getNameAsString().c_str());
6777 }
6778 }
6779 }
6780 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6781 cl->ResetCaches();
6782 if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
6783 // We need to use the Emulated Tuple but we should not trigger parsing
6784 // yet, so delay the creation of the ClassInfo
6785 delete ((TClingClassInfo *)cl->fClassInfo);
6786 cl->fClassInfo = nullptr;
6787 cl->fCanLoadClassInfo = true;
6789 if (cl->fState != TClass::kHasTClassInit) {
6791 }
6792 return;
6793 }
6794 // yes, this is almost a waste of time, but we do need to lookup
6795 // the 'type' corresponding to the TClass anyway in order to
6796 // preserve the opaque typedefs (Double32_t)
6797 if (!alias && def != nullptr)
6798 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), def);
6799 else
6800 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), cl->GetName());
6801 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6802 // We now need to update the state and bits.
6803 if (cl->fState != TClass::kHasTClassInit) {
6804 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6806 }
6807 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6808 } else {
6809 delete ((TClingClassInfo *)cl->fClassInfo);
6810 cl->fClassInfo = nullptr;
6811 }
6812 }
6813}
6814
6815////////////////////////////////////////////////////////////////////////////////
6816/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6817void TCling::UpdateClassInfoWithDecl(const NamedDecl* ND)
6818{
6819 const TagDecl *td = dyn_cast<TagDecl>(ND);
6820 const NamespaceDecl *ns = dyn_cast<NamespaceDecl>(ND);
6821 const NamedDecl *canon = nullptr;
6822
6823 std::string name;
6824 TagDecl* tdDef = nullptr;
6825 if (td) {
6826 canon = tdDef = td->getDefinition();
6827 // Let's pass the decl to the TClass only if it has a definition.
6828 if (!tdDef) return;
6829
6830 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6831 // Ignore incomplete definition.
6832 // Ignore declaration within a function.
6833 return;
6834 }
6835
6836 auto declName = tdDef->getNameAsString();
6837 // Check if we have registered the unqualified name into the list
6838 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6839 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6840 // the unqualified name is sufficient (and the fully qualified name might be
6841 // 'wrong' if there is difference in spelling in the template paramters (for example)
6842 if (!TClass::HasNoInfoOrEmuOrFwdDeclaredDecl(declName.c_str())){
6843 // fprintf (stderr,"WARNING: Impossible to find a TClassEntry in kNoInfo or kEmulated the decl of which would be called %s. Skip w/o building the normalized name.\n",declName.c_str() );
6844 return;
6845 }
6846
6847 clang::QualType type(tdDef->getTypeForDecl(), 0);
6849 } else if (ns) {
6850 canon = ns->getCanonicalDecl();
6851 name = ND->getQualifiedNameAsString();
6852 } else {
6853 name = ND->getQualifiedNameAsString();
6854 }
6855
6856 // Supposedly we are being called while something is being
6857 // loaded ... let's now tell the autoloader to do the work
6858 // yet another time.
6859 SuspendAutoLoadingRAII autoLoadOff(this);
6860 // FIXME: There can be more than one TClass for a single decl.
6861 // for example vector<double> and vector<Double32_t>
6862 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6863 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6864 RefreshClassInfo(cl, canon, false);
6865 }
6866 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6867 // and update them too:
6868 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6869 // RefreshClassInfo(cl, tdDef, true);
6870}
6871
6872////////////////////////////////////////////////////////////////////////////////
6873/// No op: see TClingCallbacks
6875void TCling::UpdateClassInfo(char* item, Long_t tagnum)
6876{
6877}
6878
6879//______________________________________________________________________________
6880//FIXME: Factor out that function in TClass, because TClass does it already twice
6881void TCling::UpdateClassInfoWork(const char* item)
6882{
6883 // This is a no-op as part of the API.
6884 // TCling uses UpdateClassInfoWithDecl() instead.
6885}
6886
6887////////////////////////////////////////////////////////////////////////////////
6888/// Update all canvases at end the terminal input command.
6889
6891{
6892 TIter next(gROOT->GetListOfCanvases());
6893 TVirtualPad* canvas;
6894 while ((canvas = (TVirtualPad*)next())) {
6895 canvas->Update();
6896 }
6897}
6898
6899////////////////////////////////////////////////////////////////////////////////
6900
6901void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6902 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6903
6904 // If the transaction does not contain anything we can return earlier.
6905 if (!HandleNewTransaction(T)) return;
6906
6907 bool isTUTransaction = false;
6908 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
6909 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
6910 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
6911 // The is the first transaction, we have to expose to meta
6912 // what's already in the AST.
6913 isTUTransaction = true;
6914 }
6915 }
6916
6917 std::set<const void*> TransactionDeclSet;
6918 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
6919 const clang::Decl* WrapperFD = T.getWrapperFD();
6920 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6921 I != E; ++I) {
6922 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
6923 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
6924 continue;
6925
6926 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6927 DE = I->m_DGR.end(); DI != DE; ++DI) {
6928 if (*DI == WrapperFD)
6929 continue;
6930 TransactionDeclSet.insert(*DI);
6931 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
6932 }
6933 }
6934 }
6935
6936 // The above might trigger more decls to be deserialized.
6937 // Thus the iteration over the deserialized decls must be last.
6938 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
6939 E = T.deserialized_decls_end(); I != E; ++I) {
6940 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6941 DE = I->m_DGR.end(); DI != DE; ++DI)
6942 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
6943 //FIXME: HandleNewDecl should take DeclGroupRef
6944 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
6945 modifiedTClasses);
6946 }
6947 }
6948
6949
6950 // When fully building the reflection info in TClass, a deserialization
6951 // could be triggered, which may result in request for building the
6952 // reflection info for the same TClass. This in turn will clear the caches
6953 // for the TClass in-flight and cause null ptr derefs.
6954 // FIXME: This is a quick fix, solving most of the issues. The actual
6955 // question is: Shouldn't TClass provide a lock mechanism on update or lock
6956 // itself until the update is done.
6957 //
6958 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
6959 std::vector<TClass*>::iterator it;
6960 it = set_difference(modifiedTClasses.begin(), modifiedTClasses.end(),
6961 ((TCling*)gCling)->GetModTClasses().begin(),
6962 ((TCling*)gCling)->GetModTClasses().end(),
6963 modifiedTClassesDiff.begin());
6964 modifiedTClassesDiff.resize(it - modifiedTClassesDiff.begin());
6965
6966 // Lock the TClass for updates
6967 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
6968 modifiedTClassesDiff.end());
6969 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
6970 E = modifiedTClassesDiff.end(); I != E; ++I) {
6971 // Make sure the TClass has not been deleted.
6972 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
6973 continue;
6974 }
6975 // Could trigger deserialization of decls.
6976 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
6977 // Unlock the TClass for updates
6978 ((TCling*)gCling)->GetModTClasses().erase(*I);
6979
6980 }
6981}
6982
6983///\brief Invalidate stored TCling state for declarations included in transaction `T'.
6984///
6985void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
6986{
6988
6989 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6990 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6991 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6992 (TListOfEnums *)gROOT->GetListOfEnums());
6993
6994 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
6995 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6996 I != E; ++I) {
6997 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
6998 continue;
6999 if (I->m_Call == cling::Transaction::kCCINone) {
7000 UpdateListsOnUnloaded(*(*iNested));
7001 ++iNested;
7002 continue;
7003 }
7004
7005 for (auto &D : I->m_DGR)
7006 InvalidateCachedDecl(Lists, D);
7007 }
7008}
7009
7010///\brief Invalidate cached TCling information for the given global declaration.
7011///
7012void TCling::InvalidateGlobal(const Decl *D) {
7013 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
7014 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
7015 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
7016 (TListOfEnums *)gROOT->GetListOfEnums());
7017 InvalidateCachedDecl(Lists, D);
7018}
7019
7020///\brief Invalidate cached TCling information for the given declaration, and
7021/// removed it from the appropriate object list.
7022///\param[in] Lists - std::tuple<TListOfDataMembers&, TListOfFunctions&,
7023/// TListOfFunctionTemplates&, TListOfEnums&>
7024/// of pointers to the (global/class) object lists.
7025///\param[in] D - Decl to discard.
7026///
7030 TListOfEnums*> &Lists, const Decl *D) {
7031 if (D->isFromASTFile()) // `D' came from the PCH; ignore
7032 return;
7033
7034 TListOfDataMembers &LODM = *(std::get<0>(Lists));
7035 TListOfFunctions &LOF = *(std::get<1>(Lists));
7036 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
7037 TListOfEnums &LOE = *(std::get<3>(Lists));
7038
7039 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D)) {
7040 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
7041 if (LODM.GetClass())
7042 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
7043 else
7044 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
7045 } else if (isa<FunctionDecl>(D)) {
7047 } else if (isa<FunctionTemplateDecl>(D)) {
7049 } else if (isa<EnumDecl>(D)) {
7050 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
7051 if (!E)
7052 return;
7053
7054 // Try to invalidate enumerators (for unscoped enumerations).
7055 for (TIter I = E->GetConstants(); auto EC = (TEnumConstant *)I(); )
7057 (TEnumConstant *)LODM.FindObject(EC->GetName()));
7058
7060 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
7061 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->isCompleteDefinition())
7062 return;
7063
7064 std::vector<TClass *> Classes;
7065 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
7066 return;
7067 for (auto &C : Classes) {
7068 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
7069 (TListOfFunctions *)C->GetListOfMethods(),
7070 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
7071 (TListOfEnums *)C->GetListOfEnums());
7072 for (auto &I : cast<DeclContext>(D)->decls())
7073 InvalidateCachedDecl(Lists, I);
7074
7075 // For NamespaceDecl (redeclarable), only invalidate this redecl.
7076 if (D->getKind() != Decl::Namespace || cast<NamespaceDecl>(D)->isFirstDecl())
7077 C->ResetClassInfo();
7078 }
7080}
7081
7082////////////////////////////////////////////////////////////////////////////////
7083// If an autoparse was done during a transaction and that it is rolled back,
7084// we need to make sure the next request for the same autoparse will be
7085// honored.
7086void TCling::TransactionRollback(const cling::Transaction &T) {
7087 auto const &triter = fTransactionHeadersMap.find(&T);
7088 if (triter != fTransactionHeadersMap.end()) {
7089 std::size_t normNameHash = triter->second;
7090
7091 fLookedUpClasses.erase(normNameHash);
7092
7093 auto const &iter = fClassesHeadersMap.find(normNameHash);
7094 if (iter != fClassesHeadersMap.end()) {
7095 auto const &hNamesPtrs = iter->second;
7096 for (auto &hName : hNamesPtrs) {
7097 if (gDebug > 0) {
7098 Info("TransactionRollback",
7099 "Restoring ability to autoaparse: %s", hName);
7100 }
7101 fParsedPayloadsAddresses.erase(hName);
7103 }
7104 }
7105}
7106
7107////////////////////////////////////////////////////////////////////////////////
7108
7109void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
7110// R__LOCKGUARD_CLING(gInterpreterMutex);
7111// UpdateListOfLoadedSharedLibraries();
7112}
7113
7114////////////////////////////////////////////////////////////////////////////////
7115
7116void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
7118 fSharedLibs = "";
7119}
7120
7121////////////////////////////////////////////////////////////////////////////////
7122/// Return the list of shared libraries loaded into the process.
7123
7125{
7128 return fSharedLibs;
7129}
7130
7131static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH, bool skipCore)
7132{
7133 if (!cls || !*cls)
7134 return {};
7135
7136 using namespace clang;
7137 if (const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
7138 /*type*/ nullptr, /*instantiate*/ false)) {
7139 if (!D->isFromASTFile()) {
7140 if (gDebug > 5)
7141 Warning("GetClassSharedLibsForModule", "Decl found for %s is not part of a module", cls);
7142 return {};
7143 }
7144 class ModuleCollector : public ConstDeclVisitor<ModuleCollector> {
7145 llvm::DenseSet<Module *> &m_TopLevelModules;
7146
7147 public:
7148 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
7149 void Collect(const Decl *D) { Visit(D); }
7150
7151 void VisitDecl(const Decl *D)
7152 {
7153 // FIXME: Such case is described ROOT-7765 where
7154 // ROOT_GENERATE_DICTIONARY does not contain the list of headers.
7155 // They are specified as #includes in the LinkDef file. This leads to
7156 // generation of incomplete modulemap files and this logic fails to
7157 // compute the corresponding module of D.
7158 // FIXME: If we want to support such a case, we should not rely on
7159 // the contents of the modulemap but mangle D and look it up in the
7160 // .so files.
7161 if (!D->hasOwningModule())
7162 return;
7163 if (Module *M = D->getOwningModule()->getTopLevelModule())
7164 m_TopLevelModules.insert(M);
7165 }
7166
7167 void VisitTemplateArgument(const TemplateArgument &TA)
7168 {
7169 switch (TA.getKind()) {
7170 case TemplateArgument::Null:
7171 case TemplateArgument::Integral:
7172 case TemplateArgument::Pack:
7173 case TemplateArgument::NullPtr:
7174 case TemplateArgument::StructuralValue:
7175 case TemplateArgument::Expression:
7176 case TemplateArgument::Template:
7177 case TemplateArgument::TemplateExpansion: return;
7178 case TemplateArgument::Type:
7179 if (const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
7180 return Visit(TagTy->getDecl());
7181 return;
7182 case TemplateArgument::Declaration: return Visit(TA.getAsDecl());
7183 }
7184 llvm_unreachable("Invalid TemplateArgument::Kind!");
7185 }
7186
7187 void VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *CTSD)
7188 {
7189 if (CTSD->getOwningModule())
7190 VisitDecl(CTSD);
7191 else
7192 VisitDecl(CTSD->getSpecializedTemplate());
7193 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
7194 for (const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
7195 VisitTemplateArgument(*Arg);
7196 }
7197 }
7198 };
7199
7200 llvm::DenseSet<Module *> TopLevelModules;
7201 ModuleCollector m(TopLevelModules);
7202 m.Collect(D);
7203 std::string result;
7204 for (auto M : TopLevelModules) {
7205 // ROOT-unaware modules (i.e. not processed by rootcling) do not have a
7206 // link declaration.
7207 if (!M->LinkLibraries.size())
7208 continue;
7209 // We have preloaded the Core module thus libCore.so
7210 if (M->Name == "Core" && skipCore)
7211 continue;
7212 assert(M->LinkLibraries.size() == 1);
7213 if (!result.empty())
7214 result += ' ';
7215 result += M->LinkLibraries[0].Library;
7216 }
7217 return result;
7218 }
7219 return {};
7220}
7221
7222////////////////////////////////////////////////////////////////////////////////
7223/// Get the list of shared libraries containing the code for class cls.
7224/// The first library in the list is the one containing the class, the
7225/// others are the libraries the first one depends on. Returns 0
7226/// in case the library is not found.
7227/// \param cls the name of the class
7228/// \param skipCore if true (default), remove "Core" from the returned list
7229
7230const char* TCling::GetClassSharedLibs(const char* cls, bool skipCore)
7231{
7232 if (fCxxModulesEnabled) {
7233 // Lock the interpreter mutex before interacting with cling.
7234 // TODO: Can we move this further deep? In principle the lock should be in
7235 // GetClassSharedLibsForModule, but it might be needed also for
7236 // getLookupHelper?
7238 llvm::StringRef className = cls;
7239 // If we get a class name containing lambda, we cannot parse it and we
7240 // can exit early.
7241 // FIXME: This works around a bug when we are instantiating a template
7242 // make_unique and the substitution fails. Seen in most of the dataframe
7243 // tests.
7244 if (className.contains("(lambda)"))
7245 return nullptr;
7246 // Limit the recursion which can be induced by GetClassSharedLibsForModule.
7247 SuspendAutoLoadingRAII AutoLoadingDisabled(this);
7248 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
7249 std::string libs = GetClassSharedLibsForModule(cls, LH, skipCore);
7250 if (!libs.empty()) {
7251 fAutoLoadLibStorage.push_back(libs);
7252 return fAutoLoadLibStorage.back().c_str();
7253 }
7254 }
7255
7256 if (!cls || !*cls) {
7257 return nullptr;
7258 }
7259 // lookup class to find list of libraries
7260 if (fMapfile) {
7261 TEnvRec* libs_record = nullptr;
7262 libs_record = fMapfile->Lookup(cls);
7263 if (libs_record) {
7264 const char* libs = libs_record->GetValue();
7265 return (*libs) ? libs : nullptr;
7266 }
7267 else {
7268 // Try the old format...
7269 TString c = TString("Library.") + cls;
7270 // convert "::" to "@@", we used "@@" because TEnv
7271 // considers "::" a terminator
7272 c.ReplaceAll("::", "@@");
7273 // convert "-" to " ", since class names may have
7274 // blanks and TEnv considers a blank a terminator
7275 c.ReplaceAll(" ", "-");
7276 // Use TEnv::Lookup here as the rootmap file must start with Library.
7277 // and do not support using any stars (so we do not need to waste time
7278 // with the search made by TEnv::GetValue).
7279 TEnvRec* libs_record = nullptr;
7280 libs_record = fMapfile->Lookup(c);
7281 if (libs_record) {
7282 const char* libs = libs_record->GetValue();
7283 return (*libs) ? libs : nullptr;
7284 }
7285 }
7286 }
7287 return nullptr;
7288}
7290/// This interface returns a list of dependent libraries in the form:
7291/// lib libA.so libB.so libC.so. The first library is the library we are
7292/// searching dependencies for.
7293/// Note: In order to speed up the search, we display the dependencies of the
7294/// libraries which are not yet loaded. For instance, if libB.so was already
7295/// loaded the list would contain: lib libA.so libC.so.
7296static std::string GetSharedLibImmediateDepsSlow(std::string lib,
7297 cling::Interpreter *interp,
7298 bool skipLoadedLibs = true)
7299{
7300 TString LibFullPath(lib);
7301 if (!llvm::sys::path::is_absolute(lib)) {
7302 if (!gSystem->FindDynamicLibrary(LibFullPath, /*quiet=*/true)) {
7303 Error("TCling__GetSharedLibImmediateDepsSlow", "Cannot find library '%s'", lib.c_str());
7304 return "";
7305 }
7306 } else {
7307 assert(llvm::sys::fs::exists(lib) && "Must exist!");
7308 lib = llvm::sys::path::filename(lib).str();
7309 }
7310
7311 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
7312 if (!ObjF) {
7313 Warning("TCling__GetSharedLibImmediateDepsSlow", "Failed to read object file %s", lib.c_str());
7314 return "";
7315 }
7316
7317 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7318
7319 std::set<string> DedupSet;
7320 std::string Result = lib + ' ';
7321 for (const auto &S : BinObjFile->symbols()) {
7322 uint32_t Flags = llvm::cantFail(S.getFlags());
7323 // Skip defined symbols: we have them.
7324 if (!(Flags & llvm::object::SymbolRef::SF_Undefined))
7325 continue;
7326 // Skip undefined weak symbols: if we don't have them we won't need them.
7327 // `__gmon_start__` being a typical example.
7328 if (Flags & llvm::object::SymbolRef::SF_Weak)
7329 continue;
7330 llvm::Expected<StringRef> SymNameErr = S.getName();
7331 if (!SymNameErr) {
7332 Warning("GetSharedLibDepsForModule", "Failed to read symbol");
7333 continue;
7334 }
7335 llvm::StringRef SymName = SymNameErr.get();
7336 if (SymName.empty())
7337 continue;
7338
7339 if (BinObjFile->isELF()) {
7340 // Skip the symbols which are part of the C/C++ runtime and have a
7341 // fixed library version. See binutils ld VERSION. Those reside in
7342 // 'system' libraries, which we avoid in FindLibraryForSymbol.
7343 if (SymName.contains("@GLIBCXX") || SymName.contains("@CXXABI") ||
7344 SymName.contains("@GLIBC") || SymName.contains("@GCC"))
7345 continue;
7346
7347 // Those are 'weak undefined' symbols produced by gcc. We can
7348 // ignore them.
7349 // FIXME: It is unclear whether we can ignore all weak undefined
7350 // symbols:
7351 // http://lists.llvm.org/pipermail/llvm-dev/2017-October/118177.html
7352 static constexpr llvm::StringRef RegisterClasses("_Jv_RegisterClasses");
7353 static constexpr llvm::StringRef RegisterCloneTable("_ITM_registerTMCloneTable");
7354 static constexpr llvm::StringRef DeregisterCloneTable("_ITM_deregisterTMCloneTable");
7355 if (SymName == RegisterClasses ||
7356 SymName == RegisterCloneTable ||
7357 SymName == DeregisterCloneTable)
7358 continue;
7359 }
7360
7361 // If we can find the address of the symbol, we have loaded it. Skip.
7362 if (skipLoadedLibs) {
7363 std::string SymNameForDlsym = ROOT::TMetaUtils::DemangleNameForDlsym(SymName.str());
7364 if (llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymNameForDlsym))
7365 continue;
7366 }
7367
7369 std::string found = interp->getDynamicLibraryManager()->searchLibrariesForSymbol(SymName, /*searchSystem*/false);
7370 // The expected output is just filename without the full path, which
7371 // is not very accurate, because our Dyld implementation might find
7372 // a match in location a/b/c.so and if we return just c.so ROOT might
7373 // resolve it to y/z/c.so and there we might not be ABI compatible.
7374 // FIXME: Teach the users of GetSharedLibDeps to work with full paths.
7375 if (!found.empty()) {
7376 std::string cand = llvm::sys::path::filename(found).str();
7377 if (!DedupSet.insert(cand).second)
7378 continue;
7379
7380 Result += cand + ' ';
7381 }
7382 }
7383
7384 return Result;
7385}
7386
7387static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
7388{
7389 // Check if we have parsed a rootmap file.
7390 llvm::SmallString<256> rootmapName;
7391 if (!lib.starts_with("lib"))
7392 rootmapName.append("lib");
7393
7394 rootmapName.append(llvm::sys::path::filename(lib));
7395 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7396
7397 if (gCling->GetRootMapFiles()->FindObject(rootmapName.c_str()))
7398 return true;
7399
7400 // Perform a last resort by dropping the lib prefix.
7401 llvm::StringRef rootmapNameNoLib = rootmapName.str();
7402 if (rootmapNameNoLib.consume_front("lib"))
7403 return gCling->GetRootMapFiles()->FindObject(rootmapNameNoLib.data());
7404
7405 return false;
7406}
7407
7408static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
7409{
7410 if (gCling->HasPCMForLibrary(lib.data()))
7411 return true;
7412
7413 return hasParsedRootmapForLibrary(lib);
7414}
7415
7416////////////////////////////////////////////////////////////////////////////////
7417/// Get the list a libraries on which the specified lib depends. The
7418/// returned string contains as first element the lib itself.
7419/// Returns 0 in case the lib does not exist or does not have
7420/// any dependencies. If useDyld is true, we iterate through all available
7421/// libraries and try to construct the dependency chain by resolving each
7422/// symbol.
7423
7424const char* TCling::GetSharedLibDeps(const char* lib, bool useDyld/* = false*/)
7425{
7426 if (llvm::sys::path::is_absolute(lib) && !llvm::sys::fs::exists(lib))
7427 return nullptr;
7428
7429 if (!hasParsedRootmapForLibrary(lib)) {
7430 llvm::SmallString<512> rootmapName(lib);
7431 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7432 if (llvm::sys::fs::exists(rootmapName)) {
7433 if (gDebug > 0)
7434 Info("Load", "loading %s", rootmapName.c_str());
7435 gInterpreter->LoadLibraryMap(rootmapName.c_str());
7436 }
7437 }
7438
7439 if (hasPrecomputedLibraryDeps(lib) && useDyld) {
7440 if (gDebug > 0)
7441 Warning("TCling::GetSharedLibDeps", "Precomputed dependencies available but scanning '%s'", lib);
7442 }
7443
7444 if (useDyld) {
7445 std::string libs = GetSharedLibImmediateDepsSlow(lib, GetInterpreterImpl());
7446 if (!libs.empty()) {
7447 fAutoLoadLibStorage.push_back(libs);
7448 return fAutoLoadLibStorage.back().c_str();
7449 }
7450 }
7451
7452 if (!fMapfile || !lib || !lib[0]) {
7453 return nullptr;
7454 }
7455 TString libname(lib);
7456 Ssiz_t idx = libname.Last('.');
7457 if (idx != kNPOS) {
7458 libname.Remove(idx);
7459 }
7460 TEnvRec* rec;
7461 TIter next(fMapfile->GetTable());
7462 size_t len = libname.Length();
7463 while ((rec = (TEnvRec*) next())) {
7464 const char* libs = rec->GetValue();
7465 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7466 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
7467 return libs;
7468 }
7469 }
7470 return nullptr;
7471}
7472
7473////////////////////////////////////////////////////////////////////////////////
7474/// If error messages are disabled, the interpreter should suppress its
7475/// failures and warning messages from stdout.
7476
7478{
7479#if defined(R__MUST_REVISIT)
7480#if R__MUST_REVISIT(6,2)
7481 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
7482#endif
7483#endif
7484 return kTRUE;
7485}
7486
7487////////////////////////////////////////////////////////////////////////////////
7488/// If error messages are disabled, the interpreter should suppress its
7489/// failures and warning messages from stdout. Return the previous state.
7490
7492{
7493#if defined(R__MUST_REVISIT)
7494#if R__MUST_REVISIT(6,2)
7495 Warning("SetErrorMessages", "Interface not available yet.");
7496#endif
7497#endif
7499}
7500
7501////////////////////////////////////////////////////////////////////////////////
7502/// Refresh the list of include paths known to the interpreter and return it
7503/// with -I prepended.
7504
7505const char* TCling::GetIncludePath()
7506{
7508
7509 fIncludePath = "";
7510
7511 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7512 //false - no system header, true - with flags.
7513 fInterpreter->GetIncludePaths(includePaths, false, true);
7514 if (const size_t nPaths = includePaths.size()) {
7515 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
7516
7517 for (size_t i = 0; i < nPaths; i += 2) {
7518 if (i)
7519 fIncludePath.Append(' ');
7520 fIncludePath.Append(includePaths[i].c_str());
7521
7522 if (includePaths[i] != "-I")
7523 fIncludePath.Append(' ');
7524 fIncludePath.Append('"');
7525 fIncludePath.Append(includePaths[i + 1], includePaths[i + 1].length());
7526 fIncludePath.Append('"');
7527 }
7528 }
7530 return fIncludePath;
7531}
7532
7533////////////////////////////////////////////////////////////////////////////////
7534/// Return the directory containing CINT's stl cintdlls.
7535
7536const char* TCling::GetSTLIncludePath() const
7537{
7538 return "";
7539}
7540
7541//______________________________________________________________________________
7542// M I S C
7543//______________________________________________________________________________
7544
7545int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
7546{
7547 // Interface to cling function
7548 return 0;
7549}
7550
7551////////////////////////////////////////////////////////////////////////////////
7552/// Interface to cling function
7553
7554int TCling::DisplayIncludePath(FILE *fout) const
7555{
7556 assert(fout != nullptr && "DisplayIncludePath, 'fout' parameter is null");
7557
7558 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7559 //false - no system header, true - with flags.
7560 fInterpreter->GetIncludePaths(includePaths, false, true);
7561 if (const size_t nPaths = includePaths.size()) {
7562 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
7563
7564 std::string allIncludes("include path:");
7565 for (size_t i = 0; i < nPaths; i += 2) {
7566 allIncludes += ' ';
7567 allIncludes += includePaths[i];
7568
7569 if (includePaths[i] != "-I")
7570 allIncludes += ' ';
7571 allIncludes += includePaths[i + 1];
7572 }
7573
7574 fprintf(fout, "%s\n", allIncludes.c_str());
7575 }
7577 return 0;
7578}
7579
7580////////////////////////////////////////////////////////////////////////////////
7581/// Interface to cling function
7582
7583void* TCling::FindSym(const char* entry) const
7584{
7586 return fInterpreter->getAddressOfGlobal(entry);
7587}
7588
7589////////////////////////////////////////////////////////////////////////////////
7590/// Let the interpreter issue a generic error, and set its error state.
7591
7592void TCling::GenericError(const char* error) const
7593{
7594#if defined(R__MUST_REVISIT)
7595#if R__MUST_REVISIT(6,2)
7596 Warning("GenericError","Interface not available yet.");
7597#endif
7598#endif
7599}
7600
7601////////////////////////////////////////////////////////////////////////////////
7602/// This routines used to return the address of the internal wrapper
7603/// function (of the interpreter) that was used to call *all* the
7604/// interpreted functions that were bytecode compiled (no longer
7605/// interpreted line by line). In Cling, there is no such
7606/// wrapper function.
7607/// In practice this routines was use to decipher whether the
7608/// pointer returns by InterfaceMethod could be used to uniquely
7609/// represent the function. In Cling if the function is in a
7610/// useable state (its compiled version is available), this is
7611/// always the case.
7612/// See TClass::GetMethod.
7613
7616 return 0;
7617}
7618
7619////////////////////////////////////////////////////////////////////////////////
7620/// Interface to cling function
7621
7622int TCling::GetSecurityError() const
7623{
7624#if defined(R__MUST_REVISIT)
7625#if R__MUST_REVISIT(6,2)
7626 Warning("GetSecurityError", "Interface not available yet.");
7627#endif
7628#endif
7629 return 0;
7630}
7631
7632////////////////////////////////////////////////////////////////////////////////
7633/// Load a source file or library called path into the interpreter.
7634
7635int TCling::LoadFile(const char* path) const
7636{
7637 // Modifying the interpreter state needs locking.
7639 cling::Interpreter::CompilationResult compRes;
7640 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(".L %s", path), compRes, /*cling::Value*/nullptr);
7641 return compRes == cling::Interpreter::kFailure;
7642}
7644////////////////////////////////////////////////////////////////////////////////
7645/// Load the declarations from text into the interpreter.
7646/// Note that this cannot be (top level) statements; text must contain
7647/// top level declarations.
7648/// Returns true on success, false on failure.
7649
7650Bool_t TCling::LoadText(const char* text) const
7652 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7653}
7654
7655////////////////////////////////////////////////////////////////////////////////
7656/// Interface to cling function
7657
7658const char* TCling::MapCppName(const char* name) const
7659{
7660 TTHREAD_TLS_DECL(std::string,buffer);
7662 return buffer.c_str(); // NOLINT
7663}
7665////////////////////////////////////////////////////////////////////////////////
7666/// [Place holder for Mutex Lock]
7667/// Provide the interpreter with a way to
7668/// acquire a lock used to protect critical section
7669/// of its code (non-thread safe parts).
7670
7671void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7672{
7673 // nothing to do for now.
7675
7676////////////////////////////////////////////////////////////////////////////////
7677/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7678/// release a lock used to protect critical section
7679/// of its code (non-thread safe parts).
7680
7681void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7683 // nothing to do for now.
7684}
7685
7686////////////////////////////////////////////////////////////////////////////////
7687/// Returns if class AutoLoading is currently enabled.
7688
7690{
7691 if (IsFromRootCling())
7692 return false;
7693 if (!fClingCallbacks)
7694 return false;
7695 return fClingCallbacks->IsAutoLoadingEnabled();
7696}
7697
7698////////////////////////////////////////////////////////////////////////////////
7699/// Enable/Disable the AutoLoading of libraries.
7700/// Returns the old value, i.e whether it was enabled or not.
7701
7702int TCling::SetClassAutoLoading(int autoload) const
7703{
7704 // If no state change is required, exit early.
7705 // FIXME: In future we probably want to complain if we made a request which
7706 // was with the same state as before in order to catch programming errors.
7707 if ((bool) autoload == IsClassAutoLoadingEnabled())
7708 return autoload;
7709
7710 assert(fClingCallbacks && "We must have callbacks!");
7711 bool oldVal = fClingCallbacks->IsAutoLoadingEnabled();
7713 return oldVal;
7714}
7715
7716////////////////////////////////////////////////////////////////////////////////
7717/// Enable/Disable the Autoparsing of headers.
7718/// Returns the old value, i.e whether it was enabled or not.
7719
7720int TCling::SetClassAutoparsing(int autoparse)
7721{
7722 bool oldVal = fHeaderParsingOnDemand;
7723 fHeaderParsingOnDemand = autoparse;
7724 return oldVal;
7725}
7726
7727////////////////////////////////////////////////////////////////////////////////
7728/// Suspend the Autoparsing of headers.
7729/// Returns the old value, i.e whether it was suspended or not.
7730
7734 if (fClingCallbacks) fClingCallbacks->SetAutoParsingSuspended(value);
7735 return old;
7736}
7737
7738////////////////////////////////////////////////////////////////////////////////
7739/// Set a callback to receive error messages.
7740
7741void TCling::SetErrmsgcallback(void* p) const
7742{
7743#if defined(R__MUST_REVISIT)
7744#if R__MUST_REVISIT(6,2)
7745 Warning("SetErrmsgcallback", "Interface not available yet.");
7746#endif
7747#endif
7748}
7749
7751{
7752 if (enable) {
7753 auto consumer = new TClingDelegateDiagnosticPrinter(
7754 &fInterpreter->getDiagnostics().getDiagnosticOptions(),
7755 fInterpreter->getCI()->getLangOpts(),
7756 [] (clang::DiagnosticsEngine::Level Level, const std::string &Info) {
7757 if (Level == clang::DiagnosticsEngine::Warning) {
7758 ::Warning("cling", "%s", Info.c_str());
7759 } else if (Level == clang::DiagnosticsEngine::Error
7760 || Level == clang::DiagnosticsEngine::Fatal) {
7761 ::Error("cling", "%s", Info.c_str());
7762 } else {
7763 ::Info("cling", "%s", Info.c_str());
7764 }
7765 });
7766 fInterpreter->replaceDiagnosticConsumer(consumer, /*Own=*/true);
7767 } else {
7768 fInterpreter->replaceDiagnosticConsumer(nullptr);
7769 }
7771
7772
7773////////////////////////////////////////////////////////////////////////////////
7774/// Create / close a scope for temporaries. No-op for cling; use
7775/// cling::Value instead.
7777void TCling::SetTempLevel(int val) const
7778{
7779}
7780
7781////////////////////////////////////////////////////////////////////////////////
7782
7783int TCling::UnloadFile(const char* path) const
7784{
7785 // Modifying the interpreter state needs locking.
7787 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7788 std::string canonical = DLM->lookupLibrary(path);
7789 if (canonical.empty()) {
7790 canonical = path;
7792 // Unload a shared library or a source file.
7793 cling::Interpreter::CompilationResult compRes;
7794 HandleInterpreterException(GetMetaProcessorImpl(), Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/nullptr);
7795 return compRes == cling::Interpreter::kFailure;
7796}
7797
7798std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7799 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7800}
7801
7802////////////////////////////////////////////////////////////////////////////////
7803/// The call to Cling's tab complition.
7804
7805void TCling::CodeComplete(const std::string& line, size_t& cursor,
7806 std::vector<std::string>& completions)
7807{
7808 fInterpreter->codeComplete(line, cursor, completions);
7809}
7810
7811////////////////////////////////////////////////////////////////////////////////
7812/// Get the interpreter value corresponding to the statement.
7813int TCling::Evaluate(const char* code, TInterpreterValue& value)
7814{
7816
7817 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7818 auto compRes = fInterpreter->evaluate(code, *V);
7819 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7820}
7821
7822////////////////////////////////////////////////////////////////////////////////
7823
7825{
7826 using namespace cling;
7827 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7829}
7830
7831////////////////////////////////////////////////////////////////////////////////
7832/// Register value as a temporary, extending its lifetime to that of the
7833/// interpreter. This is needed for TCling's compatibility interfaces
7834/// returning long - the address of the temporary objects.
7835/// As such, "simple" types don't need to be stored; they are returned by
7836/// value; only pointers / references / objects need to be stored.
7837
7838void TCling::RegisterTemporary(const cling::Value& value)
7839{
7840 if (value.isValid() && value.needsManagedAllocation()) {
7842 fTemporaries->push_back(value);
7843 }
7845
7846////////////////////////////////////////////////////////////////////////////////
7847/// If the interpreter encounters Name, check whether that is an object ROOT
7848/// could retrieve. To not re-read objects from disk, cache the name/object
7849/// pair for a given LookupCtx.
7850
7851TObject* TCling::GetObjectAddress(const char *Name, void *&LookupCtx)
7852{
7853 // The call to FindSpecialObject might induces any kind of use
7854 // of the interpreter ... (library loading, function calling, etc.)
7855 // ... and we _know_ we are in the middle of parsing, so let's make
7856 // sure to save the state and then restore it.
7857
7858 if (gDirectory) {
7859 auto iSpecObjMap = fSpecialObjectMaps.find(gDirectory);
7860 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7861 auto iSpecObj = iSpecObjMap->second.find(Name);
7862 if (iSpecObj != iSpecObjMap->second.end()) {
7863 LookupCtx = gDirectory;
7864 return iSpecObj->second;
7865 }
7866 }
7867 }
7868
7869 // Save state of the PP
7870 Sema &SemaR = fInterpreter->getSema();
7871 ASTContext& C = SemaR.getASTContext();
7872 Preprocessor &PP = SemaR.getPreprocessor();
7873 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7874 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7875 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7876 // After we have saved the token reset the current one to something which
7877 // is safe (semi colon usually means empty decl)
7878 Token& Tok = const_cast<Token&>(P.getCurToken());
7879 Tok.setKind(tok::semi);
7880
7881 // We can't PushDeclContext, because we go up and the routine that pops
7882 // the DeclContext assumes that we drill down always.
7883 // We have to be on the global context. At that point we are in a
7884 // wrapper function so the parent context must be the global.
7885 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7886 SemaR.TUScope);
7887
7888 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7889 if (specObj) {
7890 if (!LookupCtx) {
7891 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7892 } else {
7893 fSpecialObjectMaps[LookupCtx][Name] = specObj;
7894 }
7895 }
7896 return specObj;
7898
7899////////////////////////////////////////////////////////////////////////////////
7900/// Inject function as a friend into klass.
7901/// With function being f in void f() {new N::PrivKlass(); } this enables
7902/// I/O of non-public classes.
7903
7904void TCling::AddFriendToClass(clang::FunctionDecl* function,
7905 clang::CXXRecordDecl* klass) const
7906{
7907 using namespace clang;
7908 ASTContext& Ctx = klass->getASTContext();
7909 FriendDecl::FriendUnion friendUnion(function);
7910 // one dummy object for the source location
7911 SourceLocation sl;
7912 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
7913 klass->pushFriendDecl(friendDecl);
7914}
7915
7916//______________________________________________________________________________
7917//
7918// DeclId getter.
7919//
7920
7921////////////////////////////////////////////////////////////////////////////////
7922/// Return a unique identifier of the declaration represented by the
7923/// CallFunc
7924
7925TInterpreter::DeclId_t TCling::GetDeclId(CallFunc_t* func) const
7926{
7927 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
7928 return nullptr;
7929}
7931////////////////////////////////////////////////////////////////////////////////
7932/// Return a (almost) unique identifier of the declaration represented by the
7933/// ClassInfo. In ROOT, this identifier can point to more than one TClass
7934/// when the underlying class is a template instance involving one of the
7935/// opaque typedef.
7936
7937TInterpreter::DeclId_t TCling::GetDeclId(ClassInfo_t* cinfo) const
7938{
7939 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
7940 return nullptr;
7941}
7942
7943////////////////////////////////////////////////////////////////////////////////
7944/// Return a unique identifier of the declaration represented by the
7945/// MethodInfo
7946
7947TInterpreter::DeclId_t TCling::GetDeclId(DataMemberInfo_t* data) const
7948{
7949 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
7950 return nullptr;
7951}
7952
7953////////////////////////////////////////////////////////////////////////////////
7954/// Return a unique identifier of the declaration represented by the
7955/// MethodInfo
7956
7957TInterpreter::DeclId_t TCling::GetDeclId(MethodInfo_t* method) const
7958{
7959 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
7960 return nullptr;
7961}
7962
7963////////////////////////////////////////////////////////////////////////////////
7964/// Return a unique identifier of the declaration represented by the
7965/// TypedefInfo
7966
7967TInterpreter::DeclId_t TCling::GetDeclId(TypedefInfo_t* tinfo) const
7968{
7969 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
7970 return nullptr;
7971}
7972
7973//______________________________________________________________________________
7974//
7975// CallFunc interface
7976//
7977
7978////////////////////////////////////////////////////////////////////////////////
7979
7980void TCling::CallFunc_Delete(CallFunc_t* func) const
7981{
7982 delete (TClingCallFunc*) func;
7983}
7984
7985////////////////////////////////////////////////////////////////////////////////
7986
7987void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
7989 TClingCallFunc* f = (TClingCallFunc*) func;
7990 f->Exec(address);
7991}
7992
7993////////////////////////////////////////////////////////////////////////////////
7994
7995void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
7997 TClingCallFunc* f = (TClingCallFunc*) func;
7998 f->Exec(address, &val);
7999}
8000
8001////////////////////////////////////////////////////////////////////////////////
8002
8003void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
8005 TClingCallFunc* f = (TClingCallFunc*) func;
8006 f->ExecWithReturn(address, ret);
8007}
8008
8009////////////////////////////////////////////////////////////////////////////////
8010
8011void TCling::CallFunc_ExecWithArgsAndReturn(CallFunc_t* func, void* address,
8012 const void* args[] /*=0*/,
8013 int nargs /*=0*/,
8014 void* ret/*=0*/) const
8016 TClingCallFunc* f = (TClingCallFunc*) func;
8017 f->ExecWithArgsAndReturn(address, args, nargs, ret);
8018}
8019
8020////////////////////////////////////////////////////////////////////////////////
8021
8022Longptr_t TCling::CallFunc_ExecInt(CallFunc_t* func, void* address) const
8024 TClingCallFunc* f = (TClingCallFunc*) func;
8025 return f->ExecInt(address);
8026}
8027
8028////////////////////////////////////////////////////////////////////////////////
8029
8030Long64_t TCling::CallFunc_ExecInt64(CallFunc_t* func, void* address) const
8032 TClingCallFunc* f = (TClingCallFunc*) func;
8033 return f->ExecInt64(address);
8034}
8035
8036////////////////////////////////////////////////////////////////////////////////
8037
8038Double_t TCling::CallFunc_ExecDouble(CallFunc_t* func, void* address) const
8040 TClingCallFunc* f = (TClingCallFunc*) func;
8041 return f->ExecDouble(address);
8042}
8043
8044////////////////////////////////////////////////////////////////////////////////
8045
8046CallFunc_t* TCling::CallFunc_Factory() const
8049 return (CallFunc_t*) new TClingCallFunc(GetInterpreterImpl());
8050}
8051
8052////////////////////////////////////////////////////////////////////////////////
8053
8054CallFunc_t* TCling::CallFunc_FactoryCopy(CallFunc_t* func) const
8055{
8056 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
8057}
8058
8059////////////////////////////////////////////////////////////////////////////////
8060
8061MethodInfo_t* TCling::CallFunc_FactoryMethod(CallFunc_t* func) const
8063 TClingCallFunc* f = (TClingCallFunc*) func;
8064 return (MethodInfo_t*) f->FactoryMethod();
8065}
8066
8067////////////////////////////////////////////////////////////////////////////////
8068
8069void TCling::CallFunc_IgnoreExtraArgs(CallFunc_t* func, bool ignore) const
8071 TClingCallFunc* f = (TClingCallFunc*) func;
8072 f->IgnoreExtraArgs(ignore);
8073}
8074
8075////////////////////////////////////////////////////////////////////////////////
8076
8077void TCling::CallFunc_Init(CallFunc_t* func) const
8078{
8080 TClingCallFunc* f = (TClingCallFunc*) func;
8081 f->Init();
8082}
8083
8084////////////////////////////////////////////////////////////////////////////////
8085
8086bool TCling::CallFunc_IsValid(CallFunc_t* func) const
8087{
8089 return f->IsValid();
8090}
8091
8092////////////////////////////////////////////////////////////////////////////////
8093
8095TCling::CallFunc_IFacePtr(CallFunc_t * func) const
8097 TClingCallFunc* f = (TClingCallFunc*) func;
8098 return f->IFacePtr();
8099}
8100
8101////////////////////////////////////////////////////////////////////////////////
8102
8103void TCling::CallFunc_ResetArg(CallFunc_t* func) const
8105 TClingCallFunc* f = (TClingCallFunc*) func;
8106 f->ResetArg();
8107}
8108
8109////////////////////////////////////////////////////////////////////////////////
8110
8111void TCling::CallFunc_SetArg(CallFunc_t* func, Long_t param) const
8113 TClingCallFunc* f = (TClingCallFunc*) func;
8114 f->SetArg(param);
8115}
8116
8117////////////////////////////////////////////////////////////////////////////////
8118
8119void TCling::CallFunc_SetArg(CallFunc_t* func, ULong_t param) const
8121 TClingCallFunc* f = (TClingCallFunc*) func;
8122 f->SetArg(param);
8123}
8124
8125////////////////////////////////////////////////////////////////////////////////
8126
8127void TCling::CallFunc_SetArg(CallFunc_t* func, Float_t param) const
8129 TClingCallFunc* f = (TClingCallFunc*) func;
8130 f->SetArg(param);
8131}
8132
8133////////////////////////////////////////////////////////////////////////////////
8134
8135void TCling::CallFunc_SetArg(CallFunc_t* func, Double_t param) const
8137 TClingCallFunc* f = (TClingCallFunc*) func;
8138 f->SetArg(param);
8139}
8140
8141////////////////////////////////////////////////////////////////////////////////
8142
8143void TCling::CallFunc_SetArg(CallFunc_t* func, Long64_t param) const
8145 TClingCallFunc* f = (TClingCallFunc*) func;
8146 f->SetArg(param);
8147}
8148
8149////////////////////////////////////////////////////////////////////////////////
8150
8151void TCling::CallFunc_SetArg(CallFunc_t* func, ULong64_t param) const
8153 TClingCallFunc* f = (TClingCallFunc*) func;
8154 f->SetArg(param);
8155}
8156
8157////////////////////////////////////////////////////////////////////////////////
8158
8159void TCling::CallFunc_SetArgArray(CallFunc_t* func, Longptr_t* paramArr, Int_t nparam) const
8161 TClingCallFunc* f = (TClingCallFunc*) func;
8162 f->SetArgArray(paramArr, nparam);
8163}
8164
8165////////////////////////////////////////////////////////////////////////////////
8166
8167void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
8169 TClingCallFunc* f = (TClingCallFunc*) func;
8170 f->SetArgs(param);
8171}
8172
8173////////////////////////////////////////////////////////////////////////////////
8174
8175void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Longptr_t* offset) const
8176{
8178 TClingClassInfo* ci = (TClingClassInfo*) info;
8179 f->SetFunc(ci, method, params, offset);
8180}
8181
8182////////////////////////////////////////////////////////////////////////////////
8183
8184void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Longptr_t* offset) const
8186 TClingCallFunc* f = (TClingCallFunc*) func;
8187 TClingClassInfo* ci = (TClingClassInfo*) info;
8188 f->SetFunc(ci, method, params, objectIsConst, offset);
8189}
8190////////////////////////////////////////////////////////////////////////////////
8191
8192void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
8193{
8194 TClingCallFunc* f = (TClingCallFunc*) func;
8196 f->SetFunc(minfo);
8197}
8198
8199////////////////////////////////////////////////////////////////////////////////
8200/// Interface to cling function
8201
8202void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8203{
8204 TClingCallFunc* f = (TClingCallFunc*) func;
8206 f->SetFuncProto(ci, method, proto, offset, mode);
8207}
8208
8209////////////////////////////////////////////////////////////////////////////////
8210/// Interface to cling function
8211
8212void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8213{
8214 TClingCallFunc* f = (TClingCallFunc*) func;
8216 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
8217}
8218
8219////////////////////////////////////////////////////////////////////////////////
8220/// Interface to cling function
8221
8222void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const std::vector<TypeInfo_t*> &proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8223{
8224 TClingCallFunc* f = (TClingCallFunc*) func;
8225 TClingClassInfo* ci = (TClingClassInfo*) info;
8226 llvm::SmallVector<clang::QualType, 4> funcProto;
8227 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8228 iter != end; ++iter) {
8229 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8231 f->SetFuncProto(ci, method, funcProto, offset, mode);
8232}
8233
8234////////////////////////////////////////////////////////////////////////////////
8235/// Interface to cling function
8236
8237void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const std::vector<TypeInfo_t*> &proto, bool objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8238{
8239 TClingCallFunc* f = (TClingCallFunc*) func;
8240 TClingClassInfo* ci = (TClingClassInfo*) info;
8241 llvm::SmallVector<clang::QualType, 4> funcProto;
8242 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8243 iter != end; ++iter) {
8244 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8245 }
8246 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
8247}
8248
8249std::string TCling::CallFunc_GetWrapperCode(CallFunc_t *func) const
8250{
8251 TClingCallFunc *f = (TClingCallFunc *)func;
8252 std::string wrapper_name;
8253 std::string wrapper;
8254 f->get_wrapper_code(wrapper_name, wrapper);
8255 return wrapper;
8256}
8257
8258//______________________________________________________________________________
8259//
8260// ClassInfo interface
8261//
8262
8263////////////////////////////////////////////////////////////////////////////////
8264
8265size_t TCling::ClassInfo_AlignOf(ClassInfo_t *cinfo) const
8266{
8267 TClingClassInfo *TClinginfo = (TClingClassInfo *)cinfo;
8268 return TClinginfo->GetAlignOf();
8270
8271////////////////////////////////////////////////////////////////////////////////
8272/// Return true if the entity pointed to by 'declid' is declared in
8273/// the context described by 'info'. If info is null, look into the
8274/// global scope (translation unit scope).
8275
8276Bool_t TCling::ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const
8277{
8278 if (!declid)
8279 return kFALSE;
8280
8281 const clang::DeclContext *ctxt = nullptr;
8282 if (info) {
8283 ctxt = clang::Decl::castToDeclContext(((TClingClassInfo*)info)->GetDecl());
8284 } else {
8285 ctxt = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
8286 }
8287 if (!ctxt)
8288 return kFALSE;
8289
8290 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
8291 if (!decl)
8292 return kFALSE;
8293
8294 const clang::DeclContext *declDC = decl->getDeclContext();
8295 // ClassInfo_t-s are always "spellable" scopes, never unnamed or inline ones.
8296 while (true) {
8297 if (declDC->isTransparentContext()) {
8298 declDC = declDC->getParent();
8299 continue;
8300 }
8301 if (const auto *declRD = llvm::dyn_cast<clang::RecordDecl>(declDC)) {
8302 if (declRD->isAnonymousStructOrUnion()) {
8303 declDC = declRD->getParent();
8304 continue;
8305 }
8306 }
8307 if (const auto *declNS = llvm::dyn_cast<clang::NamespaceDecl>(declDC)) {
8308 if (declNS->isAnonymousNamespace() || declNS->isInlineNamespace()) {
8309 declDC = declNS->getParent();
8310 continue;
8311 }
8312 }
8313 break;
8315
8316 return declDC->Equals(ctxt);
8317}
8318
8319////////////////////////////////////////////////////////////////////////////////
8320
8321Long_t TCling::ClassInfo_ClassProperty(ClassInfo_t* cinfo) const
8323 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8324 return TClinginfo->ClassProperty();
8325}
8326
8327////////////////////////////////////////////////////////////////////////////////
8328
8329void TCling::ClassInfo_Delete(ClassInfo_t* cinfo) const
8330{
8331 delete (TClingClassInfo*) cinfo;
8332}
8333
8334////////////////////////////////////////////////////////////////////////////////
8335
8336void TCling::ClassInfo_Delete(ClassInfo_t* cinfo, void* arena) const
8338 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8339 TClinginfo->Delete(arena,*fNormalizedCtxt);
8340}
8341
8342////////////////////////////////////////////////////////////////////////////////
8343
8344void TCling::ClassInfo_DeleteArray(ClassInfo_t* cinfo, void* arena, bool dtorOnly) const
8346 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8347 TClinginfo->DeleteArray(arena, dtorOnly,*fNormalizedCtxt);
8348}
8349
8350////////////////////////////////////////////////////////////////////////////////
8351
8352void TCling::ClassInfo_Destruct(ClassInfo_t* cinfo, void* arena) const
8354 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8355 TClinginfo->Destruct(arena,*fNormalizedCtxt);
8356}
8357
8358////////////////////////////////////////////////////////////////////////////////
8359
8360ClassInfo_t* TCling::ClassInfo_Factory(Bool_t all) const
8363 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), all);
8364}
8365
8366////////////////////////////////////////////////////////////////////////////////
8367
8368ClassInfo_t* TCling::ClassInfo_Factory(ClassInfo_t* cinfo) const
8369{
8370 return (ClassInfo_t*) new TClingClassInfo(*(TClingClassInfo*)cinfo);
8371}
8372
8373////////////////////////////////////////////////////////////////////////////////
8375ClassInfo_t* TCling::ClassInfo_Factory(const char* name) const
8376{
8378 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), name);
8379}
8380
8381ClassInfo_t* TCling::ClassInfo_Factory(DeclId_t declid) const
8382{
8384 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), (const clang::Decl*)declid);
8385}
8386
8387
8388////////////////////////////////////////////////////////////////////////////////
8389
8390int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
8392 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8393 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
8394}
8395
8396////////////////////////////////////////////////////////////////////////////////
8397
8398bool TCling::ClassInfo_HasDefaultConstructor(ClassInfo_t* cinfo, Bool_t testio) const
8400 TClingClassInfo *TClinginfo = (TClingClassInfo *) cinfo;
8402}
8403
8404////////////////////////////////////////////////////////////////////////////////
8405
8406bool TCling::ClassInfo_HasMethod(ClassInfo_t* cinfo, const char* name) const
8408 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8409 return TClinginfo->HasMethod(name);
8410}
8411
8412////////////////////////////////////////////////////////////////////////////////
8413
8414void TCling::ClassInfo_Init(ClassInfo_t* cinfo, const char* name) const
8415{
8417 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8418 TClinginfo->Init(name);
8419}
8420
8421////////////////////////////////////////////////////////////////////////////////
8422
8423void TCling::ClassInfo_Init(ClassInfo_t* cinfo, int tagnum) const
8424{
8426 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8427 TClinginfo->Init(tagnum);
8428}
8429
8430////////////////////////////////////////////////////////////////////////////////
8431
8432bool TCling::ClassInfo_IsBase(ClassInfo_t* cinfo, const char* name) const
8434 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8435 return TClinginfo->IsBase(name);
8436}
8437
8438////////////////////////////////////////////////////////////////////////////////
8439
8440bool TCling::ClassInfo_IsEnum(const char* name) const
8441{
8443}
8444
8445////////////////////////////////////////////////////////////////////////////////
8446
8447Bool_t TCling::ClassInfo_IsScopedEnum(ClassInfo_t *info) const
8448{
8449 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8450 return TClinginfo->IsScopedEnum();
8451}
8452
8453
8454////////////////////////////////////////////////////////////////////////////////
8455
8456EDataType TCling::ClassInfo_GetUnderlyingType(ClassInfo_t* info) const
8457{
8458 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8459 return TClinginfo->GetUnderlyingType();
8460}
8461
8462
8463////////////////////////////////////////////////////////////////////////////////
8464
8465bool TCling::ClassInfo_IsLoaded(ClassInfo_t* cinfo) const
8467 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8468 return TClinginfo->IsLoaded();
8469}
8470
8471////////////////////////////////////////////////////////////////////////////////
8472
8473bool TCling::ClassInfo_IsValid(ClassInfo_t* cinfo) const
8475 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8476 return TClinginfo->IsValid();
8477}
8478
8479////////////////////////////////////////////////////////////////////////////////
8480
8481bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8483 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8484 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
8485}
8486
8487////////////////////////////////////////////////////////////////////////////////
8488
8489bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8491 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8492 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8493}
8494
8495////////////////////////////////////////////////////////////////////////////////
8496
8497int TCling::ClassInfo_Next(ClassInfo_t* cinfo) const
8499 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8500 return TClinginfo->Next();
8501}
8502
8503////////////////////////////////////////////////////////////////////////////////
8504
8505void* TCling::ClassInfo_New(ClassInfo_t* cinfo) const
8507 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8508 return TClinginfo->New(*fNormalizedCtxt);
8509}
8510
8511////////////////////////////////////////////////////////////////////////////////
8512
8513void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n) const
8515 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8516 return TClinginfo->New(n,*fNormalizedCtxt);
8517}
8518
8519////////////////////////////////////////////////////////////////////////////////
8520
8521void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n, void* arena) const
8523 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8524 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8525}
8526
8527////////////////////////////////////////////////////////////////////////////////
8528
8529void* TCling::ClassInfo_New(ClassInfo_t* cinfo, void* arena) const
8531 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8532 return TClinginfo->New(arena,*fNormalizedCtxt);
8533}
8534
8535////////////////////////////////////////////////////////////////////////////////
8536
8537Long_t TCling::ClassInfo_Property(ClassInfo_t* cinfo) const
8539 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8540 return TClinginfo->Property();
8541}
8542
8543////////////////////////////////////////////////////////////////////////////////
8544
8545int TCling::ClassInfo_Size(ClassInfo_t* cinfo) const
8547 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8548 return TClinginfo->Size();
8549}
8550
8551////////////////////////////////////////////////////////////////////////////////
8552
8553Longptr_t TCling::ClassInfo_Tagnum(ClassInfo_t* cinfo) const
8555 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8556 return TClinginfo->Tagnum();
8557}
8558
8559////////////////////////////////////////////////////////////////////////////////
8560
8561const char* TCling::ClassInfo_FileName(ClassInfo_t* cinfo) const
8563 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8564 return TClinginfo->FileName();
8565}
8566
8567////////////////////////////////////////////////////////////////////////////////
8568
8569const char* TCling::ClassInfo_FullName(ClassInfo_t* cinfo) const
8570{
8571 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8572 TTHREAD_TLS_DECL(std::string,output);
8573 TClinginfo->FullName(output,*fNormalizedCtxt);
8574 return output.c_str(); // NOLINT
8575}
8576
8577////////////////////////////////////////////////////////////////////////////////
8578
8579const char* TCling::ClassInfo_Name(ClassInfo_t* cinfo) const
8581 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8582 return TClinginfo->Name();
8583}
8584
8585////////////////////////////////////////////////////////////////////////////////
8586
8587const char* TCling::ClassInfo_Title(ClassInfo_t* cinfo) const
8589 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8590 return TClinginfo->Title();
8591}
8592
8593////////////////////////////////////////////////////////////////////////////////
8594
8595const char* TCling::ClassInfo_TmpltName(ClassInfo_t* cinfo) const
8596{
8597 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8598 return TClinginfo->TmpltName();
8599}
8600
8601
8602
8603//______________________________________________________________________________
8604//
8605// BaseClassInfo interface
8606//
8607
8608////////////////////////////////////////////////////////////////////////////////
8609
8610void TCling::BaseClassInfo_Delete(BaseClassInfo_t* bcinfo) const
8611{
8612 delete(TClingBaseClassInfo*) bcinfo;
8613}
8614
8615////////////////////////////////////////////////////////////////////////////////
8616
8617BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo) const
8618{
8620 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8621 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo);
8622}
8623
8624////////////////////////////////////////////////////////////////////////////////
8625
8626BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* derived,
8627 ClassInfo_t* base) const
8628{
8630 TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
8631 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) base;
8632 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo, TClinginfoBase);
8633}
8634
8635////////////////////////////////////////////////////////////////////////////////
8636
8637int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo) const
8639 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8640 return TClinginfo->Next();
8641}
8642
8643////////////////////////////////////////////////////////////////////////////////
8644
8645int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo, int onlyDirect) const
8647 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8648 return TClinginfo->Next(onlyDirect);
8649}
8650
8651////////////////////////////////////////////////////////////////////////////////
8652
8653Longptr_t TCling::BaseClassInfo_Offset(BaseClassInfo_t* toBaseClassInfo, void * address, bool isDerivedObject) const
8655 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) toBaseClassInfo;
8656 return TClinginfo->Offset(address, isDerivedObject);
8657}
8658
8659////////////////////////////////////////////////////////////////////////////////
8660
8661Longptr_t TCling::ClassInfo_GetBaseOffset(ClassInfo_t* fromDerived, ClassInfo_t* toBase, void * address, bool isDerivedObject) const
8662{
8663 TClingClassInfo* TClinginfo = (TClingClassInfo*) fromDerived;
8664 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) toBase;
8665 // Offset to the class itself.
8666 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8667 return 0;
8668 }
8669 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8670}
8671
8672////////////////////////////////////////////////////////////////////////////////
8673
8674Long_t TCling::BaseClassInfo_Property(BaseClassInfo_t* bcinfo) const
8676 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8677 return TClinginfo->Property();
8678}
8679
8680////////////////////////////////////////////////////////////////////////////////
8681
8682ClassInfo_t *TCling::BaseClassInfo_ClassInfo(BaseClassInfo_t *bcinfo) const
8684 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8685 return (ClassInfo_t *)TClinginfo->GetBase();
8686}
8687
8688////////////////////////////////////////////////////////////////////////////////
8689
8690Longptr_t TCling::BaseClassInfo_Tagnum(BaseClassInfo_t* bcinfo) const
8692 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8693 return TClinginfo->Tagnum();
8694}
8695
8696////////////////////////////////////////////////////////////////////////////////
8697
8698const char* TCling::BaseClassInfo_FullName(BaseClassInfo_t* bcinfo) const
8699{
8700 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8701 TTHREAD_TLS_DECL(std::string,output);
8702 TClinginfo->FullName(output,*fNormalizedCtxt);
8703 return output.c_str(); // NOLINT
8704}
8705
8706////////////////////////////////////////////////////////////////////////////////
8707
8708const char* TCling::BaseClassInfo_Name(BaseClassInfo_t* bcinfo) const
8710 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8711 return TClinginfo->Name();
8712}
8713
8714////////////////////////////////////////////////////////////////////////////////
8715
8716const char* TCling::BaseClassInfo_TmpltName(BaseClassInfo_t* bcinfo) const
8717{
8718 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8719 return TClinginfo->TmpltName();
8720}
8721
8722//______________________________________________________________________________
8723//
8724// DataMemberInfo interface
8725//
8726
8727////////////////////////////////////////////////////////////////////////////////
8728
8729int TCling::DataMemberInfo_ArrayDim(DataMemberInfo_t* dminfo) const
8731 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8732 return TClinginfo->ArrayDim();
8733}
8734
8735////////////////////////////////////////////////////////////////////////////////
8736
8737void TCling::DataMemberInfo_Delete(DataMemberInfo_t* dminfo) const
8738{
8739 delete(TClingDataMemberInfo*) dminfo;
8740}
8741
8742////////////////////////////////////////////////////////////////////////////////
8743
8744DataMemberInfo_t* TCling::DataMemberInfo_Factory(ClassInfo_t* clinfo, TDictionary::EMemberSelection selection) const
8745{
8747 TClingClassInfo* TClingclass_info = (TClingClassInfo*) clinfo;
8748 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), TClingclass_info, selection);
8749}
8750
8751////////////////////////////////////////////////////////////////////////////////
8752
8753DataMemberInfo_t* TCling::DataMemberInfo_Factory(DeclId_t declid, ClassInfo_t* clinfo) const
8754{
8756 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8757 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8758 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), vd, (TClingClassInfo*)clinfo);
8759}
8760
8761////////////////////////////////////////////////////////////////////////////////
8762
8763DataMemberInfo_t* TCling::DataMemberInfo_FactoryCopy(DataMemberInfo_t* dminfo) const
8765 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8766 return (DataMemberInfo_t*) new TClingDataMemberInfo(*TClinginfo);
8767}
8768
8769////////////////////////////////////////////////////////////////////////////////
8770
8771bool TCling::DataMemberInfo_IsValid(DataMemberInfo_t* dminfo) const
8773 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8774 return TClinginfo->IsValid();
8775}
8776
8777////////////////////////////////////////////////////////////////////////////////
8778
8779int TCling::DataMemberInfo_MaxIndex(DataMemberInfo_t* dminfo, Int_t dim) const
8781 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8782 return TClinginfo->MaxIndex(dim);
8783}
8784
8785////////////////////////////////////////////////////////////////////////////////
8786
8787int TCling::DataMemberInfo_Next(DataMemberInfo_t* dminfo) const
8789 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8790 return TClinginfo->Next();
8791}
8792
8793////////////////////////////////////////////////////////////////////////////////
8794
8795Longptr_t TCling::DataMemberInfo_Offset(DataMemberInfo_t* dminfo) const
8797 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8798 return TClinginfo->Offset();
8799}
8800
8801////////////////////////////////////////////////////////////////////////////////
8802
8803Long_t TCling::DataMemberInfo_Property(DataMemberInfo_t* dminfo) const
8805 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8806 return TClinginfo->Property();
8807}
8808
8809////////////////////////////////////////////////////////////////////////////////
8810
8811Long_t TCling::DataMemberInfo_TypeProperty(DataMemberInfo_t* dminfo) const
8813 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8814 return TClinginfo->TypeProperty();
8815}
8816
8817////////////////////////////////////////////////////////////////////////////////
8818
8819int TCling::DataMemberInfo_TypeSize(DataMemberInfo_t* dminfo) const
8821 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8822 return TClinginfo->TypeSize();
8823}
8824
8825////////////////////////////////////////////////////////////////////////////////
8826
8827const char* TCling::DataMemberInfo_TypeName(DataMemberInfo_t* dminfo) const
8829 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8830 return TClinginfo->TypeName();
8831}
8832
8833////////////////////////////////////////////////////////////////////////////////
8834
8835const char* TCling::DataMemberInfo_TypeTrueName(DataMemberInfo_t* dminfo) const
8837 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8838 return TClinginfo->TypeTrueName(*fNormalizedCtxt);
8839}
8840
8841////////////////////////////////////////////////////////////////////////////////
8842
8843const char* TCling::DataMemberInfo_Name(DataMemberInfo_t* dminfo) const
8845 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8846 return TClinginfo->Name();
8847}
8848
8849////////////////////////////////////////////////////////////////////////////////
8850
8851const char* TCling::DataMemberInfo_Title(DataMemberInfo_t* dminfo) const
8853 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8854 return TClinginfo->Title();
8855}
8856
8857////////////////////////////////////////////////////////////////////////////////
8858
8859const char* TCling::DataMemberInfo_ValidArrayIndex(DataMemberInfo_t* dminfo) const
8860{
8861 TTHREAD_TLS_DECL(std::string,result);
8862
8864 result = TClinginfo->ValidArrayIndex().str();
8865 return result.c_str(); // NOLINT
8866}
8867
8868////////////////////////////////////////////////////////////////////////////////
8869
8870void TCling::SetDeclAttr(DeclId_t declId, const char* attribute)
8871{
8872 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8873 ASTContext &C = decl->getASTContext();
8874 decl->addAttr(AnnotateAttr::CreateImplicit(C, attribute, nullptr, 0));
8875}
8876
8877//______________________________________________________________________________
8878//
8879// Function Template interface
8880//
8881
8882////////////////////////////////////////////////////////////////////////////////
8883
8884static void ConstructorName(std::string &name, const clang::Decl *decl,
8885 cling::Interpreter &interp,
8886 const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
8887{
8888 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8889 if (!td) return;
8890
8891 clang::QualType qualType(td->getTypeForDecl(),0);
8892 ROOT::TMetaUtils::GetNormalizedName(name, qualType, interp, normCtxt);
8893 unsigned int level = 0;
8894 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8895 if (name[cursor] == '>') ++level;
8896 else if (name[cursor] == '<' && level) --level;
8897 else if (level == 0 && name[cursor] == ':') {
8898 name.erase(0,cursor+1);
8899 break;
8900 }
8901 }
8902}
8903
8904////////////////////////////////////////////////////////////////////////////////
8905
8906void TCling::GetFunctionName(const clang::Decl *decl, std::string &output) const
8907{
8908 output.clear();
8909
8910 const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(decl);
8911 if (const auto *USD = llvm::dyn_cast<clang::UsingShadowDecl>(decl)) {
8912 FD = llvm::dyn_cast<clang::FunctionDecl>(USD->getTargetDecl());
8913 }
8914 if (!FD) {
8915 Error("GetFunctionName", "NULL Decl!");
8916 return;
8917 }
8918
8919 // For using-decls, show "Derived", not "Base", i.e. use the
8920 // name of the decl context of the UsingShadowDecl (aka `decl`)
8921 // not the name of FD's decl context.
8922 if (llvm::isa<clang::CXXConstructorDecl>(FD))
8923 {
8925
8926 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
8927 {
8929 output.insert(output.begin(), '~');
8930 } else {
8931 llvm::raw_string_ostream stream(output);
8932 auto printPolicy = decl->getASTContext().getPrintingPolicy();
8933 // Don't trigger fopen of the source file to count lines:
8934 printPolicy.AnonymousTagLocations = false;
8935 FD->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
8937}
8938
8939////////////////////////////////////////////////////////////////////////////////
8940/// Return a unique identifier of the declaration represented by the
8941/// FuncTempInfo
8942
8943TInterpreter::DeclId_t TCling::GetDeclId(FuncTempInfo_t *info) const
8945 return (DeclId_t)info;
8946}
8947
8948////////////////////////////////////////////////////////////////////////////////
8949/// Delete the FuncTempInfo_t
8950
8951void TCling::FuncTempInfo_Delete(FuncTempInfo_t * /* ft_info */) const
8952{
8953 // Currently the address of ft_info is actually the decl itself,
8954 // so we have nothing to do.
8955}
8956
8957////////////////////////////////////////////////////////////////////////////////
8958/// Construct a FuncTempInfo_t
8959
8960FuncTempInfo_t *TCling::FuncTempInfo_Factory(DeclId_t declid) const
8961{
8962 // Currently the address of ft_info is actually the decl itself,
8963 // so we have nothing to do.
8965 return (FuncTempInfo_t*)const_cast<void*>(declid);
8966}
8967
8968////////////////////////////////////////////////////////////////////////////////
8969/// Construct a FuncTempInfo_t
8970
8971FuncTempInfo_t *TCling::FuncTempInfo_FactoryCopy(FuncTempInfo_t *ft_info) const
8972{
8973 // Currently the address of ft_info is actually the decl itself,
8974 // so we have nothing to do.
8976 return (FuncTempInfo_t*)ft_info;
8977}
8978
8979////////////////////////////////////////////////////////////////////////////////
8980/// Check validity of a FuncTempInfo_t
8981
8982Bool_t TCling::FuncTempInfo_IsValid(FuncTempInfo_t *t_info) const
8983{
8984 // Currently the address of ft_info is actually the decl itself,
8985 // so we have nothing to do.
8986
8987 return t_info != nullptr;
8988}
8989
8990////////////////////////////////////////////////////////////////////////////////
8991/// Return the maximum number of template arguments of the
8992/// function template described by ft_info.
8993
8994UInt_t TCling::FuncTempInfo_TemplateNargs(FuncTempInfo_t *ft_info) const
8995{
8996 if (!ft_info) return 0;
8997 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8998 return ft->getTemplateParameters()->size();
8999}
9000
9001////////////////////////////////////////////////////////////////////////////////
9002/// Return the number of required template arguments of the
9003/// function template described by ft_info.
9004
9005UInt_t TCling::FuncTempInfo_TemplateMinReqArgs(FuncTempInfo_t *ft_info) const
9006{
9007 if (!ft_info) return 0;
9008 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9009 return ft->getTemplateParameters()->getMinRequiredArguments();
9010}
9011
9012////////////////////////////////////////////////////////////////////////////////
9013/// Return the property of the function template.
9014
9015Long_t TCling::FuncTempInfo_Property(FuncTempInfo_t *ft_info) const
9016{
9017 if (!ft_info) return 0;
9018
9019 long property = 0L;
9020 property |= kIsCompiled;
9021
9022 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9023
9024 switch (ft->getAccess()) {
9025 case clang::AS_public:
9026 property |= kIsPublic;
9027 break;
9028 case clang::AS_protected:
9029 property |= kIsProtected;
9030 break;
9031 case clang::AS_private:
9032 property |= kIsPrivate;
9033 break;
9034 case clang::AS_none:
9035 if (ft->getDeclContext()->isNamespace())
9036 property |= kIsPublic;
9037 break;
9038 default:
9039 // IMPOSSIBLE
9040 assert(false && "Unexpected value for the access property value in Clang");
9041 break;
9042 }
9043
9044 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
9045
9046 if (fd && fd->getStorageClass() == clang::SC_Static)
9047 property |= kIsStatic;
9048
9049 if (const clang::CXXMethodDecl *md =
9050 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
9051 if (md->getMethodQualifiers().hasConst()) {
9052 property |= kIsConstant | kIsConstMethod;
9053 }
9054 if (md->isVirtual()) {
9055 property |= kIsVirtual;
9056 }
9057 if (md->isPureVirtual()) {
9058 property |= kIsPureVirtual;
9059 }
9060 if (const clang::CXXConstructorDecl *cd =
9061 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
9062 if (cd->isExplicit()) {
9063 property |= kIsExplicit;
9064 }
9065 }
9066 else if (const clang::CXXConversionDecl *cd =
9067 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
9068 if (cd->isExplicit()) {
9069 property |= kIsExplicit;
9070 }
9071 }
9072 }
9073 return property;
9074}
9075
9076////////////////////////////////////////////////////////////////////////////////
9077/// Return the property not already defined in Property
9078/// See TDictionary's EFunctionProperty
9079
9080Long_t TCling::FuncTempInfo_ExtraProperty(FuncTempInfo_t* ft_info) const
9081{
9082 if (!ft_info) return 0;
9083
9084 long property = 0L;
9085 property |= kIsCompiled;
9086
9087 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9088 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
9089
9090 if (fd->isOverloadedOperator())
9091 property |= kIsOperator;
9092 if (llvm::isa<clang::CXXConversionDecl>(fd))
9093 property |= kIsConversion;
9094 if (llvm::isa<clang::CXXConstructorDecl>(fd))
9095 property |= kIsConstructor;
9096 if (llvm::isa<clang::CXXDestructorDecl>(fd))
9097 property |= kIsDestructor;
9098 if (fd->isInlined())
9099 property |= kIsInlined;
9100 return property;
9101}
9102
9103////////////////////////////////////////////////////////////////////////////////
9104/// Return the name of this function template.
9105
9106void TCling::FuncTempInfo_Name(FuncTempInfo_t *ft_info, TString &output) const
9107{
9108 output.Clear();
9109 if (!ft_info) return;
9110 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9111 std::string buf;
9112 GetFunctionName(ft->getTemplatedDecl(), buf);
9113 output = buf;
9114}
9115
9116////////////////////////////////////////////////////////////////////////////////
9117/// Return the comments associates with this function template.
9118
9119void TCling::FuncTempInfo_Title(FuncTempInfo_t *ft_info, TString &output) const
9120{
9121 output.Clear();
9122 if (!ft_info) return;
9123 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
9124
9125 // Iterate over the redeclarations, we can have multiple definitions in the
9126 // redecl chain (came from merging of pcms).
9127 if (const RedeclarableTemplateDecl *AnnotFD
9128 = ROOT::TMetaUtils::GetAnnotatedRedeclarable((const RedeclarableTemplateDecl*)ft)) {
9129 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
9130 output = A->getAnnotation().str();
9131 return;
9132 }
9133 }
9134 if (!ft->isFromASTFile()) {
9135 // Try to get the comment from the header file if present
9136 // but not for decls from AST file, where rootcling would have
9137 // created an annotation
9138 output = ROOT::TMetaUtils::GetComment(*ft).str();
9139 }
9140}
9141
9142
9143//______________________________________________________________________________
9145// MethodInfo interface
9146//
9147
9148////////////////////////////////////////////////////////////////////////////////
9149/// Interface to cling function
9150
9151void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
9152{
9153 delete(TClingMethodInfo*) minfo;
9154}
9155
9156////////////////////////////////////////////////////////////////////////////////
9157
9158void TCling::MethodInfo_CreateSignature(MethodInfo_t* minfo, TString& signature) const
9159{
9161 // The next call locks the interpreter mutex.
9162 info->CreateSignature(signature);
9163}
9164
9165////////////////////////////////////////////////////////////////////////////////
9166
9167MethodInfo_t* TCling::MethodInfo_Factory() const
9170 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl());
9171}
9172
9173////////////////////////////////////////////////////////////////////////////////
9174
9175MethodInfo_t* TCling::MethodInfo_Factory(ClassInfo_t* clinfo) const
9178 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
9179}
9180
9181////////////////////////////////////////////////////////////////////////////////
9182
9183MethodInfo_t* TCling::MethodInfo_Factory(DeclId_t declid) const
9184{
9185 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
9187 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), decl);
9188}
9189
9190////////////////////////////////////////////////////////////////////////////////
9191
9192MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
9193{
9194 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
9195}
9196
9197////////////////////////////////////////////////////////////////////////////////
9198
9199void* TCling::MethodInfo_InterfaceMethod(MethodInfo_t* minfo) const
9200{
9202 // The next call locks the interpreter mutex.
9203 return info->InterfaceMethod();
9204}
9205
9206////////////////////////////////////////////////////////////////////////////////
9207
9208bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
9210 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9211 return info->IsValid();
9212}
9213
9214////////////////////////////////////////////////////////////////////////////////
9215
9216int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
9218 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9219 return info->NArg();
9220}
9221
9222////////////////////////////////////////////////////////////////////////////////
9223
9224int TCling::MethodInfo_NDefaultArg(MethodInfo_t* minfo) const
9226 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9227 return info->NDefaultArg();
9228}
9229
9230////////////////////////////////////////////////////////////////////////////////
9231
9232int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
9234 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9235 return info->Next();
9236}
9237
9238////////////////////////////////////////////////////////////////////////////////
9239
9240Long_t TCling::MethodInfo_Property(MethodInfo_t* minfo) const
9241{
9243 // The next call locks the interpreter mutex.
9244 return info->Property();
9245}
9246
9247////////////////////////////////////////////////////////////////////////////////
9248
9249Long_t TCling::MethodInfo_ExtraProperty(MethodInfo_t* minfo) const
9250{
9252 // The next call locks the interpreter mutex.
9253 return info->ExtraProperty();
9254}
9255
9256////////////////////////////////////////////////////////////////////////////////
9257
9258TypeInfo_t* TCling::MethodInfo_Type(MethodInfo_t* minfo) const
9259{
9261 // The next call locks the interpreter mutex.
9262 return (TypeInfo_t*)info->Type();
9263}
9264
9265////////////////////////////////////////////////////////////////////////////////
9266
9267const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
9268{
9269 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9270 TTHREAD_TLS_DECL(TString, mangled_name);
9271 // The next call locks the interpreter mutex.
9272 mangled_name = info->GetMangledName();
9273 return mangled_name;
9274}
9275
9276////////////////////////////////////////////////////////////////////////////////
9277
9278const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
9279{
9281 // The next call locks the interpreter mutex.
9282 return info->GetPrototype();
9283}
9284
9285////////////////////////////////////////////////////////////////////////////////
9286
9287const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
9288{
9290 // The next call locks the interpreter mutex.
9291 return info->Name();
9292}
9293
9294////////////////////////////////////////////////////////////////////////////////
9295
9296const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
9297{
9299 // The next call locks the interpreter mutex.
9300 return info->TypeName();
9301}
9302
9303////////////////////////////////////////////////////////////////////////////////
9304
9305std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
9306{
9307 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9308 // The next part locks the interpreter mutex.
9309 if (info && info->IsValid())
9311 else
9312 return "";
9313}
9314
9315////////////////////////////////////////////////////////////////////////////////
9316
9317const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
9318{
9320 // The next call locks the interpreter mutex.
9321 return info->Title();
9322}
9323
9324////////////////////////////////////////////////////////////////////////////////
9325
9326auto TCling::MethodCallReturnType(TFunction *func) const -> EReturnType
9327{
9328 if (func) {
9329 return MethodInfo_MethodCallReturnType(func->fInfo);
9330 } else {
9331 return EReturnType::kOther;
9332 }
9333}
9334
9335////////////////////////////////////////////////////////////////////////////////
9336
9337auto TCling::MethodInfo_MethodCallReturnType(MethodInfo_t* minfo) const -> EReturnType
9338{
9339 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9340 if (info && info->IsValid()) {
9341 TClingTypeInfo *typeinfo = info->Type();
9342 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
9343 if (QT->isEnumeralType()) {
9344 return EReturnType::kLong;
9345 } else if (QT->isPointerType()) {
9346 // Look for char*
9347 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
9348 if ( QT->isCharType() ) {
9349 return EReturnType::kString;
9350 } else {
9351 return EReturnType::kOther;
9352 }
9353 } else if ( QT->isFloatingType() ) {
9354 int sz = typeinfo->Size();
9355 if (sz == 4 || sz == 8) {
9356 // Support only float and double.
9357 return EReturnType::kDouble;
9358 } else {
9359 return EReturnType::kOther;
9360 }
9361 } else if ( QT->isIntegerType() ) {
9362 int sz = typeinfo->Size();
9363 if (sz <= 8) {
9364 // Support only up to long long ... but
9365 // FIXME the TMethodCall::Execute only
9366 // return long (4 bytes) ...
9367 // The v5 implementation of TMethodCall::ReturnType
9368 // was not making the distinction so we let it go
9369 // as is for now, but we really need to upgrade
9370 // TMethodCall::Execute ...
9371 return EReturnType::kLong;
9372 } else {
9373 return EReturnType::kOther;
9374 }
9375 } else {
9376 return EReturnType::kOther;
9377 }
9378 } else {
9379 return EReturnType::kOther;
9380 }
9381}
9382
9383//______________________________________________________________________________
9384//
9385// MethodArgInfo interface
9386//
9387
9388////////////////////////////////////////////////////////////////////////////////
9389
9390void TCling::MethodArgInfo_Delete(MethodArgInfo_t* marginfo) const
9391{
9392 delete(TClingMethodArgInfo*) marginfo;
9393}
9394
9395////////////////////////////////////////////////////////////////////////////////
9396
9397MethodArgInfo_t* TCling::MethodArgInfo_Factory() const
9400 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl());
9401}
9402
9403////////////////////////////////////////////////////////////////////////////////
9404
9405MethodArgInfo_t* TCling::MethodArgInfo_Factory(MethodInfo_t *minfo) const
9408 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl(), (TClingMethodInfo*)minfo);
9409}
9410
9411////////////////////////////////////////////////////////////////////////////////
9412
9413MethodArgInfo_t* TCling::MethodArgInfo_FactoryCopy(MethodArgInfo_t* marginfo) const
9415 return (MethodArgInfo_t*)
9417}
9418
9419////////////////////////////////////////////////////////////////////////////////
9420
9421bool TCling::MethodArgInfo_IsValid(MethodArgInfo_t* marginfo) const
9423 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9424 return info->IsValid();
9425}
9426
9427////////////////////////////////////////////////////////////////////////////////
9428
9429int TCling::MethodArgInfo_Next(MethodArgInfo_t* marginfo) const
9431 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9432 return info->Next();
9433}
9434
9435////////////////////////////////////////////////////////////////////////////////
9436
9437Long_t TCling::MethodArgInfo_Property(MethodArgInfo_t* marginfo) const
9439 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9440 return info->Property();
9441}
9442
9443////////////////////////////////////////////////////////////////////////////////
9444
9445const char* TCling::MethodArgInfo_DefaultValue(MethodArgInfo_t* marginfo) const
9447 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9448 return info->DefaultValue();
9449}
9450
9451////////////////////////////////////////////////////////////////////////////////
9452
9453const char* TCling::MethodArgInfo_Name(MethodArgInfo_t* marginfo) const
9455 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9456 return info->Name();
9457}
9458
9459////////////////////////////////////////////////////////////////////////////////
9460
9461const char* TCling::MethodArgInfo_TypeName(MethodArgInfo_t* marginfo) const
9463 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9464 return info->TypeName();
9465}
9466
9467////////////////////////////////////////////////////////////////////////////////
9468
9469std::string TCling::MethodArgInfo_TypeNormalizedName(MethodArgInfo_t* marginfo) const
9471 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9472 return info->Type()->NormalizedName(*fNormalizedCtxt);
9473}
9474
9475////////////////////////////////////////////////////////////////////////////////
9476
9477TypeInfo_t* TCling::MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
9478{
9479 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9480 return (TypeInfo_t*) info->Type();
9481}
9482
9483//______________________________________________________________________________
9484//
9485// TypeInfo interface
9486//
9487
9488////////////////////////////////////////////////////////////////////////////////
9489
9490void TCling::TypeInfo_Delete(TypeInfo_t* tinfo) const
9491{
9492 delete (TClingTypeInfo*) tinfo;
9493}
9494
9495////////////////////////////////////////////////////////////////////////////////
9496
9497TypeInfo_t* TCling::TypeInfo_Factory() const
9500 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl());
9501}
9502
9503////////////////////////////////////////////////////////////////////////////////
9504
9505TypeInfo_t* TCling::TypeInfo_Factory(const char *name) const
9508 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl(), name);
9509}
9510
9511////////////////////////////////////////////////////////////////////////////////
9512
9513TypeInfo_t* TCling::TypeInfo_FactoryCopy(TypeInfo_t* tinfo) const
9514{
9515 return (TypeInfo_t*) new TClingTypeInfo(*(TClingTypeInfo*)tinfo);
9516}
9517
9518////////////////////////////////////////////////////////////////////////////////
9519
9520void TCling::TypeInfo_Init(TypeInfo_t* tinfo, const char* name) const
9521{
9523 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9524 TClinginfo->Init(name);
9525}
9526
9527////////////////////////////////////////////////////////////////////////////////
9528
9529bool TCling::TypeInfo_IsValid(TypeInfo_t* tinfo) const
9531 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9532 return TClinginfo->IsValid();
9533}
9534
9535////////////////////////////////////////////////////////////////////////////////
9536
9537const char* TCling::TypeInfo_Name(TypeInfo_t* tinfo) const
9539 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9540 return TClinginfo->Name();
9541}
9542
9543////////////////////////////////////////////////////////////////////////////////
9544
9545Long_t TCling::TypeInfo_Property(TypeInfo_t* tinfo) const
9547 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9548 return TClinginfo->Property();
9549}
9550
9551////////////////////////////////////////////////////////////////////////////////
9552
9553int TCling::TypeInfo_RefType(TypeInfo_t* tinfo) const
9555 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9556 return TClinginfo->RefType();
9557}
9558
9559////////////////////////////////////////////////////////////////////////////////
9560
9561int TCling::TypeInfo_Size(TypeInfo_t* tinfo) const
9563 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9564 return TClinginfo->Size();
9565}
9566
9567////////////////////////////////////////////////////////////////////////////////
9568
9569const char* TCling::TypeInfo_TrueName(TypeInfo_t* tinfo) const
9571 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9572 return TClinginfo->TrueName(*fNormalizedCtxt);
9573}
9574
9575////////////////////////////////////////////////////////////////////////////////
9576
9577void* TCling::TypeInfo_QualTypePtr(TypeInfo_t* tinfo) const
9578{
9579 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9580 return TClinginfo->QualTypePtr();
9581}
9582
9583
9584//______________________________________________________________________________
9585//
9586// TypedefInfo interface
9587//
9588
9589////////////////////////////////////////////////////////////////////////////////
9590
9591void TCling::TypedefInfo_Delete(TypedefInfo_t* tinfo) const
9592{
9593 delete(TClingTypedefInfo*) tinfo;
9594}
9595
9596////////////////////////////////////////////////////////////////////////////////
9597
9598TypedefInfo_t* TCling::TypedefInfo_Factory() const
9601 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl());
9602}
9603
9604////////////////////////////////////////////////////////////////////////////////
9605
9606TypedefInfo_t* TCling::TypedefInfo_Factory(const char *name) const
9609 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl(), name);
9610}
9611
9612////////////////////////////////////////////////////////////////////////////////
9613
9614TypedefInfo_t* TCling::TypedefInfo_FactoryCopy(TypedefInfo_t* tinfo) const
9615{
9616 return (TypedefInfo_t*) new TClingTypedefInfo(*(TClingTypedefInfo*)tinfo);
9617}
9618
9619////////////////////////////////////////////////////////////////////////////////
9620
9621void TCling::TypedefInfo_Init(TypedefInfo_t* tinfo,
9622 const char* name) const
9623{
9625 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9626 TClinginfo->Init(name);
9627}
9628
9629////////////////////////////////////////////////////////////////////////////////
9630
9631bool TCling::TypedefInfo_IsValid(TypedefInfo_t* tinfo) const
9633 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9634 return TClinginfo->IsValid();
9635}
9636
9637////////////////////////////////////////////////////////////////////////////////
9638
9639Int_t TCling::TypedefInfo_Next(TypedefInfo_t* tinfo) const
9641 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9642 return TClinginfo->Next();
9643}
9644
9645////////////////////////////////////////////////////////////////////////////////
9646
9647Long_t TCling::TypedefInfo_Property(TypedefInfo_t* tinfo) const
9649 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9650 return TClinginfo->Property();
9651}
9652
9653////////////////////////////////////////////////////////////////////////////////
9654
9655int TCling::TypedefInfo_Size(TypedefInfo_t* tinfo) const
9657 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9658 return TClinginfo->Size();
9659}
9660
9661////////////////////////////////////////////////////////////////////////////////
9662
9663const char* TCling::TypedefInfo_TrueName(TypedefInfo_t* tinfo) const
9665 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9666 return TClinginfo->TrueName(*fNormalizedCtxt);
9667}
9668
9669////////////////////////////////////////////////////////////////////////////////
9670
9671const char* TCling::TypedefInfo_Name(TypedefInfo_t* tinfo) const
9673 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9674 return TClinginfo->Name();
9675}
9676
9677////////////////////////////////////////////////////////////////////////////////
9678
9679const char* TCling::TypedefInfo_Title(TypedefInfo_t* tinfo) const
9681 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9682 return TClinginfo->Title();
9683}
9684
9685////////////////////////////////////////////////////////////////////////////////
9686
9687bool TCling::IsSameType(const void * QualTypePtr1, const void * QualTypePtr2) const
9688{
9689 clang::QualType QT1 = clang::QualType::getFromOpaquePtr(QualTypePtr1);
9690 clang::QualType QT2 = clang::QualType::getFromOpaquePtr(QualTypePtr2);
9691 return fInterpreter->getCI()->getASTContext().hasSameType(QT1, QT2);
9692}
9693
9694////////////////////////////////////////////////////////////////////////////////
9695
9696bool TCling::IsIntegerType(const void * QualTypePtr) const
9698 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9699 return QT->hasIntegerRepresentation();
9700}
9701
9702////////////////////////////////////////////////////////////////////////////////
9703
9704bool TCling::IsSignedIntegerType(const void * QualTypePtr) const
9706 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9707 return QT->hasSignedIntegerRepresentation();
9708}
9709
9710////////////////////////////////////////////////////////////////////////////////
9711
9712bool TCling::IsUnsignedIntegerType(const void * QualTypePtr) const
9714 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9715 return QT->hasUnsignedIntegerRepresentation();
9716}
9717
9718////////////////////////////////////////////////////////////////////////////////
9719
9720bool TCling::IsFloatingType(const void * QualTypePtr) const
9722 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9723 return QT->hasFloatingRepresentation();
9724}
9725
9726////////////////////////////////////////////////////////////////////////////////
9727
9728bool TCling::IsPointerType(const void * QualTypePtr) const
9730 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9731 return QT->hasPointerRepresentation();
9732}
9733
9734////////////////////////////////////////////////////////////////////////////////
9735
9736bool TCling::IsVoidPointerType(const void * QualTypePtr) const
9738 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9739 return QT->isVoidPointerType();
9740}
9741
9742////////////////////////////////////////////////////////////////////////////////
9743
9745{
9746 if (!fInitialMutex) {
9748 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
9749 }
9750 fInitialMutex.fState = mtx->GetStateBefore();
9751 }
9752 // We will "forget" this lock once we backed out of all interpreter frames.
9753 // Here we are entering one, so ++.
9754 ++fInitialMutex.fRecurseCount;
9755}
9756
9757////////////////////////////////////////////////////////////////////////////////
9758
9760{
9761 if (!fInitialMutex)
9762 return;
9763 if (fInitialMutex.fRecurseCount == 0) {
9764 Error("ForgetMutexState", "mutex state's recurse count already 0!");
9765 }
9766 else if (--fInitialMutex.fRecurseCount == 0) {
9767 // We have returned from all interpreter frames. Reset the initial lock state.
9768 fInitialMutex.fState.reset();
9769 }
9770}
9771
9772////////////////////////////////////////////////////////////////////////////////
9773/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
9774
9775void TCling::ApplyToInterpreterMutex(void *delta)
9776{
9777 if (gInterpreterMutex) {
9778 if (delta) {
9779 auto typedDelta = static_cast<MutexStateAndRecurseCountDelta *>(delta);
9780 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP{typedDelta};
9781 gCoreMutex->Apply(std::move(typedDelta->fDelta));
9782 // Now that we have the lock, update the global
9783 R__ASSERT(fInitialMutex.fRecurseCount == 0 && "Inconsistent state of fInitialMutex! Another thread within Interpreter critical section.");
9784 std::swap(fInitialMutex, typedDelta->fInitialState);
9785 } else {
9786 // This case happens when EnableThreadSafety is first called from
9787 // the interpreter function we just handled.
9788 // Since thread safety was not enabled at the time we rewound, there was
9789 // no lock taken and even-though we should be locking the rest of this
9790 // interpreter handling/modifying code (since there might be threads in
9791 // flight), we can't because there would not be any lock guard to release the
9792 // locks
9793 if (fInitialMutex || fInitialMutex.fRecurseCount !=0)
9794 Error("ApplyToInterpreterMutex",
9795 "After returning from user code that turned on thread safety support, we notice that fInitialMutex is already used ... "
9796 "so the rest of this function/stack execution might have race condition (with the other thread that thinks it has exclusive access to the interpreter state.");
9797 }
9799}
9800
9801////////////////////////////////////////////////////////////////////////////////
9802/// Reset the interpreter lock to the state it had before interpreter-related
9803/// calls happened.
9804
9806{
9807 if (fInitialMutex) {
9808 // Need to start a new recurse count.
9809 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP(new MutexStateAndRecurseCountDelta());
9810 std::swap(uniqueP->fInitialState, fInitialMutex);
9811 uniqueP->fDelta = gCoreMutex->Rewind(*uniqueP->fInitialState.fState);
9812 return uniqueP.release();
9813 }
9814 R__ASSERT(fInitialMutex.fRecurseCount == 0);
9815 return nullptr;
9816}
#define R__EXTERN
Definition DllImport.h:26
The file contains utilities which are foundational and could be used across the core component of ROO...
#define d(i)
Definition RSha256.hxx:102
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define s1(x)
Definition RSha256.hxx:91
#define R(a, b, c, d, e, f, g, h, i)
Definition RSha256.hxx:110
#define e(i)
Definition RSha256.hxx:103
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
char * ret
Definition Rotated.cxx:221
int Int_t
Signed integer 4 bytes (int).
Definition RtypesCore.h:59
long Longptr_t
Integer large enough to hold a pointer (platform-dependent).
Definition RtypesCore.h:89
short Version_t
Class version identifier (short).
Definition RtypesCore.h:79
int Ssiz_t
String size (currently int).
Definition RtypesCore.h:81
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int).
Definition RtypesCore.h:60
unsigned long ULong_t
Unsigned long integer 4 bytes (unsigned long). Size depends on architecture.
Definition RtypesCore.h:69
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:68
bool Bool_t
Boolean (0=false, 1=true) (bool).
Definition RtypesCore.h:77
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Ssiz_t kNPOS
The equivalent of std::string::npos for the ROOT class TString.
Definition RtypesCore.h:131
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:83
unsigned long long ULong64_t
Portable unsigned long integer 8 bytes.
Definition RtypesCore.h:84
float Float_t
Float 4 bytes (float).
Definition RtypesCore.h:71
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char).
Definition RtypesCore.h:80
TClass *(* DictFuncPtr_t)()
Definition Rtypes.h:86
externTApplication * gApplication
externTClassTable * gClassTable
static bool IsFromRootCling()
Definition TClass.cxx:176
static void indent(ostringstream &buf, int indent_level)
The file contains facilities to work with C++ module files extensions used to store rdict files.
void TCling__RestoreInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:358
void TCling__TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:596
static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
Definition TCling.cxx:1327
static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
Definition TCling.cxx:7380
void TCling__InvalidateGlobal(const clang::Decl *D)
Definition TCling.cxx:591
bool TClingLookupHelper__AutoParse(const char *cname)
Allow calling autoparsing from TMetaUtils.
Definition TCling.cxx:911
externint optind
Definition TCling.cxx:333
void * TCling__LockCompilationDuringUserCodeExecution()
Lock the interpreter.
Definition TCling.cxx:385
void TCling__UpdateListsOnUnloaded(const cling::Transaction &T)
Definition TCling.cxx:586
void TCling__GetNormalizedContext(const ROOT::TMetaUtils::TNormalizedCtxt *&normCtxt)
Definition TCling.cxx:574
int TCling__LoadLibrary(const char *library)
Load a library.
Definition TCling.cxx:349
void TCling__DEBUG__dump(clang::DeclContext *DC)
Definition TCling.cxx:226
bool TClingLookupHelper__CheckInClassTable(const std::string &tname, std::string &result)
Check if the class name is present in TClassTable.
Definition TCling.cxx:1020
ETupleOrdering
Check in what order the member of a tuple are layout.
Definition TCling.cxx:3994
bool TCling__LibraryLoadingFailed(const std::string &errmessage, const std::string &libStem, bool permanent, bool resolved)
Lookup libraries in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH with mangled_name, which is extracted by er...
Definition TCling.cxx:368
static const std::unordered_set< std::string > gIgnoredPCMNames
List of dicts that have the PCM information already in the PCH.
Definition TCling.cxx:1989
static Bool_t s_IsLibraryLoaded(const char *libname, cling::Interpreter *fInterpreter)
Definition TCling.cxx:3210
const char * TCling__GetClassSharedLibs(const char *className, bool skipCore)
Definition TCling.cxx:650
static GlobalModuleIndex * loadGlobalModuleIndex(cling::Interpreter &interp)
Definition TCling.cxx:1115
bool TClingLookupHelper__ExistingTypeCheck(const std::string &tname, std::string &result)
Try hard to avoid looking up in the Cling database as this could enduce an unwanted autoparsing.
Definition TCling.cxx:920
static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName=nullptr)
Checks if there is an ASTFile on disk for the given module M.
Definition TCling.cxx:1100
void TCling__UnlockCompilationDuringUserCodeExecution(void *)
Unlock the interpreter.
Definition TCling.cxx:396
static std::string AlternateTuple(const char *classname, const cling::LookupHelper &lh, Bool_t silent)
Definition TCling.cxx:4036
static bool R__InitStreamerInfoFactory()
Helper to initialize TVirtualStreamerInfo's factor early. Use static initialization to insure only on...
Definition TCling.cxx:1712
int TCling__AutoParseCallback(const char *className)
Definition TCling.cxx:645
clang::RecordDecl * TCling__DEBUG__DCtoRecordDecl(clang::DeclContext *DC)
Definition TCling.cxx:223
int TCling_GenerateDictionary(const std::vector< std::string > &classes, const std::vector< std::string > &headers, const std::vector< std::string > &fwdDecls, const std::vector< std::string > &unknown)
Definition TCling.cxx:716
static bool HaveFullGlobalModuleIndex
Definition TCling.cxx:1114
bool TCling__TEST_isInvalidDecl(clang::Decl *D)
Definition TCling.cxx:253
void TCling__LibraryUnloadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:610
void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter *)
Definition TCling.cxx:581
const Decl * TCling__GetObjectDecl(TObject *obj)
Definition TCling.cxx:621
static ETupleOrdering IsTupleAscending()
Definition TCling.cxx:4012
void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Definition TCling.cxx:605
static void TCling__UpdateClassInfo(const NamedDecl *TD)
Update TClingClassInfo for a class (e.g. upon seeing a definition).
Definition TCling.cxx:406
clang::DeclContext * TCling__DEBUG__getDeclContext(clang::Decl *D)
Definition TCling.cxx:217
int TCling__CompileMacro(const char *fileName, const char *options)
Definition TCling.cxx:661
void * TCling__ResetInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:377
void TCling__DEBUG__decl_dump(void *D)
Definition TCling.cxx:235
int TCling__AutoLoadCallback(const char *className)
Definition TCling.cxx:640
static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
Definition TCling.cxx:1065
static void RegisterCxxModules(cling::Interpreter &clingInterp)
Definition TCling.cxx:1218
static void ConstructorName(std::string &name, const clang::Decl *decl, cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition TCling.cxx:8877
void TCling__PrintStackTrace()
Print a StackTrace!
Definition TCling.cxx:342
static int HandleInterpreterException(cling::MetaProcessor *metaProcessor, const char *input_line, cling::Interpreter::CompilationResult &compRes, cling::Value *result)
Let cling process a command line.
Definition TCling.cxx:2474
static std::string GetSharedLibImmediateDepsSlow(std::string lib, cling::Interpreter *interp, bool skipLoadedLibs=true)
This interface returns a list of dependent libraries in the form: lib libA.so libB....
Definition TCling.cxx:7289
void TCling__DEBUG__printName(clang::Decl *D)
Definition TCling.cxx:238
static clang::ClassTemplateDecl * FindTemplateInNamespace(clang::Decl *decl)
Find a template decl within N nested namespaces, 0<=N<inf Assumes 1 and only 1 template present and 1...
Definition TCling.cxx:697
static void PrintDlError(const char *dyLibName, const char *modulename)
Definition TCling.cxx:2014
TInterpreter * CreateInterpreter(void *interpLibHandle, const char *argv[])
Definition TCling.cxx:625
static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH, bool skipCore)
Definition TCling.cxx:7124
const char * fantomline
Definition TCling.cxx:858
void TCling__LibraryLoadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:600
static cling::Interpreter::CompilationResult ExecAutoParse(const char *what, Bool_t header, cling::Interpreter *interpreter)
Parse the payload or header.
Definition TCling.cxx:6443
static bool requiresRootMap(const char *rootmapfile)
Definition TCling.cxx:5623
clang::NamespaceDecl * TCling__DEBUG__DCtoNamespace(clang::DeclContext *DC)
Definition TCling.cxx:220
TObject * TCling__GetObjectAddress(const char *Name, void *&LookupCtx)
Definition TCling.cxx:617
static void LoadModules(const std::vector< std::string > &modules, cling::Interpreter &interp)
Loads the C++ modules that we require to run any ROOT program. This is just supposed to make a C++ mo...
Definition TCling.cxx:1087
int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:656
void DestroyInterpreter(TInterpreter *interp)
Definition TCling.cxx:633
static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
Definition TCling.cxx:7401
void TCling__SplitAclicMode(const char *fileName, string &mode, string &args, string &io, string &fname)
Definition TCling.cxx:668
EDataType
Definition TDataType.h:28
@ kULong64_t
Definition TDataType.h:32
@ kLong64_t
Definition TDataType.h:32
@ kIsDestructor
@ kIsConversion
@ kIsInlined
@ kIsConstructor
@ kIsOperator
@ kIsPublic
Definition TDictionary.h:75
@ kIsConstant
Definition TDictionary.h:88
@ kIsConstMethod
Definition TDictionary.h:96
@ kIsClass
Definition TDictionary.h:65
@ kIsEnum
Definition TDictionary.h:68
@ kIsPrivate
Definition TDictionary.h:77
@ kIsFundamental
Definition TDictionary.h:70
@ kIsCompiled
Definition TDictionary.h:86
@ kIsStatic
Definition TDictionary.h:80
@ kIsExplicit
Definition TDictionary.h:94
@ kIsStruct
Definition TDictionary.h:66
@ kIsProtected
Definition TDictionary.h:76
@ kIsVirtual
Definition TDictionary.h:72
@ kIsUnion
Definition TDictionary.h:67
@ kIsPureVirtual
Definition TDictionary.h:73
@ kIsNamespace
Definition TDictionary.h:95
@ kIsNotReacheable
Definition TDictionary.h:87
return
Error("WriteTObject","The current directory (%s) is not associated with a file. The object (%s) has not been written.", GetName(), objname)
if(name) objname
#define gDirectory
Definition TDirectory.h:385
@ kEnvUser
Definition TEnv.h:71
@ kEnvGlobal
Definition TEnv.h:70
@ kEnvLocal
Definition TEnv.h:72
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:241
constexpr Int_t kWarning
Definition TError.h:46
externInt_t gErrorIgnoreLevel
errors with level below this value will be ignored. Default is kUnset.
Definition TError.h:140
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
void Fatal(const char *location, const char *msgfmt,...)
Use this function in case of a fatal error. It will abort the program.
Definition TError.cxx:267
#define N
char name[80]
Definition TGX11.cxx:148
#define R__LOCKGUARD_CLING(mutex)
#define gInterpreter
externTInterpreter * gCling
externTVirtualMutex * gInterpreterMutex
Double_t err
Int_t gDebug
Definition TROOT.cxx:777
#define gROOT
Definition TROOT.h:417
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2496
@ kReadPermission
Definition TSystem.h:55
Bool_t R_ISREG(Int_t mode)
Definition TSystem.h:126
externTSystem * gSystem
Definition TSystem.h:582
externTVirtualMutex * gGlobalMutex
#define R__LOCKGUARD(mutex)
#define R__WRITE_LOCKGUARD(mutex)
#define R__READ_LOCKGUARD(mutex)
const char * proto
Definition civetweb.c:18822
#define free
Definition civetweb.c:1578
#define snprintf
Definition civetweb.c:1579
virtual std::unique_ptr< State > GetStateBefore()=0
Storage_t const & get() const
Const access to the underlying stl container.
static Longptr_t ExecuteFile(const char *file, Int_t *error=nullptr, Bool_t keep=kFALSE)
Execute a file containing a C++ macro (static method).
static TProtoClass * GetProtoNorm(const char *cname)
Given the class normalized name returns the TClassProto object for the class.
static DictFuncPtr_t GetDictNorm(const char *cname)
Given the normalized class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProto(const char *cname)
Given the class name returns the TClassProto object for the class.
static Bool_t Check(const char *cname, std::string &normname)
static void Add(const char *cname, Version_t id, const std::type_info &info, DictFuncPtr_t dict, Int_t pragmabits)
Add a class to the class table (this is a static function).
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:84
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
Definition TClass.cxx:3501
EState GetState() const
Definition TClass.h:504
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition TClass.cxx:2907
void RemoveStreamerInfo(Int_t slot)
Remove and delete the StreamerInfo in the given slot.
Definition TClass.cxx:7477
@ kLoading
Definition TClass.h:342
@ kUnloading
Definition TClass.h:342
EState fState
!Current 'state' of the class (Emulated,Interpreted,Loaded)
Definition TClass.h:286
std::atomic< TList * > fBase
Definition TClass.h:204
static void AddClassToDeclIdMap(TDictionary::DeclId_t id, TClass *cl)
static: Add a TClass* to the map of classes.
Definition TClass.cxx:578
Version_t fClassVersion
Definition TClass.h:225
TList * GetListOfFunctionTemplates(Bool_t load=kTRUE)
Return TListOfFunctionTemplates for a class.
Definition TClass.cxx:3856
void * DynamicCast(const TClass *base, void *obj, Bool_t up=kTRUE)
Cast obj of this class type up to baseclass cl if up is true.
Definition TClass.cxx:4973
static void RemoveClassDeclId(TDictionary::DeclId_t id)
Definition TClass.cxx:605
Bool_t CallShowMembers(const void *obj, TMemberInspector &insp, Bool_t isTransient=kFALSE) const
Call ShowMembers() on the obj of this class type, passing insp and parent.
Definition TClass.cxx:2212
std::atomic< TListOfEnums * > fEnums
Definition TClass.h:208
static Bool_t HasNoInfoOrEmuOrFwdDeclaredDecl(const char *)
Definition TClass.cxx:3460
virtual void PostLoadCheck()
Do the initialization that can only be done after the CINT dictionary has been fully populated and ca...
Definition TClass.cxx:6064
static TClass * LoadClass(const char *requestedname, Bool_t silent)
Helper function used by TClass::GetClass().
Definition TClass.cxx:5851
Int_t Size() const
Return size of object of this class.
Definition TClass.cxx:5806
static DictFuncPtr_t GetDict(const char *cname)
Return a pointer to the dictionary loading function generated by rootcint.
Definition TClass.cxx:3484
TObjArray * fStreamerInfo
Definition TClass.h:201
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition TClass.cxx:6017
ClassInfo_t * GetClassInfo() const
Definition TClass.h:448
ClassInfo_t * fClassInfo
Definition TClass.h:226
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:2918
void ResetCaches()
To clean out all caches.
Definition TClass.cxx:4273
Long_t Property() const override
Returns the properties of the TClass as a bit field stored as a Long_t value.
Definition TClass.cxx:6191
static Int_t ReadRules()
Read the class.rules files from the default location:.
Definition TClass.cxx:1808
@ kInterpreted
Definition TClass.h:129
@ kHasTClassInit
Definition TClass.h:130
@ kEmulated
Definition TClass.h:128
@ kForwardDeclared
Definition TClass.h:127
@ kNamespaceForMeta
Definition TClass.h:134
std::atomic< Bool_t > fCanLoadClassInfo
!Indicates whether the ClassInfo is supposed to be available.
Definition TClass.h:269
Version_t GetClassVersion() const
Definition TClass.h:434
std::atomic< Bool_t > fHasRootPcmInfo
!Whether info was loaded from a root pcm.
Definition TClass.h:268
const char * GetDeclFileName() const
Return name of the file containing the declaration of this class.
Definition TClass.cxx:3525
@ kIsTObject
Definition TClass.h:103
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition TClass.cxx:2994
Emulation of the CINT BaseClassInfo class.
const char * TmpltName() const
const char * Name() const
ptrdiff_t Offset(void *address=0, bool isDerivedObject=true) const
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
TClingClassInfo * GetBase() const
Emulation of the CINT CallFunc class.
void SetArgs(const char *args)
void SetFunc(const TClingClassInfo *info, const char *method, const char *arglist, Longptr_t *poffset)
void ExecWithArgsAndReturn(void *address, const void *args[]=0, int nargs=0, void *ret=0)
void Exec(void *address, TInterpreterValue *interpVal=0)
TClingMethodInfo * FactoryMethod() const
bool IsAutoLoadingEnabled() const
void SetAutoLoadingEnabled(bool val=true)
Emulation of the CINT ClassInfo class.
const char * Title()
static bool IsEnum(cling::Interpreter *interp, const char *name)
long ClassProperty() const
void Init(const char *name)
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
EDataType GetUnderlyingType() const
size_t GetAlignOf() const
Return the alignment of the class in bytes as reported by clang.
const char * TmpltName() const
const clang::Type * GetType() const
ptrdiff_t GetBaseOffset(TClingClassInfo *toBase, void *address, bool isDerivedObject)
Longptr_t Tagnum() const
bool IsScopedEnum() const
ROOT::TMetaUtils::EIOCtorCategory HasDefaultConstructor(bool checkio=false, std::string *type_name=nullptr) const
TClingMethodInfo GetMethodWithArgs(const char *fname, const char *arglist, Longptr_t *poffset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch, EInheritanceMode imode=kWithInheritance) const
const clang::FunctionTemplateDecl * GetFunctionTemplate(const char *fname) const
int GetMethodNArg(const char *method, const char *proto, Bool_t objectIsConst, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
bool IsValidMethod(const char *method, const char *proto, Bool_t objectIsConst, Longptr_t *offset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
bool HasMethod(const char *name) const
TDictionary::DeclId_t GetDeclId() const
void DeleteArray(void *arena, bool dtorOnly, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
void * New(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
TClingMethodInfo GetMethod(const char *fname) const
bool IsLoaded() const
const clang::ValueDecl * GetDataMember(const char *name) const
int Size() const
Return the size of the class in bytes as reported by clang.
void Destruct(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
std::vector< std::string > GetUsingNamespaces()
const char * FileName()
bool IsBase(const char *name) const
void Delete(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Emulation of the CINT DataMemberInfo class.
const char * TypeName() const
const char * TypeTrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
llvm::StringRef ValidArrayIndex() const
const char * Name() const override
virtual const char * Name() const
virtual bool IsValid() const
virtual const clang::Decl * GetDecl() const
Uses clang::TextDiagnosticPrinter to format diagnostics, which are then passed to a user-specified fu...
Emulation of the CINT MethodInfo class.
bool IsValid() const override
const char * DefaultValue() const
const TClingTypeInfo * Type() const
const char * TypeName() const
Emulation of the CINT MethodInfo class.
std::string GetMangledName() const
const char * TypeName() const
const char * Name() const override
const clang::FunctionDecl * GetTargetFunctionDecl() const
Get the FunctionDecl, or if this represents a UsingShadowDecl, the underlying target FunctionDecl.
const char * GetPrototype()
long ExtraProperty() const
void * InterfaceMethod() const
void CreateSignature(TString &signature) const
TDictionary::DeclId_t GetDeclId() const
TClingTypeInfo * Type() const
Emulation of the CINT TypeInfo class.
long Property() const
std::string NormalizedName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
const char * Name() const override
int RefType() const
void * QualTypePtr() const
Return the QualType as a void pointer.
bool IsValid() const override
clang::QualType GetQualType() const
void Init(const char *name)
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
Emulation of the CINT TypedefInfo class.
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Get the name of the underlying type of the current typedef.
long Property() const
Return a bit mask of metadata about the current typedef.
const char * Name() const override
Get the name of the current typedef.
void Init(const char *name)
Lookup named typedef and reset the iterator to point to it.
int Next()
Increment the iterator.
int Size() const
Return the size in bytes of the underlying type of the current typedef.
Bridge between cling::Value and ROOT.
Definition TClingValue.h:36
const char * Data()
Definition TCling.cxx:1041
bool Append(const std::string &str)
Append string to the storage if not added already.
Definition TCling.cxx:1049
std::hash< std::string > fHashFunc
Definition TCling.h:627
std::set< size_t > fLinesHashSet
Definition TCling.h:626
std::string fContent
Definition TCling.h:625
This class defines an interface to the cling C++ interpreter.
Definition TCling.h:102
static Int_t DeepAutoLoadImpl(const char *cls, std::unordered_set< std::string > &visited, bool nameIsNormalized)
Definition TCling.cxx:6315
const char * MethodArgInfo_DefaultValue(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9438
bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const final
Definition TCling.cxx:8440
const char * TypeInfo_Name(TypeInfo_t *) const final
Definition TCling.cxx:9530
void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const final
Definition TCling.cxx:9192
void LoadEnums(TListOfEnums &cl) const final
Create list of pointers to enums for TClass cl.
Definition TCling.cxx:4506
void UpdateListOfGlobals() final
No op: see TClingCallbacks (used to update the list of globals).
Definition TCling.cxx:3974
bool TypedefInfo_IsValid(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9624
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE) final
Load library containing the specified class.
Definition TCling.cxx:6376
void CallFunc_Init(CallFunc_t *func) const final
Definition TCling.cxx:8070
void SetGetline(const char *(*getlineFunc)(const char *prompt), void(*histaddFunc)(const char *line)) final
Set a getline function to call when input is needed.
Definition TCling.cxx:3737
bool LibraryLoadingFailed(const std::string &, const std::string &, bool, bool)
Definition TCling.cxx:6685
void GenericError(const char *error) const final
Let the interpreter issue a generic error, and set its error state.
Definition TCling.cxx:7585
std::vector< void * > fRegisterModuleDyLibs
Definition TCling.h:140
void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const final
Definition TCling.cxx:7996
bool IsIntegerType(const void *QualTypePtr) const final
Definition TCling.cxx:9689
TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const final
Definition TCling.cxx:9251
std::vector< std::string > fAutoLoadLibStorage
Definition TCling.h:118
void CallFunc_Delete(CallFunc_t *func) const final
Definition TCling.cxx:7973
Bool_t fLockProcessLine
Definition TCling.h:129
int LoadFile(const char *path) const final
Load a source file or library called path into the interpreter.
Definition TCling.cxx:7628
void ResetAll() final
Reset the Cling state to its initial state.
Definition TCling.cxx:3813
void SetDeclAttr(DeclId_t, const char *) final
Definition TCling.cxx:8863
void HandleNewDecl(const void *DV, bool isDeserialized, std::set< TClass * > &modifiedClasses)
Definition TCling.cxx:513
void InvalidateCachedDecl(const std::tuple< TListOfDataMembers *, TListOfFunctions *, TListOfFunctionTemplates *, TListOfEnums * > &Lists, const clang::Decl *D)
Invalidate cached TCling information for the given declaration, and removed it from the appropriate o...
Definition TCling.cxx:7020
Long_t MethodInfo_Property(MethodInfo_t *minfo) const final
Definition TCling.cxx:9233
void LoadFunctionTemplates(TClass *cl) const final
Create list of pointers to function templates for TClass cl.
Definition TCling.cxx:4553
bool ClassInfo_IsValidMethod(ClassInfo_t *info, const char *method, const char *proto, Longptr_t *offset, ROOT::EFunctionMatchMode=ROOT::kConversionMatch) const final
Definition TCling.cxx:8474
Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8796
int SetClassAutoparsing(int) final
Enable/Disable the Autoparsing of headers.
Definition TCling.cxx:7713
std::vector< const char * > fCurExecutingMacros
Definition TCling.h:151
void CreateListOfDataMembers(TClass *cl) const final
Create list of pointers to data members for TClass cl.
Definition TCling.cxx:4600
void RewindDictionary() final
Rewind Cling dictionary to the point where it was before executing the current macro.
Definition TCling.cxx:3858
bool ClassInfo_IsValid(ClassInfo_t *info) const final
Definition TCling.cxx:8466
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition TCling.cxx:6894
int TypeInfo_RefType(TypeInfo_t *) const final
Definition TCling.cxx:9546
void CreateListOfBaseClasses(TClass *cl) const final
Create list of pointers to base class(es) for TClass cl.
Definition TCling.cxx:4477
ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const final
Definition TCling.cxx:8353
const char * MethodInfo_Name(MethodInfo_t *minfo) const final
Definition TCling.cxx:9280
BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const final
Definition TCling.cxx:8610
Bool_t LoadText(const char *text) const final
Load the declarations from text into the interpreter.
Definition TCling.cxx:7643
const char * GetSharedLibDeps(const char *lib, bool tryDyld=false) final
Get the list a libraries on which the specified lib depends.
Definition TCling.cxx:7417
EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const final
Definition TCling.cxx:9330
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition TCling.cxx:7844
Longptr_t ProcessLineAsynch(const char *line, EErrorCode *error=nullptr)
Let cling process a command line asynch.
Definition TCling.cxx:3649
bool MethodInfo_IsValid(MethodInfo_t *minfo) const final
Definition TCling.cxx:9201
FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8953
TypeInfo_t * TypeInfo_Factory() const final
Definition TCling.cxx:9490
bool IsClassAutoLoadingEnabled() const
Returns if class AutoLoading is currently enabled.
Definition TCling.cxx:7682
void InvalidateGlobal(const clang::Decl *D)
Invalidate stored TCling state for declarations included in transaction `T'.
Definition TCling.cxx:7005
bool IsSameType(const void *QualTypePtr1, const void *QualTypePtr2) const final
Definition TCling.cxx:9680
int Evaluate(const char *, TInterpreterValue &) final
Get the interpreter value corresponding to the statement.
Definition TCling.cxx:7806
std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const final
Definition TCling.cxx:7791
void UpdateListOfLoadedSharedLibraries()
Definition TCling.cxx:3429
const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9672
~TCling() final
Destroy the interpreter interface.
Definition TCling.cxx:1664
void CallFunc_SetFuncProto(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *proto, Longptr_t *Offset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const final
Interface to cling function.
Definition TCling.cxx:8195
void InitRootmapFile(const char *name)
Create a resource table and read the (possibly) three resource files, i.e.
Definition TCling.cxx:5766
Int_t AutoParse(const char *cls) final
Parse the headers relative to the class Returns 1 in case of success, 0 in case of failure.
Definition TCling.cxx:6640
void LoadPCM(std::string pcmFileNameFullPath)
Tries to load a rdict PCM, issues diagnostics if it fails. The caller of this function should be hold...
Definition TCling.cxx:1861
void UpdateListOfMethods(TClass *cl) const final
Update the list of pointers to method for TClass cl This is now a nop.
Definition TCling.cxx:4618
void AddFriendToClass(clang::FunctionDecl *, clang::CXXRecordDecl *) const
Inject function as a friend into klass.
Definition TCling.cxx:7897
void PrintIntro() final
No-op; see TRint instead.
Definition TCling.cxx:2699
Bool_t fCxxModulesEnabled
Definition TCling.h:130
int BaseClassInfo_Next(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8630
void RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
Internal function. Actually do the update of the ClassInfo when seeing.
Definition TCling.cxx:6752
CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const final
Definition TCling.cxx:8047
Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const final
Definition TCling.cxx:8031
std::set< std::string > fAutoLoadedLibraries
Definition TCling.h:125
void CallFunc_ResetArg(CallFunc_t *func) const final
Definition TCling.cxx:8096
const char * GetCurrentMacroName() const final
Return the file name of the currently interpreted file, included or not.
Definition TCling.cxx:5574
Bool_t IsLoaded(const char *filename) const final
Return true if the file has already been loaded by cint.
Definition TCling.cxx:3253
void SaveGlobalsContext() final
Save the current Cling state of global objects.
Definition TCling.cxx:3961
void CallFunc_IgnoreExtraArgs(CallFunc_t *func, bool ignore) const final
Definition TCling.cxx:8062
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:9768
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition TCling.cxx:6708
Int_t GenerateDictionary(const char *classes, const char *includes="", const char *options=nullptr) final
Generate the dictionary for the C++ classes listed in the first argument (in a semi-colon separated l...
Definition TCling.cxx:4834
Bool_t ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const final
Return true if the entity pointed to by 'declid' is declared in the context described by 'info'.
Definition TCling.cxx:8269
Bool_t IsLibraryLoaded(const char *libname) const final
Definition TCling.cxx:3219
Long_t GetExecByteCode() const final
This routines used to return the address of the internal wrapper function (of the interpreter) that w...
Definition TCling.cxx:7607
int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8722
DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8756
Bool_t HandleNewTransaction(const cling::Transaction &T)
Helper function to increase the internal Cling count of transactions that change the AST.
Definition TCling.cxx:3754
int ReadRootmapFile(const char *rootmapfile, TUniqueString *uniqueString=nullptr)
Read and parse a rootmapfile in its new format, and return 0 in case of success, -1 if the file has a...
Definition TCling.cxx:5639
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition TCling.h:155
int ClassInfo_Next(ClassInfo_t *info) const final
Definition TCling.cxx:8490
void SetErrmsgcallback(void *p) const final
Set a callback to receive error messages.
Definition TCling.cxx:7734
bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9414
int TypeInfo_Size(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9554
Int_t DeleteGlobal(void *obj) final
Delete obj from Cling symbol table so it cannot be accessed anymore.
Definition TCling.cxx:3872
int GetSecurityError() const final
Interface to cling function.
Definition TCling.cxx:7615
TCling(const char *name, const char *title, const char *const argv[], void *interpLibHandle)
Initialize the cling interpreter interface.
Definition TCling.cxx:1366
void SetTempLevel(int val) const final
Create / close a scope for temporaries.
Definition TCling.cxx:7770
void Print(Option_t *option="") const final
Print information about the interpreter.
Definition TCling.cxx:2709
std::set< size_t > fPayloads
Definition TCling.h:122
UInt_t FuncTempInfo_TemplateNargs(FuncTempInfo_t *) const final
Return the maximum number of template arguments of the function template described by ft_info.
Definition TCling.cxx:8987
DeclId_t GetFunctionWithPrototype(ClassInfo_t *cl, const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) final
Return pointer to cling interface function for a method of a class with a certain prototype,...
Definition TCling.cxx:5266
TypedefInfo_t * TypedefInfo_Factory() const final
Definition TCling.cxx:9591
TObjArray * fRootmapFiles
Definition TCling.h:128
Longptr_t ProcessLine(const char *line, EErrorCode *error=nullptr) final
Definition TCling.cxx:2504
int ClassInfo_Size(ClassInfo_t *info) const final
Definition TCling.cxx:8538
const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9454
cling::Interpreter * GetInterpreterImpl() const
Definition TCling.h:650
Longptr_t ExecuteMacro(const char *filename, EErrorCode *error=nullptr) final
Execute a cling macro.
Definition TCling.cxx:5514
std::vector< std::pair< TClass *, DictFuncPtr_t > > fClassesToUpdate
Definition TCling.h:148
int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8780
const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9664
void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8603
Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const final
Definition TCling.cxx:9242
void LoadMacro(const char *filename, EErrorCode *error=nullptr) final
Load a macro file in cling's memory.
Definition TCling.cxx:3641
FuncTempInfo_t * FuncTempInfo_FactoryCopy(FuncTempInfo_t *) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8964
int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const final
Definition TCling.cxx:8772
Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const final
Check validity of a FuncTempInfo_t.
Definition TCling.cxx:8975
void AddIncludePath(const char *path) final
Add a directory to the list of directories in which the interpreter looks for include files.
Definition TCling.cxx:2741
bool ClassInfo_IsBase(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8425
void RecursiveRemove(TObject *obj) final
Delete object from cling symbol table so it can not be used anymore.
Definition TCling.cxx:3772
const char * DataMemberInfo_TypeName(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8820
DeclId_t GetDataMemberAtAddr(const void *addr) const final
Return pointer to cling DeclId for a data member with a given name.
Definition TCling.cxx:5061
void CallFunc_SetArgArray(CallFunc_t *func, Longptr_t *paramArr, Int_t nparam) const final
Definition TCling.cxx:8152
std::string CallFunc_GetWrapperCode(CallFunc_t *func) const final
Definition TCling.cxx:8242
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:9798
const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9446
Bool_t HasPCMForLibrary(const char *libname) const final
Return true if ROOT has cxxmodules pcm for a given library name.
Definition TCling.cxx:3228
void TypedefInfo_Init(TypedefInfo_t *tinfo, const char *name) const final
Definition TCling.cxx:9614
const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8844
Longptr_t CallFunc_ExecInt(CallFunc_t *func, void *address) const final
Definition TCling.cxx:8015
void ClearStack() final
Delete existing temporary values.
Definition TCling.cxx:3166
void SetAlloclockfunc(void(*)()) const final
[Place holder for Mutex Lock] Provide the interpreter with a way to acquire a lock used to protect cr...
Definition TCling.cxx:7664
Bool_t SetErrorMessages(Bool_t enable=kTRUE) final
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition TCling.cxx:7484
MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const final
Definition TCling.cxx:8054
void RegisterAutoLoadedLibrary(const char *libname) final
Register that a library was autoloaded either to provide a 'missing' symbol or to provide a class (se...
Definition TCling.cxx:3495
TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9607
void GetFunctionOverloads(ClassInfo_t *cl, const char *funcname, std::vector< DeclId_t > &res) const final
Insert overloads of name in cl to res.
Definition TCling.cxx:5159
void UnRegisterTClassUpdate(const TClass *oldcl) final
If the dictionary is loaded, we can remove the class from the list (otherwise the class might be load...
Definition TCling.cxx:2444
std::string MethodArgInfo_TypeNormalizedName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9462
DeclId_t GetEnum(TClass *cl, const char *name) const final
Return pointer to cling Decl of global/static variable that is located at the address given by addr.
Definition TCling.cxx:4943
Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9430
int TypedefInfo_Size(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9648
void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:8004
void GetInterpreterTypeName(const char *name, std::string &output, Bool_t full=kFALSE) final
The 'name' is known to the interpreter, this function returns the internal version of this name (usua...
Definition TCling.cxx:5311
Int_t fGlobalsListSerial
Definition TCling.h:114
TString fSharedLibs
Definition TCling.h:113
std::map< std::string, llvm::StringRef > fPendingRdicts
Definition TCling.h:640
static void UpdateClassInfoWork(const char *name)
Definition TCling.cxx:6874
Int_t Load(const char *filenam, Bool_t system=kFALSE) final
Load a library file in cling's memory.
Definition TCling.cxx:3604
int TypedefInfo_Next(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9632
void * GetInterfaceMethod(TClass *cl, const char *method, const char *params, Bool_t objectIsConst=kFALSE) final
Return pointer to cling interface function for a method of a class with parameters params (params is ...
Definition TCling.cxx:5118
void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const final
Definition TCling.cxx:9513
Bool_t SetSuspendAutoParsing(Bool_t value) final
Suspend the Autoparsing of headers.
Definition TCling.cxx:7724
int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8812
static void * fgSetOfSpecials
Definition TCling.h:105
const char * ClassInfo_Title(ClassInfo_t *info) const final
Definition TCling.cxx:8580
const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8836
const char * TypeName(const char *typeDesc) final
Return the absolute type of typeDesc.
Definition TCling.cxx:5589
ROOT::TMetaUtils::TNormalizedCtxt * fNormalizedCtxt
Definition TCling.h:136
void ForgetMutexState() final
Definition TCling.cxx:9752
int MethodInfo_Next(MethodInfo_t *minfo) const final
Definition TCling.cxx:9225
Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const final
Definition TCling.cxx:8314
void MethodInfo_Delete(MethodInfo_t *minfo) const final
Interface to cling function.
Definition TCling.cxx:9144
bool fIsShuttingDown
Definition TCling.h:189
void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9383
bool IsSignedIntegerType(const void *QualTypePtr) const final
Definition TCling.cxx:9697
DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo, TDictionary::EMemberSelection selection) const final
Definition TCling.cxx:8737
void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const final
Definition TCling.cxx:8345
TClass * GetClass(const std::type_info &typeinfo, Bool_t load) const final
Demangle the name (from the typeinfo) and then request the class via the usual name based interface (...
Definition TCling.cxx:6221
Int_t UnloadAllSharedLibraryMaps() final
Unload the library map entries coming from all the loaded shared libraries.
Definition TCling.cxx:6109
void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const final
Definition TCling.cxx:8407
std::set< TClass * > & GetModTClasses()
Definition TCling.h:585
ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const final
Definition TCling.cxx:8675
TClingCallbacks * fClingCallbacks
Definition TCling.h:141
Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const final
Definition TCling.cxx:8023
Long_t ClassInfo_Property(ClassInfo_t *info) const final
Definition TCling.cxx:8530
Longptr_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8654
void UpdateEnumConstants(TEnum *enumObj, TClass *cl) const final
Definition TCling.cxx:438
void ExecuteWithArgsAndReturn(TMethod *method, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:5496
Bool_t IsErrorMessagesEnabled() const final
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition TCling.cxx:7470
TString fIncludePath
Definition TCling.h:115
int DisplayIncludePath(FILE *fout) const final
Interface to cling function.
Definition TCling.cxx:7547
void TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:7079
Long_t FuncTempInfo_Property(FuncTempInfo_t *) const final
Return the property of the function template.
Definition TCling.cxx:9008
TEnum * CreateEnum(void *VD, TClass *cl) const final
Definition TCling.cxx:486
const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9562
Int_t UnloadLibraryMap(const char *library) final
Unload library map entries coming from the specified library.
Definition TCling.cxx:6127
void RegisterTemporary(const TInterpreterValue &value)
Definition TCling.cxx:7817
MutexStateAndRecurseCount fInitialMutex
Definition TCling.h:176
const char * GetSharedLibs() final
Return the list of shared libraries loaded into the process.
Definition TCling.cxx:7117
int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9422
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx) final
Definition TCling.cxx:9737
Long_t TypeInfo_Property(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9538
const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const final
Definition TCling.cxx:9271
UInt_t FuncTempInfo_TemplateMinReqArgs(FuncTempInfo_t *) const final
Return the number of required template arguments of the function template described by ft_info.
Definition TCling.cxx:8998
std::vector< cling::Value > * fTemporaries
Definition TCling.h:135
void RegisterModule(const char *modulename, const char **headers, const char **includePaths, const char *payloadCode, const char *fwdDeclsCode, void(*triggerFunc)(), const FwdDeclArgsToKeepCollection_t &fwdDeclsArgToSkip, const char **classesHeaders, Bool_t lateRegistration=false, Bool_t hasCxxModule=false) final
Inject the module named "modulename" into cling; load all headers. headers is a 0-terminated array of...
Definition TCling.cxx:2061
static Int_t ShallowAutoLoadImpl(const char *cls)
Definition TCling.cxx:6267
void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const final
Definition TCling.cxx:9151
Bool_t CheckClassTemplate(const char *name) final
Return true if there is a class template by the given name ...
Definition TCling.cxx:4455
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:7102
void RegisterTClassUpdate(TClass *oldcl, DictFuncPtr_t dict) final
Register classes that already existed prior to their dictionary loading and that already had a ClassI...
Definition TCling.cxx:2435
bool IsVoidPointerType(const void *QualTypePtr) const final
Definition TCling.cxx:9729
TObjArray * GetRootMapFiles() const final
Definition TCling.h:226
bool DataMemberInfo_IsValid(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8764
bool ClassInfo_IsEnum(const char *name) const final
Definition TCling.cxx:8433
int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9217
bool IsFloatingType(const void *QualTypePtr) const final
Definition TCling.cxx:9713
void CreateListOfMethods(TClass *cl) const final
Create list of pointers to methods for TClass cl.
Definition TCling.cxx:4609
Int_t RescanLibraryMap() final
Scan again along the dynamic path for library maps.
Definition TCling.cxx:6036
std::map< const cling::Transaction *, size_t > fTransactionHeadersMap
Definition TCling.h:120
void ReportDiagnosticsToErrorHandler(bool enable=true) final
Report diagnostics to the ROOT error handler (see TError.h).
Definition TCling.cxx:7743
const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9260
TypeInfo_t * MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9470
Bool_t fHeaderParsingOnDemand
Definition TCling.h:183
std::hash< std::string > fStringHashFunction
Definition TCling.h:126
TEnv * fMapfile
Definition TCling.h:117
static void RemoveAndInvalidateObject(List &L, Object *O)
Definition TCling.h:597
void * GetInterfaceMethodWithPrototype(TClass *cl, const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) final
Return pointer to cling interface function for a method of a class with a certain prototype,...
Definition TCling.cxx:5221
void * ClassInfo_New(ClassInfo_t *info) const final
Definition TCling.cxx:8498
int DisplayClass(FILE *fout, const char *name, int base, int start) const final
Definition TCling.cxx:7538
void GetFunctionName(const clang::Decl *decl, std::string &name) const
Definition TCling.cxx:8899
void CreateListOfMethodArgs(TFunction *m) const final
Create list of pointers to method arguments for TMethod m.
Definition TCling.cxx:4634
const char * GetSTLIncludePath() const final
Return the directory containing CINT's stl cintdlls.
Definition TCling.cxx:7529
MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9406
Longptr_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8646
ECheckClassInfo CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly=kFALSE) final
Checks if an entity with the specified name is defined in Cling.
Definition TCling.cxx:4283
void * FindSym(const char *entry) const final
Interface to cling function.
Definition TCling.cxx:7576
void RegisterLoadedSharedLibrary(const char *name)
Register a new shared library name with the interpreter; add it to fSharedLibs.
Definition TCling.cxx:3504
void TypeInfo_Delete(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9483
int MethodInfo_NArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9209
DeclId_t GetDataMemberWithValue(const void *ptrvalue) const final
NOT IMPLEMENTED.
Definition TCling.cxx:5052
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition TCling.h:127
EReturnType MethodCallReturnType(TFunction *func) const final
Definition TCling.cxx:9319
void ProcessClassesToUpdate()
Definition TCling.cxx:2030
DeclId_t GetFunctionWithValues(ClassInfo_t *cl, const char *method, const char *params, Bool_t objectIsConst=kFALSE) final
Return pointer to cling DeclId for a method of a class with a certain prototype, i....
Definition TCling.cxx:5244
TString GetMangledName(TClass *cl, const char *method, const char *params, Bool_t objectIsConst=kFALSE) final
Return the cling mangled name for a method of a class with parameters params (params is a string of a...
Definition TCling.cxx:5073
const char * MethodInfo_Title(MethodInfo_t *minfo) const final
Definition TCling.cxx:9310
TString fRootmapLoadPath
Definition TCling.h:116
const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8709
Bool_t Declare(const char *code) final
Declare code to the interpreter, without any of the interpreter actions that could trigger a re-inter...
Definition TCling.cxx:3179
const char * BaseClassInfo_FullName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8691
void CallFunc_SetArgs(CallFunc_t *func, const char *param) const final
Definition TCling.cxx:8160
int UnloadFile(const char *path) const final
Definition TCling.cxx:7776
void SetClassInfo(TClass *cl, Bool_t reload=kFALSE, Bool_t silent=kFALSE) final
Set pointer to the TClingClassInfo in TClass.
Definition TCling.cxx:4147
void CallFunc_Exec(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7980
Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const final
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition TCling.cxx:9073
bool CallFunc_IsValid(CallFunc_t *func) const final
Definition TCling.cxx:8079
const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8701
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition TCling.h:137
const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8852
Int_t GetMore() const final
Return whether we are waiting for more input either because the collected input contains unbalanced b...
Definition TCling.cxx:4655
Bool_t fIsAutoParsingSuspended
Definition TCling.h:184
std::string ToString(const char *type, void *obj) final
Definition TCling.cxx:1058
DeclId_t GetDeclId(const llvm::GlobalValue *gv) const
Return pointer to cling DeclId for a global value.
Definition TCling.cxx:4983
void Execute(const char *function, const char *params, int *error=nullptr) final
Execute a global function with arguments params.
Definition TCling.cxx:5344
bool ClassInfo_IsLoaded(ClassInfo_t *info) const final
Definition TCling.cxx:8458
Longptr_t ClassInfo_Tagnum(ClassInfo_t *info) const final
Definition TCling.cxx:8546
Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8667
void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Longptr_t *Offset) const final
Definition TCling.cxx:8168
std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const final
Get the scopes representing using declarations of namespace.
Definition TCling.cxx:4589
const char * ClassInfo_FileName(ClassInfo_t *info) const final
Definition TCling.cxx:8554
void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const final
Return the comments associates with this function template.
Definition TCling.cxx:9112
const char * ClassInfo_TmpltName(ClassInfo_t *info) const final
Definition TCling.cxx:8588
void SaveContext() final
Save the current Cling state.
Definition TCling.cxx:3948
void LoadPCMImpl(TFile &pcmFile)
Tries to load a PCM from TFile; returns true on success. The caller of this function should be holdin...
Definition TCling.cxx:1745
Bool_t IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:6744
void ResetGlobals() final
Reset in Cling the list of global variables to the state saved by the last call to TCling::SaveGlobal...
Definition TCling.cxx:3829
void CodeComplete(const std::string &, size_t &, std::vector< std::string > &) final
The call to Cling's tab complition.
Definition TCling.cxx:7798
void ResetGlobalVar(void *obj) final
Reset the Cling 'user' global objects/variables state to the state saved by the last call to TCling::...
Definition TCling.cxx:3843
const char * MapCppName(const char *) const final
Interface to cling function.
Definition TCling.cxx:7651
Longptr_t Calc(const char *line, EErrorCode *error=nullptr) final
Directly execute an executable statement (e.g.
Definition TCling.cxx:3674
Int_t ReloadAllSharedLibraryMaps() final
Reload the library map entries coming from all the loaded shared libraries, after first unloading the...
Definition TCling.cxx:6048
void UpdateListOfGlobalFunctions() final
No op: see TClingCallbacks (used to update the list of global functions).
Definition TCling.cxx:3981
void DataMemberInfo_Delete(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8730
char fPrompt[64]
Definition TCling.h:110
const char * GetTopLevelMacroName() const final
Return the file name of the current un-included interpreted file.
Definition TCling.cxx:5527
void * fPrevLoadedDynLibInfo
Definition TCling.h:139
void UpdateListOfDataMembers(TClass *cl) const
Update the list of pointers to data members for TClass cl This is now a nop.
Definition TCling.cxx:4627
void InspectMembers(TMemberInspector &, const void *obj, const TClass *cl, Bool_t isTransient) final
Visit all members over members, recursing over base classes.
Definition TCling.cxx:2763
Int_t SetClassSharedLibs(const char *cls, const char *libs) final
Register the AutoLoading information for a class.
Definition TCling.cxx:6189
MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const final
Definition TCling.cxx:9185
std::set< const char * > fParsedPayloadsAddresses
Definition TCling.h:123
CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const final
Definition TCling.cxx:8088
MethodArgInfo_t * MethodArgInfo_Factory() const final
Definition TCling.cxx:9390
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition TCling.cxx:6868
DeclId_t GetFunction(ClassInfo_t *cl, const char *funcname) final
Return pointer to cling interface function for a method of a class with a certain name.
Definition TCling.cxx:5140
void ClassInfo_Delete(ClassInfo_t *info) const final
Definition TCling.cxx:8322
std::unique_ptr< cling::Interpreter > fInterpreter
Definition TCling.h:132
EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const final
Definition TCling.cxx:8449
void FuncTempInfo_Delete(FuncTempInfo_t *) const final
Delete the FuncTempInfo_t.
Definition TCling.cxx:8944
bool IsUnsignedIntegerType(const void *QualTypePtr) const final
Definition TCling.cxx:9705
DeclId_t GetFunctionTemplate(ClassInfo_t *cl, const char *funcname) final
Return pointer to cling interface function for a method of a class with a certain name.
Definition TCling.cxx:5288
Int_t DeleteVariable(const char *name) final
Undeclare obj called name.
Definition TCling.cxx:3887
const char * GetClassSharedLibs(const char *cls, bool skipCore=true) final
Get the list of shared libraries containing the code for class cls.
Definition TCling.cxx:7223
Longptr_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8788
CallFunc_t * CallFunc_Factory() const final
Definition TCling.cxx:8039
MethodInfo_t * MethodInfo_Factory() const final
Definition TCling.cxx:9160
Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8804
void ClearFileBusy() final
Reset the interpreter internal state in case a previous action was not correctly terminated.
Definition TCling.cxx:3158
cling::MetaProcessor * GetMetaProcessorImpl() const
Definition TCling.h:651
bool DiagnoseIfInterpreterException(const std::exception &e) const final
Definition TCling.cxx:2493
void SetAllocunlockfunc(void(*)()) const final
[Place holder for Mutex Unlock] Provide the interpreter with a way to release a lock used to protect ...
Definition TCling.cxx:7674
std::set< size_t > fLookedUpClasses
Definition TCling.h:121
bool IsValid() const final
Check if constructor exited correctly, ie the instance is in a valid state.
Definition TCling.cxx:3149
void AddAvailableIndentifiers(TSeqCollection &Idents) final
Definition TCling.cxx:2409
void TypedefInfo_Delete(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9584
void Reset() final
Pressing Ctrl+C should forward here.
Definition TCling.cxx:3797
const char * TypedefInfo_TrueName(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9656
int SetClassAutoLoading(int) const final
Enable/Disable the AutoLoading of libraries.
Definition TCling.cxx:7695
const char * ClassInfo_FullName(ClassInfo_t *info) const final
Definition TCling.cxx:8562
UInt_t AutoParseImplRecurse(const char *cls, bool topLevel)
Helper routine for TCling::AutoParse implementing the actual call to the parser and looping over temp...
Definition TCling.cxx:6492
const char * MethodInfo_TypeName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9289
void CallFunc_SetArg(CallFunc_t *func, Long_t param) const final
Definition TCling.cxx:8104
const char * GetIncludePath() final
Refresh the list of include paths known to the interpreter and return it with -I prepended.
Definition TCling.cxx:7498
void UpdateListsOnUnloaded(const cling::Transaction &T)
void UpdateClassInfoWithDecl(const clang::NamedDecl *ND)
Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
Definition TCling.cxx:6810
void Initialize() final
Initialize the interpreter, once TROOT::fInterpreter is set.
Definition TCling.cxx:1682
int ClassInfo_GetMethodNArg(ClassInfo_t *info, const char *method, const char *proto, Bool_t objectIsConst=false, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const final
Definition TCling.cxx:8383
DeclId_t GetDataMember(ClassInfo_t *cl, const char *name) const final
Return pointer to cling Decl of global/static variable that is located at the address given by addr.
Definition TCling.cxx:4882
void * fAutoLoadCallBack
Definition TCling.h:149
void FuncTempInfo_Name(FuncTempInfo_t *, TString &name) const final
Return the name of this function template.
Definition TCling.cxx:9099
std::unique_ptr< cling::MetaProcessor > fMetaProcessor
Definition TCling.h:133
bool TypeInfo_IsValid(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9522
bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const final
Definition TCling.cxx:1956
std::string MethodInfo_TypeNormalizedName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9298
const char * ClassInfo_Name(ClassInfo_t *info) const final
Definition TCling.cxx:8572
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE) final
Generate a TClass for the given class.
Definition TCling.cxx:4665
ULong64_t fTransactionCount
Definition TCling.h:150
std::set< std::string > fAutoParseClasses
Definition TCling.h:124
bool ClassInfo_HasDefaultConstructor(ClassInfo_t *info, Bool_t testio=kFALSE) const final
Definition TCling.cxx:8391
void EndOfLineAction() final
It calls a "fantom" method to synchronize user keyboard input and ROOT prompt line.
Definition TCling.cxx:3202
TypeInfo_t * TypeInfo_FactoryCopy(TypeInfo_t *) const final
Definition TCling.cxx:9506
size_t ClassInfo_AlignOf(ClassInfo_t *info) const final
Definition TCling.cxx:8258
bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8399
void ClassInfo_DeleteArray(ClassInfo_t *info, void *arena, bool dtorOnly) const final
Definition TCling.cxx:8337
std::map< size_t, std::vector< const char * > > fClassesHeadersMap
Definition TCling.h:119
const char * DataMemberInfo_TypeTrueName(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8828
void ShutDown() final
Definition TCling.cxx:1703
void UpdateListOfTypes() final
No op: see TClingCallbacks (used to update the list of types).
Definition TCling.cxx:3988
void * TypeInfo_QualTypePtr(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9570
Long_t TypedefInfo_Property(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9640
void RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Register Rdict data for future loading by LoadPCM;.
Definition TCling.cxx:1726
Longptr_t ProcessLineSynch(const char *line, EErrorCode *error=nullptr) final
Let cling process a command line synchronously, i.e we are waiting it will be finished.
Definition TCling.cxx:3658
TString GetMangledNameWithPrototype(TClass *cl, const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) final
Return the cling mangled name for a method of a class with a certain prototype, i....
Definition TCling.cxx:5100
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition TCling.cxx:6883
Int_t LoadLibraryMap(const char *rootmapfile=nullptr) final
Load map between class and library.
Definition TCling.cxx:5852
Longptr_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8683
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:7109
bool IsPointerType(const void *QualTypePtr) const final
Definition TCling.cxx:9721
Collection abstract base class.
Definition TCollection.h:65
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual void Add(TObject *obj)=0
TObject * FindObject(const char *name) const override
Find an object in this collection using its name.
Bool_t Contains(const char *name) const
All ROOT classes may have RTTI (run time type identification) support added.
Definition TDataMember.h:31
Bool_t IsPersistent() const
Definition TDataMember.h:91
Basic data type descriptor (datatype information is obtained from CINT).
Definition TDataType.h:44
Int_t GetType() const
Definition TDataType.h:71
EMemberSelection
Kinds of members to include in lists.
const void * DeclId_t
TList * GetListOfKeys() const override
friend class TContext
Definition TDirectory.h:169
void GetObject(const char *namecycle, T *&ptr)
Get an object with proper type checking.
Definition TDirectory.h:213
The TEnumConstant class implements the constants of the enum type.
The TEnum class implements the enum type.
Definition TEnum.h:33
const TSeqCollection * GetConstants() const
Definition TEnum.h:73
static TEnum * GetEnum(const std::type_info &ti, ESearchAction sa=kALoadAndInterpLookup)
Definition TEnum.cxx:181
DeclId_t GetDeclId() const
Definition TEnum.cxx:148
@ kNone
Definition TEnum.h:55
@ kAutoload
Definition TEnum.h:59
Definition TEnv.h:86
const char * GetValue() const
Definition TEnv.h:110
const char * GetName() const override
Returns name of object.
Definition TEnv.h:109
The TEnv class reads config files, by default named .rootrc.
Definition TEnv.h:124
Bool_t IgnoreDuplicates(Bool_t ignore)
If set to true, no warnings in case of duplicates are issued.
Definition TEnv.cxx:801
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
Definition TFile.h:130
Global functions class (global functions are obtained from CINT).
Definition TFunction.h:30
MethodInfo_t * fInfo
Definition TFunction.h:36
Global variables class (global variables are obtained from CINT).
Definition TGlobal.h:28
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition THashList.h:34
THashTable implements a hash table to store TObject's.
Definition THashTable.h:35
virtual const void * GetValAddr() const =0
This class defines an abstract interface to a generic command line interpreter.
int(* AutoLoadCallBack_t)(const char *)
friend class SuspendAutoParsing
std::vector< std::pair< std::string, int > > FwdDeclArgsToKeepCollection_t
TDictionary::DeclId_t DeclId_t
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition TKey.h:28
A collection of TDataMember objects designed for fast access given a DeclId_t and for keep track of T...
TObject * FindObject(const char *name) const override
Specialize FindObject to do search for the a data member just by name or create it if its not already...
TDictionary * Find(DeclId_t id) const
Return (after creating it if necessary) the TDataMember describing the data member corresponding to t...
TClass * GetClass() const
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
TEnum * Find(DeclId_t id) const
Return the TEnum corresponding to the Decl 'id' or NULL if it does not exist.
TEnum * Get(DeclId_t id, const char *name)
Return (after creating it if necessary) the TEnum describing the enum corresponding to the Decl 'id'.
TClass * GetClass() const
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
TFunctionTemplate * Get(DeclId_t id)
Return (after creating it if necessary) the TMethod or TFunction describing the function correspondin...
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
TFunction * Find(DeclId_t id) const
Return the TMethod or TFunction describing the function corresponding to the Decl 'id'.
A doubly linked list.
Definition TList.h:38
void Add(TObject *obj) override
Definition TList.h:81
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:487
Abstract base class for accessing the data-members of a class.
void DecrementNestedTransient()
const char * GetParent() const
void IncrementNestedTransient()
virtual void Inspect(TClass *cl, const char *parent, const char *name, const void *addr)
EObjectPointerState GetObjectValidity() const
virtual Bool_t IsTreatingNonAccessibleTypes()
void SetObjectValidity(EObjectPointerState val)
void InspectMember(const T &obj, const char *name, Bool_t isTransient)
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition TMethodArg.h:36
const char * GetFullTypeName() const
Get full type description of method argument, e.g.: "class TDirectory*".
const char * GetDefault() const
Get default value of method argument.
Each ROOT class (see TClass) has a linked list of methods.
Definition TMethod.h:38
virtual TList * GetListOfMethodArgs()
Returns methodarg list and additionally updates fDataMember in TMethod by calling FindDataMember();.
Definition TMethod.cxx:306
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
TNamed()
Definition TNamed.h:38
An array of TObjects.
Definition TObjArray.h:31
Int_t GetEntriesFast() const
Definition TObjArray.h:58
virtual void Expand(Int_t newSize)
Expand or shrink the array to newSize elements.
Int_t GetEntries() const override
Return the number of objects in array (i.e.
TObject * At(Int_t idx) const override
Definition TObjArray.h:170
TObject * UncheckedAt(Int_t i) const
Definition TObjArray.h:90
Collectable string class.
Definition TObjString.h:28
TString & String()
Definition TObjString.h:48
Mother of all ROOT objects.
Definition TObject.h:42
Bool_t TestBit(UInt_t f) const
Definition TObject.h:204
Bool_t IsOnHeap() const
Definition TObject.h:160
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1084
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:425
static TClass * Class()
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1098
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1126
virtual TClass * IsA() const
Definition TObject.h:248
void MakeZombie()
Definition TObject.h:55
TObject()
TObject constructor.
Definition TObject.h:259
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:81
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1072
Persistent version of a TClass.
Definition TProtoClass.h:38
static const TString & GetIncludeDir()
Get the include directory in the installation. Static utility function.
Definition TROOT.cxx:3347
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition TROOT.cxx:2917
static const std::vector< std::string > & AddExtraInterpreterArgs(const std::vector< std::string > &args)
Provide command line arguments to the interpreter construction.
Definition TROOT.cxx:3113
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition TROOT.cxx:3381
static const char **& GetExtraInterpreterArgs()
INTERNAL function!
Definition TROOT.cxx:3123
static const TString & GetSharedLibDir()
Get the shared libraries directory in the installation.
Definition TROOT.cxx:3208
Sequenceable collection abstract base class.
Int_t LastIndex() const
void Add(TObject *obj) override
Describes a persistent version of a class.
Basic string class.
Definition TString.h:138
Ssiz_t Length() const
Definition TString.h:425
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2250
void Clear()
Clear string without changing its capacity.
Definition TString.cxx:1241
const char * Data() const
Definition TString.h:384
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:713
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition TString.cxx:938
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition TString.cxx:2270
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:632
TString & Prepend(const char *cs)
Definition TString.h:682
Bool_t IsNull() const
Definition TString.h:422
TString & Remove(Ssiz_t pos)
Definition TString.h:694
TString & Append(const char *cs)
Definition TString.h:581
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2385
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:641
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:660
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:51
virtual void Update()=0
static void SetFactory(TVirtualStreamerInfo *factory)
static function: Set the StreamerInfo factory
TText * text
TLine * line
const Int_t n
Definition legend1.C:16
Double_t ex[n]
Definition legend1.C:17
TF1 * f1
Definition legend1.C:11
#define F(x, y, z)
#define I(x, y, z)
const std::string & GetPathSeparator()
const char & GetEnvPathSeparator()
void(off) SmallVectorTemplateBase< T
double T(double x)
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
Definition RExports.h:168
const T * GetAnnotatedRedeclarable(const T *Redecl)
int GetClassVersion(const clang::RecordDecl *cl, const cling::Interpreter &interp)
Return the version number of the class or -1 if the function Class_Version does not exist.
void GetNormalizedName(std::string &norm_name, const clang::QualType &type, const cling::Interpreter &interpreter, const TNormalizedCtxt &normCtxt)
Return the type name normalized for ROOT, keeping only the ROOT opaque typedef (Double32_t,...
std::string GetModuleFileName(const char *moduleName)
Return the dictionary file name for a module.
clang::QualType ReSubstTemplateArg(clang::QualType input, const clang::Type *instance)
Check if 'input' or any of its template parameter was substituted when instantiating the class templa...
static std::string DemangleNameForDlsym(const std::string &name)
void GetCppName(std::string &output, const char *input)
Return (in the argument 'output') a valid name of the C++ symbol/type (pass as 'input') that can be u...
std::pair< bool, int > GetTrivialIntegralReturnValue(const clang::FunctionDecl *funcCV, const cling::Interpreter &interp)
If the function contains 'just': return SomeValue; this routine will extract this value and return it...
std::string GetRealPath(const std::string &path)
void GetQualifiedName(std::string &qual_name, const clang::QualType &type, const clang::NamedDecl &forcontext)
Main implementation relying on GetFullyQualifiedTypeName All other GetQualifiedName functions leverag...
llvm::StringRef GetComment(const clang::Decl &decl, clang::SourceLocation *loc=nullptr)
Returns the comment (// striped away), annotating declaration in a meaningful for ROOT IO way.
void SetPathsForRelocatability(std::vector< std::string > &clingArgs)
Organise the parameters for cling in order to guarantee relocatability It treats the gcc toolchain an...
const clang::Type * GetUnderlyingType(clang::QualType type)
Return the base/underlying type of a chain of array or pointers type.
ROOT::ESTLType IsSTLCont(const clang::RecordDecl &cl)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container abs(result):...
bool ExtractAttrPropertyFromName(const clang::Decl &decl, const std::string &propName, std::string &propValue)
This routine counts on the "propName<separator>propValue" format.
The namespace of The Lean Mean C++ Option Parser.
externTVirtualRWMutex * gCoreMutex
EFunctionMatchMode
@ kExactMatch
RooArgList L(Args_t &&... args)
Definition RooArgList.h:156
RooArgSet S(Args_t &&... args)
Definition RooArgSet.h:200
bool IsStdPairBase(std::string_view name)
Definition TClassEdit.h:235
bool IsStdArray(std::string_view name)
Definition TClassEdit.h:230
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
bool IsStdPair(std::string_view name)
Definition TClassEdit.h:231
std::string InsertStd(const char *tname)
std::string GetLong64_Name(const char *original)
Replace 'long long' and 'unsigned long long' by 'Long64_t' and 'ULong64_t'.
char * DemangleTypeIdName(const std::type_info &ti, int &errorCode)
Demangle in a portable way the type id name.
const char * GetUnqualifiedName(const char *name)
Return the start of the unqualified name include in 'original'.
void Init(TClassEdit::TInterpreterLookupHelper *helper)
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
char * DemangleName(const char *mangled_name, int &errorCode)
Definition TClassEdit.h:255
int GetSplit(const char *type, std::vector< std::string > &output, int &nestedLoc, EModType mode=TClassEdit::kNone)
Stores in output (after emptying it) the split type.
@ kDropStlDefault
Definition TClassEdit.h:83
EComplexType GetComplexType(const char *)
constexpr Double_t C()
Velocity of light in .
Definition TMath.h:117
const char * Name
Definition TXMLSetup.cxx:66
#define R__DLLEXPORT
static const char * what
Definition stlLoader.cc:5
Int_t fMode
Definition TSystem.h:135
Long_t fMemVirtual
Definition TSystem.h:210
Long_t fMemResident
Definition TSystem.h:209
RAII used to store Parser, Sema, Preprocessor state for recursive parsing.
Definition ClingRAII.h:22
void ShortType(std::string &answer, int mode)
Return the absolute type of typeDesc into the string answ.
Int_t fRecurseCount
Interpreter-related functions will push the "entry" lock state to *this.
Definition TCling.h:164
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4