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 "TClingUtils.h"
69#include "TListOfDataMembers.h"
70#include "TListOfEnums.h"
72#include "TListOfFunctions.h"
74#include "TMemFile.h"
75#include "TProtoClass.h"
76#include "TStreamerInfo.h" // This is here to avoid to use the plugin manager
77#include "ThreadLocalStorage.h"
78#include "TFile.h"
79#include "TKey.h"
80#include "ClingRAII.h"
81
82#include "clang/AST/ASTContext.h"
83#include "clang/AST/Decl.h"
84#include "clang/AST/DeclarationName.h"
85#include "clang/AST/GlobalDecl.h"
86#include "clang/AST/RecordLayout.h"
87#include "clang/AST/DeclVisitor.h"
88#include "clang/AST/RecursiveASTVisitor.h"
89#include "clang/AST/Type.h"
90#include "clang/Basic/SourceLocation.h"
91#include "clang/Basic/Specifiers.h"
92#include "clang/Basic/TargetInfo.h"
93#include "clang/CodeGen/ModuleBuilder.h"
94#include "clang/Frontend/CompilerInstance.h"
95#include "clang/Frontend/FrontendDiagnostic.h"
96#include "clang/Lex/HeaderSearch.h"
97#include "clang/Lex/Preprocessor.h"
98#include "clang/Lex/PreprocessorOptions.h"
99#include "clang/Parse/Parser.h"
100#include "clang/Sema/Lookup.h"
101#include "clang/Sema/Sema.h"
102#include "clang/Serialization/ASTReader.h"
103#include "clang/Serialization/GlobalModuleIndex.h"
104
105#include "cling/Interpreter/ClangInternalState.h"
106#include "cling/Interpreter/DynamicLibraryManager.h"
107#include "cling/Interpreter/Interpreter.h"
108#include "cling/Interpreter/LookupHelper.h"
109#include "cling/Interpreter/Value.h"
110#include "cling/Interpreter/Transaction.h"
111#include "cling/MetaProcessor/MetaProcessor.h"
112#include "cling/Utils/AST.h"
113#include "cling/Utils/ParserStateRAII.h"
114#include "cling/Utils/SourceNormalization.h"
115#include "cling/Interpreter/Exception.h"
116
117#include <CppInterOp/CppInterOp.h>
118
119#include "llvm/IR/GlobalValue.h"
120#include "llvm/IR/Module.h"
121
122#include "llvm/Support/DynamicLibrary.h"
123#include "llvm/Support/raw_ostream.h"
124#include "llvm/Support/Path.h"
125#include "llvm/Support/Process.h"
126#include "llvm/Object/ELFObjectFile.h"
127#include "llvm/Object/ObjectFile.h"
128#include "llvm/Object/SymbolicFile.h"
129#include "llvm/Support/FileSystem.h"
130
131#include <algorithm>
132#include <iostream>
133#include <cassert>
134#include <map>
135#include <set>
136#include <stdexcept>
137#include <cstdint>
138#include <cstdio>
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" {
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"
345
346////////////////////////////////////////////////////////////////////////////////
347/// Load a library.
348
349extern "C" int TCling__LoadLibrary(const char *library)
350{
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) {
389 }
390 return nullptr;
391}
392
393////////////////////////////////////////////////////////////////////////////////
394/// Unlock the interpreter.
395
397{
398 if (gInterpreterMutex) {
400 }
401}
402
403////////////////////////////////////////////////////////////////////////////////
404/// Update TClingClassInfo for a class (e.g. upon seeing a definition).
405
407{
408 static Bool_t entered = kFALSE;
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
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);
469 if (TObject* encAsTObj = enumObj->GetConstants()->FindObject(constantName)){
470 ((TEnumConstant*)encAsTObj)->Update(dmInfo);
471 } else {
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
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);
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
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);
653}
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);
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());
777 while (dirbase.Length() && dirbase != "."
778 && dirbase != "include" && dirbase != "inc"
779 && dirbase != "prec_stl") {
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
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());
824 }
825 //(3) checking if we can compile a macro, if not then cleaning
827 gErrorIgnoreLevel = kWarning; // no "Info: creating library..."
828 Int_t ret = gSystem->CompileMacro(fileName, "k");
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);
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
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
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)
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
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
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());
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)
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)
1110
1111 return !ModuleFileName.empty();
1112}
1113
1114static bool HaveFullGlobalModuleIndex = false;
1116{
1117 CompilerInstance &CI = *interp.getCI();
1118 Preprocessor &PP = CI.getPreprocessor();
1119 auto ModuleManager = CI.getASTReader();
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.
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.
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) {
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 }
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();
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(),
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
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"};
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
1272
1273 GlobalModuleIndex *GlobalIndex = nullptr;
1274
1275 bool useGMI = true;
1276 std::optional<std::string> envUseGMI = llvm::sys::Process::GetEnv("ROOT_USE_GMI");
1277 if (envUseGMI.has_value())
1279 useGMI = false;
1280
1281 if (useGMI) {
1283 // FIXME: The ASTReader still calls loadGlobalIndex and loads the file
1284 // We should investigate how to suppress it completely.
1285 GlobalIndex = CI.getASTReader()->getGlobalIndex();
1286 }
1287
1288 llvm::StringSet<> KnownModuleFileNames;
1289 if (GlobalIndex)
1290 GlobalIndex->getKnownModuleFileNames(KnownModuleFileNames);
1291
1292 std::vector<std::string> PendingModules;
1293 PendingModules.reserve(256);
1294 for (auto I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1295 clang::Module *M = I->second;
1296 assert(M);
1297
1298 // We want to load only already created modules.
1299 std::string FullASTFilePath;
1301 continue;
1302
1304 continue;
1305
1306 if (M->IsUnimportable)
1307 continue;
1308
1309 if (GlobalIndex)
1310 LoadModule(M->Name, clingInterp);
1311 else {
1312 // FIXME: We may be able to remove those checks as cling::loadModule
1313 // checks if a module was alredy loaded.
1314 if (std::find(CoreModules.begin(), CoreModules.end(), M->Name) != CoreModules.end())
1315 continue; // This is a core module which was already loaded.
1316
1317 // Load system modules now and delay the other modules after we have
1318 // loaded all system ones.
1319 if (M->IsSystem)
1320 LoadModule(M->Name, clingInterp);
1321 else
1322 PendingModules.push_back(M->Name);
1323 }
1324 }
1326 }
1327
1328 // Check that the gROOT macro was exported by any core module.
1329 assert(clingInterp.getMacro("gROOT") && "Couldn't load gROOT macro?");
1330
1331 // `ERROR` and `PI` are from loading R related modules, which conflict with
1332 // user's code.
1333 clingInterp.declare(R"CODE(
1334#ifdef PI
1335# undef PI
1336#endif
1337#ifdef ERROR
1338# undef ERROR
1339#endif
1340 )CODE");
1341}
1342
1343static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
1344{
1345 std::string PreIncludes;
1346 bool hasCxxModules = clingInterp.getCI()->getLangOpts().Modules;
1347
1348 // For the list to also include string, we have to include it now.
1349 // rootcling does parts already if needed, e.g. genreflex does not want using
1350 // namespace std.
1351 if (IsFromRootCling()) {
1352 PreIncludes += "#include \"RtypesCore.h\"\n";
1353 } else {
1354 if (!hasCxxModules)
1355 PreIncludes += "#include \"Rtypes.h\"\n";
1356
1358 + gInterpreterClassDef + "\n"
1359 "#undef ClassImp\n" // bw compatibility
1360 "#define ClassImp(X);\n"; // bw compatibility
1361 }
1362 if (!hasCxxModules)
1363 PreIncludes += "#include <string>\n";
1364
1365 // We must include it even when we have modules because it is marked as
1366 // textual in the modulemap due to the nature of the assert header.
1367#ifndef R__WIN32
1368 PreIncludes += "#include <cassert>\n";
1369#endif
1370 PreIncludes += "using namespace std;\n";
1371 clingInterp.declare(PreIncludes);
1372}
1373
1374////////////////////////////////////////////////////////////////////////////////
1375/// Initialize the cling interpreter interface.
1376/// \param name name for TInterpreter
1377/// \param title title for TInterpreter
1378/// \param argv - array of arguments passed to the cling::Interpreter constructor
1379/// e.g. `-DFOO=bar`. The last element of the array must be `nullptr`.
1380/// \param interpLibHandle handle to interpreter library
1381
1382TCling::TCling(const char *name, const char *title, const char* const argv[], void *interpLibHandle)
1383: TInterpreter(name, title), fGlobalsListSerial(-1), fMapfile(nullptr),
1384 fRootmapFiles(nullptr), fLockProcessLine(true), fNormalizedCtxt(nullptr), fLookupHelper(nullptr),
1385 fPrevLoadedDynLibInfo(nullptr), fClingCallbacks(nullptr), fAutoLoadCallBack(nullptr),
1387{
1388 fPrompt[0] = 0;
1389 const bool fromRootCling = IsFromRootCling();
1390
1391 fCxxModulesEnabled = false;
1392#ifdef R__USE_CXXMODULES
1393 fCxxModulesEnabled = true;
1394#endif
1395
1396 llvm::install_fatal_error_handler(&exceptionErrorHandler);
1397
1398 fTemporaries = new std::vector<cling::Value>();
1399
1400 std::vector<std::string> clingArgsStorage;
1401 clingArgsStorage.push_back("cling4root");
1402 for (const char* const* arg = argv; *arg; ++arg)
1403 clingArgsStorage.push_back(*arg);
1404
1405 // rootcling sets its arguments through TROOT::GetExtraInterpreterArgs().
1406 if (!fromRootCling) {
1408
1409 // Add -I early so ASTReader can find the headers.
1410 std::string interpInclude(TROOT::GetEtcDir().Data());
1411 clingArgsStorage.push_back("-I" + interpInclude);
1412
1413 // Add include path to etc/cling.
1414 clingArgsStorage.push_back("-I" + interpInclude + "/cling");
1415
1416 // Add include path to etc/cling.
1417 clingArgsStorage.push_back("-I" + interpInclude + "/cling/plugins/include");
1418
1419 // Add the root include directory and etc/ to list searched by default.
1420 clingArgsStorage.push_back(std::string(("-I" + TROOT::GetIncludeDir()).Data()));
1421
1422 // Add the current path to the include path
1423 // TCling::AddIncludePath(".");
1424
1425 // Attach the PCH (unless we have C++ modules enabled which provide the
1426 // same functionality).
1427 if (!fCxxModulesEnabled) {
1428 std::string pchFilename = interpInclude + "/allDict.cxx.pch";
1429 if (gSystem->Getenv("ROOT_PCH")) {
1430 pchFilename = gSystem->Getenv("ROOT_PCH");
1431 }
1432
1433 clingArgsStorage.push_back("-include-pch");
1434 clingArgsStorage.push_back(pchFilename);
1435 }
1436
1437 clingArgsStorage.push_back("-Wno-undefined-inline");
1438 clingArgsStorage.push_back("-fsigned-char");
1439 clingArgsStorage.push_back("-fsized-deallocation");
1440 // The -O1 optimization flag has nasty side effects on Windows (32 and 64 bit)
1441 // See the GitHub issues #9809 and #9944
1442 // TODO: to be reviewed after the upgrade of LLVM & Clang
1443#ifndef _MSC_VER
1444 clingArgsStorage.push_back("-O1");
1445 // Disable optimized register allocation which is turned on automatically
1446 // by -O1, but seems to require -O2 to not explode in run time.
1447 clingArgsStorage.push_back("-mllvm");
1448 clingArgsStorage.push_back("-optimize-regalloc=0");
1449#endif
1450
1451#ifdef CLING_WITH_ADAPTIVECPP
1452 std::string acppInclude(TROOT::GetIncludeDir() + "/AdaptiveCpp");
1453
1454 clingArgsStorage.push_back("-isystem");
1455 clingArgsStorage.push_back(acppInclude);
1456 clingArgsStorage.push_back("-mllvm");
1457 clingArgsStorage.push_back("-acpp-sscp");
1458#endif
1459 }
1460
1461 // Process externally passed arguments if present.
1462 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv("EXTRA_CLING_ARGS");
1463 if (EnvOpt.has_value()) {
1465 while (!Env.empty()) {
1466 StringRef Arg;
1467 std::tie(Arg, Env) = Env.split(' ');
1468 clingArgsStorage.push_back(Arg.str());
1469 }
1470 }
1471
1472 auto GetEnvVarPath = [](const std::string &EnvVar, std::vector<std::string> &Paths) {
1473 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv(EnvVar);
1474 if (EnvOpt.has_value()) {
1476 while (!Env.empty()) {
1477 StringRef Arg;
1478 std::tie(Arg, Env) = Env.split(ROOT::FoundationUtils::GetEnvPathSeparator());
1479 if (std::find(Paths.begin(), Paths.end(), Arg.str()) == Paths.end())
1480 Paths.push_back(Arg.str());
1481 }
1482 }
1483 };
1484
1485 if (fCxxModulesEnabled) {
1486 std::vector<std::string> Paths;
1487 // ROOT usually knows better where its libraries are. This way we can
1488 // discover modules without having to should thisroot.sh and should fix
1489 // gnuinstall.
1490 Paths.push_back(TROOT::GetSharedLibDir().Data());
1491 GetEnvVarPath("CLING_PREBUILT_MODULE_PATH", Paths);
1492 std::string EnvVarPath;
1493 for (const std::string& P : Paths)
1495 // FIXME: We should make cling -fprebuilt-module-path work.
1496 gSystem->Setenv("CLING_PREBUILT_MODULE_PATH", EnvVarPath.c_str());
1497 }
1498
1499 // FIXME: This only will enable frontend timing reports.
1500 EnvOpt = llvm::sys::Process::GetEnv("ROOT_CLING_TIMING");
1501 if (EnvOpt.has_value())
1502 clingArgsStorage.push_back("-ftime-report");
1503
1504 // Add the overlay file. Note that we cannot factor it out for both root
1505 // and rootcling because rootcling activates modules only if -cxxmodule
1506 // flag is passed.
1508 // For now we prefer rootcling to enumerate explicitly its modulemaps.
1509 std::vector<std::string> ModuleMaps;
1510 std::string ModuleMapSuffix = ROOT::FoundationUtils::GetPathSeparator() + "ROOT.modulemap";
1511 ModuleMaps.push_back(TROOT::GetIncludeDir().Data() + ModuleMapSuffix);
1512 GetEnvVarPath("CLING_MODULEMAP_FILES", ModuleMaps);
1513
1514 std::string cwd = gSystem->WorkingDirectory();
1515 // Give highest precedence of the modulemap in the cwd if any.
1516 if (llvm::sys::fs::exists(cwd + ModuleMapSuffix))
1517 ModuleMaps.push_back(cwd + ModuleMapSuffix);
1518
1519 for (const std::string& M : ModuleMaps)
1520 clingArgsStorage.push_back("-fmodule-map-file=" + M);
1521
1522 std::string ModulesCachePath;
1523 EnvOpt = llvm::sys::Process::GetEnv("CLING_MODULES_CACHE_PATH");
1524 if (EnvOpt.has_value()){
1526 assert(llvm::sys::fs::exists(Env) && "Path does not exist!");
1527 ModulesCachePath = Env.str();
1528 } else {
1530 }
1531
1532 clingArgsStorage.push_back("-fmodules-cache-path=" + ModulesCachePath);
1533 }
1534
1535 std::vector<const char*> interpArgs;
1536 for (std::vector<std::string>::const_iterator iArg = clingArgsStorage.begin(),
1538 interpArgs.push_back(iArg->c_str());
1539
1540 // Activate C++ modules support. If we are running within rootcling, it's up
1541 // to rootcling to set this flag depending on whether it wants to produce
1542 // C++ modules.
1544 if (fCxxModulesEnabled) {
1545 if (!fromRootCling) {
1546 // We only set this flag, rest is done by the CIFactory.
1547 interpArgs.push_back("-fmodules");
1548 interpArgs.push_back("-fno-implicit-module-maps");
1549 // We should never build modules during runtime, so let's enable the
1550 // module build remarks from clang to make it easier to spot when we do
1551 // this by accident.
1552 interpArgs.push_back("-Rmodule-build");
1553 }
1554 // ROOT implements its AutoLoading upon module's link directives. We
1555 // generate module A { header "A.h" link "A.so" export * } where ROOT's
1556 // facilities use the link directive to dynamically load the relevant
1557 // library. So, we need to suppress clang's default autolink behavior.
1558 interpArgs.push_back("-fno-autolink");
1559 }
1560
1561#ifdef R__FAST_MATH
1562 // Same setting as in rootcling_impl.cxx.
1563 interpArgs.push_back("-ffast-math");
1564#endif
1565
1567 // Add statically injected extra arguments, usually coming from rootcling.
1568 for (const char** extraArgs = TROOT::GetExtraInterpreterArgs();
1569 extraArgs && *extraArgs; ++extraArgs) {
1570 if (!strcmp(*extraArgs, "-resource-dir")) {
1571 // Take the next arg as the llvm resource directory.
1573 } else {
1574 interpArgs.push_back(*extraArgs);
1575 }
1576 }
1577
1578 std::vector<std::string> _empty;
1580 for (const auto &arg: args)
1581 interpArgs.emplace_back(arg.c_str());
1582
1583 // Add the Rdict module file extension.
1584 cling::Interpreter::ModuleFileExtensions extensions;
1585 EnvOpt = llvm::sys::Process::GetEnv("ROOTDEBUG_RDICT");
1586 if (!EnvOpt.has_value())
1587 extensions.push_back(std::make_shared<TClingRdictModuleFileExtension>());
1588
1589 fInterpreter = std::make_unique<cling::Interpreter>(interpArgs.size(),
1590 &(interpArgs[0]),
1593
1594 if (!fInterpreter->getCI()) { // Compiler instance could not be created. See https://its.cern.ch/jira/browse/ROOT-10239
1595 return;
1596 }
1597
1598 // Tell CppInterOp that the cling::Interpreter instance is managed externally by ROOT
1599 // Sets the interpreter by passing the fInterpreter handle as soon as TCling is initialized
1600 if (!IsFromRootCling())
1601 Cpp::UseExternalInterpreter(fInterpreter.get());
1602
1603 // Don't check whether modules' files exist.
1604 fInterpreter->getCI()->getPreprocessorOpts().DisablePCHOrModuleValidation =
1605 DisableValidationForModuleKind::All;
1606
1607 // Until we can disable AutoLoading during Sema::CorrectTypo() we have
1608 // to disable spell checking.
1609 fInterpreter->getCI()->getLangOpts().SpellChecking = false;
1610
1611 // Sync modules on/off between clang and us: clang turns it on for C++ >= 20.
1612 auto isModulesArg = [](const char* arg) { return !strcmp(arg, "-fmodules"); };
1613 bool hasModulesArg = std::find_if(interpArgs.begin(), interpArgs.end(), isModulesArg) != interpArgs.end();
1614 fInterpreter->getCI()->getLangOpts().Modules = hasModulesArg;
1615
1616 // We need stream that doesn't close its file descriptor, thus we are not
1617 // using llvm::outs. Keeping file descriptor open we will be able to use
1618 // the results in pipes (Savannah #99234).
1619 static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO, /*ShouldClose*/false);
1620 fMetaProcessor = std::make_unique<cling::MetaProcessor>(*fInterpreter, fMPOuts);
1621
1624
1625 // We are now ready (enough is loaded) to init the list of opaque typedefs.
1631
1632 // Disallow auto-parsing in rootcling
1634
1635 ResetAll();
1636
1637 // Enable dynamic lookup
1638 if (!fromRootCling) {
1639 fInterpreter->enableDynamicLookup();
1640 }
1641
1642 // Enable ClinG's DefinitionShadower for ROOT.
1643 fInterpreter->getRuntimeOptions().AllowRedefinition = 1;
1644 auto &Policy = const_cast<clang::PrintingPolicy &>(fInterpreter->getCI()->getASTContext().getPrintingPolicy());
1645 // Print 'a<b<c> >' rather than 'a<b<c>>'.
1646 // FIXME: We should probably switch to the default printing policy setting
1647 // after adjusting tons of reference files.
1648 Policy.SplitTemplateClosers = true;
1649 // Keep default templare arguments, required for dictionary generation.
1650 Policy.SuppressDefaultTemplateArgs = false;
1651
1652
1653 // Attach cling callbacks last; they might need TROOT::fInterpreter
1654 // and should thus not be triggered during the equivalent of
1655 // TROOT::fInterpreter = new TCling;
1656 std::unique_ptr<TClingCallbacks>
1660 fInterpreter->setCallbacks(std::move(clingCallbacks));
1661
1662 if (!fromRootCling) {
1663 cling::DynamicLibraryManager& DLM = *fInterpreter->getDynamicLibraryManager();
1664 // Make sure cling looks into ROOT's libdir, even if not part of LD_LIBRARY_PATH
1665 // e.g. because of an RPATH build.
1666 DLM.addSearchPath(TROOT::GetSharedLibDir().Data(), /*isUser=*/true,
1667 /*prepend=*/true);
1668 auto ShouldPermanentlyIgnore = [](llvm::StringRef FileName) -> bool{
1669 llvm::StringRef stem = llvm::sys::path::stem(FileName);
1670 return stem.starts_with("libNew") || stem.starts_with("libcppyy_backend");
1671 };
1672 // Initialize the dyld for AutoloadLibraryGenerator.
1673 DLM.initializeDyld(ShouldPermanentlyIgnore);
1674 }
1675}
1676
1677
1678////////////////////////////////////////////////////////////////////////////////
1679/// Destroy the interpreter interface.
1680
1682{
1683 // ROOT's atexit functions require the interepreter to be available.
1684 // Run them before shutting down.
1685 if (!IsFromRootCling())
1686 GetInterpreterImpl()->runAtExitFuncs();
1687 fIsShuttingDown = true;
1688 delete fMapfile;
1689 delete fRootmapFiles;
1690 delete fTemporaries;
1691 delete fNormalizedCtxt;
1692 delete fLookupHelper;
1693 gCling = nullptr;
1694}
1695
1696////////////////////////////////////////////////////////////////////////////////
1697/// Initialize the interpreter, once TROOT::fInterpreter is set.
1698
1700{
1701 if (!fClingCallbacks) // Compiler instance could not be created. See https://its.cern.ch/jira/browse/ROOT-10239
1702 return;
1704
1705 // We are set up. Enable ROOT's AutoLoading.
1706 if (IsFromRootCling())
1707 return;
1708
1709 // Read the rules before enabling the auto loading to not inadvertently
1710 // load the libraries for the classes concerned even-though the user is
1711 // *not* using them.
1712 // Note this call must happen before the first call to LoadLibraryMap.
1713 assert(GetRootMapFiles() == nullptr && "Must be called before LoadLibraryMap!");
1714 TClass::ReadRules(); // Read the default customization rules ...
1715
1717 SetClassAutoLoading(true);
1718}
1719
1721{
1722 fIsShuttingDown = true;
1723 ResetGlobals();
1724}
1725
1726////////////////////////////////////////////////////////////////////////////////
1727/// Helper to initialize TVirtualStreamerInfo's factor early.
1728/// Use static initialization to insure only one TStreamerInfo is created.
1730{
1731 // Use lambda since SetFactory return void.
1732 auto setFactory = []() {
1734 return kTRUE;
1735 };
1736 static bool doneFactory = setFactory();
1737 return doneFactory; // avoid unused variable warning.
1738}
1739
1740////////////////////////////////////////////////////////////////////////////////
1741/// Register Rdict data for future loading by LoadPCM;
1742
1743void TCling::RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
1744{
1745 if (IsFromRootCling())
1746 return;
1747
1748 if (llvm::sys::fs::exists(pcmFileNameFullPath)) {
1749 ::Error("TCling::RegisterRdictForLoadPCM", "Rdict '%s' is both in Module extension and in File system.", pcmFileNameFullPath.c_str());
1750 return;
1751 }
1752
1753 // The pcmFileNameFullPath must be resolved already because we cannot resolve
1754 // a link to a non-existent file.
1756}
1757
1758////////////////////////////////////////////////////////////////////////////////
1759/// Tries to load a PCM from TFile; returns true on success.
1760/// The caller of this function should be holding the ROOT Write lock.
1761
1763{
1764 auto listOfKeys = pcmFile.GetListOfKeys();
1765
1766 // This is an empty pcm
1767 if (listOfKeys && ((listOfKeys->GetSize() == 0) || // Nothing here, or
1768 ((listOfKeys->GetSize() == 1) && // only one, and
1769 !strcmp(((TKey *)listOfKeys->At(0))->GetName(), "EMPTY") // name is EMPTY
1770 ))) {
1771 return;
1772 }
1773
1775 if (gDebug > 1)
1776 ::Info("TCling::LoadPCMImpl", "reading protoclasses for %s \n", pcmFile.GetName());
1777
1779 pcmFile.GetObject("__Enums", enums);
1780 if (enums) {
1781 // Cache the pointers
1782 auto listOfGlobals = gROOT->GetListOfGlobals();
1783 auto listOfEnums = dynamic_cast<THashList *>(gROOT->GetListOfEnums());
1784 // Loop on enums and then on enum constants
1785 for (auto selEnum : *enums) {
1786 const char *enumScope = selEnum->GetTitle();
1787 const char *enumName = selEnum->GetName();
1788 if (strcmp(enumScope, "") == 0) {
1789 // This is a global enum and is added to the
1790 // list of enums and its constants to the list of globals
1791 if (!listOfEnums->THashList::FindObject(enumName)) {
1792 ((TEnum *)selEnum)->SetClass(nullptr);
1793 listOfEnums->Add(selEnum);
1794 }
1795 for (auto enumConstant : *static_cast<TEnum *>(selEnum)->GetConstants()) {
1796 if (!listOfGlobals->FindObject(enumConstant)) {
1798 }
1799 }
1800 } else {
1801 // This enum is in a namespace. A TClass entry is bootstrapped if
1802 // none exists yet and the enum is added to it
1804 if (!nsTClassEntry) {
1806 }
1807 auto listOfEnums = nsTClassEntry->fEnums.load();
1808 if (!listOfEnums) {
1809 if ((kIsClass | kIsStruct | kIsUnion) & nsTClassEntry->Property()) {
1810 // For this case, the list will be immutable once constructed
1811 // (i.e. in this case, by the end of this routine).
1813 } else {
1814 // namespaces can have enums added to them
1816 }
1817 }
1818 if (listOfEnums && !listOfEnums->THashList::FindObject(enumName)) {
1819 ((TEnum *)selEnum)->SetClass(nsTClassEntry);
1820 listOfEnums->Add(selEnum);
1821 }
1822 }
1823 }
1824 enums->Clear();
1825 delete enums;
1826 }
1827
1828 pcmFile.GetObject("__ProtoClasses", protoClasses);
1829
1830 if (protoClasses) {
1831 for (auto obj : *protoClasses) {
1832 TProtoClass *proto = (TProtoClass *)obj;
1834 }
1835 // Now that all TClass-es know how to set them up we can update
1836 // existing TClasses, which might cause the creation of e.g. TBaseClass
1837 // objects which in turn requires the creation of TClasses, that could
1838 // come from the PCH, but maybe later in the loop. Instead of resolving
1839 // a dependency graph the addition to the TClassTable above allows us
1840 // to create these dependent TClasses as needed below.
1841 for (auto proto : *protoClasses) {
1842 if (TClass *existingCl = (TClass *)gROOT->GetListOfClasses()->FindObject(proto->GetName())) {
1843 // We have an existing TClass object. It might be emulated
1844 // or interpreted; we now have more information available.
1845 // Make that available.
1846 if (existingCl->GetState() != TClass::kHasTClassInit) {
1847 DictFuncPtr_t dict = gClassTable->GetDict(proto->GetName());
1848 if (!dict) {
1849 ::Error("TCling::LoadPCM", "Inconsistent TClassTable for %s", proto->GetName());
1850 } else {
1851 // This will replace the existing TClass.
1852 TClass *ncl = (*dict)();
1853 if (ncl)
1854 ncl->PostLoadCheck();
1855 }
1856 }
1857 }
1858 }
1859
1860 protoClasses->Clear(); // Ownership was transferred to TClassTable.
1861 delete protoClasses;
1862 }
1863
1865 pcmFile.GetObject("__Typedefs", dataTypes);
1866 if (dataTypes) {
1867 for (auto typedf : *dataTypes)
1868 gROOT->GetListOfTypes()->Add(typedf);
1869 dataTypes->Clear(); // Ownership was transferred to TListOfTypes.
1870 delete dataTypes;
1871 }
1872}
1873
1874////////////////////////////////////////////////////////////////////////////////
1875/// Tries to load a rdict PCM, issues diagnostics if it fails.
1876/// The caller of this function should be holding the ROOT Write lock.
1877
1879{
1882 assert(!pcmFileNameFullPath.empty());
1883 assert(llvm::sys::path::is_absolute(pcmFileNameFullPath));
1884
1885 // Easier to work with the ROOT interfaces.
1887
1888 // Prevent the ROOT-PCMs hitting this during auto-load during
1889 // JITting - which will cause recursive compilation.
1890 // Avoid to call the plugin manager at all.
1892
1894 llvm::SaveAndRestore<Int_t> SaveGDebug(gDebug);
1895 if (gDebug > 5) {
1896 gDebug -= 5;
1897 ::Info("TCling::LoadPCM", "Loading ROOT PCM %s", pcmFileName.Data());
1898 } else {
1899 gDebug = 0;
1900 }
1901
1902 if (llvm::sys::fs::is_symlink_file(pcmFileNameFullPath))
1904
1906 if (pendingRdict != fPendingRdicts.end()) {
1907 llvm::StringRef pcmContent = pendingRdict->second;
1909 std::string RDictFileOpts = pcmFileNameFullPath + "?filetype=pcm";
1911
1912 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
1914 // Currently the module file are never unloaded (even if the library is
1915 // unloaded) and, of course, never reloaded.
1916 // Consequently, we must NOT remove the `pendingRdict` from the list
1917 // of pending dictionary, otherwise if a library is unloaded and then
1918 // reload we will be unable to update properly the TClass object
1919 // (because we wont be able to load the rootpcm file by executing the
1920 // above lines)
1921
1922 return;
1923 }
1924
1925 if (!llvm::sys::fs::exists(pcmFileNameFullPath)) {
1926 ::Error("TCling::LoadPCM", "ROOT PCM %s file does not exist",
1927 pcmFileNameFullPath.data());
1928 if (!fPendingRdicts.empty())
1929 for (const auto &rdict : fPendingRdicts)
1930 ::Info("TCling::LoadPCM", "In-memory ROOT PCM candidate %s\n",
1931 rdict.first.c_str());
1932 return;
1933 }
1934
1935 if (!gROOT->IsRootFile(pcmFileName)) {
1936 Fatal("LoadPCM", "The file %s is not a ROOT as was expected\n", pcmFileName.Data());
1937 return;
1938 }
1939 TFile pcmFile(pcmFileName + "?filetype=pcm", "READ");
1941}
1942
1943//______________________________________________________________________________
1944
1945namespace {
1946 using namespace clang;
1947
1948 class ExtLexicalStorageAdder: public RecursiveASTVisitor<ExtLexicalStorageAdder>{
1949 // This class is to be considered an helper for autoparsing.
1950 // It visits the AST and marks all classes (in all of their redeclarations)
1951 // with the setHasExternalLexicalStorage method.
1952 public:
1953 bool VisitRecordDecl(clang::RecordDecl* rcd){
1954 if (gDebug > 2)
1955 Info("ExtLexicalStorageAdder",
1956 "Adding external lexical storage to class %s",
1957 rcd->getNameAsString().c_str());
1958 auto reDeclPtr = rcd->getMostRecentDecl();
1959 do {
1960 reDeclPtr->setHasExternalLexicalStorage();
1961 } while ((reDeclPtr = reDeclPtr->getPreviousDecl()));
1962
1963 return false;
1964 }
1965 };
1966
1967
1968}
1969
1970////////////////////////////////////////////////////////////////////////////////
1971///\returns true if the module map was loaded, false on error or if the map was
1972/// already loaded.
1974 const std::string &ModuleMapName /*= "module.modulemap"*/) const
1975{
1976 assert(llvm::sys::path::is_absolute(FullPath));
1977 Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
1978 FileManager &FM = PP.getFileManager();
1979 // FIXME: In a ROOT session we can add an include path (through .I /inc/path)
1980 // We should look for modulemap files there too.
1981 if (auto DE = FM.getOptionalDirectoryRef(FullPath)) {
1982 HeaderSearch &HS = PP.getHeaderSearchInfo();
1983 HeaderSearchOptions &HSOpts = const_cast<HeaderSearchOptions&>(HS.getHeaderSearchOpts());
1984 const auto &ModPaths = HSOpts.PrebuiltModulePaths;
1985 bool pathExists = std::find(ModPaths.begin(), ModPaths.end(), FullPath) != ModPaths.end();
1986 if (!pathExists)
1987 HSOpts.AddPrebuiltModulePath(FullPath);
1988 // We cannot use HS.lookupModuleMapFile(DE, /*IsFramework*/ false);
1989 // because its internal call to getFile has CacheFailure set to true.
1990 // In our case, modulemaps can appear any time due to ACLiC.
1991 // Code copied from HS.lookupModuleMapFile.
1992 llvm::SmallString<256> ModuleMapFileName(DE->getName());
1993 llvm::sys::path::append(ModuleMapFileName, ModuleMapName);
1994 if (auto FE = FM.getOptionalFileRef(ModuleMapFileName, /*openFile*/ false,
1995 /*CacheFailure*/ false)) {
1996 if (!HS.parseAndLoadModuleMapFile(*FE, /*IsSystem*/ false))
1997 return true;
1998 Error("RegisterPrebuiltModulePath", "Could not load modulemap in %s", ModuleMapFileName.c_str());
1999 }
2000 }
2001 return false;
2002}
2003
2004////////////////////////////////////////////////////////////////////////////////
2005/// List of dicts that have the PCM information already in the PCH.
2006static const std::unordered_set<std::string> gIgnoredPCMNames = {"libCore",
2007 "libRint",
2008 "libThread",
2009 "libRIO",
2010 "libImt",
2011 "libMultiProc",
2012 "libcomplexDict",
2013 "libdequeDict",
2014 "liblistDict",
2015 "libforward_listDict",
2016 "libvectorDict",
2017 "libmapDict",
2018 "libmultimap2Dict",
2019 "libmap2Dict",
2020 "libmultimapDict",
2021 "libsetDict",
2022 "libmultisetDict",
2023 "libunordered_setDict",
2024 "libunordered_multisetDict",
2025 "libunordered_mapDict",
2026 "libunordered_multimapDict",
2027 "libvalarrayDict",
2028 "G__GenVector32",
2029 "G__Smatrix32"};
2030
2031static void PrintDlError(const char *dyLibName, const char *modulename)
2032{
2033#ifdef R__WIN32
2034 char dyLibError[1000];
2036 dyLibError, sizeof(dyLibError), NULL);
2037#else
2038 const char *dyLibError = dlerror();
2039#endif
2040 ::Error("TCling::RegisterModule", "Cannot open shared library %s for dictionary %s:\n %s", dyLibName, modulename,
2041 (dyLibError) ? dyLibError : "");
2042}
2043
2044////////////////////////////////////////////////////////////////////////////////
2045// Update all the TClass registered in fClassesToUpdate
2046
2048{
2049 while (!fClassesToUpdate.empty()) {
2050 TClass *oldcl = fClassesToUpdate.back().first;
2051 // If somehow the TClass has already been loaded (maybe it was registered several time),
2052 // we skip it. Otherwise, the existing TClass is in mode kInterpreted, kEmulated or
2053 // maybe even kForwardDeclared and needs to replaced.
2054 if (oldcl->GetState() != TClass::kHasTClassInit) {
2055 // if (gDebug > 2) Info("RegisterModule", "Forcing TClass init for %s", oldcl->GetName());
2056 DictFuncPtr_t dict = fClassesToUpdate.back().second;
2057 fClassesToUpdate.pop_back();
2058 // Calling func could manipulate the list so, let maintain the list
2059 // then call the dictionary function.
2060 TClass *ncl = dict();
2061 if (ncl) ncl->PostLoadCheck();
2062 } else {
2063 fClassesToUpdate.pop_back();
2064 }
2065 }
2066}
2067////////////////////////////////////////////////////////////////////////////////
2068/// Inject the module named "modulename" into cling; load all headers.
2069/// headers is a 0-terminated array of header files to `#include` after
2070/// loading the module. The module is searched for in all $LD_LIBRARY_PATH
2071/// entries (or %PATH% on Windows).
2072/// This function gets called by the static initialization of dictionary
2073/// libraries.
2074/// The payload code is injected "as is" in the interpreter.
2075/// The value of 'triggerFunc' is used to find the shared library location.
2076/// The caller of this function should be holding the ROOT Write lock.
2077
2079 const char** headers,
2080 const char** includePaths,
2081 const char* payloadCode,
2082 const char* fwdDeclsCode,
2083 void (*triggerFunc)(),
2085 const char** classesHeaders,
2086 Bool_t lateRegistration /*=false*/,
2087 Bool_t hasCxxModule /*=false*/)
2088{
2089 const bool fromRootCling = IsFromRootCling();
2090 // We need the dictionary initialization but we don't want to inject the
2091 // declarations into the interpreter, except for those we really need for
2092 // I/O; see rootcling.cxx after the call to TCling__GetInterpreter().
2093 if (fromRootCling) return;
2094
2095 // When we cannot provide a module for the library we should enable header
2096 // parsing. This 'mixed' mode ensures gradual migration to modules.
2097 llvm::SaveAndRestore<bool> SaveHeaderParsing(fHeaderParsingOnDemand);
2099
2100 // Treat Aclic Libs in a special way. Do not delay the parsing.
2102 bool isACLiC = strstr(modulename, "_ACLiC_dict") != nullptr;
2104 if (gDebug>1)
2105 Info("TCling::RegisterModule",
2106 "Header parsing on demand is active but this is an Aclic library. Disabling it for this library.");
2108 }
2109
2110
2111 // Make sure we relookup symbols that were search for before we loaded
2112 // their autoparse information. We could be more subtil and remove only
2113 // the failed one or only the one in this module, but for now this is
2114 // better than nothing.
2115 fLookedUpClasses.clear();
2116
2117 // Make sure we do not set off AutoLoading or autoparsing during the
2118 // module registration!
2120
2121 for (const char** inclPath = includePaths; *inclPath; ++inclPath) {
2123 }
2124 cling::Transaction* T = nullptr;
2125 // Put the template decls and the number of arguments to skip in the TNormalizedCtxt
2127 const std::string& fwdDecl = fwdDeclArgToSkipPair.first;
2128 const int nArgsToSkip = fwdDeclArgToSkipPair.second;
2129 auto compRes = fInterpreter->declare(fwdDecl.c_str(), &T);
2130 assert(cling::Interpreter::kSuccess == compRes &&
2131 "A fwd declaration could not be compiled");
2132 if (compRes!=cling::Interpreter::kSuccess){
2133 Warning("TCling::RegisterModule",
2134 "Problems in declaring string '%s' were encountered.",
2135 fwdDecl.c_str()) ;
2136 continue;
2137 }
2138
2139 // Drill through namespaces recursively until the template is found
2140 if(ClassTemplateDecl* TD = FindTemplateInNamespace(T->getFirstDecl().getSingleDecl())){
2142 }
2143
2144 }
2145
2146 // FIXME: Remove #define __ROOTCLING__ once PCMs are there.
2147 // This is used to give Sema the same view on ACLiC'ed files (which
2148 // are then #included through the dictionary) as rootcling had.
2150 if (payloadCode)
2151 code += payloadCode;
2152
2153 std::string dyLibName = cling::DynamicLibraryManager::getSymbolLocation(triggerFunc);
2154 assert(!llvm::sys::fs::is_symlink_file(dyLibName));
2155
2156 if (dyLibName.empty()) {
2157 ::Error("TCling::RegisterModule", "Dictionary trigger function for %s not found", modulename);
2158 return;
2159 }
2160
2161 // The triggerFunc may not be in a shared object but in an executable.
2162 bool isSharedLib = cling::DynamicLibraryManager::isSharedLibrary(dyLibName);
2163
2164 bool wasDlopened = false;
2165
2166 // If this call happens after dlopen has finished (i.e. late registration)
2167 // there is no need to dlopen the library recursively. See ROOT-8437 where
2168 // the dyLibName would correspond to the binary.
2169 if (!lateRegistration) {
2170
2171 if (isSharedLib) {
2172 // We need to open the dictionary shared library, to resolve symbols
2173 // requested by the JIT from it: as the library is currently being dlopen'ed,
2174 // its symbols are not yet reachable from the process.
2175 // Recursive dlopen seems to work just fine.
2176 void* dyLibHandle = dlopen(dyLibName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
2177 if (dyLibHandle) {
2179 wasDlopened = true;
2180 } else {
2182 }
2183 }
2184 } // if (!lateRegistration)
2185
2187 // We now parse the forward declarations. All the classes are then modified
2188 // in order for them to have an external lexical storage.
2189 std::string fwdDeclsCodeLessEnums;
2190 {
2191 // Search for enum forward decls and only declare them if no
2192 // declaration exists yet.
2193 std::string fwdDeclsLine;
2194 std::istringstream fwdDeclsCodeStr(fwdDeclsCode);
2195 std::vector<std::string> scopes;
2196 while (std::getline(fwdDeclsCodeStr, fwdDeclsLine)) {
2197 const auto enumPos = fwdDeclsLine.find("enum __attribute__((annotate(\"");
2198 // We check if the line contains a fwd declaration of an enum
2199 if (enumPos != std::string::npos) {
2200 // We clear the scopes which we may have carried from a previous iteration
2201 scopes.clear();
2202 // We check if the enum is not in a scope. If yes, save its name
2203 // and the names of the enclosing scopes.
2204 if (enumPos != 0) {
2205 // it's enclosed in namespaces. We need to understand what they are
2206 auto nsPos = fwdDeclsLine.find("namespace");
2207 R__ASSERT(nsPos < enumPos && "Inconsistent enum and enclosing scope parsing!");
2208 while (nsPos < enumPos && nsPos != std::string::npos) {
2209 // we have a namespace, let's put it in the collection of scopes
2210 const auto nsNameStart = nsPos + 10;
2211 const auto nsNameEnd = fwdDeclsLine.find('{', nsNameStart);
2212 const auto nsName = fwdDeclsLine.substr(nsNameStart, nsNameEnd - nsNameStart);
2213 scopes.push_back(nsName);
2214 nsPos = fwdDeclsLine.find("namespace", nsNameEnd);
2215 }
2216 }
2217 clang::DeclContext* DC = nullptr;
2218 for (auto &&aScope: scopes) {
2219 DC = cling::utils::Lookup::Namespace(&fInterpreter->getSema(), aScope.c_str(), DC);
2220 if (!DC) {
2221 // No decl context means we have to fwd declare the enum.
2222 break;
2223 }
2224 }
2225 if (scopes.empty() || DC) {
2226 // We know the scope; let's look for the enum. For that, look
2227 // for the *last* closing parentheses of an attribute because
2228 // there can be multiple.
2229 size_t posEnumName = fwdDeclsLine.rfind("\"))) ");
2230 R__ASSERT(posEnumName != std::string::npos && "Inconsistent enum fwd decl!");
2231 posEnumName += 5; // skip "\"))) "
2233 ++posEnumName;
2234 size_t posEnumNameEnd = fwdDeclsLine.find(" : ", posEnumName);
2235 R__ASSERT(posEnumNameEnd != std::string::npos && "Inconsistent enum fwd decl (end)!");
2238 // posEnumNameEnd now points to the last character of the name.
2239
2240 std::string enumName = fwdDeclsLine.substr(posEnumName,
2242
2243 if (clang::NamedDecl* enumDecl
2244 = cling::utils::Lookup::Named(&fInterpreter->getSema(),
2245 enumName.c_str(), DC)) {
2246 // We have an existing enum decl (forward or definition);
2247 // skip this.
2248 R__ASSERT(llvm::dyn_cast<clang::EnumDecl>(enumDecl) && "not an enum decl!");
2249 (void)enumDecl;
2250 continue;
2251 }
2252 }
2253 }
2254
2256 }
2257 }
2258
2259 if (!fwdDeclsCodeLessEnums.empty()){ // Avoid the overhead if nothing is to be declared
2260 auto compRes = fInterpreter->declare(fwdDeclsCodeLessEnums, &T);
2261 assert(cling::Interpreter::kSuccess == compRes &&
2262 "The forward declarations could not be compiled");
2263 if (compRes!=cling::Interpreter::kSuccess){
2264 Warning("TCling::RegisterModule",
2265 "Problems in compiling forward declarations for module %s: '%s'",
2267 }
2268 else if (T){
2269 // Loop over all decls in the transaction and go through them all
2270 // to mark them properly.
2271 // In order to do that, we first iterate over all the DelayedCallInfos
2272 // within the transaction. Then we loop over all Decls in the DeclGroupRef
2273 // contained in the DelayedCallInfos. For each decl, we traverse.
2274 ExtLexicalStorageAdder elsa;
2275 for (auto dciIt = T->decls_begin();dciIt!=T->decls_end();dciIt++){
2276 cling::Transaction::DelayCallInfo& dci = *dciIt;
2277 for(auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) {
2278 clang::Decl* declPtr = *dit;
2279 elsa.TraverseDecl(declPtr);
2280 }
2281 }
2282 }
2283 }
2284
2285 // Now we register all the headers necessary for the class
2286 // Typical format of the array:
2287 // {"A", "classes.h", "@",
2288 // "vector<A>", "vector", "@",
2289 // "myClass", payloadCode, "@",
2290 // nullptr};
2291
2292 std::string temp;
2293 for (const char** classesHeader = classesHeaders; *classesHeader; ++classesHeader) {
2294 temp=*classesHeader;
2295
2296 size_t theTemplateHash = 0;
2297 bool addTemplate = false;
2298 size_t posTemplate = temp.find('<');
2299 if (posTemplate != std::string::npos) {
2300 // Add an entry for the template itself.
2301 std::string templateName = temp.substr(0, posTemplate);
2303 addTemplate = true;
2304 }
2305 size_t theHash = fStringHashFunction(temp);
2306 classesHeader++;
2308 // This is done in order to distinguish headers from files and from the payloadCode
2310 fPayloads.insert(theHash);
2312 }
2313 if (gDebug > 2)
2314 Info("TCling::RegisterModule",
2315 "Adding a header for %s", temp.c_str());
2317 if (addTemplate) {
2320 }
2321 addTemplate = false;
2322 }
2323 }
2324 }
2325 }
2326
2327 clang::Sema &TheSema = fInterpreter->getSema();
2328
2329 bool ModuleWasSuccessfullyLoaded = false;
2330 if (hasCxxModule) {
2331 std::string ModuleName = modulename;
2332 if (llvm::StringRef(modulename).starts_with("lib"))
2333 ModuleName = llvm::StringRef(modulename).substr(3).str();
2334
2335 // In case we are directly loading the library via gSystem->Load() without
2336 // specifying the relevant include paths we should try loading the
2337 // modulemap next to the library location.
2338 clang::Preprocessor &PP = TheSema.getPreprocessor();
2339 std::string ModuleMapName;
2340 if (isACLiC)
2341 ModuleMapName = ModuleName + ".modulemap";
2342 else
2343 ModuleMapName = "module.modulemap";
2344 RegisterPrebuiltModulePath(llvm::sys::path::parent_path(dyLibName).str(),
2346
2347 // FIXME: We should only complain for modules which we know to exist. For example, we should not complain about
2348 // modules such as GenVector32 because it needs to fall back to GenVector.
2349 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2352 // Only report if we found the module in the modulemap.
2353 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
2354 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
2355 if (moduleMap.findModule(ModuleName))
2356 Info("TCling::RegisterModule", "Module %s in modulemap failed to load.", ModuleName.c_str());
2357 }
2358 }
2359
2361 llvm::SmallString<256> pcmFileNameFullPath(dyLibName);
2362 // The path dyLibName might not be absolute. This can happen if dyLibName
2363 // is linked to an executable in the same folder.
2364 llvm::sys::fs::make_absolute(pcmFileNameFullPath);
2365 llvm::sys::path::remove_filename(pcmFileNameFullPath);
2366 llvm::sys::path::append(pcmFileNameFullPath,
2368 // A library built with C++ modules may ship only its .pcm and no
2369 // <lib>_rdict.pcm (the dictionary payload then lives in the C++ module).
2370 // In that case probing the legacy rootpcm makes LoadPCM emit a spurious
2371 // "ROOT PCM ... file does not exist" error followed by an in-memory
2372 // candidate dump. Skip the probe only when the C++ module was loaded AND
2373 // there is genuinely no rootpcm to load -- neither registered in-memory
2374 // (an embedded rdict, the check mirrors LoadPCM) nor present on disk. For
2375 // libraries without a C++ module the behaviour is unchanged, so a truly
2376 // missing rootpcm is still reported.
2377 std::string pcmPath = pcmFileNameFullPath.str().str();
2378 std::string pcmRealPath = llvm::sys::fs::is_symlink_file(pcmPath)
2380 : pcmPath;
2382 llvm::sys::fs::exists(pcmRealPath))
2384 }
2385
2386 { // scope within which diagnostics are de-activated
2387 // For now we disable diagnostics because we saw them already at
2388 // dictionary generation time. That won't be an issue with the PCMs.
2389
2390 clangDiagSuppr diagSuppr(TheSema.getDiagnostics());
2391
2392#if defined(R__MUST_REVISIT)
2393#if R__MUST_REVISIT(6,2)
2394 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
2395#endif
2396#endif
2397
2400
2401 const cling::Transaction* watermark = fInterpreter->getLastTransaction();
2402 cling::Interpreter::CompilationResult compRes = fInterpreter->parseForModule(code.Data());
2403 if (isACLiC) {
2404 // Register an unload point.
2405 fMetaProcessor->registerUnloadPoint(watermark, headers[0]);
2406 }
2407
2408 assert(cling::Interpreter::kSuccess == compRes &&
2409 "Payload code of a dictionary could not be parsed correctly.");
2410 if (compRes!=cling::Interpreter::kSuccess) {
2411 Warning("TCling::RegisterModule",
2412 "Problems declaring payload for module %s.", modulename) ;
2413 }
2414 }
2415 }
2416
2417 // Now that all the header have been registered/compiled, let's
2418 // make sure to 'reset' the TClass that have a class init in this module
2419 // but already had their type information available (using information/header
2420 // loaded from other modules or from class rules or from opening a TFile
2421 // or from loading header in a way that did not provoke the loading of
2422 // the library we just loaded).
2424
2426 // __ROOTCLING__ might be pulled in through PCH
2427 fInterpreter->declare("#ifdef __ROOTCLING__\n"
2428 "#undef __ROOTCLING__\n"
2430 "#endif");
2431 }
2432
2433 if (wasDlopened) {
2435 void* dyLibHandle = fRegisterModuleDyLibs.back();
2436 fRegisterModuleDyLibs.pop_back();
2438 }
2439}
2440
2442 clang::CompilerInstance& CI = *GetInterpreterImpl()->getCI();
2443 ASTContext &C = CI.getASTContext();
2444
2445 // Do not do anything if we have no global module index.
2446 // FIXME: This is mostly to real with false positives in the TTabCom
2447 // interface for non-modules.
2448 if (!fCxxModulesEnabled)
2449 return;
2450
2451 if (IdentifierInfoLookup *External = C.Idents.getExternalIdentifierLookup()) {
2452 std::unique_ptr<IdentifierIterator> Iter(External->getIdentifiers());
2453 for (llvm::StringRef Ident = Iter->Next(); !Ident.empty(); Ident = Iter->Next()) {
2454 std::string I = Ident.str();
2455 if (!Idents.Contains(I.data()))
2456 Idents.Add(new TObjString(I.c_str()));
2457 }
2458 }
2459}
2460
2461
2462////////////////////////////////////////////////////////////////////////////////
2463/// Register classes that already existed prior to their dictionary loading
2464/// and that already had a ClassInfo (and thus would not be refresh via
2465/// UpdateClassInfo.
2466
2468{
2469 fClassesToUpdate.push_back(std::make_pair(oldcl,dict));
2470}
2471
2472////////////////////////////////////////////////////////////////////////////////
2473/// If the dictionary is loaded, we can remove the class from the list
2474/// (otherwise the class might be loaded twice).
2475
2477{
2478 typedef std::vector<std::pair<TClass*,DictFuncPtr_t> >::iterator iterator;
2479 iterator stop = fClassesToUpdate.end();
2480 for(iterator i = fClassesToUpdate.begin();
2481 i != stop;
2482 ++i)
2483 {
2484 if ( i->first == oldcl ) {
2485 fClassesToUpdate.erase(i);
2486 return;
2487 }
2488 }
2489}
2490
2491
2492////////////////////////////////////////////////////////////////////////////////
2493/// Let cling process a command line.
2494///
2495/// If the command is executed and the error is 0, then the return value
2496/// is the int value corresponding to the result of the executed command
2497/// (float and double return values will be truncated).
2498///
2499
2500// Method for handling the interpreter exceptions.
2501// the MetaProcessor is passing in as argument to teh function, because
2502// cling::Interpreter::CompilationResult is a nested class and it cannot be
2503// forward declared, thus this method cannot be a static member function
2504// of TCling.
2505
2506static int HandleInterpreterException(cling::MetaProcessor* metaProcessor,
2507 const char* input_line,
2508 cling::Interpreter::CompilationResult& compRes,
2509 cling::Value* result)
2510{
2511 try {
2512 return metaProcessor->process(input_line, compRes, result);
2513 }
2514 catch (cling::InterpreterException& ex)
2515 {
2516 Error("HandleInterpreterException", "%s\n%s", ex.what(), "Execution of your code was aborted.");
2517 ex.diagnose();
2518 compRes = cling::Interpreter::kFailure;
2519 }
2520 return 0;
2521}
2522
2523////////////////////////////////////////////////////////////////////////////////
2524
2525bool TCling::DiagnoseIfInterpreterException(const std::exception &e) const
2526{
2527 if (auto ie = dynamic_cast<const cling::InterpreterException*>(&e)) {
2528 ie->diagnose();
2529 return true;
2530 }
2531 return false;
2532}
2533
2534////////////////////////////////////////////////////////////////////////////////
2535
2537{
2538 // Copy the passed line, it comes from a static buffer in TApplication
2539 // which can be reentered through the Cling evaluation routines,
2540 // which would overwrite the static buffer and we would forget what we
2541 // were doing.
2542 //
2544 if (strstr(line,fantomline)) {
2545 // End-Of-Line action
2546 // See the comment (copied from above):
2547 // It is a "fantom" method to synchronize user keyboard input
2548 // and ROOT prompt line (for WIN32)
2549 // and is implemented by
2550 if (gApplication) {
2551 if (gApplication->IsCmdThread()) {
2553 gROOT->SetLineIsProcessing();
2554
2556
2557 gROOT->SetLineHasBeenProcessed();
2558 }
2559 }
2560 return 0;
2561 }
2562
2564 gGlobalMutex->Lock();
2565 if (!gInterpreterMutex)
2568 }
2570 gROOT->SetLineIsProcessing();
2571
2572 struct InterpreterFlagsRAII {
2573 cling::Interpreter* fInterpreter;
2575
2576 InterpreterFlagsRAII(cling::Interpreter* interp):
2577 fInterpreter(interp),
2578 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2579 {
2580 fInterpreter->enableDynamicLookup(true);
2581 }
2583 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2584 gROOT->SetLineHasBeenProcessed();
2585 }
2587
2588 // A non-zero returned value means the given line was
2589 // not a complete statement.
2590 int indent = 0;
2591 // This will hold the resulting value of the evaluation the given line.
2592 cling::Value result;
2593 cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess;
2594 if (!strncmp(sLine.Data(), ".L", 2) || !strncmp(sLine.Data(), ".x", 2) ||
2595 !strncmp(sLine.Data(), ".X", 2)) {
2596 // If there was a trailing "+", then CINT compiled the code above,
2597 // and we will need to strip the "+" before passing the line to cling.
2600 TString arguments;
2601 TString io;
2603 aclicMode, arguments, io);
2604 if (aclicMode.Length()) {
2605 // Remove the leading '+'
2606 R__ASSERT(aclicMode[0]=='+' && "ACLiC mode must start with a +");
2607 aclicMode[0]='k'; // We always want to keep the .so around.
2608 if (aclicMode[1]=='+') {
2609 // We have a 2nd +
2610 aclicMode[1]='f'; // We want to force the recompilation.
2611 }
2613 // ACLiC failed.
2614 compRes = cling::Interpreter::kFailure;
2615 } else {
2616 if (strncmp(sLine.Data(), ".L", 2) != 0) {
2617 // if execution was requested.
2618
2619 if (arguments.Length() == 0) {
2620 arguments = "()";
2621 }
2622 // We need to remove the extension.
2623 Ssiz_t ext = fname.Last('.');
2624 if (ext != kNPOS) {
2625 fname.Remove(ext);
2626 }
2627 const char *function = gSystem->BaseName(fname);
2628 mod_line = function + arguments + io;
2630 }
2631 }
2632 } else if (cling::DynamicLibraryManager::isSharedLibrary(fname.Data()) &&
2633 strncmp(sLine.Data(), ".L", 2) != 0) { // .x *.so or *.dll
2634 if (gSystem->Load(fname) < 0) {
2635 // Loading failed.
2636 compRes = cling::Interpreter::kFailure;
2637 } else {
2638 if (arguments.Length() == 0) {
2639 arguments = "()";
2640 }
2641 // We need to remove the extension. (*.so or *.dll)
2642 Ssiz_t ext = fname.Last('.');
2643 if (ext != kNPOS) {
2644 fname.Remove(ext);
2645 }
2646 // Now we try to find the 'main' function to run within this shared library
2647 // We distinguish two cases: a library.so with a function library(args),
2648 // or a precompiled ACLiC macro (macro_C.so) with a function macro(args).
2649 // Only in the second case, we need to strip the suffix _C or _cpp from fname.
2650 if (!gInterpreter->GetFunction(nullptr, gSystem->BaseName(fname))) { // AcLiC macro
2651 // We need to remove the automatically appended _ extension when compiling (macro_C from macro.C)
2652 ext = fname.Last('_');
2653 if (ext != kNPOS) {
2654 fname.Remove(ext);
2655 }
2656 }
2657 const char *function = gSystem->BaseName(fname);
2658 mod_line = function + arguments + io;
2660 }
2661 } else {
2662 // neither ACLiC nor run shared-library (.x)
2663 size_t unnamedMacroOpenCurly;
2664 {
2665 std::string code;
2666 std::string codeline;
2667 // Windows requires std::ifstream::binary to properly handle
2668 // CRLF and LF line endings
2669 std::ifstream in(fname, std::ifstream::binary);
2670 while (in) {
2671 std::getline(in, codeline);
2672 code += codeline + "\n";
2673 }
2675 = cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
2676 }
2677
2678 fCurExecutingMacros.push_back(fname);
2679 if (unnamedMacroOpenCurly != std::string::npos) {
2680 compRes = fMetaProcessor->readInputFromFile(fname.Data(), &result,
2682 } else {
2683 // No DynLookup for .x, .L of named macros.
2684 fInterpreter->enableDynamicLookup(false);
2686 }
2687 fCurExecutingMacros.pop_back();
2688 }
2689 } // .L / .X / .x
2690 else {
2691 if (0!=strncmp(sLine.Data(), ".autodict ",10) && sLine != ".autodict") {
2692 // explicitly ignore .autodict without having to support it
2693 // in cling.
2694
2695 // Turn off autoparsing if this is an include directive
2696 bool isInclusionDirective = sLine.Contains("\n#include") || sLine.BeginsWith("#include");
2700 } else {
2702 }
2703 }
2704 }
2705 if (result.isValid())
2707 if (indent) {
2708 if (error)
2709 *error = kProcessing;
2710 return 0;
2711 }
2712 if (error) {
2713 switch (compRes) {
2714 case cling::Interpreter::kSuccess: *error = kNoError; break;
2715 case cling::Interpreter::kFailure: *error = kRecoverable; break;
2716 case cling::Interpreter::kMoreInputExpected: *error = kProcessing; break;
2717 }
2718 }
2719 if (compRes == cling::Interpreter::kSuccess
2720 && result.isValid()
2721 && !result.isVoid())
2722 {
2723 return result.castAs<Longptr_t>();
2724 }
2725 return 0;
2726}
2727
2728////////////////////////////////////////////////////////////////////////////////
2729/// No-op; see TRint instead.
2730
2732{
2733}
2734
2735////////////////////////////////////////////////////////////////////////////////
2736/// Print information about the interpreter.
2737///\param[in] option Selects the type of information to print.
2738///
2739/// List of currently support options:
2740/// - autoparsed: Print the list of classes that triggered autoparsing.
2742{
2743 if (option && *option) {
2744 if (!strcmp(option, "autoparsed")) {
2745 std::cout << "Auto parsed classes:" << std::endl;
2746 for (auto & cls : fAutoParseClasses) {
2747 std::cout << " " << cls << std::endl;
2748 }
2749 } else if (!strcmp(option, "autoloaded")) {
2750 std::cout << "Auto loaded libraries:" << std::endl;
2751 for (auto & lib : fAutoLoadedLibraries) {
2752 std::cout << " " << lib << std::endl;
2753 }
2754 } else {
2755 ::Error("TCling::Print", "Unknown option '%s'", option);
2756 }
2757 } else {
2758 ::Info("TCling::Print", "No options specified");
2759 }
2760}
2761
2762
2763////////////////////////////////////////////////////////////////////////////////
2764/// \brief Add a directory to the list of directories in which the
2765/// interpreter looks for include files.
2766/// \param[in] path The path to the directory.
2767/// \note Only one path item can be specified at a time, i.e. "path1:path2" is
2768/// \b NOT supported.
2769/// \warning Only the path to the directory should be specified, without
2770/// prepending the \c -I prefix, i.e.
2771/// <tt>gCling->AddIncludePath("/path/to/my/includes")</tt>. If the
2772/// \c -I prefix is used it will be ignored.
2773void TCling::AddIncludePath(const char *path)
2774{
2776 // Favorite source of annoyance: gSystem->AddIncludePath() needs "-I",
2777 // gCling->AddIncludePath() does not! Work around that inconsistency:
2778 if (path[0] == '-' && path[1] == 'I')
2779 path += 2;
2780 TString sPath(path);
2782#ifdef _MSC_VER
2783 if (sPath.BeginsWith("/")) {
2784 char drive[3];
2785 snprintf(drive, 3, "%c:", _getdrive() + 'A' - 1);
2786 sPath.Prepend(drive);
2787 }
2788#endif
2789 fInterpreter->AddIncludePath(sPath.Data());
2790}
2791
2792////////////////////////////////////////////////////////////////////////////////
2793/// Visit all members over members, recursing over base classes.
2794
2796 const TClass* cl, Bool_t isTransient)
2797{
2798 if (insp.GetObjectValidity() == TMemberInspector::kUnset) {
2799 insp.SetObjectValidity(obj ? TMemberInspector::kValidObjectGiven
2801 }
2802
2803 if (!cl || cl->GetCollectionProxy()) {
2804 // We do not need to investigate the content of the STL
2805 // collection, they are opaque to us (and details are
2806 // uninteresting).
2807 return;
2808 }
2809
2810 static const TClassRef clRefString("std::string");
2811 if (clRefString == cl) {
2812 // We stream std::string without going through members..
2813 return;
2814 }
2815
2816 if (TClassEdit::IsStdArray(cl->GetName())) {
2817 // We treat std arrays as C arrays
2818 return;
2819 }
2820
2821 const char* cobj = (const char*) obj; // for ptr arithmetics
2822
2823 // Treat the case of std::complex in a special manner. We want to enforce
2824 // the layout of a stl implementation independent class, which is the
2825 // complex as implemented in ROOT5.
2826
2827 // A simple lambda to simplify the code
2828 auto inspInspect = [&] (ptrdiff_t offset){
2829 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_real", cobj, isTransient);
2830 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_imag", cobj + offset, isTransient);
2831 };
2832
2834 switch(complexType) {
2836 {
2837 break;
2838 }
2840 {
2841 inspInspect(sizeof(float));
2842 return;
2843 }
2845 {
2846 inspInspect(sizeof(double));
2847 return;
2848 }
2850 {
2851 inspInspect(sizeof(int));
2852 return;
2853 }
2855 {
2856 inspInspect(sizeof(long));
2857 return;
2858 }
2859 }
2860
2861 static clang::PrintingPolicy
2862 printPol(fInterpreter->getCI()->getLangOpts());
2863 if (printPol.Indentation) {
2864 // not yet initialized
2865 printPol.Indentation = 0;
2866 printPol.SuppressInitializers = true;
2867 }
2868
2869 const char* clname = cl->GetName();
2870 // Printf("Inspecting class %s\n", clname);
2871
2872 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2873 const clang::Decl *scopeDecl = nullptr;
2874 const clang::Type *recordType = nullptr;
2875
2876 if (cl->GetClassInfo()) {
2878 scopeDecl = clingCI->GetDecl();
2879 recordType = clingCI->GetType();
2880 } else {
2881 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2882 // Diags will complain about private classes:
2883 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2884 &recordType);
2885 }
2886 if (!scopeDecl) {
2887 Error("InspectMembers", "Cannot find Decl for class %s", clname);
2888 return;
2889 }
2890 const clang::CXXRecordDecl* recordDecl
2891 = llvm::dyn_cast<const clang::CXXRecordDecl>(scopeDecl);
2892 if (!recordDecl) {
2893 Error("InspectMembers", "Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2894 return;
2895 }
2896
2897 {
2898 // Force possible deserializations first. We need to have no pending
2899 // Transaction when passing control flow to the inspector below (ROOT-7779).
2900 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2901
2902 astContext.getASTRecordLayout(recordDecl);
2903
2904 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2905 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2906 }
2907
2908 const clang::ASTRecordLayout& recLayout
2909 = astContext.getASTRecordLayout(recordDecl);
2910
2911 // TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
2912 // if (proxy && ( proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated ) ) {
2913 // Error("InspectMembers","The TClass for %s has an emulated proxy but we are looking at a compiled version of the collection!\n",
2914 // cl->GetName());
2915 // }
2916 if (cl->Size() != recLayout.getSize().getQuantity()) {
2917 Error("InspectMembers","TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2918 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2919 }
2920
2921 unsigned iNField = 0;
2922 // iterate over fields
2923 // FieldDecls are non-static, else it would be a VarDecl.
2924 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2925 eField = recordDecl->field_end(); iField != eField;
2926 ++iField, ++iNField) {
2927
2928
2929 clang::QualType memberQT = iField->getType();
2930 if (recordType) {
2931 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2933 }
2934 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2935 if (memberQT.isNull()) {
2936 std::string memberName;
2937 llvm::raw_string_ostream stream(memberName);
2938 // Don't trigger fopen of the source file to count lines:
2939 printPol.AnonymousTagLocations = false;
2940 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2941 stream.flush();
2942 Error("InspectMembers",
2943 "Cannot retrieve QualType for member %s while inspecting class %s",
2944 memberName.c_str(), clname);
2945 continue; // skip member
2946 }
2947 const clang::Type* memType = memberQT.getTypePtr();
2948 if (!memType) {
2949 std::string memberName;
2950 llvm::raw_string_ostream stream(memberName);
2951 // Don't trigger fopen of the source file to count lines:
2952 printPol.AnonymousTagLocations = false;
2953 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2954 stream.flush();
2955 Error("InspectMembers",
2956 "Cannot retrieve Type for member %s while inspecting class %s",
2957 memberName.c_str(), clname);
2958 continue; // skip member
2959 }
2960
2961 const clang::Type* memNonPtrType = memType;
2962 Bool_t ispointer = false;
2963 if (memNonPtrType->isPointerType()) {
2964 ispointer = true;
2965 clang::QualType ptrQT
2966 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2967 if (recordType) {
2968 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2970 }
2971 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2972 if (ptrQT.isNull()) {
2973 std::string memberName;
2974 llvm::raw_string_ostream stream(memberName);
2975 // Don't trigger fopen of the source file to count lines:
2976 printPol.AnonymousTagLocations = false;
2977 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2978 stream.flush();
2979 Error("InspectMembers",
2980 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2981 memberName.c_str(), clname);
2982 continue; // skip member
2983 }
2984 memNonPtrType = ptrQT.getTypePtr();
2985 }
2986
2987 // assemble array size(s): "[12][4][]"
2988 llvm::SmallString<8> arraySize;
2989 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2990 unsigned arrLevel = 0;
2991 bool haveErrorDueToArray = false;
2992 while (arrType) {
2993 ++arrLevel;
2994 arraySize += '[';
2995 const clang::ConstantArrayType* constArrType =
2996 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2997 if (constArrType) {
2998 constArrType->getSize().toStringUnsigned(arraySize);
2999 }
3000 arraySize += ']';
3001 clang::QualType subArrQT = arrType->getElementType();
3002 if (subArrQT.isNull()) {
3003 std::string memberName;
3004 llvm::raw_string_ostream stream(memberName);
3005 // Don't trigger fopen of the source file to count lines:
3006 printPol.AnonymousTagLocations = false;
3007 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
3008 stream.flush();
3009 Error("InspectMembers",
3010 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
3011 arrLevel, subArrQT.getAsString(printPol).c_str(),
3012 memberName.c_str(), clname);
3013 haveErrorDueToArray = true;
3014 break;
3015 }
3016 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
3017 }
3018 if (haveErrorDueToArray) {
3019 continue; // skip member
3020 }
3021
3022 // construct member name
3023 std::string fieldName;
3024 if (memType->isPointerType()) {
3025 fieldName = "*";
3026 }
3027
3028 // Check if this field has a custom ioname, if not, just use the one of the decl
3029 std::string ioname(iField->getName());
3031 fieldName += ioname;
3032 fieldName += arraySize;
3033
3034 // get member offset
3035 // NOTE currently we do not support bitfield and do not support
3036 // member that are not aligned on 'bit' boundaries.
3037 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
3038 ptrdiff_t fieldOffset = offset.getQuantity();
3039
3040 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fBits[2]", fBits);
3041 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fName", &fName);
3042 // R__insp.InspectMember(fName, "fName.");
3043 // R__insp.Inspect(R__cl, R__insp.GetParent(), "*fClass", &fClass);
3044
3045 // If the class has a custom streamer and the type of the filed is a
3046 // private enum, struct or class, skip it.
3047 if (!insp.IsTreatingNonAccessibleTypes()){
3048 auto iFiledQtype = iField->getType();
3049 if (auto tagDecl = iFiledQtype->getAsTagDecl()){
3050 auto declAccess = tagDecl->getAccess();
3052 continue;
3053 }
3054 }
3055 }
3056
3057 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
3058
3059 if (!ispointer) {
3060 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
3061 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
3062 // nested objects get an extra call to InspectMember
3063 // R__insp.InspectMember("FileStat_t", (void*)&fFileStat, "fFileStat.", false);
3064 std::string sFieldRecName;
3067 clang::QualType(memNonPtrType,0),
3068 *fInterpreter,
3070 }
3071
3072 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
3073 // if we can not find the member (which should not really happen),
3074 // let's consider it transient.
3075 Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();
3076 if (!mbr || !mbr->IsPersistent())
3077 insp.IncrementNestedTransient();
3078 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
3079 (fieldName + '.').c_str(), transient);
3080 if (!mbr || !mbr->IsPersistent())
3081 insp.DecrementNestedTransient();
3082
3083 }
3084 }
3085 } // loop over fields
3086
3087 // inspect bases
3088 // TNamed::ShowMembers(R__insp);
3089 unsigned iNBase = 0;
3090 for (clang::CXXRecordDecl::base_class_const_iterator iBase
3091 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
3092 iBase != eBase; ++iBase, ++iNBase) {
3093 clang::QualType baseQT = iBase->getType();
3094 if (baseQT.isNull()) {
3095 Error("InspectMembers",
3096 "Cannot find QualType for base number %d while inspecting class %s",
3097 iNBase, clname);
3098 continue;
3099 }
3100 const clang::CXXRecordDecl* baseDecl
3101 = baseQT->getAsCXXRecordDecl();
3102 if (!baseDecl) {
3103 Error("InspectMembers",
3104 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
3105 iNBase, clname);
3106 continue;
3107 }
3108 TClass* baseCl=nullptr;
3109 std::string sBaseName;
3110 // Try with the DeclId
3111 std::vector<TClass*> foundClasses;
3113 if (foundClasses.size()==1){
3115 } else {
3116 // Try with the normalised Name, as a fallback
3117 if (!baseCl){
3119 baseQT,
3120 *fInterpreter,
3123 }
3124 }
3125
3126 if (!baseCl){
3127 std::string qualNameForDiag;
3129 Error("InspectMembers",
3130 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
3131 continue;
3132 }
3133
3134 int64_t baseOffset;
3135 if (iBase->isVirtual()) {
3136 if (insp.GetObjectValidity() == TMemberInspector::kNoObjectGiven) {
3137 if (!isTransient) {
3138 Error("InspectMembers",
3139 "Base %s of class %s is virtual but no object provided",
3140 sBaseName.c_str(), clname);
3141 }
3143 } else {
3144 // We have an object to determine the vbase offset.
3146 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
3147 if (ci && baseCi) {
3148 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
3149 true /*isDerivedObj*/);
3150 if (baseOffset == -1) {
3151 Error("InspectMembers",
3152 "Error calculating offset of virtual base %s of class %s",
3153 sBaseName.c_str(), clname);
3154 }
3155 } else {
3156 Error("InspectMembers",
3157 "Cannot calculate offset of virtual base %s of class %s",
3158 sBaseName.c_str(), clname);
3159 continue;
3160 }
3161 }
3162 } else {
3163 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
3164 }
3165 // TOFIX: baseCl can be null here!
3166 if (baseCl->IsLoaded()) {
3167 // For loaded class, CallShowMember will (especially for TObject)
3168 // call the virtual ShowMember rather than the class specific version
3169 // resulting in an infinite recursion.
3171 } else {
3172 baseCl->CallShowMembers(cobj + baseOffset,
3173 insp, isTransient);
3174 }
3175 } // loop over bases
3176}
3177
3178////////////////////////////////////////////////////////////////////////////////
3179/// Check if constructor exited correctly, ie the instance is in a valid state
3180/// \return true if there is a compiler instance available, false otherwise
3182{
3183 return fInterpreter->getCI() != nullptr;
3184}
3185
3186////////////////////////////////////////////////////////////////////////////////
3187/// Reset the interpreter internal state in case a previous action was not correctly
3188/// terminated.
3189
3191{
3192 // No-op there is not equivalent state (to be cleared) in Cling.
3193}
3194
3195////////////////////////////////////////////////////////////////////////////////
3196/// Delete existing temporary values.
3197
3199{
3200 // No-op for cling due to cling::Value.
3201}
3202
3203namespace {
3204 // Re-enable JIT symbol library autoloading (independently of class/dictionary
3205 // autoloading) for the lifetime of the object. See its use in TCling::Declare
3206 // and #16601.
3207 class EnableAutoLoadingForJITSymbolsRAII {
3208 TClingCallbacks *fCallbacks;
3209 bool fOldValue = false;
3210
3211 public:
3212 EnableAutoLoadingForJITSymbolsRAII(TClingCallbacks *callbacks) : fCallbacks(callbacks)
3213 {
3214 if (fCallbacks) {
3215 fOldValue = fCallbacks->IsAutoLoadingForJITSymbols();
3216 fCallbacks->SetAutoLoadingForJITSymbols(true);
3217 }
3218 }
3220 {
3221 if (fCallbacks)
3222 fCallbacks->SetAutoLoadingForJITSymbols(fOldValue);
3223 }
3224 };
3225}
3226
3227////////////////////////////////////////////////////////////////////////////////
3228/// Declare code to the interpreter, without any of the interpreter actions
3229/// that could trigger a re-interpretation of the code. I.e. make cling
3230/// behave like a compiler: no dynamic lookup, no input wrapping for
3231/// subsequent execution, no automatic provision of declarations but just a
3232/// plain `#include`.
3233/// Returns true on success, false on failure.
3234
3235bool TCling::Declare(const char* code)
3236{
3238
3241
3242 // The suspensions above make parsing behave like a plain compiler, but they also
3243 // gate the JIT's library autoloading - and a declared global's static initializer
3244 // may still need symbols from a not-yet-loaded library (e.g. TVectorT<float> from
3245 // libMatrix). Re-allow autoloading for such genuine JIT symbol resolution. #16601
3246 EnableAutoLoadingForJITSymbolsRAII autoLoadJITOn(fClingCallbacks);
3247
3248 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
3249 fInterpreter->enableDynamicLookup(false);
3250 bool oldRawInput = fInterpreter->isRawInputEnabled();
3251 fInterpreter->enableRawInput(true);
3252
3253 Bool_t ret = LoadText(code);
3254
3255 fInterpreter->enableRawInput(oldRawInput);
3256 fInterpreter->enableDynamicLookup(oldDynLookup);
3257 return ret;
3258}
3259
3260////////////////////////////////////////////////////////////////////////////////
3261/// It calls a "fantom" method to synchronize user keyboard input
3262/// and ROOT prompt line.
3263
3268
3269// This static function is a hop of TCling::IsLibraryLoaded, which is taking a lock and calling
3270// into this function. This is because we wanted to avoid a duplication in TCling::IsLoaded, which
3271// was already taking a lock.
3272static Bool_t s_IsLibraryLoaded(const char* libname, cling::Interpreter* fInterpreter)
3273{
3274 // Check shared library.
3277 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
3278 return false;
3279}
3280
3286
3287////////////////////////////////////////////////////////////////////////////////
3288/// Return true if ROOT has cxxmodules pcm for a given library name.
3289// FIXME: We need to be able to support lazy loading of pcm generated by ACLiC.
3291{
3292 llvm::StringRef ModuleName(libname);
3293 ModuleName = llvm::sys::path::stem(ModuleName);
3294 ModuleName.consume_front("lib");
3295
3296 // FIXME: In case when the modulemap is not yet loaded we will return the
3297 // wrong result. Consider a call to HasPCMForLibrary(../test/libEvent.so)
3298 // We will only load the modulemap for libEvent.so after we dlopen libEvent
3299 // which may happen after calling this interface. Maybe we should also check
3300 // if there is a Event.pcm file and a module.modulemap, load it and return
3301 // true.
3302 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
3303 clang::Module *M = moduleMap.findModule(ModuleName);
3304 return M && !M->IsUnimportable && M->getASTFile();
3305}
3306
3307////////////////////////////////////////////////////////////////////////////////
3308/// Return true if the file has already been loaded by cint.
3309/// We will try in this order:
3310/// actual filename
3311/// filename as a path relative to
3312/// the include path
3313/// the shared library path
3314
3316{
3318
3319 //FIXME: if we use llvm::sys::fs::make_absolute all this can go away. See
3320 // cling::DynamicLibraryManager.
3321
3322 std::string file_name = filename;
3323 size_t at = std::string::npos;
3324 while ((at = file_name.find("/./")) != std::string::npos)
3325 file_name.replace(at, 3, "/");
3326
3327 std::string filesStr = "";
3328 llvm::raw_string_ostream filesOS(filesStr);
3329 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3330 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
3331 filesOS.flush();
3332
3333 llvm::SmallVector<llvm::StringRef, 100> files;
3334 llvm::StringRef(filesStr).split(files, "\n");
3335
3336 std::set<std::string> fileMap;
3337 llvm::StringRef file_name_ref(file_name);
3338 // Fill fileMap; return early on exact match.
3340 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
3341 if ((*iF) == file_name_ref) return kTRUE; // exact match
3342 fileMap.insert(iF->str());
3343 }
3344
3345 if (fileMap.empty()) return kFALSE;
3346
3347 // Check MacroPath.
3348 TString sFilename(file_name.c_str());
3350 && fileMap.count(sFilename.Data())) {
3351 return kTRUE;
3352 }
3353
3354 // Check IncludePath.
3355 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
3356 incPath.Append(":").Prepend(" "); // to match " -I" (note leading ' ')
3357 incPath.ReplaceAll(" -I", ":"); // of form :dir1 :dir2:dir3
3358 while (incPath.Index(" :") != -1) {
3359 incPath.ReplaceAll(" :", ":");
3360 }
3361 incPath.Prepend(".:");
3362 sFilename = file_name.c_str();
3364 && fileMap.count(sFilename.Data())) {
3365 return kTRUE;
3366 }
3367
3368 // Check shared library.
3370 return kTRUE;
3371
3372 //FIXME: We must use the cling::Interpreter::lookupFileOrLibrary iface.
3373 clang::ConstSearchDirIterator *CurDir = nullptr;
3374 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
3375 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
3376 auto FE = HS.LookupFile(file_name.c_str(),
3377 clang::SourceLocation(),
3378 /*isAngled*/ false,
3379 /*FromDir*/ nullptr, CurDir,
3380 clang::ArrayRef<std::pair<clang::OptionalFileEntryRef,
3381 clang::DirectoryEntryRef>>(),
3382 /*SearchPath*/ nullptr,
3383 /*RelativePath*/ nullptr,
3384 /*RequestingModule*/ nullptr,
3385 /*SuggestedModule*/ nullptr,
3386 /*IsMapped*/ nullptr,
3387 /*IsFrameworkFound*/ nullptr,
3388 /*SkipCache*/ false,
3389 /*BuildSystemModule*/ false,
3390 /*OpenFile*/ false,
3391 /*CacheFail*/ false);
3392 if (FE) {
3393 // check in the source manager if the file is actually loaded
3394 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3395 // this works only with header (and source) files...
3396 clang::FileID FID = SM.translateFile(*FE);
3397 if (!FID.isInvalid() && FID.getHashValue() == 0)
3398 return kFALSE;
3399 else {
3400 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
3401 if (SLocE.isFile() && !SLocE.getFile().getContentCache().getBufferIfLoaded())
3402 return kFALSE;
3403 if (!FID.isInvalid())
3404 return kTRUE;
3405 }
3406 // ...then check shared library again, but with full path now
3407 sFilename = FE->getName().str();
3409 && fileMap.count(sFilename.Data())) {
3410 return kTRUE;
3411 }
3412 }
3413 return kFALSE;
3414}
3415
3416
3417#if defined(R__MACOSX)
3418
3419////////////////////////////////////////////////////////////////////////////////
3420/// Check if lib is in the dynamic linker cache, returns true if it is, and if so,
3421/// modifies the library file name parameter `lib` from `/usr/lib/libFOO.dylib`
3422/// to `-lFOO` such that it can be passed to the linker.
3423/// This is a unique feature of macOS 11.
3424
3425static bool R__UpdateLibFileForLinking(TString &lib)
3426{
3427 const char *mapfile = nullptr;
3428#if __x86_64__
3429 mapfile = "/System/Library/dyld/dyld_shared_cache_x86_64.map";
3430#elif __arm64__
3431 mapfile = "/System/Library/dyld/dyld_shared_cache_arm64e.map";
3432#else
3433 #error unsupported architecture
3434#endif
3435 if (std::ifstream cacheMap{mapfile}) {
3436 std::string line;
3437 while (getline(cacheMap, line)) {
3438 if (line.find(lib) != std::string::npos) {
3439 lib.ReplaceAll("/usr/lib/lib","-l");
3440 lib.ReplaceAll(".dylib","");
3441 return true;
3442 }
3443 }
3444 return false;
3445 }
3446 return false;
3447}
3448#endif // R__MACOSX
3449
3450#if defined (R__LINUX) || defined (R__FBSD)
3451
3452////////////////////////////////////////////////////////////////////////////////
3453/// Callback for dl_iterate_phdr(), see `man dl_iterate_phdr`.
3454/// Collects opened libraries.
3455
3456static int callback_for_dl_iterate_phdr(struct dl_phdr_info *info, size_t size, void *data)
3457{
3458 // This function is called through UpdateListOfLoadedSharedLibraries() which is locked.
3459 static std::unordered_set<decltype(info->dlpi_addr)> sKnownLoadedLibBaseAddrs;
3460
3461 auto newLibs = static_cast<std::vector<std::string>*>(data);
3462 if (!sKnownLoadedLibBaseAddrs.count(info->dlpi_addr)) {
3463 // Skip \0, "", and kernel pseudo-libs linux-vdso.so.1 or linux-gate.so.1
3464 if (info->dlpi_name && info->dlpi_name[0]
3465#if defined(R__FBSD)
3466 //skip the executable (with null addr)
3467 && info->dlpi_addr
3468 //has no path
3469 && strncmp(info->dlpi_name, "[vdso]", 6)
3470 //the linker does not like to be mmapped
3471 //causes a crash in cling::DynamicLibraryManager::loadLibrary())
3472 //with error message "mmap of entire address space failed: Cannot allocate memory"
3473 && strncmp(info->dlpi_name, "/libexec/ld-elf.so.1", 20)
3474#endif
3475 && strncmp(info->dlpi_name, "linux-vdso.so", 13)
3476 && strncmp(info->dlpi_name, "linux-vdso32.so", 15)
3477 && strncmp(info->dlpi_name, "linux-vdso64.so", 15)
3478 && strncmp(info->dlpi_name, "linux-gate.so", 13))
3479 newLibs->emplace_back(info->dlpi_name);
3480 sKnownLoadedLibBaseAddrs.insert(info->dlpi_addr);
3481 }
3482 // No matter what the doc says, return != 0 means "stop the iteration".
3483 return 0;
3484}
3485
3486#endif // R__LINUX || R__FBSD
3487
3488
3489////////////////////////////////////////////////////////////////////////////////
3490
3492{
3493#if defined(R__WIN32) || defined(__CYGWIN__)
3494 HMODULE hModules[1024];
3495 void *hProcess;
3496 unsigned long cbModules;
3497 unsigned int i;
3498 hProcess = (void *)::GetCurrentProcess();
3500 // start at 1 to skip the executable itself
3501 for (i = 1; i < (cbModules / sizeof(void *)); i++) {
3502 static const int bufsize = 260;
3503 wchar_t winname[bufsize];
3504 char posixname[bufsize];
3506#if defined(__CYGWIN__)
3508#else
3509 std::wstring wpath = winname;
3510 std::replace(wpath.begin(), wpath.end(), '\\', '/');
3511 string path(wpath.begin(), wpath.end());
3512 strncpy(posixname, path.c_str(), bufsize);
3513#endif
3516 }
3517 }
3518#elif defined(R__MACOSX)
3519 // fPrevLoadedDynLibInfo stores the *next* image index to look at
3520 uint32_t imageIndex = (uint32_t) (size_t) fPrevLoadedDynLibInfo;
3521
3523 // Skip non-dylibs
3524 if (mh->filetype == MH_DYLIB) {
3525 if (const char* imageName = _dyld_get_image_name(imageIndex)) {
3527 }
3528 }
3529
3530 ++imageIndex;
3531 }
3532 fPrevLoadedDynLibInfo = (void*)(size_t)imageIndex;
3533#elif defined(R__LINUX) || defined(R__FBSD)
3534 // fPrevLoadedDynLibInfo is unused on Linux.
3535 (void) fPrevLoadedDynLibInfo;
3536
3537 std::vector<std::string> newLibs;
3539 for (auto &&lib: newLibs)
3540 RegisterLoadedSharedLibrary(lib.c_str());
3541#else
3542 Error("TCling::UpdateListOfLoadedSharedLibraries",
3543 "Platform not supported!");
3544#endif
3545}
3546
3547namespace {
3548template <int N>
3549static bool StartsWithStrLit(const char *haystack, const char (&needle)[N]) {
3550 return !strncmp(haystack, needle, N - 1);
3551}
3552}
3553
3554////////////////////////////////////////////////////////////////////////////////
3555/// Register that a library was autoloaded either to provide a 'missing' symbol
3556/// or to provide a class (see TClass::GetClass and TROOT::LoadClass).
3558{
3560}
3561
3562////////////////////////////////////////////////////////////////////////////////
3563/// Register a new shared library name with the interpreter; add it to
3564/// fSharedLibs.
3565
3567{
3568 // Ignore NULL filenames, aka "the process".
3569 if (!filename) return;
3570
3571 // Tell the interpreter that this library is available; all libraries can be
3572 // used to resolve symbols.
3573 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3574 if (!DLM->isLibraryLoaded(filename)) {
3575 DLM->loadLibrary(filename, true /*permanent*/, true /*resolved*/);
3576 }
3577
3578#if defined(R__MACOSX)
3579 // Check that this is not a system library that does not exist on disk.
3580 auto lenFilename = strlen(filename);
3581 auto isInMacOSSystemDir = [](const char *fn) {
3582 return StartsWithStrLit(fn, "/usr/lib/") || StartsWithStrLit(fn, "/System/Library/");
3583 };
3584 if (!strcmp(filename, "cl_kernels") // yepp, no directory
3585
3586 // These we should not link with (e.g. because they forward to .tbd):
3587 || StartsWithStrLit(filename, "/usr/lib/system/")
3588 || StartsWithStrLit(filename, "/usr/lib/libc++")
3589 || StartsWithStrLit(filename, "/System/Library/Frameworks/")
3590 || StartsWithStrLit(filename, "/System/Library/PrivateFrameworks/")
3591 || StartsWithStrLit(filename, "/System/Library/CoreServices/")
3592 || StartsWithStrLit(filename, "/usr/lib/libSystem")
3593 || StartsWithStrLit(filename, "/usr/lib/libstdc++")
3594 || StartsWithStrLit(filename, "/usr/lib/libicucore")
3595 || StartsWithStrLit(filename, "/usr/lib/libbsm")
3596 || StartsWithStrLit(filename, "/usr/lib/libobjc")
3597 || StartsWithStrLit(filename, "/usr/lib/libresolv")
3598 || StartsWithStrLit(filename, "/usr/lib/libauto")
3599 || StartsWithStrLit(filename, "/usr/lib/libcups")
3600 || StartsWithStrLit(filename, "/usr/lib/libDiagnosticMessagesClient")
3601 || StartsWithStrLit(filename, "/usr/lib/liblangid")
3602 || StartsWithStrLit(filename, "/usr/lib/libCRFSuite")
3603 || StartsWithStrLit(filename, "/usr/lib/libpam")
3604 || StartsWithStrLit(filename, "/usr/lib/libOpenScriptingUtil")
3605 || StartsWithStrLit(filename, "/usr/lib/libextension")
3606 || StartsWithStrLit(filename, "/usr/lib/libAudioToolboxUtility")
3607 || StartsWithStrLit(filename, "/usr/lib/liboah")
3608 || StartsWithStrLit(filename, "/usr/lib/libRosetta")
3609 || StartsWithStrLit(filename, "/usr/lib/libCoreEntitlements")
3610 || StartsWithStrLit(filename, "/usr/lib/libssl.")
3611 || StartsWithStrLit(filename, "/usr/lib/libcrypto.")
3612
3613 // The system lib is likely in macOS's blob.
3615
3616 // "Link against the umbrella framework 'System.framework' instead"
3617 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_kernel")
3618 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_platform")
3619 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_pthread")
3620
3621 // "cannot link directly with dylib/framework, your binary is not an allowed client of
3622 // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
3623 // SDKs/MacOSX.sdk/usr/lib/libAudioToolboxUtility.tbd for architecture x86_64
3624 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4, ".tbd")))
3625 return;
3628 filename = sFileName.Data();
3629#elif defined(__CYGWIN__)
3630 // Check that this is not a system library
3631 static const int bufsize = 260;
3632 char posixwindir[bufsize];
3633 char *windir = std::getenv("WINDIR");
3634 if (windir)
3636 else
3637 snprintf(posixwindir, sizeof(posixwindir), "/Windows/");
3638 if (strstr(filename, posixwindir) ||
3639 strstr(filename, "/usr/bin/cyg"))
3640 return;
3641#elif defined(R__WIN32)
3642 if (strstr(filename, "/Windows/"))
3643 return;
3644#elif defined (R__LINUX)
3645 if (strstr(filename, "/ld-linux")
3646 || strstr(filename, "linux-gnu/")
3647 || strstr(filename, "/libstdc++.")
3648 || strstr(filename, "/libgcc")
3649 || strstr(filename, "/libc.")
3650 || strstr(filename, "/libdl.")
3651 || strstr(filename, "/libm."))
3652 return;
3653#endif
3654 // Update string of available libraries.
3655 if (!fSharedLibs.IsNull()) {
3656 fSharedLibs.Append(" ");
3657 }
3659}
3660
3661////////////////////////////////////////////////////////////////////////////////
3662/// Load a library file in cling's memory.
3663/// if 'system' is true, the library is never unloaded.
3664/// Return 0 on success, -1 on failure.
3665
3667{
3668 assert(!IsFromRootCling() && "Trying to load library from rootcling!");
3669
3670 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3672 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3673 std::string canonLib = DLM->lookupLibrary(filename);
3674 cling::DynamicLibraryManager::LoadLibResult res
3675 = cling::DynamicLibraryManager::kLoadLibNotFound;
3676 if (!canonLib.empty()) {
3677 if (system)
3678 res = DLM->loadLibrary(filename, system, true);
3679 else {
3680 // For the non system libs, we'd like to be able to unload them.
3681 // FIXME: Here we lose the information about kLoadLibAlreadyLoaded case.
3682 cling::Interpreter::CompilationResult compRes;
3683 HandleInterpreterException(GetMetaProcessorImpl(), Form(".L %s", canonLib.c_str()), compRes, /*cling::Value*/nullptr);
3684 if (compRes == cling::Interpreter::kSuccess)
3685 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3686 }
3687 }
3688
3689 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3691 }
3692 switch (res) {
3693 case cling::DynamicLibraryManager::kLoadLibSuccess: return 0;
3694 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return 1;
3695 default: break;
3696 };
3697 return -1;
3698}
3699
3700////////////////////////////////////////////////////////////////////////////////
3701/// Load a macro file in cling's memory.
3702
3703void TCling::LoadMacro(const char* filename, EErrorCode* error)
3704{
3705 ProcessLine(Form(".L %s", filename), error);
3706}
3707
3708////////////////////////////////////////////////////////////////////////////////
3709/// Let cling process a command line asynch.
3710
3712{
3713 return ProcessLine(line, error);
3714}
3715
3716////////////////////////////////////////////////////////////////////////////////
3717/// Let cling process a command line synchronously, i.e we are waiting
3718/// it will be finished.
3719
3721{
3723 if (gApplication) {
3724 if (gApplication->IsCmdThread()) {
3725 return ProcessLine(line, error);
3726 }
3727 return 0;
3728 }
3729 return ProcessLine(line, error);
3730}
3731
3732////////////////////////////////////////////////////////////////////////////////
3733/// Directly execute an executable statement (e.g. "func()", "3+5", etc.
3734/// however not declarations, like "Int_t x;").
3735
3737{
3738#ifdef R__WIN32
3739 // Test on ApplicationImp not being 0 is needed because only at end of
3740 // TApplication ctor the IsLineProcessing flag is set to 0, so before
3741 // we can not use it.
3743 while (gROOT->IsLineProcessing() && !gApplication) {
3744 Warning("Calc", "waiting for cling thread to free");
3745 gSystem->Sleep(500);
3746 }
3747 gROOT->SetLineIsProcessing();
3748 }
3749#endif // R__WIN32
3751 if (error) {
3752 *error = TInterpreter::kNoError;
3753 }
3754 cling::Value valRef;
3755 cling::Interpreter::CompilationResult cr = cling::Interpreter::kFailure;
3756 try {
3757 cr = fInterpreter->evaluate(line, valRef);
3758 }
3759 catch (cling::InterpreterException& ex)
3760 {
3761 Error("Calc", "%s.\n%s", ex.what(), "Evaluation of your expression was aborted.");
3762 ex.diagnose();
3763 cr = cling::Interpreter::kFailure;
3764 }
3765
3766 if (cr != cling::Interpreter::kSuccess) {
3767 // Failure in compilation.
3768 if (error) {
3769 // Note: Yes these codes are weird.
3771 }
3772 return 0L;
3773 }
3774 if (!valRef.isValid()) {
3775 // Failure at runtime.
3776 if (error) {
3777 // Note: Yes these codes are weird.
3778 *error = TInterpreter::kDangerous;
3779 }
3780 return 0L;
3781 }
3782
3783 if (valRef.isVoid()) {
3784 return 0;
3785 }
3786
3788#ifdef R__WIN32
3790 gROOT->SetLineHasBeenProcessed();
3791 }
3792#endif // R__WIN32
3793 return valRef.castAs<Longptr_t>();
3794}
3795
3796////////////////////////////////////////////////////////////////////////////////
3797/// Set a getline function to call when input is needed.
3798
3799void TCling::SetGetline(const char * (*getlineFunc)(const char* prompt),
3800 void (*histaddFunc)(const char* line))
3801{
3802 // If cling offers a replacement for G__pause(), it would need to
3803 // also offer a way to customize at least the history recording.
3804
3805#if defined(R__MUST_REVISIT)
3806#if R__MUST_REVISIT(6,2)
3807 Warning("SetGetline","Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3808#endif
3809#endif
3810}
3811
3812////////////////////////////////////////////////////////////////////////////////
3813/// Helper function to increase the internal Cling count of transactions
3814/// that change the AST.
3815
3816Bool_t TCling::HandleNewTransaction(const cling::Transaction &T)
3817{
3819
3820 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3821 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3822 || T.macros_begin() != T.macros_end()
3823 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3825 return true;
3826 }
3827 return false;
3828}
3829
3830////////////////////////////////////////////////////////////////////////////////
3831/// Delete object from cling symbol table so it can not be used anymore.
3832/// cling objects are always on the heap.
3833
3835{
3836 // NOTE: When replacing the mutex by a ReadWrite mutex, we **must**
3837 // put in place the Read/Write part here. Keeping the write lock
3838 // here is 'catasptrophic' for scaling as it means that ALL calls
3839 // to RecursiveRemove will take the write lock and performance
3840 // of many threads trying to access the write lock at the same
3841 // time is relatively bad.
3843 // Note that fgSetOfSpecials is supposed to be updated by TClingCallbacks::tryFindROOTSpecialInternal
3844 // (but isn't at the moment).
3845 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3846 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3847 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3849 DeleteGlobal(obj);
3850 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3851 }
3852 }
3853}
3854
3855////////////////////////////////////////////////////////////////////////////////
3856/// Pressing Ctrl+C should forward here. In the case where we have had
3857/// continuation requested we must reset it.
3858
3860{
3861 fMetaProcessor->cancelContinuation();
3862 // Reset the Cling state to the state saved by the last call to
3863 // TCling::SaveContext().
3864#if defined(R__MUST_REVISIT)
3865#if R__MUST_REVISIT(6,2)
3867 Warning("Reset","Cling should support the equivalent of scratch_upto(&fDictPos)");
3868#endif
3869#endif
3870}
3871
3872////////////////////////////////////////////////////////////////////////////////
3873/// Reset the Cling state to its initial state.
3874
3876{
3877#if defined(R__MUST_REVISIT)
3878#if R__MUST_REVISIT(6,2)
3880 Warning("ResetAll","Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3881#endif
3882#endif
3883}
3884
3885////////////////////////////////////////////////////////////////////////////////
3886/// Reset in Cling the list of global variables to the state saved by the last
3887/// call to TCling::SaveGlobalsContext().
3888///
3889/// Note: Right now, all we do is run the global destructors.
3890
3892{
3894 // TODO:
3895 // Here we should iterate over the transactions (N-3) and revert.
3896 // N-3 because the first three internal to cling.
3897
3898 fInterpreter->runAndRemoveStaticDestructors();
3899}
3900
3901////////////////////////////////////////////////////////////////////////////////
3902/// Reset the Cling 'user' global objects/variables state to the state saved by the last
3903/// call to TCling::SaveGlobalsContext().
3904
3906{
3907#if defined(R__MUST_REVISIT)
3908#if R__MUST_REVISIT(6,2)
3910 Warning("ResetGlobalVar","Cling should support the equivalent of resetglobalvar(obj)");
3911#endif
3912#endif
3913}
3914
3915////////////////////////////////////////////////////////////////////////////////
3916/// Rewind Cling dictionary to the point where it was before executing
3917/// the current macro. This function is typically called after SEGV or
3918/// ctlr-C after doing a longjmp back to the prompt.
3919
3921{
3922#if defined(R__MUST_REVISIT)
3923#if R__MUST_REVISIT(6,2)
3925 Warning("RewindDictionary","Cling should provide a way to revert transaction similar to rewinddictionary()");
3926#endif
3927#endif
3928}
3929
3930////////////////////////////////////////////////////////////////////////////////
3931/// Delete obj from Cling symbol table so it cannot be accessed anymore.
3932/// Returns 1 in case of success and 0 in case object was not in table.
3933
3935{
3936#if defined(R__MUST_REVISIT)
3937#if R__MUST_REVISIT(6,2)
3939 Warning("DeleteGlobal","Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3940#endif
3941#endif
3942 return 0;
3943}
3944
3945////////////////////////////////////////////////////////////////////////////////
3946/// Undeclare obj called name.
3947/// Returns 1 in case of success, 0 for failure.
3948
3950{
3951#if defined(R__MUST_REVISIT)
3952#if R__MUST_REVISIT(6,2)
3953 Warning("DeleteVariable","should do more that just reseting the value to zero");
3954#endif
3955#endif
3956
3958 llvm::StringRef srName(name);
3959 const char* unscopedName = name;
3960 llvm::StringRef::size_type posScope = srName.rfind("::");
3961 const clang::DeclContext* declCtx = nullptr;
3962 if (posScope != llvm::StringRef::npos) {
3963 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3964 const clang::Decl* scopeDecl
3965 = lh.findScope(srName.substr(0, posScope),
3966 cling::LookupHelper::WithDiagnostics);
3967 if (!scopeDecl) {
3968 Error("DeleteVariable", "Cannot find enclosing scope for variable %s",
3969 name);
3970 return 0;
3971 }
3972 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3973 if (!declCtx) {
3974 Error("DeleteVariable",
3975 "Enclosing scope for variable %s is not a declaration context",
3976 name);
3977 return 0;
3978 }
3979 unscopedName += posScope + 2;
3980 }
3981 // Could trigger deserialization of decls.
3982 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
3983 clang::NamedDecl* nVarDecl
3984 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3985 if (!nVarDecl) {
3986 Error("DeleteVariable", "Unknown variable %s", name);
3987 return 0;
3988 }
3989 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3990 if (!varDecl) {
3991 Error("DeleteVariable", "Entity %s is not a variable", name);
3992 return 0;
3993 }
3994
3995 clang::QualType qType = varDecl->getType();
3996 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3997 // Cannot set a reference's address to nullptr; the JIT can place it
3998 // into read-only memory (ROOT-7100).
3999 if (type->isPointerType()) {
4000 int** ppInt = (int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
4001 // set pointer to invalid.
4002 if (ppInt) *ppInt = nullptr;
4003 }
4004 return 1;
4005}
4006
4007////////////////////////////////////////////////////////////////////////////////
4008/// Save the current Cling state.
4009
4011{
4012#if defined(R__MUST_REVISIT)
4013#if R__MUST_REVISIT(6,2)
4015 Warning("SaveContext","Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
4016#endif
4017#endif
4018}
4019
4020////////////////////////////////////////////////////////////////////////////////
4021/// Save the current Cling state of global objects.
4022
4024{
4025#if defined(R__MUST_REVISIT)
4026#if R__MUST_REVISIT(6,2)
4028 Warning("SaveGlobalsContext","Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
4029#endif
4030#endif
4031}
4032
4033////////////////////////////////////////////////////////////////////////////////
4034/// No op: see TClingCallbacks (used to update the list of globals)
4035
4039
4040////////////////////////////////////////////////////////////////////////////////
4041/// No op: see TClingCallbacks (used to update the list of global functions)
4042
4046
4047////////////////////////////////////////////////////////////////////////////////
4048/// No op: see TClingCallbacks (used to update the list of types)
4049
4051{
4052}
4053
4054////////////////////////////////////////////////////////////////////////////////
4055/// Check in what order the member of a tuple are layout.
4056enum class ETupleOrdering {
4057 kAscending,
4060};
4061
4067
4073
4075{
4076 std::tuple<int,double> value;
4079
4080 size_t offset0 = ((char*)&(std::get<0>(value))) - ((char*)&value);
4081 size_t offset1 = ((char*)&(std::get<1>(value))) - ((char*)&value);
4082
4083 size_t ascOffset0 = ((char*)&(asc._0)) - ((char*)&asc);
4084 size_t ascOffset1 = ((char*)&(asc._1)) - ((char*)&asc);
4085
4086 size_t desOffset0 = ((char*)&(des._0)) - ((char*)&des);
4087 size_t desOffset1 = ((char*)&(des._1)) - ((char*)&des);
4088
4089 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
4091 } else if (offset0 == desOffset0 && offset1 == desOffset1) {
4093 } else {
4095 }
4096}
4097
4098static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh, Bool_t silent)
4099{
4101 std::string alternateName = "TEmulatedTuple";
4102 alternateName.append( classname + 5 );
4103
4104 std::string fullname = "ROOT::Internal::" + alternateName;
4105 if (lh.findScope(fullname, cling::LookupHelper::NoDiagnostics,
4106 /*resultType*/nullptr, /* intantiateTemplate= */ false))
4107 return fullname;
4108
4109 {
4110 // Check if we can produce the tuple
4111 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
4112 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
4113 auto deleter = [](TypeInfo_t *type) {
4114 gInterpreter->TypeInfo_Delete(type);
4115 };
4116 std::unique_ptr<TypeInfo_t, decltype(deleter)> type{ gInterpreter->TypeInfo_Factory(), deleter };
4117 while (iter != theEnd) {
4118 gInterpreter->TypeInfo_Init(type.get(), iter->c_str());
4119 if (gInterpreter->TypeInfo_Property(type.get()) & kIsNotReacheable) {
4120 if (!silent)
4121 Error("Load","Could not declare alternate type for %s since %s (or one of its context) is private or protected",
4122 classname, iter->c_str());
4123 return "";
4124 }
4125 ++iter;
4126 }
4127 }
4128
4129 std::string guard_name;
4131 std::ostringstream guard;
4132 guard << "ROOT_INTERNAL_TEmulated_";
4133 guard << guard_name;
4134
4135 std::ostringstream alternateTuple;
4136 std::ostringstream initializers;
4137
4138 alternateTuple << "#ifndef " << guard.str() << "\n";
4139 alternateTuple << "#define " << guard.str() << "\n";
4140 alternateTuple << "namespace ROOT { namespace Internal {\n";
4141 alternateTuple << "template <class... Types> struct TEmulatedTuple;\n";
4142 alternateTuple << "template <> struct " << alternateName << " {\n";
4143
4144 // This could also be a compile time choice ...
4145 switch(IsTupleAscending()) {
4147 unsigned int nMember = 0;
4148 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
4149 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
4150 auto sep = ':';
4151 while (iter != theEnd) {
4152 alternateTuple << " " << *iter << " _" << nMember << ";\n";
4153 initializers << " " << sep << " _" << nMember << "(std::get<" << nMember << ">(std::forward<Tuple>(t)))\n";
4154 ++iter;
4155 ++nMember;
4156 sep = ',';
4157 }
4158 break;
4159 }
4161 unsigned int nMember = tupleContent.fElements.size() - 3;
4162 auto iter = tupleContent.fElements.rbegin() + 1; // skip the 'stars'.
4163 auto theEnd = tupleContent.fElements.rend() - 1; // Skip the template name (tuple).
4164 auto sep = ':';
4165 while (iter != theEnd) {
4166 alternateTuple << " " << *iter << " _" << nMember << ";\n";
4167 initializers << " " << sep << " _" << nMember << "(std::get<" << nMember << ">(std::forward<Tuple>(t)))\n";
4168 ++iter;
4169 --nMember;
4170 sep = ',';
4171 }
4172 break;
4173 }
4175 Fatal("TCling::SetClassInfo::AlternateTuple",
4176 "Layout of std::tuple on this platform is unexpected.");
4177 break;
4178 }
4179 }
4180
4181 // default constructor
4182 alternateTuple << " TEmulatedTuple() = default;\n";
4183
4184 // constructor from other tuple-like types, like std::tuple
4185 alternateTuple << " template <typename Tuple>\n";
4186 alternateTuple << " TEmulatedTuple(Tuple&& t)\n";
4188 alternateTuple << " {}\n";
4189
4190 alternateTuple << "};\n";
4191 alternateTuple << "}}\n";
4192 alternateTuple << "#endif\n";
4193 if (!gCling->Declare(alternateTuple.str().c_str()))
4194 {
4195 // Declare is not silent (yet?), so add an explicit error message
4196 // to indicate the consequence of the syntax errors.
4197 Error("Load","Could not declare %s",alternateName.c_str());
4198 return "";
4199 }
4200 alternateName = "ROOT::Internal::" + alternateName;
4201 return alternateName;
4202}
4203
4204////////////////////////////////////////////////////////////////////////////////
4205/// Set pointer to the TClingClassInfo in TClass.
4206/// If 'reload' is true, (attempt to) generate a new ClassInfo even if we
4207/// already have one.
4208/// If 'classInfo' is non-null, take ownership of it and use it instead of
4209/// looking up the class again; it must have been obtained from a call to
4210/// CheckClassInfo(cl->GetName(), ...).
4211
4213{
4214 // Whether we use it below or not, we own the passed class info.
4215 std::unique_ptr<TClingClassInfo> providedInfo{(TClingClassInfo *)classInfo};
4216
4217 // A provided class info is a cached lookup result; honoring it would defeat
4218 // the point of a reload, which is to redo the lookup.
4219 if (reload)
4220 providedInfo.reset();
4221
4222 // We are shutting down, there is no point in reloading, it only triggers
4223 // redundant deserializations.
4224 if (fIsShuttingDown) {
4225 // Remove the decl_id from the DeclIdToTClass map
4226 if (cl->fClassInfo) {
4229 // Test again as another thread may have set fClassInfo to nullptr.
4230 if (TClinginfo) {
4232 }
4233 delete TClinginfo;
4234 cl->fClassInfo = nullptr;
4235 }
4236 return;
4237 }
4238
4240 if (cl->fClassInfo && !reload) {
4241 return;
4242 }
4243 //Remove the decl_id from the DeclIdToTClass map
4245 if (TClinginfo) {
4247 }
4248 delete TClinginfo;
4249 cl->fClassInfo = nullptr;
4250 std::string name(cl->GetName());
4251
4252 auto SetWithoutClassInfoState = [](TClass *cl)
4253 {
4254 if (cl->fState != TClass::kHasTClassInit) {
4255 if (cl->fStreamerInfo->GetEntries() != 0) {
4257 } else {
4259 }
4260 }
4261 };
4262 // Handle the special case of 'tuple' where we ignore the real implementation
4263 // details and just overlay a 'simpler'/'simplistic' version that is easy
4264 // for the I/O to understand and handle.
4265 if (strncmp(cl->GetName(),"tuple<",std::char_traits<char>::length("tuple<"))==0) {
4266 // A provided class info would describe the real std::tuple, not the
4267 // alternate version overlaid below: it cannot be used.
4268 providedInfo.reset();
4269 if (!reload)
4270 name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper(), silent);
4271 if (reload || name.empty()) {
4272 // We could not generate the alternate
4274 return;
4275 }
4276 }
4277
4279 // FIXME: Rather than adding an option to the TClingClassInfo, we should consider combining code
4280 // that is currently in the caller (like SetUnloaded) that disable AutoLoading and AutoParsing and
4281 // code is in the callee (disabling template instantiation) and end up with a more explicit class:
4282 // TClingClassInfoReadOnly.
4285 if (!info->IsValid()) {
4287 delete info;
4288 return;
4289 }
4290 cl->fClassInfo = (ClassInfo_t*)info; // Note: We are transferring ownership here.
4291 // In case a class contains an external enum, the enum will be seen as a
4292 // class. We must detect this special case and make the class a Zombie.
4293 // Here we assume that a class has at least one method.
4294 // We can NOT call TClass::Property from here, because this method
4295 // assumes that the TClass is well formed to do a lot of information
4296 // caching. The method SetClassInfo (i.e. here) is usually called during
4297 // the building phase of the TClass, hence it is NOT well formed yet.
4299 if (
4300 info->IsValid() &&
4301 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
4302 ) {
4304 }
4305 if (!info->IsLoaded()) {
4306 if (info->Property() & (kIsNamespace)) {
4307 // Namespaces can have info but no corresponding CINT dictionary
4308 // because they are auto-created if one of their contained
4309 // classes has a dictionary.
4311 }
4312 // this happens when no dictionary is available
4313 delete info;
4314 cl->fClassInfo = nullptr;
4315 }
4316 if (zombieCandidate && !cl->GetCollectionType()) {
4317 cl->MakeZombie();
4318 }
4319 // If we reach here, the info was valid (See early returns).
4320 if (cl->fState != TClass::kHasTClassInit) {
4321 if (cl->fClassInfo) {
4323 } else {
4324// if (TClassEdit::IsSTLCont(cl->GetName()) {
4325// There will be an emulated collection proxy, is that the same?
4326// cl->fState = TClass::kEmulated;
4327// } else {
4328 if (cl->fStreamerInfo->GetEntries() != 0) {
4330 } else {
4332 }
4333// }
4334 }
4335 }
4336 if (cl->fClassInfo) {
4337 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
4338 }
4339}
4340
4341////////////////////////////////////////////////////////////////////////////////
4342/// Checks if an entity with the specified name is defined in Cling.
4343/// Returns kUnknown if the entity is not defined.
4344/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
4345/// Returns kKnown if the entity is defined.
4346///
4347/// By default, structs, namespaces, classes, enums and unions are looked for.
4348/// If the flag isClassOrNamespaceOnly is true, classes, structs and
4349/// namespaces only are considered. I.e. if the name is an enum or a union,
4350/// the returned value is false.
4351///
4352/// In the case where the class is not loaded and belongs to a namespace
4353/// or is nested, looking for the full class name is outputting a lots of
4354/// (expected) error messages. Currently the only way to avoid this is to
4355/// specifically check that each level of nesting is already loaded.
4356/// In case of templates the idea is that everything between the outer
4357/// '<' and '>' has to be skipped, e.g.: `aap<pippo<noot>::klaas>::a_class`
4358///
4359/// If 'classInfo' is non-null and the lookup found a declaration (which
4360/// findScope only returns if it points to a complete definition, i.e. when no
4361/// template instantiation would be needed to create it), '*classInfo' is set
4362/// to a newly allocated TClingClassInfo for that declaration, owned by the
4363/// caller. Passing it to SetClassInfo() avoids repeating the lookup there.
4364
4366 Bool_t isClassOrNamespaceOnly /* = kFALSE*/,
4367 ClassInfo_t **classInfo /* = nullptr*/)
4368{
4370 if (classInfo)
4371 *classInfo = nullptr;
4372 static const char *anonEnum = "anonymous enum ";
4373 static const int cmplen = strlen(anonEnum);
4374
4375 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
4376 return kUnknown;
4377 }
4378
4379 // Do not turn on the AutoLoading if it is globally off.
4381
4382 // Avoid the double search below in case the name is a fundamental type
4383 // or typedef to a fundamental type.
4384 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
4385 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
4386
4388 && fundType->GetType() > 0) {
4389 // Fundamental type, no a class.
4390 return kUnknown;
4391 }
4392
4393 // Migrated from within TClass::GetClass
4394 // If we want to know if a class or a namespace with this name exists in the
4395 // interpreter and this is an enum in the type system, before or after loading
4396 // according to the autoload function argument, return kUnknown.
4398 return kUnknown;
4399
4400 const char *classname = name;
4401
4402 // RAII to suspend and restore auto-loading and auto-parsing based on some external conditions.
4404 int fStoreAutoLoad = 0;
4405 int fStoreAutoParse = 0;
4406 bool fSuspendedAutoParse = false;
4407 public:
4409 fStoreAutoLoad = ((TCling*)gCling)->SetClassAutoLoading(autoload);
4410 }
4411
4412 void SuspendAutoParsing() {
4413 fSuspendedAutoParse = true;
4414 fStoreAutoParse = ((TCling*)gCling)->SetSuspendAutoParsing(true);
4415 }
4416
4419 ((TCling*)gCling)->SetSuspendAutoParsing(fStoreAutoParse);
4420 ((TCling*)gCling)->SetClassAutoLoading(fStoreAutoLoad);
4421 }
4422 };
4423
4425 if (TClassEdit::IsStdPair(classname) || TClassEdit::IsStdPairBase(classname))
4426 autoLoadParseRAII.SuspendAutoParsing();
4427
4428 // First we want to check whether the decl exist, but _without_
4429 // generating any template instantiation. However, the lookup
4430 // still will create a forward declaration of the class template instance
4431 // if it exist. In this case, the return value of findScope will still
4432 // be zero but the type will be initialized.
4433 // Note in the corresponding code in ROOT 5, CINT was not instantiating
4434 // this forward declaration.
4435 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4436 const clang::Type *type = nullptr;
4437 const clang::Decl *decl
4438 = lh.findScope(classname,
4439 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4440 : cling::LookupHelper::NoDiagnostics,
4441 &type, /* intantiateTemplate= */ false );
4442 if (!decl) {
4443 // Use a separate output type for the retry: findScope does not write it
4444 // on every path (e.g. when finding a namespace), and the type left over
4445 // from the lookup above must not be paired with this lookup's decl.
4446 const clang::Type *typeFromStd = nullptr;
4447 std::string buf = TClassEdit::InsertStd(classname);
4448 decl = lh.findScope(buf, gDebug > 5 ? cling::LookupHelper::WithDiagnostics : cling::LookupHelper::NoDiagnostics,
4449 &typeFromStd, false);
4450 if (decl || typeFromStd)
4451 type = typeFromStd;
4452 }
4453
4454 // If requested and an entity was found by the lookup above, hand a class
4455 // info for it out to the caller (see the function documentation).
4456 auto provideClassInfo = [this, classInfo, &decl, &type] {
4457 if (classInfo && decl && !decl->isInvalidDecl())
4459 };
4460
4461 if (type) {
4462 // If decl==0 and the type is valid, then we have a forward declaration.
4463 if (!decl) {
4464 // If we have a forward declaration for a class template instantiation,
4465 // we want to ignore it if it was produced/induced by the call to
4466 // findScope, however we can not distinguish those from the
4467 // instantiation induce by 'soft' use (and thus also induce by the
4468 // same underlying code paths)
4469 // ['soft' use = use not requiring a complete definition]
4470 // So to reduce the amount of disruption to the existing code we
4471 // would just ignore those for STL collection, for which we really
4472 // need to have the compiled collection proxy (and thus the TClass
4473 // bootstrap).
4474 clang::ClassTemplateSpecializationDecl *tmpltDecl =
4475 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
4476 (type->getAsCXXRecordDecl());
4477 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
4478 // Since the point of instantiation is invalid, we 'guess' that
4479 // the 'instantiation' of the forwarded type appended in
4480 // findscope.
4482 // For STL Collection we return kUnknown.
4483 return kUnknown;
4484 }
4485 }
4486 }
4488 if (!tci.IsValid()) {
4489 return kUnknown;
4490 }
4493
4494 if (tci.Property() & propertiesMask) {
4495 bool hasClassDefInline = false;
4497 // We do not need to check for ClassDefInline when this is called from
4498 // TClass::Init, we only do it for the call from TClass::GetClass.
4499 auto hasDictionary = tci.GetMethod("Dictionary", "", false, nullptr, ROOT::kExactMatch);
4500 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, nullptr, ROOT::kExactMatch);
4501
4502 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
4503 int lineNumber = 0;
4504 bool success = false;
4505 std::tie(success, lineNumber) =
4508 }
4509 }
4510
4511 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
4512 // , hasClassDefInline);
4513
4514 // We are now sure that the entry is not in fact an autoload entry.
4517 return kWithClassDefInline;
4518 else
4519 return kKnown;
4520 } else {
4521 // We are now sure that the entry is not in fact an autoload entry.
4522 return kUnknown;
4523 }
4524 }
4525
4526 if (decl) {
4528 return kKnown;
4529 } else
4530 return kUnknown;
4531
4532 // Setting up iterator part of TClingTypedefInfo is too slow.
4533 // Copy the lookup code instead:
4534 /*
4535 TClingTypedefInfo t(fInterpreter, name);
4536 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
4537 delete[] classname;
4538 return kTRUE;
4539 }
4540 */
4541
4542// const clang::Decl *decl = lh.findScope(name);
4543// if (!decl) {
4544// std::string buf = TClassEdit::InsertStd(name);
4545// decl = lh.findScope(buf);
4546// }
4547
4548// return (decl);
4549}
4550
4551////////////////////////////////////////////////////////////////////////////////
4552/// Return true if there is a class template by the given name ...
4553
4555{
4556 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4557 // Interpreter transaction ahead, needs locking
4559 const clang::Decl *decl
4560 = lh.findClassTemplate(name,
4561 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4562 : cling::LookupHelper::NoDiagnostics);
4563 if (!decl) {
4564 std::string strname = "std::";
4565 strname += name;
4566 decl = lh.findClassTemplate(strname,
4567 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4568 : cling::LookupHelper::NoDiagnostics);
4569 }
4570 return nullptr != decl;
4571}
4572
4573////////////////////////////////////////////////////////////////////////////////
4574/// Create list of pointers to base class(es) for TClass cl.
4575
4577{
4579 if (cl->fBase) {
4580 return;
4581 }
4582 // Ignore the base class (e.g. `std::_Complex_base` on Windows)
4584 cl->fBase = new TList();
4585 return;
4586 }
4588 if (!tci) return;
4590 TList *listOfBase = new TList;
4591 while (t.Next()) {
4592 // if name cannot be obtained no use to put in list
4593 if (t.IsValid() && t.Name()) {
4595 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
4596 }
4597 }
4598 // Now that is complete, publish it.
4599 cl->fBase = listOfBase;
4600}
4601
4602////////////////////////////////////////////////////////////////////////////////
4603/// Create list of pointers to enums for TClass cl.
4604
4606{
4608
4609 const Decl * D;
4610 TClass* cl = enumList.GetClass();
4611 if (cl) {
4612 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4613 }
4614 else {
4615 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4616 }
4617 // Iterate on the decl of the class and get the enums.
4618 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4619 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4620 // Collect all contexts of the namespace.
4621 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4622 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4624 declIter != declEnd; ++declIter) {
4625 // Iterate on all decls for each context.
4626 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4627 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4628 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4629 // Get name of the enum type.
4630 std::string buf;
4631 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4632 llvm::raw_string_ostream stream(buf);
4633 // Don't trigger fopen of the source file to count lines:
4634 Policy.AnonymousTagLocations = false;
4635 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
4636 stream.flush();
4637 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
4638 if (!buf.empty()) {
4639 const char* name = buf.c_str();
4640 // Add the enum to the list of loaded enums.
4641 enumList.Get(ED, name);
4642 }
4643 }
4644 }
4645 }
4646 }
4647}
4648
4649////////////////////////////////////////////////////////////////////////////////
4650/// Create list of pointers to function templates for TClass cl.
4651
4653{
4655
4656 const Decl * D;
4658 if (cl) {
4659 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4661 }
4662 else {
4663 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4664 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4665 }
4666 // Iterate on the decl of the class and get the enums.
4667 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4668 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4669 // Collect all contexts of the namespace.
4670 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4671 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4674 // Iterate on all decls for each context.
4675 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4676 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4677 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4678 funcTempList->Get(FTD);
4679 }
4680 }
4681 }
4682 }
4683}
4684
4685////////////////////////////////////////////////////////////////////////////////
4686/// Get the scopes representing using declarations of namespace
4687
4688std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4689{
4691 return ci->GetUsingNamespaces();
4692}
4693
4694////////////////////////////////////////////////////////////////////////////////
4695/// Create list of pointers to data members for TClass cl.
4696/// This is now a nop. The creation and updating is handled in
4697/// TListOfDataMembers.
4698
4700{
4701}
4702
4703////////////////////////////////////////////////////////////////////////////////
4704/// Create list of pointers to methods for TClass cl.
4705/// This is now a nop. The creation and updating is handled in
4706/// TListOfFunctions.
4707
4709{
4710}
4711
4712////////////////////////////////////////////////////////////////////////////////
4713/// Update the list of pointers to method for TClass cl
4714/// This is now a nop. The creation and updating is handled in
4715/// TListOfFunctions.
4716
4718{
4719}
4720
4721////////////////////////////////////////////////////////////////////////////////
4722/// Update the list of pointers to data members for TClass cl
4723/// This is now a nop. The creation and updating is handled in
4724/// TListOfDataMembers.
4725
4727{
4728}
4729
4730////////////////////////////////////////////////////////////////////////////////
4731/// Create list of pointers to method arguments for TMethod m.
4732
4734{
4736 if (m->fMethodArgs) {
4737 return;
4738 }
4739 TList *arglist = new TList;
4741 while (t.Next()) {
4742 if (t.IsValid()) {
4744 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4745 }
4746 }
4747 m->fMethodArgs = arglist;
4748}
4749
4750////////////////////////////////////////////////////////////////////////////////
4751/// Return whether we are waiting for more input either because the collected
4752/// input contains unbalanced braces or last seen token was a `\` (backslash-newline)
4753
4755{
4756 return fMetaProcessor->awaitingMoreInput();
4757}
4758
4759////////////////////////////////////////////////////////////////////////////////
4760/// Generate a TClass for the given class.
4761/// Since the caller has already check the ClassInfo, let it give use the
4762/// result (via the value of emulation) rather than recalculate it.
4763
4764TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4765{
4766// For now the following line would lead to the (unwanted) instantiation
4767// of class template. This could/would need to be resurrected only if
4768// we re-introduce so sort of automatic instantiation. However this would
4769// have to include carefull look at the template parameter to avoid
4770// creating instance we can not really use (if the parameter are only forward
4771// declaration or do not have all the necessary interfaces).
4772
4773 // TClingClassInfo tci(fInterpreter, classname);
4774 // if (1 || !tci.IsValid()) {
4775
4776 Version_t version = 1;
4777 if (TClassEdit::IsSTLCont(classname)) {
4778 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4779 }
4781 TClass *cl = new TClass(classname, version, silent);
4782 if (!emulation) {
4783 // Set the class version if the class is versioned.
4784 // Note that we cannot just call CLASS::Class_Version() as we might not have
4785 // an execution engine (when invoked from rootcling).
4786
4787 // Do not call cl->GetClassVersion(), it has side effects!
4789 if (oldvers == version && cl->GetClassInfo()) {
4790 // We have a version and it might need an update.
4792 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4793 // Namespaces don't have class versions.
4794 return cl;
4795 }
4796 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", nullptr /*poffset*/,
4799 if (!mi.IsValid()) {
4800 if (cl->TestBit(TClass::kIsTObject)) {
4801 Error("GenerateTClass",
4802 "Cannot find %s::Class_Version()! Class version might be wrong.",
4803 cl->GetName());
4804 }
4805 return cl;
4806 }
4807 Version_t newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4808 *fInterpreter);
4809 if (newvers == -1) {
4810 // Didn't manage to determine the class version from the AST.
4811 // Use runtime instead.
4812 if ((mi.Property() & kIsStatic)
4813 && !fInterpreter->isInSyntaxOnlyMode()) {
4814 // This better be a static function.
4816 callfunc.SetFunc(&mi);
4817 newvers = callfunc.ExecInt(nullptr);
4818 } else {
4819 Error("GenerateTClass",
4820 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4821 cl->GetName());
4822 }
4823 }
4824 if (newvers != oldvers) {
4825 cl->fClassVersion = newvers;
4826 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4827 }
4828 }
4829 }
4830
4831 return cl;
4832
4833// } else {
4834// return GenerateTClass(&tci,silent);
4835// }
4836}
4837
4838#if 0
4839////////////////////////////////////////////////////////////////////////////////
4840
4841static void GenerateTClass_GatherInnerIncludes(cling::Interpreter *interp, TString &includes,TClingClassInfo *info)
4842{
4843 includes += info->FileName();
4844
4845 const clang::ClassTemplateSpecializationDecl *templateCl
4846 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4847 if (templateCl) {
4848 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4849 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4850 if (arg.getKind() == clang::TemplateArgument::Type) {
4851 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4852
4853 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4854 // We really need a header file.
4855 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4856 if (argdecl) {
4857 includes += ";";
4858 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4860 } else {
4861 std::string Result;
4862 llvm::raw_string_ostream OS(Result);
4863 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4864 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4865 }
4866 }
4867 }
4868 }
4869 }
4870}
4871#endif
4872
4873////////////////////////////////////////////////////////////////////////////////
4874/// Generate a TClass for the given class.
4875
4877{
4879 if (!info || !info->IsValid()) {
4880 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4881 return nullptr;
4882 }
4883 // We are in the case where we have AST nodes for this class.
4884 TClass *cl = nullptr;
4885 std::string classname;
4886 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4887 if (TClassEdit::IsSTLCont(classname)) {
4888#if 0
4889 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4890 // We need to build up the list of required headers, by
4891 // looking at each template arguments.
4892 TString includes;
4894
4895 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4896 // 0 means success.
4897 cl = TClass::LoadClass(classnam.c_str(), silent);
4898 if (cl == 0) {
4899 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4900 }
4901 }
4902#endif
4903 if (cl == nullptr) {
4904 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4905 cl = new TClass(classinfo, version, nullptr, nullptr, -1, -1, silent);
4906 }
4907 } else {
4908 // For regular class, just create a TClass on the fly ...
4909 // Not quite useful yet, but that what CINT used to do anyway.
4910 cl = new TClass(classinfo, 1, nullptr, nullptr, -1, -1, silent);
4911 }
4912 // Add the new TClass to the map of declid and TClass*.
4913 if (cl) {
4915 }
4916 return cl;
4917}
4918
4919////////////////////////////////////////////////////////////////////////////////
4920/// Generate the dictionary for the C++ classes listed in the first
4921/// argument (in a semi-colon separated list).
4922/// 'includes' contains a semi-colon separated list of file to
4923/// `#include` in the dictionary.
4924/// For example:
4925/// ~~~ {.cpp}
4926/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4927/// ~~~
4928/// or
4929/// ~~~ {.cpp}
4930/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4931/// ~~~
4932
4933Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4934{
4935 if (classes == nullptr || classes[0] == 0) {
4936 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4937 return 0;
4938 }
4939 // Split the input list
4940 std::vector<std::string> listClasses;
4941 for (
4942 const char* current = classes, *prev = classes;
4943 *current != 0;
4944 ++current
4945 ) {
4946 if (*current == ';') {
4947 listClasses.push_back(std::string(prev, current - prev));
4948 prev = current + 1;
4949 }
4950 else if (*(current + 1) == 0) {
4951 listClasses.push_back(std::string(prev, current + 1 - prev));
4952 prev = current + 1;
4953 }
4954 }
4955 std::vector<std::string> listIncludes;
4956 if (!includes)
4957 includes = "";
4958 for (
4959 const char* current = includes, *prev = includes;
4960 *current != 0;
4961 ++current
4962 ) {
4963 if (*current == ';') {
4964 listIncludes.push_back(std::string(prev, current - prev));
4965 prev = current + 1;
4966 }
4967 else if (*(current + 1) == 0) {
4968 listIncludes.push_back(std::string(prev, current + 1 - prev));
4969 prev = current + 1;
4970 }
4971 }
4972 // Generate the temporary dictionary file
4974 std::vector<std::string>(), std::vector<std::string>());
4975}
4976
4977////////////////////////////////////////////////////////////////////////////////
4978/// Return pointer to cling Decl of global/static variable that is located
4979/// at the address given by addr.
4980
4982{
4984 DeclId_t d;
4986
4987 // Could trigger deserialization of decls.
4988 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4989
4990 if (cl) {
4991 d = cl->GetDataMember(name);
4992 // We check if the decl of the data member has an annotation which indicates
4993 // an ioname.
4994 // In case this is true, if the name requested is not the ioname, we
4995 // return 0, as if the member did not exist. In some sense we override
4996 // the information in the TClassInfo instance, isolating the typesystem in
4997 // TClass from the one in the AST.
4998 if (const ValueDecl* decl = (const ValueDecl*) d){
4999 std::string ioName;
5001 if (hasIoName && ioName != name) return nullptr;
5002 }
5003 return d;
5004 }
5005 // We are looking up for something on the TU scope.
5006 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
5007 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
5008 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
5009 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
5010 // are only fulfilling ROOT's understanding for a Data Member.
5011 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
5012 // similar as below.
5013 using namespace clang;
5014 Sema& SemaR = fInterpreter->getSema();
5015 DeclarationName DName = &SemaR.Context.Idents.get(name);
5016
5017 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
5018 RedeclarationKind::ForExternalRedeclaration);
5019
5020 cling::utils::Lookup::Named(&SemaR, R);
5021
5022 LookupResult::Filter F = R.makeFilter();
5023 // Filter the data-member looking decls.
5024 while (F.hasNext()) {
5025 NamedDecl *D = F.next();
5028 continue;
5029 F.erase();
5030 }
5031 F.done();
5032
5033 if (R.isSingleResult())
5034 return R.getFoundDecl();
5035 return nullptr;
5036}
5037
5038////////////////////////////////////////////////////////////////////////////////
5039/// Return pointer to cling Decl of global/static variable that is located
5040/// at the address given by addr.
5041
5043{
5045
5046 const clang::Decl* possibleEnum = nullptr;
5047 // FInd the context of the decl.
5048 if (cl) {
5050 if (cci) {
5051 const clang::DeclContext* dc = nullptr;
5052 if (const clang::Decl* D = cci->GetDecl()) {
5053 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
5055 }
5056 }
5057 if (dc) {
5058 // If it is a data member enum.
5059 // Could trigger deserialization of decls.
5060 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
5061 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
5062 } else {
5063 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
5064 }
5065 }
5066 } else {
5067 // If it is a global enum.
5068 // Could trigger deserialization of decls.
5069 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
5070 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
5071 }
5072 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
5074 return possibleEnum;
5075 }
5076 return nullptr;
5077}
5078
5079////////////////////////////////////////////////////////////////////////////////
5080/// Return pointer to cling DeclId for a global value
5081
5082TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
5083{
5084 if (!gv) return nullptr;
5085
5086 llvm::StringRef mangled_name = gv->getName();
5087
5088 int err = 0;
5090 if (err) {
5091 if (err == -2) {
5092 // It might simply be an unmangled global name.
5093 DeclId_t d;
5095 d = gcl.GetDataMember(mangled_name.str().c_str());
5096 return d;
5097 }
5098 return nullptr;
5099 }
5100
5101 std::string scopename(demangled_name_c);
5103
5104 //
5105 // Separate out the class or namespace part of the
5106 // function name.
5107 //
5108 std::string dataname;
5109
5110 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
5111 scopename.erase(0, sizeof("typeinfo for ")-1);
5112 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
5113 scopename.erase(0, sizeof("vtable for ")-1);
5114 } else {
5115 // See if it is a function
5116 std::string::size_type pos = scopename.rfind('(');
5117 if (pos != std::string::npos) {
5118 return nullptr;
5119 }
5120 // Separate the scope and member name
5121 pos = scopename.rfind(':');
5122 if (pos != std::string::npos) {
5123 if ((pos != 0) && (scopename[pos-1] == ':')) {
5124 dataname = scopename.substr(pos+1);
5125 scopename.erase(pos-1);
5126 }
5127 } else {
5128 scopename.clear();
5130 }
5131 }
5132 //fprintf(stderr, "name: '%s'\n", name.c_str());
5133 // Now we have the class or namespace name, so do the lookup.
5134
5135
5136 DeclId_t d;
5137 if (scopename.size()) {
5139 d = cl.GetDataMember(dataname.c_str());
5140 }
5141 else {
5143 d = gcl.GetDataMember(dataname.c_str());
5144 }
5145 return d;
5146}
5147
5148////////////////////////////////////////////////////////////////////////////////
5149/// NOT IMPLEMENTED.
5150
5152{
5153 Error("GetDataMemberWithValue()", "not implemented");
5154 return nullptr;
5155}
5156
5157////////////////////////////////////////////////////////////////////////////////
5158/// Return pointer to cling DeclId for a data member with a given name.
5159
5161{
5162 // NOT IMPLEMENTED.
5163 Error("GetDataMemberAtAddr()", "not implemented");
5164 return nullptr;
5165}
5166
5167////////////////////////////////////////////////////////////////////////////////
5168/// Return the cling mangled name for a method of a class with parameters
5169/// params (params is a string of actual arguments, not formal ones). If the
5170/// class is 0 the global function list will be searched.
5171
5173 const char* params, Bool_t objectIsConst /* = kFALSE */)
5174{
5177 if (cl) {
5180 &offset);
5181 }
5182 else {
5185 func.SetFunc(&gcl, method, params, &offset);
5186 }
5188 if (!mi) return "";
5189 TString mangled_name( mi->GetMangledName() );
5190 delete mi;
5191 return mangled_name;
5192}
5193
5194////////////////////////////////////////////////////////////////////////////////
5195/// Return the cling mangled name for a method of a class with a certain
5196/// prototype, i.e. "char*,int,float". If the class is 0 the global function
5197/// list will be searched.
5198
5200 const char* proto, Bool_t objectIsConst /* = kFALSE */,
5201 EFunctionMatchMode mode /* = kConversionMatch */)
5202{
5204 if (cl) {
5205 return ((TClingClassInfo*)cl->GetClassInfo())->
5206 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
5207 }
5209 return gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
5210}
5211
5212////////////////////////////////////////////////////////////////////////////////
5213/// Return pointer to cling interface function for a method of a class with
5214/// parameters params (params is a string of actual arguments, not formal
5215/// ones). If the class is 0 the global function list will be searched.
5216
5218 const char* params, Bool_t objectIsConst /* = kFALSE */)
5219{
5222 if (cl) {
5225 &offset);
5226 }
5227 else {
5230 func.SetFunc(&gcl, method, params, &offset);
5231 }
5232 return (void*) func.InterfaceMethod();
5233}
5234
5235////////////////////////////////////////////////////////////////////////////////
5236/// Return pointer to cling interface function for a method of a class with
5237/// a certain name.
5238
5240{
5242 DeclId_t f;
5244 if (cl) {
5245 f = cl->GetMethod(method).GetDeclId();
5246 }
5247 else {
5249 f = gcl.GetMethod(method).GetDeclId();
5250 }
5251 return f;
5252
5253}
5254
5255////////////////////////////////////////////////////////////////////////////////
5256/// Insert overloads of name in cl to res.
5257
5259 std::vector<DeclId_t>& res) const
5260{
5261 clang::Sema& S = fInterpreter->getSema();
5262 clang::ASTContext& Ctx = S.Context;
5263 const clang::Decl* CtxDecl
5264 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
5265 Ctx.getTranslationUnitDecl();
5266 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
5267 const clang::DeclContext* DeclCtx = RecDecl;
5268
5269 if (!DeclCtx)
5271 if (!DeclCtx) return;
5272
5273 clang::DeclarationName DName;
5274 // The DeclarationName is funcname, unless it's a ctor or dtor.
5275 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
5276
5277 if (RecDecl) {
5278 if (RecDecl->getNameAsString() == funcname) {
5279 clang::CanQualType QT = Ctx.getCanonicalTagType(RecDecl);
5280 DName = Ctx.DeclarationNames.getCXXConstructorName(QT);
5281 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
5282 clang::CanQualType QT = Ctx.getCanonicalTagType(RecDecl);
5283 DName = Ctx.DeclarationNames.getCXXDestructorName(QT);
5284 } else {
5285 DName = &Ctx.Idents.get(funcname);
5286 }
5287 } else {
5288 DName = &Ctx.Idents.get(funcname);
5289 }
5290
5291 // NotForRedeclaration: we want to find names in inline namespaces etc.
5292 clang::LookupResult R(S, DName, clang::SourceLocation(), Sema::LookupOrdinaryName,
5293 RedeclarationKind::NotForRedeclaration);
5294 R.suppressDiagnostics(); // else lookup with NotForRedeclaration will check access etc
5295 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
5296 if (R.empty()) return;
5297 R.resolveKind();
5298 res.reserve(res.size() + (R.end() - R.begin()));
5299 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
5300 IR != ER; ++IR) {
5301 if (const clang::FunctionDecl* FD
5302 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
5303 if (!FD->getDescribedFunctionTemplate()) {
5304 res.push_back(FD);
5305 }
5306 } else if (const auto *USD = llvm::dyn_cast<const clang::UsingShadowDecl>(*IR)) {
5307 // FIXME: multi-level using
5308 if (llvm::isa<clang::FunctionDecl>(USD->getTargetDecl())) {
5309 res.push_back(USD);
5310 }
5311 }
5312 }
5313}
5314
5315////////////////////////////////////////////////////////////////////////////////
5316/// Return pointer to cling interface function for a method of a class with
5317/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5318/// function list will be searched.
5319
5321 const char* proto,
5322 Bool_t objectIsConst /* = kFALSE */,
5323 EFunctionMatchMode mode /* = kConversionMatch */)
5324{
5326 void* f;
5327 if (cl) {
5328 f = ((TClingClassInfo*)cl->GetClassInfo())->
5329 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5330 }
5331 else {
5333 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5334 }
5335 return f;
5336}
5337
5338////////////////////////////////////////////////////////////////////////////////
5339/// Return pointer to cling DeclId for a method of a class with
5340/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5341/// function list will be searched.
5342
5344 const char* params,
5345 Bool_t objectIsConst /* = kFALSE */)
5346{
5348 DeclId_t f;
5350 if (cl) {
5351 f = cl->GetMethodWithArgs(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5352 }
5353 else {
5355 f = gcl.GetMethod(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5356 }
5357 return f;
5358}
5359
5360////////////////////////////////////////////////////////////////////////////////
5361/// Return pointer to cling interface function for a method of a class with
5362/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5363/// function list will be searched.
5364
5366 const char* proto,
5367 Bool_t objectIsConst /* = kFALSE */,
5368 EFunctionMatchMode mode /* = kConversionMatch */)
5369{
5371 DeclId_t f;
5373 if (cl) {
5374 f = cl->GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5375 }
5376 else {
5378 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5379 }
5380 return f;
5381}
5382
5383////////////////////////////////////////////////////////////////////////////////
5384/// Return pointer to cling interface function for a method of a class with
5385/// a certain name.
5386
5388{
5390 DeclId_t f;
5392 if (cl) {
5393 f = cl->GetFunctionTemplate(name);
5394 }
5395 else {
5397 f = gcl.GetFunctionTemplate(name);
5398 }
5399 return f;
5400
5401}
5402
5403////////////////////////////////////////////////////////////////////////////////
5404/// The 'name' is known to the interpreter, this function returns
5405/// the internal version of this name (usually just resolving typedefs)
5406/// This is used in particular to synchronize between the name used
5407/// by rootcling and by the run-time environment (TClass)
5408/// Return 0 if the name is not known.
5409
5410void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
5411{
5412 output.clear();
5413
5415
5417 if (!cl.IsValid()) {
5418 return ;
5419 }
5420 if (full) {
5421 cl.FullName(output,*fNormalizedCtxt);
5422 return;
5423 }
5424 // Well well well, for backward compatibility we need to act a bit too
5425 // much like CINT.
5427 splitname.ShortType(output, TClassEdit::kDropStd );
5428
5429 return;
5430}
5431
5432////////////////////////////////////////////////////////////////////////////////
5433/// Execute a global function with arguments params.
5434///
5435/// FIXME: The cint-based version of this code does not check if the
5436/// SetFunc() call works, and does not do any real checking
5437/// for errors from the Exec() call. It did fetch the most
5438/// recent cint security error and return that in error, but
5439/// this does not really translate well to cling/clang. We
5440/// should enhance these interfaces so that we can report
5441/// compilation and runtime errors properly.
5442
5443void TCling::Execute(const char* function, const char* params, int* error)
5444{
5446 if (error) {
5447 *error = TInterpreter::kNoError;
5448 }
5450 Longptr_t offset = 0L;
5452 func.SetFunc(&cl, function, params, &offset);
5453 func.Exec(nullptr);
5454}
5455
5456////////////////////////////////////////////////////////////////////////////////
5457/// Execute a method from class cl with arguments params.
5458///
5459/// FIXME: The cint-based version of this code does not check if the
5460/// SetFunc() call works, and does not do any real checking
5461/// for errors from the Exec() call. It did fetch the most
5462/// recent cint security error and return that in error, but
5463/// this does not really translate well to cling/clang. We
5464/// should enhance these interfaces so that we can report
5465/// compilation and runtime errors properly.
5466
5467void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5468 const char* params, Bool_t objectIsConst, int* error)
5469{
5471 if (error) {
5472 *error = TInterpreter::kNoError;
5473 }
5474 // If the actual class of this object inherits 2nd (or more) from TObject,
5475 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5476 // hence gInterpreter->Execute will improperly correct the offset.
5477 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5478 Longptr_t offset = 0L;
5481 void* address = (void*)((Longptr_t)addr + offset);
5482 func.Exec(address);
5483}
5484
5485////////////////////////////////////////////////////////////////////////////////
5486
5487void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5488 const char* params, int* error)
5489{
5490 Execute(obj,cl,method,params,false,error);
5491}
5492
5493////////////////////////////////////////////////////////////////////////////////
5494/// Execute a method from class cl with the arguments in array params
5495/// (params[0] ... params[n] = array of TObjString parameters).
5496/// Convert the TObjArray array of TObjString parameters to a character
5497/// string of comma separated parameters.
5498/// The parameters of type 'char' are enclosed in double quotes and all
5499/// internal quotes are escaped.
5500
5502 TObjArray* params, int* error)
5503{
5504 if (!method) {
5505 Error("Execute", "No method was defined");
5506 return;
5507 }
5508 TList* argList = method->GetListOfMethodArgs();
5509 // Check number of actual parameters against of expected formal ones
5510
5511 Int_t nparms = argList->LastIndex() + 1;
5512 Int_t argc = params ? params->GetEntries() : 0;
5513
5514 if (argc > nparms) {
5515 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
5516 return;
5517 }
5518 if (nparms != argc) {
5519 // Let's see if the 'missing' argument are all defaulted.
5520 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
5521 assert(nparms > 0);
5522
5523 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
5524 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5525 // There is a default value for the first missing
5526 // argument, so we are fine.
5527 } else {
5528 Int_t firstDefault = -1;
5529 for (Int_t i = 0; i < nparms; i ++) {
5530 arg = (TMethodArg *) argList->At( i );
5531 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5532 firstDefault = i;
5533 break;
5534 }
5535 }
5536 if (firstDefault >= 0) {
5537 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);
5538 } else {
5539 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
5540 }
5541 return;
5542 }
5543 }
5544
5545 const char* listpar = "";
5546 TString complete(10);
5547 if (params) {
5548 // Create a character string of parameters from TObjArray
5549 TIter next(params);
5550 for (Int_t i = 0; i < argc; i ++) {
5551 TMethodArg* arg = (TMethodArg*) argList->At(i);
5553 TObjString* nxtpar = (TObjString*) next();
5554 if (i) {
5555 complete += ',';
5556 }
5557 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
5558 TString chpar('\"');
5559 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
5560 // At this point we have to check if string contains \\"
5561 // and apply some more sophisticated parser. Not implemented yet!
5562 complete += chpar;
5563 complete += '\"';
5564 }
5565 else {
5566 complete += nxtpar->String();
5567 }
5568 }
5569 listpar = complete.Data();
5570 }
5571
5572 // And now execute it.
5574 if (error) {
5575 *error = TInterpreter::kNoError;
5576 }
5577 // If the actual class of this object inherits 2nd (or more) from TObject,
5578 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5579 // hence gInterpreter->Execute will improperly correct the offset.
5580 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5583 func.Init(*minfo);
5584 func.SetArgs(listpar);
5585 // Now calculate the 'this' pointer offset for the method
5586 // when starting from the class described by cl.
5587 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetTargetFunctionDecl());
5588 Longptr_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
5589 void* address = (void*)((Longptr_t)addr + offset);
5590 func.Exec(address);
5591}
5592
5593////////////////////////////////////////////////////////////////////////////////
5594
5596 const void* args[] /*=0*/,
5597 int nargs /*=0*/,
5598 void* ret/*= 0*/) const
5599{
5600 if (!method) {
5601 Error("ExecuteWithArgsAndReturn", "No method was defined");
5602 return;
5603 }
5604
5606 TClingCallFunc func(*minfo);
5607 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5608}
5609
5610////////////////////////////////////////////////////////////////////////////////
5611/// Execute a cling macro.
5612
5614{
5616 fCurExecutingMacros.push_back(filename);
5618 fCurExecutingMacros.pop_back();
5619 return result;
5620}
5621
5622////////////////////////////////////////////////////////////////////////////////
5623/// Return the file name of the current un-included interpreted file.
5624/// See the documentation for GetCurrentMacroName().
5625
5627{
5628 Warning("GetTopLevelMacroName", "Must change return type!");
5629 return fCurExecutingMacros.empty() ? nullptr : fCurExecutingMacros.back();
5630}
5631
5632////////////////////////////////////////////////////////////////////////////////
5633/// Return the file name of the currently interpreted file,
5634/// included or not. Example to illustrate the difference between
5635/// GetCurrentMacroName() and GetTopLevelMacroName():
5636/// ~~~ {.cpp}
5637/// void inclfile() {
5638/// std::cout << "In inclfile.C" << std::endl;
5639/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5640/// TCling::GetCurrentMacroName() << std::endl;
5641/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5642/// TCling::GetTopLevelMacroName() << std::endl;
5643/// }
5644/// ~~~
5645/// ~~~ {.cpp}
5646/// void mymacro() {
5647/// std::cout << "In mymacro.C" << std::endl;
5648/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5649/// TCling::GetCurrentMacroName() << std::endl;
5650/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5651/// TCling::GetTopLevelMacroName() << std::endl;
5652/// std::cout << " Now calling inclfile..." << std::endl;
5653/// gInterpreter->ProcessLine(".x inclfile.C");
5654/// }
5655/// ~~~
5656/// Running mymacro.C will print:
5657///
5658/// ~~~ {.cpp}
5659/// root [0] .x mymacro.C
5660/// ~~~
5661/// In mymacro.C
5662/// ~~~ {.cpp}
5663/// TCling::GetCurrentMacroName() returns ./mymacro.C
5664/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5665/// ~~~
5666/// Now calling inclfile...
5667/// In inclfile.h
5668/// ~~~ {.cpp}
5669/// TCling::GetCurrentMacroName() returns inclfile.C
5670/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5671/// ~~~
5672
5674{
5675#if defined(R__MUST_REVISIT)
5676#if R__MUST_REVISIT(6,0)
5677 Warning("GetCurrentMacroName", "Must change return type!");
5678#endif
5679#endif
5680 return fCurExecutingMacros.empty() ? nullptr : fCurExecutingMacros.back();
5681}
5682
5683////////////////////////////////////////////////////////////////////////////////
5684/// Return the absolute type of typeDesc.
5685/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
5686/// You need to use the result immediately before it is being overwritten.
5687
5688const char* TCling::TypeName(const char* typeDesc)
5689{
5690 TTHREAD_TLS_DECL(std::string,t);
5691
5692 if (!strstr(typeDesc, "(*)(")) {
5693 const char *s = strchr(typeDesc, ' ');
5694 const char *template_start = strchr(typeDesc, '<');
5695 if (!strcmp(typeDesc, "long long")) {
5696 t = typeDesc;
5697 }
5698 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5699 t = typeDesc;
5700 }
5701 // s is the position of the second 'word' (if any)
5702 // except in the case of templates where there will be a space
5703 // just before any closing '>': eg.
5704 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5705 else if (s && (template_start == nullptr || (s < template_start))) {
5706 t = s + 1;
5707 }
5708 else {
5709 t = typeDesc;
5710 }
5711 }
5712 else {
5713 t = typeDesc;
5714 }
5715 auto l = t.length();
5716 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&'))
5717 --l;
5718 t.resize(l);
5719 return t.c_str(); // NOLINT
5720}
5721
5722static bool requiresRootMap(const char* rootmapfile)
5723{
5725
5726 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5727 libName.consume_back(".rootmap");
5728
5729 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5730}
5731
5732////////////////////////////////////////////////////////////////////////////////
5733/// Read and parse a rootmapfile in its new format, and return 0 in case of
5734/// success, -1 if the file has already been read, and -3 in case its format
5735/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5736/// error.
5737
5739{
5740 if (!(rootmapfile && *rootmapfile))
5741 return 0;
5742
5744 return 0; // success
5745
5746 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5747 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5748
5750#ifdef _MSC_VER
5751 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5752#endif
5753 // Add content of a specific rootmap file
5755 return -1;
5756
5757 // Line 1 is `{ decls }`
5758 std::string lineDirective = std::string("\n#line 2 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n";
5759
5760 std::ifstream file(rootmapfileNoBackslash);
5761 std::string line;
5762 line.reserve(200);
5763 std::string lib_name;
5764 line.reserve(100);
5765 bool newFormat = false;
5766 while (getline(file, line, '\n')) {
5767 if (!newFormat && (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5768 file.close();
5769 return -3; // old format
5770 }
5771 newFormat = true;
5772
5773 if (line.compare(0, 9, "{ decls }") == 0) {
5774 // forward declarations
5775
5776 while (getline(file, line, '\n')) {
5777 if (line[0] == '[')
5778 break;
5779 if (!uniqueString) {
5780 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5781 rootmapfileNoBackslash.c_str());
5782 return -4;
5783 }
5784 if (!lineDirective.empty())
5785 uniqueString->Append(lineDirective);
5786 uniqueString->Append(line + '\n');
5787 }
5788 }
5789 const char firstChar = line[0];
5790 if (firstChar == '[') {
5791 // new section (library)
5792 auto brpos = line.find(']');
5793 if (brpos == string::npos)
5794 continue;
5795 lib_name = line.substr(1, brpos - 1);
5796 // Remove spaces at the beginning and at the end of the library name
5797 lib_name.erase(lib_name.find_last_not_of(' ') + 1);
5798 lib_name.erase(0, lib_name.find_first_not_of(' '));
5799 if (gDebug > 3) {
5800 TString lib_nameTstr(lib_name.c_str());
5801 TObjArray *tokens = lib_nameTstr.Tokenize(" ");
5802 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5803 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5804 if (wlib) {
5805 Info("ReadRootmapFile", "%s: New section for %s", rootmapfile, lib_nameTstr.Data());
5806 } else {
5807 Info("ReadRootmapFile", "%s: Section for %s (library does not exist)", rootmapfile, lib_nameTstr.Data());
5808 }
5809 delete[] wlib;
5810 delete tokens;
5811 }
5812 } else {
5813 auto keyLenIt = keyLenMap.find(firstChar);
5814 if (keyLenIt == keyLenMap.end())
5815 continue;
5816 unsigned int keyLen = keyLenIt->second;
5817 // Do not make a copy, just start after the key
5818 const char *keyname = line.c_str() + keyLen;
5819 if (gDebug > 6)
5820 Info("ReadRootmapFile", "%s: class %s in %s", rootmapfile, keyname, lib_name.c_str());
5822 if (isThere) {
5823 if (lib_name != isThere->GetValue()) { // the same key for two different libs
5824 if (firstChar == 'n') {
5825 if (gDebug > 3)
5826 Info("ReadRootmapFile",
5827 "While processing %s, namespace %s was found to be associated to %s although it is already "
5828 "associated to %s",
5829 rootmapfile, keyname, lib_name.c_str(), isThere->GetValue());
5830 } else if (firstChar == 'h') { // it is a header: add the libname to the list of libs to be loaded.
5831 lib_name += " ";
5832 lib_name += isThere->GetValue();
5833 fMapfile->SetValue(keyname, lib_name.c_str());
5834 } else if (!TClassEdit::IsSTLCont(keyname)) {
5835 Warning("ReadRootmapFile",
5836 "While processing %s, %s %s was found to be associated to %s although it is already "
5837 "associated to %s",
5838 rootmapfile, line.substr(0, keyLen - 1).c_str(), keyname, lib_name.c_str(),
5839 isThere->GetValue());
5840 }
5841 } else { // the same key for the same lib
5842 if (gDebug > 3)
5843 Info("ReadRootmapFile", "While processing %s, key %s was found to be already defined for %s",
5844 rootmapfile, keyname, lib_name.c_str());
5845 }
5846 } else {
5847 fMapfile->SetValue(keyname, lib_name.c_str());
5848 }
5849 }
5850 }
5851 file.close();
5852 return 0;
5853}
5854
5855////////////////////////////////////////////////////////////////////////////////
5856/// Create a resource table and read the (possibly) three resource files,
5857/// i.e. `$ROOTSYS/etc/system<name>` (or `ROOTETCDIR/system<name>`), `$HOME/<name>`
5858/// and `$PWD/<name>`. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You
5859/// can read additional user defined resource files by creating additional TEnv
5860/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5861/// the `$HOME/<name>` resource file will be skipped. This might be useful in
5862/// case the home directory resides on an automounted remote file system
5863/// and one wants to avoid the file system from being mounted.
5864
5866{
5867 assert(requiresRootMap(name) && "We have a module!");
5868
5869 if (!requiresRootMap(name))
5870 return;
5871
5873
5875
5876 TString sname = "system";
5877 sname += name;
5880
5882 if (ret == -3) // old format
5884 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5888 if (ret == -3) // old format
5892 if (ret == -3) // old format
5894 }
5895 } else {
5897 if (ret == -3) // old format
5899 }
5901}
5902
5903
5904namespace {
5905 using namespace clang;
5906
5907 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5908 // This class is to be considered an helper for AutoLoading.
5909 // It is a recursive visitor is used to inspect namespaces and specializations
5910 // coming from forward declarations in rootmaps and to set the external visible
5911 // storage flag for them.
5912 public:
5913 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5914 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5915 // We want to enable the external lookup for this namespace
5916 // because it may shadow the lookup of other names contained
5917 // in that namespace
5918
5919 nsDecl->setHasExternalVisibleStorage();
5920 fNSSet.insert(nsDecl);
5921 return true;
5922 }
5924 // We want to enable the external lookup for this specialization
5925 // because we can provide a definition for it!
5926 if (specDecl->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
5927 //SpecSet.insert(specDecl);
5928 specDecl->setHasExternalLexicalStorage();
5929
5930 // No need to recurse. On the contrary, recursing is actively harmful:
5931 // NOTE: must not recurse to prevent this visitor from triggering loading from
5932 // the external AST source (i.e. autoloading). This would be triggered right here,
5933 // before autoloading is even set up, as rootmap file parsing happens before that.
5934 // Even if autoloading is off and has no effect, triggering loading from external
5935 // AST source resets the flag setHasExternalLexicalStorage(), hiding this specialization
5936 // from subsequent autoloads!
5937 return false;
5938 }
5939 private:
5940 std::unordered_set<const NamespaceDecl*>& fNSSet;
5941 };
5942}
5943
5944////////////////////////////////////////////////////////////////////////////////
5945/// Load map between class and library. If rootmapfile is specified a
5946/// specific rootmap file can be added (typically used by ACLiC).
5947/// In case of error -1 is returned, 0 otherwise.
5948/// The interpreter uses this information to automatically load the shared
5949/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5950
5952{
5954 return 0;
5955
5957
5958 // open the [system].rootmap files
5959 if (!fMapfile) {
5960 fMapfile = new TEnv();
5964 InitRootmapFile(".rootmap");
5965 }
5966
5967 // Prepare a list of all forward declarations for cling
5968 // For some experiments it is easily as big as 500k characters. To be on the
5969 // safe side, we go for 1M.
5970 TUniqueString uniqueString(1048576);
5971
5972 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5973 // A rootmap file must end with the string ".rootmap".
5975 if (ldpath != fRootmapLoadPath) {
5977#ifdef WIN32
5978 TObjArray* paths = ldpath.Tokenize(";");
5979#else
5980 TObjArray* paths = ldpath.Tokenize(":");
5981#endif
5982 TString d;
5983 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5984 d = ((TObjString *)paths->At(i))->GetString();
5985 // check if directory already scanned
5986 Int_t skip = 0;
5987 for (Int_t j = 0; j < i; j++) {
5988 TString pd = ((TObjString *)paths->At(j))->GetString();
5989 if (pd == d) {
5990 skip++;
5991 break;
5992 }
5993 }
5994 if (!skip) {
5995 void* dirp = gSystem->OpenDirectory(d);
5996 if (dirp) {
5997 if (gDebug > 3) {
5998 Info("LoadLibraryMap", "%s", d.Data());
5999 }
6000 const char* f1;
6001 while ((f1 = gSystem->GetDirEntry(dirp))) {
6002 TString f = f1;
6003 if (f.EndsWith(".rootmap")) {
6004 TString p;
6005 p = d + "/" + f;
6007 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
6008 if (gDebug > 4) {
6009 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
6010 }
6012
6013 if (ret == 0)
6014 fRootmapFiles->Add(new TNamed(gSystem->BaseName(f), p.Data()));
6015 if (ret == -3) {
6016 // old format
6018 fRootmapFiles->Add(new TNamed(f, p));
6019 }
6020 }
6021 // else {
6022 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
6023 // fRootmapFiles->FindObject(f)->ls();
6024 // }
6025 }
6026 }
6027 if (f.BeginsWith("rootmap")) {
6028 TString p;
6029 p = d + "/" + f;
6031 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
6032 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
6033 }
6034 }
6035 }
6036 }
6038 }
6039 }
6040 delete paths;
6041 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
6042 return -1;
6043 }
6044 }
6045 if (rootmapfile && *rootmapfile) {
6047 if (res == 0) {
6048 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
6049 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
6051 }
6052 else if (res == -3) {
6053 // old format
6058 }
6059 }
6060 TEnvRec* rec;
6061 TIter next(fMapfile->GetTable());
6062 while ((rec = (TEnvRec*) next())) {
6063 TString cls = rec->GetName();
6064 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
6065 // get the first lib from the list of lib and dependent libs
6066 TString libs = rec->GetValue();
6067 if (libs == "") {
6068 continue;
6069 }
6070 TString delim(" ");
6071 TObjArray* tokens = libs.Tokenize(delim);
6072 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6073 // convert "@@" to "::", we used "@@" because TEnv
6074 // considers "::" a terminator
6075 cls.Remove(0, 8);
6076 cls.ReplaceAll("@@", "::");
6077 // convert "-" to " ", since class names may have
6078 // blanks and TEnv considers a blank a terminator
6079 cls.ReplaceAll("-", " ");
6080 if (gDebug > 6) {
6081 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
6082 if (wlib) {
6083 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
6084 }
6085 else {
6086 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
6087 }
6088 delete[] wlib;
6089 }
6090 delete tokens;
6091 }
6092 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
6093 cls.Remove(0, 8);
6094 // convert "-" to " ", since class names may have
6095 // blanks and TEnv considers a blank a terminator
6096 cls.ReplaceAll("-", " ");
6097 fInterpreter->declare(cls.Data());
6098 }
6099 }
6100
6101 // Process the forward declarations collected
6102 cling::Transaction* T = nullptr;
6103 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
6104 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
6105
6106 if (compRes!=cling::Interpreter::kSuccess){
6107 Warning("LoadLibraryMap",
6108 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
6109 }
6110
6111 if (T) {
6112 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
6113 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
6114 if (declIt->m_DGR.isSingleDecl()) {
6115 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
6116 if (clang::isa<TagDecl>(D) || clang::isa<NamespaceDecl>(D)) {
6117 evsAdder.TraverseDecl(D);
6118 }
6119 }
6120 }
6121 }
6122 }
6123
6124 // clear duplicates
6125
6126 return 0;
6127}
6128
6129////////////////////////////////////////////////////////////////////////////////
6130/// Scan again along the dynamic path for library maps. Entries for the loaded
6131/// shared libraries are unloaded first. This can be useful after reseting
6132/// the dynamic path through TSystem::SetDynamicPath()
6133/// In case of error -1 is returned, 0 otherwise.
6134
6141
6142////////////////////////////////////////////////////////////////////////////////
6143/// Reload the library map entries coming from all the loaded shared libraries,
6144/// after first unloading the current ones.
6145/// In case of error -1 is returned, 0 otherwise.
6146
6148{
6150 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
6151 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
6152 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
6153 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
6156 if (ret < 0) {
6157 continue;
6158 }
6160 if (sharedLibBaseStr.EndsWith(".dll")) {
6161 rootMapBaseStr.ReplaceAll(".dll", "");
6162 }
6163 else if (sharedLibBaseStr.EndsWith(".DLL")) {
6164 rootMapBaseStr.ReplaceAll(".DLL", "");
6165 }
6166 else if (sharedLibBaseStr.EndsWith(".so")) {
6167 rootMapBaseStr.ReplaceAll(".so", "");
6168 }
6169 else if (sharedLibBaseStr.EndsWith(".sl")) {
6170 rootMapBaseStr.ReplaceAll(".sl", "");
6171 }
6172 else if (sharedLibBaseStr.EndsWith(".dl")) {
6173 rootMapBaseStr.ReplaceAll(".dl", "");
6174 }
6175 else if (sharedLibBaseStr.EndsWith(".a")) {
6176 rootMapBaseStr.ReplaceAll(".a", "");
6177 }
6178 else {
6179 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
6180 delete sharedLibL;
6181 return -1;
6182 }
6183 rootMapBaseStr += ".rootmap";
6185 if (!rootMap) {
6186 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
6187 delete[] rootMap;
6188 delete sharedLibL;
6189 return -1;
6190 }
6191 const Int_t status = LoadLibraryMap(rootMap);
6192 if (status < 0) {
6193 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
6194 delete[] rootMap;
6195 delete sharedLibL;
6196 return -1;
6197 }
6198 delete[] rootMap;
6199 }
6200 delete sharedLibL;
6201 return 0;
6202}
6203
6204////////////////////////////////////////////////////////////////////////////////
6205/// Unload the library map entries coming from all the loaded shared libraries.
6206/// Returns 0 if succesful
6207
6209{
6211 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
6212 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
6213 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
6216 }
6217 delete sharedLibL;
6218 return 0;
6219}
6220
6221////////////////////////////////////////////////////////////////////////////////
6222/// Unload library map entries coming from the specified library.
6223/// Returns -1 in case no entries for the specified library were found,
6224/// 0 otherwise.
6225
6227{
6228 if (!fMapfile || !library || !*library) {
6229 return 0;
6230 }
6232 Ssiz_t idx = libname.Last('.');
6233 if (idx != kNPOS) {
6234 libname.Remove(idx);
6235 }
6236 size_t len = libname.Length();
6237 TEnvRec *rec;
6238 TIter next(fMapfile->GetTable());
6240 Int_t ret = 0;
6241 while ((rec = (TEnvRec *) next())) {
6242 TString cls = rec->GetName();
6243 if (cls.Length() > 2) {
6244 // get the first lib from the list of lib and dependent libs
6245 TString libs = rec->GetValue();
6246 if (libs == "") {
6247 continue;
6248 }
6249 TString delim(" ");
6250 TObjArray* tokens = libs.Tokenize(delim);
6251 const char* lib = ((TObjString *)tokens->At(0))->GetName();
6252 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
6253 // convert "@@" to "::", we used "@@" because TEnv
6254 // considers "::" a terminator
6255 cls.Remove(0, 8);
6256 cls.ReplaceAll("@@", "::");
6257 // convert "-" to " ", since class names may have
6258 // blanks and TEnv considers a blank a terminator
6259 cls.ReplaceAll("-", " ");
6260 }
6261 if (!strncmp(lib, libname.Data(), len)) {
6262 if (fMapfile->GetTable()->Remove(rec) == nullptr) {
6263 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
6264 ret = -1;
6265 }
6266 }
6267 delete tokens;
6268 }
6269 }
6270 if (ret >= 0) {
6272 if (!library_rootmap.EndsWith(".rootmap"))
6273 library_rootmap.Append(".rootmap");
6274 TNamed* mfile = nullptr;
6277 delete mfile;
6278 }
6280 }
6281 return ret;
6282}
6283
6284////////////////////////////////////////////////////////////////////////////////
6285/// Register the AutoLoading information for a class.
6286/// libs is a space separated list of libraries.
6287
6288Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
6289{
6290 if (!cls || !*cls)
6291 return 0;
6292
6293 TString key = TString("Library.") + cls;
6294 // convert "::" to "@@", we used "@@" because TEnv
6295 // considers "::" a terminator
6296 key.ReplaceAll("::", "@@");
6297 // convert "-" to " ", since class names may have
6298 // blanks and TEnv considers a blank a terminator
6299 key.ReplaceAll(" ", "-");
6300
6302 if (!fMapfile) {
6303 fMapfile = new TEnv();
6305
6308
6309 InitRootmapFile(".rootmap");
6310 }
6311 //fMapfile->SetValue(key, libs);
6313 return 1;
6314}
6315
6316////////////////////////////////////////////////////////////////////////////////
6317/// Demangle the name (from the typeinfo) and then request the class
6318/// via the usual name based interface (TClass::GetClass).
6319
6320TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
6321{
6322 int err = 0;
6324 if (err) return nullptr;
6327 return theClass;
6328}
6329
6330////////////////////////////////////////////////////////////////////////////////
6331/// Load library containing the specified class. Returns 0 in case of error
6332/// and 1 in case if success.
6333
6334Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
6335{
6336 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6337
6338 int err = 0;
6340 if (err) {
6341 return 0;
6342 }
6343
6344 std::string demangled_name(demangled_name_c);
6346
6347 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
6348 // shortened name.
6351
6352 // No need to worry about typedef, they aren't any ... but there are
6353 // inlined namespaces ...
6354
6356 if (result == 0) {
6359 }
6360
6361 return result;
6362}
6363
6364////////////////////////////////////////////////////////////////////////////////
6365// Get the list of 'published'/'known' library for the class and load them.
6367{
6368 Int_t status = 0;
6369
6370 // lookup class to find list of dependent libraries
6372 if (!deplibs.IsNull()) {
6373 TString delim(" ");
6374 TObjArray* tokens = deplibs.Tokenize(delim);
6375 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
6376 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
6377 if (gROOT->LoadClass(cls, deplib) == 0) {
6378 if (gDebug > 0) {
6379 gCling->Info("TCling::AutoLoad",
6380 "loaded dependent library %s for %s", deplib, cls);
6381 }
6382 }
6383 else {
6384 gCling->Error("TCling::AutoLoad",
6385 "failure loading dependent library %s for %s",
6386 deplib, cls);
6387 }
6388 }
6389 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6390 if (lib && lib[0]) {
6391 if (gROOT->LoadClass(cls, lib) == 0) {
6392 if (gDebug > 0) {
6393 gCling->Info("TCling::AutoLoad",
6394 "loaded library %s for %s", lib, cls);
6395 }
6396 status = 1;
6397 }
6398 else {
6399 gCling->Error("TCling::AutoLoad",
6400 "failure loading library %s for %s", lib, cls);
6401 }
6402 }
6403 delete tokens;
6404 }
6405
6406 return status;
6407}
6408
6409////////////////////////////////////////////////////////////////////////////////
6410// Iterate through the data member of the class (either through the TProtoClass
6411// or through Cling) and trigger, recursively, the loading the necessary libraries.
6412// \note `cls` is expected to be already normalized!
6413// \returns 1 on success.
6414Int_t TCling::DeepAutoLoadImpl(const char *cls, std::unordered_set<std::string> &visited,
6415 bool nameIsNormalized)
6416{
6417 // Try to insert; if insertion failed because the entry existed, DeepAutoLoadImpl()
6418 // has previously (within the same call to `AutoLoad()`) tried to load this class
6419 // and we are done, whether success or not, as it won't work better now than before,
6420 // because there is no additional information now compared to before.
6421 if (!visited.insert(std::string(cls)).second)
6422 return 1;
6423
6424 if (ShallowAutoLoadImpl(cls) == 0) {
6425 // If ShallowAutoLoadImpl() has an error, we have an error.
6426 return 0;
6427 }
6428
6429 // Now look through the TProtoClass to load the required library/dictionary
6431 for (auto element : proto->GetData()) {
6432 if (element->IsBasic())
6433 continue;
6434 const char *subtypename = element->GetTypeName();
6436 // Failure to load a dictionary is not (quite) a failure load
6437 // the top-level library. If we return false here, then
6438 // we would end up in a situation where the library and thus
6439 // the dictionary is loaded for "cls" but the TClass is
6440 // not created and/or marked as unavailable (in case where
6441 // AutoLoad is called from TClass::GetClass).
6442 DeepAutoLoadImpl(subtypename, visited, true /*normalized*/);
6443 }
6444 }
6445 return 1;
6446 }
6447
6448 // We found no TProtoClass for cls.
6449 auto classinfo = gInterpreter->ClassInfo_Factory(cls);
6450 if (classinfo && gInterpreter->ClassInfo_IsValid(classinfo)
6451 && !(gInterpreter->ClassInfo_Property(classinfo) & kIsEnum))
6452 {
6454 while (gInterpreter->DataMemberInfo_Next(memberinfo)) {
6455 if (gInterpreter->DataMemberInfo_TypeProperty(memberinfo) & ::kIsFundamental)
6456 continue;
6457 auto membertypename = TClassEdit::GetLong64_Name(gInterpreter->TypeName(gInterpreter->DataMemberInfo_TypeTrueName(memberinfo)));
6459 // Failure to load a dictionary is not (quite) a failure load
6460 // the top-level library. See detailed comment in the TProtoClass
6461 // branch (above).
6462 (void)DeepAutoLoadImpl(membertypename.c_str(), visited, true /*normalized*/);
6463 }
6464 }
6465 gInterpreter->DataMemberInfo_Delete(memberinfo);
6466 }
6467 gInterpreter->ClassInfo_Delete(classinfo);
6468 return 1;
6469}
6470
6471////////////////////////////////////////////////////////////////////////////////
6472/// Load library containing the specified class. Returns 0 in case of error
6473/// and 1 in case if success.
6474
6476{
6477 // Prevent update to IsClassAutoloading between our check and our actions.
6479
6480 // TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
6481 // rootcling (in *_rdict.pcm file generation) it is a no op.
6482 // FIXME: We should avoid calling autoload when we know we are not supposed
6483 // to and transform this check into an assert.
6485 // Never load any library from rootcling/genreflex.
6486 if (gDebug > 2) {
6487 Info("TCling::AutoLoad", "Explicitly disabled (the class name is %s)", cls);
6488 }
6489 return 0;
6490 }
6491
6492 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6493
6495
6497 // The library is already loaded as the class's dictionary is known.
6498 // Return success.
6499 // Note: the name (cls) is expected to be normalized as it comes either
6500 // from a callbacks (that can/should calculate the normalized name from the
6501 // decl) or from TClass::GetClass (which does also calculate the normalized
6502 // name).
6503 return 1;
6504 }
6505
6506 if (gDebug > 2) {
6507 Info("TCling::AutoLoad",
6508 "Trying to autoload for %s", cls);
6509 }
6510
6511 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
6512 if (gDebug > 2) {
6513 Info("TCling::AutoLoad",
6514 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
6515 }
6516 return 0;
6517 }
6518 // Prevent the recursion when the library dictionary are loaded.
6520 // Try using externally provided callback first.
6521 if (fAutoLoadCallBack) {
6523 if (success)
6524 return success;
6525 }
6526
6527 // During the 'Deep' part of the search we will call GetClassSharedLibsForModule
6528 // (when module are enabled) which might end up calling AutoParsing but
6529 // that should only be for the cases where the library has no generated pcm
6530 // and in that case a rootmap should be available.
6531 // This avoids a very costly operation (for generally no gain) but reduce the
6532 // quality of the search (i.e. bad in case of library with no pcm and no rootmap
6533 // file).
6535 std::unordered_set<std::string> visited;
6536 return DeepAutoLoadImpl(cls, visited, false /*normalized*/);
6537}
6538
6539////////////////////////////////////////////////////////////////////////////////
6540/// Parse the payload or header.
6541
6542static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
6543 Bool_t header,
6544 cling::Interpreter *interpreter)
6545{
6546 std::string code = gNonInterpreterClassDef ;
6547 if (!header) {
6548 // This is the complete header file content and not the
6549 // name of a header.
6550 code += what;
6551
6552 } else {
6553 code += ("#include \"");
6554 code += what;
6555 code += "\"\n";
6556 }
6557 code += ("#ifdef __ROOTCLING__\n"
6558 "#undef __ROOTCLING__\n"
6560 "#endif");
6561
6562 cling::Interpreter::CompilationResult cr;
6563 {
6564 // scope within which diagnostics are de-activated
6565 // For now we disable diagnostics because we saw them already at
6566 // dictionary generation time. That won't be an issue with the PCMs.
6567
6568 Sema &SemaR = interpreter->getSema();
6570 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
6571
6572 #if defined(R__MUST_REVISIT)
6573 #if R__MUST_REVISIT(6,2)
6574 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
6575 #endif
6576 #endif
6577
6578 cr = interpreter->parseForModule(code);
6579 }
6580 return cr;
6581}
6582
6583////////////////////////////////////////////////////////////////////////////////
6584/// Helper routine for TCling::AutoParse implementing the actual call to the
6585/// parser and looping over template parameters (if
6586/// any) and when they don't have a registered header to autoparse,
6587/// recurse over their template parameters.
6588///
6589/// Returns the number of header parsed.
6590
6592{
6593 // We assume the lock has already been taken.
6594 // R__LOCKGUARD(gInterpreterMutex);
6595
6597 unsigned long offset = 0;
6598 if (strncmp(cls, "const ", 6) == 0) {
6599 offset = 6;
6600 }
6601
6602 // Loop on the possible autoparse keys
6603 bool skipFirstEntry = false;
6604 std::vector<std::string> autoparseKeys;
6605 if (strchr(cls, '<')) {
6606 int nestedLoc = 0;
6608 // Check if we can skip the name of the template in the autoparses
6609 // Take all the scopes one by one. If all of them are in the AST, we do not
6610 // need to autoparse for that particular template.
6611 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
6612 // autoparseKeys[0] is empty when the input is not a template instance.
6613 // The case strchr(cls, '<') != 0 but still not a template instance can
6614 // happens 'just' for string (GetSplit replaces the template by the short name
6615 // and then use that for thew splitting)
6617 auto tokens = templateName.Tokenize("::");
6618 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
6619 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
6621 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
6622 auto nTokens = tokens->GetEntriesFast();
6623 for (Int_t tk = 0; tk < nTokens; ++tk) {
6624 auto scopeObj = tokens->UncheckedAt(tk);
6625 auto scopeName = ((TObjString*) scopeObj)->String().Data();
6626 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
6627 // Check if we have multiple nodes in the AST with this name
6628 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
6629 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
6630 if (!previousScopeAsContext) break; // this is not a context
6631 }
6632 delete tokens;
6633 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
6634 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
6635 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
6636 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
6637 skipFirstEntry = templatedDecl->hasDefinition();
6638 }
6639 }
6640 }
6641
6642 }
6643 }
6644 if (topLevel) autoparseKeys.emplace_back(cls);
6645
6646 for (const auto & apKeyStr : autoparseKeys) {
6647 if (skipFirstEntry) {
6648 skipFirstEntry=false;
6649 continue;
6650 }
6651 if (apKeyStr.empty()) continue;
6652 const char *apKey = apKeyStr.c_str();
6654 // If the class was not looked up
6655 if (gDebug > 1) {
6656 Info("TCling::AutoParse",
6657 "Starting autoparse for %s\n", apKey);
6658 }
6659 if (fLookedUpClasses.insert(normNameHash).second) {
6660 auto const &iter = fClassesHeadersMap.find(normNameHash);
6661 if (iter != fClassesHeadersMap.end()) {
6662 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
6664 auto const &hNamesPtrs = iter->second;
6665 if (gDebug > 1) {
6666 Info("TCling::AutoParse",
6667 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
6668 }
6669 for (auto & hName : hNamesPtrs) {
6670 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
6671 if (0 != fPayloads.count(normNameHash)) {
6672 float initRSSval=0.f, initVSIZEval=0.f;
6673 (void) initRSSval; // Avoid unused var warning
6674 (void) initVSIZEval;
6675 if (gDebug > 0) {
6676 Info("AutoParse",
6677 "Parsing full payload for %s", apKey);
6680 initRSSval = 1e-3*info.fMemResident;
6681 initVSIZEval = 1e-3*info.fMemVirtual;
6682 }
6684 if (cRes != cling::Interpreter::kSuccess) {
6685 if (hName[0] == '\n')
6686 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
6687 } else {
6690 if (gDebug > 0){
6693 float endRSSval = 1e-3*info.fMemResident;
6694 float endVSIZEval = 1e-3*info.fMemVirtual;
6695 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6696 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6697 }
6698 }
6699 } else if (!IsLoaded(hName)) {
6700 if (gDebug > 0) {
6701 Info("AutoParse",
6702 "Parsing single header %s", hName);
6703 }
6705 if (cRes != cling::Interpreter::kSuccess) {
6706 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
6707 } else {
6709 }
6710 }
6711 }
6712 }
6713 else {
6714 // There is no header registered for this class, if this a
6715 // template, it will be instantiated if/when it is requested
6716 // and if we do no load/parse its components we might end up
6717 // not using an eventual specialization.
6718 if (strchr(apKey, '<')) {
6720 }
6721 }
6722 }
6723 }
6724
6725 if (nHheadersParsed) {
6726 // Register that we did autoparsing for this class.
6727 fAutoParseClasses.insert(cls);
6728 if (gDebug)
6729 Info("AutoParse", "Parsed %d headers for %s", nHheadersParsed, cls);
6730 }
6731 return nHheadersParsed;
6732
6733}
6734
6735////////////////////////////////////////////////////////////////////////////////
6736/// Parse the headers relative to the class
6737/// Returns 1 in case of success, 0 in case of failure
6738
6740{
6741 if (llvm::StringRef(cls).contains("(lambda)"))
6742 return 0;
6743
6746 return AutoLoad(cls);
6747 } else {
6748 return 0;
6749 }
6750 }
6751
6753
6754 if (gDebug > 1) {
6755 Info("TCling::AutoParse",
6756 "Trying to autoparse for %s", cls);
6757 }
6758
6759 // The catalogue of headers is in the dictionary
6761 && !gClassTable->GetDictNorm(cls)) {
6762 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
6764 fInterpreter->getSema());
6765 AutoLoad(cls, true /*knowDictNotLoaded*/);
6766 }
6767
6768 // Prevent the recursion when the library dictionary are loaded.
6770
6771 // No recursive header parsing on demand; we require headers to be standalone.
6773
6774 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
6775
6777
6778 return nHheadersParsed > 0 ? 1 : 0;
6779}
6780
6781// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6782// Try to solve the problem by AutoLoading. Return true when AutoLoading success, return
6783// false if not.
6784bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6785{
6787 if (errMsg.contains("undefined symbol: ")) {
6788 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6789 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6790 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6791 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6792 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6793 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6794 return true;
6795 } else {
6796 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6798 return true;
6799 }
6800
6801 return false;
6802}
6803
6804////////////////////////////////////////////////////////////////////////////////
6805/// Autoload a library based on a missing symbol.
6806
6809
6810 // We have already loaded the library.
6811 if (void* Addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name))
6812 return Addr;
6813
6814 const cling::DynamicLibraryManager &DLM = *GetInterpreterImpl()->getDynamicLibraryManager();
6816
6817 auto LibLoader = [](const std::string& LibName) -> bool {
6818 if (gSystem->Load(LibName.c_str(), "", false) < 0) {
6819 ::Error("TCling__LazyFunctionCreatorAutoloadForModule",
6820 "Failed to load library %s", LibName.c_str());
6821 return false;
6822 }
6823 return true; //success.
6824 };
6825
6826 std::string libName = DLM.searchLibrariesForSymbol(mangled_name,
6827 /*searchSystem=*/ true);
6828
6829 assert(!llvm::StringRef(libName).starts_with("libNew") && "We must not resolve symbols from libNew!");
6830
6831 if (libName.empty())
6832 return nullptr;
6833
6834 if (!LibLoader(libName))
6835 return nullptr;
6836
6838 return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name);
6839}
6840
6841////////////////////////////////////////////////////////////////////////////////
6842
6844{
6845 return fNSFromRootmaps.count(nsDecl) != 0;
6846}
6847
6848////////////////////////////////////////////////////////////////////////////////
6849/// Internal function. Actually do the update of the ClassInfo when seeing
6850// new TagDecl or NamespaceDecl.
6851void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6852{
6853
6855 if (cci) {
6856 // If we only had a forward declaration then update the
6857 // TClingClassInfo with the definition if we have it now.
6858 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6859 if (!oldDef || (def && def != oldDef)) {
6860 cl->ResetCaches();
6861 TClass::RemoveClassDeclId(cci->GetDeclId());
6862 if (def) {
6863 if (cci->GetType()) {
6864 // It's a tag decl, not a namespace decl.
6865 cci->Init(*cci->GetType());
6866 TClass::AddClassToDeclIdMap(cci->GetDeclId(), cl);
6867 } else {
6868 Error("RefreshClassInfo", "Should not need to update the classInfo a non type decl: %s", oldDef->getNameAsString().c_str());
6869 }
6870 }
6871 }
6872 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6873 cl->ResetCaches();
6874 if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
6875 // We need to use the Emulated Tuple but we should not trigger parsing
6876 // yet, so delay the creation of the ClassInfo
6877 delete ((TClingClassInfo *)cl->fClassInfo);
6878 cl->fClassInfo = nullptr;
6879 cl->fCanLoadClassInfo = true;
6881 if (cl->fState != TClass::kHasTClassInit) {
6883 }
6884 return;
6885 }
6886 // yes, this is almost a waste of time, but we do need to lookup
6887 // the 'type' corresponding to the TClass anyway in order to
6888 // preserve the opaque typedefs (Double32_t)
6889 if (!alias && def != nullptr)
6891 else
6893 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6894 // We now need to update the state and bits.
6895 if (cl->fState != TClass::kHasTClassInit) {
6896 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6898 }
6899 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6900 } else {
6901 delete ((TClingClassInfo *)cl->fClassInfo);
6902 cl->fClassInfo = nullptr;
6903 }
6904 }
6905}
6906
6907////////////////////////////////////////////////////////////////////////////////
6908/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6910{
6911 const TagDecl *td = dyn_cast<TagDecl>(ND);
6913 const NamedDecl *canon = nullptr;
6914
6915 std::string name;
6916 TagDecl* tdDef = nullptr;
6917 if (td) {
6918 canon = tdDef = td->getDefinition();
6919 // Let's pass the decl to the TClass only if it has a definition.
6920 if (!tdDef) return;
6921
6922 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6923 // Ignore incomplete definition.
6924 // Ignore declaration within a function.
6925 return;
6926 }
6927
6928 auto declName = tdDef->getNameAsString();
6929 // Check if we have registered the unqualified name into the list
6930 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6931 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6932 // the unqualified name is sufficient (and the fully qualified name might be
6933 // 'wrong' if there is difference in spelling in the template paramters (for example)
6935 // 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() );
6936 return;
6937 }
6938
6939 clang::QualType type = tdDef->getASTContext().getCanonicalTagType(tdDef);
6941 } else if (ns) {
6942 canon = ns->getCanonicalDecl();
6943 name = ND->getQualifiedNameAsString();
6944 } else {
6945 name = ND->getQualifiedNameAsString();
6946 }
6947
6948 // Supposedly we are being called while something is being
6949 // loaded ... let's now tell the autoloader to do the work
6950 // yet another time.
6952 // FIXME: There can be more than one TClass for a single decl.
6953 // for example vector<double> and vector<Double32_t>
6954 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6955 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6956 RefreshClassInfo(cl, canon, false);
6957 }
6958 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6959 // and update them too:
6960 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6961 // RefreshClassInfo(cl, tdDef, true);
6962}
6963
6964////////////////////////////////////////////////////////////////////////////////
6965/// No op: see TClingCallbacks
6966
6970
6971//______________________________________________________________________________
6972//FIXME: Factor out that function in TClass, because TClass does it already twice
6974{
6975 // This is a no-op as part of the API.
6976 // TCling uses UpdateClassInfoWithDecl() instead.
6977}
6978
6979////////////////////////////////////////////////////////////////////////////////
6980/// Update all canvases at end the terminal input command.
6981
6983{
6984 TIter next(gROOT->GetListOfCanvases());
6985 TVirtualPad* canvas;
6986 while ((canvas = (TVirtualPad*)next())) {
6987 canvas->Update();
6988 }
6989}
6990
6991////////////////////////////////////////////////////////////////////////////////
6992
6993void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6994 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6995
6996 // If the transaction does not contain anything we can return earlier.
6997 if (!HandleNewTransaction(T)) return;
6998
6999 bool isTUTransaction = false;
7000 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
7001 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
7002 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
7003 // The is the first transaction, we have to expose to meta
7004 // what's already in the AST.
7005 isTUTransaction = true;
7006 }
7007 }
7008
7009 std::set<const void*> TransactionDeclSet;
7010 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
7011 const clang::Decl* WrapperFD = T.getWrapperFD();
7012 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
7013 I != E; ++I) {
7014 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
7015 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
7016 continue;
7017
7018 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
7019 DE = I->m_DGR.end(); DI != DE; ++DI) {
7020 if (*DI == WrapperFD)
7021 continue;
7022 TransactionDeclSet.insert(*DI);
7023 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
7024 }
7025 }
7026 }
7027
7028 // The above might trigger more decls to be deserialized.
7029 // Thus the iteration over the deserialized decls must be last.
7030 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
7031 E = T.deserialized_decls_end(); I != E; ++I) {
7032 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
7033 DE = I->m_DGR.end(); DI != DE; ++DI)
7034 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
7035 //FIXME: HandleNewDecl should take DeclGroupRef
7036 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
7038 }
7039 }
7040
7041
7042 // When fully building the reflection info in TClass, a deserialization
7043 // could be triggered, which may result in request for building the
7044 // reflection info for the same TClass. This in turn will clear the caches
7045 // for the TClass in-flight and cause null ptr derefs.
7046 // FIXME: This is a quick fix, solving most of the issues. The actual
7047 // question is: Shouldn't TClass provide a lock mechanism on update or lock
7048 // itself until the update is done.
7049 //
7050 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
7051 std::vector<TClass*>::iterator it;
7053 ((TCling*)gCling)->GetModTClasses().begin(),
7054 ((TCling*)gCling)->GetModTClasses().end(),
7057
7058 // Lock the TClass for updates
7059 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
7061 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
7062 E = modifiedTClassesDiff.end(); I != E; ++I) {
7063 // Make sure the TClass has not been deleted.
7064 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
7065 continue;
7066 }
7067 // Could trigger deserialization of decls.
7068 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
7069 // Unlock the TClass for updates
7070 ((TCling*)gCling)->GetModTClasses().erase(*I);
7071
7072 }
7073}
7074
7075///\brief Invalidate stored TCling state for declarations included in transaction `T'.
7076///
7077void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
7078{
7080
7081 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
7082 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
7083 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
7084 (TListOfEnums *)gROOT->GetListOfEnums());
7085
7086 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
7087 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
7088 I != E; ++I) {
7089 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
7090 continue;
7091 if (I->m_Call == cling::Transaction::kCCINone) {
7093 ++iNested;
7094 continue;
7095 }
7096
7097 for (auto &D : I->m_DGR)
7099 }
7100}
7101
7102///\brief Invalidate cached TCling information for the given global declaration.
7103///
7105 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
7106 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
7107 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
7108 (TListOfEnums *)gROOT->GetListOfEnums());
7110}
7111
7112///\brief Invalidate cached TCling information for the given declaration, and
7113/// removed it from the appropriate object list.
7114///\param[in] Lists - std::tuple<TListOfDataMembers&, TListOfFunctions&,
7115/// TListOfFunctionTemplates&, TListOfEnums&>
7116/// of pointers to the (global/class) object lists.
7117///\param[in] D - Decl to discard.
7118///
7122 TListOfEnums*> &Lists, const Decl *D) {
7123 if (D->isFromASTFile()) // `D' came from the PCH; ignore
7124 return;
7125
7126 TListOfDataMembers &LODM = *(std::get<0>(Lists));
7127 TListOfFunctions &LOF = *(std::get<1>(Lists));
7128 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
7129 TListOfEnums &LOE = *(std::get<3>(Lists));
7130
7132 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
7133 if (LODM.GetClass())
7134 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
7135 else
7136 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
7137 } else if (isa<FunctionDecl>(D)) {
7139 } else if (isa<FunctionTemplateDecl>(D)) {
7141 } else if (isa<EnumDecl>(D)) {
7142 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
7143 if (!E)
7144 return;
7145
7146 // Try to invalidate enumerators (for unscoped enumerations).
7147 for (TIter I = E->GetConstants(); auto EC = (TEnumConstant *)I(); )
7149 (TEnumConstant *)LODM.FindObject(EC->GetName()));
7150
7152 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
7154 return;
7155
7156 std::vector<TClass *> Classes;
7157 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
7158 return;
7159 for (auto &C : Classes) {
7160 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
7161 (TListOfFunctions *)C->GetListOfMethods(),
7162 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
7163 (TListOfEnums *)C->GetListOfEnums());
7164 for (auto &I : cast<DeclContext>(D)->decls())
7166
7167 // For NamespaceDecl (redeclarable), only invalidate this redecl.
7168 if (D->getKind() != Decl::Namespace || cast<NamespaceDecl>(D)->isFirstDecl())
7169 C->ResetClassInfo();
7170 }
7171 }
7172}
7173
7174////////////////////////////////////////////////////////////////////////////////
7175// If an autoparse was done during a transaction and that it is rolled back,
7176// we need to make sure the next request for the same autoparse will be
7177// honored.
7178void TCling::TransactionRollback(const cling::Transaction &T) {
7179 auto const &triter = fTransactionHeadersMap.find(&T);
7180 if (triter != fTransactionHeadersMap.end()) {
7181 std::size_t normNameHash = triter->second;
7182
7184
7185 auto const &iter = fClassesHeadersMap.find(normNameHash);
7186 if (iter != fClassesHeadersMap.end()) {
7187 auto const &hNamesPtrs = iter->second;
7188 for (auto &hName : hNamesPtrs) {
7189 if (gDebug > 0) {
7190 Info("TransactionRollback",
7191 "Restoring ability to autoaparse: %s", hName);
7192 }
7194 }
7195 }
7196 }
7197}
7198
7199////////////////////////////////////////////////////////////////////////////////
7200
7201void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
7202// R__LOCKGUARD_CLING(gInterpreterMutex);
7203// UpdateListOfLoadedSharedLibraries();
7204}
7205
7206////////////////////////////////////////////////////////////////////////////////
7207
7208void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
7209 fPrevLoadedDynLibInfo = nullptr;
7210 fSharedLibs = "";
7211}
7212
7213////////////////////////////////////////////////////////////////////////////////
7214/// Return the list of shared libraries loaded into the process.
7215
7222
7223static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH, bool skipCore)
7224{
7225 if (!cls || !*cls)
7226 return {};
7227
7228 using namespace clang;
7229 if (const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
7230 /*type*/ nullptr, /*instantiate*/ false)) {
7231 if (!D->isFromASTFile()) {
7232 if (gDebug > 5)
7233 Warning("GetClassSharedLibsForModule", "Decl found for %s is not part of a module", cls);
7234 return {};
7235 }
7236 class ModuleCollector : public ConstDeclVisitor<ModuleCollector> {
7237 llvm::DenseSet<Module *> &m_TopLevelModules;
7238
7239 public:
7240 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
7241 void Collect(const Decl *D) { Visit(D); }
7242
7243 void VisitDecl(const Decl *D)
7244 {
7245 // FIXME: Such case is described ROOT-7765 where
7246 // ROOT_GENERATE_DICTIONARY does not contain the list of headers.
7247 // They are specified as #includes in the LinkDef file. This leads to
7248 // generation of incomplete modulemap files and this logic fails to
7249 // compute the corresponding module of D.
7250 // FIXME: If we want to support such a case, we should not rely on
7251 // the contents of the modulemap but mangle D and look it up in the
7252 // .so files.
7253 if (!D->hasOwningModule())
7254 return;
7255 if (Module *M = D->getOwningModule()->getTopLevelModule())
7256 m_TopLevelModules.insert(M);
7257 }
7258
7260 {
7261 switch (TA.getKind()) {
7262 case TemplateArgument::Null:
7263 case TemplateArgument::Integral:
7264 case TemplateArgument::Pack:
7265 case TemplateArgument::NullPtr:
7266 case TemplateArgument::StructuralValue:
7267 case TemplateArgument::Expression:
7268 case TemplateArgument::Template:
7269 case TemplateArgument::TemplateExpansion: return;
7270 case TemplateArgument::Type:
7271 if (const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
7272 return Visit(TagTy->getDecl());
7273 return;
7274 case TemplateArgument::Declaration: return Visit(TA.getAsDecl());
7275 }
7276 llvm_unreachable("Invalid TemplateArgument::Kind!");
7277 }
7278
7280 {
7281 if (CTSD->getOwningModule())
7282 VisitDecl(CTSD);
7283 else
7284 VisitDecl(CTSD->getSpecializedTemplate());
7285 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
7286 for (const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
7288 }
7289 }
7290 };
7291
7292 llvm::DenseSet<Module *> TopLevelModules;
7294 m.Collect(D);
7295 std::string result;
7296 for (auto M : TopLevelModules) {
7297 // ROOT-unaware modules (i.e. not processed by rootcling) do not have a
7298 // link declaration.
7299 if (!M->LinkLibraries.size())
7300 continue;
7301 // We have preloaded the Core module thus libCore.so
7302 if (M->Name == "Core" && skipCore)
7303 continue;
7304 assert(M->LinkLibraries.size() == 1);
7305 if (!result.empty())
7306 result += ' ';
7307 result += M->LinkLibraries[0].Library;
7308 }
7309 return result;
7310 }
7311 return {};
7312}
7313
7314////////////////////////////////////////////////////////////////////////////////
7315/// Get the list of shared libraries containing the code for class cls.
7316/// The first library in the list is the one containing the class, the
7317/// others are the libraries the first one depends on. Returns 0
7318/// in case the library is not found.
7319/// \param cls the name of the class
7320/// \param skipCore if true (default), remove "Core" from the returned list
7321
7322const char* TCling::GetClassSharedLibs(const char* cls, bool skipCore)
7323{
7324 if (fCxxModulesEnabled) {
7325 // Lock the interpreter mutex before interacting with cling.
7326 // TODO: Can we move this further deep? In principle the lock should be in
7327 // GetClassSharedLibsForModule, but it might be needed also for
7328 // getLookupHelper?
7330 llvm::StringRef className = cls;
7331 // If we get a class name containing lambda, we cannot parse it and we
7332 // can exit early.
7333 // FIXME: This works around a bug when we are instantiating a template
7334 // make_unique and the substitution fails. Seen in most of the dataframe
7335 // tests.
7336 if (className.contains("(lambda)"))
7337 return nullptr;
7338 // Limit the recursion which can be induced by GetClassSharedLibsForModule.
7340 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
7342 if (!libs.empty()) {
7343 fAutoLoadLibStorage.push_back(libs);
7344 return fAutoLoadLibStorage.back().c_str();
7345 }
7346 }
7347
7348 if (!cls || !*cls) {
7349 return nullptr;
7350 }
7351 // lookup class to find list of libraries
7352 if (fMapfile) {
7353 TEnvRec* libs_record = nullptr;
7355 if (libs_record) {
7356 const char* libs = libs_record->GetValue();
7357 return (*libs) ? libs : nullptr;
7358 }
7359 else {
7360 // Try the old format...
7361 TString c = TString("Library.") + cls;
7362 // convert "::" to "@@", we used "@@" because TEnv
7363 // considers "::" a terminator
7364 c.ReplaceAll("::", "@@");
7365 // convert "-" to " ", since class names may have
7366 // blanks and TEnv considers a blank a terminator
7367 c.ReplaceAll(" ", "-");
7368 // Use TEnv::Lookup here as the rootmap file must start with Library.
7369 // and do not support using any stars (so we do not need to waste time
7370 // with the search made by TEnv::GetValue).
7371 TEnvRec* libs_record = nullptr;
7373 if (libs_record) {
7374 const char* libs = libs_record->GetValue();
7375 return (*libs) ? libs : nullptr;
7376 }
7377 }
7378 }
7379 return nullptr;
7380}
7381
7382/// This interface returns a list of dependent libraries in the form:
7383/// lib libA.so libB.so libC.so. The first library is the library we are
7384/// searching dependencies for.
7385/// Note: In order to speed up the search, we display the dependencies of the
7386/// libraries which are not yet loaded. For instance, if libB.so was already
7387/// loaded the list would contain: lib libA.so libC.so.
7388static std::string GetSharedLibImmediateDepsSlow(std::string lib,
7389 cling::Interpreter *interp,
7390 bool skipLoadedLibs = true)
7391{
7392 TString LibFullPath(lib);
7393 if (!llvm::sys::path::is_absolute(lib)) {
7394 if (!gSystem->FindDynamicLibrary(LibFullPath, /*quiet=*/true)) {
7395 Error("TCling__GetSharedLibImmediateDepsSlow", "Cannot find library '%s'", lib.c_str());
7396 return "";
7397 }
7398 } else {
7399 assert(llvm::sys::fs::exists(lib) && "Must exist!");
7400 lib = llvm::sys::path::filename(lib).str();
7401 }
7402
7403 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
7404 if (!ObjF) {
7405 Warning("TCling__GetSharedLibImmediateDepsSlow", "Failed to read object file %s", lib.c_str());
7406 return "";
7407 }
7408
7409 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7410
7411 std::set<string> DedupSet;
7412 std::string Result = lib + ' ';
7413 for (const auto &S : BinObjFile->symbols()) {
7414 uint32_t Flags = llvm::cantFail(S.getFlags());
7415 // Skip defined symbols: we have them.
7416 if (!(Flags & llvm::object::SymbolRef::SF_Undefined))
7417 continue;
7418 // Skip undefined weak symbols: if we don't have them we won't need them.
7419 // `__gmon_start__` being a typical example.
7420 if (Flags & llvm::object::SymbolRef::SF_Weak)
7421 continue;
7422 llvm::Expected<StringRef> SymNameErr = S.getName();
7423 if (!SymNameErr) {
7424 Warning("GetSharedLibDepsForModule", "Failed to read symbol");
7425 continue;
7426 }
7427 llvm::StringRef SymName = SymNameErr.get();
7428 if (SymName.empty())
7429 continue;
7430
7431 if (BinObjFile->isELF()) {
7432 // Skip the symbols which are part of the C/C++ runtime and have a
7433 // fixed library version. See binutils ld VERSION. Those reside in
7434 // 'system' libraries, which we avoid in FindLibraryForSymbol.
7435 if (SymName.contains("@GLIBCXX") || SymName.contains("@CXXABI") ||
7436 SymName.contains("@GLIBC") || SymName.contains("@GCC"))
7437 continue;
7438
7439 // Those are 'weak undefined' symbols produced by gcc. We can
7440 // ignore them.
7441 // FIXME: It is unclear whether we can ignore all weak undefined
7442 // symbols:
7443 // http://lists.llvm.org/pipermail/llvm-dev/2017-October/118177.html
7444 static constexpr llvm::StringRef RegisterClasses("_Jv_RegisterClasses");
7445 static constexpr llvm::StringRef RegisterCloneTable("_ITM_registerTMCloneTable");
7446 static constexpr llvm::StringRef DeregisterCloneTable("_ITM_deregisterTMCloneTable");
7447 if (SymName == RegisterClasses ||
7450 continue;
7451 }
7452
7453 // If we can find the address of the symbol, we have loaded it. Skip.
7454 if (skipLoadedLibs) {
7456 if (llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymNameForDlsym))
7457 continue;
7458 }
7459
7461 std::string found = interp->getDynamicLibraryManager()->searchLibrariesForSymbol(SymName, /*searchSystem*/false);
7462 // The expected output is just filename without the full path, which
7463 // is not very accurate, because our Dyld implementation might find
7464 // a match in location a/b/c.so and if we return just c.so ROOT might
7465 // resolve it to y/z/c.so and there we might not be ABI compatible.
7466 // FIXME: Teach the users of GetSharedLibDeps to work with full paths.
7467 if (!found.empty()) {
7468 std::string cand = llvm::sys::path::filename(found).str();
7469 if (!DedupSet.insert(cand).second)
7470 continue;
7471
7472 Result += cand + ' ';
7473 }
7474 }
7475
7476 return Result;
7477}
7478
7479static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
7480{
7481 // Check if we have parsed a rootmap file.
7482 llvm::SmallString<256> rootmapName;
7483 if (!lib.starts_with("lib"))
7484 rootmapName.append("lib");
7485
7486 rootmapName.append(llvm::sys::path::filename(lib));
7487 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7488
7489 if (gCling->GetRootMapFiles()->FindObject(rootmapName.c_str()))
7490 return true;
7491
7492 // Perform a last resort by dropping the lib prefix.
7493 llvm::StringRef rootmapNameNoLib = rootmapName.str();
7494 if (rootmapNameNoLib.consume_front("lib"))
7495 return gCling->GetRootMapFiles()->FindObject(rootmapNameNoLib.data());
7496
7497 return false;
7498}
7499
7500static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
7501{
7502 if (gCling->HasPCMForLibrary(lib.data()))
7503 return true;
7504
7505 return hasParsedRootmapForLibrary(lib);
7506}
7507
7508////////////////////////////////////////////////////////////////////////////////
7509/// Get the list a libraries on which the specified lib depends. The
7510/// returned string contains as first element the lib itself.
7511/// Returns 0 in case the lib does not exist or does not have
7512/// any dependencies. If useDyld is true, we iterate through all available
7513/// libraries and try to construct the dependency chain by resolving each
7514/// symbol.
7515
7516const char* TCling::GetSharedLibDeps(const char* lib, bool useDyld/* = false*/)
7517{
7518 if (llvm::sys::path::is_absolute(lib) && !llvm::sys::fs::exists(lib))
7519 return nullptr;
7520
7521 if (!hasParsedRootmapForLibrary(lib)) {
7522 llvm::SmallString<512> rootmapName(lib);
7523 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7524 if (llvm::sys::fs::exists(rootmapName)) {
7525 if (gDebug > 0)
7526 Info("Load", "loading %s", rootmapName.c_str());
7527 gInterpreter->LoadLibraryMap(rootmapName.c_str());
7528 }
7529 }
7530
7531 if (hasPrecomputedLibraryDeps(lib) && useDyld) {
7532 if (gDebug > 0)
7533 Warning("TCling::GetSharedLibDeps", "Precomputed dependencies available but scanning '%s'", lib);
7534 }
7535
7536 if (useDyld) {
7538 if (!libs.empty()) {
7539 fAutoLoadLibStorage.push_back(libs);
7540 return fAutoLoadLibStorage.back().c_str();
7541 }
7542 }
7543
7544 if (!fMapfile || !lib || !lib[0]) {
7545 return nullptr;
7546 }
7547 TString libname(lib);
7548 Ssiz_t idx = libname.Last('.');
7549 if (idx != kNPOS) {
7550 libname.Remove(idx);
7551 }
7552 TEnvRec* rec;
7553 TIter next(fMapfile->GetTable());
7554 size_t len = libname.Length();
7555 while ((rec = (TEnvRec*) next())) {
7556 const char* libs = rec->GetValue();
7557 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7558 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
7559 return libs;
7560 }
7561 }
7562 return nullptr;
7563}
7564
7565////////////////////////////////////////////////////////////////////////////////
7566/// If error messages are disabled, the interpreter should suppress its
7567/// failures and warning messages from stdout.
7568
7570{
7571#if defined(R__MUST_REVISIT)
7572#if R__MUST_REVISIT(6,2)
7573 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
7574#endif
7575#endif
7576 return kTRUE;
7577}
7578
7579////////////////////////////////////////////////////////////////////////////////
7580/// If error messages are disabled, the interpreter should suppress its
7581/// failures and warning messages from stdout. Return the previous state.
7582
7584{
7585#if defined(R__MUST_REVISIT)
7586#if R__MUST_REVISIT(6,2)
7587 Warning("SetErrorMessages", "Interface not available yet.");
7588#endif
7589#endif
7591}
7592
7593////////////////////////////////////////////////////////////////////////////////
7594/// Refresh the list of include paths known to the interpreter and return it
7595/// with -I prepended.
7596
7598{
7600
7601 fIncludePath = "";
7602
7603 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7604 //false - no system header, true - with flags.
7605 fInterpreter->GetIncludePaths(includePaths, false, true);
7606 if (const size_t nPaths = includePaths.size()) {
7607 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
7608
7609 for (size_t i = 0; i < nPaths; i += 2) {
7610 if (i)
7611 fIncludePath.Append(' ');
7612 fIncludePath.Append(includePaths[i].c_str());
7613
7614 if (includePaths[i] != "-I")
7615 fIncludePath.Append(' ');
7616 fIncludePath.Append('"');
7618 fIncludePath.Append('"');
7619 }
7620 }
7621
7622 return fIncludePath;
7623}
7624
7625////////////////////////////////////////////////////////////////////////////////
7626/// Return the directory containing CINT's stl cintdlls.
7627
7628const char* TCling::GetSTLIncludePath() const
7629{
7630 return "";
7631}
7632
7633//______________________________________________________________________________
7634// M I S C
7635//______________________________________________________________________________
7636
7637int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
7638{
7639 // Interface to cling function
7640 return 0;
7641}
7642
7643////////////////////////////////////////////////////////////////////////////////
7644/// Interface to cling function
7645
7647{
7648 assert(fout != nullptr && "DisplayIncludePath, 'fout' parameter is null");
7649
7650 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7651 //false - no system header, true - with flags.
7652 fInterpreter->GetIncludePaths(includePaths, false, true);
7653 if (const size_t nPaths = includePaths.size()) {
7654 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
7655
7656 std::string allIncludes("include path:");
7657 for (size_t i = 0; i < nPaths; i += 2) {
7658 allIncludes += ' ';
7660
7661 if (includePaths[i] != "-I")
7662 allIncludes += ' ';
7663 allIncludes += includePaths[i + 1];
7664 }
7665
7666 fprintf(fout, "%s\n", allIncludes.c_str());
7667 }
7668
7669 return 0;
7670}
7671
7672////////////////////////////////////////////////////////////////////////////////
7673/// Interface to cling function
7674
7675void* TCling::FindSym(const char* entry) const
7676{
7678 return fInterpreter->getAddressOfGlobal(entry);
7679}
7680
7681////////////////////////////////////////////////////////////////////////////////
7682/// Let the interpreter issue a generic error, and set its error state.
7683
7684void TCling::GenericError(const char* error) const
7685{
7686#if defined(R__MUST_REVISIT)
7687#if R__MUST_REVISIT(6,2)
7688 Warning("GenericError","Interface not available yet.");
7689#endif
7690#endif
7691}
7692
7693////////////////////////////////////////////////////////////////////////////////
7694/// This routines used to return the address of the internal wrapper
7695/// function (of the interpreter) that was used to call *all* the
7696/// interpreted functions that were bytecode compiled (no longer
7697/// interpreted line by line). In Cling, there is no such
7698/// wrapper function.
7699/// In practice this routines was use to decipher whether the
7700/// pointer returns by InterfaceMethod could be used to uniquely
7701/// represent the function. In Cling if the function is in a
7702/// useable state (its compiled version is available), this is
7703/// always the case.
7704/// See TClass::GetMethod.
7705
7707{
7708 return 0;
7709}
7710
7711////////////////////////////////////////////////////////////////////////////////
7712/// Interface to cling function
7713
7715{
7716#if defined(R__MUST_REVISIT)
7717#if R__MUST_REVISIT(6,2)
7718 Warning("GetSecurityError", "Interface not available yet.");
7719#endif
7720#endif
7721 return 0;
7722}
7723
7724////////////////////////////////////////////////////////////////////////////////
7725/// Load a source file or library called path into the interpreter.
7726
7727int TCling::LoadFile(const char* path) const
7728{
7729 // Modifying the interpreter state needs locking.
7731 cling::Interpreter::CompilationResult compRes;
7732 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(".L %s", path), compRes, /*cling::Value*/nullptr);
7733 return compRes == cling::Interpreter::kFailure;
7734}
7735
7736////////////////////////////////////////////////////////////////////////////////
7737/// Load the declarations from text into the interpreter.
7738/// Note that this cannot be (top level) statements; text must contain
7739/// top level declarations.
7740/// Returns true on success, false on failure.
7741
7742Bool_t TCling::LoadText(const char* text) const
7743{
7744 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7745}
7746
7747////////////////////////////////////////////////////////////////////////////////
7748/// Interface to cling function
7749
7750const char* TCling::MapCppName(const char* name) const
7751{
7752 TTHREAD_TLS_DECL(std::string,buffer);
7754 return buffer.c_str(); // NOLINT
7755}
7756
7757////////////////////////////////////////////////////////////////////////////////
7758/// [Place holder for Mutex Lock]
7759/// Provide the interpreter with a way to
7760/// acquire a lock used to protect critical section
7761/// of its code (non-thread safe parts).
7762
7763void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7764{
7765 // nothing to do for now.
7766}
7767
7768////////////////////////////////////////////////////////////////////////////////
7769/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7770/// release a lock used to protect critical section
7771/// of its code (non-thread safe parts).
7772
7773void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7774{
7775 // nothing to do for now.
7776}
7777
7778////////////////////////////////////////////////////////////////////////////////
7779/// Returns if class AutoLoading is currently enabled.
7780
7782{
7783 if (IsFromRootCling())
7784 return false;
7785 if (!fClingCallbacks)
7786 return false;
7788}
7789
7790////////////////////////////////////////////////////////////////////////////////
7791/// Enable/Disable the AutoLoading of libraries.
7792/// Returns the old value, i.e whether it was enabled or not.
7793
7795{
7796 // If no state change is required, exit early.
7797 // FIXME: In future we probably want to complain if we made a request which
7798 // was with the same state as before in order to catch programming errors.
7799 if ((bool) autoload == IsClassAutoLoadingEnabled())
7800 return autoload;
7801
7802 assert(fClingCallbacks && "We must have callbacks!");
7805 return oldVal;
7806}
7807
7808////////////////////////////////////////////////////////////////////////////////
7809/// Enable/Disable the Autoparsing of headers.
7810/// Returns the old value, i.e whether it was enabled or not.
7811
7818
7819////////////////////////////////////////////////////////////////////////////////
7820/// Suspend the Autoparsing of headers.
7821/// Returns the old value, i.e whether it was suspended or not.
7822
7829
7830////////////////////////////////////////////////////////////////////////////////
7831/// Set a callback to receive error messages.
7832
7834{
7835#if defined(R__MUST_REVISIT)
7836#if R__MUST_REVISIT(6,2)
7837 Warning("SetErrmsgcallback", "Interface not available yet.");
7838#endif
7839#endif
7840}
7841
7843{
7844 if (enable) {
7846 &fInterpreter->getDiagnostics().getDiagnosticOptions(),
7847 fInterpreter->getCI()->getLangOpts(),
7848 [] (clang::DiagnosticsEngine::Level Level, const std::string &Info) {
7849 if (Level == clang::DiagnosticsEngine::Warning) {
7850 ::Warning("cling", "%s", Info.c_str());
7851 } else if (Level == clang::DiagnosticsEngine::Error
7852 || Level == clang::DiagnosticsEngine::Fatal) {
7853 ::Error("cling", "%s", Info.c_str());
7854 } else {
7855 ::Info("cling", "%s", Info.c_str());
7856 }
7857 });
7858 fInterpreter->replaceDiagnosticConsumer(consumer, /*Own=*/true);
7859 } else {
7860 fInterpreter->replaceDiagnosticConsumer(nullptr);
7861 }
7862}
7863
7864
7865////////////////////////////////////////////////////////////////////////////////
7866/// Create / close a scope for temporaries. No-op for cling; use
7867/// cling::Value instead.
7868
7869void TCling::SetTempLevel(int val) const
7870{
7871}
7872
7873////////////////////////////////////////////////////////////////////////////////
7874
7875int TCling::UnloadFile(const char* path) const
7876{
7877 // Modifying the interpreter state needs locking.
7879 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7880 std::string canonical = DLM->lookupLibrary(path);
7881 if (canonical.empty()) {
7882 canonical = path;
7883 }
7884 // Unload a shared library or a source file.
7885 cling::Interpreter::CompilationResult compRes;
7886 HandleInterpreterException(GetMetaProcessorImpl(), Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/nullptr);
7887 return compRes == cling::Interpreter::kFailure;
7888}
7889
7890std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7891 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7892}
7893
7894////////////////////////////////////////////////////////////////////////////////
7895/// The call to Cling's tab complition.
7896
7897void TCling::CodeComplete(const std::string& line, size_t& cursor,
7898 std::vector<std::string>& completions)
7899{
7900 fInterpreter->codeComplete(line, cursor, completions);
7901}
7902
7903////////////////////////////////////////////////////////////////////////////////
7904/// Get the interpreter value corresponding to the statement.
7906{
7908
7909 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7910 auto compRes = fInterpreter->evaluate(code, *V);
7911 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7912}
7913
7914////////////////////////////////////////////////////////////////////////////////
7915
7917{
7918 using namespace cling;
7919 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7921}
7922
7923////////////////////////////////////////////////////////////////////////////////
7924/// Register value as a temporary, extending its lifetime to that of the
7925/// interpreter. This is needed for TCling's compatibility interfaces
7926/// returning long - the address of the temporary objects.
7927/// As such, "simple" types don't need to be stored; they are returned by
7928/// value; only pointers / references / objects need to be stored.
7929
7930void TCling::RegisterTemporary(const cling::Value& value)
7931{
7932 if (value.isValid() && value.needsManagedAllocation()) {
7934 fTemporaries->push_back(value);
7935 }
7936}
7937
7938////////////////////////////////////////////////////////////////////////////////
7939/// If the interpreter encounters Name, check whether that is an object ROOT
7940/// could retrieve. To not re-read objects from disk, cache the name/object
7941/// pair for a given LookupCtx.
7942
7944{
7945 // The call to FindSpecialObject might induces any kind of use
7946 // of the interpreter ... (library loading, function calling, etc.)
7947 // ... and we _know_ we are in the middle of parsing, so let's make
7948 // sure to save the state and then restore it.
7949
7950 if (gDirectory) {
7952 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7953 auto iSpecObj = iSpecObjMap->second.find(Name);
7954 if (iSpecObj != iSpecObjMap->second.end()) {
7956 return iSpecObj->second;
7957 }
7958 }
7959 }
7960
7961 // Save state of the PP
7962 Sema &SemaR = fInterpreter->getSema();
7963 ASTContext& C = SemaR.getASTContext();
7964 Preprocessor &PP = SemaR.getPreprocessor();
7965 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7966 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7967 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7968 // After we have saved the token reset the current one to something which
7969 // is safe (semi colon usually means empty decl)
7970 Token& Tok = const_cast<Token&>(P.getCurToken());
7971 Tok.setKind(tok::semi);
7972
7973 // We can't PushDeclContext, because we go up and the routine that pops
7974 // the DeclContext assumes that we drill down always.
7975 // We have to be on the global context. At that point we are in a
7976 // wrapper function so the parent context must be the global.
7977 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7978 SemaR.TUScope);
7979
7980 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7981 if (specObj) {
7982 if (!LookupCtx) {
7983 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7984 } else {
7986 }
7987 }
7988 return specObj;
7989}
7990
7991////////////////////////////////////////////////////////////////////////////////
7992/// Inject function as a friend into klass.
7993/// With function being f in void f() {new N::PrivKlass(); } this enables
7994/// I/O of non-public classes.
7995
7996void TCling::AddFriendToClass(clang::FunctionDecl* function,
7997 clang::CXXRecordDecl* klass) const
7998{
7999 using namespace clang;
8000 ASTContext& Ctx = klass->getASTContext();
8001 FriendDecl::FriendUnion friendUnion(function);
8002 // one dummy object for the source location
8004 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
8005 klass->pushFriendDecl(friendDecl);
8006}
8007
8008//______________________________________________________________________________
8009//
8010// DeclId getter.
8011//
8012
8013////////////////////////////////////////////////////////////////////////////////
8014/// Return a unique identifier of the declaration represented by the
8015/// CallFunc
8016
8018{
8019 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
8020 return nullptr;
8021}
8022
8023////////////////////////////////////////////////////////////////////////////////
8024/// Return a (almost) unique identifier of the declaration represented by the
8025/// ClassInfo. In ROOT, this identifier can point to more than one TClass
8026/// when the underlying class is a template instance involving one of the
8027/// opaque typedef.
8028
8030{
8031 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
8032 return nullptr;
8033}
8034
8035////////////////////////////////////////////////////////////////////////////////
8036/// Return a unique identifier of the declaration represented by the
8037/// MethodInfo
8038
8040{
8041 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
8042 return nullptr;
8043}
8044
8045////////////////////////////////////////////////////////////////////////////////
8046/// Return a unique identifier of the declaration represented by the
8047/// MethodInfo
8048
8050{
8051 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
8052 return nullptr;
8053}
8054
8055////////////////////////////////////////////////////////////////////////////////
8056/// Return a unique identifier of the declaration represented by the
8057/// TypedefInfo
8058
8060{
8061 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
8062 return nullptr;
8063}
8064
8065//______________________________________________________________________________
8066//
8067// CallFunc interface
8068//
8069
8070////////////////////////////////////////////////////////////////////////////////
8071
8073{
8074 delete (TClingCallFunc*) func;
8075}
8076
8077////////////////////////////////////////////////////////////////////////////////
8078
8079void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
8080{
8081 TClingCallFunc* f = (TClingCallFunc*) func;
8082 f->Exec(address);
8083}
8084
8085////////////////////////////////////////////////////////////////////////////////
8086
8087void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
8088{
8089 TClingCallFunc* f = (TClingCallFunc*) func;
8090 f->Exec(address, &val);
8091}
8092
8093////////////////////////////////////////////////////////////////////////////////
8094
8095void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
8096{
8097 TClingCallFunc* f = (TClingCallFunc*) func;
8098 f->ExecWithReturn(address, ret);
8099}
8100
8101////////////////////////////////////////////////////////////////////////////////
8102
8104 const void* args[] /*=0*/,
8105 int nargs /*=0*/,
8106 void* ret/*=0*/) const
8107{
8108 TClingCallFunc* f = (TClingCallFunc*) func;
8109 f->ExecWithArgsAndReturn(address, args, nargs, ret);
8110}
8111
8112////////////////////////////////////////////////////////////////////////////////
8113
8115{
8116 TClingCallFunc* f = (TClingCallFunc*) func;
8117 return f->ExecInt(address);
8118}
8119
8120////////////////////////////////////////////////////////////////////////////////
8121
8123{
8124 TClingCallFunc* f = (TClingCallFunc*) func;
8125 return f->ExecInt64(address);
8126}
8127
8128////////////////////////////////////////////////////////////////////////////////
8129
8131{
8132 TClingCallFunc* f = (TClingCallFunc*) func;
8133 return f->ExecDouble(address);
8134}
8135
8136////////////////////////////////////////////////////////////////////////////////
8137
8143
8144////////////////////////////////////////////////////////////////////////////////
8145
8147{
8148 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
8149}
8150
8151////////////////////////////////////////////////////////////////////////////////
8152
8154{
8155 TClingCallFunc* f = (TClingCallFunc*) func;
8156 return (MethodInfo_t*) f->FactoryMethod();
8157}
8158
8159////////////////////////////////////////////////////////////////////////////////
8160
8162{
8163 TClingCallFunc* f = (TClingCallFunc*) func;
8164 f->IgnoreExtraArgs(ignore);
8165}
8166
8167////////////////////////////////////////////////////////////////////////////////
8168
8170{
8172 TClingCallFunc* f = (TClingCallFunc*) func;
8173 f->Init();
8174}
8175
8176////////////////////////////////////////////////////////////////////////////////
8177
8179{
8180 TClingCallFunc* f = (TClingCallFunc*) func;
8181 return f->IsValid();
8182}
8183
8184////////////////////////////////////////////////////////////////////////////////
8185
8188{
8189 TClingCallFunc* f = (TClingCallFunc*) func;
8190 return f->IFacePtr();
8191}
8192
8193////////////////////////////////////////////////////////////////////////////////
8194
8196{
8197 TClingCallFunc* f = (TClingCallFunc*) func;
8198 f->ResetArg();
8199}
8200
8201////////////////////////////////////////////////////////////////////////////////
8202
8204{
8205 TClingCallFunc* f = (TClingCallFunc*) func;
8206 f->SetArg(param);
8207}
8208
8209////////////////////////////////////////////////////////////////////////////////
8210
8212{
8213 TClingCallFunc* f = (TClingCallFunc*) func;
8214 f->SetArg(param);
8215}
8216
8217////////////////////////////////////////////////////////////////////////////////
8218
8220{
8221 TClingCallFunc* f = (TClingCallFunc*) func;
8222 f->SetArg(param);
8223}
8224
8225////////////////////////////////////////////////////////////////////////////////
8226
8228{
8229 TClingCallFunc* f = (TClingCallFunc*) func;
8230 f->SetArg(param);
8231}
8232
8233////////////////////////////////////////////////////////////////////////////////
8234
8236{
8237 TClingCallFunc* f = (TClingCallFunc*) func;
8238 f->SetArg(param);
8239}
8240
8241////////////////////////////////////////////////////////////////////////////////
8242
8244{
8245 TClingCallFunc* f = (TClingCallFunc*) func;
8246 f->SetArg(param);
8247}
8248
8249////////////////////////////////////////////////////////////////////////////////
8250
8252{
8253 TClingCallFunc* f = (TClingCallFunc*) func;
8254 f->SetArgArray(paramArr, nparam);
8255}
8256
8257////////////////////////////////////////////////////////////////////////////////
8258
8259void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
8260{
8261 TClingCallFunc* f = (TClingCallFunc*) func;
8262 f->SetArgs(param);
8263}
8264
8265////////////////////////////////////////////////////////////////////////////////
8266
8267void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Longptr_t* offset) const
8268{
8269 TClingCallFunc* f = (TClingCallFunc*) func;
8271 f->SetFunc(ci, method, params, offset);
8272}
8273
8274////////////////////////////////////////////////////////////////////////////////
8275
8276void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Longptr_t* offset) const
8277{
8278 TClingCallFunc* f = (TClingCallFunc*) func;
8280 f->SetFunc(ci, method, params, objectIsConst, offset);
8281}
8282////////////////////////////////////////////////////////////////////////////////
8283
8284void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
8285{
8286 TClingCallFunc* f = (TClingCallFunc*) func;
8288 f->SetFunc(minfo);
8289}
8290
8291////////////////////////////////////////////////////////////////////////////////
8292/// Interface to cling function
8293
8294void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8295{
8296 TClingCallFunc* f = (TClingCallFunc*) func;
8298 f->SetFuncProto(ci, method, proto, offset, mode);
8299}
8300
8301////////////////////////////////////////////////////////////////////////////////
8302/// Interface to cling function
8303
8304void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8305{
8306 TClingCallFunc* f = (TClingCallFunc*) func;
8308 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
8309}
8310
8311////////////////////////////////////////////////////////////////////////////////
8312/// Interface to cling function
8313
8314void 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
8315{
8316 TClingCallFunc* f = (TClingCallFunc*) func;
8318 llvm::SmallVector<clang::QualType, 4> funcProto;
8319 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8320 iter != end; ++iter) {
8321 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8322 }
8323 f->SetFuncProto(ci, method, funcProto, offset, mode);
8324}
8325
8326////////////////////////////////////////////////////////////////////////////////
8327/// Interface to cling function
8328
8329void 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
8330{
8331 TClingCallFunc* f = (TClingCallFunc*) func;
8333 llvm::SmallVector<clang::QualType, 4> funcProto;
8334 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8335 iter != end; ++iter) {
8336 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8337 }
8338 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
8339}
8340
8342{
8343 TClingCallFunc *f = (TClingCallFunc *)func;
8344 std::string wrapper_name;
8345 std::string wrapper;
8346 f->get_wrapper_code(wrapper_name, wrapper);
8347 return wrapper;
8348}
8349
8350//______________________________________________________________________________
8351//
8352// ClassInfo interface
8353//
8354
8355////////////////////////////////////////////////////////////////////////////////
8356
8358{
8360 return TClinginfo->GetAlignOf();
8361}
8362
8363////////////////////////////////////////////////////////////////////////////////
8364/// Return true if the entity pointed to by 'declid' is declared in
8365/// the context described by 'info'. If info is null, look into the
8366/// global scope (translation unit scope).
8367
8369{
8370 if (!declid)
8371 return kFALSE;
8372
8373 const clang::DeclContext *ctxt = nullptr;
8374 if (info) {
8375 ctxt = clang::Decl::castToDeclContext(((TClingClassInfo*)info)->GetDecl());
8376 } else {
8377 ctxt = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
8378 }
8379 if (!ctxt)
8380 return kFALSE;
8381
8382 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
8383 if (!decl)
8384 return kFALSE;
8385
8386 const clang::DeclContext *declDC = decl->getDeclContext();
8387 // ClassInfo_t-s are always "spellable" scopes, never unnamed or inline ones.
8388 while (true) {
8389 if (declDC->isTransparentContext()) {
8390 declDC = declDC->getParent();
8391 continue;
8392 }
8393 if (const auto *declRD = llvm::dyn_cast<clang::RecordDecl>(declDC)) {
8394 if (declRD->isAnonymousStructOrUnion()) {
8395 declDC = declRD->getParent();
8396 continue;
8397 }
8398 }
8399 if (const auto *declNS = llvm::dyn_cast<clang::NamespaceDecl>(declDC)) {
8400 if (declNS->isAnonymousNamespace() || declNS->isInlineNamespace()) {
8401 declDC = declNS->getParent();
8402 continue;
8403 }
8404 }
8405 break;
8406 }
8407
8408 return declDC->Equals(ctxt);
8409}
8410
8411////////////////////////////////////////////////////////////////////////////////
8412
8418
8419////////////////////////////////////////////////////////////////////////////////
8420
8422{
8423 delete (TClingClassInfo*) cinfo;
8424}
8425
8426////////////////////////////////////////////////////////////////////////////////
8427
8433
8434////////////////////////////////////////////////////////////////////////////////
8435
8441
8442////////////////////////////////////////////////////////////////////////////////
8443
8449
8450////////////////////////////////////////////////////////////////////////////////
8451
8457
8458////////////////////////////////////////////////////////////////////////////////
8459
8464
8465////////////////////////////////////////////////////////////////////////////////
8466
8472
8478
8479
8480////////////////////////////////////////////////////////////////////////////////
8481
8482int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
8483{
8485 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
8486}
8487
8488////////////////////////////////////////////////////////////////////////////////
8489
8495
8496////////////////////////////////////////////////////////////////////////////////
8497
8499{
8501 return TClinginfo->HasMethod(name);
8502}
8503
8504////////////////////////////////////////////////////////////////////////////////
8505
8512
8513////////////////////////////////////////////////////////////////////////////////
8514
8521
8522////////////////////////////////////////////////////////////////////////////////
8523
8525{
8527 return TClinginfo->IsBase(name);
8528}
8529
8530////////////////////////////////////////////////////////////////////////////////
8531
8532bool TCling::ClassInfo_IsEnum(const char* name) const
8533{
8535}
8536
8537////////////////////////////////////////////////////////////////////////////////
8538
8544
8545
8546////////////////////////////////////////////////////////////////////////////////
8547
8553
8554
8555////////////////////////////////////////////////////////////////////////////////
8556
8558{
8560 return TClinginfo->IsLoaded();
8561}
8562
8563////////////////////////////////////////////////////////////////////////////////
8564
8566{
8568 return TClinginfo->IsValid();
8569}
8570
8571////////////////////////////////////////////////////////////////////////////////
8572
8573bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8574{
8576 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
8577}
8578
8579////////////////////////////////////////////////////////////////////////////////
8580
8582{
8584 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8585}
8586
8587////////////////////////////////////////////////////////////////////////////////
8588
8594
8595////////////////////////////////////////////////////////////////////////////////
8596
8602
8603////////////////////////////////////////////////////////////////////////////////
8604
8610
8611////////////////////////////////////////////////////////////////////////////////
8612
8614{
8616 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8617}
8618
8619////////////////////////////////////////////////////////////////////////////////
8620
8626
8627////////////////////////////////////////////////////////////////////////////////
8628
8634
8635////////////////////////////////////////////////////////////////////////////////
8636
8642
8643////////////////////////////////////////////////////////////////////////////////
8644
8650
8651////////////////////////////////////////////////////////////////////////////////
8652
8654{
8656 return TClinginfo->FileName();
8657}
8658
8659////////////////////////////////////////////////////////////////////////////////
8660
8662{
8664 TTHREAD_TLS_DECL(std::string,output);
8665 TClinginfo->FullName(output,*fNormalizedCtxt);
8666 return output.c_str(); // NOLINT
8667}
8668
8669////////////////////////////////////////////////////////////////////////////////
8670
8672{
8674 return TClinginfo->Name();
8675}
8676
8677////////////////////////////////////////////////////////////////////////////////
8678
8680{
8682 return TClinginfo->Title();
8683}
8684
8685////////////////////////////////////////////////////////////////////////////////
8686
8688{
8690 return TClinginfo->TmpltName();
8691}
8692
8693
8694
8695//______________________________________________________________________________
8696//
8697// BaseClassInfo interface
8698//
8699
8700////////////////////////////////////////////////////////////////////////////////
8701
8706
8707////////////////////////////////////////////////////////////////////////////////
8708
8715
8716////////////////////////////////////////////////////////////////////////////////
8717
8726
8727////////////////////////////////////////////////////////////////////////////////
8728
8734
8735////////////////////////////////////////////////////////////////////////////////
8736
8742
8743////////////////////////////////////////////////////////////////////////////////
8744
8750
8751////////////////////////////////////////////////////////////////////////////////
8752
8754{
8757 // Offset to the class itself.
8758 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8759 return 0;
8760 }
8761 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8762}
8763
8764////////////////////////////////////////////////////////////////////////////////
8765
8771
8772////////////////////////////////////////////////////////////////////////////////
8773
8779
8780////////////////////////////////////////////////////////////////////////////////
8781
8787
8788////////////////////////////////////////////////////////////////////////////////
8789
8791{
8793 TTHREAD_TLS_DECL(std::string,output);
8794 TClinginfo->FullName(output,*fNormalizedCtxt);
8795 return output.c_str(); // NOLINT
8796}
8797
8798////////////////////////////////////////////////////////////////////////////////
8799
8805
8806////////////////////////////////////////////////////////////////////////////////
8807
8813
8814//______________________________________________________________________________
8815//
8816// DataMemberInfo interface
8817//
8818
8819////////////////////////////////////////////////////////////////////////////////
8820
8826
8827////////////////////////////////////////////////////////////////////////////////
8828
8833
8834////////////////////////////////////////////////////////////////////////////////
8835
8842
8843////////////////////////////////////////////////////////////////////////////////
8844
8846{
8848 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8849 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8851}
8852
8853////////////////////////////////////////////////////////////////////////////////
8854
8860
8861////////////////////////////////////////////////////////////////////////////////
8862
8868
8869////////////////////////////////////////////////////////////////////////////////
8870
8876
8877////////////////////////////////////////////////////////////////////////////////
8878
8884
8885////////////////////////////////////////////////////////////////////////////////
8886
8892
8893////////////////////////////////////////////////////////////////////////////////
8894
8900
8901////////////////////////////////////////////////////////////////////////////////
8902
8908
8909////////////////////////////////////////////////////////////////////////////////
8910
8916
8917////////////////////////////////////////////////////////////////////////////////
8918
8924
8925////////////////////////////////////////////////////////////////////////////////
8926
8932
8933////////////////////////////////////////////////////////////////////////////////
8934
8940
8941////////////////////////////////////////////////////////////////////////////////
8942
8948
8949////////////////////////////////////////////////////////////////////////////////
8950
8952{
8953 TTHREAD_TLS_DECL(std::string,result);
8954
8956 result = TClinginfo->ValidArrayIndex().str();
8957 return result.c_str(); // NOLINT
8958}
8959
8960////////////////////////////////////////////////////////////////////////////////
8961
8962void TCling::SetDeclAttr(DeclId_t declId, const char* attribute)
8963{
8964 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8965 ASTContext &C = decl->getASTContext();
8966 decl->addAttr(AnnotateAttr::CreateImplicit(C, attribute, nullptr, 0));
8967}
8968
8969//______________________________________________________________________________
8970//
8971// Function Template interface
8972//
8973
8974////////////////////////////////////////////////////////////////////////////////
8975
8976static void ConstructorName(std::string &name, const clang::Decl *decl,
8977 cling::Interpreter &interp,
8979{
8980 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8981 if (!td) return;
8982
8983 clang::QualType qualType = td->getASTContext().getTypeDeclType(td);
8985 unsigned int level = 0;
8986 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8987 if (name[cursor] == '>') ++level;
8988 else if (name[cursor] == '<' && level) --level;
8989 else if (level == 0 && name[cursor] == ':') {
8990 name.erase(0,cursor+1);
8991 break;
8992 }
8993 }
8994}
8995
8996////////////////////////////////////////////////////////////////////////////////
8997
8998void TCling::GetFunctionName(const clang::Decl *decl, std::string &output) const
8999{
9000 output.clear();
9001
9002 const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(decl);
9003 if (const auto *USD = llvm::dyn_cast<clang::UsingShadowDecl>(decl)) {
9004 FD = llvm::dyn_cast<clang::FunctionDecl>(USD->getTargetDecl());
9005 }
9006 if (!FD) {
9007 Error("GetFunctionName", "NULL Decl!");
9008 return;
9009 }
9010
9011 // For using-decls, show "Derived", not "Base", i.e. use the
9012 // name of the decl context of the UsingShadowDecl (aka `decl`)
9013 // not the name of FD's decl context.
9014 if (llvm::isa<clang::CXXConstructorDecl>(FD))
9015 {
9017
9018 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
9019 {
9021 output.insert(output.begin(), '~');
9022 } else {
9023 llvm::raw_string_ostream stream(output);
9024 auto printPolicy = decl->getASTContext().getPrintingPolicy();
9025 // Don't trigger fopen of the source file to count lines:
9026 printPolicy.AnonymousTagLocations = false;
9027 FD->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
9028 }
9029}
9030
9031////////////////////////////////////////////////////////////////////////////////
9032/// Return a unique identifier of the declaration represented by the
9033/// FuncTempInfo
9034
9039
9040////////////////////////////////////////////////////////////////////////////////
9041/// Delete the FuncTempInfo_t
9042
9044{
9045 // Currently the address of ft_info is actually the decl itself,
9046 // so we have nothing to do.
9047}
9048
9049////////////////////////////////////////////////////////////////////////////////
9050/// Construct a FuncTempInfo_t
9051
9053{
9054 // Currently the address of ft_info is actually the decl itself,
9055 // so we have nothing to do.
9056
9057 return (FuncTempInfo_t*)const_cast<void*>(declid);
9058}
9059
9060////////////////////////////////////////////////////////////////////////////////
9061/// Construct a FuncTempInfo_t
9062
9064{
9065 // Currently the address of ft_info is actually the decl itself,
9066 // so we have nothing to do.
9067
9068 return (FuncTempInfo_t*)ft_info;
9069}
9070
9071////////////////////////////////////////////////////////////////////////////////
9072/// Check validity of a FuncTempInfo_t
9073
9075{
9076 // Currently the address of ft_info is actually the decl itself,
9077 // so we have nothing to do.
9078
9079 return t_info != nullptr;
9080}
9081
9082////////////////////////////////////////////////////////////////////////////////
9083/// Return the maximum number of template arguments of the
9084/// function template described by ft_info.
9085
9087{
9088 if (!ft_info) return 0;
9089 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
9090 return ft->getTemplateParameters()->size();
9091}
9092
9093////////////////////////////////////////////////////////////////////////////////
9094/// Return the number of required template arguments of the
9095/// function template described by ft_info.
9096
9098{
9099 if (!ft_info) return 0;
9100 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9101 return ft->getTemplateParameters()->getMinRequiredArguments();
9102}
9103
9104////////////////////////////////////////////////////////////////////////////////
9105/// Return the property of the function template.
9106
9108{
9109 if (!ft_info) return 0;
9110
9111 long property = 0L;
9112 property |= kIsCompiled;
9113
9114 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9115
9116 switch (ft->getAccess()) {
9117 case clang::AS_public:
9118 property |= kIsPublic;
9119 break;
9120 case clang::AS_protected:
9121 property |= kIsProtected;
9122 break;
9123 case clang::AS_private:
9124 property |= kIsPrivate;
9125 break;
9126 case clang::AS_none:
9127 if (ft->getDeclContext()->isNamespace())
9129 break;
9130 default:
9131 // IMPOSSIBLE
9132 assert(false && "Unexpected value for the access property value in Clang");
9133 break;
9134 }
9135
9136 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
9137
9138 if (fd && fd->getStorageClass() == clang::SC_Static)
9139 property |= kIsStatic;
9140
9141 if (const clang::CXXMethodDecl *md =
9142 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
9143 if (md->getMethodQualifiers().hasConst()) {
9144 property |= kIsConstant | kIsConstMethod;
9145 }
9146 if (md->isVirtual()) {
9147 property |= kIsVirtual;
9148 }
9149 if (md->isPureVirtual()) {
9150 property |= kIsPureVirtual;
9151 }
9152 if (const clang::CXXConstructorDecl *cd =
9153 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
9154 if (cd->isExplicit()) {
9155 property |= kIsExplicit;
9156 }
9157 }
9158 else if (const clang::CXXConversionDecl *cd =
9159 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
9160 if (cd->isExplicit()) {
9161 property |= kIsExplicit;
9162 }
9163 }
9164 }
9165 return property;
9166}
9167
9168////////////////////////////////////////////////////////////////////////////////
9169/// Return the property not already defined in Property
9170/// See TDictionary's EFunctionProperty
9171
9173{
9174 if (!ft_info) return 0;
9175
9176 long property = 0L;
9177 property |= kIsCompiled;
9178
9179 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9180 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
9181
9182 if (fd->isOverloadedOperator())
9184 if (llvm::isa<clang::CXXConversionDecl>(fd))
9186 if (llvm::isa<clang::CXXConstructorDecl>(fd))
9188 if (llvm::isa<clang::CXXDestructorDecl>(fd))
9190 if (fd->isInlined())
9192 return property;
9193}
9194
9195////////////////////////////////////////////////////////////////////////////////
9196/// Return the name of this function template.
9197
9199{
9200 output.Clear();
9201 if (!ft_info) return;
9202 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9203 std::string buf;
9204 GetFunctionName(ft->getTemplatedDecl(), buf);
9205 output = buf;
9206}
9207
9208////////////////////////////////////////////////////////////////////////////////
9209/// Return the comments associates with this function template.
9210
9212{
9213 output.Clear();
9214 if (!ft_info) return;
9215 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
9216
9217 // Iterate over the redeclarations, we can have multiple definitions in the
9218 // redecl chain (came from merging of pcms).
9221 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
9222 output = A->getAnnotation().str();
9223 return;
9224 }
9225 }
9226 if (!ft->isFromASTFile()) {
9227 // Try to get the comment from the header file if present
9228 // but not for decls from AST file, where rootcling would have
9229 // created an annotation
9230 output = ROOT::TMetaUtils::GetComment(*ft).str();
9231 }
9232}
9233
9234
9235//______________________________________________________________________________
9236//
9237// MethodInfo interface
9238//
9239
9240////////////////////////////////////////////////////////////////////////////////
9241/// Interface to cling function
9242
9243void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
9244{
9245 delete(TClingMethodInfo*) minfo;
9246}
9247
9248////////////////////////////////////////////////////////////////////////////////
9249
9251{
9253 // The next call locks the interpreter mutex.
9254 info->CreateSignature(signature);
9255}
9256
9257////////////////////////////////////////////////////////////////////////////////
9258
9259MethodInfo_t* TCling::MethodInfo_Factory() const
9260{
9262 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl());
9263}
9264
9265////////////////////////////////////////////////////////////////////////////////
9266
9268{
9270 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
9271}
9272
9273////////////////////////////////////////////////////////////////////////////////
9274
9276{
9277 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
9279 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), decl);
9280}
9281
9282////////////////////////////////////////////////////////////////////////////////
9283
9284MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
9285{
9286 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
9287}
9288
9289////////////////////////////////////////////////////////////////////////////////
9290
9292{
9294 // The next call locks the interpreter mutex.
9295 return info->InterfaceMethod();
9296}
9297
9298////////////////////////////////////////////////////////////////////////////////
9299
9300bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
9301{
9303 return info->IsValid();
9304}
9305
9306////////////////////////////////////////////////////////////////////////////////
9307
9308int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
9309{
9311 return info->NArg();
9312}
9313
9314////////////////////////////////////////////////////////////////////////////////
9315
9317{
9319 return info->NDefaultArg();
9320}
9321
9322////////////////////////////////////////////////////////////////////////////////
9323
9324int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
9325{
9327 return info->Next();
9328}
9329
9330////////////////////////////////////////////////////////////////////////////////
9331
9333{
9335 // The next call locks the interpreter mutex.
9336 return info->Property();
9337}
9338
9339////////////////////////////////////////////////////////////////////////////////
9340
9342{
9344 // The next call locks the interpreter mutex.
9345 return info->ExtraProperty();
9346}
9347
9348////////////////////////////////////////////////////////////////////////////////
9349
9351{
9353 // The next call locks the interpreter mutex.
9354 return (TypeInfo_t*)info->Type();
9355}
9356
9357////////////////////////////////////////////////////////////////////////////////
9358
9359const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
9360{
9363 // The next call locks the interpreter mutex.
9364 mangled_name = info->GetMangledName();
9365 return mangled_name;
9366}
9367
9368////////////////////////////////////////////////////////////////////////////////
9369
9370const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
9371{
9373 // The next call locks the interpreter mutex.
9374 return info->GetPrototype();
9375}
9376
9377////////////////////////////////////////////////////////////////////////////////
9378
9379const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
9380{
9382 // The next call locks the interpreter mutex.
9383 return info->Name();
9384}
9385
9386////////////////////////////////////////////////////////////////////////////////
9387
9388const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
9389{
9391 // The next call locks the interpreter mutex.
9392 return info->TypeName();
9393}
9394
9395////////////////////////////////////////////////////////////////////////////////
9396
9397std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
9398{
9400 // The next part locks the interpreter mutex.
9401 if (info && info->IsValid())
9402 return info->Type()->NormalizedName(*fNormalizedCtxt);
9403 else
9404 return "";
9405}
9406
9407////////////////////////////////////////////////////////////////////////////////
9408
9409const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
9410{
9412 // The next call locks the interpreter mutex.
9413 return info->Title();
9414}
9415
9416////////////////////////////////////////////////////////////////////////////////
9417
9419{
9420 if (func) {
9421 return MethodInfo_MethodCallReturnType(func->fInfo);
9422 } else {
9423 return EReturnType::kOther;
9424 }
9425}
9426
9427////////////////////////////////////////////////////////////////////////////////
9428
9430{
9432 if (info && info->IsValid()) {
9433 TClingTypeInfo *typeinfo = info->Type();
9434 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
9435 if (QT->isEnumeralType()) {
9436 return EReturnType::kLong;
9437 } else if (QT->isPointerType()) {
9438 // Look for char*
9439 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
9440 if ( QT->isCharType() ) {
9441 return EReturnType::kString;
9442 } else {
9443 return EReturnType::kOther;
9444 }
9445 } else if ( QT->isFloatingType() ) {
9446 int sz = typeinfo->Size();
9447 if (sz == 4 || sz == 8) {
9448 // Support only float and double.
9449 return EReturnType::kDouble;
9450 } else {
9451 return EReturnType::kOther;
9452 }
9453 } else if ( QT->isIntegerType() ) {
9454 int sz = typeinfo->Size();
9455 if (sz <= 8) {
9456 // Support only up to long long ... but
9457 // FIXME the TMethodCall::Execute only
9458 // return long (4 bytes) ...
9459 // The v5 implementation of TMethodCall::ReturnType
9460 // was not making the distinction so we let it go
9461 // as is for now, but we really need to upgrade
9462 // TMethodCall::Execute ...
9463 return EReturnType::kLong;
9464 } else {
9465 return EReturnType::kOther;
9466 }
9467 } else {
9468 return EReturnType::kOther;
9469 }
9470 } else {
9471 return EReturnType::kOther;
9472 }
9473}
9474
9475//______________________________________________________________________________
9476//
9477// MethodArgInfo interface
9478//
9479
9480////////////////////////////////////////////////////////////////////////////////
9481
9486
9487////////////////////////////////////////////////////////////////////////////////
9488
9494
9495////////////////////////////////////////////////////////////////////////////////
9496
9502
9503////////////////////////////////////////////////////////////////////////////////
9504
9510
9511////////////////////////////////////////////////////////////////////////////////
9512
9518
9519////////////////////////////////////////////////////////////////////////////////
9520
9526
9527////////////////////////////////////////////////////////////////////////////////
9528
9534
9535////////////////////////////////////////////////////////////////////////////////
9536
9538{
9540 return info->DefaultValue();
9541}
9542
9543////////////////////////////////////////////////////////////////////////////////
9544
9546{
9548 return info->Name();
9549}
9550
9551////////////////////////////////////////////////////////////////////////////////
9552
9554{
9556 return info->TypeName();
9557}
9558
9559////////////////////////////////////////////////////////////////////////////////
9560
9562{
9564 return info->Type()->NormalizedName(*fNormalizedCtxt);
9565}
9566
9567////////////////////////////////////////////////////////////////////////////////
9568
9574
9575//______________________________________________________________________________
9576//
9577// TypeInfo interface
9578//
9579
9580////////////////////////////////////////////////////////////////////////////////
9581
9583{
9584 delete (TClingTypeInfo*) tinfo;
9585}
9586
9587////////////////////////////////////////////////////////////////////////////////
9588
9594
9595////////////////////////////////////////////////////////////////////////////////
9596
9602
9603////////////////////////////////////////////////////////////////////////////////
9604
9609
9610////////////////////////////////////////////////////////////////////////////////
9611
9618
9619////////////////////////////////////////////////////////////////////////////////
9620
9622{
9624 return TClinginfo->IsValid();
9625}
9626
9627////////////////////////////////////////////////////////////////////////////////
9628
9630{
9632 return TClinginfo->Name();
9633}
9634
9635////////////////////////////////////////////////////////////////////////////////
9636
9642
9643////////////////////////////////////////////////////////////////////////////////
9644
9646{
9648 return TClinginfo->RefType();
9649}
9650
9651////////////////////////////////////////////////////////////////////////////////
9652
9654{
9656 return TClinginfo->Size();
9657}
9658
9659////////////////////////////////////////////////////////////////////////////////
9660
9662{
9664 return TClinginfo->TrueName(*fNormalizedCtxt);
9665}
9666
9667////////////////////////////////////////////////////////////////////////////////
9668
9670{
9672 return TClinginfo->QualTypePtr();
9673}
9674
9675
9676//______________________________________________________________________________
9677//
9678// TypedefInfo interface
9679//
9680
9681////////////////////////////////////////////////////////////////////////////////
9682
9687
9688////////////////////////////////////////////////////////////////////////////////
9689
9695
9696////////////////////////////////////////////////////////////////////////////////
9697
9703
9704////////////////////////////////////////////////////////////////////////////////
9705
9710
9711////////////////////////////////////////////////////////////////////////////////
9712
9720
9721////////////////////////////////////////////////////////////////////////////////
9722
9728
9729////////////////////////////////////////////////////////////////////////////////
9730
9736
9737////////////////////////////////////////////////////////////////////////////////
9738
9744
9745////////////////////////////////////////////////////////////////////////////////
9746
9752
9753////////////////////////////////////////////////////////////////////////////////
9754
9760
9761////////////////////////////////////////////////////////////////////////////////
9762
9764{
9766 return TClinginfo->Name();
9767}
9768
9769////////////////////////////////////////////////////////////////////////////////
9770
9772{
9774 return TClinginfo->Title();
9775}
9776
9777////////////////////////////////////////////////////////////////////////////////
9778
9779bool TCling::IsSameType(const void * QualTypePtr1, const void * QualTypePtr2) const
9780{
9781 clang::QualType QT1 = clang::QualType::getFromOpaquePtr(QualTypePtr1);
9782 clang::QualType QT2 = clang::QualType::getFromOpaquePtr(QualTypePtr2);
9783 return fInterpreter->getCI()->getASTContext().hasSameType(QT1, QT2);
9784}
9785
9786////////////////////////////////////////////////////////////////////////////////
9787
9788bool TCling::IsIntegerType(const void * QualTypePtr) const
9789{
9790 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9791 return QT->hasIntegerRepresentation();
9792}
9793
9794////////////////////////////////////////////////////////////////////////////////
9795
9796bool TCling::IsSignedIntegerType(const void * QualTypePtr) const
9797{
9798 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9799 return QT->hasSignedIntegerRepresentation();
9800}
9801
9802////////////////////////////////////////////////////////////////////////////////
9803
9804bool TCling::IsUnsignedIntegerType(const void * QualTypePtr) const
9805{
9806 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9807 return QT->hasUnsignedIntegerRepresentation();
9808}
9809
9810////////////////////////////////////////////////////////////////////////////////
9811
9812bool TCling::IsFloatingType(const void * QualTypePtr) const
9813{
9814 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9815 return QT->hasFloatingRepresentation();
9816}
9817
9818////////////////////////////////////////////////////////////////////////////////
9819
9820bool TCling::IsPointerType(const void * QualTypePtr) const
9821{
9822 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9823 return QT->hasPointerRepresentation();
9824}
9825
9826////////////////////////////////////////////////////////////////////////////////
9827
9828bool TCling::IsVoidPointerType(const void * QualTypePtr) const
9829{
9830 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9831 return QT->isVoidPointerType();
9832}
9833
9834////////////////////////////////////////////////////////////////////////////////
9835
9837{
9838 if (!fInitialMutex) {
9840 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
9841 }
9842 fInitialMutex.fState = mtx->GetStateBefore();
9843 }
9844 // We will "forget" this lock once we backed out of all interpreter frames.
9845 // Here we are entering one, so ++.
9847}
9848
9849////////////////////////////////////////////////////////////////////////////////
9850
9852{
9853 if (!fInitialMutex)
9854 return;
9855 if (fInitialMutex.fRecurseCount == 0) {
9856 Error("ForgetMutexState", "mutex state's recurse count already 0!");
9857 }
9858 else if (--fInitialMutex.fRecurseCount == 0) {
9859 // We have returned from all interpreter frames. Reset the initial lock state.
9860 fInitialMutex.fState.reset();
9861 }
9862}
9863
9864////////////////////////////////////////////////////////////////////////////////
9865/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
9866
9868{
9869 if (gInterpreterMutex) {
9870 if (delta) {
9871 auto typedDelta = static_cast<MutexStateAndRecurseCountDelta *>(delta);
9872 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP{typedDelta};
9873 gCoreMutex->Apply(std::move(typedDelta->fDelta));
9874 // Now that we have the lock, update the global
9875 R__ASSERT(fInitialMutex.fRecurseCount == 0 && "Inconsistent state of fInitialMutex! Another thread within Interpreter critical section.");
9876 std::swap(fInitialMutex, typedDelta->fInitialState);
9877 } else {
9878 // This case happens when EnableThreadSafety is first called from
9879 // the interpreter function we just handled.
9880 // Since thread safety was not enabled at the time we rewound, there was
9881 // no lock taken and even-though we should be locking the rest of this
9882 // interpreter handling/modifying code (since there might be threads in
9883 // flight), we can't because there would not be any lock guard to release the
9884 // locks
9886 Error("ApplyToInterpreterMutex",
9887 "After returning from user code that turned on thread safety support, we notice that fInitialMutex is already used ... "
9888 "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.");
9889 }
9890 }
9891}
9892
9893////////////////////////////////////////////////////////////////////////////////
9894/// Reset the interpreter lock to the state it had before interpreter-related
9895/// calls happened.
9896
9898{
9899 if (fInitialMutex) {
9900 // Need to start a new recurse count.
9901 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP(new MutexStateAndRecurseCountDelta());
9902 std::swap(uniqueP->fInitialState, fInitialMutex);
9903 uniqueP->fDelta = gCoreMutex->Rewind(*uniqueP->fInitialState.fState);
9904 return uniqueP.release();
9905 }
9907 return nullptr;
9908}
free(fBuffer)
#define R__EXTERN
Definition DllImport.h:26
The file contains utilities which are foundational and could be used across the core component of ROO...
#define d(i)
Definition RSha256.hxx:102
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define s1(x)
Definition RSha256.hxx:91
#define R(a, b, c, d, e, f, g, h, i)
Definition RSha256.hxx:110
#define e(i)
Definition RSha256.hxx:103
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:78
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
long Longptr_t
Integer large enough to hold a pointer (platform-dependent)
Definition RtypesCore.h:90
short Version_t
Class version identifier (short)
Definition RtypesCore.h:80
unsigned long ULong_t
Unsigned long integer 4 bytes (unsigned long). Size depends on architecture.
Definition RtypesCore.h:70
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:69
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:61
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
constexpr Ssiz_t kNPOS
The equivalent of std::string::npos for the ROOT class TString.
Definition RtypesCore.h:132
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:84
unsigned long long ULong64_t
Portable unsigned long integer 8 bytes.
Definition RtypesCore.h:85
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
const char Option_t
Option string (const char)
Definition RtypesCore.h:81
TClass *(* DictFuncPtr_t)()
Definition Rtypes.h:85
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:1343
static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
Definition TCling.cxx:7479
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
R__EXTERN int optind
Definition TCling.cxx:333
void * TCling__LockCompilationDuringUserCodeExecution()
Lock the interpreter.
Definition TCling.cxx:385
void TCling__UpdateListsOnUnloaded(const cling::Transaction &T)
Definition TCling.cxx:586
void TCling__GetNormalizedContext(const ROOT::TMetaUtils::TNormalizedCtxt *&normCtxt)
Definition TCling.cxx:574
int TCling__LoadLibrary(const char *library)
Load a library.
Definition TCling.cxx:349
void TCling__DEBUG__dump(clang::DeclContext *DC)
Definition TCling.cxx:226
bool TClingLookupHelper__CheckInClassTable(const std::string &tname, std::string &result)
Check if the class name is present in TClassTable.
Definition TCling.cxx:1020
ETupleOrdering
Check in what order the member of a tuple are layout.
Definition TCling.cxx:4056
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:2006
static Bool_t s_IsLibraryLoaded(const char *libname, cling::Interpreter *fInterpreter)
Definition TCling.cxx:3272
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:4098
static bool R__InitStreamerInfoFactory()
Helper to initialize TVirtualStreamerInfo's factor early.
Definition TCling.cxx:1729
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:4074
void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Definition TCling.cxx:605
static void TCling__UpdateClassInfo(const NamedDecl *TD)
Update TClingClassInfo for a class (e.g. upon seeing a definition).
Definition TCling.cxx:406
clang::DeclContext * TCling__DEBUG__getDeclContext(clang::Decl *D)
Definition TCling.cxx:217
int TCling__CompileMacro(const char *fileName, const char *options)
Definition TCling.cxx:661
#define R__DLLEXPORT
Definition TCling.cxx:153
void * TCling__ResetInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:377
void TCling__DEBUG__decl_dump(void *D)
Definition TCling.cxx:235
int TCling__AutoLoadCallback(const char *className)
Definition TCling.cxx:640
static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
Definition TCling.cxx:1065
static void RegisterCxxModules(cling::Interpreter &clingInterp)
Definition TCling.cxx:1218
static void ConstructorName(std::string &name, const clang::Decl *decl, cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition TCling.cxx:8976
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:2506
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:7388
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:2031
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:7223
const char * fantomline
Definition TCling.cxx:858
void TCling__LibraryLoadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:600
static cling::Interpreter::CompilationResult ExecAutoParse(const char *what, Bool_t header, cling::Interpreter *interpreter)
Parse the payload or header.
Definition TCling.cxx:6542
static bool requiresRootMap(const char *rootmapfile)
Definition TCling.cxx:5722
clang::NamespaceDecl * TCling__DEBUG__DCtoNamespace(clang::DeclContext *DC)
Definition TCling.cxx:220
TObject * TCling__GetObjectAddress(const char *Name, void *&LookupCtx)
Definition TCling.cxx:617
static void LoadModules(const std::vector< std::string > &modules, cling::Interpreter &interp)
Loads the C++ modules that we require to run any ROOT program.
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:7500
void TCling__SplitAclicMode(const char *fileName, string &mode, string &args, string &io, string &fname)
Definition TCling.cxx:668
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
EDataType
Definition TDataType.h:28
@ kULong64_t
Definition TDataType.h:32
@ kLong64_t
Definition TDataType.h:32
@ kIsDestructor
@ kIsConversion
@ kIsInlined
@ kIsConstructor
@ kIsOperator
@ kIsPublic
Definition TDictionary.h:75
@ kIsConstant
Definition TDictionary.h:88
@ kIsConstMethod
Definition TDictionary.h:96
@ kIsClass
Definition TDictionary.h:65
@ kIsEnum
Definition TDictionary.h:68
@ kIsPrivate
Definition TDictionary.h:77
@ kIsFundamental
Definition TDictionary.h:70
@ kIsCompiled
Definition TDictionary.h:86
@ kIsStatic
Definition TDictionary.h:80
@ kIsExplicit
Definition TDictionary.h:94
@ kIsStruct
Definition TDictionary.h:66
@ kIsProtected
Definition TDictionary.h:76
@ kIsVirtual
Definition TDictionary.h:72
@ kIsUnion
Definition TDictionary.h:67
@ kIsPureVirtual
Definition TDictionary.h:73
@ kIsNamespace
Definition TDictionary.h:95
@ kIsNotReacheable
Definition TDictionary.h:87
#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:130
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:241
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
Int_t gErrorIgnoreLevel
errors with level below this value will be ignored. Default is kUnset.
Definition TError.cxx:33
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
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
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:142
R__EXTERN TVirtualMutex * gInterpreterMutex
#define R__LOCKGUARD_CLING(mutex)
R__EXTERN TInterpreter * gCling
#define gInterpreter
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:792
#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_iterator begin() const
const_iterator end() const
void AddTemplAndNargsToKeep(const clang::ClassTemplateDecl *templ, unsigned int i)
const Config_t & GetConfig() const
virtual std::unique_ptr< StateDelta > Rewind(const State &earlierState)=0
virtual void Apply(std::unique_ptr< StateDelta > &&delta)=0
static Longptr_t ExecuteFile(const char *file, Int_t *error=nullptr, Bool_t keep=kFALSE)
Execute a file containing a C++ macro (static method).
virtual TApplicationImp * GetApplicationImp()
virtual Bool_t IsCmdThread()
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 DictFuncPtr_t GetDict(const char *cname)
Given the class name returns the Dictionary() function of a class (uses hash of name).
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:3506
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition TClass.cxx:2912
void RemoveStreamerInfo(Int_t slot)
Remove and delete the StreamerInfo in the given slot.
Definition TClass.cxx:7540
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:3861
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:5036
static void RemoveClassDeclId(TDictionary::DeclId_t id)
Definition TClass.cxx:605
static Bool_t HasNoInfoOrEmuOrFwdDeclaredDecl(const char *)
Definition TClass.cxx:3465
@ kLoading
Definition TClass.h:342
@ kUnloading
Definition TClass.h:342
static TClass * LoadClass(const char *requestedname, Bool_t silent)
Helper function used by TClass::GetClass().
Definition TClass.cxx:5914
Int_t Size() const
Return size of object of this class.
Definition TClass.cxx:5869
TObjArray * fStreamerInfo
Definition TClass.h:201
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:2923
void ResetCaches()
To clean out all caches.
Definition TClass.cxx:4278
static Int_t ReadRules()
Read the class.rules files from the default location:.
Definition TClass.cxx:1813
@ 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
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:3530
@ 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:2999
Emulation of the CINT BaseClassInfo class.
const char * Name() const
Emulation of the CINT CallFunc class.
void SetArgs(const char *args)
void SetFunc(const TClingClassInfo *info, const char *method, const char *arglist, Longptr_t *poffset)
void ExecWithArgsAndReturn(void *address, const void *args[]=0, int nargs=0, void *ret=0)
void Exec(void *address, TInterpreterValue *interpVal=0)
TClingMethodInfo * FactoryMethod() const
bool IsAutoLoadingForJITSymbols() const
bool IsAutoLoadingEnabled() const
void SetAutoParsingSuspended(bool val=true)
void SetAutoLoadingForJITSymbols(bool val=true)
void SetAutoLoadingEnabled(bool val=true)
Emulation of the CINT ClassInfo class.
static bool IsEnum(cling::Interpreter *interp, const char *name)
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) 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
TClingMethodInfo GetMethod(const char *fname) const
const clang::ValueDecl * GetDataMember(const char *name) const
Emulation of the CINT DataMemberInfo class.
virtual const char * Name() const
virtual bool IsValid() 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
Emulation of the CINT MethodInfo class.
TDictionary::DeclId_t GetDeclId() const
Emulation of the CINT TypeInfo class.
Emulation of the CINT TypedefInfo class.
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::string fContent
Definition TCling.h:631
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:6414
const char * MethodArgInfo_DefaultValue(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9537
bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const final
Definition TCling.cxx:8539
const char * TypeInfo_Name(TypeInfo_t *) const final
Definition TCling.cxx:9629
void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const final
Definition TCling.cxx:9291
void LoadEnums(TListOfEnums &cl) const final
Create list of pointers to enums for TClass cl.
Definition TCling.cxx:4605
void UpdateListOfGlobals() final
No op: see TClingCallbacks (used to update the list of globals)
Definition TCling.cxx:4036
bool TypedefInfo_IsValid(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9723
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE) final
Load library containing the specified class.
Definition TCling.cxx:6475
void CallFunc_Init(CallFunc_t *func) const final
Definition TCling.cxx:8169
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:3799
bool LibraryLoadingFailed(const std::string &, const std::string &, bool, bool)
Definition TCling.cxx:6784
void GenericError(const char *error) const final
Let the interpreter issue a generic error, and set its error state.
Definition TCling.cxx:7684
std::vector< void * > fRegisterModuleDyLibs
Definition TCling.h:140
void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const final
Definition TCling.cxx:8095
bool IsIntegerType(const void *QualTypePtr) const final
Definition TCling.cxx:9788
TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const final
Definition TCling.cxx:9350
std::vector< std::string > fAutoLoadLibStorage
Definition TCling.h:118
void CallFunc_Delete(CallFunc_t *func) const final
Definition TCling.cxx:8072
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:7727
void ResetAll() final
Reset the Cling state to its initial state.
Definition TCling.cxx:3875
void SetDeclAttr(DeclId_t, const char *) final
Definition TCling.cxx:8962
void HandleNewDecl(const void *DV, bool isDeserialized, std::set< TClass * > &modifiedClasses)
Definition TCling.cxx:513
void InvalidateCachedDecl(const std::tuple< TListOfDataMembers *, TListOfFunctions *, TListOfFunctionTemplates *, TListOfEnums * > &Lists, const clang::Decl *D)
Invalidate cached TCling information for the given declaration, and removed it from the appropriate o...
Definition TCling.cxx:7119
Long_t MethodInfo_Property(MethodInfo_t *minfo) const final
Definition TCling.cxx:9332
void LoadFunctionTemplates(TClass *cl) const final
Create list of pointers to function templates for TClass cl.
Definition TCling.cxx:4652
bool ClassInfo_IsValidMethod(ClassInfo_t *info, const char *method, const char *proto, Longptr_t *offset, ROOT::EFunctionMatchMode=ROOT::kConversionMatch) const final
Definition TCling.cxx:8573
Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8895
int SetClassAutoparsing(int) final
Enable/Disable the Autoparsing of headers.
Definition TCling.cxx:7812
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:4699
void RewindDictionary() final
Rewind Cling dictionary to the point where it was before executing the current macro.
Definition TCling.cxx:3920
bool ClassInfo_IsValid(ClassInfo_t *info) const final
Definition TCling.cxx:8565
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition TCling.cxx:6993
int TypeInfo_RefType(TypeInfo_t *) const final
Definition TCling.cxx:9645
void CreateListOfBaseClasses(TClass *cl) const final
Create list of pointers to base class(es) for TClass cl.
Definition TCling.cxx:4576
ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const final
Definition TCling.cxx:8452
const char * MethodInfo_Name(MethodInfo_t *minfo) const final
Definition TCling.cxx:9379
BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const final
Definition TCling.cxx:8709
Bool_t LoadText(const char *text) const final
Load the declarations from text into the interpreter.
Definition TCling.cxx:7742
const char * GetSharedLibDeps(const char *lib, bool tryDyld=false) final
Get the list a libraries on which the specified lib depends.
Definition TCling.cxx:7516
EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const final
Definition TCling.cxx:9429
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition TCling.cxx:7943
Longptr_t ProcessLineAsynch(const char *line, EErrorCode *error=nullptr)
Let cling process a command line asynch.
Definition TCling.cxx:3711
bool MethodInfo_IsValid(MethodInfo_t *minfo) const final
Definition TCling.cxx:9300
FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:9052
TypeInfo_t * TypeInfo_Factory() const final
Definition TCling.cxx:9589
bool IsClassAutoLoadingEnabled() const
Returns if class AutoLoading is currently enabled.
Definition TCling.cxx:7781
void InvalidateGlobal(const clang::Decl *D)
Invalidate cached TCling information for the given global declaration.
Definition TCling.cxx:7104
bool IsSameType(const void *QualTypePtr1, const void *QualTypePtr2) const final
Definition TCling.cxx:9779
int Evaluate(const char *, TInterpreterValue &) final
Get the interpreter value corresponding to the statement.
Definition TCling.cxx:7905
std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const final
Definition TCling.cxx:7890
void UpdateListOfLoadedSharedLibraries()
Definition TCling.cxx:3491
const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9771
~TCling() final
Destroy the interpreter interface.
Definition TCling.cxx:1681
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:8294
void InitRootmapFile(const char *name)
Create a resource table and read the (possibly) three resource files, i.e.
Definition TCling.cxx:5865
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:6739
void LoadPCM(std::string pcmFileNameFullPath)
Tries to load a rdict PCM, issues diagnostics if it fails.
Definition TCling.cxx:1878
void UpdateListOfMethods(TClass *cl) const final
Update the list of pointers to method for TClass cl This is now a nop.
Definition TCling.cxx:4717
void AddFriendToClass(clang::FunctionDecl *, clang::CXXRecordDecl *) const
Inject function as a friend into klass.
Definition TCling.cxx:7996
void PrintIntro() final
No-op; see TRint instead.
Definition TCling.cxx:2731
Bool_t fCxxModulesEnabled
Definition TCling.h:130
int BaseClassInfo_Next(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8729
void RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
Internal function. Actually do the update of the ClassInfo when seeing.
Definition TCling.cxx:6851
CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const final
Definition TCling.cxx:8146
Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const final
Definition TCling.cxx:8130
std::set< std::string > fAutoLoadedLibraries
Definition TCling.h:125
void CallFunc_ResetArg(CallFunc_t *func) const final
Definition TCling.cxx:8195
const char * GetCurrentMacroName() const final
Return the file name of the currently interpreted file, included or not.
Definition TCling.cxx:5673
Bool_t IsLoaded(const char *filename) const final
Return true if the file has already been loaded by cint.
Definition TCling.cxx:3315
void SaveGlobalsContext() final
Save the current Cling state of global objects.
Definition TCling.cxx:4023
void CallFunc_IgnoreExtraArgs(CallFunc_t *func, bool ignore) const final
Definition TCling.cxx:8161
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:9867
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition TCling.cxx:6807
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:4933
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:8368
Bool_t IsLibraryLoaded(const char *libname) const final
Definition TCling.cxx:3281
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:7706
int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8821
DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8855
Bool_t HandleNewTransaction(const cling::Transaction &T)
Helper function to increase the internal Cling count of transactions that change the AST.
Definition TCling.cxx:3816
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:5738
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition TCling.h:155
int ClassInfo_Next(ClassInfo_t *info) const final
Definition TCling.cxx:8589
void SetErrmsgcallback(void *p) const final
Set a callback to receive error messages.
Definition TCling.cxx:7833
bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9513
int TypeInfo_Size(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9653
Int_t DeleteGlobal(void *obj) final
Delete obj from Cling symbol table so it cannot be accessed anymore.
Definition TCling.cxx:3934
int GetSecurityError() const final
Interface to cling function.
Definition TCling.cxx:7714
void SetTempLevel(int val) const final
Create / close a scope for temporaries.
Definition TCling.cxx:7869
void Print(Option_t *option="") const final
Print information about the interpreter.
Definition TCling.cxx:2741
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:9086
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:5365
TypedefInfo_t * TypedefInfo_Factory() const final
Definition TCling.cxx:9690
TObjArray * fRootmapFiles
Definition TCling.h:128
Longptr_t ProcessLine(const char *line, EErrorCode *error=nullptr) final
Definition TCling.cxx:2536
int ClassInfo_Size(ClassInfo_t *info) const final
Definition TCling.cxx:8637
const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9553
cling::Interpreter * GetInterpreterImpl() const
Definition TCling.h:656
Longptr_t ExecuteMacro(const char *filename, EErrorCode *error=nullptr) final
Execute a cling macro.
Definition TCling.cxx:5613
std::vector< std::pair< TClass *, DictFuncPtr_t > > fClassesToUpdate
Definition TCling.h:148
int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8879
const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9763
void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8702
Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const final
Definition TCling.cxx:9341
void LoadMacro(const char *filename, EErrorCode *error=nullptr) final
Load a macro file in cling's memory.
Definition TCling.cxx:3703
FuncTempInfo_t * FuncTempInfo_FactoryCopy(FuncTempInfo_t *) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:9063
int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const final
Definition TCling.cxx:8871
Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const final
Check validity of a FuncTempInfo_t.
Definition TCling.cxx:9074
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:2773
bool ClassInfo_IsBase(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8524
void RecursiveRemove(TObject *obj) final
Delete object from cling symbol table so it can not be used anymore.
Definition TCling.cxx:3834
const char * DataMemberInfo_TypeName(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8919
DeclId_t GetDataMemberAtAddr(const void *addr) const final
Return pointer to cling DeclId for a data member with a given name.
Definition TCling.cxx:5160
void CallFunc_SetArgArray(CallFunc_t *func, Longptr_t *paramArr, Int_t nparam) const final
Definition TCling.cxx:8251
std::string CallFunc_GetWrapperCode(CallFunc_t *func) const final
Definition TCling.cxx:8341
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:9897
const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9545
Bool_t HasPCMForLibrary(const char *libname) const final
Return true if ROOT has cxxmodules pcm for a given library name.
Definition TCling.cxx:3290
void TypedefInfo_Init(TypedefInfo_t *tinfo, const char *name) const final
Definition TCling.cxx:9713
const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8943
Longptr_t CallFunc_ExecInt(CallFunc_t *func, void *address) const final
Definition TCling.cxx:8114
void ClearStack() final
Delete existing temporary values.
Definition TCling.cxx:3198
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:7763
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:7583
MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const final
Definition TCling.cxx:8153
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:3557
TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9706
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:5258
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:2476
std::string MethodArgInfo_TypeNormalizedName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9561
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:5042
Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9529
int TypedefInfo_Size(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9747
void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:8103
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:5410
Int_t fGlobalsListSerial
Definition TCling.h:114
TString fSharedLibs
Definition TCling.h:113
std::map< std::string, llvm::StringRef > fPendingRdicts
Definition TCling.h:646
static void UpdateClassInfoWork(const char *name)
Definition TCling.cxx:6973
Int_t Load(const char *filenam, Bool_t system=kFALSE) final
Load a library file in cling's memory.
Definition TCling.cxx:3666
int TypedefInfo_Next(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9731
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:5217
void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const final
Definition TCling.cxx:9612
Bool_t SetSuspendAutoParsing(Bool_t value) final
Suspend the Autoparsing of headers.
Definition TCling.cxx:7823
int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8911
static void * fgSetOfSpecials
Definition TCling.h:105
const char * ClassInfo_Title(ClassInfo_t *info) const final
Definition TCling.cxx:8679
const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8935
const char * TypeName(const char *typeDesc) final
Return the absolute type of typeDesc.
Definition TCling.cxx:5688
ROOT::TMetaUtils::TNormalizedCtxt * fNormalizedCtxt
Definition TCling.h:136
void ForgetMutexState() final
Definition TCling.cxx:9851
int MethodInfo_Next(MethodInfo_t *minfo) const final
Definition TCling.cxx:9324
Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const final
Definition TCling.cxx:8413
void MethodInfo_Delete(MethodInfo_t *minfo) const final
Interface to cling function.
Definition TCling.cxx:9243
bool fIsShuttingDown
Definition TCling.h:189
void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9482
bool IsSignedIntegerType(const void *QualTypePtr) const final
Definition TCling.cxx:9796
DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo, TDictionary::EMemberSelection selection) const final
Definition TCling.cxx:8836
void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const final
Definition TCling.cxx:8444
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:6320
Int_t UnloadAllSharedLibraryMaps() final
Unload the library map entries coming from all the loaded shared libraries.
Definition TCling.cxx:6208
void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const final
Definition TCling.cxx:8506
std::set< TClass * > & GetModTClasses()
Definition TCling.h:591
ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const final
Definition TCling.cxx:8774
ECheckClassInfo CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly=kFALSE, ClassInfo_t **classInfo=nullptr) final
Checks if an entity with the specified name is defined in Cling.
Definition TCling.cxx:4365
TClingCallbacks * fClingCallbacks
Definition TCling.h:141
Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const final
Definition TCling.cxx:8122
Long_t ClassInfo_Property(ClassInfo_t *info) const final
Definition TCling.cxx:8629
Longptr_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8753
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:5595
Bool_t IsErrorMessagesEnabled() const final
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition TCling.cxx:7569
TString fIncludePath
Definition TCling.h:115
int DisplayIncludePath(FILE *fout) const final
Interface to cling function.
Definition TCling.cxx:7646
void TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:7178
Long_t FuncTempInfo_Property(FuncTempInfo_t *) const final
Return the property of the function template.
Definition TCling.cxx:9107
TEnum * CreateEnum(void *VD, TClass *cl) const final
Definition TCling.cxx:486
const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9661
Int_t UnloadLibraryMap(const char *library) final
Unload library map entries coming from the specified library.
Definition TCling.cxx:6226
void RegisterTemporary(const TInterpreterValue &value)
Definition TCling.cxx:7916
MutexStateAndRecurseCount fInitialMutex
Definition TCling.h:176
const char * GetSharedLibs() final
Return the list of shared libraries loaded into the process.
Definition TCling.cxx:7216
int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9521
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx) final
Definition TCling.cxx:9836
Long_t TypeInfo_Property(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9637
const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const final
Definition TCling.cxx:9370
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:9097
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:2078
static Int_t ShallowAutoLoadImpl(const char *cls)
Definition TCling.cxx:6366
void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const final
Definition TCling.cxx:9250
Bool_t CheckClassTemplate(const char *name) final
Return true if there is a class template by the given name ...
Definition TCling.cxx:4554
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:7201
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:2467
bool IsVoidPointerType(const void *QualTypePtr) const final
Definition TCling.cxx:9828
TObjArray * GetRootMapFiles() const final
Definition TCling.h:226
bool DataMemberInfo_IsValid(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8863
bool ClassInfo_IsEnum(const char *name) const final
Definition TCling.cxx:8532
int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9316
bool IsFloatingType(const void *QualTypePtr) const final
Definition TCling.cxx:9812
void CreateListOfMethods(TClass *cl) const final
Create list of pointers to methods for TClass cl.
Definition TCling.cxx:4708
Int_t RescanLibraryMap() final
Scan again along the dynamic path for library maps.
Definition TCling.cxx:6135
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:7842
const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9359
TypeInfo_t * MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9569
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:603
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:5320
void * ClassInfo_New(ClassInfo_t *info) const final
Definition TCling.cxx:8597
int DisplayClass(FILE *fout, const char *name, int base, int start) const final
Definition TCling.cxx:7637
void GetFunctionName(const clang::Decl *decl, std::string &name) const
Definition TCling.cxx:8998
void CreateListOfMethodArgs(TFunction *m) const final
Create list of pointers to method arguments for TMethod m.
Definition TCling.cxx:4733
const char * GetSTLIncludePath() const final
Return the directory containing CINT's stl cintdlls.
Definition TCling.cxx:7628
MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9505
Longptr_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8745
void * FindSym(const char *entry) const final
Interface to cling function.
Definition TCling.cxx:7675
void RegisterLoadedSharedLibrary(const char *name)
Register a new shared library name with the interpreter; add it to fSharedLibs.
Definition TCling.cxx:3566
void TypeInfo_Delete(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9582
int MethodInfo_NArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9308
DeclId_t GetDataMemberWithValue(const void *ptrvalue) const final
NOT IMPLEMENTED.
Definition TCling.cxx:5151
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition TCling.h:127
EReturnType MethodCallReturnType(TFunction *func) const final
Definition TCling.cxx:9418
void ProcessClassesToUpdate()
Definition TCling.cxx:2047
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:5343
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:5172
const char * MethodInfo_Title(MethodInfo_t *minfo) const final
Definition TCling.cxx:9409
TString fRootmapLoadPath
Definition TCling.h:116
void SetClassInfo(TClass *cl, Bool_t reload=kFALSE, Bool_t silent=kFALSE, ClassInfo_t *classInfo=nullptr) final
Set pointer to the TClingClassInfo in TClass.
Definition TCling.cxx:4212
const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8808
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:3235
const char * BaseClassInfo_FullName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8790
void CallFunc_SetArgs(CallFunc_t *func, const char *param) const final
Definition TCling.cxx:8259
int UnloadFile(const char *path) const final
Definition TCling.cxx:7875
void CallFunc_Exec(CallFunc_t *func, void *address) const final
Definition TCling.cxx:8079
Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const final
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition TCling.cxx:9172
bool CallFunc_IsValid(CallFunc_t *func) const final
Definition TCling.cxx:8178
const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8800
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition TCling.h:137
const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8951
Int_t GetMore() const final
Return whether we are waiting for more input either because the collected input contains unbalanced b...
Definition TCling.cxx:4754
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:5082
void Execute(const char *function, const char *params, int *error=nullptr) final
Execute a global function with arguments params.
Definition TCling.cxx:5443
bool ClassInfo_IsLoaded(ClassInfo_t *info) const final
Definition TCling.cxx:8557
Longptr_t ClassInfo_Tagnum(ClassInfo_t *info) const final
Definition TCling.cxx:8645
Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8766
void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Longptr_t *Offset) const final
Definition TCling.cxx:8267
std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const final
Get the scopes representing using declarations of namespace.
Definition TCling.cxx:4688
const char * ClassInfo_FileName(ClassInfo_t *info) const final
Definition TCling.cxx:8653
void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const final
Return the comments associates with this function template.
Definition TCling.cxx:9211
const char * ClassInfo_TmpltName(ClassInfo_t *info) const final
Definition TCling.cxx:8687
void SaveContext() final
Save the current Cling state.
Definition TCling.cxx:4010
void LoadPCMImpl(TFile &pcmFile)
Tries to load a PCM from TFile; returns true on success.
Definition TCling.cxx:1762
Bool_t IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:6843
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:3891
void CodeComplete(const std::string &, size_t &, std::vector< std::string > &) final
The call to Cling's tab complition.
Definition TCling.cxx:7897
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:3905
const char * MapCppName(const char *) const final
Interface to cling function.
Definition TCling.cxx:7750
Longptr_t Calc(const char *line, EErrorCode *error=nullptr) final
Directly execute an executable statement (e.g.
Definition TCling.cxx:3736
Int_t ReloadAllSharedLibraryMaps() final
Reload the library map entries coming from all the loaded shared libraries, after first unloading the...
Definition TCling.cxx:6147
void UpdateListOfGlobalFunctions() final
No op: see TClingCallbacks (used to update the list of global functions)
Definition TCling.cxx:4043
void DataMemberInfo_Delete(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8829
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:5626
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:4726
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:2795
Int_t SetClassSharedLibs(const char *cls, const char *libs) final
Register the AutoLoading information for a class.
Definition TCling.cxx:6288
MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const final
Definition TCling.cxx:9284
std::set< const char * > fParsedPayloadsAddresses
Definition TCling.h:123
CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const final
Definition TCling.cxx:8187
MethodArgInfo_t * MethodArgInfo_Factory() const final
Definition TCling.cxx:9489
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition TCling.cxx:6967
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:5239
void ClassInfo_Delete(ClassInfo_t *info) const final
Definition TCling.cxx:8421
std::unique_ptr< cling::Interpreter > fInterpreter
Definition TCling.h:132
EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const final
Definition TCling.cxx:8548
void FuncTempInfo_Delete(FuncTempInfo_t *) const final
Delete the FuncTempInfo_t.
Definition TCling.cxx:9043
bool IsUnsignedIntegerType(const void *QualTypePtr) const final
Definition TCling.cxx:9804
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:5387
Int_t DeleteVariable(const char *name) final
Undeclare obj called name.
Definition TCling.cxx:3949
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:7322
Longptr_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8887
CallFunc_t * CallFunc_Factory() const final
Definition TCling.cxx:8138
MethodInfo_t * MethodInfo_Factory() const final
Definition TCling.cxx:9259
Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8903
void ClearFileBusy() final
Reset the interpreter internal state in case a previous action was not correctly terminated.
Definition TCling.cxx:3190
cling::MetaProcessor * GetMetaProcessorImpl() const
Definition TCling.h:657
bool DiagnoseIfInterpreterException(const std::exception &e) const final
Definition TCling.cxx:2525
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:7773
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:3181
void AddAvailableIndentifiers(TSeqCollection &Idents) final
Definition TCling.cxx:2441
void TypedefInfo_Delete(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9683
void Reset() final
Pressing Ctrl+C should forward here.
Definition TCling.cxx:3859
const char * TypedefInfo_TrueName(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9755
int SetClassAutoLoading(int) const final
Enable/Disable the AutoLoading of libraries.
Definition TCling.cxx:7794
const char * ClassInfo_FullName(ClassInfo_t *info) const final
Definition TCling.cxx:8661
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:6591
const char * MethodInfo_TypeName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9388
void CallFunc_SetArg(CallFunc_t *func, Long_t param) const final
Definition TCling.cxx:8203
const char * GetIncludePath() final
Refresh the list of include paths known to the interpreter and return it with -I prepended.
Definition TCling.cxx:7597
void UpdateListsOnUnloaded(const cling::Transaction &T)
Invalidate stored TCling state for declarations included in transaction ‘T’.
Definition TCling.cxx:7077
void UpdateClassInfoWithDecl(const clang::NamedDecl *ND)
Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
Definition TCling.cxx:6909
void Initialize() final
Initialize the interpreter, once TROOT::fInterpreter is set.
Definition TCling.cxx:1699
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:8482
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:4981
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:9198
std::unique_ptr< cling::MetaProcessor > fMetaProcessor
Definition TCling.h:133
bool TypeInfo_IsValid(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9621
bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const final
Definition TCling.cxx:1973
std::string MethodInfo_TypeNormalizedName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9397
const char * ClassInfo_Name(ClassInfo_t *info) const final
Definition TCling.cxx:8671
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE) final
Generate a TClass for the given class.
Definition TCling.cxx:4764
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:8490
void EndOfLineAction() final
It calls a "fantom" method to synchronize user keyboard input and ROOT prompt line.
Definition TCling.cxx:3264
TypeInfo_t * TypeInfo_FactoryCopy(TypeInfo_t *) const final
Definition TCling.cxx:9605
size_t ClassInfo_AlignOf(ClassInfo_t *info) const final
Definition TCling.cxx:8357
bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8498
void ClassInfo_DeleteArray(ClassInfo_t *info, void *arena, bool dtorOnly) const final
Definition TCling.cxx:8436
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:8927
void ShutDown() final
Definition TCling.cxx:1720
void UpdateListOfTypes() final
No op: see TClingCallbacks (used to update the list of types)
Definition TCling.cxx:4050
void * TypeInfo_QualTypePtr(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9669
Long_t TypedefInfo_Property(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9739
void RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Register Rdict data for future loading by LoadPCM;.
Definition TCling.cxx:1743
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:3720
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:5199
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition TCling.cxx:6982
Int_t LoadLibraryMap(const char *rootmapfile=nullptr) final
Load map between class and library.
Definition TCling.cxx:5951
Longptr_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8782
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:7208
bool IsPointerType(const void *QualTypePtr) const final
Definition TCling.cxx:9820
Collection abstract base class.
Definition TCollection.h:65
virtual Int_t GetEntries() const
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
All ROOT classes may have RTTI (run time type identification) support added.
Definition TDataMember.h:31
Basic data type descriptor (datatype information is obtained from CINT).
Definition TDataType.h:44
EMemberSelection
Kinds of members to include in lists.
const void * DeclId_t
TDirectory::TContext keeps track and restore the current directory.
Definition TDirectory.h:89
The TEnumConstant class implements the constants of the enum type.
The TEnum class implements the enum type.
Definition TEnum.h:33
static TEnum * GetEnum(const std::type_info &ti, ESearchAction sa=kALoadAndInterpLookup)
Definition TEnum.cxx:181
@ kNone
Definition TEnum.h:55
@ kAutoload
Definition TEnum.h:59
Definition TEnv.h:41
The TEnv class reads config files, by default named .rootrc.
Definition TEnv.h:79
THashList * GetTable() const
Definition TEnv.h:96
Bool_t IgnoreDuplicates(Bool_t ignore)
If set to true, no warnings in case of duplicates are issued.
Definition TEnv.cxx:809
virtual void SetRcName(const char *name)
Definition TEnv.h:101
virtual Int_t ReadFile(const char *fname, EEnvLevel level)
Read and parse the resource file for a certain level.
Definition TEnv.cxx:612
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=nullptr)
Set the value of a resource or create a new resource.
Definition TEnv.cxx:752
virtual TEnvRec * Lookup(const char *n) const
Loop over all resource records and return the one with name.
Definition TEnv.cxx:567
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
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
TObject * Remove(TObject *obj) override
Remove object 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.
virtual bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const =0
virtual Bool_t HasPCMForLibrary(const char *libname) const =0
virtual Int_t AutoParse(const char *cls)=0
int(* AutoLoadCallBack_t)(const char *)
virtual void RegisterAutoLoadedLibrary(const char *libname)=0
virtual Bool_t Declare(const char *code)=0
virtual const char * GetClassSharedLibs(const char *cls, bool skipCore=true)=0
std::vector< std::pair< std::string, int > > FwdDeclArgsToKeepCollection_t
TDictionary::DeclId_t DeclId_t
virtual TObjArray * GetRootMapFiles() const =0
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...
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...
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
A doubly linked list.
Definition TList.h:38
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.
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
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
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
virtual void Expand(Int_t newSize)
Expand or shrink the array to newSize elements.
virtual void Compress()
Remove empty slots from array.
Int_t GetEntries() const override
Return the number of objects in array (i.e.
TObject * Remove(TObject *obj) override
Remove object from array.
TObject * FindObject(const char *name) const override
Find an object in this collection using its name.
void Add(TObject *obj) override
Definition TObjArray.h:68
Collectable string class.
Definition TObjString.h:28
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:1081
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:423
static TClass * Class()
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1095
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1123
virtual TClass * IsA() const
Definition TObject.h:248
void MakeZombie()
Definition TObject.h:55
@ 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:1069
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:3362
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition TROOT.cxx:2932
static const std::vector< std::string > & AddExtraInterpreterArgs(const std::vector< std::string > &args)
Provide command line arguments to the interpreter construction.
Definition TROOT.cxx:3128
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition TROOT.cxx:3396
static const char **& GetExtraInterpreterArgs()
INTERNAL function! Used by rootcling to inject interpreter arguments through a C-interface layer.
Definition TROOT.cxx:3138
static const TString & GetSharedLibDir()
Get the shared libraries directory in the installation.
Definition TROOT.cxx:3223
Sequenceable collection abstract base class.
Int_t LastIndex() const
Describes a persistent version of a class.
Basic string class.
Definition TString.h:137
Ssiz_t Length() const
Definition TString.h:426
void Clear()
Clear string without changing its capacity.
Definition TString.cxx:1241
const char * Data() const
Definition TString.h:385
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:714
Bool_t IsNull() const
Definition TString.h:423
TString & Append(const char *cs)
Definition TString.h:582
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:642
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1289
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition TSystem.cxx:859
virtual void * OpenDirectory(const char *name)
Open a directory.
Definition TSystem.cxx:850
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1680
virtual const char * GetIncludePath()
Get the list of include path.
Definition TSystem.cxx:4057
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition TSystem.cxx:4344
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1553
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition TSystem.cxx:1872
int GetPathInfo(const char *path, Long_t *id, Long_t *size, Long_t *flags, Long_t *modtime)
Get info about a file: id, size, flags, modification time.
Definition TSystem.cxx:1413
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition TSystem.cxx:1096
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition TSystem.cxx:1311
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition TSystem.cxx:867
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition TSystem.cxx:2509
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:948
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition TSystem.cxx:1810
virtual const char * FindDynamicLibrary(TString &lib, Bool_t quiet=kFALSE)
Find a dynamic library using the system search paths.
Definition TSystem.cxx:2049
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition TSystem.cxx:439
virtual int CompileMacro(const char *filename, Option_t *opt="", const char *library_name="", const char *build_dir="", UInt_t dirmode=0)
This method compiles and loads a shared library containing the code from the file "filename".
Definition TSystem.cxx:2895
virtual const char * WorkingDirectory()
Return working directory.
Definition TSystem.cxx:885
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1563
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition TSystem.cxx:1664
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition TSystem.cxx:901
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1046
virtual void StackTrace()
Print a stack trace.
Definition TSystem.cxx:747
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
Definition TSystem.cxx:2035
virtual Int_t UnLock()=0
virtual Int_t Lock()=0
virtual TVirtualMutex * Factory(Bool_t=kFALSE)=0
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
const std::string & GetPathSeparator()
const char & GetEnvPathSeparator()
bool ConvertEnvValueToBool(const std::string &value)
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.
R__EXTERN TVirtualRWMutex * gCoreMutex
@ kWarning
Warnings about likely unexpected behavior.
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 *)
static const char * what
Definition stlLoader.cc:5
RAII used to store Parser, Sema, Preprocessor state for recursive parsing.
Definition ClingRAII.h:22
std::unique_ptr< ROOT::TVirtualRWMutex::State > fState
State of gCoreMutex when the first interpreter-related function was invoked.
Definition TCling.h:159
Int_t fRecurseCount
Interpreter-related functions will push the "entry" lock state to *this.
Definition TCling.h:164
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