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}
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.
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
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);
1664 }
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;
1682 delete fLookupHelper;
1683 gCling = nullptr;
1684}
1685
1686////////////////////////////////////////////////////////////////////////////////
1687/// Initialize the interpreter, once TROOT::fInterpreter is set.
1688
1690{
1691 if (!fClingCallbacks) // Compiler instance could not be created. See https://its.cern.ch/jira/browse/ROOT-10239
1692 return;
1693 fClingCallbacks->Initialize();
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
1711{
1712 fIsShuttingDown = true;
1713 ResetGlobals();
1714}
1715
1716////////////////////////////////////////////////////////////////////////////////
1717/// Helper to initialize TVirtualStreamerInfo's factor early.
1718/// Use static initialization to insure only one TStreamerInfo is created.
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
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;
1861 }
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 };
1956
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());
1989 }
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 // A library built with C++ modules may ship only its .pcm and no
2359 // <lib>_rdict.pcm (the dictionary payload then lives in the C++ module).
2360 // In that case probing the legacy rootpcm makes LoadPCM emit a spurious
2361 // "ROOT PCM ... file does not exist" error followed by an in-memory
2362 // candidate dump. Skip the probe only when the C++ module was loaded AND
2363 // there is genuinely no rootpcm to load -- neither registered in-memory
2364 // (an embedded rdict, the check mirrors LoadPCM) nor present on disk. For
2365 // libraries without a C++ module the behaviour is unchanged, so a truly
2366 // missing rootpcm is still reported.
2367 std::string pcmPath = pcmFileNameFullPath.str().str();
2368 std::string pcmRealPath = llvm::sys::fs::is_symlink_file(pcmPath)
2370 : pcmPath;
2371 if (!ModuleWasSuccessfullyLoaded || fPendingRdicts.count(pcmRealPath) ||
2372 llvm::sys::fs::exists(pcmRealPath))
2373 LoadPCM(pcmPath);
2374 }
2375
2376 { // scope within which diagnostics are de-activated
2377 // For now we disable diagnostics because we saw them already at
2378 // dictionary generation time. That won't be an issue with the PCMs.
2379
2380 clangDiagSuppr diagSuppr(TheSema.getDiagnostics());
2381
2382#if defined(R__MUST_REVISIT)
2383#if R__MUST_REVISIT(6,2)
2384 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
2385#endif
2386#endif
2387
2388 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand){
2389 SuspendAutoParsing autoParseRaii(this);
2390
2391 const cling::Transaction* watermark = fInterpreter->getLastTransaction();
2392 cling::Interpreter::CompilationResult compRes = fInterpreter->parseForModule(code.Data());
2393 if (isACLiC) {
2394 // Register an unload point.
2395 fMetaProcessor->registerUnloadPoint(watermark, headers[0]);
2396 }
2397
2398 assert(cling::Interpreter::kSuccess == compRes &&
2399 "Payload code of a dictionary could not be parsed correctly.");
2400 if (compRes!=cling::Interpreter::kSuccess) {
2401 Warning("TCling::RegisterModule",
2402 "Problems declaring payload for module %s.", modulename) ;
2403 }
2404 }
2405 }
2406
2407 // Now that all the header have been registered/compiled, let's
2408 // make sure to 'reset' the TClass that have a class init in this module
2409 // but already had their type information available (using information/header
2410 // loaded from other modules or from class rules or from opening a TFile
2411 // or from loading header in a way that did not provoke the loading of
2412 // the library we just loaded).
2414
2415 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand) {
2416 // __ROOTCLING__ might be pulled in through PCH
2417 fInterpreter->declare("#ifdef __ROOTCLING__\n"
2418 "#undef __ROOTCLING__\n"
2419 + gInterpreterClassDef +
2420 "#endif");
2421 }
2422
2423 if (wasDlopened) {
2424 assert(isSharedLib);
2425 void* dyLibHandle = fRegisterModuleDyLibs.back();
2426 fRegisterModuleDyLibs.pop_back();
2427 dlclose(dyLibHandle);
2428 }
2429}
2430
2432 clang::CompilerInstance& CI = *GetInterpreterImpl()->getCI();
2433 ASTContext &C = CI.getASTContext();
2434
2435 // Do not do anything if we have no global module index.
2436 // FIXME: This is mostly to real with false positives in the TTabCom
2437 // interface for non-modules.
2438 if (!fCxxModulesEnabled)
2439 return;
2440
2441 if (IdentifierInfoLookup *External = C.Idents.getExternalIdentifierLookup()) {
2442 std::unique_ptr<IdentifierIterator> Iter(External->getIdentifiers());
2443 for (llvm::StringRef Ident = Iter->Next(); !Ident.empty(); Ident = Iter->Next()) {
2444 std::string I = Ident.str();
2445 if (!Idents.Contains(I.data()))
2446 Idents.Add(new TObjString(I.c_str()));
2447 }
2448 }
2449}
2450
2451
2452////////////////////////////////////////////////////////////////////////////////
2453/// Register classes that already existed prior to their dictionary loading
2454/// and that already had a ClassInfo (and thus would not be refresh via
2455/// UpdateClassInfo.
2456
2458{
2459 fClassesToUpdate.push_back(std::make_pair(oldcl,dict));
2460}
2461
2462////////////////////////////////////////////////////////////////////////////////
2463/// If the dictionary is loaded, we can remove the class from the list
2464/// (otherwise the class might be loaded twice).
2465
2467{
2468 typedef std::vector<std::pair<TClass*,DictFuncPtr_t> >::iterator iterator;
2469 iterator stop = fClassesToUpdate.end();
2470 for(iterator i = fClassesToUpdate.begin();
2471 i != stop;
2472 ++i)
2473 {
2474 if ( i->first == oldcl ) {
2475 fClassesToUpdate.erase(i);
2476 return;
2477 }
2478 }
2479}
2480
2481
2482////////////////////////////////////////////////////////////////////////////////
2483/// Let cling process a command line.
2484///
2485/// If the command is executed and the error is 0, then the return value
2486/// is the int value corresponding to the result of the executed command
2487/// (float and double return values will be truncated).
2488///
2489
2490// Method for handling the interpreter exceptions.
2491// the MetaProcessor is passing in as argument to teh function, because
2492// cling::Interpreter::CompilationResult is a nested class and it cannot be
2493// forward declared, thus this method cannot be a static member function
2494// of TCling.
2495
2496static int HandleInterpreterException(cling::MetaProcessor* metaProcessor,
2497 const char* input_line,
2498 cling::Interpreter::CompilationResult& compRes,
2499 cling::Value* result)
2500{
2501 try {
2502 return metaProcessor->process(input_line, compRes, result);
2503 }
2504 catch (cling::InterpreterException& ex)
2505 {
2506 Error("HandleInterpreterException", "%s\n%s", ex.what(), "Execution of your code was aborted.");
2507 ex.diagnose();
2508 compRes = cling::Interpreter::kFailure;
2509 }
2510 return 0;
2511}
2512
2513////////////////////////////////////////////////////////////////////////////////
2514
2515bool TCling::DiagnoseIfInterpreterException(const std::exception &e) const
2516{
2517 if (auto ie = dynamic_cast<const cling::InterpreterException*>(&e)) {
2518 ie->diagnose();
2519 return true;
2520 }
2521 return false;
2522}
2523
2524////////////////////////////////////////////////////////////////////////////////
2525
2527{
2528 // Copy the passed line, it comes from a static buffer in TApplication
2529 // which can be reentered through the Cling evaluation routines,
2530 // which would overwrite the static buffer and we would forget what we
2531 // were doing.
2532 //
2533 TString sLine(line);
2534 if (strstr(line,fantomline)) {
2535 // End-Of-Line action
2536 // See the comment (copied from above):
2537 // It is a "fantom" method to synchronize user keyboard input
2538 // and ROOT prompt line (for WIN32)
2539 // and is implemented by
2540 if (gApplication) {
2541 if (gApplication->IsCmdThread()) {
2543 gROOT->SetLineIsProcessing();
2544
2546
2547 gROOT->SetLineHasBeenProcessed();
2548 }
2549 }
2550 return 0;
2551 }
2552
2554 gGlobalMutex->Lock();
2555 if (!gInterpreterMutex)
2557 gGlobalMutex->UnLock();
2558 }
2560 gROOT->SetLineIsProcessing();
2561
2562 struct InterpreterFlagsRAII {
2563 cling::Interpreter* fInterpreter;
2564 bool fWasDynamicLookupEnabled;
2565
2566 InterpreterFlagsRAII(cling::Interpreter* interp):
2567 fInterpreter(interp),
2568 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2569 {
2570 fInterpreter->enableDynamicLookup(true);
2571 }
2572 ~InterpreterFlagsRAII() {
2573 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2574 gROOT->SetLineHasBeenProcessed();
2575 }
2576 } interpreterFlagsRAII(GetInterpreterImpl());
2577
2578 // A non-zero returned value means the given line was
2579 // not a complete statement.
2580 int indent = 0;
2581 // This will hold the resulting value of the evaluation the given line.
2582 cling::Value result;
2583 cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess;
2584 if (!strncmp(sLine.Data(), ".L", 2) || !strncmp(sLine.Data(), ".x", 2) ||
2585 !strncmp(sLine.Data(), ".X", 2)) {
2586 // If there was a trailing "+", then CINT compiled the code above,
2587 // and we will need to strip the "+" before passing the line to cling.
2588 TString mod_line(sLine);
2589 TString aclicMode;
2590 TString arguments;
2591 TString io;
2592 TString fname = gSystem->SplitAclicMode(sLine.Data() + 3,
2593 aclicMode, arguments, io);
2594 if (aclicMode.Length()) {
2595 // Remove the leading '+'
2596 R__ASSERT(aclicMode[0]=='+' && "ACLiC mode must start with a +");
2597 aclicMode[0]='k'; // We always want to keep the .so around.
2598 if (aclicMode[1]=='+') {
2599 // We have a 2nd +
2600 aclicMode[1]='f'; // We want to force the recompilation.
2601 }
2602 if (!gSystem->CompileMacro(fname,aclicMode)) {
2603 // ACLiC failed.
2604 compRes = cling::Interpreter::kFailure;
2605 } else {
2606 if (strncmp(sLine.Data(), ".L", 2) != 0) {
2607 // if execution was requested.
2608
2609 if (arguments.Length() == 0) {
2610 arguments = "()";
2611 }
2612 // We need to remove the extension.
2613 Ssiz_t ext = fname.Last('.');
2614 if (ext != kNPOS) {
2615 fname.Remove(ext);
2616 }
2617 const char *function = gSystem->BaseName(fname);
2618 mod_line = function + arguments + io;
2620 }
2621 }
2622 } else if (cling::DynamicLibraryManager::isSharedLibrary(fname.Data()) &&
2623 strncmp(sLine.Data(), ".L", 2) != 0) { // .x *.so or *.dll
2624 if (gSystem->Load(fname) < 0) {
2625 // Loading failed.
2626 compRes = cling::Interpreter::kFailure;
2627 } else {
2628 if (arguments.Length() == 0) {
2629 arguments = "()";
2630 }
2631 // We need to remove the extension. (*.so or *.dll)
2632 Ssiz_t ext = fname.Last('.');
2633 if (ext != kNPOS) {
2634 fname.Remove(ext);
2635 }
2636 // Now we try to find the 'main' function to run within this shared library
2637 // We distinguish two cases: a library.so with a function library(args),
2638 // or a precompiled ACLiC macro (macro_C.so) with a function macro(args).
2639 // Only in the second case, we need to strip the suffix _C or _cpp from fname.
2640 if (!gInterpreter->GetFunction(nullptr, gSystem->BaseName(fname))) { // AcLiC macro
2641 // We need to remove the automatically appended _ extension when compiling (macro_C from macro.C)
2642 ext = fname.Last('_');
2643 if (ext != kNPOS) {
2644 fname.Remove(ext);
2645 }
2646 }
2647 const char *function = gSystem->BaseName(fname);
2648 mod_line = function + arguments + io;
2650 }
2651 } else {
2652 // neither ACLiC nor run shared-library (.x)
2653 size_t unnamedMacroOpenCurly;
2654 {
2655 std::string code;
2656 std::string codeline;
2657 // Windows requires std::ifstream::binary to properly handle
2658 // CRLF and LF line endings
2659 std::ifstream in(fname, std::ifstream::binary);
2660 while (in) {
2661 std::getline(in, codeline);
2662 code += codeline + "\n";
2663 }
2664 unnamedMacroOpenCurly
2665 = cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
2666 }
2667
2668 fCurExecutingMacros.push_back(fname);
2669 if (unnamedMacroOpenCurly != std::string::npos) {
2670 compRes = fMetaProcessor->readInputFromFile(fname.Data(), &result,
2671 unnamedMacroOpenCurly);
2672 } else {
2673 // No DynLookup for .x, .L of named macros.
2674 fInterpreter->enableDynamicLookup(false);
2676 }
2677 fCurExecutingMacros.pop_back();
2678 }
2679 } // .L / .X / .x
2680 else {
2681 if (0!=strncmp(sLine.Data(), ".autodict ",10) && sLine != ".autodict") {
2682 // explicitly ignore .autodict without having to support it
2683 // in cling.
2684
2685 // Turn off autoparsing if this is an include directive
2686 bool isInclusionDirective = sLine.Contains("\n#include") || sLine.BeginsWith("#include");
2687 if (isInclusionDirective) {
2688 SuspendAutoParsing autoParseRaii(this);
2690 } else {
2692 }
2693 }
2694 }
2695 if (result.isValid())
2697 if (indent) {
2698 if (error)
2699 *error = kProcessing;
2700 return 0;
2701 }
2702 if (error) {
2703 switch (compRes) {
2704 case cling::Interpreter::kSuccess: *error = kNoError; break;
2705 case cling::Interpreter::kFailure: *error = kRecoverable; break;
2706 case cling::Interpreter::kMoreInputExpected: *error = kProcessing; break;
2707 }
2708 }
2709 if (compRes == cling::Interpreter::kSuccess
2710 && result.isValid()
2711 && !result.isVoid())
2712 {
2713 return result.castAs<Longptr_t>();
2714 }
2715 return 0;
2716}
2717
2718////////////////////////////////////////////////////////////////////////////////
2719/// No-op; see TRint instead.
2720
2722{
2723}
2724
2725////////////////////////////////////////////////////////////////////////////////
2726/// Print information about the interpreter.
2727///\param[in] option Selects the type of information to print.
2728///
2729/// List of currently support options:
2730/// - autoparsed: Print the list of classes that triggered autoparsing.
2732{
2733 if (option && *option) {
2734 if (!strcmp(option, "autoparsed")) {
2735 std::cout << "Auto parsed classes:" << std::endl;
2736 for (auto & cls : fAutoParseClasses) {
2737 std::cout << " " << cls << std::endl;
2738 }
2739 } else if (!strcmp(option, "autoloaded")) {
2740 std::cout << "Auto loaded libraries:" << std::endl;
2741 for (auto & lib : fAutoLoadedLibraries) {
2742 std::cout << " " << lib << std::endl;
2743 }
2744 } else {
2745 ::Error("TCling::Print", "Unknown option '%s'", option);
2746 }
2747 } else {
2748 ::Info("TCling::Print", "No options specified");
2749 }
2750}
2751
2752
2753////////////////////////////////////////////////////////////////////////////////
2754/// \brief Add a directory to the list of directories in which the
2755/// interpreter looks for include files.
2756/// \param[in] path The path to the directory.
2757/// \note Only one path item can be specified at a time, i.e. "path1:path2" is
2758/// \b NOT supported.
2759/// \warning Only the path to the directory should be specified, without
2760/// prepending the \c -I prefix, i.e.
2761/// <tt>gCling->AddIncludePath("/path/to/my/includes")</tt>. If the
2762/// \c -I prefix is used it will be ignored.
2763void TCling::AddIncludePath(const char *path)
2764{
2766 // Favorite source of annoyance: gSystem->AddIncludePath() needs "-I",
2767 // gCling->AddIncludePath() does not! Work around that inconsistency:
2768 if (path[0] == '-' && path[1] == 'I')
2769 path += 2;
2770 TString sPath(path);
2771 gSystem->ExpandPathName(sPath);
2772#ifdef _MSC_VER
2773 if (sPath.BeginsWith("/")) {
2774 char drive[3];
2775 snprintf(drive, 3, "%c:", _getdrive() + 'A' - 1);
2776 sPath.Prepend(drive);
2777 }
2778#endif
2779 fInterpreter->AddIncludePath(sPath.Data());
2780}
2781
2782////////////////////////////////////////////////////////////////////////////////
2783/// Visit all members over members, recursing over base classes.
2784
2785void TCling::InspectMembers(TMemberInspector& insp, const void* obj,
2786 const TClass* cl, Bool_t isTransient)
2787{
2791 }
2792
2793 if (!cl || cl->GetCollectionProxy()) {
2794 // We do not need to investigate the content of the STL
2795 // collection, they are opaque to us (and details are
2796 // uninteresting).
2797 return;
2798 }
2799
2800 static const TClassRef clRefString("std::string");
2801 if (clRefString == cl) {
2802 // We stream std::string without going through members..
2803 return;
2804 }
2805
2806 if (TClassEdit::IsStdArray(cl->GetName())) {
2807 // We treat std arrays as C arrays
2808 return;
2809 }
2810
2811 const char* cobj = (const char*) obj; // for ptr arithmetics
2812
2813 // Treat the case of std::complex in a special manner. We want to enforce
2814 // the layout of a stl implementation independent class, which is the
2815 // complex as implemented in ROOT5.
2816
2817 // A simple lambda to simplify the code
2818 auto inspInspect = [&] (ptrdiff_t offset){
2819 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_real", cobj, isTransient);
2820 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_imag", cobj + offset, isTransient);
2821 };
2822
2823 auto complexType = TClassEdit::GetComplexType(cl->GetName());
2824 switch(complexType) {
2826 {
2827 break;
2828 }
2830 {
2831 inspInspect(sizeof(float));
2832 return;
2833 }
2835 {
2836 inspInspect(sizeof(double));
2837 return;
2838 }
2840 {
2841 inspInspect(sizeof(int));
2842 return;
2843 }
2845 {
2846 inspInspect(sizeof(long));
2847 return;
2848 }
2849 }
2850
2851 static clang::PrintingPolicy
2852 printPol(fInterpreter->getCI()->getLangOpts());
2853 if (printPol.Indentation) {
2854 // not yet initialized
2855 printPol.Indentation = 0;
2856 printPol.SuppressInitializers = true;
2857 }
2858
2859 const char* clname = cl->GetName();
2860 // Printf("Inspecting class %s\n", clname);
2861
2862 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2863 const clang::Decl *scopeDecl = nullptr;
2864 const clang::Type *recordType = nullptr;
2865
2866 if (cl->GetClassInfo()) {
2867 TClingClassInfo * clingCI = (TClingClassInfo *)cl->GetClassInfo();
2868 scopeDecl = clingCI->GetDecl();
2869 recordType = clingCI->GetType();
2870 } else {
2871 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2872 // Diags will complain about private classes:
2873 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2874 &recordType);
2875 }
2876 if (!scopeDecl) {
2877 Error("InspectMembers", "Cannot find Decl for class %s", clname);
2878 return;
2879 }
2880 const clang::CXXRecordDecl* recordDecl
2881 = llvm::dyn_cast<const clang::CXXRecordDecl>(scopeDecl);
2882 if (!recordDecl) {
2883 Error("InspectMembers", "Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2884 return;
2885 }
2886
2887 {
2888 // Force possible deserializations first. We need to have no pending
2889 // Transaction when passing control flow to the inspector below (ROOT-7779).
2890 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2891
2892 astContext.getASTRecordLayout(recordDecl);
2893
2894 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2895 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2896 }
2897
2898 const clang::ASTRecordLayout& recLayout
2899 = astContext.getASTRecordLayout(recordDecl);
2900
2901 // TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
2902 // if (proxy && ( proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated ) ) {
2903 // Error("InspectMembers","The TClass for %s has an emulated proxy but we are looking at a compiled version of the collection!\n",
2904 // cl->GetName());
2905 // }
2906 if (cl->Size() != recLayout.getSize().getQuantity()) {
2907 Error("InspectMembers","TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2908 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2909 }
2910
2911 unsigned iNField = 0;
2912 // iterate over fields
2913 // FieldDecls are non-static, else it would be a VarDecl.
2914 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2915 eField = recordDecl->field_end(); iField != eField;
2916 ++iField, ++iNField) {
2917
2918
2919 clang::QualType memberQT = iField->getType();
2920 if (recordType) {
2921 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2922 memberQT = ROOT::TMetaUtils::ReSubstTemplateArg(memberQT, recordType);
2923 }
2924 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2925 if (memberQT.isNull()) {
2926 std::string memberName;
2927 llvm::raw_string_ostream stream(memberName);
2928 // Don't trigger fopen of the source file to count lines:
2929 printPol.AnonymousTagLocations = false;
2930 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2931 stream.flush();
2932 Error("InspectMembers",
2933 "Cannot retrieve QualType for member %s while inspecting class %s",
2934 memberName.c_str(), clname);
2935 continue; // skip member
2936 }
2937 const clang::Type* memType = memberQT.getTypePtr();
2938 if (!memType) {
2939 std::string memberName;
2940 llvm::raw_string_ostream stream(memberName);
2941 // Don't trigger fopen of the source file to count lines:
2942 printPol.AnonymousTagLocations = false;
2943 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2944 stream.flush();
2945 Error("InspectMembers",
2946 "Cannot retrieve Type for member %s while inspecting class %s",
2947 memberName.c_str(), clname);
2948 continue; // skip member
2949 }
2950
2951 const clang::Type* memNonPtrType = memType;
2952 Bool_t ispointer = false;
2953 if (memNonPtrType->isPointerType()) {
2954 ispointer = true;
2955 clang::QualType ptrQT
2956 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2957 if (recordType) {
2958 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2959 ptrQT = ROOT::TMetaUtils::ReSubstTemplateArg(ptrQT, recordType);
2960 }
2961 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2962 if (ptrQT.isNull()) {
2963 std::string memberName;
2964 llvm::raw_string_ostream stream(memberName);
2965 // Don't trigger fopen of the source file to count lines:
2966 printPol.AnonymousTagLocations = false;
2967 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2968 stream.flush();
2969 Error("InspectMembers",
2970 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2971 memberName.c_str(), clname);
2972 continue; // skip member
2973 }
2974 memNonPtrType = ptrQT.getTypePtr();
2975 }
2976
2977 // assemble array size(s): "[12][4][]"
2978 llvm::SmallString<8> arraySize;
2979 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2980 unsigned arrLevel = 0;
2981 bool haveErrorDueToArray = false;
2982 while (arrType) {
2983 ++arrLevel;
2984 arraySize += '[';
2985 const clang::ConstantArrayType* constArrType =
2986 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2987 if (constArrType) {
2988 constArrType->getSize().toStringUnsigned(arraySize);
2989 }
2990 arraySize += ']';
2991 clang::QualType subArrQT = arrType->getElementType();
2992 if (subArrQT.isNull()) {
2993 std::string memberName;
2994 llvm::raw_string_ostream stream(memberName);
2995 // Don't trigger fopen of the source file to count lines:
2996 printPol.AnonymousTagLocations = false;
2997 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2998 stream.flush();
2999 Error("InspectMembers",
3000 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
3001 arrLevel, subArrQT.getAsString(printPol).c_str(),
3002 memberName.c_str(), clname);
3003 haveErrorDueToArray = true;
3004 break;
3005 }
3006 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
3007 }
3008 if (haveErrorDueToArray) {
3009 continue; // skip member
3010 }
3011
3012 // construct member name
3013 std::string fieldName;
3014 if (memType->isPointerType()) {
3015 fieldName = "*";
3016 }
3017
3018 // Check if this field has a custom ioname, if not, just use the one of the decl
3019 std::string ioname(iField->getName());
3020 ROOT::TMetaUtils::ExtractAttrPropertyFromName(**iField,"ioname",ioname);
3021 fieldName += ioname;
3022 fieldName += arraySize;
3023
3024 // get member offset
3025 // NOTE currently we do not support bitfield and do not support
3026 // member that are not aligned on 'bit' boundaries.
3027 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
3028 ptrdiff_t fieldOffset = offset.getQuantity();
3029
3030 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fBits[2]", fBits);
3031 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fName", &fName);
3032 // R__insp.InspectMember(fName, "fName.");
3033 // R__insp.Inspect(R__cl, R__insp.GetParent(), "*fClass", &fClass);
3034
3035 // If the class has a custom streamer and the type of the filed is a
3036 // private enum, struct or class, skip it.
3037 if (!insp.IsTreatingNonAccessibleTypes()){
3038 auto iFiledQtype = iField->getType();
3039 if (auto tagDecl = iFiledQtype->getAsTagDecl()){
3040 auto declAccess = tagDecl->getAccess();
3041 if (declAccess == AS_private || declAccess == AS_protected) {
3042 continue;
3043 }
3044 }
3045 }
3046
3047 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
3048
3049 if (!ispointer) {
3050 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
3051 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
3052 // nested objects get an extra call to InspectMember
3053 // R__insp.InspectMember("FileStat_t", (void*)&fFileStat, "fFileStat.", false);
3054 std::string sFieldRecName;
3055 if (!ROOT::TMetaUtils::ExtractAttrPropertyFromName(*fieldRecDecl,"iotype",sFieldRecName)){
3057 clang::QualType(memNonPtrType,0),
3058 *fInterpreter,
3060 }
3061
3062 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
3063 // if we can not find the member (which should not really happen),
3064 // let's consider it transient.
3065 Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();
3066 if (!mbr || !mbr->IsPersistent())
3068 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
3069 (fieldName + '.').c_str(), transient);
3070 if (!mbr || !mbr->IsPersistent())
3072
3073 }
3074 }
3075 } // loop over fields
3076
3077 // inspect bases
3078 // TNamed::ShowMembers(R__insp);
3079 unsigned iNBase = 0;
3080 for (clang::CXXRecordDecl::base_class_const_iterator iBase
3081 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
3082 iBase != eBase; ++iBase, ++iNBase) {
3083 clang::QualType baseQT = iBase->getType();
3084 if (baseQT.isNull()) {
3085 Error("InspectMembers",
3086 "Cannot find QualType for base number %d while inspecting class %s",
3087 iNBase, clname);
3088 continue;
3089 }
3090 const clang::CXXRecordDecl* baseDecl
3091 = baseQT->getAsCXXRecordDecl();
3092 if (!baseDecl) {
3093 Error("InspectMembers",
3094 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
3095 iNBase, clname);
3096 continue;
3097 }
3098 TClass* baseCl=nullptr;
3099 std::string sBaseName;
3100 // Try with the DeclId
3101 std::vector<TClass*> foundClasses;
3102 TClass::GetClass(static_cast<DeclId_t>(baseDecl), foundClasses);
3103 if (foundClasses.size()==1){
3104 baseCl=foundClasses[0];
3105 } else {
3106 // Try with the normalised Name, as a fallback
3107 if (!baseCl){
3109 baseQT,
3110 *fInterpreter,
3112 baseCl = TClass::GetClass(sBaseName.c_str());
3113 }
3114 }
3115
3116 if (!baseCl){
3117 std::string qualNameForDiag;
3118 ROOT::TMetaUtils::GetQualifiedName(qualNameForDiag, *baseDecl);
3119 Error("InspectMembers",
3120 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
3121 continue;
3122 }
3123
3124 int64_t baseOffset;
3125 if (iBase->isVirtual()) {
3127 if (!isTransient) {
3128 Error("InspectMembers",
3129 "Base %s of class %s is virtual but no object provided",
3130 sBaseName.c_str(), clname);
3131 }
3133 } else {
3134 // We have an object to determine the vbase offset.
3136 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
3137 if (ci && baseCi) {
3138 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
3139 true /*isDerivedObj*/);
3140 if (baseOffset == -1) {
3141 Error("InspectMembers",
3142 "Error calculating offset of virtual base %s of class %s",
3143 sBaseName.c_str(), clname);
3144 }
3145 } else {
3146 Error("InspectMembers",
3147 "Cannot calculate offset of virtual base %s of class %s",
3148 sBaseName.c_str(), clname);
3149 continue;
3150 }
3151 }
3152 } else {
3153 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
3154 }
3155 // TOFIX: baseCl can be null here!
3156 if (baseCl->IsLoaded()) {
3157 // For loaded class, CallShowMember will (especially for TObject)
3158 // call the virtual ShowMember rather than the class specific version
3159 // resulting in an infinite recursion.
3160 InspectMembers(insp, cobj + baseOffset, baseCl, isTransient);
3161 } else {
3162 baseCl->CallShowMembers(cobj + baseOffset,
3163 insp, isTransient);
3164 }
3165 } // loop over bases
3166}
3167
3168////////////////////////////////////////////////////////////////////////////////
3169/// Check if constructor exited correctly, ie the instance is in a valid state
3170/// \return true if there is a compiler instance available, false otherwise
3172{
3173 return fInterpreter->getCI() != nullptr;
3174}
3175
3176////////////////////////////////////////////////////////////////////////////////
3177/// Reset the interpreter internal state in case a previous action was not correctly
3178/// terminated.
3179
3181{
3182 // No-op there is not equivalent state (to be cleared) in Cling.
3183}
3184
3185////////////////////////////////////////////////////////////////////////////////
3186/// Delete existing temporary values.
3187
3189{
3190 // No-op for cling due to cling::Value.
3191}
3192
3193////////////////////////////////////////////////////////////////////////////////
3194/// Declare code to the interpreter, without any of the interpreter actions
3195/// that could trigger a re-interpretation of the code. I.e. make cling
3196/// behave like a compiler: no dynamic lookup, no input wrapping for
3197/// subsequent execution, no automatic provision of declarations but just a
3198/// plain `#include`.
3199/// Returns true on success, false on failure.
3200
3201bool TCling::Declare(const char* code)
3202{
3204
3205 SuspendAutoLoadingRAII autoLoadOff(this);
3206 SuspendAutoParsing autoParseRaii(this);
3207
3208 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
3209 fInterpreter->enableDynamicLookup(false);
3210 bool oldRawInput = fInterpreter->isRawInputEnabled();
3211 fInterpreter->enableRawInput(true);
3212
3213 Bool_t ret = LoadText(code);
3214
3215 fInterpreter->enableRawInput(oldRawInput);
3216 fInterpreter->enableDynamicLookup(oldDynLookup);
3217 return ret;
3218}
3219
3220////////////////////////////////////////////////////////////////////////////////
3221/// It calls a "fantom" method to synchronize user keyboard input
3222/// and ROOT prompt line.
3223
3228
3229// This static function is a hop of TCling::IsLibraryLoaded, which is taking a lock and calling
3230// into this function. This is because we wanted to avoid a duplication in TCling::IsLoaded, which
3231// was already taking a lock.
3232static Bool_t s_IsLibraryLoaded(const char* libname, cling::Interpreter* fInterpreter)
3233{
3234 // Check shared library.
3235 TString tLibName(libname);
3236 if (gSystem->FindDynamicLibrary(tLibName, kTRUE))
3237 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
3238 return false;
3239}
3240
3241Bool_t TCling::IsLibraryLoaded(const char* libname) const
3242{
3244 return s_IsLibraryLoaded(libname, GetInterpreterImpl());
3245}
3246
3247////////////////////////////////////////////////////////////////////////////////
3248/// Return true if ROOT has cxxmodules pcm for a given library name.
3249// FIXME: We need to be able to support lazy loading of pcm generated by ACLiC.
3250Bool_t TCling::HasPCMForLibrary(const char *libname) const
3251{
3252 llvm::StringRef ModuleName(libname);
3253 ModuleName = llvm::sys::path::stem(ModuleName);
3254 ModuleName.consume_front("lib");
3255
3256 // FIXME: In case when the modulemap is not yet loaded we will return the
3257 // wrong result. Consider a call to HasPCMForLibrary(../test/libEvent.so)
3258 // We will only load the modulemap for libEvent.so after we dlopen libEvent
3259 // which may happen after calling this interface. Maybe we should also check
3260 // if there is a Event.pcm file and a module.modulemap, load it and return
3261 // true.
3262 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
3263 clang::Module *M = moduleMap.findModule(ModuleName);
3264 return M && !M->IsUnimportable && M->getASTFile();
3265}
3266
3267////////////////////////////////////////////////////////////////////////////////
3268/// Return true if the file has already been loaded by cint.
3269/// We will try in this order:
3270/// actual filename
3271/// filename as a path relative to
3272/// the include path
3273/// the shared library path
3274
3276{
3278
3279 //FIXME: if we use llvm::sys::fs::make_absolute all this can go away. See
3280 // cling::DynamicLibraryManager.
3281
3282 std::string file_name = filename;
3283 size_t at = std::string::npos;
3284 while ((at = file_name.find("/./")) != std::string::npos)
3285 file_name.replace(at, 3, "/");
3286
3287 std::string filesStr = "";
3288 llvm::raw_string_ostream filesOS(filesStr);
3289 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3290 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
3291 filesOS.flush();
3292
3293 llvm::SmallVector<llvm::StringRef, 100> files;
3294 llvm::StringRef(filesStr).split(files, "\n");
3295
3296 std::set<std::string> fileMap;
3297 llvm::StringRef file_name_ref(file_name);
3298 // Fill fileMap; return early on exact match.
3299 for (llvm::SmallVector<llvm::StringRef, 100>::const_iterator
3300 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
3301 if ((*iF) == file_name_ref) return kTRUE; // exact match
3302 fileMap.insert(iF->str());
3303 }
3304
3305 if (fileMap.empty()) return kFALSE;
3306
3307 // Check MacroPath.
3308 TString sFilename(file_name.c_str());
3309 if (gSystem->FindFile(TROOT::GetMacroPath(), sFilename, kReadPermission)
3310 && fileMap.count(sFilename.Data())) {
3311 return kTRUE;
3312 }
3313
3314 // Check IncludePath.
3315 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
3316 incPath.Append(":").Prepend(" "); // to match " -I" (note leading ' ')
3317 incPath.ReplaceAll(" -I", ":"); // of form :dir1 :dir2:dir3
3318 while (incPath.Index(" :") != -1) {
3319 incPath.ReplaceAll(" :", ":");
3320 }
3321 incPath.Prepend(".:");
3322 sFilename = file_name.c_str();
3323 if (gSystem->FindFile(incPath, sFilename, kReadPermission)
3324 && fileMap.count(sFilename.Data())) {
3325 return kTRUE;
3326 }
3327
3328 // Check shared library.
3329 if (s_IsLibraryLoaded(file_name.c_str(), GetInterpreterImpl()))
3330 return kTRUE;
3331
3332 //FIXME: We must use the cling::Interpreter::lookupFileOrLibrary iface.
3333 clang::ConstSearchDirIterator *CurDir = nullptr;
3334 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
3335 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
3336 auto FE = HS.LookupFile(file_name.c_str(),
3337 clang::SourceLocation(),
3338 /*isAngled*/ false,
3339 /*FromDir*/ nullptr, CurDir,
3340 clang::ArrayRef<std::pair<clang::OptionalFileEntryRef,
3341 clang::DirectoryEntryRef>>(),
3342 /*SearchPath*/ nullptr,
3343 /*RelativePath*/ nullptr,
3344 /*RequestingModule*/ nullptr,
3345 /*SuggestedModule*/ nullptr,
3346 /*IsMapped*/ nullptr,
3347 /*IsFrameworkFound*/ nullptr,
3348 /*SkipCache*/ false,
3349 /*BuildSystemModule*/ false,
3350 /*OpenFile*/ false,
3351 /*CacheFail*/ false);
3352 if (FE) {
3353 // check in the source manager if the file is actually loaded
3354 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3355 // this works only with header (and source) files...
3356 clang::FileID FID = SM.translateFile(*FE);
3357 if (!FID.isInvalid() && FID.getHashValue() == 0)
3358 return kFALSE;
3359 else {
3360 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
3361 if (SLocE.isFile() && !SLocE.getFile().getContentCache().getBufferIfLoaded())
3362 return kFALSE;
3363 if (!FID.isInvalid())
3364 return kTRUE;
3365 }
3366 // ...then check shared library again, but with full path now
3367 sFilename = FE->getName().str();
3368 if (gSystem->FindDynamicLibrary(sFilename, kTRUE)
3369 && fileMap.count(sFilename.Data())) {
3370 return kTRUE;
3371 }
3372 }
3373 return kFALSE;
3374}
3375
3376
3377#if defined(R__MACOSX)
3378
3379////////////////////////////////////////////////////////////////////////////////
3380/// Check if lib is in the dynamic linker cache, returns true if it is, and if so,
3381/// modifies the library file name parameter `lib` from `/usr/lib/libFOO.dylib`
3382/// to `-lFOO` such that it can be passed to the linker.
3383/// This is a unique feature of macOS 11.
3384
3385static bool R__UpdateLibFileForLinking(TString &lib)
3386{
3387 const char *mapfile = nullptr;
3388#if __x86_64__
3389 mapfile = "/System/Library/dyld/dyld_shared_cache_x86_64.map";
3390#elif __arm64__
3391 mapfile = "/System/Library/dyld/dyld_shared_cache_arm64e.map";
3392#else
3393 #error unsupported architecture
3394#endif
3395 if (std::ifstream cacheMap{mapfile}) {
3396 std::string line;
3397 while (getline(cacheMap, line)) {
3398 if (line.find(lib) != std::string::npos) {
3399 lib.ReplaceAll("/usr/lib/lib","-l");
3400 lib.ReplaceAll(".dylib","");
3401 return true;
3402 }
3403 }
3404 return false;
3405 }
3406 return false;
3407}
3408#endif // R__MACOSX
3409
3410#if defined (R__LINUX) || defined (R__FBSD)
3411
3412////////////////////////////////////////////////////////////////////////////////
3413/// Callback for dl_iterate_phdr(), see `man dl_iterate_phdr`.
3414/// Collects opened libraries.
3415
3416static int callback_for_dl_iterate_phdr(struct dl_phdr_info *info, size_t size, void *data)
3417{
3418 // This function is called through UpdateListOfLoadedSharedLibraries() which is locked.
3419 static std::unordered_set<decltype(info->dlpi_addr)> sKnownLoadedLibBaseAddrs;
3420
3421 auto newLibs = static_cast<std::vector<std::string>*>(data);
3422 if (!sKnownLoadedLibBaseAddrs.count(info->dlpi_addr)) {
3423 // Skip \0, "", and kernel pseudo-libs linux-vdso.so.1 or linux-gate.so.1
3424 if (info->dlpi_name && info->dlpi_name[0]
3425#if defined(R__FBSD)
3426 //skip the executable (with null addr)
3427 && info->dlpi_addr
3428 //has no path
3429 && strncmp(info->dlpi_name, "[vdso]", 6)
3430 //the linker does not like to be mmapped
3431 //causes a crash in cling::DynamicLibraryManager::loadLibrary())
3432 //with error message "mmap of entire address space failed: Cannot allocate memory"
3433 && strncmp(info->dlpi_name, "/libexec/ld-elf.so.1", 20)
3434#endif
3435 && strncmp(info->dlpi_name, "linux-vdso.so", 13)
3436 && strncmp(info->dlpi_name, "linux-vdso32.so", 15)
3437 && strncmp(info->dlpi_name, "linux-vdso64.so", 15)
3438 && strncmp(info->dlpi_name, "linux-gate.so", 13))
3439 newLibs->emplace_back(info->dlpi_name);
3440 sKnownLoadedLibBaseAddrs.insert(info->dlpi_addr);
3441 }
3442 // No matter what the doc says, return != 0 means "stop the iteration".
3443 return 0;
3444}
3445
3446#endif // R__LINUX || R__FBSD
3447
3448
3449////////////////////////////////////////////////////////////////////////////////
3450
3452{
3453#if defined(R__WIN32) || defined(__CYGWIN__)
3454 HMODULE hModules[1024];
3455 void *hProcess;
3456 unsigned long cbModules;
3457 unsigned int i;
3458 hProcess = (void *)::GetCurrentProcess();
3459 ::EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbModules);
3460 // start at 1 to skip the executable itself
3461 for (i = 1; i < (cbModules / sizeof(void *)); i++) {
3462 static const int bufsize = 260;
3463 wchar_t winname[bufsize];
3464 char posixname[bufsize];
3465 ::GetModuleFileNameExW(hProcess, hModules[i], winname, bufsize);
3466#if defined(__CYGWIN__)
3467 cygwin_conv_path(CCP_WIN_W_TO_POSIX, winname, posixname, bufsize);
3468#else
3469 std::wstring wpath = winname;
3470 std::replace(wpath.begin(), wpath.end(), '\\', '/');
3471 string path(wpath.begin(), wpath.end());
3472 strncpy(posixname, path.c_str(), bufsize);
3473#endif
3474 if (!fSharedLibs.Contains(posixname)) {
3475 RegisterLoadedSharedLibrary(posixname);
3476 }
3477 }
3478#elif defined(R__MACOSX)
3479 // fPrevLoadedDynLibInfo stores the *next* image index to look at
3480 uint32_t imageIndex = (uint32_t) (size_t) fPrevLoadedDynLibInfo;
3481
3482 while (const mach_header* mh = _dyld_get_image_header(imageIndex)) {
3483 // Skip non-dylibs
3484 if (mh->filetype == MH_DYLIB) {
3485 if (const char* imageName = _dyld_get_image_name(imageIndex)) {
3486 RegisterLoadedSharedLibrary(imageName);
3487 }
3488 }
3489
3490 ++imageIndex;
3491 }
3492 fPrevLoadedDynLibInfo = (void*)(size_t)imageIndex;
3493#elif defined(R__LINUX) || defined(R__FBSD)
3494 // fPrevLoadedDynLibInfo is unused on Linux.
3495 (void) fPrevLoadedDynLibInfo;
3496
3497 std::vector<std::string> newLibs;
3498 dl_iterate_phdr(callback_for_dl_iterate_phdr, &newLibs);
3499 for (auto &&lib: newLibs)
3500 RegisterLoadedSharedLibrary(lib.c_str());
3501#else
3502 Error("TCling::UpdateListOfLoadedSharedLibraries",
3503 "Platform not supported!");
3504#endif
3505}
3506
3507namespace {
3508template <int N>
3509static bool StartsWithStrLit(const char *haystack, const char (&needle)[N]) {
3510 return !strncmp(haystack, needle, N - 1);
3511}
3512}
3513
3514////////////////////////////////////////////////////////////////////////////////
3515/// Register that a library was autoloaded either to provide a 'missing' symbol
3516/// or to provide a class (see TClass::GetClass and TROOT::LoadClass).
3517void TCling::RegisterAutoLoadedLibrary(const char *libname)
3518{
3519 fAutoLoadedLibraries.insert(libname);
3520}
3521
3522////////////////////////////////////////////////////////////////////////////////
3523/// Register a new shared library name with the interpreter; add it to
3524/// fSharedLibs.
3525
3527{
3528 // Ignore NULL filenames, aka "the process".
3529 if (!filename) return;
3530
3531 // Tell the interpreter that this library is available; all libraries can be
3532 // used to resolve symbols.
3533 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3534 if (!DLM->isLibraryLoaded(filename)) {
3535 DLM->loadLibrary(filename, true /*permanent*/, true /*resolved*/);
3536 }
3537
3538#if defined(R__MACOSX)
3539 // Check that this is not a system library that does not exist on disk.
3540 auto lenFilename = strlen(filename);
3541 auto isInMacOSSystemDir = [](const char *fn) {
3542 return StartsWithStrLit(fn, "/usr/lib/") || StartsWithStrLit(fn, "/System/Library/");
3543 };
3544 if (!strcmp(filename, "cl_kernels") // yepp, no directory
3545
3546 // These we should not link with (e.g. because they forward to .tbd):
3547 || StartsWithStrLit(filename, "/usr/lib/system/")
3548 || StartsWithStrLit(filename, "/usr/lib/libc++")
3549 || StartsWithStrLit(filename, "/System/Library/Frameworks/")
3550 || StartsWithStrLit(filename, "/System/Library/PrivateFrameworks/")
3551 || StartsWithStrLit(filename, "/System/Library/CoreServices/")
3552 || StartsWithStrLit(filename, "/usr/lib/libSystem")
3553 || StartsWithStrLit(filename, "/usr/lib/libstdc++")
3554 || StartsWithStrLit(filename, "/usr/lib/libicucore")
3555 || StartsWithStrLit(filename, "/usr/lib/libbsm")
3556 || StartsWithStrLit(filename, "/usr/lib/libobjc")
3557 || StartsWithStrLit(filename, "/usr/lib/libresolv")
3558 || StartsWithStrLit(filename, "/usr/lib/libauto")
3559 || StartsWithStrLit(filename, "/usr/lib/libcups")
3560 || StartsWithStrLit(filename, "/usr/lib/libDiagnosticMessagesClient")
3561 || StartsWithStrLit(filename, "/usr/lib/liblangid")
3562 || StartsWithStrLit(filename, "/usr/lib/libCRFSuite")
3563 || StartsWithStrLit(filename, "/usr/lib/libpam")
3564 || StartsWithStrLit(filename, "/usr/lib/libOpenScriptingUtil")
3565 || StartsWithStrLit(filename, "/usr/lib/libextension")
3566 || StartsWithStrLit(filename, "/usr/lib/libAudioToolboxUtility")
3567 || StartsWithStrLit(filename, "/usr/lib/liboah")
3568 || StartsWithStrLit(filename, "/usr/lib/libRosetta")
3569 || StartsWithStrLit(filename, "/usr/lib/libCoreEntitlements")
3570 || StartsWithStrLit(filename, "/usr/lib/libssl.")
3571 || StartsWithStrLit(filename, "/usr/lib/libcrypto.")
3572
3573 // The system lib is likely in macOS's blob.
3574 || (isInMacOSSystemDir(filename) && gSystem->AccessPathName(filename))
3575
3576 // "Link against the umbrella framework 'System.framework' instead"
3577 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_kernel")
3578 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_platform")
3579 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_pthread")
3580
3581 // "cannot link directly with dylib/framework, your binary is not an allowed client of
3582 // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
3583 // SDKs/MacOSX.sdk/usr/lib/libAudioToolboxUtility.tbd for architecture x86_64
3584 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4, ".tbd")))
3585 return;
3586 TString sFileName(filename);
3587 R__UpdateLibFileForLinking(sFileName);
3588 filename = sFileName.Data();
3589#elif defined(__CYGWIN__)
3590 // Check that this is not a system library
3591 static const int bufsize = 260;
3592 char posixwindir[bufsize];
3593 char *windir = std::getenv("WINDIR");
3594 if (windir)
3595 cygwin_conv_path(CCP_WIN_A_TO_POSIX, windir, posixwindir, bufsize);
3596 else
3597 snprintf(posixwindir, sizeof(posixwindir), "/Windows/");
3598 if (strstr(filename, posixwindir) ||
3599 strstr(filename, "/usr/bin/cyg"))
3600 return;
3601#elif defined(R__WIN32)
3602 if (strstr(filename, "/Windows/"))
3603 return;
3604#elif defined (R__LINUX)
3605 if (strstr(filename, "/ld-linux")
3606 || strstr(filename, "linux-gnu/")
3607 || strstr(filename, "/libstdc++.")
3608 || strstr(filename, "/libgcc")
3609 || strstr(filename, "/libc.")
3610 || strstr(filename, "/libdl.")
3611 || strstr(filename, "/libm."))
3612 return;
3613#endif
3614 // Update string of available libraries.
3615 if (!fSharedLibs.IsNull()) {
3616 fSharedLibs.Append(" ");
3617 }
3618 fSharedLibs.Append(filename);
3619}
3620
3621////////////////////////////////////////////////////////////////////////////////
3622/// Load a library file in cling's memory.
3623/// if 'system' is true, the library is never unloaded.
3624/// Return 0 on success, -1 on failure.
3625
3626Int_t TCling::Load(const char* filename, Bool_t system)
3627{
3628 assert(!IsFromRootCling() && "Trying to load library from rootcling!");
3629
3630 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3632 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3633 std::string canonLib = DLM->lookupLibrary(filename);
3634 cling::DynamicLibraryManager::LoadLibResult res
3635 = cling::DynamicLibraryManager::kLoadLibNotFound;
3636 if (!canonLib.empty()) {
3637 if (system)
3638 res = DLM->loadLibrary(filename, system, true);
3639 else {
3640 // For the non system libs, we'd like to be able to unload them.
3641 // FIXME: Here we lose the information about kLoadLibAlreadyLoaded case.
3642 cling::Interpreter::CompilationResult compRes;
3643 HandleInterpreterException(GetMetaProcessorImpl(), Form(".L %s", canonLib.c_str()), compRes, /*cling::Value*/nullptr);
3644 if (compRes == cling::Interpreter::kSuccess)
3645 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3646 }
3647 }
3648
3649 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3651 }
3652 switch (res) {
3653 case cling::DynamicLibraryManager::kLoadLibSuccess: return 0;
3654 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return 1;
3655 default: break;
3656 };
3657 return -1;
3658}
3659
3660////////////////////////////////////////////////////////////////////////////////
3661/// Load a macro file in cling's memory.
3662
3663void TCling::LoadMacro(const char* filename, EErrorCode* error)
3664{
3665 ProcessLine(Form(".L %s", filename), error);
3666}
3667
3668////////////////////////////////////////////////////////////////////////////////
3669/// Let cling process a command line asynch.
3670
3672{
3673 return ProcessLine(line, error);
3674}
3675
3676////////////////////////////////////////////////////////////////////////////////
3677/// Let cling process a command line synchronously, i.e we are waiting
3678/// it will be finished.
3679
3681{
3683 if (gApplication) {
3684 if (gApplication->IsCmdThread()) {
3685 return ProcessLine(line, error);
3686 }
3687 return 0;
3688 }
3689 return ProcessLine(line, error);
3690}
3691
3692////////////////////////////////////////////////////////////////////////////////
3693/// Directly execute an executable statement (e.g. "func()", "3+5", etc.
3694/// however not declarations, like "Int_t x;").
3695
3697{
3698#ifdef R__WIN32
3699 // Test on ApplicationImp not being 0 is needed because only at end of
3700 // TApplication ctor the IsLineProcessing flag is set to 0, so before
3701 // we can not use it.
3702 if (gApplication && gApplication->GetApplicationImp()) {
3703 while (gROOT->IsLineProcessing() && !gApplication) {
3704 Warning("Calc", "waiting for cling thread to free");
3705 gSystem->Sleep(500);
3706 }
3707 gROOT->SetLineIsProcessing();
3708 }
3709#endif // R__WIN32
3711 if (error) {
3712 *error = TInterpreter::kNoError;
3713 }
3714 cling::Value valRef;
3715 cling::Interpreter::CompilationResult cr = cling::Interpreter::kFailure;
3716 try {
3717 cr = fInterpreter->evaluate(line, valRef);
3718 }
3719 catch (cling::InterpreterException& ex)
3720 {
3721 Error("Calc", "%s.\n%s", ex.what(), "Evaluation of your expression was aborted.");
3722 ex.diagnose();
3723 cr = cling::Interpreter::kFailure;
3724 }
3725
3726 if (cr != cling::Interpreter::kSuccess) {
3727 // Failure in compilation.
3728 if (error) {
3729 // Note: Yes these codes are weird.
3731 }
3732 return 0L;
3733 }
3734 if (!valRef.isValid()) {
3735 // Failure at runtime.
3736 if (error) {
3737 // Note: Yes these codes are weird.
3738 *error = TInterpreter::kDangerous;
3739 }
3740 return 0L;
3741 }
3742
3743 if (valRef.isVoid()) {
3744 return 0;
3745 }
3746
3747 RegisterTemporary(valRef);
3748#ifdef R__WIN32
3749 if (gApplication && gApplication->GetApplicationImp()) {
3750 gROOT->SetLineHasBeenProcessed();
3751 }
3752#endif // R__WIN32
3753 return valRef.castAs<Longptr_t>();
3754}
3755
3756////////////////////////////////////////////////////////////////////////////////
3757/// Set a getline function to call when input is needed.
3758
3759void TCling::SetGetline(const char * (*getlineFunc)(const char* prompt),
3760 void (*histaddFunc)(const char* line))
3761{
3762 // If cling offers a replacement for G__pause(), it would need to
3763 // also offer a way to customize at least the history recording.
3764
3765#if defined(R__MUST_REVISIT)
3766#if R__MUST_REVISIT(6,2)
3767 Warning("SetGetline","Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3768#endif
3769#endif
3770}
3771
3772////////////////////////////////////////////////////////////////////////////////
3773/// Helper function to increase the internal Cling count of transactions
3774/// that change the AST.
3775
3776Bool_t TCling::HandleNewTransaction(const cling::Transaction &T)
3777{
3779
3780 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3781 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3782 || T.macros_begin() != T.macros_end()
3783 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3785 return true;
3786 }
3787 return false;
3788}
3789
3790////////////////////////////////////////////////////////////////////////////////
3791/// Delete object from cling symbol table so it can not be used anymore.
3792/// cling objects are always on the heap.
3793
3795{
3796 // NOTE: When replacing the mutex by a ReadWrite mutex, we **must**
3797 // put in place the Read/Write part here. Keeping the write lock
3798 // here is 'catasptrophic' for scaling as it means that ALL calls
3799 // to RecursiveRemove will take the write lock and performance
3800 // of many threads trying to access the write lock at the same
3801 // time is relatively bad.
3803 // Note that fgSetOfSpecials is supposed to be updated by TClingCallbacks::tryFindROOTSpecialInternal
3804 // (but isn't at the moment).
3805 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3806 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3807 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3809 DeleteGlobal(obj);
3810 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3811 }
3812 }
3813}
3814
3815////////////////////////////////////////////////////////////////////////////////
3816/// Pressing Ctrl+C should forward here. In the case where we have had
3817/// continuation requested we must reset it.
3818
3820{
3821 fMetaProcessor->cancelContinuation();
3822 // Reset the Cling state to the state saved by the last call to
3823 // TCling::SaveContext().
3824#if defined(R__MUST_REVISIT)
3825#if R__MUST_REVISIT(6,2)
3827 Warning("Reset","Cling should support the equivalent of scratch_upto(&fDictPos)");
3828#endif
3829#endif
3830}
3831
3832////////////////////////////////////////////////////////////////////////////////
3833/// Reset the Cling state to its initial state.
3834
3836{
3837#if defined(R__MUST_REVISIT)
3838#if R__MUST_REVISIT(6,2)
3840 Warning("ResetAll","Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3841#endif
3842#endif
3843}
3844
3845////////////////////////////////////////////////////////////////////////////////
3846/// Reset in Cling the list of global variables to the state saved by the last
3847/// call to TCling::SaveGlobalsContext().
3848///
3849/// Note: Right now, all we do is run the global destructors.
3850
3852{
3854 // TODO:
3855 // Here we should iterate over the transactions (N-3) and revert.
3856 // N-3 because the first three internal to cling.
3857
3858 fInterpreter->runAndRemoveStaticDestructors();
3859}
3860
3861////////////////////////////////////////////////////////////////////////////////
3862/// Reset the Cling 'user' global objects/variables state to the state saved by the last
3863/// call to TCling::SaveGlobalsContext().
3864
3866{
3867#if defined(R__MUST_REVISIT)
3868#if R__MUST_REVISIT(6,2)
3870 Warning("ResetGlobalVar","Cling should support the equivalent of resetglobalvar(obj)");
3871#endif
3872#endif
3873}
3874
3875////////////////////////////////////////////////////////////////////////////////
3876/// Rewind Cling dictionary to the point where it was before executing
3877/// the current macro. This function is typically called after SEGV or
3878/// ctlr-C after doing a longjmp back to the prompt.
3879
3881{
3882#if defined(R__MUST_REVISIT)
3883#if R__MUST_REVISIT(6,2)
3885 Warning("RewindDictionary","Cling should provide a way to revert transaction similar to rewinddictionary()");
3886#endif
3887#endif
3888}
3889
3890////////////////////////////////////////////////////////////////////////////////
3891/// Delete obj from Cling symbol table so it cannot be accessed anymore.
3892/// Returns 1 in case of success and 0 in case object was not in table.
3893
3895{
3896#if defined(R__MUST_REVISIT)
3897#if R__MUST_REVISIT(6,2)
3899 Warning("DeleteGlobal","Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3900#endif
3901#endif
3902 return 0;
3903}
3904
3905////////////////////////////////////////////////////////////////////////////////
3906/// Undeclare obj called name.
3907/// Returns 1 in case of success, 0 for failure.
3908
3910{
3911#if defined(R__MUST_REVISIT)
3912#if R__MUST_REVISIT(6,2)
3913 Warning("DeleteVariable","should do more that just reseting the value to zero");
3914#endif
3915#endif
3916
3918 llvm::StringRef srName(name);
3919 const char* unscopedName = name;
3920 llvm::StringRef::size_type posScope = srName.rfind("::");
3921 const clang::DeclContext* declCtx = nullptr;
3922 if (posScope != llvm::StringRef::npos) {
3923 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3924 const clang::Decl* scopeDecl
3925 = lh.findScope(srName.substr(0, posScope),
3926 cling::LookupHelper::WithDiagnostics);
3927 if (!scopeDecl) {
3928 Error("DeleteVariable", "Cannot find enclosing scope for variable %s",
3929 name);
3930 return 0;
3931 }
3932 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3933 if (!declCtx) {
3934 Error("DeleteVariable",
3935 "Enclosing scope for variable %s is not a declaration context",
3936 name);
3937 return 0;
3938 }
3939 unscopedName += posScope + 2;
3940 }
3941 // Could trigger deserialization of decls.
3942 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
3943 clang::NamedDecl* nVarDecl
3944 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3945 if (!nVarDecl) {
3946 Error("DeleteVariable", "Unknown variable %s", name);
3947 return 0;
3948 }
3949 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3950 if (!varDecl) {
3951 Error("DeleteVariable", "Entity %s is not a variable", name);
3952 return 0;
3953 }
3954
3955 clang::QualType qType = varDecl->getType();
3956 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3957 // Cannot set a reference's address to nullptr; the JIT can place it
3958 // into read-only memory (ROOT-7100).
3959 if (type->isPointerType()) {
3960 int** ppInt = (int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
3961 // set pointer to invalid.
3962 if (ppInt) *ppInt = nullptr;
3963 }
3964 return 1;
3965}
3966
3967////////////////////////////////////////////////////////////////////////////////
3968/// Save the current Cling state.
3969
3971{
3972#if defined(R__MUST_REVISIT)
3973#if R__MUST_REVISIT(6,2)
3975 Warning("SaveContext","Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
3976#endif
3977#endif
3978}
3979
3980////////////////////////////////////////////////////////////////////////////////
3981/// Save the current Cling state of global objects.
3982
3984{
3985#if defined(R__MUST_REVISIT)
3986#if R__MUST_REVISIT(6,2)
3988 Warning("SaveGlobalsContext","Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
3989#endif
3990#endif
3991}
3992
3993////////////////////////////////////////////////////////////////////////////////
3994/// No op: see TClingCallbacks (used to update the list of globals)
3995
3999
4000////////////////////////////////////////////////////////////////////////////////
4001/// No op: see TClingCallbacks (used to update the list of global functions)
4002
4006
4007////////////////////////////////////////////////////////////////////////////////
4008/// No op: see TClingCallbacks (used to update the list of types)
4009
4011{
4012}
4013
4014////////////////////////////////////////////////////////////////////////////////
4015/// Check in what order the member of a tuple are layout.
4021
4027
4033
4035{
4036 std::tuple<int,double> value;
4039
4040 size_t offset0 = ((char*)&(std::get<0>(value))) - ((char*)&value);
4041 size_t offset1 = ((char*)&(std::get<1>(value))) - ((char*)&value);
4042
4043 size_t ascOffset0 = ((char*)&(asc._0)) - ((char*)&asc);
4044 size_t ascOffset1 = ((char*)&(asc._1)) - ((char*)&asc);
4045
4046 size_t desOffset0 = ((char*)&(des._0)) - ((char*)&des);
4047 size_t desOffset1 = ((char*)&(des._1)) - ((char*)&des);
4048
4049 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
4051 } else if (offset0 == desOffset0 && offset1 == desOffset1) {
4053 } else {
4055 }
4056}
4057
4058static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh, Bool_t silent)
4059{
4060 TClassEdit::TSplitType tupleContent(classname);
4061 std::string alternateName = "TEmulatedTuple";
4062 alternateName.append( classname + 5 );
4063
4064 std::string fullname = "ROOT::Internal::" + alternateName;
4065 if (lh.findScope(fullname, cling::LookupHelper::NoDiagnostics,
4066 /*resultType*/nullptr, /* intantiateTemplate= */ false))
4067 return fullname;
4068
4069 {
4070 // Check if we can produce the tuple
4071 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
4072 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
4073 auto deleter = [](TypeInfo_t *type) {
4074 gInterpreter->TypeInfo_Delete(type);
4075 };
4076 std::unique_ptr<TypeInfo_t, decltype(deleter)> type{ gInterpreter->TypeInfo_Factory(), deleter };
4077 while (iter != theEnd) {
4078 gInterpreter->TypeInfo_Init(type.get(), iter->c_str());
4079 if (gInterpreter->TypeInfo_Property(type.get()) & kIsNotReacheable) {
4080 if (!silent)
4081 Error("Load","Could not declare alternate type for %s since %s (or one of its context) is private or protected",
4082 classname, iter->c_str());
4083 return "";
4084 }
4085 ++iter;
4086 }
4087 }
4088
4089 std::string guard_name;
4090 ROOT::TMetaUtils::GetCppName(guard_name,alternateName.c_str());
4091 std::ostringstream guard;
4092 guard << "ROOT_INTERNAL_TEmulated_";
4093 guard << guard_name;
4094
4095 std::ostringstream alternateTuple;
4096 std::ostringstream initializers;
4097
4098 alternateTuple << "#ifndef " << guard.str() << "\n";
4099 alternateTuple << "#define " << guard.str() << "\n";
4100 alternateTuple << "namespace ROOT { namespace Internal {\n";
4101 alternateTuple << "template <class... Types> struct TEmulatedTuple;\n";
4102 alternateTuple << "template <> struct " << alternateName << " {\n";
4103
4104 // This could also be a compile time choice ...
4105 switch(IsTupleAscending()) {
4107 unsigned int nMember = 0;
4108 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
4109 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
4110 auto sep = ':';
4111 while (iter != theEnd) {
4112 alternateTuple << " " << *iter << " _" << nMember << ";\n";
4113 initializers << " " << sep << " _" << nMember << "(std::get<" << nMember << ">(std::forward<Tuple>(t)))\n";
4114 ++iter;
4115 ++nMember;
4116 sep = ',';
4117 }
4118 break;
4119 }
4121 unsigned int nMember = tupleContent.fElements.size() - 3;
4122 auto iter = tupleContent.fElements.rbegin() + 1; // skip the 'stars'.
4123 auto theEnd = tupleContent.fElements.rend() - 1; // Skip the template name (tuple).
4124 auto sep = ':';
4125 while (iter != theEnd) {
4126 alternateTuple << " " << *iter << " _" << nMember << ";\n";
4127 initializers << " " << sep << " _" << nMember << "(std::get<" << nMember << ">(std::forward<Tuple>(t)))\n";
4128 ++iter;
4129 --nMember;
4130 sep = ',';
4131 }
4132 break;
4133 }
4135 Fatal("TCling::SetClassInfo::AlternateTuple",
4136 "Layout of std::tuple on this platform is unexpected.");
4137 break;
4138 }
4139 }
4140
4141 // default constructor
4142 alternateTuple << " TEmulatedTuple() = default;\n";
4143
4144 // constructor from other tuple-like types, like std::tuple
4145 alternateTuple << " template <typename Tuple>\n";
4146 alternateTuple << " TEmulatedTuple(Tuple&& t)\n";
4147 alternateTuple << initializers.str();
4148 alternateTuple << " {}\n";
4149
4150 alternateTuple << "};\n";
4151 alternateTuple << "}}\n";
4152 alternateTuple << "#endif\n";
4153 if (!gCling->Declare(alternateTuple.str().c_str()))
4154 {
4155 // Declare is not silent (yet?), so add an explicit error message
4156 // to indicate the consequence of the syntax errors.
4157 Error("Load","Could not declare %s",alternateName.c_str());
4158 return "";
4159 }
4160 alternateName = "ROOT::Internal::" + alternateName;
4161 return alternateName;
4162}
4163
4164////////////////////////////////////////////////////////////////////////////////
4165/// Set pointer to the TClingClassInfo in TClass.
4166/// If 'reload' is true, (attempt to) generate a new ClassInfo even if we
4167/// already have one.
4168
4169void TCling::SetClassInfo(TClass* cl, Bool_t reload, Bool_t silent)
4170{
4171 // We are shutting down, there is no point in reloading, it only triggers
4172 // redundant deserializations.
4173 if (fIsShuttingDown) {
4174 // Remove the decl_id from the DeclIdToTClass map
4175 if (cl->fClassInfo) {
4177 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4178 // Test again as another thread may have set fClassInfo to nullptr.
4179 if (TClinginfo) {
4180 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4181 }
4182 delete TClinginfo;
4183 cl->fClassInfo = nullptr;
4184 }
4185 return;
4186 }
4187
4189 if (cl->fClassInfo && !reload) {
4190 return;
4191 }
4192 //Remove the decl_id from the DeclIdToTClass map
4193 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4194 if (TClinginfo) {
4195 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4196 }
4197 delete TClinginfo;
4198 cl->fClassInfo = nullptr;
4199 std::string name(cl->GetName());
4200
4201 auto SetWithoutClassInfoState = [](TClass *cl)
4202 {
4203 if (cl->fState != TClass::kHasTClassInit) {
4204 if (cl->fStreamerInfo->GetEntries() != 0) {
4206 } else {
4208 }
4209 }
4210 };
4211 // Handle the special case of 'tuple' where we ignore the real implementation
4212 // details and just overlay a 'simpler'/'simplistic' version that is easy
4213 // for the I/O to understand and handle.
4214 if (strncmp(cl->GetName(),"tuple<",std::char_traits<char>::length("tuple<"))==0) {
4215 if (!reload)
4216 name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper(), silent);
4217 if (reload || name.empty()) {
4218 // We could not generate the alternate
4219 SetWithoutClassInfoState(cl);
4220 return;
4221 }
4222 }
4223
4224 bool instantiateTemplate = !cl->TestBit(TClass::kUnloading);
4225 // FIXME: Rather than adding an option to the TClingClassInfo, we should consider combining code
4226 // that is currently in the caller (like SetUnloaded) that disable AutoLoading and AutoParsing and
4227 // code is in the callee (disabling template instantiation) and end up with a more explicit class:
4228 // TClingClassInfoReadOnly.
4229 TClingClassInfo* info = new TClingClassInfo(GetInterpreterImpl(), name.c_str(), instantiateTemplate);
4230 if (!info->IsValid()) {
4231 SetWithoutClassInfoState(cl);
4232 delete info;
4233 return;
4234 }
4235 cl->fClassInfo = (ClassInfo_t*)info; // Note: We are transferring ownership here.
4236 // In case a class contains an external enum, the enum will be seen as a
4237 // class. We must detect this special case and make the class a Zombie.
4238 // Here we assume that a class has at least one method.
4239 // We can NOT call TClass::Property from here, because this method
4240 // assumes that the TClass is well formed to do a lot of information
4241 // caching. The method SetClassInfo (i.e. here) is usually called during
4242 // the building phase of the TClass, hence it is NOT well formed yet.
4243 Bool_t zombieCandidate = kFALSE;
4244 if (
4245 info->IsValid() &&
4246 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
4247 ) {
4248 zombieCandidate = kTRUE;
4249 }
4250 if (!info->IsLoaded()) {
4251 if (info->Property() & (kIsNamespace)) {
4252 // Namespaces can have info but no corresponding CINT dictionary
4253 // because they are auto-created if one of their contained
4254 // classes has a dictionary.
4255 zombieCandidate = kTRUE;
4256 }
4257 // this happens when no dictionary is available
4258 delete info;
4259 cl->fClassInfo = nullptr;
4260 }
4261 if (zombieCandidate && !cl->GetCollectionType()) {
4262 cl->MakeZombie();
4263 }
4264 // If we reach here, the info was valid (See early returns).
4265 if (cl->fState != TClass::kHasTClassInit) {
4266 if (cl->fClassInfo) {
4268 } else {
4269// if (TClassEdit::IsSTLCont(cl->GetName()) {
4270// There will be an emulated collection proxy, is that the same?
4271// cl->fState = TClass::kEmulated;
4272// } else {
4273 if (cl->fStreamerInfo->GetEntries() != 0) {
4275 } else {
4277 }
4278// }
4279 }
4280 }
4281 if (cl->fClassInfo) {
4282 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
4283 }
4284}
4285
4286////////////////////////////////////////////////////////////////////////////////
4287/// Checks if an entity with the specified name is defined in Cling.
4288/// Returns kUnknown if the entity is not defined.
4289/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
4290/// Returns kKnown if the entity is defined.
4291///
4292/// By default, structs, namespaces, classes, enums and unions are looked for.
4293/// If the flag isClassOrNamespaceOnly is true, classes, structs and
4294/// namespaces only are considered. I.e. if the name is an enum or a union,
4295/// the returned value is false.
4296///
4297/// In the case where the class is not loaded and belongs to a namespace
4298/// or is nested, looking for the full class name is outputting a lots of
4299/// (expected) error messages. Currently the only way to avoid this is to
4300/// specifically check that each level of nesting is already loaded.
4301/// In case of templates the idea is that everything between the outer
4302/// '<' and '>' has to be skipped, e.g.: `aap<pippo<noot>::klaas>::a_class`
4303
4305TCling::CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly /* = kFALSE*/)
4306{
4308 static const char *anonEnum = "anonymous enum ";
4309 static const int cmplen = strlen(anonEnum);
4310
4311 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
4312 return kUnknown;
4313 }
4314
4315 // Do not turn on the AutoLoading if it is globally off.
4316 autoload = autoload && IsClassAutoLoadingEnabled();
4317
4318 // Avoid the double search below in case the name is a fundamental type
4319 // or typedef to a fundamental type.
4320 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
4321 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
4322
4323 if (fundType && fundType->GetType() < TVirtualStreamerInfo::kObject
4324 && fundType->GetType() > 0) {
4325 // Fundamental type, no a class.
4326 return kUnknown;
4327 }
4328
4329 // Migrated from within TClass::GetClass
4330 // If we want to know if a class or a namespace with this name exists in the
4331 // interpreter and this is an enum in the type system, before or after loading
4332 // according to the autoload function argument, return kUnknown.
4333 if (isClassOrNamespaceOnly && TEnum::GetEnum(name, autoload ? TEnum::kAutoload : TEnum::kNone))
4334 return kUnknown;
4335
4336 const char *classname = name;
4337
4338 // RAII to suspend and restore auto-loading and auto-parsing based on some external conditions.
4339 class MaybeSuspendAutoLoadParse {
4340 int fStoreAutoLoad = 0;
4341 int fStoreAutoParse = 0;
4342 bool fSuspendedAutoParse = false;
4343 public:
4344 MaybeSuspendAutoLoadParse(int autoload) {
4345 fStoreAutoLoad = ((TCling*)gCling)->SetClassAutoLoading(autoload);
4346 }
4347
4348 void SuspendAutoParsing() {
4349 fSuspendedAutoParse = true;
4350 fStoreAutoParse = ((TCling*)gCling)->SetSuspendAutoParsing(true);
4351 }
4352
4353 ~MaybeSuspendAutoLoadParse() {
4354 if (fSuspendedAutoParse)
4355 ((TCling*)gCling)->SetSuspendAutoParsing(fStoreAutoParse);
4356 ((TCling*)gCling)->SetClassAutoLoading(fStoreAutoLoad);
4357 }
4358 };
4359
4360 MaybeSuspendAutoLoadParse autoLoadParseRAII( autoload );
4361 if (TClassEdit::IsStdPair(classname) || TClassEdit::IsStdPairBase(classname))
4362 autoLoadParseRAII.SuspendAutoParsing();
4363
4364 // First we want to check whether the decl exist, but _without_
4365 // generating any template instantiation. However, the lookup
4366 // still will create a forward declaration of the class template instance
4367 // if it exist. In this case, the return value of findScope will still
4368 // be zero but the type will be initialized.
4369 // Note in the corresponding code in ROOT 5, CINT was not instantiating
4370 // this forward declaration.
4371 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4372 const clang::Type *type = nullptr;
4373 const clang::Decl *decl
4374 = lh.findScope(classname,
4375 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4376 : cling::LookupHelper::NoDiagnostics,
4377 &type, /* intantiateTemplate= */ false );
4378 if (!decl) {
4379 std::string buf = TClassEdit::InsertStd(classname);
4380 decl = lh.findScope(buf,
4381 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4382 : cling::LookupHelper::NoDiagnostics,
4383 &type,false);
4384 }
4385
4386 if (type) {
4387 // If decl==0 and the type is valid, then we have a forward declaration.
4388 if (!decl) {
4389 // If we have a forward declaration for a class template instantiation,
4390 // we want to ignore it if it was produced/induced by the call to
4391 // findScope, however we can not distinguish those from the
4392 // instantiation induce by 'soft' use (and thus also induce by the
4393 // same underlying code paths)
4394 // ['soft' use = use not requiring a complete definition]
4395 // So to reduce the amount of disruption to the existing code we
4396 // would just ignore those for STL collection, for which we really
4397 // need to have the compiled collection proxy (and thus the TClass
4398 // bootstrap).
4399 clang::ClassTemplateSpecializationDecl *tmpltDecl =
4400 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
4401 (type->getAsCXXRecordDecl());
4402 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
4403 // Since the point of instantiation is invalid, we 'guess' that
4404 // the 'instantiation' of the forwarded type appended in
4405 // findscope.
4406 if (ROOT::TMetaUtils::IsSTLCont(*tmpltDecl)) {
4407 // For STL Collection we return kUnknown.
4408 return kUnknown;
4409 }
4410 }
4411 }
4413 if (!tci.IsValid()) {
4414 return kUnknown;
4415 }
4416 auto propertiesMask = isClassOrNamespaceOnly ? kIsClass | kIsStruct | kIsNamespace :
4418
4419 if (tci.Property() & propertiesMask) {
4420 bool hasClassDefInline = false;
4421 if (isClassOrNamespaceOnly) {
4422 // We do not need to check for ClassDefInline when this is called from
4423 // TClass::Init, we only do it for the call from TClass::GetClass.
4424 auto hasDictionary = tci.GetMethod("Dictionary", "", false, nullptr, ROOT::kExactMatch);
4425 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, nullptr, ROOT::kExactMatch);
4426
4427 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
4428 int lineNumber = 0;
4429 bool success = false;
4430 std::tie(success, lineNumber) =
4431 ROOT::TMetaUtils::GetTrivialIntegralReturnValue(implLineFunc.GetAsFunctionDecl(), *fInterpreter);
4432 hasClassDefInline = success && (lineNumber == -1);
4433 }
4434 }
4435
4436 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
4437 // , hasClassDefInline);
4438
4439 // We are now sure that the entry is not in fact an autoload entry.
4440 if (hasClassDefInline)
4441 return kWithClassDefInline;
4442 else
4443 return kKnown;
4444 } else {
4445 // We are now sure that the entry is not in fact an autoload entry.
4446 return kUnknown;
4447 }
4448 }
4449
4450 if (decl)
4451 return kKnown;
4452 else
4453 return kUnknown;
4454
4455 // Setting up iterator part of TClingTypedefInfo is too slow.
4456 // Copy the lookup code instead:
4457 /*
4458 TClingTypedefInfo t(fInterpreter, name);
4459 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
4460 delete[] classname;
4461 return kTRUE;
4462 }
4463 */
4464
4465// const clang::Decl *decl = lh.findScope(name);
4466// if (!decl) {
4467// std::string buf = TClassEdit::InsertStd(name);
4468// decl = lh.findScope(buf);
4469// }
4470
4471// return (decl);
4472}
4473
4474////////////////////////////////////////////////////////////////////////////////
4475/// Return true if there is a class template by the given name ...
4476
4478{
4479 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4480 // Interpreter transaction ahead, needs locking
4482 const clang::Decl *decl
4483 = lh.findClassTemplate(name,
4484 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4485 : cling::LookupHelper::NoDiagnostics);
4486 if (!decl) {
4487 std::string strname = "std::";
4488 strname += name;
4489 decl = lh.findClassTemplate(strname,
4490 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4491 : cling::LookupHelper::NoDiagnostics);
4492 }
4493 return nullptr != decl;
4494}
4495
4496////////////////////////////////////////////////////////////////////////////////
4497/// Create list of pointers to base class(es) for TClass cl.
4498
4500{
4502 if (cl->fBase) {
4503 return;
4504 }
4505 // Ignore the base class (e.g. `std::_Complex_base` on Windows)
4507 cl->fBase = new TList();
4508 return;
4509 }
4511 if (!tci) return;
4513 TList *listOfBase = new TList;
4514 while (t.Next()) {
4515 // if name cannot be obtained no use to put in list
4516 if (t.IsValid() && t.Name()) {
4518 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
4519 }
4520 }
4521 // Now that is complete, publish it.
4522 cl->fBase = listOfBase;
4523}
4524
4525////////////////////////////////////////////////////////////////////////////////
4526/// Create list of pointers to enums for TClass cl.
4527
4528void TCling::LoadEnums(TListOfEnums& enumList) const
4529{
4531
4532 const Decl * D;
4533 TClass* cl = enumList.GetClass();
4534 if (cl) {
4535 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4536 }
4537 else {
4538 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4539 }
4540 // Iterate on the decl of the class and get the enums.
4541 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4542 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4543 // Collect all contexts of the namespace.
4544 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4545 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4546 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(), declEnd = allDeclContexts.end();
4547 declIter != declEnd; ++declIter) {
4548 // Iterate on all decls for each context.
4549 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4550 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4551 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4552 // Get name of the enum type.
4553 std::string buf;
4554 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4555 llvm::raw_string_ostream stream(buf);
4556 // Don't trigger fopen of the source file to count lines:
4557 Policy.AnonymousTagLocations = false;
4558 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
4559 stream.flush();
4560 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
4561 if (!buf.empty()) {
4562 const char* name = buf.c_str();
4563 // Add the enum to the list of loaded enums.
4564 enumList.Get(ED, name);
4565 }
4566 }
4567 }
4568 }
4569 }
4570}
4571
4572////////////////////////////////////////////////////////////////////////////////
4573/// Create list of pointers to function templates for TClass cl.
4574
4576{
4578
4579 const Decl * D;
4580 TListOfFunctionTemplates* funcTempList;
4581 if (cl) {
4582 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4583 funcTempList = (TListOfFunctionTemplates*)cl->GetListOfFunctionTemplates(false);
4584 }
4585 else {
4586 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4587 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4588 }
4589 // Iterate on the decl of the class and get the enums.
4590 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4591 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4592 // Collect all contexts of the namespace.
4593 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4594 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4595 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(),
4596 declEnd = allDeclContexts.end(); declIter != declEnd; ++declIter) {
4597 // Iterate on all decls for each context.
4598 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4599 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4600 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4601 funcTempList->Get(FTD);
4602 }
4603 }
4604 }
4605 }
4606}
4607
4608////////////////////////////////////////////////////////////////////////////////
4609/// Get the scopes representing using declarations of namespace
4610
4611std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4612{
4614 return ci->GetUsingNamespaces();
4615}
4616
4617////////////////////////////////////////////////////////////////////////////////
4618/// Create list of pointers to data members for TClass cl.
4619/// This is now a nop. The creation and updating is handled in
4620/// TListOfDataMembers.
4621
4623{
4624}
4625
4626////////////////////////////////////////////////////////////////////////////////
4627/// Create list of pointers to methods for TClass cl.
4628/// This is now a nop. The creation and updating is handled in
4629/// TListOfFunctions.
4630
4632{
4633}
4634
4635////////////////////////////////////////////////////////////////////////////////
4636/// Update the list of pointers to method for TClass cl
4637/// This is now a nop. The creation and updating is handled in
4638/// TListOfFunctions.
4639
4641{
4642}
4643
4644////////////////////////////////////////////////////////////////////////////////
4645/// Update the list of pointers to data members for TClass cl
4646/// This is now a nop. The creation and updating is handled in
4647/// TListOfDataMembers.
4648
4650{
4651}
4652
4653////////////////////////////////////////////////////////////////////////////////
4654/// Create list of pointers to method arguments for TMethod m.
4655
4657{
4659 if (m->fMethodArgs) {
4660 return;
4661 }
4662 TList *arglist = new TList;
4664 while (t.Next()) {
4665 if (t.IsValid()) {
4667 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4668 }
4669 }
4670 m->fMethodArgs = arglist;
4671}
4672
4673////////////////////////////////////////////////////////////////////////////////
4674/// Return whether we are waiting for more input either because the collected
4675/// input contains unbalanced braces or last seen token was a `\` (backslash-newline)
4676
4678{
4679 return fMetaProcessor->awaitingMoreInput();
4680}
4681
4682////////////////////////////////////////////////////////////////////////////////
4683/// Generate a TClass for the given class.
4684/// Since the caller has already check the ClassInfo, let it give use the
4685/// result (via the value of emulation) rather than recalculate it.
4686
4687TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4688{
4689// For now the following line would lead to the (unwanted) instantiation
4690// of class template. This could/would need to be resurrected only if
4691// we re-introduce so sort of automatic instantiation. However this would
4692// have to include carefull look at the template parameter to avoid
4693// creating instance we can not really use (if the parameter are only forward
4694// declaration or do not have all the necessary interfaces).
4695
4696 // TClingClassInfo tci(fInterpreter, classname);
4697 // if (1 || !tci.IsValid()) {
4698
4699 Version_t version = 1;
4700 if (TClassEdit::IsSTLCont(classname)) {
4701 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4702 }
4704 TClass *cl = new TClass(classname, version, silent);
4705 if (!emulation) {
4706 // Set the class version if the class is versioned.
4707 // Note that we cannot just call CLASS::Class_Version() as we might not have
4708 // an execution engine (when invoked from rootcling).
4709
4710 // Do not call cl->GetClassVersion(), it has side effects!
4711 Version_t oldvers = cl->fClassVersion;
4712 if (oldvers == version && cl->GetClassInfo()) {
4713 // We have a version and it might need an update.
4715 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4716 // Namespaces don't have class versions.
4717 return cl;
4718 }
4719 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", nullptr /*poffset*/,
4722 if (!mi.IsValid()) {
4723 if (cl->TestBit(TClass::kIsTObject)) {
4724 Error("GenerateTClass",
4725 "Cannot find %s::Class_Version()! Class version might be wrong.",
4726 cl->GetName());
4727 }
4728 return cl;
4729 }
4730 Version_t newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4731 *fInterpreter);
4732 if (newvers == -1) {
4733 // Didn't manage to determine the class version from the AST.
4734 // Use runtime instead.
4735 if ((mi.Property() & kIsStatic)
4736 && !fInterpreter->isInSyntaxOnlyMode()) {
4737 // This better be a static function.
4739 callfunc.SetFunc(&mi);
4740 newvers = callfunc.ExecInt(nullptr);
4741 } else {
4742 Error("GenerateTClass",
4743 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4744 cl->GetName());
4745 }
4746 }
4747 if (newvers != oldvers) {
4748 cl->fClassVersion = newvers;
4749 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4750 }
4751 }
4752 }
4753
4754 return cl;
4755
4756// } else {
4757// return GenerateTClass(&tci,silent);
4758// }
4759}
4760
4761#if 0
4762////////////////////////////////////////////////////////////////////////////////
4763
4764static void GenerateTClass_GatherInnerIncludes(cling::Interpreter *interp, TString &includes,TClingClassInfo *info)
4765{
4766 includes += info->FileName();
4767
4768 const clang::ClassTemplateSpecializationDecl *templateCl
4769 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4770 if (templateCl) {
4771 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4772 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4773 if (arg.getKind() == clang::TemplateArgument::Type) {
4774 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4775
4776 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4777 // We really need a header file.
4778 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4779 if (argdecl) {
4780 includes += ";";
4781 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4782 GenerateTClass_GatherInnerIncludes(interp, includes, &subinfo);
4783 } else {
4784 std::string Result;
4785 llvm::raw_string_ostream OS(Result);
4786 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4787 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4788 }
4789 }
4790 }
4791 }
4792 }
4793}
4794#endif
4795
4796////////////////////////////////////////////////////////////////////////////////
4797/// Generate a TClass for the given class.
4798
4799TClass *TCling::GenerateTClass(ClassInfo_t *classinfo, Bool_t silent /* = kFALSE */)
4800{
4801 TClingClassInfo *info = (TClingClassInfo*)classinfo;
4802 if (!info || !info->IsValid()) {
4803 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4804 return nullptr;
4805 }
4806 // We are in the case where we have AST nodes for this class.
4807 TClass *cl = nullptr;
4808 std::string classname;
4809 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4810 if (TClassEdit::IsSTLCont(classname)) {
4811#if 0
4812 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4813 // We need to build up the list of required headers, by
4814 // looking at each template arguments.
4815 TString includes;
4816 GenerateTClass_GatherInnerIncludes(fInterpreter,includes,info);
4817
4818 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4819 // 0 means success.
4820 cl = TClass::LoadClass(classnam.c_str(), silent);
4821 if (cl == 0) {
4822 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4823 }
4824 }
4825#endif
4826 if (cl == nullptr) {
4827 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4828 cl = new TClass(classinfo, version, nullptr, nullptr, -1, -1, silent);
4829 }
4830 } else {
4831 // For regular class, just create a TClass on the fly ...
4832 // Not quite useful yet, but that what CINT used to do anyway.
4833 cl = new TClass(classinfo, 1, nullptr, nullptr, -1, -1, silent);
4834 }
4835 // Add the new TClass to the map of declid and TClass*.
4836 if (cl) {
4838 }
4839 return cl;
4840}
4841
4842////////////////////////////////////////////////////////////////////////////////
4843/// Generate the dictionary for the C++ classes listed in the first
4844/// argument (in a semi-colon separated list).
4845/// 'includes' contains a semi-colon separated list of file to
4846/// `#include` in the dictionary.
4847/// For example:
4848/// ~~~ {.cpp}
4849/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4850/// ~~~
4851/// or
4852/// ~~~ {.cpp}
4853/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4854/// ~~~
4855
4856Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4857{
4858 if (classes == nullptr || classes[0] == 0) {
4859 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4860 return 0;
4861 }
4862 // Split the input list
4863 std::vector<std::string> listClasses;
4864 for (
4865 const char* current = classes, *prev = classes;
4866 *current != 0;
4867 ++current
4868 ) {
4869 if (*current == ';') {
4870 listClasses.push_back(std::string(prev, current - prev));
4871 prev = current + 1;
4872 }
4873 else if (*(current + 1) == 0) {
4874 listClasses.push_back(std::string(prev, current + 1 - prev));
4875 prev = current + 1;
4876 }
4877 }
4878 std::vector<std::string> listIncludes;
4879 if (!includes)
4880 includes = "";
4881 for (
4882 const char* current = includes, *prev = includes;
4883 *current != 0;
4884 ++current
4885 ) {
4886 if (*current == ';') {
4887 listIncludes.push_back(std::string(prev, current - prev));
4888 prev = current + 1;
4889 }
4890 else if (*(current + 1) == 0) {
4891 listIncludes.push_back(std::string(prev, current + 1 - prev));
4892 prev = current + 1;
4893 }
4894 }
4895 // Generate the temporary dictionary file
4896 return !TCling_GenerateDictionary(listClasses, listIncludes,
4897 std::vector<std::string>(), std::vector<std::string>());
4898}
4899
4900////////////////////////////////////////////////////////////////////////////////
4901/// Return pointer to cling Decl of global/static variable that is located
4902/// at the address given by addr.
4903
4904TInterpreter::DeclId_t TCling::GetDataMember(ClassInfo_t *opaque_cl, const char *name) const
4905{
4907 DeclId_t d;
4908 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4909
4910 // Could trigger deserialization of decls.
4911 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4912
4913 if (cl) {
4914 d = cl->GetDataMember(name);
4915 // We check if the decl of the data member has an annotation which indicates
4916 // an ioname.
4917 // In case this is true, if the name requested is not the ioname, we
4918 // return 0, as if the member did not exist. In some sense we override
4919 // the information in the TClassInfo instance, isolating the typesystem in
4920 // TClass from the one in the AST.
4921 if (const ValueDecl* decl = (const ValueDecl*) d){
4922 std::string ioName;
4923 bool hasIoName = ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"ioname",ioName);
4924 if (hasIoName && ioName != name) return nullptr;
4925 }
4926 return d;
4927 }
4928 // We are looking up for something on the TU scope.
4929 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
4930 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
4931 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
4932 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
4933 // are only fulfilling ROOT's understanding for a Data Member.
4934 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
4935 // similar as below.
4936 using namespace clang;
4937 Sema& SemaR = fInterpreter->getSema();
4938 DeclarationName DName = &SemaR.Context.Idents.get(name);
4939
4940 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
4941 RedeclarationKind::ForExternalRedeclaration);
4942
4943 cling::utils::Lookup::Named(&SemaR, R);
4944
4945 LookupResult::Filter F = R.makeFilter();
4946 // Filter the data-member looking decls.
4947 while (F.hasNext()) {
4948 NamedDecl *D = F.next();
4949 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) ||
4950 isa<IndirectFieldDecl>(D))
4951 continue;
4952 F.erase();
4953 }
4954 F.done();
4955
4956 if (R.isSingleResult())
4957 return R.getFoundDecl();
4958 return nullptr;
4959}
4960
4961////////////////////////////////////////////////////////////////////////////////
4962/// Return pointer to cling Decl of global/static variable that is located
4963/// at the address given by addr.
4964
4966{
4968
4969 const clang::Decl* possibleEnum = nullptr;
4970 // FInd the context of the decl.
4971 if (cl) {
4973 if (cci) {
4974 const clang::DeclContext* dc = nullptr;
4975 if (const clang::Decl* D = cci->GetDecl()) {
4976 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
4977 dc = dyn_cast<clang::RecordDecl>(D);
4978 }
4979 }
4980 if (dc) {
4981 // If it is a data member enum.
4982 // Could trigger deserialization of decls.
4983 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4984 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
4985 } else {
4986 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
4987 }
4988 }
4989 } else {
4990 // If it is a global enum.
4991 // Could trigger deserialization of decls.
4992 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4993 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
4994 }
4995 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
4996 && isa<clang::EnumDecl>(possibleEnum)) {
4997 return possibleEnum;
4998 }
4999 return nullptr;
5000}
5001
5002////////////////////////////////////////////////////////////////////////////////
5003/// Return pointer to cling DeclId for a global value
5004
5005TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
5006{
5007 if (!gv) return nullptr;
5008
5009 llvm::StringRef mangled_name = gv->getName();
5010
5011 int err = 0;
5012 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.str().c_str(), err);
5013 if (err) {
5014 if (err == -2) {
5015 // It might simply be an unmangled global name.
5016 DeclId_t d;
5018 d = gcl.GetDataMember(mangled_name.str().c_str());
5019 return d;
5020 }
5021 return nullptr;
5022 }
5023
5024 std::string scopename(demangled_name_c);
5025 free(demangled_name_c);
5026
5027 //
5028 // Separate out the class or namespace part of the
5029 // function name.
5030 //
5031 std::string dataname;
5032
5033 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
5034 scopename.erase(0, sizeof("typeinfo for ")-1);
5035 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
5036 scopename.erase(0, sizeof("vtable for ")-1);
5037 } else {
5038 // See if it is a function
5039 std::string::size_type pos = scopename.rfind('(');
5040 if (pos != std::string::npos) {
5041 return nullptr;
5042 }
5043 // Separate the scope and member name
5044 pos = scopename.rfind(':');
5045 if (pos != std::string::npos) {
5046 if ((pos != 0) && (scopename[pos-1] == ':')) {
5047 dataname = scopename.substr(pos+1);
5048 scopename.erase(pos-1);
5049 }
5050 } else {
5051 scopename.clear();
5052 dataname = scopename;
5053 }
5054 }
5055 //fprintf(stderr, "name: '%s'\n", name.c_str());
5056 // Now we have the class or namespace name, so do the lookup.
5057
5058
5059 DeclId_t d;
5060 if (scopename.size()) {
5061 TClingClassInfo cl(GetInterpreterImpl(), scopename.c_str());
5062 d = cl.GetDataMember(dataname.c_str());
5063 }
5064 else {
5066 d = gcl.GetDataMember(dataname.c_str());
5067 }
5068 return d;
5069}
5070
5071////////////////////////////////////////////////////////////////////////////////
5072/// NOT IMPLEMENTED.
5073
5075{
5076 Error("GetDataMemberWithValue()", "not implemented");
5077 return nullptr;
5078}
5079
5080////////////////////////////////////////////////////////////////////////////////
5081/// Return pointer to cling DeclId for a data member with a given name.
5082
5084{
5085 // NOT IMPLEMENTED.
5086 Error("GetDataMemberAtAddr()", "not implemented");
5087 return nullptr;
5088}
5089
5090////////////////////////////////////////////////////////////////////////////////
5091/// Return the cling mangled name for a method of a class with parameters
5092/// params (params is a string of actual arguments, not formal ones). If the
5093/// class is 0 the global function list will be searched.
5094
5095TString TCling::GetMangledName(TClass* cl, const char* method,
5096 const char* params, Bool_t objectIsConst /* = kFALSE */)
5097{
5100 if (cl) {
5102 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
5103 &offset);
5104 }
5105 else {
5108 func.SetFunc(&gcl, method, params, &offset);
5109 }
5111 if (!mi) return "";
5112 TString mangled_name( mi->GetMangledName() );
5113 delete mi;
5114 return mangled_name;
5115}
5116
5117////////////////////////////////////////////////////////////////////////////////
5118/// Return the cling mangled name for a method of a class with a certain
5119/// prototype, i.e. "char*,int,float". If the class is 0 the global function
5120/// list will be searched.
5121
5123 const char* proto, Bool_t objectIsConst /* = kFALSE */,
5124 EFunctionMatchMode mode /* = kConversionMatch */)
5125{
5127 if (cl) {
5128 return ((TClingClassInfo*)cl->GetClassInfo())->
5129 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
5130 }
5132 return gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
5133}
5134
5135////////////////////////////////////////////////////////////////////////////////
5136/// Return pointer to cling interface function for a method of a class with
5137/// parameters params (params is a string of actual arguments, not formal
5138/// ones). If the class is 0 the global function list will be searched.
5139
5140void* TCling::GetInterfaceMethod(TClass* cl, const char* method,
5141 const char* params, Bool_t objectIsConst /* = kFALSE */)
5142{
5145 if (cl) {
5147 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
5148 &offset);
5149 }
5150 else {
5153 func.SetFunc(&gcl, method, params, &offset);
5154 }
5155 return (void*) func.InterfaceMethod();
5156}
5157
5158////////////////////////////////////////////////////////////////////////////////
5159/// Return pointer to cling interface function for a method of a class with
5160/// a certain name.
5161
5162TInterpreter::DeclId_t TCling::GetFunction(ClassInfo_t *opaque_cl, const char* method)
5163{
5165 DeclId_t f;
5166 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5167 if (cl) {
5168 f = cl->GetMethod(method).GetDeclId();
5169 }
5170 else {
5172 f = gcl.GetMethod(method).GetDeclId();
5173 }
5174 return f;
5175
5176}
5177
5178////////////////////////////////////////////////////////////////////////////////
5179/// Insert overloads of name in cl to res.
5180
5181void TCling::GetFunctionOverloads(ClassInfo_t *cl, const char *funcname,
5182 std::vector<DeclId_t>& res) const
5183{
5184 clang::Sema& S = fInterpreter->getSema();
5185 clang::ASTContext& Ctx = S.Context;
5186 const clang::Decl* CtxDecl
5187 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
5188 Ctx.getTranslationUnitDecl();
5189 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
5190 const clang::DeclContext* DeclCtx = RecDecl;
5191
5192 if (!DeclCtx)
5193 DeclCtx = dyn_cast<clang::NamespaceDecl>(CtxDecl);
5194 if (!DeclCtx) return;
5195
5196 clang::DeclarationName DName;
5197 // The DeclarationName is funcname, unless it's a ctor or dtor.
5198 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
5199
5200 if (RecDecl) {
5201 if (RecDecl->getNameAsString() == funcname) {
5202 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5203 DName = Ctx.DeclarationNames.getCXXConstructorName(Ctx.getCanonicalType(QT));
5204 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
5205 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5206 DName = Ctx.DeclarationNames.getCXXDestructorName(Ctx.getCanonicalType(QT));
5207 } else {
5208 DName = &Ctx.Idents.get(funcname);
5209 }
5210 } else {
5211 DName = &Ctx.Idents.get(funcname);
5212 }
5213
5214 // NotForRedeclaration: we want to find names in inline namespaces etc.
5215 clang::LookupResult R(S, DName, clang::SourceLocation(), Sema::LookupOrdinaryName,
5216 RedeclarationKind::NotForRedeclaration);
5217 R.suppressDiagnostics(); // else lookup with NotForRedeclaration will check access etc
5218 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
5219 if (R.empty()) return;
5220 R.resolveKind();
5221 res.reserve(res.size() + (R.end() - R.begin()));
5222 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
5223 IR != ER; ++IR) {
5224 if (const clang::FunctionDecl* FD
5225 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
5226 if (!FD->getDescribedFunctionTemplate()) {
5227 res.push_back(FD);
5228 }
5229 } else if (const auto *USD = llvm::dyn_cast<const clang::UsingShadowDecl>(*IR)) {
5230 // FIXME: multi-level using
5231 if (llvm::isa<clang::FunctionDecl>(USD->getTargetDecl())) {
5232 res.push_back(USD);
5233 }
5234 }
5235 }
5236}
5237
5238////////////////////////////////////////////////////////////////////////////////
5239/// Return pointer to cling interface function for a method of a class with
5240/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5241/// function list will be searched.
5242
5244 const char* proto,
5245 Bool_t objectIsConst /* = kFALSE */,
5246 EFunctionMatchMode mode /* = kConversionMatch */)
5247{
5249 void* f;
5250 if (cl) {
5251 f = ((TClingClassInfo*)cl->GetClassInfo())->
5252 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5253 }
5254 else {
5256 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5257 }
5258 return f;
5259}
5260
5261////////////////////////////////////////////////////////////////////////////////
5262/// Return pointer to cling DeclId for a method of a class with
5263/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5264/// function list will be searched.
5265
5266TInterpreter::DeclId_t TCling::GetFunctionWithValues(ClassInfo_t *opaque_cl, const char* method,
5267 const char* params,
5268 Bool_t objectIsConst /* = kFALSE */)
5269{
5271 DeclId_t f;
5272 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5273 if (cl) {
5274 f = cl->GetMethodWithArgs(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5275 }
5276 else {
5278 f = gcl.GetMethod(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5279 }
5280 return f;
5281}
5282
5283////////////////////////////////////////////////////////////////////////////////
5284/// Return pointer to cling interface function for a method of a class with
5285/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5286/// function list will be searched.
5287
5288TInterpreter::DeclId_t TCling::GetFunctionWithPrototype(ClassInfo_t *opaque_cl, const char* method,
5289 const char* proto,
5290 Bool_t objectIsConst /* = kFALSE */,
5291 EFunctionMatchMode mode /* = kConversionMatch */)
5292{
5294 DeclId_t f;
5295 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5296 if (cl) {
5297 f = cl->GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5298 }
5299 else {
5301 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5302 }
5303 return f;
5304}
5305
5306////////////////////////////////////////////////////////////////////////////////
5307/// Return pointer to cling interface function for a method of a class with
5308/// a certain name.
5309
5310TInterpreter::DeclId_t TCling::GetFunctionTemplate(ClassInfo_t *opaque_cl, const char* name)
5311{
5313 DeclId_t f;
5314 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5315 if (cl) {
5316 f = cl->GetFunctionTemplate(name);
5317 }
5318 else {
5320 f = gcl.GetFunctionTemplate(name);
5321 }
5322 return f;
5323
5324}
5325
5326////////////////////////////////////////////////////////////////////////////////
5327/// The 'name' is known to the interpreter, this function returns
5328/// the internal version of this name (usually just resolving typedefs)
5329/// This is used in particular to synchronize between the name used
5330/// by rootcling and by the run-time environment (TClass)
5331/// Return 0 if the name is not known.
5332
5333void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
5334{
5335 output.clear();
5336
5338
5340 if (!cl.IsValid()) {
5341 return ;
5342 }
5343 if (full) {
5344 cl.FullName(output,*fNormalizedCtxt);
5345 return;
5346 }
5347 // Well well well, for backward compatibility we need to act a bit too
5348 // much like CINT.
5350 splitname.ShortType(output, TClassEdit::kDropStd );
5351
5352 return;
5353}
5354
5355////////////////////////////////////////////////////////////////////////////////
5356/// Execute a global function with arguments params.
5357///
5358/// FIXME: The cint-based version of this code does not check if the
5359/// SetFunc() call works, and does not do any real checking
5360/// for errors from the Exec() call. It did fetch the most
5361/// recent cint security error and return that in error, but
5362/// this does not really translate well to cling/clang. We
5363/// should enhance these interfaces so that we can report
5364/// compilation and runtime errors properly.
5365
5366void TCling::Execute(const char* function, const char* params, int* error)
5367{
5369 if (error) {
5370 *error = TInterpreter::kNoError;
5371 }
5373 Longptr_t offset = 0L;
5375 func.SetFunc(&cl, function, params, &offset);
5376 func.Exec(nullptr);
5377}
5378
5379////////////////////////////////////////////////////////////////////////////////
5380/// Execute a method from class cl with arguments params.
5381///
5382/// FIXME: The cint-based version of this code does not check if the
5383/// SetFunc() call works, and does not do any real checking
5384/// for errors from the Exec() call. It did fetch the most
5385/// recent cint security error and return that in error, but
5386/// this does not really translate well to cling/clang. We
5387/// should enhance these interfaces so that we can report
5388/// compilation and runtime errors properly.
5389
5390void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5391 const char* params, Bool_t objectIsConst, int* error)
5392{
5394 if (error) {
5395 *error = TInterpreter::kNoError;
5396 }
5397 // If the actual class of this object inherits 2nd (or more) from TObject,
5398 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5399 // hence gInterpreter->Execute will improperly correct the offset.
5400 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5401 Longptr_t offset = 0L;
5403 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst, &offset);
5404 void* address = (void*)((Longptr_t)addr + offset);
5405 func.Exec(address);
5406}
5407
5408////////////////////////////////////////////////////////////////////////////////
5409
5410void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5411 const char* params, int* error)
5412{
5413 Execute(obj,cl,method,params,false,error);
5414}
5415
5416////////////////////////////////////////////////////////////////////////////////
5417/// Execute a method from class cl with the arguments in array params
5418/// (params[0] ... params[n] = array of TObjString parameters).
5419/// Convert the TObjArray array of TObjString parameters to a character
5420/// string of comma separated parameters.
5421/// The parameters of type 'char' are enclosed in double quotes and all
5422/// internal quotes are escaped.
5423
5424void TCling::Execute(TObject* obj, TClass* cl, TMethod* method,
5425 TObjArray* params, int* error)
5426{
5427 if (!method) {
5428 Error("Execute", "No method was defined");
5429 return;
5430 }
5431 TList* argList = method->GetListOfMethodArgs();
5432 // Check number of actual parameters against of expected formal ones
5433
5434 Int_t nparms = argList->LastIndex() + 1;
5435 Int_t argc = params ? params->GetEntries() : 0;
5436
5437 if (argc > nparms) {
5438 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
5439 return;
5440 }
5441 if (nparms != argc) {
5442 // Let's see if the 'missing' argument are all defaulted.
5443 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
5444 assert(nparms > 0);
5445
5446 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
5447 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5448 // There is a default value for the first missing
5449 // argument, so we are fine.
5450 } else {
5451 Int_t firstDefault = -1;
5452 for (Int_t i = 0; i < nparms; i ++) {
5453 arg = (TMethodArg *) argList->At( i );
5454 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5455 firstDefault = i;
5456 break;
5457 }
5458 }
5459 if (firstDefault >= 0) {
5460 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);
5461 } else {
5462 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
5463 }
5464 return;
5465 }
5466 }
5467
5468 const char* listpar = "";
5469 TString complete(10);
5470 if (params) {
5471 // Create a character string of parameters from TObjArray
5472 TIter next(params);
5473 for (Int_t i = 0; i < argc; i ++) {
5474 TMethodArg* arg = (TMethodArg*) argList->At(i);
5476 TObjString* nxtpar = (TObjString*) next();
5477 if (i) {
5478 complete += ',';
5479 }
5480 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
5481 TString chpar('\"');
5482 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
5483 // At this point we have to check if string contains \\"
5484 // and apply some more sophisticated parser. Not implemented yet!
5485 complete += chpar;
5486 complete += '\"';
5487 }
5488 else {
5489 complete += nxtpar->String();
5490 }
5491 }
5492 listpar = complete.Data();
5493 }
5494
5495 // And now execute it.
5497 if (error) {
5498 *error = TInterpreter::kNoError;
5499 }
5500 // If the actual class of this object inherits 2nd (or more) from TObject,
5501 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5502 // hence gInterpreter->Execute will improperly correct the offset.
5503 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5505 TClingMethodInfo *minfo = (TClingMethodInfo*)method->fInfo;
5506 func.Init(*minfo);
5507 func.SetArgs(listpar);
5508 // Now calculate the 'this' pointer offset for the method
5509 // when starting from the class described by cl.
5510 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetTargetFunctionDecl());
5511 Longptr_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
5512 void* address = (void*)((Longptr_t)addr + offset);
5513 func.Exec(address);
5514}
5515
5516////////////////////////////////////////////////////////////////////////////////
5517
5518void TCling::ExecuteWithArgsAndReturn(TMethod* method, void* address,
5519 const void* args[] /*=0*/,
5520 int nargs /*=0*/,
5521 void* ret/*= 0*/) const
5522{
5523 if (!method) {
5524 Error("ExecuteWithArgsAndReturn", "No method was defined");
5525 return;
5526 }
5527
5528 TClingMethodInfo* minfo = (TClingMethodInfo*) method->fInfo;
5529 TClingCallFunc func(*minfo);
5530 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5531}
5532
5533////////////////////////////////////////////////////////////////////////////////
5534/// Execute a cling macro.
5535
5537{
5539 fCurExecutingMacros.push_back(filename);
5541 fCurExecutingMacros.pop_back();
5542 return result;
5543}
5544
5545////////////////////////////////////////////////////////////////////////////////
5546/// Return the file name of the current un-included interpreted file.
5547/// See the documentation for GetCurrentMacroName().
5548
5550{
5551 Warning("GetTopLevelMacroName", "Must change return type!");
5552 return fCurExecutingMacros.empty() ? nullptr : fCurExecutingMacros.back();
5553}
5554
5555////////////////////////////////////////////////////////////////////////////////
5556/// Return the file name of the currently interpreted file,
5557/// included or not. Example to illustrate the difference between
5558/// GetCurrentMacroName() and GetTopLevelMacroName():
5559/// ~~~ {.cpp}
5560/// void inclfile() {
5561/// std::cout << "In inclfile.C" << std::endl;
5562/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5563/// TCling::GetCurrentMacroName() << std::endl;
5564/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5565/// TCling::GetTopLevelMacroName() << std::endl;
5566/// }
5567/// ~~~
5568/// ~~~ {.cpp}
5569/// void mymacro() {
5570/// std::cout << "In mymacro.C" << std::endl;
5571/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5572/// TCling::GetCurrentMacroName() << std::endl;
5573/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5574/// TCling::GetTopLevelMacroName() << std::endl;
5575/// std::cout << " Now calling inclfile..." << std::endl;
5576/// gInterpreter->ProcessLine(".x inclfile.C");
5577/// }
5578/// ~~~
5579/// Running mymacro.C will print:
5580///
5581/// ~~~ {.cpp}
5582/// root [0] .x mymacro.C
5583/// ~~~
5584/// In mymacro.C
5585/// ~~~ {.cpp}
5586/// TCling::GetCurrentMacroName() returns ./mymacro.C
5587/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5588/// ~~~
5589/// Now calling inclfile...
5590/// In inclfile.h
5591/// ~~~ {.cpp}
5592/// TCling::GetCurrentMacroName() returns inclfile.C
5593/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5594/// ~~~
5595
5597{
5598#if defined(R__MUST_REVISIT)
5599#if R__MUST_REVISIT(6,0)
5600 Warning("GetCurrentMacroName", "Must change return type!");
5601#endif
5602#endif
5603 return fCurExecutingMacros.empty() ? nullptr : fCurExecutingMacros.back();
5604}
5605
5606////////////////////////////////////////////////////////////////////////////////
5607/// Return the absolute type of typeDesc.
5608/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
5609/// You need to use the result immediately before it is being overwritten.
5610
5611const char* TCling::TypeName(const char* typeDesc)
5612{
5613 TTHREAD_TLS_DECL(std::string,t);
5614
5615 if (!strstr(typeDesc, "(*)(")) {
5616 const char *s = strchr(typeDesc, ' ');
5617 const char *template_start = strchr(typeDesc, '<');
5618 if (!strcmp(typeDesc, "long long")) {
5619 t = typeDesc;
5620 }
5621 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5622 t = typeDesc;
5623 }
5624 // s is the position of the second 'word' (if any)
5625 // except in the case of templates where there will be a space
5626 // just before any closing '>': eg.
5627 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5628 else if (s && (template_start == nullptr || (s < template_start))) {
5629 t = s + 1;
5630 }
5631 else {
5632 t = typeDesc;
5633 }
5634 }
5635 else {
5636 t = typeDesc;
5637 }
5638 auto l = t.length();
5639 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&'))
5640 --l;
5641 t.resize(l);
5642 return t.c_str(); // NOLINT
5643}
5644
5645static bool requiresRootMap(const char* rootmapfile)
5646{
5647 assert(rootmapfile && *rootmapfile);
5648
5649 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5650 libName.consume_back(".rootmap");
5651
5652 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5653}
5654
5655////////////////////////////////////////////////////////////////////////////////
5656/// Read and parse a rootmapfile in its new format, and return 0 in case of
5657/// success, -1 if the file has already been read, and -3 in case its format
5658/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5659/// error.
5660
5661int TCling::ReadRootmapFile(const char *rootmapfile, TUniqueString *uniqueString)
5662{
5663 if (!(rootmapfile && *rootmapfile))
5664 return 0;
5665
5666 if (!requiresRootMap(rootmapfile))
5667 return 0; // success
5668
5669 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5670 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5671
5672 std::string rootmapfileNoBackslash(rootmapfile);
5673#ifdef _MSC_VER
5674 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5675#endif
5676 // Add content of a specific rootmap file
5677 if (fRootmapFiles->FindObject(rootmapfileNoBackslash.c_str()))
5678 return -1;
5679
5680 // Line 1 is `{ decls }`
5681 std::string lineDirective = std::string("\n#line 2 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n";
5682
5683 std::ifstream file(rootmapfileNoBackslash);
5684 std::string line;
5685 line.reserve(200);
5686 std::string lib_name;
5687 line.reserve(100);
5688 bool newFormat = false;
5689 while (getline(file, line, '\n')) {
5690 if (!newFormat && (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5691 file.close();
5692 return -3; // old format
5693 }
5694 newFormat = true;
5695
5696 if (line.compare(0, 9, "{ decls }") == 0) {
5697 // forward declarations
5698
5699 while (getline(file, line, '\n')) {
5700 if (line[0] == '[')
5701 break;
5702 if (!uniqueString) {
5703 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5704 rootmapfileNoBackslash.c_str());
5705 return -4;
5706 }
5707 if (!lineDirective.empty())
5708 uniqueString->Append(lineDirective);
5709 uniqueString->Append(line + '\n');
5710 }
5711 }
5712 const char firstChar = line[0];
5713 if (firstChar == '[') {
5714 // new section (library)
5715 auto brpos = line.find(']');
5716 if (brpos == string::npos)
5717 continue;
5718 lib_name = line.substr(1, brpos - 1);
5719 // Remove spaces at the beginning and at the end of the library name
5720 lib_name.erase(lib_name.find_last_not_of(' ') + 1);
5721 lib_name.erase(0, lib_name.find_first_not_of(' '));
5722 if (gDebug > 3) {
5723 TString lib_nameTstr(lib_name.c_str());
5724 TObjArray *tokens = lib_nameTstr.Tokenize(" ");
5725 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5726 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5727 if (wlib) {
5728 Info("ReadRootmapFile", "%s: New section for %s", rootmapfile, lib_nameTstr.Data());
5729 } else {
5730 Info("ReadRootmapFile", "%s: Section for %s (library does not exist)", rootmapfile, lib_nameTstr.Data());
5731 }
5732 delete[] wlib;
5733 delete tokens;
5734 }
5735 } else {
5736 auto keyLenIt = keyLenMap.find(firstChar);
5737 if (keyLenIt == keyLenMap.end())
5738 continue;
5739 unsigned int keyLen = keyLenIt->second;
5740 // Do not make a copy, just start after the key
5741 const char *keyname = line.c_str() + keyLen;
5742 if (gDebug > 6)
5743 Info("ReadRootmapFile", "%s: class %s in %s", rootmapfile, keyname, lib_name.c_str());
5744 TEnvRec *isThere = fMapfile->Lookup(keyname);
5745 if (isThere) {
5746 if (lib_name != isThere->GetValue()) { // the same key for two different libs
5747 if (firstChar == 'n') {
5748 if (gDebug > 3)
5749 Info("ReadRootmapFile",
5750 "While processing %s, namespace %s was found to be associated to %s although it is already "
5751 "associated to %s",
5752 rootmapfile, keyname, lib_name.c_str(), isThere->GetValue());
5753 } else if (firstChar == 'h') { // it is a header: add the libname to the list of libs to be loaded.
5754 lib_name += " ";
5755 lib_name += isThere->GetValue();
5756 fMapfile->SetValue(keyname, lib_name.c_str());
5757 } else if (!TClassEdit::IsSTLCont(keyname)) {
5758 Warning("ReadRootmapFile",
5759 "While processing %s, %s %s was found to be associated to %s although it is already "
5760 "associated to %s",
5761 rootmapfile, line.substr(0, keyLen - 1).c_str(), keyname, lib_name.c_str(),
5762 isThere->GetValue());
5763 }
5764 } else { // the same key for the same lib
5765 if (gDebug > 3)
5766 Info("ReadRootmapFile", "While processing %s, key %s was found to be already defined for %s",
5767 rootmapfile, keyname, lib_name.c_str());
5768 }
5769 } else {
5770 fMapfile->SetValue(keyname, lib_name.c_str());
5771 }
5772 }
5773 }
5774 file.close();
5775 return 0;
5776}
5777
5778////////////////////////////////////////////////////////////////////////////////
5779/// Create a resource table and read the (possibly) three resource files,
5780/// i.e. `$ROOTSYS/etc/system<name>` (or `ROOTETCDIR/system<name>`), `$HOME/<name>`
5781/// and `$PWD/<name>`. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You
5782/// can read additional user defined resource files by creating additional TEnv
5783/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5784/// the `$HOME/<name>` resource file will be skipped. This might be useful in
5785/// case the home directory resides on an automounted remote file system
5786/// and one wants to avoid the file system from being mounted.
5787
5789{
5790 assert(requiresRootMap(name) && "We have a module!");
5791
5792 if (!requiresRootMap(name))
5793 return;
5794
5795 Bool_t ignore = fMapfile->IgnoreDuplicates(kFALSE);
5796
5797 fMapfile->SetRcName(name);
5798
5799 TString sname = "system";
5800 sname += name;
5801 TString temp_sname = sname;
5802 const char *s1 = gSystem->PrependPathName(TROOT::GetEtcDir(), temp_sname);
5803
5804 Int_t ret = ReadRootmapFile(s1);
5805 if (ret == -3) // old format
5806 fMapfile->ReadFile(s1, kEnvGlobal);
5807 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5808 TString temp_name = name;
5809 const char *s2 = gSystem->PrependPathName(gSystem->HomeDirectory(), temp_name);
5810 ret = ReadRootmapFile(s2);
5811 if (ret == -3) // old format
5812 fMapfile->ReadFile(s2, kEnvUser);
5813 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
5814 ret = ReadRootmapFile(name);
5815 if (ret == -3) // old format
5816 fMapfile->ReadFile(name, kEnvLocal);
5817 }
5818 } else {
5819 ret = ReadRootmapFile(name);
5820 if (ret == -3) // old format
5821 fMapfile->ReadFile(name, kEnvLocal);
5822 }
5823 fMapfile->IgnoreDuplicates(ignore);
5824}
5825
5826
5827namespace {
5828 using namespace clang;
5829
5830 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5831 // This class is to be considered an helper for AutoLoading.
5832 // It is a recursive visitor is used to inspect namespaces and specializations
5833 // coming from forward declarations in rootmaps and to set the external visible
5834 // storage flag for them.
5835 public:
5836 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5837 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5838 // We want to enable the external lookup for this namespace
5839 // because it may shadow the lookup of other names contained
5840 // in that namespace
5841
5842 nsDecl->setHasExternalVisibleStorage();
5843 fNSSet.insert(nsDecl);
5844 return true;
5845 }
5846 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl* specDecl) {
5847 // We want to enable the external lookup for this specialization
5848 // because we can provide a definition for it!
5849 if (specDecl->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
5850 //SpecSet.insert(specDecl);
5851 specDecl->setHasExternalLexicalStorage();
5852
5853 // No need to recurse. On the contrary, recursing is actively harmful:
5854 // NOTE: must not recurse to prevent this visitor from triggering loading from
5855 // the external AST source (i.e. autoloading). This would be triggered right here,
5856 // before autoloading is even set up, as rootmap file parsing happens before that.
5857 // Even if autoloading is off and has no effect, triggering loading from external
5858 // AST source resets the flag setHasExternalLexicalStorage(), hiding this specialization
5859 // from subsequent autoloads!
5860 return false;
5861 }
5862 private:
5863 std::unordered_set<const NamespaceDecl*>& fNSSet;
5864 };
5865}
5866
5867////////////////////////////////////////////////////////////////////////////////
5868/// Load map between class and library. If rootmapfile is specified a
5869/// specific rootmap file can be added (typically used by ACLiC).
5870/// In case of error -1 is returned, 0 otherwise.
5871/// The interpreter uses this information to automatically load the shared
5872/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5873
5874Int_t TCling::LoadLibraryMap(const char* rootmapfile)
5875{
5876 if (rootmapfile && *rootmapfile && !requiresRootMap(rootmapfile))
5877 return 0;
5878
5880
5881 // open the [system].rootmap files
5882 if (!fMapfile) {
5883 fMapfile = new TEnv();
5884 fMapfile->IgnoreDuplicates(kTRUE);
5886 fRootmapFiles->SetOwner();
5887 InitRootmapFile(".rootmap");
5888 }
5889
5890 // Prepare a list of all forward declarations for cling
5891 // For some experiments it is easily as big as 500k characters. To be on the
5892 // safe side, we go for 1M.
5893 TUniqueString uniqueString(1048576);
5894
5895 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5896 // A rootmap file must end with the string ".rootmap".
5897 TString ldpath = gSystem->GetDynamicPath();
5898 if (ldpath != fRootmapLoadPath) {
5899 fRootmapLoadPath = ldpath;
5900#ifdef WIN32
5901 TObjArray* paths = ldpath.Tokenize(";");
5902#else
5903 TObjArray* paths = ldpath.Tokenize(":");
5904#endif
5905 TString d;
5906 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5907 d = ((TObjString *)paths->At(i))->GetString();
5908 // check if directory already scanned
5909 Int_t skip = 0;
5910 for (Int_t j = 0; j < i; j++) {
5911 TString pd = ((TObjString *)paths->At(j))->GetString();
5912 if (pd == d) {
5913 skip++;
5914 break;
5915 }
5916 }
5917 if (!skip) {
5918 void* dirp = gSystem->OpenDirectory(d);
5919 if (dirp) {
5920 if (gDebug > 3) {
5921 Info("LoadLibraryMap", "%s", d.Data());
5922 }
5923 const char* f1;
5924 while ((f1 = gSystem->GetDirEntry(dirp))) {
5925 TString f = f1;
5926 if (f.EndsWith(".rootmap")) {
5927 TString p;
5928 p = d + "/" + f;
5929 if (!gSystem->AccessPathName(p, kReadPermission)) {
5930 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
5931 if (gDebug > 4) {
5932 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
5933 }
5934 Int_t ret = ReadRootmapFile(p, &uniqueString);
5935
5936 if (ret == 0)
5937 fRootmapFiles->Add(new TNamed(gSystem->BaseName(f), p.Data()));
5938 if (ret == -3) {
5939 // old format
5940 fMapfile->ReadFile(p, kEnvGlobal);
5941 fRootmapFiles->Add(new TNamed(f, p));
5942 }
5943 }
5944 // else {
5945 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
5946 // fRootmapFiles->FindObject(f)->ls();
5947 // }
5948 }
5949 }
5950 if (f.BeginsWith("rootmap")) {
5951 TString p;
5952 p = d + "/" + f;
5953 FileStat_t stat;
5954 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
5955 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
5956 }
5957 }
5958 }
5959 }
5960 gSystem->FreeDirectory(dirp);
5961 }
5962 }
5963 delete paths;
5964 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
5965 return -1;
5966 }
5967 }
5968 if (rootmapfile && *rootmapfile) {
5969 Int_t res = ReadRootmapFile(rootmapfile, &uniqueString);
5970 if (res == 0) {
5971 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
5972 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
5973 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5974 }
5975 else if (res == -3) {
5976 // old format
5977 Bool_t ignore = fMapfile->IgnoreDuplicates(kFALSE);
5978 fMapfile->ReadFile(rootmapfile, kEnvGlobal);
5979 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5980 fMapfile->IgnoreDuplicates(ignore);
5981 }
5982 }
5983 TEnvRec* rec;
5984 TIter next(fMapfile->GetTable());
5985 while ((rec = (TEnvRec*) next())) {
5986 TString cls = rec->GetName();
5987 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5988 // get the first lib from the list of lib and dependent libs
5989 TString libs = rec->GetValue();
5990 if (libs == "") {
5991 continue;
5992 }
5993 TString delim(" ");
5994 TObjArray* tokens = libs.Tokenize(delim);
5995 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5996 // convert "@@" to "::", we used "@@" because TEnv
5997 // considers "::" a terminator
5998 cls.Remove(0, 8);
5999 cls.ReplaceAll("@@", "::");
6000 // convert "-" to " ", since class names may have
6001 // blanks and TEnv considers a blank a terminator
6002 cls.ReplaceAll("-", " ");
6003 if (gDebug > 6) {
6004 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
6005 if (wlib) {
6006 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
6007 }
6008 else {
6009 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
6010 }
6011 delete[] wlib;
6012 }
6013 delete tokens;
6014 }
6015 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
6016 cls.Remove(0, 8);
6017 // convert "-" to " ", since class names may have
6018 // blanks and TEnv considers a blank a terminator
6019 cls.ReplaceAll("-", " ");
6020 fInterpreter->declare(cls.Data());
6021 }
6022 }
6023
6024 // Process the forward declarations collected
6025 cling::Transaction* T = nullptr;
6026 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
6027 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
6028
6029 if (compRes!=cling::Interpreter::kSuccess){
6030 Warning("LoadLibraryMap",
6031 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
6032 }
6033
6034 if (T) {
6035 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
6036 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
6037 if (declIt->m_DGR.isSingleDecl()) {
6038 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
6039 if (clang::isa<TagDecl>(D) || clang::isa<NamespaceDecl>(D)) {
6040 evsAdder.TraverseDecl(D);
6041 }
6042 }
6043 }
6044 }
6045 }
6046
6047 // clear duplicates
6048
6049 return 0;
6050}
6051
6052////////////////////////////////////////////////////////////////////////////////
6053/// Scan again along the dynamic path for library maps. Entries for the loaded
6054/// shared libraries are unloaded first. This can be useful after reseting
6055/// the dynamic path through TSystem::SetDynamicPath()
6056/// In case of error -1 is returned, 0 otherwise.
6057
6064
6065////////////////////////////////////////////////////////////////////////////////
6066/// Reload the library map entries coming from all the loaded shared libraries,
6067/// after first unloading the current ones.
6068/// In case of error -1 is returned, 0 otherwise.
6069
6071{
6072 const TString sharedLibLStr = GetSharedLibs();
6073 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
6074 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
6075 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
6076 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
6077 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
6078 const Int_t ret = UnloadLibraryMap(sharedLibBaseStr);
6079 if (ret < 0) {
6080 continue;
6081 }
6082 TString rootMapBaseStr = sharedLibBaseStr;
6083 if (sharedLibBaseStr.EndsWith(".dll")) {
6084 rootMapBaseStr.ReplaceAll(".dll", "");
6085 }
6086 else if (sharedLibBaseStr.EndsWith(".DLL")) {
6087 rootMapBaseStr.ReplaceAll(".DLL", "");
6088 }
6089 else if (sharedLibBaseStr.EndsWith(".so")) {
6090 rootMapBaseStr.ReplaceAll(".so", "");
6091 }
6092 else if (sharedLibBaseStr.EndsWith(".sl")) {
6093 rootMapBaseStr.ReplaceAll(".sl", "");
6094 }
6095 else if (sharedLibBaseStr.EndsWith(".dl")) {
6096 rootMapBaseStr.ReplaceAll(".dl", "");
6097 }
6098 else if (sharedLibBaseStr.EndsWith(".a")) {
6099 rootMapBaseStr.ReplaceAll(".a", "");
6100 }
6101 else {
6102 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
6103 delete sharedLibL;
6104 return -1;
6105 }
6106 rootMapBaseStr += ".rootmap";
6107 const char* rootMap = gSystem->Which(gSystem->GetDynamicPath(), rootMapBaseStr);
6108 if (!rootMap) {
6109 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
6110 delete[] rootMap;
6111 delete sharedLibL;
6112 return -1;
6113 }
6114 const Int_t status = LoadLibraryMap(rootMap);
6115 if (status < 0) {
6116 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
6117 delete[] rootMap;
6118 delete sharedLibL;
6119 return -1;
6120 }
6121 delete[] rootMap;
6122 }
6123 delete sharedLibL;
6124 return 0;
6125}
6126
6127////////////////////////////////////////////////////////////////////////////////
6128/// Unload the library map entries coming from all the loaded shared libraries.
6129/// Returns 0 if succesful
6130
6132{
6133 const TString sharedLibLStr = GetSharedLibs();
6134 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
6135 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
6136 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
6137 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
6138 UnloadLibraryMap(sharedLibBaseStr);
6139 }
6140 delete sharedLibL;
6141 return 0;
6142}
6143
6144////////////////////////////////////////////////////////////////////////////////
6145/// Unload library map entries coming from the specified library.
6146/// Returns -1 in case no entries for the specified library were found,
6147/// 0 otherwise.
6148
6150{
6151 if (!fMapfile || !library || !*library) {
6152 return 0;
6153 }
6154 TString libname(library);
6155 Ssiz_t idx = libname.Last('.');
6156 if (idx != kNPOS) {
6157 libname.Remove(idx);
6158 }
6159 size_t len = libname.Length();
6160 TEnvRec *rec;
6161 TIter next(fMapfile->GetTable());
6163 Int_t ret = 0;
6164 while ((rec = (TEnvRec *) next())) {
6165 TString cls = rec->GetName();
6166 if (cls.Length() > 2) {
6167 // get the first lib from the list of lib and dependent libs
6168 TString libs = rec->GetValue();
6169 if (libs == "") {
6170 continue;
6171 }
6172 TString delim(" ");
6173 TObjArray* tokens = libs.Tokenize(delim);
6174 const char* lib = ((TObjString *)tokens->At(0))->GetName();
6175 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
6176 // convert "@@" to "::", we used "@@" because TEnv
6177 // considers "::" a terminator
6178 cls.Remove(0, 8);
6179 cls.ReplaceAll("@@", "::");
6180 // convert "-" to " ", since class names may have
6181 // blanks and TEnv considers a blank a terminator
6182 cls.ReplaceAll("-", " ");
6183 }
6184 if (!strncmp(lib, libname.Data(), len)) {
6185 if (fMapfile->GetTable()->Remove(rec) == nullptr) {
6186 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
6187 ret = -1;
6188 }
6189 }
6190 delete tokens;
6191 }
6192 }
6193 if (ret >= 0) {
6194 TString library_rootmap(library);
6195 if (!library_rootmap.EndsWith(".rootmap"))
6196 library_rootmap.Append(".rootmap");
6197 TNamed* mfile = nullptr;
6198 while ((mfile = (TNamed *)fRootmapFiles->FindObject(library_rootmap))) {
6199 fRootmapFiles->Remove(mfile);
6200 delete mfile;
6201 }
6202 fRootmapFiles->Compress();
6203 }
6204 return ret;
6205}
6206
6207////////////////////////////////////////////////////////////////////////////////
6208/// Register the AutoLoading information for a class.
6209/// libs is a space separated list of libraries.
6210
6211Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
6212{
6213 if (!cls || !*cls)
6214 return 0;
6215
6216 TString key = TString("Library.") + cls;
6217 // convert "::" to "@@", we used "@@" because TEnv
6218 // considers "::" a terminator
6219 key.ReplaceAll("::", "@@");
6220 // convert "-" to " ", since class names may have
6221 // blanks and TEnv considers a blank a terminator
6222 key.ReplaceAll(" ", "-");
6223
6225 if (!fMapfile) {
6226 fMapfile = new TEnv();
6227 fMapfile->IgnoreDuplicates(kTRUE);
6228
6230 fRootmapFiles->SetOwner();
6231
6232 InitRootmapFile(".rootmap");
6233 }
6234 //fMapfile->SetValue(key, libs);
6235 fMapfile->SetValue(cls, libs);
6236 return 1;
6237}
6238
6239////////////////////////////////////////////////////////////////////////////////
6240/// Demangle the name (from the typeinfo) and then request the class
6241/// via the usual name based interface (TClass::GetClass).
6242
6243TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
6244{
6245 int err = 0;
6246 char* demangled_name = TClassEdit::DemangleTypeIdName(typeinfo, err);
6247 if (err) return nullptr;
6248 TClass* theClass = TClass::GetClass(demangled_name, load, kTRUE);
6249 free(demangled_name);
6250 return theClass;
6251}
6252
6253////////////////////////////////////////////////////////////////////////////////
6254/// Load library containing the specified class. Returns 0 in case of error
6255/// and 1 in case if success.
6256
6257Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
6258{
6259 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6260
6261 int err = 0;
6262 char* demangled_name_c = TClassEdit::DemangleTypeIdName(typeinfo, err);
6263 if (err) {
6264 return 0;
6265 }
6266
6267 std::string demangled_name(demangled_name_c);
6268 free(demangled_name_c);
6269
6270 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
6271 // shortened name.
6273 splitname.ShortType(demangled_name, TClassEdit::kDropStlDefault | TClassEdit::kDropStd);
6274
6275 // No need to worry about typedef, they aren't any ... but there are
6276 // inlined namespaces ...
6277
6278 Int_t result = AutoLoad(demangled_name.c_str());
6279 if (result == 0) {
6280 demangled_name = TClassEdit::GetLong64_Name(demangled_name);
6281 result = AutoLoad(demangled_name.c_str(), knowDictNotLoaded);
6282 }
6283
6284 return result;
6285}
6286
6287////////////////////////////////////////////////////////////////////////////////
6288// Get the list of 'published'/'known' library for the class and load them.
6290{
6291 Int_t status = 0;
6292
6293 // lookup class to find list of dependent libraries
6294 TString deplibs = gCling->GetClassSharedLibs(cls);
6295 if (!deplibs.IsNull()) {
6296 TString delim(" ");
6297 TObjArray* tokens = deplibs.Tokenize(delim);
6298 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
6299 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
6300 if (gROOT->LoadClass(cls, deplib) == 0) {
6301 if (gDebug > 0) {
6302 gCling->Info("TCling::AutoLoad",
6303 "loaded dependent library %s for %s", deplib, cls);
6304 }
6305 }
6306 else {
6307 gCling->Error("TCling::AutoLoad",
6308 "failure loading dependent library %s for %s",
6309 deplib, cls);
6310 }
6311 }
6312 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6313 if (lib && lib[0]) {
6314 if (gROOT->LoadClass(cls, lib) == 0) {
6315 if (gDebug > 0) {
6316 gCling->Info("TCling::AutoLoad",
6317 "loaded library %s for %s", lib, cls);
6318 }
6319 status = 1;
6320 }
6321 else {
6322 gCling->Error("TCling::AutoLoad",
6323 "failure loading library %s for %s", lib, cls);
6324 }
6325 }
6326 delete tokens;
6327 }
6328
6329 return status;
6330}
6331
6332////////////////////////////////////////////////////////////////////////////////
6333// Iterate through the data member of the class (either through the TProtoClass
6334// or through Cling) and trigger, recursively, the loading the necessary libraries.
6335// \note `cls` is expected to be already normalized!
6336// \returns 1 on success.
6337Int_t TCling::DeepAutoLoadImpl(const char *cls, std::unordered_set<std::string> &visited,
6338 bool nameIsNormalized)
6339{
6340 // Try to insert; if insertion failed because the entry existed, DeepAutoLoadImpl()
6341 // has previously (within the same call to `AutoLoad()`) tried to load this class
6342 // and we are done, whether success or not, as it won't work better now than before,
6343 // because there is no additional information now compared to before.
6344 if (!visited.insert(std::string(cls)).second)
6345 return 1;
6346
6347 if (ShallowAutoLoadImpl(cls) == 0) {
6348 // If ShallowAutoLoadImpl() has an error, we have an error.
6349 return 0;
6350 }
6351
6352 // Now look through the TProtoClass to load the required library/dictionary
6353 if (TProtoClass *proto = nameIsNormalized ? TClassTable::GetProtoNorm(cls) : TClassTable::GetProto(cls)) {
6354 for (auto element : proto->GetData()) {
6355 if (element->IsBasic())
6356 continue;
6357 const char *subtypename = element->GetTypeName();
6358 if (!TClassTable::GetDictNorm(subtypename)) {
6359 // Failure to load a dictionary is not (quite) a failure load
6360 // the top-level library. If we return false here, then
6361 // we would end up in a situation where the library and thus
6362 // the dictionary is loaded for "cls" but the TClass is
6363 // not created and/or marked as unavailable (in case where
6364 // AutoLoad is called from TClass::GetClass).
6365 DeepAutoLoadImpl(subtypename, visited, true /*normalized*/);
6366 }
6367 }
6368 return 1;
6369 }
6370
6371 // We found no TProtoClass for cls.
6372 auto classinfo = gInterpreter->ClassInfo_Factory(cls);
6373 if (classinfo && gInterpreter->ClassInfo_IsValid(classinfo)
6374 && !(gInterpreter->ClassInfo_Property(classinfo) & kIsEnum))
6375 {
6376 DataMemberInfo_t *memberinfo = gInterpreter->DataMemberInfo_Factory(classinfo, TDictionary::EMemberSelection::kNoUsingDecls);
6377 while (gInterpreter->DataMemberInfo_Next(memberinfo)) {
6378 if (gInterpreter->DataMemberInfo_TypeProperty(memberinfo) & ::kIsFundamental)
6379 continue;
6380 auto membertypename = TClassEdit::GetLong64_Name(gInterpreter->TypeName(gInterpreter->DataMemberInfo_TypeTrueName(memberinfo)));
6381 if (!TClassTable::GetDictNorm(membertypename.c_str())) {
6382 // Failure to load a dictionary is not (quite) a failure load
6383 // the top-level library. See detailed comment in the TProtoClass
6384 // branch (above).
6385 (void)DeepAutoLoadImpl(membertypename.c_str(), visited, true /*normalized*/);
6386 }
6387 }
6388 gInterpreter->DataMemberInfo_Delete(memberinfo);
6389 }
6390 gInterpreter->ClassInfo_Delete(classinfo);
6391 return 1;
6392}
6393
6394////////////////////////////////////////////////////////////////////////////////
6395/// Load library containing the specified class. Returns 0 in case of error
6396/// and 1 in case if success.
6397
6398Int_t TCling::AutoLoad(const char *cls, Bool_t knowDictNotLoaded /* = kFALSE */)
6399{
6400 // Prevent update to IsClassAutoloading between our check and our actions.
6402
6403 // TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
6404 // rootcling (in *_rdict.pcm file generation) it is a no op.
6405 // FIXME: We should avoid calling autoload when we know we are not supposed
6406 // to and transform this check into an assert.
6408 // Never load any library from rootcling/genreflex.
6409 if (gDebug > 2) {
6410 Info("TCling::AutoLoad", "Explicitly disabled (the class name is %s)", cls);
6411 }
6412 return 0;
6413 }
6414
6415 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6416
6418
6419 if (!knowDictNotLoaded && gClassTable->GetDictNorm(cls)) {
6420 // The library is already loaded as the class's dictionary is known.
6421 // Return success.
6422 // Note: the name (cls) is expected to be normalized as it comes either
6423 // from a callbacks (that can/should calculate the normalized name from the
6424 // decl) or from TClass::GetClass (which does also calculate the normalized
6425 // name).
6426 return 1;
6427 }
6428
6429 if (gDebug > 2) {
6430 Info("TCling::AutoLoad",
6431 "Trying to autoload for %s", cls);
6432 }
6433
6434 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
6435 if (gDebug > 2) {
6436 Info("TCling::AutoLoad",
6437 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
6438 }
6439 return 0;
6440 }
6441 // Prevent the recursion when the library dictionary are loaded.
6442 SuspendAutoLoadingRAII autoLoadOff(this);
6443 // Try using externally provided callback first.
6444 if (fAutoLoadCallBack) {
6445 int success = (*(AutoLoadCallBack_t)fAutoLoadCallBack)(cls);
6446 if (success)
6447 return success;
6448 }
6449
6450 // During the 'Deep' part of the search we will call GetClassSharedLibsForModule
6451 // (when module are enabled) which might end up calling AutoParsing but
6452 // that should only be for the cases where the library has no generated pcm
6453 // and in that case a rootmap should be available.
6454 // This avoids a very costly operation (for generally no gain) but reduce the
6455 // quality of the search (i.e. bad in case of library with no pcm and no rootmap
6456 // file).
6457 TInterpreter::SuspendAutoParsing autoParseRaii(this);
6458 std::unordered_set<std::string> visited;
6459 return DeepAutoLoadImpl(cls, visited, false /*normalized*/);
6460}
6461
6462////////////////////////////////////////////////////////////////////////////////
6463/// Parse the payload or header.
6464
6465static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
6466 Bool_t header,
6467 cling::Interpreter *interpreter)
6468{
6469 std::string code = gNonInterpreterClassDef ;
6470 if (!header) {
6471 // This is the complete header file content and not the
6472 // name of a header.
6473 code += what;
6474
6475 } else {
6476 code += ("#include \"");
6477 code += what;
6478 code += "\"\n";
6479 }
6480 code += ("#ifdef __ROOTCLING__\n"
6481 "#undef __ROOTCLING__\n"
6482 + gInterpreterClassDef +
6483 "#endif");
6484
6485 cling::Interpreter::CompilationResult cr;
6486 {
6487 // scope within which diagnostics are de-activated
6488 // For now we disable diagnostics because we saw them already at
6489 // dictionary generation time. That won't be an issue with the PCMs.
6490
6491 Sema &SemaR = interpreter->getSema();
6492 ROOT::Internal::ParsingStateRAII parsingStateRAII(interpreter->getParser(), SemaR);
6493 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
6494
6495 #if defined(R__MUST_REVISIT)
6496 #if R__MUST_REVISIT(6,2)
6497 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
6498 #endif
6499 #endif
6500
6501 cr = interpreter->parseForModule(code);
6502 }
6503 return cr;
6504}
6505
6506////////////////////////////////////////////////////////////////////////////////
6507/// Helper routine for TCling::AutoParse implementing the actual call to the
6508/// parser and looping over template parameters (if
6509/// any) and when they don't have a registered header to autoparse,
6510/// recurse over their template parameters.
6511///
6512/// Returns the number of header parsed.
6513
6514UInt_t TCling::AutoParseImplRecurse(const char *cls, bool topLevel)
6515{
6516 // We assume the lock has already been taken.
6517 // R__LOCKGUARD(gInterpreterMutex);
6518
6519 Int_t nHheadersParsed = 0;
6520 unsigned long offset = 0;
6521 if (strncmp(cls, "const ", 6) == 0) {
6522 offset = 6;
6523 }
6524
6525 // Loop on the possible autoparse keys
6526 bool skipFirstEntry = false;
6527 std::vector<std::string> autoparseKeys;
6528 if (strchr(cls, '<')) {
6529 int nestedLoc = 0;
6530 TClassEdit::GetSplit(cls + offset, autoparseKeys, nestedLoc, TClassEdit::kDropTrailStar);
6531 // Check if we can skip the name of the template in the autoparses
6532 // Take all the scopes one by one. If all of them are in the AST, we do not
6533 // need to autoparse for that particular template.
6534 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
6535 // autoparseKeys[0] is empty when the input is not a template instance.
6536 // The case strchr(cls, '<') != 0 but still not a template instance can
6537 // happens 'just' for string (GetSplit replaces the template by the short name
6538 // and then use that for thew splitting)
6539 TString templateName(autoparseKeys[0]);
6540 auto tokens = templateName.Tokenize("::");
6541 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
6542 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
6543 if (TClassEdit::IsStdClass(cls + offset))
6544 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
6545 auto nTokens = tokens->GetEntriesFast();
6546 for (Int_t tk = 0; tk < nTokens; ++tk) {
6547 auto scopeObj = tokens->UncheckedAt(tk);
6548 auto scopeName = ((TObjString*) scopeObj)->String().Data();
6549 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
6550 // Check if we have multiple nodes in the AST with this name
6551 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
6552 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
6553 if (!previousScopeAsContext) break; // this is not a context
6554 }
6555 delete tokens;
6556 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
6557 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
6558 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
6559 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
6560 skipFirstEntry = templatedDecl->hasDefinition();
6561 }
6562 }
6563 }
6564
6565 }
6566 }
6567 if (topLevel) autoparseKeys.emplace_back(cls);
6568
6569 for (const auto & apKeyStr : autoparseKeys) {
6570 if (skipFirstEntry) {
6571 skipFirstEntry=false;
6572 continue;
6573 }
6574 if (apKeyStr.empty()) continue;
6575 const char *apKey = apKeyStr.c_str();
6576 std::size_t normNameHash(fStringHashFunction(apKey));
6577 // If the class was not looked up
6578 if (gDebug > 1) {
6579 Info("TCling::AutoParse",
6580 "Starting autoparse for %s\n", apKey);
6581 }
6582 if (fLookedUpClasses.insert(normNameHash).second) {
6583 auto const &iter = fClassesHeadersMap.find(normNameHash);
6584 if (iter != fClassesHeadersMap.end()) {
6585 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
6586 fTransactionHeadersMap.insert({T,normNameHash});
6587 auto const &hNamesPtrs = iter->second;
6588 if (gDebug > 1) {
6589 Info("TCling::AutoParse",
6590 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
6591 }
6592 for (auto & hName : hNamesPtrs) {
6593 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
6594 if (0 != fPayloads.count(normNameHash)) {
6595 float initRSSval=0.f, initVSIZEval=0.f;
6596 (void) initRSSval; // Avoid unused var warning
6597 (void) initVSIZEval;
6598 if (gDebug > 0) {
6599 Info("AutoParse",
6600 "Parsing full payload for %s", apKey);
6601 ProcInfo_t info;
6602 gSystem->GetProcInfo(&info);
6603 initRSSval = 1e-3*info.fMemResident;
6604 initVSIZEval = 1e-3*info.fMemVirtual;
6605 }
6606 auto cRes = ExecAutoParse(hName, kFALSE, GetInterpreterImpl());
6607 if (cRes != cling::Interpreter::kSuccess) {
6608 if (hName[0] == '\n')
6609 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
6610 } else {
6611 fParsedPayloadsAddresses.insert(hName);
6612 nHheadersParsed++;
6613 if (gDebug > 0){
6614 ProcInfo_t info;
6615 gSystem->GetProcInfo(&info);
6616 float endRSSval = 1e-3*info.fMemResident;
6617 float endVSIZEval = 1e-3*info.fMemVirtual;
6618 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6619 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6620 }
6621 }
6622 } else if (!IsLoaded(hName)) {
6623 if (gDebug > 0) {
6624 Info("AutoParse",
6625 "Parsing single header %s", hName);
6626 }
6627 auto cRes = ExecAutoParse(hName, kTRUE, GetInterpreterImpl());
6628 if (cRes != cling::Interpreter::kSuccess) {
6629 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
6630 } else {
6631 nHheadersParsed++;
6632 }
6633 }
6634 }
6635 }
6636 else {
6637 // There is no header registered for this class, if this a
6638 // template, it will be instantiated if/when it is requested
6639 // and if we do no load/parse its components we might end up
6640 // not using an eventual specialization.
6641 if (strchr(apKey, '<')) {
6642 nHheadersParsed += AutoParseImplRecurse(apKey, false);
6643 }
6644 }
6645 }
6646 }
6647
6648 if (nHheadersParsed) {
6649 // Register that we did autoparsing for this class.
6650 fAutoParseClasses.insert(cls);
6651 if (gDebug)
6652 Info("AutoParse", "Parsed %d headers for %s", nHheadersParsed, cls);
6653 }
6654 return nHheadersParsed;
6655
6656}
6657
6658////////////////////////////////////////////////////////////////////////////////
6659/// Parse the headers relative to the class
6660/// Returns 1 in case of success, 0 in case of failure
6661
6662Int_t TCling::AutoParse(const char *cls)
6663{
6664 if (llvm::StringRef(cls).contains("(lambda)"))
6665 return 0;
6666
6668 if (fClingCallbacks->IsAutoLoadingEnabled()) {
6669 return AutoLoad(cls);
6670 } else {
6671 return 0;
6672 }
6673 }
6674
6676
6677 if (gDebug > 1) {
6678 Info("TCling::AutoParse",
6679 "Trying to autoparse for %s", cls);
6680 }
6681
6682 // The catalogue of headers is in the dictionary
6683 if (fClingCallbacks->IsAutoLoadingEnabled()
6684 && !gClassTable->GetDictNorm(cls)) {
6685 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
6686 ROOT::Internal::ParsingStateRAII parsingStateRAII(fInterpreter->getParser(),
6687 fInterpreter->getSema());
6688 AutoLoad(cls, true /*knowDictNotLoaded*/);
6689 }
6690
6691 // Prevent the recursion when the library dictionary are loaded.
6692 SuspendAutoLoadingRAII autoLoadOff(this);
6693
6694 // No recursive header parsing on demand; we require headers to be standalone.
6695 SuspendAutoParsing autoParseRAII(this);
6696
6697 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
6698
6700
6701 return nHheadersParsed > 0 ? 1 : 0;
6702}
6703
6704// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6705// Try to solve the problem by AutoLoading. Return true when AutoLoading success, return
6706// false if not.
6707bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6708{
6709 StringRef errMsg(errmessage);
6710 if (errMsg.contains("undefined symbol: ")) {
6711 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6712 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6713 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6714 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6715 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6716 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6717 return true;
6718 } else {
6719 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6720 if ( ((TCling*)gCling)->LazyFunctionCreatorAutoload(errmessage))
6721 return true;
6722 }
6723
6724 return false;
6725}
6726
6727////////////////////////////////////////////////////////////////////////////////
6728/// Autoload a library based on a missing symbol.
6729
6730void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {
6731 std::string dlsym_mangled_name = ROOT::TMetaUtils::DemangleNameForDlsym(mangled_name);
6732
6733 // We have already loaded the library.
6734 if (void* Addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name))
6735 return Addr;
6736
6737 const cling::DynamicLibraryManager &DLM = *GetInterpreterImpl()->getDynamicLibraryManager();
6739
6740 auto LibLoader = [](const std::string& LibName) -> bool {
6741 if (gSystem->Load(LibName.c_str(), "", false) < 0) {
6742 ::Error("TCling__LazyFunctionCreatorAutoloadForModule",
6743 "Failed to load library %s", LibName.c_str());
6744 return false;
6745 }
6746 return true; //success.
6747 };
6748
6749 std::string libName = DLM.searchLibrariesForSymbol(mangled_name,
6750 /*searchSystem=*/ true);
6751
6752 assert(!llvm::StringRef(libName).starts_with("libNew") && "We must not resolve symbols from libNew!");
6753
6754 if (libName.empty())
6755 return nullptr;
6756
6757 if (!LibLoader(libName))
6758 return nullptr;
6759
6760 fAutoLoadedLibraries.insert(libName);
6761 return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name);
6762}
6763
6764////////////////////////////////////////////////////////////////////////////////
6765
6766Bool_t TCling::IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
6767{
6768 return fNSFromRootmaps.count(nsDecl) != 0;
6769}
6770
6771////////////////////////////////////////////////////////////////////////////////
6772/// Internal function. Actually do the update of the ClassInfo when seeing
6773// new TagDecl or NamespaceDecl.
6774void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6775{
6776
6778 if (cci) {
6779 // If we only had a forward declaration then update the
6780 // TClingClassInfo with the definition if we have it now.
6781 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6782 if (!oldDef || (def && def != oldDef)) {
6783 cl->ResetCaches();
6785 if (def) {
6786 if (cci->GetType()) {
6787 // It's a tag decl, not a namespace decl.
6788 cci->Init(*cci->GetType());
6790 } else {
6791 Error("RefreshClassInfo", "Should not need to update the classInfo a non type decl: %s", oldDef->getNameAsString().c_str());
6792 }
6793 }
6794 }
6795 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6796 cl->ResetCaches();
6797 if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
6798 // We need to use the Emulated Tuple but we should not trigger parsing
6799 // yet, so delay the creation of the ClassInfo
6800 delete ((TClingClassInfo *)cl->fClassInfo);
6801 cl->fClassInfo = nullptr;
6802 cl->fCanLoadClassInfo = true;
6804 if (cl->fState != TClass::kHasTClassInit) {
6806 }
6807 return;
6808 }
6809 // yes, this is almost a waste of time, but we do need to lookup
6810 // the 'type' corresponding to the TClass anyway in order to
6811 // preserve the opaque typedefs (Double32_t)
6812 if (!alias && def != nullptr)
6813 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), def);
6814 else
6815 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), cl->GetName());
6816 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6817 // We now need to update the state and bits.
6818 if (cl->fState != TClass::kHasTClassInit) {
6819 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6821 }
6822 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6823 } else {
6824 delete ((TClingClassInfo *)cl->fClassInfo);
6825 cl->fClassInfo = nullptr;
6826 }
6827 }
6828}
6829
6830////////////////////////////////////////////////////////////////////////////////
6831/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6832void TCling::UpdateClassInfoWithDecl(const NamedDecl* ND)
6833{
6834 const TagDecl *td = dyn_cast<TagDecl>(ND);
6835 const NamespaceDecl *ns = dyn_cast<NamespaceDecl>(ND);
6836 const NamedDecl *canon = nullptr;
6837
6838 std::string name;
6839 TagDecl* tdDef = nullptr;
6840 if (td) {
6841 canon = tdDef = td->getDefinition();
6842 // Let's pass the decl to the TClass only if it has a definition.
6843 if (!tdDef) return;
6844
6845 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6846 // Ignore incomplete definition.
6847 // Ignore declaration within a function.
6848 return;
6849 }
6850
6851 auto declName = tdDef->getNameAsString();
6852 // Check if we have registered the unqualified name into the list
6853 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6854 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6855 // the unqualified name is sufficient (and the fully qualified name might be
6856 // 'wrong' if there is difference in spelling in the template paramters (for example)
6857 if (!TClass::HasNoInfoOrEmuOrFwdDeclaredDecl(declName.c_str())){
6858 // 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() );
6859 return;
6860 }
6861
6862 clang::QualType type(tdDef->getTypeForDecl(), 0);
6864 } else if (ns) {
6865 canon = ns->getCanonicalDecl();
6866 name = ND->getQualifiedNameAsString();
6867 } else {
6868 name = ND->getQualifiedNameAsString();
6869 }
6870
6871 // Supposedly we are being called while something is being
6872 // loaded ... let's now tell the autoloader to do the work
6873 // yet another time.
6874 SuspendAutoLoadingRAII autoLoadOff(this);
6875 // FIXME: There can be more than one TClass for a single decl.
6876 // for example vector<double> and vector<Double32_t>
6877 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6878 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6879 RefreshClassInfo(cl, canon, false);
6880 }
6881 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6882 // and update them too:
6883 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6884 // RefreshClassInfo(cl, tdDef, true);
6885}
6886
6887////////////////////////////////////////////////////////////////////////////////
6888/// No op: see TClingCallbacks
6889
6890void TCling::UpdateClassInfo(char* item, Long_t tagnum)
6891{
6892}
6893
6894//______________________________________________________________________________
6895//FIXME: Factor out that function in TClass, because TClass does it already twice
6896void TCling::UpdateClassInfoWork(const char* item)
6897{
6898 // This is a no-op as part of the API.
6899 // TCling uses UpdateClassInfoWithDecl() instead.
6900}
6901
6902////////////////////////////////////////////////////////////////////////////////
6903/// Update all canvases at end the terminal input command.
6904
6906{
6907 TIter next(gROOT->GetListOfCanvases());
6908 TVirtualPad* canvas;
6909 while ((canvas = (TVirtualPad*)next())) {
6910 canvas->Update();
6911 }
6912}
6913
6914////////////////////////////////////////////////////////////////////////////////
6915
6916void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6917 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6918
6919 // If the transaction does not contain anything we can return earlier.
6920 if (!HandleNewTransaction(T)) return;
6921
6922 bool isTUTransaction = false;
6923 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
6924 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
6925 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
6926 // The is the first transaction, we have to expose to meta
6927 // what's already in the AST.
6928 isTUTransaction = true;
6929 }
6930 }
6931
6932 std::set<const void*> TransactionDeclSet;
6933 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
6934 const clang::Decl* WrapperFD = T.getWrapperFD();
6935 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6936 I != E; ++I) {
6937 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
6938 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
6939 continue;
6940
6941 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6942 DE = I->m_DGR.end(); DI != DE; ++DI) {
6943 if (*DI == WrapperFD)
6944 continue;
6945 TransactionDeclSet.insert(*DI);
6946 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
6947 }
6948 }
6949 }
6950
6951 // The above might trigger more decls to be deserialized.
6952 // Thus the iteration over the deserialized decls must be last.
6953 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
6954 E = T.deserialized_decls_end(); I != E; ++I) {
6955 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6956 DE = I->m_DGR.end(); DI != DE; ++DI)
6957 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
6958 //FIXME: HandleNewDecl should take DeclGroupRef
6959 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
6960 modifiedTClasses);
6961 }
6962 }
6963
6964
6965 // When fully building the reflection info in TClass, a deserialization
6966 // could be triggered, which may result in request for building the
6967 // reflection info for the same TClass. This in turn will clear the caches
6968 // for the TClass in-flight and cause null ptr derefs.
6969 // FIXME: This is a quick fix, solving most of the issues. The actual
6970 // question is: Shouldn't TClass provide a lock mechanism on update or lock
6971 // itself until the update is done.
6972 //
6973 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
6974 std::vector<TClass*>::iterator it;
6975 it = set_difference(modifiedTClasses.begin(), modifiedTClasses.end(),
6976 ((TCling*)gCling)->GetModTClasses().begin(),
6977 ((TCling*)gCling)->GetModTClasses().end(),
6978 modifiedTClassesDiff.begin());
6979 modifiedTClassesDiff.resize(it - modifiedTClassesDiff.begin());
6980
6981 // Lock the TClass for updates
6982 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
6983 modifiedTClassesDiff.end());
6984 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
6985 E = modifiedTClassesDiff.end(); I != E; ++I) {
6986 // Make sure the TClass has not been deleted.
6987 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
6988 continue;
6989 }
6990 // Could trigger deserialization of decls.
6991 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
6992 // Unlock the TClass for updates
6993 ((TCling*)gCling)->GetModTClasses().erase(*I);
6994
6995 }
6996}
6997
6998///\brief Invalidate stored TCling state for declarations included in transaction `T'.
6999///
7000void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
7001{
7003
7004 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
7005 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
7006 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
7007 (TListOfEnums *)gROOT->GetListOfEnums());
7008
7009 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
7010 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
7011 I != E; ++I) {
7012 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
7013 continue;
7014 if (I->m_Call == cling::Transaction::kCCINone) {
7015 UpdateListsOnUnloaded(*(*iNested));
7016 ++iNested;
7017 continue;
7018 }
7019
7020 for (auto &D : I->m_DGR)
7021 InvalidateCachedDecl(Lists, D);
7022 }
7023}
7024
7025///\brief Invalidate cached TCling information for the given global declaration.
7026///
7027void TCling::InvalidateGlobal(const Decl *D) {
7028 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
7029 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
7030 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
7031 (TListOfEnums *)gROOT->GetListOfEnums());
7032 InvalidateCachedDecl(Lists, D);
7033}
7034
7035///\brief Invalidate cached TCling information for the given declaration, and
7036/// removed it from the appropriate object list.
7037///\param[in] Lists - std::tuple<TListOfDataMembers&, TListOfFunctions&,
7038/// TListOfFunctionTemplates&, TListOfEnums&>
7039/// of pointers to the (global/class) object lists.
7040///\param[in] D - Decl to discard.
7041///
7045 TListOfEnums*> &Lists, const Decl *D) {
7046 if (D->isFromASTFile()) // `D' came from the PCH; ignore
7047 return;
7048
7049 TListOfDataMembers &LODM = *(std::get<0>(Lists));
7050 TListOfFunctions &LOF = *(std::get<1>(Lists));
7051 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
7052 TListOfEnums &LOE = *(std::get<3>(Lists));
7053
7054 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D)) {
7055 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
7056 if (LODM.GetClass())
7057 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
7058 else
7059 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
7060 } else if (isa<FunctionDecl>(D)) {
7062 } else if (isa<FunctionTemplateDecl>(D)) {
7064 } else if (isa<EnumDecl>(D)) {
7065 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
7066 if (!E)
7067 return;
7068
7069 // Try to invalidate enumerators (for unscoped enumerations).
7070 for (TIter I = E->GetConstants(); auto EC = (TEnumConstant *)I(); )
7072 (TEnumConstant *)LODM.FindObject(EC->GetName()));
7073
7075 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
7076 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->isCompleteDefinition())
7077 return;
7078
7079 std::vector<TClass *> Classes;
7080 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
7081 return;
7082 for (auto &C : Classes) {
7083 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
7084 (TListOfFunctions *)C->GetListOfMethods(),
7085 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
7086 (TListOfEnums *)C->GetListOfEnums());
7087 for (auto &I : cast<DeclContext>(D)->decls())
7088 InvalidateCachedDecl(Lists, I);
7089
7090 // For NamespaceDecl (redeclarable), only invalidate this redecl.
7091 if (D->getKind() != Decl::Namespace || cast<NamespaceDecl>(D)->isFirstDecl())
7092 C->ResetClassInfo();
7093 }
7094 }
7095}
7096
7097////////////////////////////////////////////////////////////////////////////////
7098// If an autoparse was done during a transaction and that it is rolled back,
7099// we need to make sure the next request for the same autoparse will be
7100// honored.
7101void TCling::TransactionRollback(const cling::Transaction &T) {
7102 auto const &triter = fTransactionHeadersMap.find(&T);
7103 if (triter != fTransactionHeadersMap.end()) {
7104 std::size_t normNameHash = triter->second;
7105
7106 fLookedUpClasses.erase(normNameHash);
7107
7108 auto const &iter = fClassesHeadersMap.find(normNameHash);
7109 if (iter != fClassesHeadersMap.end()) {
7110 auto const &hNamesPtrs = iter->second;
7111 for (auto &hName : hNamesPtrs) {
7112 if (gDebug > 0) {
7113 Info("TransactionRollback",
7114 "Restoring ability to autoaparse: %s", hName);
7115 }
7116 fParsedPayloadsAddresses.erase(hName);
7117 }
7118 }
7119 }
7120}
7121
7122////////////////////////////////////////////////////////////////////////////////
7123
7124void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
7125// R__LOCKGUARD_CLING(gInterpreterMutex);
7126// UpdateListOfLoadedSharedLibraries();
7127}
7128
7129////////////////////////////////////////////////////////////////////////////////
7130
7131void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
7132 fPrevLoadedDynLibInfo = nullptr;
7133 fSharedLibs = "";
7134}
7135
7136////////////////////////////////////////////////////////////////////////////////
7137/// Return the list of shared libraries loaded into the process.
7138
7145
7146static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH, bool skipCore)
7147{
7148 if (!cls || !*cls)
7149 return {};
7150
7151 using namespace clang;
7152 if (const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
7153 /*type*/ nullptr, /*instantiate*/ false)) {
7154 if (!D->isFromASTFile()) {
7155 if (gDebug > 5)
7156 Warning("GetClassSharedLibsForModule", "Decl found for %s is not part of a module", cls);
7157 return {};
7158 }
7159 class ModuleCollector : public ConstDeclVisitor<ModuleCollector> {
7160 llvm::DenseSet<Module *> &m_TopLevelModules;
7161
7162 public:
7163 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
7164 void Collect(const Decl *D) { Visit(D); }
7165
7166 void VisitDecl(const Decl *D)
7167 {
7168 // FIXME: Such case is described ROOT-7765 where
7169 // ROOT_GENERATE_DICTIONARY does not contain the list of headers.
7170 // They are specified as #includes in the LinkDef file. This leads to
7171 // generation of incomplete modulemap files and this logic fails to
7172 // compute the corresponding module of D.
7173 // FIXME: If we want to support such a case, we should not rely on
7174 // the contents of the modulemap but mangle D and look it up in the
7175 // .so files.
7176 if (!D->hasOwningModule())
7177 return;
7178 if (Module *M = D->getOwningModule()->getTopLevelModule())
7179 m_TopLevelModules.insert(M);
7180 }
7181
7182 void VisitTemplateArgument(const TemplateArgument &TA)
7183 {
7184 switch (TA.getKind()) {
7185 case TemplateArgument::Null:
7186 case TemplateArgument::Integral:
7187 case TemplateArgument::Pack:
7188 case TemplateArgument::NullPtr:
7189 case TemplateArgument::StructuralValue:
7190 case TemplateArgument::Expression:
7191 case TemplateArgument::Template:
7192 case TemplateArgument::TemplateExpansion: return;
7193 case TemplateArgument::Type:
7194 if (const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
7195 return Visit(TagTy->getDecl());
7196 return;
7197 case TemplateArgument::Declaration: return Visit(TA.getAsDecl());
7198 }
7199 llvm_unreachable("Invalid TemplateArgument::Kind!");
7200 }
7201
7202 void VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *CTSD)
7203 {
7204 if (CTSD->getOwningModule())
7205 VisitDecl(CTSD);
7206 else
7207 VisitDecl(CTSD->getSpecializedTemplate());
7208 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
7209 for (const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
7210 VisitTemplateArgument(*Arg);
7211 }
7212 }
7213 };
7214
7215 llvm::DenseSet<Module *> TopLevelModules;
7216 ModuleCollector m(TopLevelModules);
7217 m.Collect(D);
7218 std::string result;
7219 for (auto M : TopLevelModules) {
7220 // ROOT-unaware modules (i.e. not processed by rootcling) do not have a
7221 // link declaration.
7222 if (!M->LinkLibraries.size())
7223 continue;
7224 // We have preloaded the Core module thus libCore.so
7225 if (M->Name == "Core" && skipCore)
7226 continue;
7227 assert(M->LinkLibraries.size() == 1);
7228 if (!result.empty())
7229 result += ' ';
7230 result += M->LinkLibraries[0].Library;
7231 }
7232 return result;
7233 }
7234 return {};
7235}
7236
7237////////////////////////////////////////////////////////////////////////////////
7238/// Get the list of shared libraries containing the code for class cls.
7239/// The first library in the list is the one containing the class, the
7240/// others are the libraries the first one depends on. Returns 0
7241/// in case the library is not found.
7242/// \param cls the name of the class
7243/// \param skipCore if true (default), remove "Core" from the returned list
7244
7245const char* TCling::GetClassSharedLibs(const char* cls, bool skipCore)
7246{
7247 if (fCxxModulesEnabled) {
7248 // Lock the interpreter mutex before interacting with cling.
7249 // TODO: Can we move this further deep? In principle the lock should be in
7250 // GetClassSharedLibsForModule, but it might be needed also for
7251 // getLookupHelper?
7253 llvm::StringRef className = cls;
7254 // If we get a class name containing lambda, we cannot parse it and we
7255 // can exit early.
7256 // FIXME: This works around a bug when we are instantiating a template
7257 // make_unique and the substitution fails. Seen in most of the dataframe
7258 // tests.
7259 if (className.contains("(lambda)"))
7260 return nullptr;
7261 // Limit the recursion which can be induced by GetClassSharedLibsForModule.
7262 SuspendAutoLoadingRAII AutoLoadingDisabled(this);
7263 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
7264 std::string libs = GetClassSharedLibsForModule(cls, LH, skipCore);
7265 if (!libs.empty()) {
7266 fAutoLoadLibStorage.push_back(libs);
7267 return fAutoLoadLibStorage.back().c_str();
7268 }
7269 }
7270
7271 if (!cls || !*cls) {
7272 return nullptr;
7273 }
7274 // lookup class to find list of libraries
7275 if (fMapfile) {
7276 TEnvRec* libs_record = nullptr;
7277 libs_record = fMapfile->Lookup(cls);
7278 if (libs_record) {
7279 const char* libs = libs_record->GetValue();
7280 return (*libs) ? libs : nullptr;
7281 }
7282 else {
7283 // Try the old format...
7284 TString c = TString("Library.") + cls;
7285 // convert "::" to "@@", we used "@@" because TEnv
7286 // considers "::" a terminator
7287 c.ReplaceAll("::", "@@");
7288 // convert "-" to " ", since class names may have
7289 // blanks and TEnv considers a blank a terminator
7290 c.ReplaceAll(" ", "-");
7291 // Use TEnv::Lookup here as the rootmap file must start with Library.
7292 // and do not support using any stars (so we do not need to waste time
7293 // with the search made by TEnv::GetValue).
7294 TEnvRec* libs_record = nullptr;
7295 libs_record = fMapfile->Lookup(c);
7296 if (libs_record) {
7297 const char* libs = libs_record->GetValue();
7298 return (*libs) ? libs : nullptr;
7299 }
7300 }
7301 }
7302 return nullptr;
7303}
7304
7305/// This interface returns a list of dependent libraries in the form:
7306/// lib libA.so libB.so libC.so. The first library is the library we are
7307/// searching dependencies for.
7308/// Note: In order to speed up the search, we display the dependencies of the
7309/// libraries which are not yet loaded. For instance, if libB.so was already
7310/// loaded the list would contain: lib libA.so libC.so.
7311static std::string GetSharedLibImmediateDepsSlow(std::string lib,
7312 cling::Interpreter *interp,
7313 bool skipLoadedLibs = true)
7314{
7315 TString LibFullPath(lib);
7316 if (!llvm::sys::path::is_absolute(lib)) {
7317 if (!gSystem->FindDynamicLibrary(LibFullPath, /*quiet=*/true)) {
7318 Error("TCling__GetSharedLibImmediateDepsSlow", "Cannot find library '%s'", lib.c_str());
7319 return "";
7320 }
7321 } else {
7322 assert(llvm::sys::fs::exists(lib) && "Must exist!");
7323 lib = llvm::sys::path::filename(lib).str();
7324 }
7325
7326 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
7327 if (!ObjF) {
7328 Warning("TCling__GetSharedLibImmediateDepsSlow", "Failed to read object file %s", lib.c_str());
7329 return "";
7330 }
7331
7332 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7333
7334 std::set<string> DedupSet;
7335 std::string Result = lib + ' ';
7336 for (const auto &S : BinObjFile->symbols()) {
7337 uint32_t Flags = llvm::cantFail(S.getFlags());
7338 // Skip defined symbols: we have them.
7339 if (!(Flags & llvm::object::SymbolRef::SF_Undefined))
7340 continue;
7341 // Skip undefined weak symbols: if we don't have them we won't need them.
7342 // `__gmon_start__` being a typical example.
7343 if (Flags & llvm::object::SymbolRef::SF_Weak)
7344 continue;
7345 llvm::Expected<StringRef> SymNameErr = S.getName();
7346 if (!SymNameErr) {
7347 Warning("GetSharedLibDepsForModule", "Failed to read symbol");
7348 continue;
7349 }
7350 llvm::StringRef SymName = SymNameErr.get();
7351 if (SymName.empty())
7352 continue;
7353
7354 if (BinObjFile->isELF()) {
7355 // Skip the symbols which are part of the C/C++ runtime and have a
7356 // fixed library version. See binutils ld VERSION. Those reside in
7357 // 'system' libraries, which we avoid in FindLibraryForSymbol.
7358 if (SymName.contains("@GLIBCXX") || SymName.contains("@CXXABI") ||
7359 SymName.contains("@GLIBC") || SymName.contains("@GCC"))
7360 continue;
7361
7362 // Those are 'weak undefined' symbols produced by gcc. We can
7363 // ignore them.
7364 // FIXME: It is unclear whether we can ignore all weak undefined
7365 // symbols:
7366 // http://lists.llvm.org/pipermail/llvm-dev/2017-October/118177.html
7367 static constexpr llvm::StringRef RegisterClasses("_Jv_RegisterClasses");
7368 static constexpr llvm::StringRef RegisterCloneTable("_ITM_registerTMCloneTable");
7369 static constexpr llvm::StringRef DeregisterCloneTable("_ITM_deregisterTMCloneTable");
7370 if (SymName == RegisterClasses ||
7371 SymName == RegisterCloneTable ||
7372 SymName == DeregisterCloneTable)
7373 continue;
7374 }
7375
7376 // If we can find the address of the symbol, we have loaded it. Skip.
7377 if (skipLoadedLibs) {
7378 std::string SymNameForDlsym = ROOT::TMetaUtils::DemangleNameForDlsym(SymName.str());
7379 if (llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymNameForDlsym))
7380 continue;
7381 }
7382
7384 std::string found = interp->getDynamicLibraryManager()->searchLibrariesForSymbol(SymName, /*searchSystem*/false);
7385 // The expected output is just filename without the full path, which
7386 // is not very accurate, because our Dyld implementation might find
7387 // a match in location a/b/c.so and if we return just c.so ROOT might
7388 // resolve it to y/z/c.so and there we might not be ABI compatible.
7389 // FIXME: Teach the users of GetSharedLibDeps to work with full paths.
7390 if (!found.empty()) {
7391 std::string cand = llvm::sys::path::filename(found).str();
7392 if (!DedupSet.insert(cand).second)
7393 continue;
7394
7395 Result += cand + ' ';
7396 }
7397 }
7398
7399 return Result;
7400}
7401
7402static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
7403{
7404 // Check if we have parsed a rootmap file.
7405 llvm::SmallString<256> rootmapName;
7406 if (!lib.starts_with("lib"))
7407 rootmapName.append("lib");
7408
7409 rootmapName.append(llvm::sys::path::filename(lib));
7410 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7411
7412 if (gCling->GetRootMapFiles()->FindObject(rootmapName.c_str()))
7413 return true;
7414
7415 // Perform a last resort by dropping the lib prefix.
7416 llvm::StringRef rootmapNameNoLib = rootmapName.str();
7417 if (rootmapNameNoLib.consume_front("lib"))
7418 return gCling->GetRootMapFiles()->FindObject(rootmapNameNoLib.data());
7419
7420 return false;
7421}
7422
7423static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
7424{
7425 if (gCling->HasPCMForLibrary(lib.data()))
7426 return true;
7427
7428 return hasParsedRootmapForLibrary(lib);
7429}
7430
7431////////////////////////////////////////////////////////////////////////////////
7432/// Get the list a libraries on which the specified lib depends. The
7433/// returned string contains as first element the lib itself.
7434/// Returns 0 in case the lib does not exist or does not have
7435/// any dependencies. If useDyld is true, we iterate through all available
7436/// libraries and try to construct the dependency chain by resolving each
7437/// symbol.
7438
7439const char* TCling::GetSharedLibDeps(const char* lib, bool useDyld/* = false*/)
7440{
7441 if (llvm::sys::path::is_absolute(lib) && !llvm::sys::fs::exists(lib))
7442 return nullptr;
7443
7444 if (!hasParsedRootmapForLibrary(lib)) {
7445 llvm::SmallString<512> rootmapName(lib);
7446 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7447 if (llvm::sys::fs::exists(rootmapName)) {
7448 if (gDebug > 0)
7449 Info("Load", "loading %s", rootmapName.c_str());
7450 gInterpreter->LoadLibraryMap(rootmapName.c_str());
7451 }
7452 }
7453
7454 if (hasPrecomputedLibraryDeps(lib) && useDyld) {
7455 if (gDebug > 0)
7456 Warning("TCling::GetSharedLibDeps", "Precomputed dependencies available but scanning '%s'", lib);
7457 }
7458
7459 if (useDyld) {
7460 std::string libs = GetSharedLibImmediateDepsSlow(lib, GetInterpreterImpl());
7461 if (!libs.empty()) {
7462 fAutoLoadLibStorage.push_back(libs);
7463 return fAutoLoadLibStorage.back().c_str();
7464 }
7465 }
7466
7467 if (!fMapfile || !lib || !lib[0]) {
7468 return nullptr;
7469 }
7470 TString libname(lib);
7471 Ssiz_t idx = libname.Last('.');
7472 if (idx != kNPOS) {
7473 libname.Remove(idx);
7474 }
7475 TEnvRec* rec;
7476 TIter next(fMapfile->GetTable());
7477 size_t len = libname.Length();
7478 while ((rec = (TEnvRec*) next())) {
7479 const char* libs = rec->GetValue();
7480 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7481 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
7482 return libs;
7483 }
7484 }
7485 return nullptr;
7486}
7487
7488////////////////////////////////////////////////////////////////////////////////
7489/// If error messages are disabled, the interpreter should suppress its
7490/// failures and warning messages from stdout.
7491
7493{
7494#if defined(R__MUST_REVISIT)
7495#if R__MUST_REVISIT(6,2)
7496 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
7497#endif
7498#endif
7499 return kTRUE;
7500}
7501
7502////////////////////////////////////////////////////////////////////////////////
7503/// If error messages are disabled, the interpreter should suppress its
7504/// failures and warning messages from stdout. Return the previous state.
7505
7507{
7508#if defined(R__MUST_REVISIT)
7509#if R__MUST_REVISIT(6,2)
7510 Warning("SetErrorMessages", "Interface not available yet.");
7511#endif
7512#endif
7514}
7515
7516////////////////////////////////////////////////////////////////////////////////
7517/// Refresh the list of include paths known to the interpreter and return it
7518/// with -I prepended.
7519
7521{
7523
7524 fIncludePath = "";
7525
7526 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7527 //false - no system header, true - with flags.
7528 fInterpreter->GetIncludePaths(includePaths, false, true);
7529 if (const size_t nPaths = includePaths.size()) {
7530 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
7531
7532 for (size_t i = 0; i < nPaths; i += 2) {
7533 if (i)
7534 fIncludePath.Append(' ');
7535 fIncludePath.Append(includePaths[i].c_str());
7536
7537 if (includePaths[i] != "-I")
7538 fIncludePath.Append(' ');
7539 fIncludePath.Append('"');
7540 fIncludePath.Append(includePaths[i + 1], includePaths[i + 1].length());
7541 fIncludePath.Append('"');
7542 }
7543 }
7544
7545 return fIncludePath;
7546}
7547
7548////////////////////////////////////////////////////////////////////////////////
7549/// Return the directory containing CINT's stl cintdlls.
7550
7551const char* TCling::GetSTLIncludePath() const
7552{
7553 return "";
7554}
7555
7556//______________________________________________________________________________
7557// M I S C
7558//______________________________________________________________________________
7559
7560int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
7561{
7562 // Interface to cling function
7563 return 0;
7564}
7565
7566////////////////////////////////////////////////////////////////////////////////
7567/// Interface to cling function
7568
7569int TCling::DisplayIncludePath(FILE *fout) const
7570{
7571 assert(fout != nullptr && "DisplayIncludePath, 'fout' parameter is null");
7572
7573 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7574 //false - no system header, true - with flags.
7575 fInterpreter->GetIncludePaths(includePaths, false, true);
7576 if (const size_t nPaths = includePaths.size()) {
7577 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
7578
7579 std::string allIncludes("include path:");
7580 for (size_t i = 0; i < nPaths; i += 2) {
7581 allIncludes += ' ';
7582 allIncludes += includePaths[i];
7583
7584 if (includePaths[i] != "-I")
7585 allIncludes += ' ';
7586 allIncludes += includePaths[i + 1];
7587 }
7588
7589 fprintf(fout, "%s\n", allIncludes.c_str());
7590 }
7591
7592 return 0;
7593}
7594
7595////////////////////////////////////////////////////////////////////////////////
7596/// Interface to cling function
7597
7598void* TCling::FindSym(const char* entry) const
7599{
7601 return fInterpreter->getAddressOfGlobal(entry);
7602}
7603
7604////////////////////////////////////////////////////////////////////////////////
7605/// Let the interpreter issue a generic error, and set its error state.
7606
7607void TCling::GenericError(const char* error) const
7608{
7609#if defined(R__MUST_REVISIT)
7610#if R__MUST_REVISIT(6,2)
7611 Warning("GenericError","Interface not available yet.");
7612#endif
7613#endif
7614}
7615
7616////////////////////////////////////////////////////////////////////////////////
7617/// This routines used to return the address of the internal wrapper
7618/// function (of the interpreter) that was used to call *all* the
7619/// interpreted functions that were bytecode compiled (no longer
7620/// interpreted line by line). In Cling, there is no such
7621/// wrapper function.
7622/// In practice this routines was use to decipher whether the
7623/// pointer returns by InterfaceMethod could be used to uniquely
7624/// represent the function. In Cling if the function is in a
7625/// useable state (its compiled version is available), this is
7626/// always the case.
7627/// See TClass::GetMethod.
7628
7630{
7631 return 0;
7632}
7633
7634////////////////////////////////////////////////////////////////////////////////
7635/// Interface to cling function
7636
7638{
7639#if defined(R__MUST_REVISIT)
7640#if R__MUST_REVISIT(6,2)
7641 Warning("GetSecurityError", "Interface not available yet.");
7642#endif
7643#endif
7644 return 0;
7645}
7646
7647////////////////////////////////////////////////////////////////////////////////
7648/// Load a source file or library called path into the interpreter.
7649
7650int TCling::LoadFile(const char* path) const
7651{
7652 // Modifying the interpreter state needs locking.
7654 cling::Interpreter::CompilationResult compRes;
7655 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(".L %s", path), compRes, /*cling::Value*/nullptr);
7656 return compRes == cling::Interpreter::kFailure;
7657}
7658
7659////////////////////////////////////////////////////////////////////////////////
7660/// Load the declarations from text into the interpreter.
7661/// Note that this cannot be (top level) statements; text must contain
7662/// top level declarations.
7663/// Returns true on success, false on failure.
7664
7665Bool_t TCling::LoadText(const char* text) const
7666{
7667 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7668}
7669
7670////////////////////////////////////////////////////////////////////////////////
7671/// Interface to cling function
7672
7673const char* TCling::MapCppName(const char* name) const
7674{
7675 TTHREAD_TLS_DECL(std::string,buffer);
7677 return buffer.c_str(); // NOLINT
7678}
7679
7680////////////////////////////////////////////////////////////////////////////////
7681/// [Place holder for Mutex Lock]
7682/// Provide the interpreter with a way to
7683/// acquire a lock used to protect critical section
7684/// of its code (non-thread safe parts).
7685
7686void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7687{
7688 // nothing to do for now.
7689}
7690
7691////////////////////////////////////////////////////////////////////////////////
7692/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7693/// release a lock used to protect critical section
7694/// of its code (non-thread safe parts).
7695
7696void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7697{
7698 // nothing to do for now.
7699}
7700
7701////////////////////////////////////////////////////////////////////////////////
7702/// Returns if class AutoLoading is currently enabled.
7703
7705{
7706 if (IsFromRootCling())
7707 return false;
7708 if (!fClingCallbacks)
7709 return false;
7710 return fClingCallbacks->IsAutoLoadingEnabled();
7711}
7712
7713////////////////////////////////////////////////////////////////////////////////
7714/// Enable/Disable the AutoLoading of libraries.
7715/// Returns the old value, i.e whether it was enabled or not.
7716
7717int TCling::SetClassAutoLoading(int autoload) const
7718{
7719 // If no state change is required, exit early.
7720 // FIXME: In future we probably want to complain if we made a request which
7721 // was with the same state as before in order to catch programming errors.
7722 if ((bool) autoload == IsClassAutoLoadingEnabled())
7723 return autoload;
7724
7725 assert(fClingCallbacks && "We must have callbacks!");
7726 bool oldVal = fClingCallbacks->IsAutoLoadingEnabled();
7727 fClingCallbacks->SetAutoLoadingEnabled(autoload);
7728 return oldVal;
7729}
7730
7731////////////////////////////////////////////////////////////////////////////////
7732/// Enable/Disable the Autoparsing of headers.
7733/// Returns the old value, i.e whether it was enabled or not.
7734
7736{
7737 bool oldVal = fHeaderParsingOnDemand;
7738 fHeaderParsingOnDemand = autoparse;
7739 return oldVal;
7740}
7741
7742////////////////////////////////////////////////////////////////////////////////
7743/// Suspend the Autoparsing of headers.
7744/// Returns the old value, i.e whether it was suspended or not.
7745
7752
7753////////////////////////////////////////////////////////////////////////////////
7754/// Set a callback to receive error messages.
7755
7756void TCling::SetErrmsgcallback(void* p) const
7757{
7758#if defined(R__MUST_REVISIT)
7759#if R__MUST_REVISIT(6,2)
7760 Warning("SetErrmsgcallback", "Interface not available yet.");
7761#endif
7762#endif
7763}
7764
7766{
7767 if (enable) {
7768 auto consumer = new TClingDelegateDiagnosticPrinter(
7769 &fInterpreter->getDiagnostics().getDiagnosticOptions(),
7770 fInterpreter->getCI()->getLangOpts(),
7771 [] (clang::DiagnosticsEngine::Level Level, const std::string &Info) {
7772 if (Level == clang::DiagnosticsEngine::Warning) {
7773 ::Warning("cling", "%s", Info.c_str());
7774 } else if (Level == clang::DiagnosticsEngine::Error
7775 || Level == clang::DiagnosticsEngine::Fatal) {
7776 ::Error("cling", "%s", Info.c_str());
7777 } else {
7778 ::Info("cling", "%s", Info.c_str());
7779 }
7780 });
7781 fInterpreter->replaceDiagnosticConsumer(consumer, /*Own=*/true);
7782 } else {
7783 fInterpreter->replaceDiagnosticConsumer(nullptr);
7784 }
7785}
7786
7787
7788////////////////////////////////////////////////////////////////////////////////
7789/// Create / close a scope for temporaries. No-op for cling; use
7790/// cling::Value instead.
7791
7792void TCling::SetTempLevel(int val) const
7793{
7794}
7795
7796////////////////////////////////////////////////////////////////////////////////
7797
7798int TCling::UnloadFile(const char* path) const
7799{
7800 // Modifying the interpreter state needs locking.
7802 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7803 std::string canonical = DLM->lookupLibrary(path);
7804 if (canonical.empty()) {
7805 canonical = path;
7806 }
7807 // Unload a shared library or a source file.
7808 cling::Interpreter::CompilationResult compRes;
7809 HandleInterpreterException(GetMetaProcessorImpl(), Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/nullptr);
7810 return compRes == cling::Interpreter::kFailure;
7811}
7812
7813std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7814 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7815}
7816
7817////////////////////////////////////////////////////////////////////////////////
7818/// The call to Cling's tab complition.
7819
7820void TCling::CodeComplete(const std::string& line, size_t& cursor,
7821 std::vector<std::string>& completions)
7822{
7823 fInterpreter->codeComplete(line, cursor, completions);
7824}
7825
7826////////////////////////////////////////////////////////////////////////////////
7827/// Get the interpreter value corresponding to the statement.
7829{
7831
7832 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7833 auto compRes = fInterpreter->evaluate(code, *V);
7834 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7835}
7836
7837////////////////////////////////////////////////////////////////////////////////
7838
7840{
7841 using namespace cling;
7842 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7844}
7845
7846////////////////////////////////////////////////////////////////////////////////
7847/// Register value as a temporary, extending its lifetime to that of the
7848/// interpreter. This is needed for TCling's compatibility interfaces
7849/// returning long - the address of the temporary objects.
7850/// As such, "simple" types don't need to be stored; they are returned by
7851/// value; only pointers / references / objects need to be stored.
7852
7853void TCling::RegisterTemporary(const cling::Value& value)
7854{
7855 if (value.isValid() && value.needsManagedAllocation()) {
7857 fTemporaries->push_back(value);
7858 }
7859}
7860
7861////////////////////////////////////////////////////////////////////////////////
7862/// If the interpreter encounters Name, check whether that is an object ROOT
7863/// could retrieve. To not re-read objects from disk, cache the name/object
7864/// pair for a given LookupCtx.
7865
7866TObject* TCling::GetObjectAddress(const char *Name, void *&LookupCtx)
7867{
7868 // The call to FindSpecialObject might induces any kind of use
7869 // of the interpreter ... (library loading, function calling, etc.)
7870 // ... and we _know_ we are in the middle of parsing, so let's make
7871 // sure to save the state and then restore it.
7872
7873 if (gDirectory) {
7874 auto iSpecObjMap = fSpecialObjectMaps.find(gDirectory);
7875 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7876 auto iSpecObj = iSpecObjMap->second.find(Name);
7877 if (iSpecObj != iSpecObjMap->second.end()) {
7878 LookupCtx = gDirectory;
7879 return iSpecObj->second;
7880 }
7881 }
7882 }
7883
7884 // Save state of the PP
7885 Sema &SemaR = fInterpreter->getSema();
7886 ASTContext& C = SemaR.getASTContext();
7887 Preprocessor &PP = SemaR.getPreprocessor();
7888 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7889 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7890 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7891 // After we have saved the token reset the current one to something which
7892 // is safe (semi colon usually means empty decl)
7893 Token& Tok = const_cast<Token&>(P.getCurToken());
7894 Tok.setKind(tok::semi);
7895
7896 // We can't PushDeclContext, because we go up and the routine that pops
7897 // the DeclContext assumes that we drill down always.
7898 // We have to be on the global context. At that point we are in a
7899 // wrapper function so the parent context must be the global.
7900 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7901 SemaR.TUScope);
7902
7903 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7904 if (specObj) {
7905 if (!LookupCtx) {
7906 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7907 } else {
7908 fSpecialObjectMaps[LookupCtx][Name] = specObj;
7909 }
7910 }
7911 return specObj;
7912}
7913
7914////////////////////////////////////////////////////////////////////////////////
7915/// Inject function as a friend into klass.
7916/// With function being f in void f() {new N::PrivKlass(); } this enables
7917/// I/O of non-public classes.
7918
7919void TCling::AddFriendToClass(clang::FunctionDecl* function,
7920 clang::CXXRecordDecl* klass) const
7921{
7922 using namespace clang;
7923 ASTContext& Ctx = klass->getASTContext();
7924 FriendDecl::FriendUnion friendUnion(function);
7925 // one dummy object for the source location
7926 SourceLocation sl;
7927 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
7928 klass->pushFriendDecl(friendDecl);
7929}
7930
7931//______________________________________________________________________________
7932//
7933// DeclId getter.
7934//
7935
7936////////////////////////////////////////////////////////////////////////////////
7937/// Return a unique identifier of the declaration represented by the
7938/// CallFunc
7939
7941{
7942 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
7943 return nullptr;
7944}
7945
7946////////////////////////////////////////////////////////////////////////////////
7947/// Return a (almost) unique identifier of the declaration represented by the
7948/// ClassInfo. In ROOT, this identifier can point to more than one TClass
7949/// when the underlying class is a template instance involving one of the
7950/// opaque typedef.
7951
7953{
7954 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
7955 return nullptr;
7956}
7957
7958////////////////////////////////////////////////////////////////////////////////
7959/// Return a unique identifier of the declaration represented by the
7960/// MethodInfo
7961
7963{
7964 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
7965 return nullptr;
7966}
7967
7968////////////////////////////////////////////////////////////////////////////////
7969/// Return a unique identifier of the declaration represented by the
7970/// MethodInfo
7971
7973{
7974 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
7975 return nullptr;
7976}
7977
7978////////////////////////////////////////////////////////////////////////////////
7979/// Return a unique identifier of the declaration represented by the
7980/// TypedefInfo
7981
7983{
7984 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
7985 return nullptr;
7986}
7987
7988//______________________________________________________________________________
7989//
7990// CallFunc interface
7991//
7992
7993////////////////////////////////////////////////////////////////////////////////
7994
7995void TCling::CallFunc_Delete(CallFunc_t* func) const
7996{
7997 delete (TClingCallFunc*) func;
7998}
7999
8000////////////////////////////////////////////////////////////////////////////////
8001
8002void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
8003{
8004 TClingCallFunc* f = (TClingCallFunc*) func;
8005 f->Exec(address);
8006}
8007
8008////////////////////////////////////////////////////////////////////////////////
8009
8010void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
8011{
8012 TClingCallFunc* f = (TClingCallFunc*) func;
8013 f->Exec(address, &val);
8014}
8015
8016////////////////////////////////////////////////////////////////////////////////
8017
8018void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
8019{
8020 TClingCallFunc* f = (TClingCallFunc*) func;
8021 f->ExecWithReturn(address, ret);
8022}
8023
8024////////////////////////////////////////////////////////////////////////////////
8025
8026void TCling::CallFunc_ExecWithArgsAndReturn(CallFunc_t* func, void* address,
8027 const void* args[] /*=0*/,
8028 int nargs /*=0*/,
8029 void* ret/*=0*/) const
8030{
8031 TClingCallFunc* f = (TClingCallFunc*) func;
8032 f->ExecWithArgsAndReturn(address, args, nargs, ret);
8033}
8034
8035////////////////////////////////////////////////////////////////////////////////
8036
8037Longptr_t TCling::CallFunc_ExecInt(CallFunc_t* func, void* address) const
8038{
8039 TClingCallFunc* f = (TClingCallFunc*) func;
8040 return f->ExecInt(address);
8041}
8042
8043////////////////////////////////////////////////////////////////////////////////
8044
8045Long64_t TCling::CallFunc_ExecInt64(CallFunc_t* func, void* address) const
8046{
8047 TClingCallFunc* f = (TClingCallFunc*) func;
8048 return f->ExecInt64(address);
8049}
8050
8051////////////////////////////////////////////////////////////////////////////////
8052
8053Double_t TCling::CallFunc_ExecDouble(CallFunc_t* func, void* address) const
8054{
8055 TClingCallFunc* f = (TClingCallFunc*) func;
8056 return f->ExecDouble(address);
8057}
8058
8059////////////////////////////////////////////////////////////////////////////////
8060
8061CallFunc_t* TCling::CallFunc_Factory() const
8062{
8064 return (CallFunc_t*) new TClingCallFunc(GetInterpreterImpl());
8065}
8066
8067////////////////////////////////////////////////////////////////////////////////
8068
8069CallFunc_t* TCling::CallFunc_FactoryCopy(CallFunc_t* func) const
8070{
8071 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
8072}
8073
8074////////////////////////////////////////////////////////////////////////////////
8075
8076MethodInfo_t* TCling::CallFunc_FactoryMethod(CallFunc_t* func) const
8077{
8078 TClingCallFunc* f = (TClingCallFunc*) func;
8079 return (MethodInfo_t*) f->FactoryMethod();
8080}
8081
8082////////////////////////////////////////////////////////////////////////////////
8083
8084void TCling::CallFunc_IgnoreExtraArgs(CallFunc_t* func, bool ignore) const
8085{
8086 TClingCallFunc* f = (TClingCallFunc*) func;
8087 f->IgnoreExtraArgs(ignore);
8088}
8089
8090////////////////////////////////////////////////////////////////////////////////
8091
8092void TCling::CallFunc_Init(CallFunc_t* func) const
8093{
8095 TClingCallFunc* f = (TClingCallFunc*) func;
8096 f->Init();
8097}
8098
8099////////////////////////////////////////////////////////////////////////////////
8100
8101bool TCling::CallFunc_IsValid(CallFunc_t* func) const
8102{
8103 TClingCallFunc* f = (TClingCallFunc*) func;
8104 return f->IsValid();
8105}
8106
8107////////////////////////////////////////////////////////////////////////////////
8108
8110TCling::CallFunc_IFacePtr(CallFunc_t * func) const
8111{
8112 TClingCallFunc* f = (TClingCallFunc*) func;
8113 return f->IFacePtr();
8114}
8115
8116////////////////////////////////////////////////////////////////////////////////
8117
8118void TCling::CallFunc_ResetArg(CallFunc_t* func) const
8119{
8120 TClingCallFunc* f = (TClingCallFunc*) func;
8121 f->ResetArg();
8122}
8123
8124////////////////////////////////////////////////////////////////////////////////
8125
8126void TCling::CallFunc_SetArg(CallFunc_t* func, Long_t param) const
8127{
8128 TClingCallFunc* f = (TClingCallFunc*) func;
8129 f->SetArg(param);
8130}
8131
8132////////////////////////////////////////////////////////////////////////////////
8133
8134void TCling::CallFunc_SetArg(CallFunc_t* func, ULong_t param) const
8135{
8136 TClingCallFunc* f = (TClingCallFunc*) func;
8137 f->SetArg(param);
8138}
8139
8140////////////////////////////////////////////////////////////////////////////////
8141
8142void TCling::CallFunc_SetArg(CallFunc_t* func, Float_t param) const
8143{
8144 TClingCallFunc* f = (TClingCallFunc*) func;
8145 f->SetArg(param);
8146}
8147
8148////////////////////////////////////////////////////////////////////////////////
8149
8150void TCling::CallFunc_SetArg(CallFunc_t* func, Double_t param) const
8151{
8152 TClingCallFunc* f = (TClingCallFunc*) func;
8153 f->SetArg(param);
8154}
8155
8156////////////////////////////////////////////////////////////////////////////////
8157
8158void TCling::CallFunc_SetArg(CallFunc_t* func, Long64_t param) const
8159{
8160 TClingCallFunc* f = (TClingCallFunc*) func;
8161 f->SetArg(param);
8162}
8163
8164////////////////////////////////////////////////////////////////////////////////
8165
8166void TCling::CallFunc_SetArg(CallFunc_t* func, ULong64_t param) const
8167{
8168 TClingCallFunc* f = (TClingCallFunc*) func;
8169 f->SetArg(param);
8170}
8171
8172////////////////////////////////////////////////////////////////////////////////
8173
8174void TCling::CallFunc_SetArgArray(CallFunc_t* func, Longptr_t* paramArr, Int_t nparam) const
8175{
8176 TClingCallFunc* f = (TClingCallFunc*) func;
8177 f->SetArgArray(paramArr, nparam);
8178}
8179
8180////////////////////////////////////////////////////////////////////////////////
8181
8182void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
8183{
8184 TClingCallFunc* f = (TClingCallFunc*) func;
8185 f->SetArgs(param);
8186}
8187
8188////////////////////////////////////////////////////////////////////////////////
8189
8190void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Longptr_t* offset) const
8191{
8192 TClingCallFunc* f = (TClingCallFunc*) func;
8193 TClingClassInfo* ci = (TClingClassInfo*) info;
8194 f->SetFunc(ci, method, params, offset);
8195}
8196
8197////////////////////////////////////////////////////////////////////////////////
8198
8199void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Longptr_t* offset) const
8200{
8201 TClingCallFunc* f = (TClingCallFunc*) func;
8202 TClingClassInfo* ci = (TClingClassInfo*) info;
8203 f->SetFunc(ci, method, params, objectIsConst, offset);
8204}
8205////////////////////////////////////////////////////////////////////////////////
8206
8207void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
8208{
8209 TClingCallFunc* f = (TClingCallFunc*) func;
8210 TClingMethodInfo* minfo = (TClingMethodInfo*) info;
8211 f->SetFunc(minfo);
8212}
8213
8214////////////////////////////////////////////////////////////////////////////////
8215/// Interface to cling function
8216
8217void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8218{
8219 TClingCallFunc* f = (TClingCallFunc*) func;
8220 TClingClassInfo* ci = (TClingClassInfo*) info;
8221 f->SetFuncProto(ci, method, proto, offset, mode);
8222}
8223
8224////////////////////////////////////////////////////////////////////////////////
8225/// Interface to cling function
8226
8227void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8228{
8229 TClingCallFunc* f = (TClingCallFunc*) func;
8230 TClingClassInfo* ci = (TClingClassInfo*) info;
8231 f->SetFuncProto(ci, method, proto, objectIsConst, 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, 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, offset, mode);
8247}
8248
8249////////////////////////////////////////////////////////////////////////////////
8250/// Interface to cling function
8251
8252void 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
8253{
8254 TClingCallFunc* f = (TClingCallFunc*) func;
8255 TClingClassInfo* ci = (TClingClassInfo*) info;
8256 llvm::SmallVector<clang::QualType, 4> funcProto;
8257 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8258 iter != end; ++iter) {
8259 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8260 }
8261 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
8262}
8263
8264std::string TCling::CallFunc_GetWrapperCode(CallFunc_t *func) const
8265{
8266 TClingCallFunc *f = (TClingCallFunc *)func;
8267 std::string wrapper_name;
8268 std::string wrapper;
8269 f->get_wrapper_code(wrapper_name, wrapper);
8270 return wrapper;
8271}
8272
8273//______________________________________________________________________________
8274//
8275// ClassInfo interface
8276//
8277
8278////////////////////////////////////////////////////////////////////////////////
8279
8280size_t TCling::ClassInfo_AlignOf(ClassInfo_t *cinfo) const
8281{
8282 TClingClassInfo *TClinginfo = (TClingClassInfo *)cinfo;
8283 return TClinginfo->GetAlignOf();
8284}
8285
8286////////////////////////////////////////////////////////////////////////////////
8287/// Return true if the entity pointed to by 'declid' is declared in
8288/// the context described by 'info'. If info is null, look into the
8289/// global scope (translation unit scope).
8290
8291Bool_t TCling::ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const
8292{
8293 if (!declid)
8294 return kFALSE;
8295
8296 const clang::DeclContext *ctxt = nullptr;
8297 if (info) {
8298 ctxt = clang::Decl::castToDeclContext(((TClingClassInfo*)info)->GetDecl());
8299 } else {
8300 ctxt = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
8301 }
8302 if (!ctxt)
8303 return kFALSE;
8304
8305 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
8306 if (!decl)
8307 return kFALSE;
8308
8309 const clang::DeclContext *declDC = decl->getDeclContext();
8310 // ClassInfo_t-s are always "spellable" scopes, never unnamed or inline ones.
8311 while (true) {
8312 if (declDC->isTransparentContext()) {
8313 declDC = declDC->getParent();
8314 continue;
8315 }
8316 if (const auto *declRD = llvm::dyn_cast<clang::RecordDecl>(declDC)) {
8317 if (declRD->isAnonymousStructOrUnion()) {
8318 declDC = declRD->getParent();
8319 continue;
8320 }
8321 }
8322 if (const auto *declNS = llvm::dyn_cast<clang::NamespaceDecl>(declDC)) {
8323 if (declNS->isAnonymousNamespace() || declNS->isInlineNamespace()) {
8324 declDC = declNS->getParent();
8325 continue;
8326 }
8327 }
8328 break;
8329 }
8330
8331 return declDC->Equals(ctxt);
8332}
8333
8334////////////////////////////////////////////////////////////////////////////////
8335
8337{
8338 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8339 return TClinginfo->ClassProperty();
8340}
8341
8342////////////////////////////////////////////////////////////////////////////////
8343
8344void TCling::ClassInfo_Delete(ClassInfo_t* cinfo) const
8345{
8346 delete (TClingClassInfo*) cinfo;
8347}
8348
8349////////////////////////////////////////////////////////////////////////////////
8350
8351void TCling::ClassInfo_Delete(ClassInfo_t* cinfo, void* arena) const
8352{
8353 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8354 TClinginfo->Delete(arena,*fNormalizedCtxt);
8355}
8356
8357////////////////////////////////////////////////////////////////////////////////
8358
8359void TCling::ClassInfo_DeleteArray(ClassInfo_t* cinfo, void* arena, bool dtorOnly) const
8360{
8361 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8362 TClinginfo->DeleteArray(arena, dtorOnly,*fNormalizedCtxt);
8363}
8364
8365////////////////////////////////////////////////////////////////////////////////
8366
8367void TCling::ClassInfo_Destruct(ClassInfo_t* cinfo, void* arena) const
8368{
8369 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8370 TClinginfo->Destruct(arena,*fNormalizedCtxt);
8371}
8372
8373////////////////////////////////////////////////////////////////////////////////
8374
8375ClassInfo_t* TCling::ClassInfo_Factory(Bool_t all) const
8376{
8378 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), all);
8379}
8380
8381////////////////////////////////////////////////////////////////////////////////
8382
8383ClassInfo_t* TCling::ClassInfo_Factory(ClassInfo_t* cinfo) const
8384{
8385 return (ClassInfo_t*) new TClingClassInfo(*(TClingClassInfo*)cinfo);
8386}
8387
8388////////////////////////////////////////////////////////////////////////////////
8389
8390ClassInfo_t* TCling::ClassInfo_Factory(const char* name) const
8391{
8393 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), name);
8394}
8395
8396ClassInfo_t* TCling::ClassInfo_Factory(DeclId_t declid) const
8397{
8399 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), (const clang::Decl*)declid);
8400}
8401
8402
8403////////////////////////////////////////////////////////////////////////////////
8404
8405int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
8406{
8407 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8408 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
8409}
8410
8411////////////////////////////////////////////////////////////////////////////////
8412
8413bool TCling::ClassInfo_HasDefaultConstructor(ClassInfo_t* cinfo, Bool_t testio) const
8414{
8415 TClingClassInfo *TClinginfo = (TClingClassInfo *) cinfo;
8417}
8418
8419////////////////////////////////////////////////////////////////////////////////
8420
8421bool TCling::ClassInfo_HasMethod(ClassInfo_t* cinfo, const char* name) const
8422{
8423 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8424 return TClinginfo->HasMethod(name);
8425}
8426
8427////////////////////////////////////////////////////////////////////////////////
8428
8429void TCling::ClassInfo_Init(ClassInfo_t* cinfo, const char* name) const
8430{
8432 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8433 TClinginfo->Init(name);
8434}
8435
8436////////////////////////////////////////////////////////////////////////////////
8437
8438void TCling::ClassInfo_Init(ClassInfo_t* cinfo, int tagnum) const
8439{
8441 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8442 TClinginfo->Init(tagnum);
8443}
8444
8445////////////////////////////////////////////////////////////////////////////////
8446
8447bool TCling::ClassInfo_IsBase(ClassInfo_t* cinfo, const char* name) const
8448{
8449 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8450 return TClinginfo->IsBase(name);
8451}
8452
8453////////////////////////////////////////////////////////////////////////////////
8454
8455bool TCling::ClassInfo_IsEnum(const char* name) const
8456{
8458}
8459
8460////////////////////////////////////////////////////////////////////////////////
8461
8463{
8464 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8465 return TClinginfo->IsScopedEnum();
8466}
8467
8468
8469////////////////////////////////////////////////////////////////////////////////
8470
8471EDataType TCling::ClassInfo_GetUnderlyingType(ClassInfo_t* info) const
8472{
8473 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8474 return TClinginfo->GetUnderlyingType();
8475}
8476
8477
8478////////////////////////////////////////////////////////////////////////////////
8479
8480bool TCling::ClassInfo_IsLoaded(ClassInfo_t* cinfo) const
8481{
8482 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8483 return TClinginfo->IsLoaded();
8484}
8485
8486////////////////////////////////////////////////////////////////////////////////
8487
8488bool TCling::ClassInfo_IsValid(ClassInfo_t* cinfo) const
8489{
8490 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8491 return TClinginfo->IsValid();
8492}
8493
8494////////////////////////////////////////////////////////////////////////////////
8495
8496bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8497{
8498 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8499 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
8500}
8501
8502////////////////////////////////////////////////////////////////////////////////
8503
8504bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8505{
8506 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8507 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8508}
8509
8510////////////////////////////////////////////////////////////////////////////////
8511
8512int TCling::ClassInfo_Next(ClassInfo_t* cinfo) const
8513{
8514 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8515 return TClinginfo->Next();
8516}
8517
8518////////////////////////////////////////////////////////////////////////////////
8519
8520void* TCling::ClassInfo_New(ClassInfo_t* cinfo) const
8521{
8522 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8523 return TClinginfo->New(*fNormalizedCtxt);
8524}
8525
8526////////////////////////////////////////////////////////////////////////////////
8527
8528void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n) const
8529{
8530 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8531 return TClinginfo->New(n,*fNormalizedCtxt);
8532}
8533
8534////////////////////////////////////////////////////////////////////////////////
8535
8536void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n, void* arena) const
8537{
8538 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8539 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8540}
8541
8542////////////////////////////////////////////////////////////////////////////////
8543
8544void* TCling::ClassInfo_New(ClassInfo_t* cinfo, void* arena) const
8545{
8546 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8547 return TClinginfo->New(arena,*fNormalizedCtxt);
8548}
8549
8550////////////////////////////////////////////////////////////////////////////////
8551
8552Long_t TCling::ClassInfo_Property(ClassInfo_t* cinfo) const
8553{
8554 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8555 return TClinginfo->Property();
8556}
8557
8558////////////////////////////////////////////////////////////////////////////////
8559
8560int TCling::ClassInfo_Size(ClassInfo_t* cinfo) const
8561{
8562 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8563 return TClinginfo->Size();
8564}
8565
8566////////////////////////////////////////////////////////////////////////////////
8567
8568Longptr_t TCling::ClassInfo_Tagnum(ClassInfo_t* cinfo) const
8569{
8570 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8571 return TClinginfo->Tagnum();
8572}
8573
8574////////////////////////////////////////////////////////////////////////////////
8575
8576const char* TCling::ClassInfo_FileName(ClassInfo_t* cinfo) const
8577{
8578 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8579 return TClinginfo->FileName();
8580}
8581
8582////////////////////////////////////////////////////////////////////////////////
8583
8584const char* TCling::ClassInfo_FullName(ClassInfo_t* cinfo) const
8585{
8586 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8587 TTHREAD_TLS_DECL(std::string,output);
8588 TClinginfo->FullName(output,*fNormalizedCtxt);
8589 return output.c_str(); // NOLINT
8590}
8591
8592////////////////////////////////////////////////////////////////////////////////
8593
8594const char* TCling::ClassInfo_Name(ClassInfo_t* cinfo) const
8595{
8596 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8597 return TClinginfo->Name();
8598}
8599
8600////////////////////////////////////////////////////////////////////////////////
8601
8602const char* TCling::ClassInfo_Title(ClassInfo_t* cinfo) const
8603{
8604 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8605 return TClinginfo->Title();
8606}
8607
8608////////////////////////////////////////////////////////////////////////////////
8609
8610const char* TCling::ClassInfo_TmpltName(ClassInfo_t* cinfo) const
8611{
8612 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8613 return TClinginfo->TmpltName();
8614}
8615
8616
8617
8618//______________________________________________________________________________
8619//
8620// BaseClassInfo interface
8621//
8622
8623////////////////////////////////////////////////////////////////////////////////
8624
8625void TCling::BaseClassInfo_Delete(BaseClassInfo_t* bcinfo) const
8626{
8627 delete(TClingBaseClassInfo*) bcinfo;
8628}
8629
8630////////////////////////////////////////////////////////////////////////////////
8631
8632BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo) const
8633{
8635 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8636 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo);
8637}
8638
8639////////////////////////////////////////////////////////////////////////////////
8640
8641BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* derived,
8642 ClassInfo_t* base) const
8643{
8645 TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
8646 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) base;
8647 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo, TClinginfoBase);
8648}
8649
8650////////////////////////////////////////////////////////////////////////////////
8651
8652int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo) const
8653{
8654 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8655 return TClinginfo->Next();
8656}
8657
8658////////////////////////////////////////////////////////////////////////////////
8659
8660int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo, int onlyDirect) const
8661{
8662 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8663 return TClinginfo->Next(onlyDirect);
8664}
8665
8666////////////////////////////////////////////////////////////////////////////////
8667
8668Longptr_t TCling::BaseClassInfo_Offset(BaseClassInfo_t* toBaseClassInfo, void * address, bool isDerivedObject) const
8669{
8670 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) toBaseClassInfo;
8671 return TClinginfo->Offset(address, isDerivedObject);
8672}
8673
8674////////////////////////////////////////////////////////////////////////////////
8675
8676Longptr_t TCling::ClassInfo_GetBaseOffset(ClassInfo_t* fromDerived, ClassInfo_t* toBase, void * address, bool isDerivedObject) const
8677{
8678 TClingClassInfo* TClinginfo = (TClingClassInfo*) fromDerived;
8679 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) toBase;
8680 // Offset to the class itself.
8681 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8682 return 0;
8683 }
8684 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8685}
8686
8687////////////////////////////////////////////////////////////////////////////////
8688
8689Long_t TCling::BaseClassInfo_Property(BaseClassInfo_t* bcinfo) const
8690{
8691 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8692 return TClinginfo->Property();
8693}
8694
8695////////////////////////////////////////////////////////////////////////////////
8696
8697ClassInfo_t *TCling::BaseClassInfo_ClassInfo(BaseClassInfo_t *bcinfo) const
8698{
8699 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8700 return (ClassInfo_t *)TClinginfo->GetBase();
8701}
8702
8703////////////////////////////////////////////////////////////////////////////////
8704
8705Longptr_t TCling::BaseClassInfo_Tagnum(BaseClassInfo_t* bcinfo) const
8706{
8707 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8708 return TClinginfo->Tagnum();
8709}
8710
8711////////////////////////////////////////////////////////////////////////////////
8712
8713const char* TCling::BaseClassInfo_FullName(BaseClassInfo_t* bcinfo) const
8714{
8715 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8716 TTHREAD_TLS_DECL(std::string,output);
8717 TClinginfo->FullName(output,*fNormalizedCtxt);
8718 return output.c_str(); // NOLINT
8719}
8720
8721////////////////////////////////////////////////////////////////////////////////
8722
8723const char* TCling::BaseClassInfo_Name(BaseClassInfo_t* bcinfo) const
8724{
8725 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8726 return TClinginfo->Name();
8727}
8728
8729////////////////////////////////////////////////////////////////////////////////
8730
8731const char* TCling::BaseClassInfo_TmpltName(BaseClassInfo_t* bcinfo) const
8732{
8733 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8734 return TClinginfo->TmpltName();
8735}
8736
8737//______________________________________________________________________________
8738//
8739// DataMemberInfo interface
8740//
8741
8742////////////////////////////////////////////////////////////////////////////////
8743
8744int TCling::DataMemberInfo_ArrayDim(DataMemberInfo_t* dminfo) const
8745{
8746 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8747 return TClinginfo->ArrayDim();
8748}
8749
8750////////////////////////////////////////////////////////////////////////////////
8751
8752void TCling::DataMemberInfo_Delete(DataMemberInfo_t* dminfo) const
8753{
8754 delete(TClingDataMemberInfo*) dminfo;
8755}
8756
8757////////////////////////////////////////////////////////////////////////////////
8758
8759DataMemberInfo_t* TCling::DataMemberInfo_Factory(ClassInfo_t* clinfo, TDictionary::EMemberSelection selection) const
8760{
8762 TClingClassInfo* TClingclass_info = (TClingClassInfo*) clinfo;
8763 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), TClingclass_info, selection);
8764}
8765
8766////////////////////////////////////////////////////////////////////////////////
8767
8768DataMemberInfo_t* TCling::DataMemberInfo_Factory(DeclId_t declid, ClassInfo_t* clinfo) const
8769{
8771 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8772 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8773 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), vd, (TClingClassInfo*)clinfo);
8774}
8775
8776////////////////////////////////////////////////////////////////////////////////
8777
8778DataMemberInfo_t* TCling::DataMemberInfo_FactoryCopy(DataMemberInfo_t* dminfo) const
8779{
8780 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8781 return (DataMemberInfo_t*) new TClingDataMemberInfo(*TClinginfo);
8782}
8783
8784////////////////////////////////////////////////////////////////////////////////
8785
8786bool TCling::DataMemberInfo_IsValid(DataMemberInfo_t* dminfo) const
8787{
8788 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8789 return TClinginfo->IsValid();
8790}
8791
8792////////////////////////////////////////////////////////////////////////////////
8793
8794int TCling::DataMemberInfo_MaxIndex(DataMemberInfo_t* dminfo, Int_t dim) const
8795{
8796 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8797 return TClinginfo->MaxIndex(dim);
8798}
8799
8800////////////////////////////////////////////////////////////////////////////////
8801
8802int TCling::DataMemberInfo_Next(DataMemberInfo_t* dminfo) const
8803{
8804 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8805 return TClinginfo->Next();
8806}
8807
8808////////////////////////////////////////////////////////////////////////////////
8809
8810Longptr_t TCling::DataMemberInfo_Offset(DataMemberInfo_t* dminfo) const
8811{
8812 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8813 return TClinginfo->Offset();
8814}
8815
8816////////////////////////////////////////////////////////////////////////////////
8817
8818Long_t TCling::DataMemberInfo_Property(DataMemberInfo_t* dminfo) const
8819{
8820 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8821 return TClinginfo->Property();
8822}
8823
8824////////////////////////////////////////////////////////////////////////////////
8825
8826Long_t TCling::DataMemberInfo_TypeProperty(DataMemberInfo_t* dminfo) const
8827{
8828 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8829 return TClinginfo->TypeProperty();
8830}
8831
8832////////////////////////////////////////////////////////////////////////////////
8833
8834int TCling::DataMemberInfo_TypeSize(DataMemberInfo_t* dminfo) const
8835{
8836 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8837 return TClinginfo->TypeSize();
8838}
8839
8840////////////////////////////////////////////////////////////////////////////////
8841
8842const char* TCling::DataMemberInfo_TypeName(DataMemberInfo_t* dminfo) const
8843{
8844 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8845 return TClinginfo->TypeName();
8846}
8847
8848////////////////////////////////////////////////////////////////////////////////
8849
8850const char* TCling::DataMemberInfo_TypeTrueName(DataMemberInfo_t* dminfo) const
8851{
8852 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8853 return TClinginfo->TypeTrueName(*fNormalizedCtxt);
8854}
8855
8856////////////////////////////////////////////////////////////////////////////////
8857
8858const char* TCling::DataMemberInfo_Name(DataMemberInfo_t* dminfo) const
8859{
8860 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8861 return TClinginfo->Name();
8862}
8863
8864////////////////////////////////////////////////////////////////////////////////
8865
8866const char* TCling::DataMemberInfo_Title(DataMemberInfo_t* dminfo) const
8867{
8868 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8869 return TClinginfo->Title();
8870}
8871
8872////////////////////////////////////////////////////////////////////////////////
8873
8874const char* TCling::DataMemberInfo_ValidArrayIndex(DataMemberInfo_t* dminfo) const
8875{
8876 TTHREAD_TLS_DECL(std::string,result);
8877
8878 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8879 result = TClinginfo->ValidArrayIndex().str();
8880 return result.c_str(); // NOLINT
8881}
8882
8883////////////////////////////////////////////////////////////////////////////////
8884
8885void TCling::SetDeclAttr(DeclId_t declId, const char* attribute)
8886{
8887 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8888 ASTContext &C = decl->getASTContext();
8889 decl->addAttr(AnnotateAttr::CreateImplicit(C, attribute, nullptr, 0));
8890}
8891
8892//______________________________________________________________________________
8893//
8894// Function Template interface
8895//
8896
8897////////////////////////////////////////////////////////////////////////////////
8898
8899static void ConstructorName(std::string &name, const clang::Decl *decl,
8900 cling::Interpreter &interp,
8901 const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
8902{
8903 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8904 if (!td) return;
8905
8906 clang::QualType qualType(td->getTypeForDecl(),0);
8907 ROOT::TMetaUtils::GetNormalizedName(name, qualType, interp, normCtxt);
8908 unsigned int level = 0;
8909 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8910 if (name[cursor] == '>') ++level;
8911 else if (name[cursor] == '<' && level) --level;
8912 else if (level == 0 && name[cursor] == ':') {
8913 name.erase(0,cursor+1);
8914 break;
8915 }
8916 }
8917}
8918
8919////////////////////////////////////////////////////////////////////////////////
8920
8921void TCling::GetFunctionName(const clang::Decl *decl, std::string &output) const
8922{
8923 output.clear();
8924
8925 const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(decl);
8926 if (const auto *USD = llvm::dyn_cast<clang::UsingShadowDecl>(decl)) {
8927 FD = llvm::dyn_cast<clang::FunctionDecl>(USD->getTargetDecl());
8928 }
8929 if (!FD) {
8930 Error("GetFunctionName", "NULL Decl!");
8931 return;
8932 }
8933
8934 // For using-decls, show "Derived", not "Base", i.e. use the
8935 // name of the decl context of the UsingShadowDecl (aka `decl`)
8936 // not the name of FD's decl context.
8937 if (llvm::isa<clang::CXXConstructorDecl>(FD))
8938 {
8940
8941 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
8942 {
8944 output.insert(output.begin(), '~');
8945 } else {
8946 llvm::raw_string_ostream stream(output);
8947 auto printPolicy = decl->getASTContext().getPrintingPolicy();
8948 // Don't trigger fopen of the source file to count lines:
8949 printPolicy.AnonymousTagLocations = false;
8950 FD->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
8951 }
8952}
8953
8954////////////////////////////////////////////////////////////////////////////////
8955/// Return a unique identifier of the declaration represented by the
8956/// FuncTempInfo
8957
8959{
8960 return (DeclId_t)info;
8961}
8962
8963////////////////////////////////////////////////////////////////////////////////
8964/// Delete the FuncTempInfo_t
8965
8966void TCling::FuncTempInfo_Delete(FuncTempInfo_t * /* ft_info */) const
8967{
8968 // Currently the address of ft_info is actually the decl itself,
8969 // so we have nothing to do.
8970}
8971
8972////////////////////////////////////////////////////////////////////////////////
8973/// Construct a FuncTempInfo_t
8974
8975FuncTempInfo_t *TCling::FuncTempInfo_Factory(DeclId_t declid) const
8976{
8977 // Currently the address of ft_info is actually the decl itself,
8978 // so we have nothing to do.
8979
8980 return (FuncTempInfo_t*)const_cast<void*>(declid);
8981}
8982
8983////////////////////////////////////////////////////////////////////////////////
8984/// Construct a FuncTempInfo_t
8985
8986FuncTempInfo_t *TCling::FuncTempInfo_FactoryCopy(FuncTempInfo_t *ft_info) const
8987{
8988 // Currently the address of ft_info is actually the decl itself,
8989 // so we have nothing to do.
8990
8991 return (FuncTempInfo_t*)ft_info;
8992}
8993
8994////////////////////////////////////////////////////////////////////////////////
8995/// Check validity of a FuncTempInfo_t
8996
8997Bool_t TCling::FuncTempInfo_IsValid(FuncTempInfo_t *t_info) const
8998{
8999 // Currently the address of ft_info is actually the decl itself,
9000 // so we have nothing to do.
9001
9002 return t_info != nullptr;
9003}
9004
9005////////////////////////////////////////////////////////////////////////////////
9006/// Return the maximum number of template arguments of the
9007/// function template described by ft_info.
9008
9009UInt_t TCling::FuncTempInfo_TemplateNargs(FuncTempInfo_t *ft_info) const
9010{
9011 if (!ft_info) return 0;
9012 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
9013 return ft->getTemplateParameters()->size();
9014}
9015
9016////////////////////////////////////////////////////////////////////////////////
9017/// Return the number of required template arguments of the
9018/// function template described by ft_info.
9019
9020UInt_t TCling::FuncTempInfo_TemplateMinReqArgs(FuncTempInfo_t *ft_info) const
9021{
9022 if (!ft_info) return 0;
9023 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9024 return ft->getTemplateParameters()->getMinRequiredArguments();
9025}
9026
9027////////////////////////////////////////////////////////////////////////////////
9028/// Return the property of the function template.
9029
9030Long_t TCling::FuncTempInfo_Property(FuncTempInfo_t *ft_info) const
9031{
9032 if (!ft_info) return 0;
9033
9034 long property = 0L;
9035 property |= kIsCompiled;
9036
9037 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9038
9039 switch (ft->getAccess()) {
9040 case clang::AS_public:
9041 property |= kIsPublic;
9042 break;
9043 case clang::AS_protected:
9044 property |= kIsProtected;
9045 break;
9046 case clang::AS_private:
9047 property |= kIsPrivate;
9048 break;
9049 case clang::AS_none:
9050 if (ft->getDeclContext()->isNamespace())
9051 property |= kIsPublic;
9052 break;
9053 default:
9054 // IMPOSSIBLE
9055 assert(false && "Unexpected value for the access property value in Clang");
9056 break;
9057 }
9058
9059 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
9060
9061 if (fd && fd->getStorageClass() == clang::SC_Static)
9062 property |= kIsStatic;
9063
9064 if (const clang::CXXMethodDecl *md =
9065 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
9066 if (md->getMethodQualifiers().hasConst()) {
9067 property |= kIsConstant | kIsConstMethod;
9068 }
9069 if (md->isVirtual()) {
9070 property |= kIsVirtual;
9071 }
9072 if (md->isPureVirtual()) {
9073 property |= kIsPureVirtual;
9074 }
9075 if (const clang::CXXConstructorDecl *cd =
9076 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
9077 if (cd->isExplicit()) {
9078 property |= kIsExplicit;
9079 }
9080 }
9081 else if (const clang::CXXConversionDecl *cd =
9082 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
9083 if (cd->isExplicit()) {
9084 property |= kIsExplicit;
9085 }
9086 }
9087 }
9088 return property;
9089}
9090
9091////////////////////////////////////////////////////////////////////////////////
9092/// Return the property not already defined in Property
9093/// See TDictionary's EFunctionProperty
9094
9095Long_t TCling::FuncTempInfo_ExtraProperty(FuncTempInfo_t* ft_info) const
9096{
9097 if (!ft_info) return 0;
9098
9099 long property = 0L;
9100 property |= kIsCompiled;
9101
9102 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9103 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
9104
9105 if (fd->isOverloadedOperator())
9106 property |= kIsOperator;
9107 if (llvm::isa<clang::CXXConversionDecl>(fd))
9108 property |= kIsConversion;
9109 if (llvm::isa<clang::CXXConstructorDecl>(fd))
9110 property |= kIsConstructor;
9111 if (llvm::isa<clang::CXXDestructorDecl>(fd))
9112 property |= kIsDestructor;
9113 if (fd->isInlined())
9114 property |= kIsInlined;
9115 return property;
9116}
9117
9118////////////////////////////////////////////////////////////////////////////////
9119/// Return the name of this function template.
9120
9121void TCling::FuncTempInfo_Name(FuncTempInfo_t *ft_info, TString &output) const
9122{
9123 output.Clear();
9124 if (!ft_info) return;
9125 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9126 std::string buf;
9127 GetFunctionName(ft->getTemplatedDecl(), buf);
9128 output = buf;
9129}
9130
9131////////////////////////////////////////////////////////////////////////////////
9132/// Return the comments associates with this function template.
9133
9134void TCling::FuncTempInfo_Title(FuncTempInfo_t *ft_info, TString &output) const
9135{
9136 output.Clear();
9137 if (!ft_info) return;
9138 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
9139
9140 // Iterate over the redeclarations, we can have multiple definitions in the
9141 // redecl chain (came from merging of pcms).
9142 if (const RedeclarableTemplateDecl *AnnotFD
9143 = ROOT::TMetaUtils::GetAnnotatedRedeclarable((const RedeclarableTemplateDecl*)ft)) {
9144 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
9145 output = A->getAnnotation().str();
9146 return;
9147 }
9148 }
9149 if (!ft->isFromASTFile()) {
9150 // Try to get the comment from the header file if present
9151 // but not for decls from AST file, where rootcling would have
9152 // created an annotation
9153 output = ROOT::TMetaUtils::GetComment(*ft).str();
9154 }
9155}
9156
9157
9158//______________________________________________________________________________
9159//
9160// MethodInfo interface
9161//
9162
9163////////////////////////////////////////////////////////////////////////////////
9164/// Interface to cling function
9165
9166void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
9167{
9168 delete(TClingMethodInfo*) minfo;
9169}
9170
9171////////////////////////////////////////////////////////////////////////////////
9172
9173void TCling::MethodInfo_CreateSignature(MethodInfo_t* minfo, TString& signature) const
9174{
9175 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9176 // The next call locks the interpreter mutex.
9177 info->CreateSignature(signature);
9178}
9179
9180////////////////////////////////////////////////////////////////////////////////
9181
9182MethodInfo_t* TCling::MethodInfo_Factory() const
9183{
9185 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl());
9186}
9187
9188////////////////////////////////////////////////////////////////////////////////
9189
9190MethodInfo_t* TCling::MethodInfo_Factory(ClassInfo_t* clinfo) const
9191{
9193 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
9194}
9195
9196////////////////////////////////////////////////////////////////////////////////
9197
9198MethodInfo_t* TCling::MethodInfo_Factory(DeclId_t declid) const
9199{
9200 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
9202 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), decl);
9203}
9204
9205////////////////////////////////////////////////////////////////////////////////
9206
9207MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
9208{
9209 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
9210}
9211
9212////////////////////////////////////////////////////////////////////////////////
9213
9214void* TCling::MethodInfo_InterfaceMethod(MethodInfo_t* minfo) const
9215{
9216 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9217 // The next call locks the interpreter mutex.
9218 return info->InterfaceMethod();
9219}
9220
9221////////////////////////////////////////////////////////////////////////////////
9222
9223bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
9224{
9225 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9226 return info->IsValid();
9227}
9228
9229////////////////////////////////////////////////////////////////////////////////
9230
9231int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
9232{
9233 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9234 return info->NArg();
9235}
9236
9237////////////////////////////////////////////////////////////////////////////////
9238
9239int TCling::MethodInfo_NDefaultArg(MethodInfo_t* minfo) const
9240{
9241 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9242 return info->NDefaultArg();
9243}
9244
9245////////////////////////////////////////////////////////////////////////////////
9246
9247int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
9248{
9249 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9250 return info->Next();
9251}
9252
9253////////////////////////////////////////////////////////////////////////////////
9254
9255Long_t TCling::MethodInfo_Property(MethodInfo_t* minfo) const
9256{
9257 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9258 // The next call locks the interpreter mutex.
9259 return info->Property();
9260}
9261
9262////////////////////////////////////////////////////////////////////////////////
9263
9265{
9266 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9267 // The next call locks the interpreter mutex.
9268 return info->ExtraProperty();
9269}
9270
9271////////////////////////////////////////////////////////////////////////////////
9272
9273TypeInfo_t* TCling::MethodInfo_Type(MethodInfo_t* minfo) const
9274{
9275 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9276 // The next call locks the interpreter mutex.
9277 return (TypeInfo_t*)info->Type();
9278}
9279
9280////////////////////////////////////////////////////////////////////////////////
9281
9282const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
9283{
9284 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9285 TTHREAD_TLS_DECL(TString, mangled_name);
9286 // The next call locks the interpreter mutex.
9287 mangled_name = info->GetMangledName();
9288 return mangled_name;
9289}
9290
9291////////////////////////////////////////////////////////////////////////////////
9292
9293const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
9294{
9295 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9296 // The next call locks the interpreter mutex.
9297 return info->GetPrototype();
9298}
9299
9300////////////////////////////////////////////////////////////////////////////////
9301
9302const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
9303{
9304 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9305 // The next call locks the interpreter mutex.
9306 return info->Name();
9307}
9308
9309////////////////////////////////////////////////////////////////////////////////
9310
9311const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
9312{
9313 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9314 // The next call locks the interpreter mutex.
9315 return info->TypeName();
9316}
9317
9318////////////////////////////////////////////////////////////////////////////////
9319
9320std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
9321{
9322 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9323 // The next part locks the interpreter mutex.
9324 if (info && info->IsValid())
9325 return info->Type()->NormalizedName(*fNormalizedCtxt);
9326 else
9327 return "";
9328}
9329
9330////////////////////////////////////////////////////////////////////////////////
9331
9332const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
9333{
9334 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9335 // The next call locks the interpreter mutex.
9336 return info->Title();
9337}
9338
9339////////////////////////////////////////////////////////////////////////////////
9340
9342{
9343 if (func) {
9344 return MethodInfo_MethodCallReturnType(func->fInfo);
9345 } else {
9346 return EReturnType::kOther;
9347 }
9348}
9349
9350////////////////////////////////////////////////////////////////////////////////
9351
9353{
9354 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9355 if (info && info->IsValid()) {
9356 TClingTypeInfo *typeinfo = info->Type();
9357 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
9358 if (QT->isEnumeralType()) {
9359 return EReturnType::kLong;
9360 } else if (QT->isPointerType()) {
9361 // Look for char*
9362 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
9363 if ( QT->isCharType() ) {
9364 return EReturnType::kString;
9365 } else {
9366 return EReturnType::kOther;
9367 }
9368 } else if ( QT->isFloatingType() ) {
9369 int sz = typeinfo->Size();
9370 if (sz == 4 || sz == 8) {
9371 // Support only float and double.
9372 return EReturnType::kDouble;
9373 } else {
9374 return EReturnType::kOther;
9375 }
9376 } else if ( QT->isIntegerType() ) {
9377 int sz = typeinfo->Size();
9378 if (sz <= 8) {
9379 // Support only up to long long ... but
9380 // FIXME the TMethodCall::Execute only
9381 // return long (4 bytes) ...
9382 // The v5 implementation of TMethodCall::ReturnType
9383 // was not making the distinction so we let it go
9384 // as is for now, but we really need to upgrade
9385 // TMethodCall::Execute ...
9386 return EReturnType::kLong;
9387 } else {
9388 return EReturnType::kOther;
9389 }
9390 } else {
9391 return EReturnType::kOther;
9392 }
9393 } else {
9394 return EReturnType::kOther;
9395 }
9396}
9397
9398//______________________________________________________________________________
9399//
9400// MethodArgInfo interface
9401//
9402
9403////////////////////////////////////////////////////////////////////////////////
9404
9405void TCling::MethodArgInfo_Delete(MethodArgInfo_t* marginfo) const
9406{
9407 delete(TClingMethodArgInfo*) marginfo;
9408}
9409
9410////////////////////////////////////////////////////////////////////////////////
9411
9412MethodArgInfo_t* TCling::MethodArgInfo_Factory() const
9413{
9415 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl());
9416}
9417
9418////////////////////////////////////////////////////////////////////////////////
9419
9420MethodArgInfo_t* TCling::MethodArgInfo_Factory(MethodInfo_t *minfo) const
9421{
9423 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl(), (TClingMethodInfo*)minfo);
9424}
9425
9426////////////////////////////////////////////////////////////////////////////////
9427
9428MethodArgInfo_t* TCling::MethodArgInfo_FactoryCopy(MethodArgInfo_t* marginfo) const
9429{
9430 return (MethodArgInfo_t*)
9432}
9433
9434////////////////////////////////////////////////////////////////////////////////
9435
9436bool TCling::MethodArgInfo_IsValid(MethodArgInfo_t* marginfo) const
9437{
9438 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9439 return info->IsValid();
9440}
9441
9442////////////////////////////////////////////////////////////////////////////////
9443
9444int TCling::MethodArgInfo_Next(MethodArgInfo_t* marginfo) const
9445{
9446 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9447 return info->Next();
9448}
9449
9450////////////////////////////////////////////////////////////////////////////////
9451
9452Long_t TCling::MethodArgInfo_Property(MethodArgInfo_t* marginfo) const
9453{
9454 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9455 return info->Property();
9456}
9457
9458////////////////////////////////////////////////////////////////////////////////
9459
9460const char* TCling::MethodArgInfo_DefaultValue(MethodArgInfo_t* marginfo) const
9461{
9462 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9463 return info->DefaultValue();
9464}
9465
9466////////////////////////////////////////////////////////////////////////////////
9467
9468const char* TCling::MethodArgInfo_Name(MethodArgInfo_t* marginfo) const
9469{
9470 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9471 return info->Name();
9472}
9473
9474////////////////////////////////////////////////////////////////////////////////
9475
9476const char* TCling::MethodArgInfo_TypeName(MethodArgInfo_t* marginfo) const
9477{
9478 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9479 return info->TypeName();
9480}
9481
9482////////////////////////////////////////////////////////////////////////////////
9483
9484std::string TCling::MethodArgInfo_TypeNormalizedName(MethodArgInfo_t* marginfo) const
9485{
9486 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9487 return info->Type()->NormalizedName(*fNormalizedCtxt);
9488}
9489
9490////////////////////////////////////////////////////////////////////////////////
9491
9492TypeInfo_t* TCling::MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
9493{
9494 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9495 return (TypeInfo_t*) info->Type();
9496}
9497
9498//______________________________________________________________________________
9499//
9500// TypeInfo interface
9501//
9502
9503////////////////////////////////////////////////////////////////////////////////
9504
9505void TCling::TypeInfo_Delete(TypeInfo_t* tinfo) const
9506{
9507 delete (TClingTypeInfo*) tinfo;
9508}
9509
9510////////////////////////////////////////////////////////////////////////////////
9511
9512TypeInfo_t* TCling::TypeInfo_Factory() const
9513{
9515 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl());
9516}
9517
9518////////////////////////////////////////////////////////////////////////////////
9519
9520TypeInfo_t* TCling::TypeInfo_Factory(const char *name) const
9521{
9523 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl(), name);
9524}
9525
9526////////////////////////////////////////////////////////////////////////////////
9527
9528TypeInfo_t* TCling::TypeInfo_FactoryCopy(TypeInfo_t* tinfo) const
9529{
9530 return (TypeInfo_t*) new TClingTypeInfo(*(TClingTypeInfo*)tinfo);
9531}
9532
9533////////////////////////////////////////////////////////////////////////////////
9534
9535void TCling::TypeInfo_Init(TypeInfo_t* tinfo, const char* name) const
9536{
9538 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9539 TClinginfo->Init(name);
9540}
9541
9542////////////////////////////////////////////////////////////////////////////////
9543
9544bool TCling::TypeInfo_IsValid(TypeInfo_t* tinfo) const
9545{
9546 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9547 return TClinginfo->IsValid();
9548}
9549
9550////////////////////////////////////////////////////////////////////////////////
9551
9552const char* TCling::TypeInfo_Name(TypeInfo_t* tinfo) const
9553{
9554 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9555 return TClinginfo->Name();
9556}
9557
9558////////////////////////////////////////////////////////////////////////////////
9559
9560Long_t TCling::TypeInfo_Property(TypeInfo_t* tinfo) const
9561{
9562 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9563 return TClinginfo->Property();
9564}
9565
9566////////////////////////////////////////////////////////////////////////////////
9567
9568int TCling::TypeInfo_RefType(TypeInfo_t* tinfo) const
9569{
9570 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9571 return TClinginfo->RefType();
9572}
9573
9574////////////////////////////////////////////////////////////////////////////////
9575
9576int TCling::TypeInfo_Size(TypeInfo_t* tinfo) const
9577{
9578 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9579 return TClinginfo->Size();
9580}
9581
9582////////////////////////////////////////////////////////////////////////////////
9583
9584const char* TCling::TypeInfo_TrueName(TypeInfo_t* tinfo) const
9585{
9586 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9587 return TClinginfo->TrueName(*fNormalizedCtxt);
9588}
9589
9590////////////////////////////////////////////////////////////////////////////////
9591
9592void* TCling::TypeInfo_QualTypePtr(TypeInfo_t* tinfo) const
9593{
9594 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9595 return TClinginfo->QualTypePtr();
9596}
9597
9598
9599//______________________________________________________________________________
9600//
9601// TypedefInfo interface
9602//
9603
9604////////////////////////////////////////////////////////////////////////////////
9605
9606void TCling::TypedefInfo_Delete(TypedefInfo_t* tinfo) const
9607{
9608 delete(TClingTypedefInfo*) tinfo;
9609}
9610
9611////////////////////////////////////////////////////////////////////////////////
9612
9613TypedefInfo_t* TCling::TypedefInfo_Factory() const
9614{
9616 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl());
9617}
9618
9619////////////////////////////////////////////////////////////////////////////////
9620
9621TypedefInfo_t* TCling::TypedefInfo_Factory(const char *name) const
9622{
9624 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl(), name);
9625}
9626
9627////////////////////////////////////////////////////////////////////////////////
9628
9629TypedefInfo_t* TCling::TypedefInfo_FactoryCopy(TypedefInfo_t* tinfo) const
9630{
9631 return (TypedefInfo_t*) new TClingTypedefInfo(*(TClingTypedefInfo*)tinfo);
9632}
9633
9634////////////////////////////////////////////////////////////////////////////////
9635
9636void TCling::TypedefInfo_Init(TypedefInfo_t* tinfo,
9637 const char* name) const
9638{
9640 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9641 TClinginfo->Init(name);
9642}
9643
9644////////////////////////////////////////////////////////////////////////////////
9645
9646bool TCling::TypedefInfo_IsValid(TypedefInfo_t* tinfo) const
9647{
9648 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9649 return TClinginfo->IsValid();
9650}
9651
9652////////////////////////////////////////////////////////////////////////////////
9653
9654Int_t TCling::TypedefInfo_Next(TypedefInfo_t* tinfo) const
9655{
9656 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9657 return TClinginfo->Next();
9658}
9659
9660////////////////////////////////////////////////////////////////////////////////
9661
9662Long_t TCling::TypedefInfo_Property(TypedefInfo_t* tinfo) const
9663{
9664 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9665 return TClinginfo->Property();
9666}
9667
9668////////////////////////////////////////////////////////////////////////////////
9669
9670int TCling::TypedefInfo_Size(TypedefInfo_t* tinfo) const
9671{
9672 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9673 return TClinginfo->Size();
9674}
9675
9676////////////////////////////////////////////////////////////////////////////////
9677
9678const char* TCling::TypedefInfo_TrueName(TypedefInfo_t* tinfo) const
9679{
9680 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9681 return TClinginfo->TrueName(*fNormalizedCtxt);
9682}
9683
9684////////////////////////////////////////////////////////////////////////////////
9685
9686const char* TCling::TypedefInfo_Name(TypedefInfo_t* tinfo) const
9687{
9688 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9689 return TClinginfo->Name();
9690}
9691
9692////////////////////////////////////////////////////////////////////////////////
9693
9694const char* TCling::TypedefInfo_Title(TypedefInfo_t* tinfo) const
9695{
9696 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9697 return TClinginfo->Title();
9698}
9699
9700////////////////////////////////////////////////////////////////////////////////
9701
9702bool TCling::IsSameType(const void * QualTypePtr1, const void * QualTypePtr2) const
9703{
9704 clang::QualType QT1 = clang::QualType::getFromOpaquePtr(QualTypePtr1);
9705 clang::QualType QT2 = clang::QualType::getFromOpaquePtr(QualTypePtr2);
9706 return fInterpreter->getCI()->getASTContext().hasSameType(QT1, QT2);
9707}
9708
9709////////////////////////////////////////////////////////////////////////////////
9710
9711bool TCling::IsIntegerType(const void * QualTypePtr) const
9712{
9713 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9714 return QT->hasIntegerRepresentation();
9715}
9716
9717////////////////////////////////////////////////////////////////////////////////
9718
9719bool TCling::IsSignedIntegerType(const void * QualTypePtr) const
9720{
9721 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9722 return QT->hasSignedIntegerRepresentation();
9723}
9724
9725////////////////////////////////////////////////////////////////////////////////
9726
9727bool TCling::IsUnsignedIntegerType(const void * QualTypePtr) const
9728{
9729 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9730 return QT->hasUnsignedIntegerRepresentation();
9731}
9732
9733////////////////////////////////////////////////////////////////////////////////
9734
9735bool TCling::IsFloatingType(const void * QualTypePtr) const
9736{
9737 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9738 return QT->hasFloatingRepresentation();
9739}
9740
9741////////////////////////////////////////////////////////////////////////////////
9742
9743bool TCling::IsPointerType(const void * QualTypePtr) const
9744{
9745 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9746 return QT->hasPointerRepresentation();
9747}
9748
9749////////////////////////////////////////////////////////////////////////////////
9750
9751bool TCling::IsVoidPointerType(const void * QualTypePtr) const
9752{
9753 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9754 return QT->isVoidPointerType();
9755}
9756
9757////////////////////////////////////////////////////////////////////////////////
9758
9760{
9761 if (!fInitialMutex) {
9762 if (fInitialMutex.fRecurseCount) {
9763 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
9764 }
9765 fInitialMutex.fState = mtx->GetStateBefore();
9766 }
9767 // We will "forget" this lock once we backed out of all interpreter frames.
9768 // Here we are entering one, so ++.
9769 ++fInitialMutex.fRecurseCount;
9770}
9771
9772////////////////////////////////////////////////////////////////////////////////
9773
9775{
9776 if (!fInitialMutex)
9777 return;
9778 if (fInitialMutex.fRecurseCount == 0) {
9779 Error("ForgetMutexState", "mutex state's recurse count already 0!");
9780 }
9781 else if (--fInitialMutex.fRecurseCount == 0) {
9782 // We have returned from all interpreter frames. Reset the initial lock state.
9783 fInitialMutex.fState.reset();
9784 }
9785}
9786
9787////////////////////////////////////////////////////////////////////////////////
9788/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
9789
9791{
9792 if (gInterpreterMutex) {
9793 if (delta) {
9794 auto typedDelta = static_cast<MutexStateAndRecurseCountDelta *>(delta);
9795 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP{typedDelta};
9796 gCoreMutex->Apply(std::move(typedDelta->fDelta));
9797 // Now that we have the lock, update the global
9798 R__ASSERT(fInitialMutex.fRecurseCount == 0 && "Inconsistent state of fInitialMutex! Another thread within Interpreter critical section.");
9799 std::swap(fInitialMutex, typedDelta->fInitialState);
9800 } else {
9801 // This case happens when EnableThreadSafety is first called from
9802 // the interpreter function we just handled.
9803 // Since thread safety was not enabled at the time we rewound, there was
9804 // no lock taken and even-though we should be locking the rest of this
9805 // interpreter handling/modifying code (since there might be threads in
9806 // flight), we can't because there would not be any lock guard to release the
9807 // locks
9808 if (fInitialMutex || fInitialMutex.fRecurseCount !=0)
9809 Error("ApplyToInterpreterMutex",
9810 "After returning from user code that turned on thread safety support, we notice that fInitialMutex is already used ... "
9811 "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.");
9812 }
9813 }
9814}
9815
9816////////////////////////////////////////////////////////////////////////////////
9817/// Reset the interpreter lock to the state it had before interpreter-related
9818/// calls happened.
9819
9821{
9822 if (fInitialMutex) {
9823 // Need to start a new recurse count.
9824 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP(new MutexStateAndRecurseCountDelta());
9825 std::swap(uniqueP->fInitialState, fInitialMutex);
9826 uniqueP->fDelta = gCoreMutex->Rewind(*uniqueP->fInitialState.fState);
9827 return uniqueP.release();
9828 }
9829 R__ASSERT(fInitialMutex.fRecurseCount == 0);
9830 return nullptr;
9831}
#define R__EXTERN
Definition DllImport.h:26
The file contains utilities which are foundational and could be used across the core component of ROO...
true
Register systematic variations for multiple existing columns using auto-generated tags.
#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
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:77
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 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
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:60
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
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
R__EXTERN TApplication * gApplication
R__EXTERN TClassTable * 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:1334
static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
Definition TCling.cxx:7402
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
TListOfDataMembers & LODM
Definition TCling.cxx:7049
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:4016
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:1996
static Bool_t s_IsLibraryLoaded(const char *libname, cling::Interpreter *fInterpreter)
Definition TCling.cxx:3232
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:4058
static bool R__InitStreamerInfoFactory()
Helper to initialize TVirtualStreamerInfo's factor early.
Definition TCling.cxx:1719
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:4034
void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Definition TCling.cxx:605
return
Invalidate stored TCling state for declarations included in transaction ‘T’.
Definition TCling.cxx:7047
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
TListOfEnums & LOE
Definition TCling.cxx:7052
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
TListOfFunctions & LOF
Definition TCling.cxx:7050
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:8899
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:2496
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:7311
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:2021
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:7146
const char * fantomline
Definition TCling.cxx:858
TListOfFunctionTemplates & LOFT
Definition TCling.cxx:7051
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:6465
static bool requiresRootMap(const char *rootmapfile)
Definition TCling.cxx:5645
clang::NamespaceDecl * TCling__DEBUG__DCtoNamespace(clang::DeclContext *DC)
Definition TCling.cxx:220
if(isa< VarDecl >(D)||isa< FieldDecl >(D)||isa< EnumConstantDecl >(D))
Definition TCling.cxx:7054
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.
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:7423
void TCling__SplitAclicMode(const char *fileName, string &mode, string &args, string &io, string &fname)
Definition TCling.cxx:668
@ 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
#define gDirectory
Definition TDirectory.h:385
@ kEnvUser
Definition TEnv.h:26
@ kEnvGlobal
Definition TEnv.h:25
@ kEnvLocal
Definition TEnv.h:27
#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
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
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
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t cursor
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char cname
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t property
Option_t Option_t TPoint TPoint const char text
char name[80]
Definition TGX11.cxx:148
R__EXTERN TVirtualMutex * gInterpreterMutex
#define R__LOCKGUARD_CLING(mutex)
R__EXTERN TInterpreter * gCling
#define gInterpreter
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:2570
@ kReadPermission
Definition TSystem.h:55
Bool_t R_ISREG(Int_t mode)
Definition TSystem.h:126
R__EXTERN TSystem * gSystem
Definition TSystem.h:582
R__EXTERN TVirtualMutex * 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).
Each class (see TClass) has a linked list of its base class(es).
Definition TBaseClass.h:33
TClassRef is used to implement a permanent reference to a TClass object.
Definition TClassRef.h:29
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
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)
Longptr_t ExecInt(void *address)
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
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:6337
const char * MethodArgInfo_DefaultValue(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9460
bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const final
Definition TCling.cxx:8462
const char * TypeInfo_Name(TypeInfo_t *) const final
Definition TCling.cxx:9552
void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const final
Definition TCling.cxx:9214
void LoadEnums(TListOfEnums &cl) const final
Create list of pointers to enums for TClass cl.
Definition TCling.cxx:4528
void UpdateListOfGlobals() final
No op: see TClingCallbacks (used to update the list of globals)
Definition TCling.cxx:3996
bool TypedefInfo_IsValid(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9646
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE) final
Load library containing the specified class.
Definition TCling.cxx:6398
void CallFunc_Init(CallFunc_t *func) const final
Definition TCling.cxx:8092
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:3759
bool LibraryLoadingFailed(const std::string &, const std::string &, bool, bool)
Definition TCling.cxx:6707
void GenericError(const char *error) const final
Let the interpreter issue a generic error, and set its error state.
Definition TCling.cxx:7607
std::vector< void * > fRegisterModuleDyLibs
Definition TCling.h:140
void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const final
Definition TCling.cxx:8018
bool IsIntegerType(const void *QualTypePtr) const final
Definition TCling.cxx:9711
TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const final
Definition TCling.cxx:9273
std::vector< std::string > fAutoLoadLibStorage
Definition TCling.h:118
void CallFunc_Delete(CallFunc_t *func) const final
Definition TCling.cxx:7995
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:7650
void ResetAll() final
Reset the Cling state to its initial state.
Definition TCling.cxx:3835
void SetDeclAttr(DeclId_t, const char *) final
Definition TCling.cxx:8885
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)
Long_t MethodInfo_Property(MethodInfo_t *minfo) const final
Definition TCling.cxx:9255
void LoadFunctionTemplates(TClass *cl) const final
Create list of pointers to function templates for TClass cl.
Definition TCling.cxx:4575
bool ClassInfo_IsValidMethod(ClassInfo_t *info, const char *method, const char *proto, Longptr_t *offset, ROOT::EFunctionMatchMode=ROOT::kConversionMatch) const final
Definition TCling.cxx:8496
Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8818
int SetClassAutoparsing(int) final
Enable/Disable the Autoparsing of headers.
Definition TCling.cxx:7735
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:4622
void RewindDictionary() final
Rewind Cling dictionary to the point where it was before executing the current macro.
Definition TCling.cxx:3880
bool ClassInfo_IsValid(ClassInfo_t *info) const final
Definition TCling.cxx:8488
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition TCling.cxx:6916
int TypeInfo_RefType(TypeInfo_t *) const final
Definition TCling.cxx:9568
void CreateListOfBaseClasses(TClass *cl) const final
Create list of pointers to base class(es) for TClass cl.
Definition TCling.cxx:4499
ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const final
Definition TCling.cxx:8375
const char * MethodInfo_Name(MethodInfo_t *minfo) const final
Definition TCling.cxx:9302
BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const final
Definition TCling.cxx:8632
Bool_t LoadText(const char *text) const final
Load the declarations from text into the interpreter.
Definition TCling.cxx:7665
const char * GetSharedLibDeps(const char *lib, bool tryDyld=false) final
Get the list a libraries on which the specified lib depends.
Definition TCling.cxx:7439
EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const final
Definition TCling.cxx:9352
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition TCling.cxx:7866
Longptr_t ProcessLineAsynch(const char *line, EErrorCode *error=nullptr)
Let cling process a command line asynch.
Definition TCling.cxx:3671
bool MethodInfo_IsValid(MethodInfo_t *minfo) const final
Definition TCling.cxx:9223
FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8975
TypeInfo_t * TypeInfo_Factory() const final
Definition TCling.cxx:9512
bool IsClassAutoLoadingEnabled() const
Returns if class AutoLoading is currently enabled.
Definition TCling.cxx:7704
void InvalidateGlobal(const clang::Decl *D)
bool IsSameType(const void *QualTypePtr1, const void *QualTypePtr2) const final
Definition TCling.cxx:9702
int Evaluate(const char *, TInterpreterValue &) final
Get the interpreter value corresponding to the statement.
Definition TCling.cxx:7828
std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const final
Definition TCling.cxx:7813
void UpdateListOfLoadedSharedLibraries()
Definition TCling.cxx:3451
const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9694
~TCling() final
Destroy the interpreter interface.
Definition TCling.cxx:1671
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:8217
void InitRootmapFile(const char *name)
Create a resource table and read the (possibly) three resource files, i.e.
Definition TCling.cxx:5788
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:6662
void LoadPCM(std::string pcmFileNameFullPath)
Tries to load a rdict PCM, issues diagnostics if it fails.
Definition TCling.cxx:1868
void UpdateListOfMethods(TClass *cl) const final
Update the list of pointers to method for TClass cl This is now a nop.
Definition TCling.cxx:4640
void AddFriendToClass(clang::FunctionDecl *, clang::CXXRecordDecl *) const
Inject function as a friend into klass.
Definition TCling.cxx:7919
void PrintIntro() final
No-op; see TRint instead.
Definition TCling.cxx:2721
Bool_t fCxxModulesEnabled
Definition TCling.h:130
int BaseClassInfo_Next(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8652
void RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
Internal function. Actually do the update of the ClassInfo when seeing.
Definition TCling.cxx:6774
CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const final
Definition TCling.cxx:8069
Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const final
Definition TCling.cxx:8053
std::set< std::string > fAutoLoadedLibraries
Definition TCling.h:125
void CallFunc_ResetArg(CallFunc_t *func) const final
Definition TCling.cxx:8118
const char * GetCurrentMacroName() const final
Return the file name of the currently interpreted file, included or not.
Definition TCling.cxx:5596
Bool_t IsLoaded(const char *filename) const final
Return true if the file has already been loaded by cint.
Definition TCling.cxx:3275
void SaveGlobalsContext() final
Save the current Cling state of global objects.
Definition TCling.cxx:3983
void CallFunc_IgnoreExtraArgs(CallFunc_t *func, bool ignore) const final
Definition TCling.cxx:8084
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:9790
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition TCling.cxx:6730
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:4856
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:8291
Bool_t IsLibraryLoaded(const char *libname) const final
Definition TCling.cxx:3241
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:7629
int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8744
DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8778
Bool_t HandleNewTransaction(const cling::Transaction &T)
Helper function to increase the internal Cling count of transactions that change the AST.
Definition TCling.cxx:3776
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:5661
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition TCling.h:155
int ClassInfo_Next(ClassInfo_t *info) const final
Definition TCling.cxx:8512
void SetErrmsgcallback(void *p) const final
Set a callback to receive error messages.
Definition TCling.cxx:7756
bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9436
int TypeInfo_Size(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9576
Int_t DeleteGlobal(void *obj) final
Delete obj from Cling symbol table so it cannot be accessed anymore.
Definition TCling.cxx:3894
int GetSecurityError() const final
Interface to cling function.
Definition TCling.cxx:7637
TCling(const char *name, const char *title, const char *const argv[], void *interpLibHandle)
Initialize the cling interpreter interface.
Definition TCling.cxx:1373
void SetTempLevel(int val) const final
Create / close a scope for temporaries.
Definition TCling.cxx:7792
void Print(Option_t *option="") const final
Print information about the interpreter.
Definition TCling.cxx:2731
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:9009
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:5288
TypedefInfo_t * TypedefInfo_Factory() const final
Definition TCling.cxx:9613
TObjArray * fRootmapFiles
Definition TCling.h:128
Longptr_t ProcessLine(const char *line, EErrorCode *error=nullptr) final
Definition TCling.cxx:2526
int ClassInfo_Size(ClassInfo_t *info) const final
Definition TCling.cxx:8560
const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9476
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:5536
std::vector< std::pair< TClass *, DictFuncPtr_t > > fClassesToUpdate
Definition TCling.h:148
int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8802
const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9686
void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8625
Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const final
Definition TCling.cxx:9264
void LoadMacro(const char *filename, EErrorCode *error=nullptr) final
Load a macro file in cling's memory.
Definition TCling.cxx:3663
FuncTempInfo_t * FuncTempInfo_FactoryCopy(FuncTempInfo_t *) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8986
int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const final
Definition TCling.cxx:8794
Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const final
Check validity of a FuncTempInfo_t.
Definition TCling.cxx:8997
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:2763
bool ClassInfo_IsBase(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8447
void RecursiveRemove(TObject *obj) final
Delete object from cling symbol table so it can not be used anymore.
Definition TCling.cxx:3794
const char * DataMemberInfo_TypeName(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8842
DeclId_t GetDataMemberAtAddr(const void *addr) const final
Return pointer to cling DeclId for a data member with a given name.
Definition TCling.cxx:5083
void CallFunc_SetArgArray(CallFunc_t *func, Longptr_t *paramArr, Int_t nparam) const final
Definition TCling.cxx:8174
std::string CallFunc_GetWrapperCode(CallFunc_t *func) const final
Definition TCling.cxx:8264
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:9820
const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9468
Bool_t HasPCMForLibrary(const char *libname) const final
Return true if ROOT has cxxmodules pcm for a given library name.
Definition TCling.cxx:3250
void TypedefInfo_Init(TypedefInfo_t *tinfo, const char *name) const final
Definition TCling.cxx:9636
const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8866
Longptr_t CallFunc_ExecInt(CallFunc_t *func, void *address) const final
Definition TCling.cxx:8037
void ClearStack() final
Delete existing temporary values.
Definition TCling.cxx:3188
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:7686
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:7506
MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const final
Definition TCling.cxx:8076
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:3517
TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9629
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:5181
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:2466
std::string MethodArgInfo_TypeNormalizedName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9484
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:4965
Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9452
int TypedefInfo_Size(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9670
void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:8026
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:5333
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:6896
Int_t Load(const char *filenam, Bool_t system=kFALSE) final
Load a library file in cling's memory.
Definition TCling.cxx:3626
int TypedefInfo_Next(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9654
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:5140
void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const final
Definition TCling.cxx:9535
Bool_t SetSuspendAutoParsing(Bool_t value) final
Suspend the Autoparsing of headers.
Definition TCling.cxx:7746
int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8834
static void * fgSetOfSpecials
Definition TCling.h:105
const char * ClassInfo_Title(ClassInfo_t *info) const final
Definition TCling.cxx:8602
const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8858
const char * TypeName(const char *typeDesc) final
Return the absolute type of typeDesc.
Definition TCling.cxx:5611
ROOT::TMetaUtils::TNormalizedCtxt * fNormalizedCtxt
Definition TCling.h:136
void ForgetMutexState() final
Definition TCling.cxx:9774
int MethodInfo_Next(MethodInfo_t *minfo) const final
Definition TCling.cxx:9247
Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const final
Definition TCling.cxx:8336
void MethodInfo_Delete(MethodInfo_t *minfo) const final
Interface to cling function.
Definition TCling.cxx:9166
bool fIsShuttingDown
Definition TCling.h:189
void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9405
bool IsSignedIntegerType(const void *QualTypePtr) const final
Definition TCling.cxx:9719
DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo, TDictionary::EMemberSelection selection) const final
Definition TCling.cxx:8759
void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const final
Definition TCling.cxx:8367
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:6243
Int_t UnloadAllSharedLibraryMaps() final
Unload the library map entries coming from all the loaded shared libraries.
Definition TCling.cxx:6131
void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const final
Definition TCling.cxx:8429
std::set< TClass * > & GetModTClasses()
Definition TCling.h:585
ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const final
Definition TCling.cxx:8697
TClingCallbacks * fClingCallbacks
Definition TCling.h:141
Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const final
Definition TCling.cxx:8045
Long_t ClassInfo_Property(ClassInfo_t *info) const final
Definition TCling.cxx:8552
Longptr_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8676
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:5518
Bool_t IsErrorMessagesEnabled() const final
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition TCling.cxx:7492
TString fIncludePath
Definition TCling.h:115
int DisplayIncludePath(FILE *fout) const final
Interface to cling function.
Definition TCling.cxx:7569
void TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:7101
Long_t FuncTempInfo_Property(FuncTempInfo_t *) const final
Return the property of the function template.
Definition TCling.cxx:9030
TEnum * CreateEnum(void *VD, TClass *cl) const final
Definition TCling.cxx:486
const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9584
Int_t UnloadLibraryMap(const char *library) final
Unload library map entries coming from the specified library.
Definition TCling.cxx:6149
void RegisterTemporary(const TInterpreterValue &value)
Definition TCling.cxx:7839
MutexStateAndRecurseCount fInitialMutex
Definition TCling.h:176
const char * GetSharedLibs() final
Return the list of shared libraries loaded into the process.
Definition TCling.cxx:7139
int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9444
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx) final
Definition TCling.cxx:9759
Long_t TypeInfo_Property(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9560
const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const final
Definition TCling.cxx:9293
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:9020
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.
Definition TCling.cxx:2068
static Int_t ShallowAutoLoadImpl(const char *cls)
Definition TCling.cxx:6289
void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const final
Definition TCling.cxx:9173
Bool_t CheckClassTemplate(const char *name) final
Return true if there is a class template by the given name ...
Definition TCling.cxx:4477
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:7124
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:2457
bool IsVoidPointerType(const void *QualTypePtr) const final
Definition TCling.cxx:9751
TObjArray * GetRootMapFiles() const final
Definition TCling.h:226
bool DataMemberInfo_IsValid(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8786
bool ClassInfo_IsEnum(const char *name) const final
Definition TCling.cxx:8455
int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9239
bool IsFloatingType(const void *QualTypePtr) const final
Definition TCling.cxx:9735
void CreateListOfMethods(TClass *cl) const final
Create list of pointers to methods for TClass cl.
Definition TCling.cxx:4631
Int_t RescanLibraryMap() final
Scan again along the dynamic path for library maps.
Definition TCling.cxx:6058
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:7765
const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9282
TypeInfo_t * MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9492
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:5243
void * ClassInfo_New(ClassInfo_t *info) const final
Definition TCling.cxx:8520
int DisplayClass(FILE *fout, const char *name, int base, int start) const final
Definition TCling.cxx:7560
void GetFunctionName(const clang::Decl *decl, std::string &name) const
Definition TCling.cxx:8921
void CreateListOfMethodArgs(TFunction *m) const final
Create list of pointers to method arguments for TMethod m.
Definition TCling.cxx:4656
const char * GetSTLIncludePath() const final
Return the directory containing CINT's stl cintdlls.
Definition TCling.cxx:7551
MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9428
Longptr_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8668
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:4305
void * FindSym(const char *entry) const final
Interface to cling function.
Definition TCling.cxx:7598
void RegisterLoadedSharedLibrary(const char *name)
Register a new shared library name with the interpreter; add it to fSharedLibs.
Definition TCling.cxx:3526
void TypeInfo_Delete(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9505
int MethodInfo_NArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9231
DeclId_t GetDataMemberWithValue(const void *ptrvalue) const final
NOT IMPLEMENTED.
Definition TCling.cxx:5074
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition TCling.h:127
EReturnType MethodCallReturnType(TFunction *func) const final
Definition TCling.cxx:9341
void ProcessClassesToUpdate()
Definition TCling.cxx:2037
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:5266
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:5095
const char * MethodInfo_Title(MethodInfo_t *minfo) const final
Definition TCling.cxx:9332
TString fRootmapLoadPath
Definition TCling.h:116
const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8731
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:3201
const char * BaseClassInfo_FullName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8713
void CallFunc_SetArgs(CallFunc_t *func, const char *param) const final
Definition TCling.cxx:8182
int UnloadFile(const char *path) const final
Definition TCling.cxx:7798
void SetClassInfo(TClass *cl, Bool_t reload=kFALSE, Bool_t silent=kFALSE) final
Set pointer to the TClingClassInfo in TClass.
Definition TCling.cxx:4169
void CallFunc_Exec(CallFunc_t *func, void *address) const final
Definition TCling.cxx:8002
Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const final
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition TCling.cxx:9095
bool CallFunc_IsValid(CallFunc_t *func) const final
Definition TCling.cxx:8101
const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8723
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition TCling.h:137
const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8874
Int_t GetMore() const final
Return whether we are waiting for more input either because the collected input contains unbalanced b...
Definition TCling.cxx:4677
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:5005
void Execute(const char *function, const char *params, int *error=nullptr) final
Execute a global function with arguments params.
Definition TCling.cxx:5366
bool ClassInfo_IsLoaded(ClassInfo_t *info) const final
Definition TCling.cxx:8480
Longptr_t ClassInfo_Tagnum(ClassInfo_t *info) const final
Definition TCling.cxx:8568
Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8689
void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Longptr_t *Offset) const final
Definition TCling.cxx:8190
std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const final
Get the scopes representing using declarations of namespace.
Definition TCling.cxx:4611
const char * ClassInfo_FileName(ClassInfo_t *info) const final
Definition TCling.cxx:8576
void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const final
Return the comments associates with this function template.
Definition TCling.cxx:9134
const char * ClassInfo_TmpltName(ClassInfo_t *info) const final
Definition TCling.cxx:8610
void SaveContext() final
Save the current Cling state.
Definition TCling.cxx:3970
void LoadPCMImpl(TFile &pcmFile)
Tries to load a PCM from TFile; returns true on success.
Definition TCling.cxx:1752
Bool_t IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:6766
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:3851
void CodeComplete(const std::string &, size_t &, std::vector< std::string > &) final
The call to Cling's tab complition.
Definition TCling.cxx:7820
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:3865
const char * MapCppName(const char *) const final
Interface to cling function.
Definition TCling.cxx:7673
Longptr_t Calc(const char *line, EErrorCode *error=nullptr) final
Directly execute an executable statement (e.g.
Definition TCling.cxx:3696
Int_t ReloadAllSharedLibraryMaps() final
Reload the library map entries coming from all the loaded shared libraries, after first unloading the...
Definition TCling.cxx:6070
void UpdateListOfGlobalFunctions() final
No op: see TClingCallbacks (used to update the list of global functions)
Definition TCling.cxx:4003
void DataMemberInfo_Delete(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8752
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:5549
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:4649
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:2785
Int_t SetClassSharedLibs(const char *cls, const char *libs) final
Register the AutoLoading information for a class.
Definition TCling.cxx:6211
MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const final
Definition TCling.cxx:9207
std::set< const char * > fParsedPayloadsAddresses
Definition TCling.h:123
CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const final
Definition TCling.cxx:8110
MethodArgInfo_t * MethodArgInfo_Factory() const final
Definition TCling.cxx:9412
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition TCling.cxx:6890
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:5162
void ClassInfo_Delete(ClassInfo_t *info) const final
Definition TCling.cxx:8344
std::unique_ptr< cling::Interpreter > fInterpreter
Definition TCling.h:132
EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const final
Definition TCling.cxx:8471
void FuncTempInfo_Delete(FuncTempInfo_t *) const final
Delete the FuncTempInfo_t.
Definition TCling.cxx:8966
bool IsUnsignedIntegerType(const void *QualTypePtr) const final
Definition TCling.cxx:9727
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:5310
Int_t DeleteVariable(const char *name) final
Undeclare obj called name.
Definition TCling.cxx:3909
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:7245
Longptr_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8810
CallFunc_t * CallFunc_Factory() const final
Definition TCling.cxx:8061
MethodInfo_t * MethodInfo_Factory() const final
Definition TCling.cxx:9182
Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8826
void ClearFileBusy() final
Reset the interpreter internal state in case a previous action was not correctly terminated.
Definition TCling.cxx:3180
cling::MetaProcessor * GetMetaProcessorImpl() const
Definition TCling.h:651
bool DiagnoseIfInterpreterException(const std::exception &e) const final
Definition TCling.cxx:2515
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:7696
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:3171
void AddAvailableIndentifiers(TSeqCollection &Idents) final
Definition TCling.cxx:2431
void TypedefInfo_Delete(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9606
void Reset() final
Pressing Ctrl+C should forward here.
Definition TCling.cxx:3819
const char * TypedefInfo_TrueName(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9678
int SetClassAutoLoading(int) const final
Enable/Disable the AutoLoading of libraries.
Definition TCling.cxx:7717
const char * ClassInfo_FullName(ClassInfo_t *info) const final
Definition TCling.cxx:8584
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:6514
const char * MethodInfo_TypeName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9311
void CallFunc_SetArg(CallFunc_t *func, Long_t param) const final
Definition TCling.cxx:8126
const char * GetIncludePath() final
Refresh the list of include paths known to the interpreter and return it with -I prepended.
Definition TCling.cxx:7520
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:6832
void Initialize() final
Initialize the interpreter, once TROOT::fInterpreter is set.
Definition TCling.cxx:1689
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:8405
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:4904
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:9121
std::unique_ptr< cling::MetaProcessor > fMetaProcessor
Definition TCling.h:133
bool TypeInfo_IsValid(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9544
bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const final
Definition TCling.cxx:1963
std::string MethodInfo_TypeNormalizedName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9320
const char * ClassInfo_Name(ClassInfo_t *info) const final
Definition TCling.cxx:8594
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE) final
Generate a TClass for the given class.
Definition TCling.cxx:4687
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:8413
void EndOfLineAction() final
It calls a "fantom" method to synchronize user keyboard input and ROOT prompt line.
Definition TCling.cxx:3224
TypeInfo_t * TypeInfo_FactoryCopy(TypeInfo_t *) const final
Definition TCling.cxx:9528
size_t ClassInfo_AlignOf(ClassInfo_t *info) const final
Definition TCling.cxx:8280
bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8421
void ClassInfo_DeleteArray(ClassInfo_t *info, void *arena, bool dtorOnly) const final
Definition TCling.cxx:8359
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:8850
void ShutDown() final
Definition TCling.cxx:1710
void UpdateListOfTypes() final
No op: see TClingCallbacks (used to update the list of types)
Definition TCling.cxx:4010
void * TypeInfo_QualTypePtr(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9592
Long_t TypedefInfo_Property(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9662
void RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Register Rdict data for future loading by LoadPCM;.
Definition TCling.cxx:1733
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:3680
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:5122
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition TCling.cxx:6905
Int_t LoadLibraryMap(const char *rootmapfile=nullptr) final
Load map between class and library.
Definition TCling.cxx:5874
Longptr_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8705
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:7131
bool IsPointerType(const void *QualTypePtr) const final
Definition TCling.cxx:9743
Collection abstract base class.
Definition TCollection.h:65
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
TDirectory::TContext keeps track and restore the current directory.
Definition TDirectory.h:89
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:41
const char * GetValue() const
Definition TEnv.h:65
const char * GetName() const override
Returns name of object.
Definition TEnv.h:64
The TEnv class reads config files, by default named .rootrc.
Definition TEnv.h:79
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
void Clear(Option_t *option="") override
Remove all objects from the list.
THashTable implements a hash table to store TObject's.
Definition THashTable.h:35
This class defines an abstract interface to a generic command line interpreter.
int(* AutoLoadCallBack_t)(const char *)
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...
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
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
A TMemFile is like a normal TFile except that it reads and writes only from memory.
Definition TMemFile.h:27
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
Collectable string class.
Definition TObjString.h:28
TString & String()
Definition TObjString.h:48
Mother of all ROOT objects.
Definition TObject.h:42
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:204
R__ALWAYS_INLINE 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
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:427
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2324
void Clear()
Clear string without changing its capacity.
Definition TString.cxx:1241
const char * Data() const
Definition TString.h:386
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:715
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:2344
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:634
TString & Prepend(const char *cs)
Definition TString.h:684
Bool_t IsNull() const
Definition TString.h:424
TString & Remove(Ssiz_t pos)
Definition TString.h:696
TString & Append(const char *cs)
Definition TString.h:583
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:2459
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:643
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:662
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
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 I(x, y, z)
const std::string & GetPathSeparator()
const char & GetEnvPathSeparator()
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.
R__EXTERN TVirtualRWMutex * gCoreMutex
EFunctionMatchMode
@ kExactMatch
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
constexpr Double_t E()
Base of natural log: .
Definition TMath.h:96
#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
std::vector< std::string > fElements
Definition TClassEdit.h:143
void ShortType(std::string &answer, int mode)
Return the absolute type of typeDesc into the string answ.
A read-only memory range which we do not control.
Definition TMemFile.h:33
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4