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#define ROOT_compiledata_cxx
65#include "compiledata.h"
66#include "strlcpy.h"
67#include "TClingUtils.h"
70#include "TListOfDataMembers.h"
71#include "TListOfEnums.h"
73#include "TListOfFunctions.h"
75#include "TMemFile.h"
76#include "TProtoClass.h"
77#include "TStreamerInfo.h" // This is here to avoid to use the plugin manager
78#include "ThreadLocalStorage.h"
79#include "TFile.h"
80#include "TKey.h"
81#include "ClingRAII.h"
82
83#include "clang/AST/ASTContext.h"
84#include "clang/AST/Decl.h"
85#include "clang/AST/DeclarationName.h"
86#include "clang/AST/GlobalDecl.h"
87#include "clang/AST/RecordLayout.h"
88#include "clang/AST/DeclVisitor.h"
89#include "clang/AST/RecursiveASTVisitor.h"
90#include "clang/AST/Type.h"
91#include "clang/Basic/SourceLocation.h"
92#include "clang/Basic/Specifiers.h"
93#include "clang/Basic/TargetInfo.h"
94#include "clang/CodeGen/ModuleBuilder.h"
95#include "clang/Frontend/CompilerInstance.h"
96#include "clang/Frontend/FrontendDiagnostic.h"
97#include "clang/Lex/HeaderSearch.h"
98#include "clang/Lex/Preprocessor.h"
99#include "clang/Lex/PreprocessorOptions.h"
100#include "clang/Parse/Parser.h"
101#include "clang/Sema/Lookup.h"
102#include "clang/Sema/Sema.h"
103#include "clang/Serialization/ASTReader.h"
104#include "clang/Serialization/GlobalModuleIndex.h"
105
106#include "cling/Interpreter/ClangInternalState.h"
107#include "cling/Interpreter/DynamicLibraryManager.h"
108#include "cling/Interpreter/Interpreter.h"
109#include "cling/Interpreter/LookupHelper.h"
110#include "cling/Interpreter/Value.h"
111#include "cling/Interpreter/Transaction.h"
112#include "cling/MetaProcessor/MetaProcessor.h"
113#include "cling/Utils/AST.h"
114#include "cling/Utils/ParserStateRAII.h"
115#include "cling/Utils/SourceNormalization.h"
116#include "cling/Interpreter/Exception.h"
117
118#include <CppInterOp/CppInterOp.h>
119
120#include "llvm/IR/GlobalValue.h"
121#include "llvm/IR/Module.h"
122
123#include "llvm/Support/DynamicLibrary.h"
124#include "llvm/Support/raw_ostream.h"
125#include "llvm/Support/Path.h"
126#include "llvm/Support/Process.h"
127#include "llvm/Object/ELFObjectFile.h"
128#include "llvm/Object/ObjectFile.h"
129#include "llvm/Object/SymbolicFile.h"
130#include "llvm/Support/FileSystem.h"
131
132#include <algorithm>
133#include <iostream>
134#include <cassert>
135#include <map>
136#include <set>
137#include <stdexcept>
138#include <cstdint>
139#include <cstdio>
140#include <fstream>
141#include <sstream>
142#include <string>
143#include <tuple>
144#include <typeinfo>
145#include <unordered_map>
146#include <unordered_set>
147#include <utility>
148#include <vector>
149#include <functional>
150#include <optional>
151
152#ifndef R__WIN32
153#include <cxxabi.h>
154#define R__DLLEXPORT __attribute__ ((visibility ("default")))
155#include <sys/stat.h>
156#endif
157#include <climits>
158#include <cstdio>
159
160#ifdef __APPLE__
161#include <dlfcn.h>
162#include <mach-o/dyld.h>
163#include <mach-o/loader.h>
164#endif // __APPLE__
165
166#ifdef R__UNIX
167#include <dlfcn.h>
168#endif
169
170#if defined(R__LINUX) || defined(R__FBSD)
171# ifndef _GNU_SOURCE
172# define _GNU_SOURCE
173# endif
174# include <link.h> // dl_iterate_phdr()
175#endif
176
177#if defined(__CYGWIN__)
178#include <sys/cygwin.h>
179#define HMODULE void *
180extern "C" {
182 __declspec(dllimport) bool __stdcall EnumProcessModules(void *, void **, unsigned long, unsigned long *);
183 __declspec(dllimport) unsigned long __stdcall GetModuleFileNameExW(void *, void *, wchar_t *, unsigned long);
184}
185#endif
186
187// Fragment copied from LLVM's raw_ostream.cpp
188#if defined(_MSC_VER)
189#ifndef STDIN_FILENO
190# define STDIN_FILENO 0
191#endif
192#ifndef STDOUT_FILENO
193# define STDOUT_FILENO 1
194#endif
195#ifndef STDERR_FILENO
196# define STDERR_FILENO 2
197#endif
198#ifndef R__WIN32
199//#if defined(HAVE_UNISTD_H)
200# include <unistd.h>
201//#endif
202#else
203#include "Windows4Root.h"
204#include <Psapi.h>
205#include <direct.h>
206#undef GetModuleFileName
207#define RTLD_DEFAULT ((void *)::GetModuleHandle(NULL))
208#define dlsym(library, function_name) ::GetProcAddress((HMODULE)library, function_name)
209#define dlopen(library_name, flags) ::LoadLibraryA(library_name)
210#define dlclose(library) ::FreeLibrary((HMODULE)library)
211#define R__DLLEXPORT __declspec(dllexport)
212#endif
213#endif
214
215//______________________________________________________________________________
216// These functions are helpers for debugging issues with non-LLVMDEV builds.
217//
218R__DLLEXPORT clang::DeclContext* TCling__DEBUG__getDeclContext(clang::Decl* D) {
219 return D->getDeclContext();
220}
221R__DLLEXPORT clang::NamespaceDecl* TCling__DEBUG__DCtoNamespace(clang::DeclContext* DC) {
222 return llvm::dyn_cast<clang::NamespaceDecl>(DC);
223}
224R__DLLEXPORT clang::RecordDecl* TCling__DEBUG__DCtoRecordDecl(clang::DeclContext* DC) {
225 return llvm::dyn_cast<clang::RecordDecl>(DC);
226}
227R__DLLEXPORT void TCling__DEBUG__dump(clang::DeclContext* DC) {
228 return DC->dumpDeclContext();
229}
230R__DLLEXPORT void TCling__DEBUG__dump(clang::Decl* D) {
231 return D->dump();
232}
233R__DLLEXPORT void TCling__DEBUG__dump(clang::FunctionDecl* FD) {
234 return FD->dump();
235}
237 return ((clang::Decl*)D)->dump();
238}
240 if (clang::NamedDecl* ND = llvm::dyn_cast<clang::NamedDecl>(D)) {
241 std::string name;
242 {
243 llvm::raw_string_ostream OS(name);
244 ND->getNameForDiagnostic(OS, D->getASTContext().getPrintingPolicy(),
245 true /*Qualified*/);
246 }
247 printf("%s\n", name.c_str());
248 }
249}
250//______________________________________________________________________________
251// These functions are helpers for testing issues directly rather than
252// relying on side effects.
253// This is used for the test for ROOT-7462/ROOT-6070
255 return D->isInvalidDecl();
256}
259 assert(info && info->IsValid());
260 return info->GetDecl()->isInvalidDecl();
261}
262
263using std::string, std::vector;
264using namespace clang;
265using namespace ROOT;
266
267namespace {
268 static const std::string gInterpreterClassDef = R"ICF(
269#undef ClassDef
270#define ClassDef(name, id) \
271_ClassDefInterp_(name,id,virtual,) \
272static int DeclFileLine() { return __LINE__; }
273#undef ClassDefNV
274#define ClassDefNV(name, id) \
275_ClassDefInterp_(name,id,,) \
276static int DeclFileLine() { return __LINE__; }
277#undef ClassDefOverride
278#define ClassDefOverride(name, id) \
279_ClassDefInterp_(name,id,,override) \
280static int DeclFileLine() { return __LINE__; }
281)ICF";
282
283 static const std::string gNonInterpreterClassDef = R"ICF(
284#define __ROOTCLING__ 1
285#undef ClassDef
286#define ClassDef(name,id) \
287_ClassDefOutline_(name,id,virtual,) \
288static int DeclFileLine() { return __LINE__; }
289#undef ClassDefNV
290#define ClassDefNV(name, id)\
291_ClassDefOutline_(name,id,,)\
292static int DeclFileLine() { return __LINE__; }
293#undef ClassDefOverride
294#define ClassDefOverride(name, id)\
295_ClassDefOutline_(name,id,,override)\
296static int DeclFileLine() { return __LINE__; }
297)ICF";
298
299// The macros below use ::Error, so let's ensure it is included
300 static const std::string gClassDefInterpMacro = R"ICF(
301#include "TError.h"
302
303#define _ClassDefInterp_(name,id,virtual_keyword, overrd) \
304private: \
305public: \
306 static TClass *Class() { static TClass* sIsA = 0; if (!sIsA) sIsA = TClass::GetClass(#name); return sIsA; } \
307 static const char *Class_Name() { return #name; } \
308 virtual_keyword Bool_t CheckTObjectHashConsistency() const overrd { \
309 static std::atomic<UChar_t> recurseBlocker(0); \
310 if (R__likely(recurseBlocker >= 2)) { \
311 return ::ROOT::Internal::THashConsistencyHolder<decltype(*this)>::fgHashConsistency; \
312 } else if (recurseBlocker == 1) { \
313 return false; \
314 } else if (recurseBlocker++ == 0) { \
315 ::ROOT::Internal::THashConsistencyHolder<decltype(*this)>::fgHashConsistency = \
316 ::ROOT::Internal::HasConsistentHashMember(_QUOTE_(name)) || \
317 ::ROOT::Internal::HasConsistentHashMember(*IsA()); \
318 ++recurseBlocker; \
319 return ::ROOT::Internal::THashConsistencyHolder<decltype(*this)>::fgHashConsistency; \
320 } \
321 return false; /* unreachable */ \
322 } \
323 static Version_t Class_Version() { return id; } \
324 static TClass *Dictionary() { return 0; } \
325 virtual_keyword TClass *IsA() const overrd { return name::Class(); } \
326 virtual_keyword void ShowMembers(TMemberInspector&insp) const overrd { ::ROOT::Class_ShowMembers(name::Class(), this, insp); } \
327 virtual_keyword void Streamer(TBuffer&) overrd { ::Error("Streamer", "Cannot stream interpreted class."); } \
328 void StreamerNVirtual(TBuffer&ClassDef_StreamerNVirtual_b) { name::Streamer(ClassDef_StreamerNVirtual_b); } \
329 static const char *DeclFileName() { return __FILE__; } \
330 static int ImplFileLine() { return 0; } \
331 static const char *ImplFileName() { return __FILE__; }
332)ICF";
333}
335
336// The functions are used to bridge cling/clang/llvm compiled with no-rtti and
337// ROOT (which uses rtti)
338
339////////////////////////////////////////////////////////////////////////////////
340/// Print a StackTrace!
341
342extern "C"
346
347////////////////////////////////////////////////////////////////////////////////
348/// Load a library.
349
350extern "C" int TCling__LoadLibrary(const char *library)
351{
353 return gSystem->Load(library, "", false);
354}
355
356////////////////////////////////////////////////////////////////////////////////
357/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
358
359extern "C" void TCling__RestoreInterpreterMutex(void *delta)
360{
361 ((TCling*)gCling)->ApplyToInterpreterMutex(delta);
362}
363
364////////////////////////////////////////////////////////////////////////////////
365/// Lookup libraries in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH with mangled_name,
366/// which is extracted by error messages we get from callback from cling. Return true
367/// when the missing library was autoloaded.
368
369extern "C" bool TCling__LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
370{
371 return ((TCling*)gCling)->LibraryLoadingFailed(errmessage, libStem, permanent, resolved);
372}
373
374////////////////////////////////////////////////////////////////////////////////
375/// Reset the interpreter lock to the state it had before interpreter-related
376/// calls happened.
377
379{
380 return ((TCling*)gCling)->RewindInterpreterMutex();
381}
382
383////////////////////////////////////////////////////////////////////////////////
384/// Lock the interpreter.
385
387{
388 if (gInterpreterMutex) {
390 }
391 return nullptr;
392}
393
394////////////////////////////////////////////////////////////////////////////////
395/// Unlock the interpreter.
396
398{
399 if (gInterpreterMutex) {
401 }
402}
403
404////////////////////////////////////////////////////////////////////////////////
405/// Update TClingClassInfo for a class (e.g. upon seeing a definition).
406
408{
409 static Bool_t entered = kFALSE;
412
413 if (entered) topLevel = kFALSE;
414 else {
415 entered = kTRUE;
416 topLevel = kTRUE;
417 }
418 if (topLevel) {
419 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(TD);
420 } else {
421 // If we are called indirectly from within another call to
422 // TCling::UpdateClassInfo, we delay the update until the dictionary loading
423 // is finished (i.e. when we return to the top level TCling::UpdateClassInfo).
424 // This allows for the dictionary to be fully populated when we actually
425 // update the TClass object. The updating of the TClass sometimes
426 // (STL containers and when there is an emulated class) forces the building
427 // of the TClass object's real data (which needs the dictionary info).
428 updateList.push_back(TD);
429 }
430 if (topLevel) {
431 while (!updateList.empty()) {
432 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(updateList.back());
433 updateList.pop_back();
434 }
435 entered = kFALSE;
436 }
437}
438
440 const clang::Decl* D = static_cast<const clang::Decl*>(enumObj->GetDeclId());
441 if(const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(D)) {
442 // Add the constants to the enum type.
443 for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin(),
444 EDE = ED->enumerator_end(); EDI != EDE; ++EDI) {
445 // Get name of the enum type.
446 std::string constbuf;
447 if (const NamedDecl* END = llvm::dyn_cast<NamedDecl>(*EDI)) {
448 PrintingPolicy Policy((*EDI)->getASTContext().getPrintingPolicy());
449 llvm::raw_string_ostream stream(constbuf);
450 // Don't trigger fopen of the source file to count lines:
451 Policy.AnonymousTagLocations = false;
452 (END)->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
453 }
454 const char* constantName = constbuf.c_str();
455
456 // Get value of the constant.
458 const llvm::APSInt valAPSInt = (*EDI)->getInitVal();
459 if (valAPSInt.isSigned()) {
460 value = valAPSInt.getSExtValue();
461 } else {
462 value = valAPSInt.getZExtValue();
463 }
464
465 // Create the TEnumConstant or update it if existing
466 TEnumConstant* enumConstant = nullptr;
467 TClingClassInfo* tcCInfo = (TClingClassInfo*)(cl ? cl->GetClassInfo() : nullptr);
470 if (TObject* encAsTObj = enumObj->GetConstants()->FindObject(constantName)){
471 ((TEnumConstant*)encAsTObj)->Update(dmInfo);
472 } else {
474 }
475
476 // Add the global constants to the list of Globals.
477 if (!cl) {
478 TCollection* globals = gROOT->GetListOfGlobals(false);
479 if (!globals->FindObject(constantName)) {
480 globals->Add(enumConstant);
481 }
482 }
483 }
484 }
485}
486
488{
489 // Handle new enum declaration for either global and nested enums.
490
491 // Create the enum type.
492 TEnum* enumType = nullptr;
493 const clang::Decl* D = static_cast<const clang::Decl*>(VD);
494 std::string buf;
495 if (const EnumDecl* ED = llvm::dyn_cast<EnumDecl>(D)) {
496 // Get name of the enum type.
497 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
498 llvm::raw_string_ostream stream(buf);
499 // Don't trigger fopen of the source file to count lines:
500 Policy.AnonymousTagLocations = false;
501 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
502 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
503 }
504 if (buf.empty()) {
505 return nullptr;
506 }
507 const char* name = buf.c_str();
508 enumType = new TEnum(name, VD, cl);
510
511 return enumType;
512}
513
514void TCling::HandleNewDecl(const void* DV, bool isDeserialized, std::set<TClass*> &modifiedTClasses) {
515 // Handle new declaration.
516 // Record the modified class, struct and namespaces in 'modifiedTClasses'.
517
518 const clang::Decl* D = static_cast<const clang::Decl*>(DV);
519
520 if (!D->isCanonicalDecl() && !isa<clang::NamespaceDecl>(D)
521 && !dyn_cast<clang::RecordDecl>(D)) return;
522
523 if (isa<clang::FunctionDecl>(D->getDeclContext())
524 || isa<clang::TagDecl>(D->getDeclContext()))
525 return;
526
527 // Don't list templates.
528 if (const clang::CXXRecordDecl* RD = dyn_cast<clang::CXXRecordDecl>(D)) {
529 if (RD->getDescribedClassTemplate())
530 return;
531 } else if (const clang::FunctionDecl* FD = dyn_cast<clang::FunctionDecl>(D)) {
532 if (FD->getDescribedFunctionTemplate())
533 return;
534 }
535
536 if (const RecordDecl *TD = dyn_cast<RecordDecl>(D)) {
537 if (TD->isCanonicalDecl() || TD->isThisDeclarationADefinition())
539 }
540 else if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
541
542 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
543 // Mostly just for EnumDecl (the other TagDecl are handled
544 // by the 'RecordDecl' if statement.
546 } else if (const NamespaceDecl* NSD = dyn_cast<NamespaceDecl>(D)) {
548 }
549
550 // We care about declarations on the global scope.
551 if (!isa<TranslationUnitDecl>(ND->getDeclContext()))
552 return;
553
554 // Enums are lazyly created, thus we don not need to handle them here.
555 if (isa<EnumDecl>(ND))
556 return;
557
558 // ROOT says that global is enum(lazylycreated)/var/field declared on the global
559 // scope.
560 if (!(isa<VarDecl>(ND)))
561 return;
562
563 // Skip if already in the list.
564 if (gROOT->GetListOfGlobals()->FindObject(ND->getNameAsString().c_str()))
565 return;
566
567 // Put the global constants and global enums in the corresponding lists.
568 gROOT->GetListOfGlobals()->Add(new TGlobal((DataMemberInfo_t *)
570 cast<ValueDecl>(ND), nullptr)));
571 }
572}
573
574extern "C"
576{
577 // We are sure in this context of the type of the interpreter
578 normCtxt = &( (TCling*) gInterpreter)->GetNormalizedContext();
579}
580
581extern "C"
582void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter*) {
583 ((TCling*)gCling)->UpdateListsOnCommitted(T);
584}
585
586extern "C"
587void TCling__UpdateListsOnUnloaded(const cling::Transaction &T) {
588 ((TCling*)gCling)->UpdateListsOnUnloaded(T);
589}
590
591extern "C"
592void TCling__InvalidateGlobal(const clang::Decl *D) {
593 ((TCling*)gCling)->InvalidateGlobal(D);
594}
595
596extern "C"
597void TCling__TransactionRollback(const cling::Transaction &T) {
598 ((TCling*)gCling)->TransactionRollback(T);
599}
600
601extern "C" void TCling__LibraryLoadedRTTI(const void* dyLibHandle,
602 const char* canonicalName) {
603 ((TCling*)gCling)->LibraryLoaded(dyLibHandle, canonicalName);
604}
605
606extern "C" void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
607{
608 ((TCling *)gCling)->RegisterRdictForLoadPCM(pcmFileNameFullPath, pcmContent);
609}
610
611extern "C" void TCling__LibraryUnloadedRTTI(const void* dyLibHandle,
612 const char* canonicalName) {
613 ((TCling*)gCling)->LibraryUnloaded(dyLibHandle, canonicalName);
614}
615
616
617extern "C"
618TObject* TCling__GetObjectAddress(const char *Name, void *&LookupCtx) {
619 return ((TCling*)gCling)->GetObjectAddress(Name, LookupCtx);
620}
621
622extern "C" const Decl* TCling__GetObjectDecl(TObject *obj) {
623 return ((TClingClassInfo*)obj->IsA()->GetClassInfo())->GetDecl();
624}
625
627 const char* argv[])
628{
629 auto tcling = new TCling("C++", "cling C++ Interpreter", argv, interpLibHandle);
630
631 return tcling;
632}
633
635{
636 delete interp;
637}
638
639// Load library containing specified class. Returns 0 in case of error
640// and 1 in case if success.
641extern "C" int TCling__AutoLoadCallback(const char* className)
642{
643 return ((TCling*)gCling)->AutoLoad(className);
644}
645
646extern "C" int TCling__AutoParseCallback(const char* className)
647{
648 return ((TCling*)gCling)->AutoParse(className);
649}
650
651extern "C" const char* TCling__GetClassSharedLibs(const char* className, bool skipCore)
652{
653 return ((TCling*)gCling)->GetClassSharedLibs(className, skipCore);
654}
655
656// Returns 0 for failure 1 for success
657extern "C" int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
658{
659 return ((TCling*)gCling)->IsAutoLoadNamespaceCandidate(nsDecl);
660}
661
662extern "C" int TCling__CompileMacro(const char *fileName, const char *options)
663{
664 string file(fileName);
665 string opt(options);
666 return gSystem->CompileMacro(file.c_str(), opt.c_str());
667}
668
669extern "C" void TCling__SplitAclicMode(const char* fileName, string &mode,
670 string &args, string &io, string &fname)
671{
672 string file(fileName);
673 TString f, amode, arguments, aclicio;
674 f = gSystem->SplitAclicMode(file.c_str(), amode, arguments, aclicio);
675 mode = amode.Data(); args = arguments.Data();
676 io = aclicio.Data(); fname = f.Data();
677}
678
679//______________________________________________________________________________
680//
681//
682//
683
684#ifdef R__WIN32
685extern "C" {
686 char *__unDName(char *demangled, const char *mangled, int out_len,
687 void * (* pAlloc )(size_t), void (* pFree )(void *),
688 unsigned short int flags);
689}
690#endif
691
692////////////////////////////////////////////////////////////////////////////////
693/// Find a template decl within N nested namespaces, 0<=N<inf
694/// Assumes 1 and only 1 template present and 1 and only 1 entity contained
695/// by the namespace. Example: `ns1::ns2::..::%nsN::%myTemplate`
696/// Returns nullptr in case of error
697
698static clang::ClassTemplateDecl* FindTemplateInNamespace(clang::Decl* decl)
699{
700 using namespace clang;
701 if (NamespaceDecl* nsd = llvm::dyn_cast<NamespaceDecl>(decl)){
702 return FindTemplateInNamespace(*nsd->decls_begin());
703 }
704
705 if (ClassTemplateDecl* ctd = llvm::dyn_cast<ClassTemplateDecl>(decl)){
706 return ctd;
707 }
708
709 return nullptr; // something went wrong.
710}
711
712//______________________________________________________________________________
713//
714//
715//
716
717int TCling_GenerateDictionary(const std::vector<std::string> &classes,
718 const std::vector<std::string> &headers,
719 const std::vector<std::string> &fwdDecls,
720 const std::vector<std::string> &unknown)
721{
722 //This function automatically creates the "LinkDef.h" file for templated
723 //classes then executes CompileMacro on it.
724 //The name of the file depends on the class name, and it's not generated again
725 //if the file exist.
726 if (classes.empty()) {
727 return 0;
728 }
729 // Use the name of the first class as the main name.
730 const std::string& className = classes[0];
731 //(0) prepare file name
732 TString fileName = "AutoDict_";
733 std::string::const_iterator sIt;
734 for (sIt = className.begin(); sIt != className.end(); ++sIt) {
735 if (*sIt == '<' || *sIt == '>' ||
736 *sIt == ' ' || *sIt == '*' ||
737 *sIt == ',' || *sIt == '&' ||
738 *sIt == ':') {
739 fileName += '_';
740 }
741 else {
742 fileName += *sIt;
743 }
744 }
745 if (classes.size() > 1) {
746 Int_t chk = 0;
747 std::vector<std::string>::const_iterator it = classes.begin();
748 while ((++it) != classes.end()) {
749 for (UInt_t cursor = 0; cursor != it->length(); ++cursor) {
750 chk = chk * 3 + it->at(cursor);
751 }
752 }
753 fileName += TString::Format("_%u", chk);
754 }
755 fileName += ".cxx";
756 if (gSystem->AccessPathName(fileName) != 0) {
757 //file does not exist
758 //(1) prepare file data
759 // If STL, also request iterators' operators.
760 // vector is special: we need to check whether
761 // vector::iterator is a typedef to pointer or a
762 // class.
763 static const std::set<std::string> sSTLTypes {
764 "vector","list","forward_list","deque","map","unordered_map","multimap",
765 "unordered_multimap","set","unordered_set","multiset","unordered_multiset",
766 "queue","priority_queue","stack","iterator"};
767 std::vector<std::string>::const_iterator it;
768 std::string fileContent("");
769 for (it = headers.begin(); it != headers.end(); ++it) {
770 fileContent += "#include \"" + *it + "\"\n";
771 }
772 for (it = unknown.begin(); it != unknown.end(); ++it) {
773 TClass* cl = TClass::GetClass(it->c_str());
774 if (cl && cl->GetDeclFileName()) {
775 TString header = gSystem->BaseName(cl->GetDeclFileName());
778 while (dirbase.Length() && dirbase != "."
779 && dirbase != "include" && dirbase != "inc"
780 && dirbase != "prec_stl") {
782 dir = gSystem->GetDirName(dir);
783 }
784 fileContent += TString("#include \"") + header + "\"\n";
785 }
786 }
787 for (it = fwdDecls.begin(); it != fwdDecls.end(); ++it) {
788 fileContent += "class " + *it + ";\n";
789 }
790 fileContent += "#ifdef __CLING__ \n";
791 fileContent += "#pragma link C++ nestedclasses;\n";
792 fileContent += "#pragma link C++ nestedtypedefs;\n";
793 for (it = classes.begin(); it != classes.end(); ++it) {
794 std::string n(*it);
795 size_t posTemplate = n.find('<');
796 std::set<std::string>::const_iterator iSTLType = sSTLTypes.end();
797 if (posTemplate != std::string::npos) {
798 n.erase(posTemplate, std::string::npos);
799 if (n.compare(0, 5, "std::") == 0) {
800 n.erase(0, 5);
801 }
802 iSTLType = sSTLTypes.find(n);
803 }
804 fileContent += "#pragma link C++ class ";
805 fileContent += *it + "+;\n" ;
806 if (iSTLType == sSTLTypes.end()) {
807 // Not an STL class; we need to allow the I/O of contained
808 // classes (now that we have a dictionary for them).
809 fileContent += "#pragma link C++ class " + *it + "::*+;\n" ;
810 }
811 }
812 fileContent += "#endif\n";
813 //end(1)
814 //(2) prepare the file
816 filePointer = fopen(fileName, "w");
817 if (filePointer == nullptr) {
818 //can't open a file
819 return 1;
820 }
821 //end(2)
822 //write data into the file
823 fprintf(filePointer, "%s", fileContent.c_str());
825 }
826 //(3) checking if we can compile a macro, if not then cleaning
828 gErrorIgnoreLevel = kWarning; // no "Info: creating library..."
829 Int_t ret = gSystem->CompileMacro(fileName, "k");
831 if (ret == 0) { //can't compile a macro
832 return 2;
833 }
834 //end(3)
835 return 0;
836}
837
838int TCling_GenerateDictionary(const std::string& className,
839 const std::vector<std::string> &headers,
840 const std::vector<std::string> &fwdDecls,
841 const std::vector<std::string> &unknown)
842{
843 //This function automatically creates the "LinkDef.h" file for templated
844 //classes then executes CompileMacro on it.
845 //The name of the file depends on the class name, and it's not generated again
846 //if the file exist.
847 std::vector<std::string> classes;
848 classes.push_back(className);
850}
851
852//______________________________________________________________________________
853//
854//
855//
856
857// It is a "fantom" method to synchronize user keyboard input
858// and ROOT prompt line (for WIN32)
859const char* fantomline = "TRint::EndOfLineAction();";
860
861//______________________________________________________________________________
862//
863//
864//
865
866void* TCling::fgSetOfSpecials = nullptr;
867
868//______________________________________________________________________________
869//
870// llvm error handler through exceptions; see also cling/UserInterface
871//
872namespace {
873 // Handle fatal llvm errors by throwing an exception.
874 // Yes, throwing exceptions in error handlers is bad.
875 // Doing nothing is pretty terrible, too.
876 void exceptionErrorHandler(void * /*user_data*/,
877 const char *reason,
878 bool /*gen_crash_diag*/) {
879 throw std::runtime_error(std::string(">>> Interpreter compilation error:\n") + reason);
880 }
881}
882
883//______________________________________________________________________________
884//
885//
886//
887
888////////////////////////////////////////////////////////////////////////////////
889
890namespace{
891 // An instance of this class causes the diagnostics of clang to be suppressed
892 // during its lifetime
893 class clangDiagSuppr {
894 public:
895 clangDiagSuppr(clang::DiagnosticsEngine& diag): fDiagEngine(diag){
896 fOldDiagValue = fDiagEngine.getIgnoreAllWarnings();
897 fDiagEngine.setIgnoreAllWarnings(true);
898 }
899
901 fDiagEngine.setIgnoreAllWarnings(fOldDiagValue);
902 }
903 private:
904 clang::DiagnosticsEngine& fDiagEngine;
905 bool fOldDiagValue;
906 };
907
908}
909
910////////////////////////////////////////////////////////////////////////////////
911/// Allow calling autoparsing from TMetaUtils
913{
914 return gCling->AutoParse(cname);
915}
916
917////////////////////////////////////////////////////////////////////////////////
918/// Try hard to avoid looking up in the Cling database as this could enduce
919/// an unwanted autoparsing.
920
922 std::string &result)
923{
924 result.clear();
925
926 unsigned long offset = 0;
927 if (strncmp(tname.c_str(), "const ", 6) == 0) {
928 offset = 6;
929 }
930 unsigned long end = tname.length();
931 while( end && (tname[end-1]=='&' || tname[end-1]=='*' || tname[end-1]==']') ) {
932 if ( tname[end-1]==']' ) {
933 --end;
934 while ( end && tname[end-1]!='[' ) --end;
935 }
936 --end;
937 }
938 std::string innerbuf;
939 const char *inner;
940 if (end != tname.length()) {
941 innerbuf = tname.substr(offset,end-offset);
942 inner = innerbuf.c_str();
943 } else {
944 inner = tname.c_str()+offset;
945 }
946
947 //if (strchr(tname.c_str(),'[')!=0) fprintf(stderr,"DEBUG: checking on %s vs %s %lu %lu\n",tname.c_str(),inner,offset,end);
948 if (gROOT->GetListOfClasses()->FindObject(inner)
950 // This is a known class.
951 return true;
952 }
953
954 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
955 TDataType *type = (TDataType *)typeTable->THashTable::FindObject( inner );
956 if (type) {
957 // This is a raw type and an already loaded typedef.
958 const char *newname = type->GetFullTypeName();
959 if (type->GetType() == kLong64_t) {
960 newname = "Long64_t";
961 } else if (type->GetType() == kULong64_t) {
962 newname = "ULong64_t";
963 }
964 if (strcmp(inner,newname) == 0) {
965 return true;
966 }
967 if (offset) result = "const ";
968 result += newname;
969 if ( end != tname.length() ) {
970 result += tname.substr(end,tname.length()-end);
971 }
972 if (result == tname) result.clear();
973 return true;
974 }
975
976 // Check if the name is an enumerator
978 if (lastPos != inner) // Main switch: case 1 - scoped enum, case 2 global enum
979 {
980 // We have a scope
981 const auto enName = lastPos;
982 const auto scopeNameSize = (lastPos - inner) / sizeof(decltype(*lastPos)) - 2;
983 std::string scopeName{inner, scopeNameSize};
984 // Check if the scope is in the list of classes
985 if (auto scope = static_cast<TClass *>(gROOT->GetListOfClasses()->FindObject(scopeName.c_str()))) {
986 auto enumTable = dynamic_cast<const THashList *>(scope->GetListOfEnums(false));
987 if (enumTable && enumTable->THashList::FindObject(enName))
988 return true;
989 }
990 // It may still be in one of the loaded protoclasses
991 else if (auto scope = static_cast<TProtoClass *>(gClassTable->GetProtoNorm(scopeName.c_str()))) {
992 auto listOfEnums = scope->GetListOfEnums();
993 if (listOfEnums) { // it could be null: no enumerators in the protoclass
994 auto enumTable = dynamic_cast<const THashList *>(listOfEnums);
995 if (enumTable && enumTable->THashList::FindObject(enName))
996 return true;
997 }
998 }
999 } else
1000 {
1001 // We don't have any scope: this could only be a global enum
1002 auto enumTable = dynamic_cast<const THashList *>(gROOT->GetListOfEnums());
1003 if (enumTable && enumTable->THashList::FindObject(inner)) return true;
1004 }
1005
1007 {
1008 // This is a class name.
1009 return true;
1010 }
1011
1012 return false;
1013}
1014
1015////////////////////////////////////////////////////////////////////////////////
1016/// Check if the class name is present in TClassTable.
1017///
1018/// \param[in] tname class name to check.
1019/// \param[out] result If a class name has an alternative name registered in
1020/// TClassTable, it will be copied into this string.
1021bool TClingLookupHelper__CheckInClassTable(const std::string &tname, std::string &result)
1022{
1023 result.clear();
1024
1025 if (gROOT->GetListOfClasses()->FindObject(tname.c_str()) || TClassTable::Check(tname.c_str(), result)) {
1026 // This is a known class.
1027 return true;
1028 }
1029
1030 return false;
1031}
1032
1033////////////////////////////////////////////////////////////////////////////////
1034
1039
1040////////////////////////////////////////////////////////////////////////////////
1041
1043{
1044 return fContent.c_str();
1045}
1046
1047////////////////////////////////////////////////////////////////////////////////
1048/// Append string to the storage if not added already.
1049
1050inline bool TCling::TUniqueString::Append(const std::string& str)
1051{
1052 bool notPresent = fLinesHashSet.emplace(fHashFunc(str)).second;
1053 if (notPresent){
1054 fContent+=str;
1055 }
1056 return notPresent;
1057}
1058
1059std::string TCling::ToString(const char* type, void* obj)
1060{
1061 return fInterpreter->toString(type, obj);
1062}
1063
1064////////////////////////////////////////////////////////////////////////////////
1065///\returns true if the module was loaded.
1066static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
1067{
1068 // When starting up ROOT, cling would load all modulemap files on the include
1069 // paths. However, in a ROOT session, it is very common to run aclic which
1070 // will invoke rootcling and possibly produce a modulemap and a module in
1071 // the current folder.
1072 //
1073 // Before failing, try loading the modulemap in the current folder and try
1074 // loading the requested module from it.
1075 std::string currentDir = gSystem->WorkingDirectory();
1076 assert(!currentDir.empty());
1078 if (gDebug > 2)
1079 ::Info("TCling::__LoadModule", "Preloading module %s. \n",
1080 ModuleName.c_str());
1081
1082 return interp.loadModule(ModuleName, /*Complain=*/true);
1083}
1084
1085////////////////////////////////////////////////////////////////////////////////
1086/// Loads the C++ modules that we require to run any ROOT program. This is just
1087/// supposed to make a C++ module from a modulemap available to the interpreter.
1088static void LoadModules(const std::vector<std::string> &modules, cling::Interpreter &interp)
1089{
1090 for (const auto &modName : modules)
1092}
1093
1094static bool IsFromRootCling() {
1095 // rootcling also uses TCling for generating the dictionary ROOT files.
1096 const static bool foundSymbol = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
1097 return foundSymbol;
1098}
1099
1100/// Checks if there is an ASTFile on disk for the given module \c M.
1101static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName = nullptr)
1102{
1103 const HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
1104
1105 std::string ModuleFileName;
1106 if (!HSOpts.PrebuiltModulePaths.empty())
1107 // Load the module from *only* in the prebuilt module path.
1108 ModuleFileName = PP.getHeaderSearchInfo().getPrebuiltModuleFileName(M->Name);
1109 if (FullFileName)
1111
1112 return !ModuleFileName.empty();
1113}
1114
1115static bool HaveFullGlobalModuleIndex = false;
1117{
1118 CompilerInstance &CI = *interp.getCI();
1119 Preprocessor &PP = CI.getPreprocessor();
1120 auto ModuleManager = CI.getASTReader();
1122 // StringRef ModuleIndexPath = HSI.getModuleCachePath();
1123 // HeaderSearch& HSI = PP.getHeaderSearchInfo();
1124 // HSI.setModuleCachePath(TROOT::GetSharedLibDir().Data());
1125 std::string ModuleIndexPath = TROOT::GetSharedLibDir().Data();
1126 if (ModuleIndexPath.empty())
1127 return nullptr;
1128 // Get an existing global index. This loads it if not already loaded.
1129 ModuleManager->resetForReload();
1130 ModuleManager->loadGlobalIndex();
1131 GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex();
1132
1133 // For finding modules needing to be imported for fixit messages,
1134 // we need to make the global index cover all modules, so we do that here.
1136 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1137 bool RecreateIndex = false;
1138 for (ModuleMap::module_iterator I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1139 Module *TheModule = I->second;
1140 // We want the index only of the prebuilt modules.
1142 continue;
1143 LoadModule(TheModule->Name, interp);
1144 RecreateIndex = true;
1145 }
1146 if (RecreateIndex) {
1147 cling::Interpreter::PushTransactionRAII deserRAII(&interp);
1148 clang::GlobalModuleIndex::UserDefinedInterestingIDs IDs;
1149
1150 struct DefinitionFinder : public RecursiveASTVisitor<DefinitionFinder> {
1151 DefinitionFinder(clang::GlobalModuleIndex::UserDefinedInterestingIDs& IDs,
1152 clang::TranslationUnitDecl* TU) : DefinitionIDs(IDs) {
1154 }
1155 bool VisitNamedDecl(NamedDecl *ND) {
1156 if (!ND->isFromASTFile())
1157 return true;
1158 if (!ND->getIdentifier())
1159 return true;
1160
1161 if (ND->getAccess() == AS_protected || ND->getAccess() == AS_private)
1162 return true;
1163
1164 if (TagDecl *TD = llvm::dyn_cast<TagDecl>(ND)) {
1165 if (TD->isCompleteDefinition())
1166 Register(TD);
1167 } else if (NamespaceDecl *NSD = llvm::dyn_cast<NamespaceDecl>(ND)) {
1168 Register(NSD, /*AddSingleEntry=*/ false);
1169 }
1171 Register(TND);
1172 // FIXME: Add the rest...
1173 return true; // continue decending
1174 }
1175 private:
1176 clang::GlobalModuleIndex::UserDefinedInterestingIDs &DefinitionIDs;
1177 void Register(const NamedDecl* ND, bool AddSingleEntry = true) {
1178 assert(ND->isFromASTFile());
1179 // FIXME: All decls should have an owning module once rootcling
1180 // updates its generated decls from within the LookupHelper & co.
1181 if (!ND->hasOwningModule()) {
1182#ifndef NDEBUG
1183 SourceManager &SM = ND->getASTContext().getSourceManager();
1184 SourceLocation Loc = ND->getLocation();
1185 OptionalFileEntryRef FE = SM.getFileEntryRefForID(SM.getFileID(Loc));
1186 (void)FE;
1187 assert(FE->getName().contains("input_line_"));
1188#endif
1189 return;
1190 }
1191
1192 Module *OwningModule = ND->getOwningModule()->getTopLevelModule();
1194 assert(!ND->getName().empty() && "Empty name");
1195 if (AddSingleEntry && DefinitionIDs.count(ND->getName()))
1196 return;
1197 // FIXME: The FileEntry in not stable to serialize.
1198 // FIXME: We might end up with many times with the same module.
1199 // FIXME: We might end up two modules containing a definition.
1200 // FIXME: What do we do if no definition is found.
1201 DefinitionIDs[ND->getName()].push_back(OwningModule->getASTFile());
1202 }
1203 };
1204 DefinitionFinder defFinder(IDs, CI.getASTContext().getTranslationUnitDecl());
1205
1206 llvm::cantFail(GlobalModuleIndex::writeIndex(CI.getFileManager(),
1207 CI.getPCHContainerReader(),
1209 &IDs));
1210 ModuleManager->resetForReload();
1211 ModuleManager->loadGlobalIndex();
1212 GlobalIndex = ModuleManager->getGlobalIndex();
1213 }
1215 }
1216 return GlobalIndex;
1217}
1218
1219static void RegisterCxxModules(cling::Interpreter &clingInterp)
1220{
1221 if (!clingInterp.getCI()->getLangOpts().Modules)
1222 return;
1223
1224 // Loading of a module might deserialize.
1225 cling::Interpreter::PushTransactionRAII deserRAII(&clingInterp);
1226
1227 // Setup core C++ modules if we have any to setup.
1228
1229 // Load libc and stl first.
1230 // Load vcruntime module for windows
1231#ifdef R__WIN32
1232 LoadModule("vcruntime", clingInterp);
1233 LoadModule("services", clingInterp);
1234#endif
1235
1236#ifdef R__MACOSX
1237 LoadModule("Darwin", clingInterp);
1238#else
1239 LoadModule("libc", clingInterp);
1240#endif
1241 LoadModule("std", clingInterp);
1242
1243 LoadModule("_Builtin_intrinsics", clingInterp);
1244
1245 // Load core modules
1246 // This should be vector in order to be able to pass it to LoadModules
1247 std::vector<std::string> CoreModules = {"ROOT_Foundation_C",
1248 "ROOT_Config",
1249 "ROOT_Rtypes",
1250 "ROOT_Foundation_Stage1_NoRTTI",
1251 "Core",
1252 "Rint",
1253 "RIO"};
1254
1256
1257 // Take this branch only from ROOT because we don't need to preload modules in rootcling
1258 if (!IsFromRootCling()) {
1259 std::vector<std::string> CommonModules = {"MathCore"};
1261
1262 // These modules should not be preloaded but they fix issues.
1263 // FIXME: Hist is not a core module but is very entangled to MathCore and
1264 // causes issues.
1265 std::vector<std::string> FIXMEModules = {"Hist"};
1266 clang::CompilerInstance &CI = *clingInterp.getCI();
1267 clang::Preprocessor &PP = CI.getPreprocessor();
1268 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1269 if (MMap.findModule("RInterface"))
1270 FIXMEModules.push_back("RInterface");
1271
1273
1274 GlobalModuleIndex *GlobalIndex = nullptr;
1275
1276 bool useGMI = true;
1277 std::optional<std::string> envUseGMI = llvm::sys::Process::GetEnv("ROOT_USE_GMI");
1278 if (envUseGMI.has_value())
1280 useGMI = false;
1281
1282 if (useGMI) {
1284 // FIXME: The ASTReader still calls loadGlobalIndex and loads the file
1285 // We should investigate how to suppress it completely.
1286 GlobalIndex = CI.getASTReader()->getGlobalIndex();
1287 }
1288
1289 llvm::StringSet<> KnownModuleFileNames;
1290 if (GlobalIndex)
1291 GlobalIndex->getKnownModuleFileNames(KnownModuleFileNames);
1292
1293 std::vector<std::string> PendingModules;
1294 PendingModules.reserve(256);
1295 for (auto I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1296 clang::Module *M = I->second;
1297 assert(M);
1298
1299 // We want to load only already created modules.
1300 std::string FullASTFilePath;
1302 continue;
1303
1305 continue;
1306
1307 if (M->IsUnimportable)
1308 continue;
1309
1310 if (GlobalIndex)
1311 LoadModule(M->Name, clingInterp);
1312 else {
1313 // FIXME: We may be able to remove those checks as cling::loadModule
1314 // checks if a module was alredy loaded.
1315 if (std::find(CoreModules.begin(), CoreModules.end(), M->Name) != CoreModules.end())
1316 continue; // This is a core module which was already loaded.
1317
1318 // Load system modules now and delay the other modules after we have
1319 // loaded all system ones.
1320 if (M->IsSystem)
1321 LoadModule(M->Name, clingInterp);
1322 else
1323 PendingModules.push_back(M->Name);
1324 }
1325 }
1327 }
1328
1329 // Check that the gROOT macro was exported by any core module.
1330 assert(clingInterp.getMacro("gROOT") && "Couldn't load gROOT macro?");
1331
1332 // `ERROR` and `PI` are from loading R related modules, which conflict with
1333 // user's code.
1334 clingInterp.declare(R"CODE(
1335#ifdef PI
1336# undef PI
1337#endif
1338#ifdef ERROR
1339# undef ERROR
1340#endif
1341 )CODE");
1342}
1343
1344static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
1345{
1346 std::string PreIncludes;
1347 bool hasCxxModules = clingInterp.getCI()->getLangOpts().Modules;
1348
1349 // For the list to also include string, we have to include it now.
1350 // rootcling does parts already if needed, e.g. genreflex does not want using
1351 // namespace std.
1352 if (IsFromRootCling()) {
1353 PreIncludes += "#include \"RtypesCore.h\"\n";
1354 } else {
1355 if (!hasCxxModules)
1356 PreIncludes += "#include \"Rtypes.h\"\n";
1357
1359 + gInterpreterClassDef + "\n"
1360 "#undef ClassImp\n" // bw compatibility
1361 "#define ClassImp(X);\n"; // bw compatibility
1362 }
1363 if (!hasCxxModules)
1364 PreIncludes += "#include <string>\n";
1365
1366 // We must include it even when we have modules because it is marked as
1367 // textual in the modulemap due to the nature of the assert header.
1368#ifndef R__WIN32
1369 PreIncludes += "#include <cassert>\n";
1370#endif
1371 PreIncludes += "using namespace std;\n";
1372 clingInterp.declare(PreIncludes);
1373}
1374
1375////////////////////////////////////////////////////////////////////////////////
1376/// Initialize the cling interpreter interface.
1377/// \param name name for TInterpreter
1378/// \param title title for TInterpreter
1379/// \param argv - array of arguments passed to the cling::Interpreter constructor
1380/// e.g. `-DFOO=bar`. The last element of the array must be `nullptr`.
1381/// \param interpLibHandle handle to interpreter library
1382
1383TCling::TCling(const char *name, const char *title, const char* const argv[], void *interpLibHandle)
1384: TInterpreter(name, title), fGlobalsListSerial(-1), fMapfile(nullptr),
1385 fRootmapFiles(nullptr), fLockProcessLine(true), fNormalizedCtxt(nullptr), fLookupHelper(nullptr),
1386 fPrevLoadedDynLibInfo(nullptr), fClingCallbacks(nullptr), fAutoLoadCallBack(nullptr),
1388{
1389 fPrompt[0] = 0;
1390 const bool fromRootCling = IsFromRootCling();
1391
1392 fCxxModulesEnabled = false;
1393#ifdef R__USE_CXXMODULES
1394 fCxxModulesEnabled = true;
1395#endif
1396
1397 llvm::install_fatal_error_handler(&exceptionErrorHandler);
1398
1399 fTemporaries = new std::vector<cling::Value>();
1400
1401 std::vector<std::string> clingArgsStorage;
1402 clingArgsStorage.push_back("cling4root");
1403 for (const char* const* arg = argv; *arg; ++arg)
1404 clingArgsStorage.push_back(*arg);
1405
1406 // rootcling sets its arguments through TROOT::GetExtraInterpreterArgs().
1407 if (!fromRootCling) {
1409
1410 // Add -I early so ASTReader can find the headers.
1411 std::string interpInclude(TROOT::GetEtcDir().Data());
1412 clingArgsStorage.push_back("-I" + interpInclude);
1413
1414 // Add include path to etc/cling.
1415 clingArgsStorage.push_back("-I" + interpInclude + "/cling");
1416
1417 // Add include path to etc/cling.
1418 clingArgsStorage.push_back("-I" + interpInclude + "/cling/plugins/include");
1419
1420 // Add the root include directory and etc/ to list searched by default.
1421 clingArgsStorage.push_back(std::string(("-I" + TROOT::GetIncludeDir()).Data()));
1422
1423 // Add the current path to the include path
1424 // TCling::AddIncludePath(".");
1425
1426 // Attach the PCH (unless we have C++ modules enabled which provide the
1427 // same functionality).
1428 if (!fCxxModulesEnabled) {
1429 std::string pchFilename = interpInclude + "/allDict.cxx.pch";
1430 if (gSystem->Getenv("ROOT_PCH")) {
1431 pchFilename = gSystem->Getenv("ROOT_PCH");
1432 }
1433
1434 clingArgsStorage.push_back("-include-pch");
1435 clingArgsStorage.push_back(pchFilename);
1436 }
1437
1438 clingArgsStorage.push_back("-Wno-undefined-inline");
1439 clingArgsStorage.push_back("-fsigned-char");
1440 clingArgsStorage.push_back("-fsized-deallocation");
1441 // The -O1 optimization flag has nasty side effects on Windows (32 and 64 bit)
1442 // See the GitHub issues #9809 and #9944
1443 // TODO: to be reviewed after the upgrade of LLVM & Clang
1444#ifndef _MSC_VER
1445 clingArgsStorage.push_back("-O1");
1446 // Disable optimized register allocation which is turned on automatically
1447 // by -O1, but seems to require -O2 to not explode in run time.
1448 clingArgsStorage.push_back("-mllvm");
1449 clingArgsStorage.push_back("-optimize-regalloc=0");
1450#endif
1451
1452#ifdef CLING_WITH_ADAPTIVECPP
1453 std::string acppInclude(TROOT::GetIncludeDir() + "/AdaptiveCpp");
1454
1455 clingArgsStorage.push_back("-isystem");
1456 clingArgsStorage.push_back(acppInclude);
1457 clingArgsStorage.push_back("-mllvm");
1458 clingArgsStorage.push_back("-acpp-sscp");
1459#endif
1460 }
1461
1462 // Process externally passed arguments if present.
1463 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv("EXTRA_CLING_ARGS");
1464 if (EnvOpt.has_value()) {
1466 while (!Env.empty()) {
1467 StringRef Arg;
1468 std::tie(Arg, Env) = Env.split(' ');
1469 clingArgsStorage.push_back(Arg.str());
1470 }
1471 }
1472
1473 auto GetEnvVarPath = [](const std::string &EnvVar, std::vector<std::string> &Paths) {
1474 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv(EnvVar);
1475 if (EnvOpt.has_value()) {
1477 while (!Env.empty()) {
1478 StringRef Arg;
1479 std::tie(Arg, Env) = Env.split(ROOT::FoundationUtils::GetEnvPathSeparator());
1480 if (std::find(Paths.begin(), Paths.end(), Arg.str()) == Paths.end())
1481 Paths.push_back(Arg.str());
1482 }
1483 }
1484 };
1485
1486 if (fCxxModulesEnabled) {
1487 std::vector<std::string> Paths;
1488 // ROOT usually knows better where its libraries are. This way we can
1489 // discover modules without having to should thisroot.sh and should fix
1490 // gnuinstall.
1491 Paths.push_back(TROOT::GetSharedLibDir().Data());
1492 GetEnvVarPath("CLING_PREBUILT_MODULE_PATH", Paths);
1493 std::string EnvVarPath;
1494 for (const std::string& P : Paths)
1496 // FIXME: We should make cling -fprebuilt-module-path work.
1497 gSystem->Setenv("CLING_PREBUILT_MODULE_PATH", EnvVarPath.c_str());
1498 }
1499
1500 // FIXME: This only will enable frontend timing reports.
1501 EnvOpt = llvm::sys::Process::GetEnv("ROOT_CLING_TIMING");
1502 if (EnvOpt.has_value())
1503 clingArgsStorage.push_back("-ftime-report");
1504
1505 // Add the overlay file. Note that we cannot factor it out for both root
1506 // and rootcling because rootcling activates modules only if -cxxmodule
1507 // flag is passed.
1509 // For now we prefer rootcling to enumerate explicitly its modulemaps.
1510 std::vector<std::string> ModuleMaps;
1511 std::string ModuleMapSuffix = ROOT::FoundationUtils::GetPathSeparator() + "ROOT.modulemap";
1512 ModuleMaps.push_back(TROOT::GetIncludeDir().Data() + ModuleMapSuffix);
1513 GetEnvVarPath("CLING_MODULEMAP_FILES", ModuleMaps);
1514
1515 std::string cwd = gSystem->WorkingDirectory();
1516 // Give highest precedence of the modulemap in the cwd if any.
1517 if (llvm::sys::fs::exists(cwd + ModuleMapSuffix))
1518 ModuleMaps.push_back(cwd + ModuleMapSuffix);
1519
1520 for (const std::string& M : ModuleMaps)
1521 clingArgsStorage.push_back("-fmodule-map-file=" + M);
1522
1523 std::string ModulesCachePath;
1524 EnvOpt = llvm::sys::Process::GetEnv("CLING_MODULES_CACHE_PATH");
1525 if (EnvOpt.has_value()){
1527 assert(llvm::sys::fs::exists(Env) && "Path does not exist!");
1528 ModulesCachePath = Env.str();
1529 } else {
1531 }
1532
1533 clingArgsStorage.push_back("-fmodules-cache-path=" + ModulesCachePath);
1534 }
1535
1536 std::vector<const char*> interpArgs;
1537 for (std::vector<std::string>::const_iterator iArg = clingArgsStorage.begin(),
1539 interpArgs.push_back(iArg->c_str());
1540
1541 // Activate C++ modules support. If we are running within rootcling, it's up
1542 // to rootcling to set this flag depending on whether it wants to produce
1543 // C++ modules.
1545 if (fCxxModulesEnabled) {
1546 if (!fromRootCling) {
1547 // We only set this flag, rest is done by the CIFactory.
1548 interpArgs.push_back("-fmodules");
1549 interpArgs.push_back("-fno-implicit-module-maps");
1550 // We should never build modules during runtime, so let's enable the
1551 // module build remarks from clang to make it easier to spot when we do
1552 // this by accident.
1553 interpArgs.push_back("-Rmodule-build");
1554 }
1555 // ROOT implements its AutoLoading upon module's link directives. We
1556 // generate module A { header "A.h" link "A.so" export * } where ROOT's
1557 // facilities use the link directive to dynamically load the relevant
1558 // library. So, we need to suppress clang's default autolink behavior.
1559 interpArgs.push_back("-fno-autolink");
1560 }
1561
1562#ifdef R__FAST_MATH
1563 // Same setting as in rootcling_impl.cxx.
1564 interpArgs.push_back("-ffast-math");
1565#endif
1566
1568 // Add statically injected extra arguments, usually coming from rootcling.
1569 for (const char** extraArgs = TROOT::GetExtraInterpreterArgs();
1570 extraArgs && *extraArgs; ++extraArgs) {
1571 if (!strcmp(*extraArgs, "-resource-dir")) {
1572 // Take the next arg as the llvm resource directory.
1574 } else {
1575 interpArgs.push_back(*extraArgs);
1576 }
1577 }
1578
1579 std::vector<std::string> _empty;
1581 for (const auto &arg: args)
1582 interpArgs.emplace_back(arg.c_str());
1583
1584 // Add the Rdict module file extension.
1585 cling::Interpreter::ModuleFileExtensions extensions;
1586 EnvOpt = llvm::sys::Process::GetEnv("ROOTDEBUG_RDICT");
1587 if (!EnvOpt.has_value())
1588 extensions.push_back(std::make_shared<TClingRdictModuleFileExtension>());
1589
1590 fInterpreter = std::make_unique<cling::Interpreter>(interpArgs.size(),
1591 &(interpArgs[0]),
1594
1595 if (!fInterpreter->getCI()) { // Compiler instance could not be created. See https://its.cern.ch/jira/browse/ROOT-10239
1596 return;
1597 }
1598
1599 // Tell CppInterOp that the cling::Interpreter instance is managed externally by ROOT
1600 // Sets the interpreter by passing the fInterpreter handle as soon as TCling is initialized
1601 if (!IsFromRootCling())
1602 Cpp::UseExternalInterpreter(fInterpreter.get());
1603
1604 // Don't check whether modules' files exist.
1605 fInterpreter->getCI()->getPreprocessorOpts().DisablePCHOrModuleValidation =
1606 DisableValidationForModuleKind::All;
1607
1608 // Until we can disable AutoLoading during Sema::CorrectTypo() we have
1609 // to disable spell checking.
1610 fInterpreter->getCI()->getLangOpts().SpellChecking = false;
1611
1612 // Sync modules on/off between clang and us: clang turns it on for C++ >= 20.
1613 auto isModulesArg = [](const char* arg) { return !strcmp(arg, "-fmodules"); };
1614 bool hasModulesArg = std::find_if(interpArgs.begin(), interpArgs.end(), isModulesArg) != interpArgs.end();
1615 fInterpreter->getCI()->getLangOpts().Modules = hasModulesArg;
1616
1617 // We need stream that doesn't close its file descriptor, thus we are not
1618 // using llvm::outs. Keeping file descriptor open we will be able to use
1619 // the results in pipes (Savannah #99234).
1620 static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO, /*ShouldClose*/false);
1621 fMetaProcessor = std::make_unique<cling::MetaProcessor>(*fInterpreter, fMPOuts);
1622
1625
1626 // We are now ready (enough is loaded) to init the list of opaque typedefs.
1632
1633 // Disallow auto-parsing in rootcling
1635
1636 ResetAll();
1637
1638 // Enable dynamic lookup
1639 if (!fromRootCling) {
1640 fInterpreter->enableDynamicLookup();
1641 }
1642
1643 // Enable ClinG's DefinitionShadower for ROOT.
1644 fInterpreter->getRuntimeOptions().AllowRedefinition = 1;
1645 auto &Policy = const_cast<clang::PrintingPolicy &>(fInterpreter->getCI()->getASTContext().getPrintingPolicy());
1646 // Print 'a<b<c> >' rather than 'a<b<c>>'.
1647 // FIXME: We should probably switch to the default printing policy setting
1648 // after adjusting tons of reference files.
1649 Policy.SplitTemplateClosers = true;
1650 // Keep default templare arguments, required for dictionary generation.
1651 Policy.SuppressDefaultTemplateArgs = false;
1652
1653
1654 // Attach cling callbacks last; they might need TROOT::fInterpreter
1655 // and should thus not be triggered during the equivalent of
1656 // TROOT::fInterpreter = new TCling;
1657 std::unique_ptr<TClingCallbacks>
1661 fInterpreter->setCallbacks(std::move(clingCallbacks));
1662
1663 if (!fromRootCling) {
1664 cling::DynamicLibraryManager& DLM = *fInterpreter->getDynamicLibraryManager();
1665 // Make sure cling looks into ROOT's libdir, even if not part of LD_LIBRARY_PATH
1666 // e.g. because of an RPATH build.
1667 DLM.addSearchPath(TROOT::GetSharedLibDir().Data(), /*isUser=*/true,
1668 /*prepend=*/true);
1669 auto ShouldPermanentlyIgnore = [](llvm::StringRef FileName) -> bool{
1670 llvm::StringRef stem = llvm::sys::path::stem(FileName);
1671 return stem.starts_with("libNew") || stem.starts_with("libcppyy_backend");
1672 };
1673 // Initialize the dyld for AutoloadLibraryGenerator.
1674 DLM.initializeDyld(ShouldPermanentlyIgnore);
1675 }
1676}
1677
1678
1679////////////////////////////////////////////////////////////////////////////////
1680/// Destroy the interpreter interface.
1681
1683{
1684 // ROOT's atexit functions require the interepreter to be available.
1685 // Run them before shutting down.
1686 if (!IsFromRootCling())
1687 GetInterpreterImpl()->runAtExitFuncs();
1688 fIsShuttingDown = true;
1689 delete fMapfile;
1690 delete fRootmapFiles;
1691 delete fTemporaries;
1692 delete fNormalizedCtxt;
1693 delete fLookupHelper;
1694 gCling = nullptr;
1695}
1696
1697////////////////////////////////////////////////////////////////////////////////
1698/// Initialize the interpreter, once TROOT::fInterpreter is set.
1699
1701{
1702 if (!fClingCallbacks) // Compiler instance could not be created. See https://its.cern.ch/jira/browse/ROOT-10239
1703 return;
1705
1706 // We are set up. Enable ROOT's AutoLoading.
1707 if (IsFromRootCling())
1708 return;
1709
1710 // Read the rules before enabling the auto loading to not inadvertently
1711 // load the libraries for the classes concerned even-though the user is
1712 // *not* using them.
1713 // Note this call must happen before the first call to LoadLibraryMap.
1714 assert(GetRootMapFiles() == nullptr && "Must be called before LoadLibraryMap!");
1715 TClass::ReadRules(); // Read the default customization rules ...
1716
1718 SetClassAutoLoading(true);
1719}
1720
1722{
1723 fIsShuttingDown = true;
1724 ResetGlobals();
1725}
1726
1727////////////////////////////////////////////////////////////////////////////////
1728/// Helper to initialize TVirtualStreamerInfo's factor early.
1729/// Use static initialization to insure only one TStreamerInfo is created.
1731{
1732 // Use lambda since SetFactory return void.
1733 auto setFactory = []() {
1735 return kTRUE;
1736 };
1737 static bool doneFactory = setFactory();
1738 return doneFactory; // avoid unused variable warning.
1739}
1740
1741////////////////////////////////////////////////////////////////////////////////
1742/// Register Rdict data for future loading by LoadPCM;
1743
1744void TCling::RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
1745{
1746 if (IsFromRootCling())
1747 return;
1748
1749 if (llvm::sys::fs::exists(pcmFileNameFullPath)) {
1750 ::Error("TCling::RegisterRdictForLoadPCM", "Rdict '%s' is both in Module extension and in File system.", pcmFileNameFullPath.c_str());
1751 return;
1752 }
1753
1754 // The pcmFileNameFullPath must be resolved already because we cannot resolve
1755 // a link to a non-existent file.
1757}
1758
1759////////////////////////////////////////////////////////////////////////////////
1760/// Tries to load a PCM from TFile; returns true on success.
1761/// The caller of this function should be holding the ROOT Write lock.
1762
1764{
1765 auto listOfKeys = pcmFile.GetListOfKeys();
1766
1767 // This is an empty pcm
1768 if (listOfKeys && ((listOfKeys->GetSize() == 0) || // Nothing here, or
1769 ((listOfKeys->GetSize() == 1) && // only one, and
1770 !strcmp(((TKey *)listOfKeys->At(0))->GetName(), "EMPTY") // name is EMPTY
1771 ))) {
1772 return;
1773 }
1774
1776 if (gDebug > 1)
1777 ::Info("TCling::LoadPCMImpl", "reading protoclasses for %s \n", pcmFile.GetName());
1778
1780 pcmFile.GetObject("__Enums", enums);
1781 if (enums) {
1782 // Cache the pointers
1783 auto listOfGlobals = gROOT->GetListOfGlobals();
1784 auto listOfEnums = dynamic_cast<THashList *>(gROOT->GetListOfEnums());
1785 // Loop on enums and then on enum constants
1786 for (auto selEnum : *enums) {
1787 const char *enumScope = selEnum->GetTitle();
1788 const char *enumName = selEnum->GetName();
1789 if (strcmp(enumScope, "") == 0) {
1790 // This is a global enum and is added to the
1791 // list of enums and its constants to the list of globals
1792 if (!listOfEnums->THashList::FindObject(enumName)) {
1793 ((TEnum *)selEnum)->SetClass(nullptr);
1794 listOfEnums->Add(selEnum);
1795 }
1796 for (auto enumConstant : *static_cast<TEnum *>(selEnum)->GetConstants()) {
1797 if (!listOfGlobals->FindObject(enumConstant)) {
1799 }
1800 }
1801 } else {
1802 // This enum is in a namespace. A TClass entry is bootstrapped if
1803 // none exists yet and the enum is added to it
1805 if (!nsTClassEntry) {
1807 }
1808 auto listOfEnums = nsTClassEntry->fEnums.load();
1809 if (!listOfEnums) {
1810 if ((kIsClass | kIsStruct | kIsUnion) & nsTClassEntry->Property()) {
1811 // For this case, the list will be immutable once constructed
1812 // (i.e. in this case, by the end of this routine).
1814 } else {
1815 // namespaces can have enums added to them
1817 }
1818 }
1819 if (listOfEnums && !listOfEnums->THashList::FindObject(enumName)) {
1820 ((TEnum *)selEnum)->SetClass(nsTClassEntry);
1821 listOfEnums->Add(selEnum);
1822 }
1823 }
1824 }
1825 enums->Clear();
1826 delete enums;
1827 }
1828
1829 pcmFile.GetObject("__ProtoClasses", protoClasses);
1830
1831 if (protoClasses) {
1832 for (auto obj : *protoClasses) {
1833 TProtoClass *proto = (TProtoClass *)obj;
1835 }
1836 // Now that all TClass-es know how to set them up we can update
1837 // existing TClasses, which might cause the creation of e.g. TBaseClass
1838 // objects which in turn requires the creation of TClasses, that could
1839 // come from the PCH, but maybe later in the loop. Instead of resolving
1840 // a dependency graph the addition to the TClassTable above allows us
1841 // to create these dependent TClasses as needed below.
1842 for (auto proto : *protoClasses) {
1843 if (TClass *existingCl = (TClass *)gROOT->GetListOfClasses()->FindObject(proto->GetName())) {
1844 // We have an existing TClass object. It might be emulated
1845 // or interpreted; we now have more information available.
1846 // Make that available.
1847 if (existingCl->GetState() != TClass::kHasTClassInit) {
1848 DictFuncPtr_t dict = gClassTable->GetDict(proto->GetName());
1849 if (!dict) {
1850 ::Error("TCling::LoadPCM", "Inconsistent TClassTable for %s", proto->GetName());
1851 } else {
1852 // This will replace the existing TClass.
1853 TClass *ncl = (*dict)();
1854 if (ncl)
1855 ncl->PostLoadCheck();
1856 }
1857 }
1858 }
1859 }
1860
1861 protoClasses->Clear(); // Ownership was transferred to TClassTable.
1862 delete protoClasses;
1863 }
1864
1866 pcmFile.GetObject("__Typedefs", dataTypes);
1867 if (dataTypes) {
1868 for (auto typedf : *dataTypes)
1869 gROOT->GetListOfTypes()->Add(typedf);
1870 dataTypes->Clear(); // Ownership was transferred to TListOfTypes.
1871 delete dataTypes;
1872 }
1873}
1874
1875////////////////////////////////////////////////////////////////////////////////
1876/// Tries to load a rdict PCM, issues diagnostics if it fails.
1877/// The caller of this function should be holding the ROOT Write lock.
1878
1880{
1883 assert(!pcmFileNameFullPath.empty());
1884 assert(llvm::sys::path::is_absolute(pcmFileNameFullPath));
1885
1886 // Easier to work with the ROOT interfaces.
1888
1889 // Prevent the ROOT-PCMs hitting this during auto-load during
1890 // JITting - which will cause recursive compilation.
1891 // Avoid to call the plugin manager at all.
1893
1895 llvm::SaveAndRestore<Int_t> SaveGDebug(gDebug);
1896 if (gDebug > 5) {
1897 gDebug -= 5;
1898 ::Info("TCling::LoadPCM", "Loading ROOT PCM %s", pcmFileName.Data());
1899 } else {
1900 gDebug = 0;
1901 }
1902
1903 if (llvm::sys::fs::is_symlink_file(pcmFileNameFullPath))
1905
1907 if (pendingRdict != fPendingRdicts.end()) {
1908 llvm::StringRef pcmContent = pendingRdict->second;
1910 std::string RDictFileOpts = pcmFileNameFullPath + "?filetype=pcm";
1912
1913 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
1915 // Currently the module file are never unloaded (even if the library is
1916 // unloaded) and, of course, never reloaded.
1917 // Consequently, we must NOT remove the `pendingRdict` from the list
1918 // of pending dictionary, otherwise if a library is unloaded and then
1919 // reload we will be unable to update properly the TClass object
1920 // (because we wont be able to load the rootpcm file by executing the
1921 // above lines)
1922
1923 return;
1924 }
1925
1926 if (!llvm::sys::fs::exists(pcmFileNameFullPath)) {
1927 ::Error("TCling::LoadPCM", "ROOT PCM %s file does not exist",
1928 pcmFileNameFullPath.data());
1929 if (!fPendingRdicts.empty())
1930 for (const auto &rdict : fPendingRdicts)
1931 ::Info("TCling::LoadPCM", "In-memory ROOT PCM candidate %s\n",
1932 rdict.first.c_str());
1933 return;
1934 }
1935
1936 if (!gROOT->IsRootFile(pcmFileName)) {
1937 Fatal("LoadPCM", "The file %s is not a ROOT as was expected\n", pcmFileName.Data());
1938 return;
1939 }
1940 TFile pcmFile(pcmFileName + "?filetype=pcm", "READ");
1942}
1943
1944//______________________________________________________________________________
1945
1946namespace {
1947 using namespace clang;
1948
1949 class ExtLexicalStorageAdder: public RecursiveASTVisitor<ExtLexicalStorageAdder>{
1950 // This class is to be considered an helper for autoparsing.
1951 // It visits the AST and marks all classes (in all of their redeclarations)
1952 // with the setHasExternalLexicalStorage method.
1953 public:
1954 bool VisitRecordDecl(clang::RecordDecl* rcd){
1955 if (gDebug > 2)
1956 Info("ExtLexicalStorageAdder",
1957 "Adding external lexical storage to class %s",
1958 rcd->getNameAsString().c_str());
1959 auto reDeclPtr = rcd->getMostRecentDecl();
1960 do {
1961 reDeclPtr->setHasExternalLexicalStorage();
1962 } while ((reDeclPtr = reDeclPtr->getPreviousDecl()));
1963
1964 return false;
1965 }
1966 };
1967
1968
1969}
1970
1971////////////////////////////////////////////////////////////////////////////////
1972///\returns true if the module map was loaded, false on error or if the map was
1973/// already loaded.
1975 const std::string &ModuleMapName /*= "module.modulemap"*/) const
1976{
1977 assert(llvm::sys::path::is_absolute(FullPath));
1978 Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
1979 FileManager &FM = PP.getFileManager();
1980 // FIXME: In a ROOT session we can add an include path (through .I /inc/path)
1981 // We should look for modulemap files there too.
1982 if (auto DE = FM.getOptionalDirectoryRef(FullPath)) {
1983 HeaderSearch &HS = PP.getHeaderSearchInfo();
1984 HeaderSearchOptions &HSOpts = const_cast<HeaderSearchOptions&>(HS.getHeaderSearchOpts());
1985 const auto &ModPaths = HSOpts.PrebuiltModulePaths;
1986 bool pathExists = std::find(ModPaths.begin(), ModPaths.end(), FullPath) != ModPaths.end();
1987 if (!pathExists)
1988 HSOpts.AddPrebuiltModulePath(FullPath);
1989 // We cannot use HS.lookupModuleMapFile(DE, /*IsFramework*/ false);
1990 // because its internal call to getFile has CacheFailure set to true.
1991 // In our case, modulemaps can appear any time due to ACLiC.
1992 // Code copied from HS.lookupModuleMapFile.
1993 llvm::SmallString<256> ModuleMapFileName(DE->getName());
1994 llvm::sys::path::append(ModuleMapFileName, ModuleMapName);
1995 if (auto FE = FM.getOptionalFileRef(ModuleMapFileName, /*openFile*/ false,
1996 /*CacheFailure*/ false)) {
1997 if (!HS.parseAndLoadModuleMapFile(*FE, /*IsSystem*/ false))
1998 return true;
1999 Error("RegisterPrebuiltModulePath", "Could not load modulemap in %s", ModuleMapFileName.c_str());
2000 }
2001 }
2002 return false;
2003}
2004
2005////////////////////////////////////////////////////////////////////////////////
2006/// List of dicts that have the PCM information already in the PCH.
2007static const std::unordered_set<std::string> gIgnoredPCMNames = {"libCore",
2008 "libRint",
2009 "libThread",
2010 "libRIO",
2011 "libImt",
2012 "libMultiProc",
2013 "libcomplexDict",
2014 "libdequeDict",
2015 "liblistDict",
2016 "libforward_listDict",
2017 "libvectorDict",
2018 "libmapDict",
2019 "libmultimap2Dict",
2020 "libmap2Dict",
2021 "libmultimapDict",
2022 "libsetDict",
2023 "libmultisetDict",
2024 "libunordered_setDict",
2025 "libunordered_multisetDict",
2026 "libunordered_mapDict",
2027 "libunordered_multimapDict",
2028 "libvalarrayDict",
2029 "G__GenVector32",
2030 "G__Smatrix32"};
2031
2032static void PrintDlError(const char *dyLibName, const char *modulename)
2033{
2034#ifdef R__WIN32
2035 char dyLibError[1000];
2037 dyLibError, sizeof(dyLibError), NULL);
2038#else
2039 const char *dyLibError = dlerror();
2040#endif
2041 ::Error("TCling::RegisterModule", "Cannot open shared library %s for dictionary %s:\n %s", dyLibName, modulename,
2042 (dyLibError) ? dyLibError : "");
2043}
2044
2045////////////////////////////////////////////////////////////////////////////////
2046// Update all the TClass registered in fClassesToUpdate
2047
2049{
2050 while (!fClassesToUpdate.empty()) {
2051 TClass *oldcl = fClassesToUpdate.back().first;
2052 // If somehow the TClass has already been loaded (maybe it was registered several time),
2053 // we skip it. Otherwise, the existing TClass is in mode kInterpreted, kEmulated or
2054 // maybe even kForwardDeclared and needs to replaced.
2055 if (oldcl->GetState() != TClass::kHasTClassInit) {
2056 // if (gDebug > 2) Info("RegisterModule", "Forcing TClass init for %s", oldcl->GetName());
2057 DictFuncPtr_t dict = fClassesToUpdate.back().second;
2058 fClassesToUpdate.pop_back();
2059 // Calling func could manipulate the list so, let maintain the list
2060 // then call the dictionary function.
2061 TClass *ncl = dict();
2062 if (ncl) ncl->PostLoadCheck();
2063 } else {
2064 fClassesToUpdate.pop_back();
2065 }
2066 }
2067}
2068////////////////////////////////////////////////////////////////////////////////
2069/// Inject the module named "modulename" into cling; load all headers.
2070/// headers is a 0-terminated array of header files to `#include` after
2071/// loading the module. The module is searched for in all $LD_LIBRARY_PATH
2072/// entries (or %PATH% on Windows).
2073/// This function gets called by the static initialization of dictionary
2074/// libraries.
2075/// The payload code is injected "as is" in the interpreter.
2076/// The value of 'triggerFunc' is used to find the shared library location.
2077/// The caller of this function should be holding the ROOT Write lock.
2078
2080 const char** headers,
2081 const char** includePaths,
2082 const char* payloadCode,
2083 const char* fwdDeclsCode,
2084 void (*triggerFunc)(),
2086 const char** classesHeaders,
2087 Bool_t lateRegistration /*=false*/,
2088 Bool_t hasCxxModule /*=false*/)
2089{
2090 const bool fromRootCling = IsFromRootCling();
2091 // We need the dictionary initialization but we don't want to inject the
2092 // declarations into the interpreter, except for those we really need for
2093 // I/O; see rootcling.cxx after the call to TCling__GetInterpreter().
2094 if (fromRootCling) return;
2095
2096 // When we cannot provide a module for the library we should enable header
2097 // parsing. This 'mixed' mode ensures gradual migration to modules.
2098 llvm::SaveAndRestore<bool> SaveHeaderParsing(fHeaderParsingOnDemand);
2100
2101 // Treat Aclic Libs in a special way. Do not delay the parsing.
2103 bool isACLiC = strstr(modulename, "_ACLiC_dict") != nullptr;
2105 if (gDebug>1)
2106 Info("TCling::RegisterModule",
2107 "Header parsing on demand is active but this is an Aclic library. Disabling it for this library.");
2109 }
2110
2111
2112 // Make sure we relookup symbols that were search for before we loaded
2113 // their autoparse information. We could be more subtil and remove only
2114 // the failed one or only the one in this module, but for now this is
2115 // better than nothing.
2116 fLookedUpClasses.clear();
2117
2118 // Make sure we do not set off AutoLoading or autoparsing during the
2119 // module registration!
2121
2122 for (const char** inclPath = includePaths; *inclPath; ++inclPath) {
2124 }
2125 cling::Transaction* T = nullptr;
2126 // Put the template decls and the number of arguments to skip in the TNormalizedCtxt
2128 const std::string& fwdDecl = fwdDeclArgToSkipPair.first;
2129 const int nArgsToSkip = fwdDeclArgToSkipPair.second;
2130 auto compRes = fInterpreter->declare(fwdDecl.c_str(), &T);
2131 assert(cling::Interpreter::kSuccess == compRes &&
2132 "A fwd declaration could not be compiled");
2133 if (compRes!=cling::Interpreter::kSuccess){
2134 Warning("TCling::RegisterModule",
2135 "Problems in declaring string '%s' were encountered.",
2136 fwdDecl.c_str()) ;
2137 continue;
2138 }
2139
2140 // Drill through namespaces recursively until the template is found
2141 if(ClassTemplateDecl* TD = FindTemplateInNamespace(T->getFirstDecl().getSingleDecl())){
2143 }
2144
2145 }
2146
2147 // FIXME: Remove #define __ROOTCLING__ once PCMs are there.
2148 // This is used to give Sema the same view on ACLiC'ed files (which
2149 // are then #included through the dictionary) as rootcling had.
2151 if (payloadCode)
2152 code += payloadCode;
2153
2154 std::string dyLibName = cling::DynamicLibraryManager::getSymbolLocation(triggerFunc);
2155 assert(!llvm::sys::fs::is_symlink_file(dyLibName));
2156
2157 if (dyLibName.empty()) {
2158 ::Error("TCling::RegisterModule", "Dictionary trigger function for %s not found", modulename);
2159 return;
2160 }
2161
2162 // The triggerFunc may not be in a shared object but in an executable.
2163 bool isSharedLib = cling::DynamicLibraryManager::isSharedLibrary(dyLibName);
2164
2165 bool wasDlopened = false;
2166
2167 // If this call happens after dlopen has finished (i.e. late registration)
2168 // there is no need to dlopen the library recursively. See ROOT-8437 where
2169 // the dyLibName would correspond to the binary.
2170 if (!lateRegistration) {
2171
2172 if (isSharedLib) {
2173 // We need to open the dictionary shared library, to resolve symbols
2174 // requested by the JIT from it: as the library is currently being dlopen'ed,
2175 // its symbols are not yet reachable from the process.
2176 // Recursive dlopen seems to work just fine.
2177 void* dyLibHandle = dlopen(dyLibName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
2178 if (dyLibHandle) {
2180 wasDlopened = true;
2181 } else {
2183 }
2184 }
2185 } // if (!lateRegistration)
2186
2188 // We now parse the forward declarations. All the classes are then modified
2189 // in order for them to have an external lexical storage.
2190 std::string fwdDeclsCodeLessEnums;
2191 {
2192 // Search for enum forward decls and only declare them if no
2193 // declaration exists yet.
2194 std::string fwdDeclsLine;
2195 std::istringstream fwdDeclsCodeStr(fwdDeclsCode);
2196 std::vector<std::string> scopes;
2197 while (std::getline(fwdDeclsCodeStr, fwdDeclsLine)) {
2198 const auto enumPos = fwdDeclsLine.find("enum __attribute__((annotate(\"");
2199 // We check if the line contains a fwd declaration of an enum
2200 if (enumPos != std::string::npos) {
2201 // We clear the scopes which we may have carried from a previous iteration
2202 scopes.clear();
2203 // We check if the enum is not in a scope. If yes, save its name
2204 // and the names of the enclosing scopes.
2205 if (enumPos != 0) {
2206 // it's enclosed in namespaces. We need to understand what they are
2207 auto nsPos = fwdDeclsLine.find("namespace");
2208 R__ASSERT(nsPos < enumPos && "Inconsistent enum and enclosing scope parsing!");
2209 while (nsPos < enumPos && nsPos != std::string::npos) {
2210 // we have a namespace, let's put it in the collection of scopes
2211 const auto nsNameStart = nsPos + 10;
2212 const auto nsNameEnd = fwdDeclsLine.find('{', nsNameStart);
2213 const auto nsName = fwdDeclsLine.substr(nsNameStart, nsNameEnd - nsNameStart);
2214 scopes.push_back(nsName);
2215 nsPos = fwdDeclsLine.find("namespace", nsNameEnd);
2216 }
2217 }
2218 clang::DeclContext* DC = nullptr;
2219 for (auto &&aScope: scopes) {
2220 DC = cling::utils::Lookup::Namespace(&fInterpreter->getSema(), aScope.c_str(), DC);
2221 if (!DC) {
2222 // No decl context means we have to fwd declare the enum.
2223 break;
2224 }
2225 }
2226 if (scopes.empty() || DC) {
2227 // We know the scope; let's look for the enum. For that, look
2228 // for the *last* closing parentheses of an attribute because
2229 // there can be multiple.
2230 size_t posEnumName = fwdDeclsLine.rfind("\"))) ");
2231 R__ASSERT(posEnumName != std::string::npos && "Inconsistent enum fwd decl!");
2232 posEnumName += 5; // skip "\"))) "
2234 ++posEnumName;
2235 size_t posEnumNameEnd = fwdDeclsLine.find(" : ", posEnumName);
2236 R__ASSERT(posEnumNameEnd != std::string::npos && "Inconsistent enum fwd decl (end)!");
2239 // posEnumNameEnd now points to the last character of the name.
2240
2241 std::string enumName = fwdDeclsLine.substr(posEnumName,
2243
2244 if (clang::NamedDecl* enumDecl
2245 = cling::utils::Lookup::Named(&fInterpreter->getSema(),
2246 enumName.c_str(), DC)) {
2247 // We have an existing enum decl (forward or definition);
2248 // skip this.
2249 R__ASSERT(llvm::dyn_cast<clang::EnumDecl>(enumDecl) && "not an enum decl!");
2250 (void)enumDecl;
2251 continue;
2252 }
2253 }
2254 }
2255
2257 }
2258 }
2259
2260 if (!fwdDeclsCodeLessEnums.empty()){ // Avoid the overhead if nothing is to be declared
2261 auto compRes = fInterpreter->declare(fwdDeclsCodeLessEnums, &T);
2262 assert(cling::Interpreter::kSuccess == compRes &&
2263 "The forward declarations could not be compiled");
2264 if (compRes!=cling::Interpreter::kSuccess){
2265 Warning("TCling::RegisterModule",
2266 "Problems in compiling forward declarations for module %s: '%s'",
2268 }
2269 else if (T){
2270 // Loop over all decls in the transaction and go through them all
2271 // to mark them properly.
2272 // In order to do that, we first iterate over all the DelayedCallInfos
2273 // within the transaction. Then we loop over all Decls in the DeclGroupRef
2274 // contained in the DelayedCallInfos. For each decl, we traverse.
2275 ExtLexicalStorageAdder elsa;
2276 for (auto dciIt = T->decls_begin();dciIt!=T->decls_end();dciIt++){
2277 cling::Transaction::DelayCallInfo& dci = *dciIt;
2278 for(auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) {
2279 clang::Decl* declPtr = *dit;
2280 elsa.TraverseDecl(declPtr);
2281 }
2282 }
2283 }
2284 }
2285
2286 // Now we register all the headers necessary for the class
2287 // Typical format of the array:
2288 // {"A", "classes.h", "@",
2289 // "vector<A>", "vector", "@",
2290 // "myClass", payloadCode, "@",
2291 // nullptr};
2292
2293 std::string temp;
2294 for (const char** classesHeader = classesHeaders; *classesHeader; ++classesHeader) {
2295 temp=*classesHeader;
2296
2297 size_t theTemplateHash = 0;
2298 bool addTemplate = false;
2299 size_t posTemplate = temp.find('<');
2300 if (posTemplate != std::string::npos) {
2301 // Add an entry for the template itself.
2302 std::string templateName = temp.substr(0, posTemplate);
2304 addTemplate = true;
2305 }
2306 size_t theHash = fStringHashFunction(temp);
2307 classesHeader++;
2309 // This is done in order to distinguish headers from files and from the payloadCode
2311 fPayloads.insert(theHash);
2313 }
2314 if (gDebug > 2)
2315 Info("TCling::RegisterModule",
2316 "Adding a header for %s", temp.c_str());
2318 if (addTemplate) {
2321 }
2322 addTemplate = false;
2323 }
2324 }
2325 }
2326 }
2327
2328 clang::Sema &TheSema = fInterpreter->getSema();
2329
2330 bool ModuleWasSuccessfullyLoaded = false;
2331 if (hasCxxModule) {
2332 std::string ModuleName = modulename;
2333 if (llvm::StringRef(modulename).starts_with("lib"))
2334 ModuleName = llvm::StringRef(modulename).substr(3).str();
2335
2336 // In case we are directly loading the library via gSystem->Load() without
2337 // specifying the relevant include paths we should try loading the
2338 // modulemap next to the library location.
2339 clang::Preprocessor &PP = TheSema.getPreprocessor();
2340 std::string ModuleMapName;
2341 if (isACLiC)
2342 ModuleMapName = ModuleName + ".modulemap";
2343 else
2344 ModuleMapName = "module.modulemap";
2345 RegisterPrebuiltModulePath(llvm::sys::path::parent_path(dyLibName).str(),
2347
2348 // FIXME: We should only complain for modules which we know to exist. For example, we should not complain about
2349 // modules such as GenVector32 because it needs to fall back to GenVector.
2350 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2353 // Only report if we found the module in the modulemap.
2354 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
2355 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
2356 if (moduleMap.findModule(ModuleName))
2357 Info("TCling::RegisterModule", "Module %s in modulemap failed to load.", ModuleName.c_str());
2358 }
2359 }
2360
2362 llvm::SmallString<256> pcmFileNameFullPath(dyLibName);
2363 // The path dyLibName might not be absolute. This can happen if dyLibName
2364 // is linked to an executable in the same folder.
2365 llvm::sys::fs::make_absolute(pcmFileNameFullPath);
2366 llvm::sys::path::remove_filename(pcmFileNameFullPath);
2367 llvm::sys::path::append(pcmFileNameFullPath,
2369 // A library built with C++ modules may ship only its .pcm and no
2370 // <lib>_rdict.pcm (the dictionary payload then lives in the C++ module).
2371 // In that case probing the legacy rootpcm makes LoadPCM emit a spurious
2372 // "ROOT PCM ... file does not exist" error followed by an in-memory
2373 // candidate dump. Skip the probe only when the C++ module was loaded AND
2374 // there is genuinely no rootpcm to load -- neither registered in-memory
2375 // (an embedded rdict, the check mirrors LoadPCM) nor present on disk. For
2376 // libraries without a C++ module the behaviour is unchanged, so a truly
2377 // missing rootpcm is still reported.
2378 std::string pcmPath = pcmFileNameFullPath.str().str();
2379 std::string pcmRealPath = llvm::sys::fs::is_symlink_file(pcmPath)
2381 : pcmPath;
2383 llvm::sys::fs::exists(pcmRealPath))
2385 }
2386
2387 { // scope within which diagnostics are de-activated
2388 // For now we disable diagnostics because we saw them already at
2389 // dictionary generation time. That won't be an issue with the PCMs.
2390
2391 clangDiagSuppr diagSuppr(TheSema.getDiagnostics());
2392
2393#if defined(R__MUST_REVISIT)
2394#if R__MUST_REVISIT(6,2)
2395 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
2396#endif
2397#endif
2398
2401
2402 const cling::Transaction* watermark = fInterpreter->getLastTransaction();
2403 cling::Interpreter::CompilationResult compRes = fInterpreter->parseForModule(code.Data());
2404 if (isACLiC) {
2405 // Register an unload point.
2406 fMetaProcessor->registerUnloadPoint(watermark, headers[0]);
2407 }
2408
2409 assert(cling::Interpreter::kSuccess == compRes &&
2410 "Payload code of a dictionary could not be parsed correctly.");
2411 if (compRes!=cling::Interpreter::kSuccess) {
2412 Warning("TCling::RegisterModule",
2413 "Problems declaring payload for module %s.", modulename) ;
2414 }
2415 }
2416 }
2417
2418 // Now that all the header have been registered/compiled, let's
2419 // make sure to 'reset' the TClass that have a class init in this module
2420 // but already had their type information available (using information/header
2421 // loaded from other modules or from class rules or from opening a TFile
2422 // or from loading header in a way that did not provoke the loading of
2423 // the library we just loaded).
2425
2427 // __ROOTCLING__ might be pulled in through PCH
2428 fInterpreter->declare("#ifdef __ROOTCLING__\n"
2429 "#undef __ROOTCLING__\n"
2431 "#endif");
2432 }
2433
2434 if (wasDlopened) {
2436 void* dyLibHandle = fRegisterModuleDyLibs.back();
2437 fRegisterModuleDyLibs.pop_back();
2439 }
2440}
2441
2443 clang::CompilerInstance& CI = *GetInterpreterImpl()->getCI();
2444 ASTContext &C = CI.getASTContext();
2445
2446 // Do not do anything if we have no global module index.
2447 // FIXME: This is mostly to real with false positives in the TTabCom
2448 // interface for non-modules.
2449 if (!fCxxModulesEnabled)
2450 return;
2451
2452 if (IdentifierInfoLookup *External = C.Idents.getExternalIdentifierLookup()) {
2453 std::unique_ptr<IdentifierIterator> Iter(External->getIdentifiers());
2454 for (llvm::StringRef Ident = Iter->Next(); !Ident.empty(); Ident = Iter->Next()) {
2455 std::string I = Ident.str();
2456 if (!Idents.Contains(I.data()))
2457 Idents.Add(new TObjString(I.c_str()));
2458 }
2459 }
2460}
2461
2462
2463////////////////////////////////////////////////////////////////////////////////
2464/// Register classes that already existed prior to their dictionary loading
2465/// and that already had a ClassInfo (and thus would not be refresh via
2466/// UpdateClassInfo.
2467
2469{
2470 fClassesToUpdate.push_back(std::make_pair(oldcl,dict));
2471}
2472
2473////////////////////////////////////////////////////////////////////////////////
2474/// If the dictionary is loaded, we can remove the class from the list
2475/// (otherwise the class might be loaded twice).
2476
2478{
2479 typedef std::vector<std::pair<TClass*,DictFuncPtr_t> >::iterator iterator;
2480 iterator stop = fClassesToUpdate.end();
2481 for(iterator i = fClassesToUpdate.begin();
2482 i != stop;
2483 ++i)
2484 {
2485 if ( i->first == oldcl ) {
2486 fClassesToUpdate.erase(i);
2487 return;
2488 }
2489 }
2490}
2491
2492
2493////////////////////////////////////////////////////////////////////////////////
2494/// Let cling process a command line.
2495///
2496/// If the command is executed and the error is 0, then the return value
2497/// is the int value corresponding to the result of the executed command
2498/// (float and double return values will be truncated).
2499///
2500
2501// Method for handling the interpreter exceptions.
2502// the MetaProcessor is passing in as argument to teh function, because
2503// cling::Interpreter::CompilationResult is a nested class and it cannot be
2504// forward declared, thus this method cannot be a static member function
2505// of TCling.
2506
2507static int HandleInterpreterException(cling::MetaProcessor* metaProcessor,
2508 const char* input_line,
2509 cling::Interpreter::CompilationResult& compRes,
2510 cling::Value* result)
2511{
2512 try {
2513 return metaProcessor->process(input_line, compRes, result);
2514 }
2515 catch (cling::InterpreterException& ex)
2516 {
2517 Error("HandleInterpreterException", "%s\n%s", ex.what(), "Execution of your code was aborted.");
2518 ex.diagnose();
2519 compRes = cling::Interpreter::kFailure;
2520 }
2521 return 0;
2522}
2523
2524////////////////////////////////////////////////////////////////////////////////
2525
2526bool TCling::DiagnoseIfInterpreterException(const std::exception &e) const
2527{
2528 if (auto ie = dynamic_cast<const cling::InterpreterException*>(&e)) {
2529 ie->diagnose();
2530 return true;
2531 }
2532 return false;
2533}
2534
2535////////////////////////////////////////////////////////////////////////////////
2536
2538{
2539 // Copy the passed line, it comes from a static buffer in TApplication
2540 // which can be reentered through the Cling evaluation routines,
2541 // which would overwrite the static buffer and we would forget what we
2542 // were doing.
2543 //
2545 if (strstr(line,fantomline)) {
2546 // End-Of-Line action
2547 // See the comment (copied from above):
2548 // It is a "fantom" method to synchronize user keyboard input
2549 // and ROOT prompt line (for WIN32)
2550 // and is implemented by
2551 if (gApplication) {
2552 if (gApplication->IsCmdThread()) {
2554 gROOT->SetLineIsProcessing();
2555
2557
2558 gROOT->SetLineHasBeenProcessed();
2559 }
2560 }
2561 return 0;
2562 }
2563
2565 gGlobalMutex->Lock();
2566 if (!gInterpreterMutex)
2569 }
2571 gROOT->SetLineIsProcessing();
2572
2573 struct InterpreterFlagsRAII {
2574 cling::Interpreter* fInterpreter;
2576
2577 InterpreterFlagsRAII(cling::Interpreter* interp):
2578 fInterpreter(interp),
2579 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2580 {
2581 fInterpreter->enableDynamicLookup(true);
2582 }
2584 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2585 gROOT->SetLineHasBeenProcessed();
2586 }
2588
2589 // A non-zero returned value means the given line was
2590 // not a complete statement.
2591 int indent = 0;
2592 // This will hold the resulting value of the evaluation the given line.
2593 cling::Value result;
2594 cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess;
2595 if (!strncmp(sLine.Data(), ".L", 2) || !strncmp(sLine.Data(), ".x", 2) ||
2596 !strncmp(sLine.Data(), ".X", 2)) {
2597 // If there was a trailing "+", then CINT compiled the code above,
2598 // and we will need to strip the "+" before passing the line to cling.
2601 TString arguments;
2602 TString io;
2604 aclicMode, arguments, io);
2605 if (aclicMode.Length()) {
2606 // Remove the leading '+'
2607 R__ASSERT(aclicMode[0]=='+' && "ACLiC mode must start with a +");
2608 aclicMode[0]='k'; // We always want to keep the .so around.
2609 if (aclicMode[1]=='+') {
2610 // We have a 2nd +
2611 aclicMode[1]='f'; // We want to force the recompilation.
2612 }
2614 // ACLiC failed.
2615 compRes = cling::Interpreter::kFailure;
2616 } else {
2617 if (strncmp(sLine.Data(), ".L", 2) != 0) {
2618 // if execution was requested.
2619
2620 if (arguments.Length() == 0) {
2621 arguments = "()";
2622 }
2623 // We need to remove the extension.
2624 Ssiz_t ext = fname.Last('.');
2625 if (ext != kNPOS) {
2626 fname.Remove(ext);
2627 }
2628 const char *function = gSystem->BaseName(fname);
2629 mod_line = function + arguments + io;
2631 }
2632 }
2633 } else if (cling::DynamicLibraryManager::isSharedLibrary(fname.Data()) &&
2634 strncmp(sLine.Data(), ".L", 2) != 0) { // .x *.so or *.dll
2635 if (gSystem->Load(fname) < 0) {
2636 // Loading failed.
2637 compRes = cling::Interpreter::kFailure;
2638 } else {
2639 if (arguments.Length() == 0) {
2640 arguments = "()";
2641 }
2642 // We need to remove the extension. (*.so or *.dll)
2643 Ssiz_t ext = fname.Last('.');
2644 if (ext != kNPOS) {
2645 fname.Remove(ext);
2646 }
2647 // Now we try to find the 'main' function to run within this shared library
2648 // We distinguish two cases: a library.so with a function library(args),
2649 // or a precompiled ACLiC macro (macro_C.so) with a function macro(args).
2650 // Only in the second case, we need to strip the suffix _C or _cpp from fname.
2651 if (!gInterpreter->GetFunction(nullptr, gSystem->BaseName(fname))) { // AcLiC macro
2652 // We need to remove the automatically appended _ extension when compiling (macro_C from macro.C)
2653 ext = fname.Last('_');
2654 if (ext != kNPOS) {
2655 fname.Remove(ext);
2656 }
2657 }
2658 const char *function = gSystem->BaseName(fname);
2659 mod_line = function + arguments + io;
2661 }
2662 } else {
2663 // neither ACLiC nor run shared-library (.x)
2664 size_t unnamedMacroOpenCurly;
2665 {
2666 std::string code;
2667 std::string codeline;
2668 // Windows requires std::ifstream::binary to properly handle
2669 // CRLF and LF line endings
2670 std::ifstream in(fname, std::ifstream::binary);
2671 while (in) {
2672 std::getline(in, codeline);
2673 code += codeline + "\n";
2674 }
2676 = cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
2677 }
2678
2679 fCurExecutingMacros.push_back(fname);
2680 if (unnamedMacroOpenCurly != std::string::npos) {
2681 compRes = fMetaProcessor->readInputFromFile(fname.Data(), &result,
2683 } else {
2684 // No DynLookup for .x, .L of named macros.
2685 fInterpreter->enableDynamicLookup(false);
2687 }
2688 fCurExecutingMacros.pop_back();
2689 }
2690 } // .L / .X / .x
2691 else {
2692 if (0!=strncmp(sLine.Data(), ".autodict ",10) && sLine != ".autodict") {
2693 // explicitly ignore .autodict without having to support it
2694 // in cling.
2695
2696 // Turn off autoparsing if this is an include directive
2697 bool isInclusionDirective = sLine.Contains("\n#include") || sLine.BeginsWith("#include");
2701 } else {
2703 }
2704 }
2705 }
2706 if (result.isValid())
2708 if (indent) {
2709 if (error)
2710 *error = kProcessing;
2711 return 0;
2712 }
2713 if (error) {
2714 switch (compRes) {
2715 case cling::Interpreter::kSuccess: *error = kNoError; break;
2716 case cling::Interpreter::kFailure: *error = kRecoverable; break;
2717 case cling::Interpreter::kMoreInputExpected: *error = kProcessing; break;
2718 }
2719 }
2720 if (compRes == cling::Interpreter::kSuccess
2721 && result.isValid()
2722 && !result.isVoid())
2723 {
2724 return result.castAs<Longptr_t>();
2725 }
2726 return 0;
2727}
2728
2729////////////////////////////////////////////////////////////////////////////////
2730/// No-op; see TRint instead.
2731
2733{
2734}
2735
2736////////////////////////////////////////////////////////////////////////////////
2737/// Print information about the interpreter.
2738///\param[in] option Selects the type of information to print.
2739///
2740/// List of currently support options:
2741/// - autoparsed: Print the list of classes that triggered autoparsing.
2743{
2744 if (option && *option) {
2745 if (!strcmp(option, "autoparsed")) {
2746 std::cout << "Auto parsed classes:" << std::endl;
2747 for (auto & cls : fAutoParseClasses) {
2748 std::cout << " " << cls << std::endl;
2749 }
2750 } else if (!strcmp(option, "autoloaded")) {
2751 std::cout << "Auto loaded libraries:" << std::endl;
2752 for (auto & lib : fAutoLoadedLibraries) {
2753 std::cout << " " << lib << std::endl;
2754 }
2755 } else {
2756 ::Error("TCling::Print", "Unknown option '%s'", option);
2757 }
2758 } else {
2759 ::Info("TCling::Print", "No options specified");
2760 }
2761}
2762
2763
2764////////////////////////////////////////////////////////////////////////////////
2765/// \brief Add a directory to the list of directories in which the
2766/// interpreter looks for include files.
2767/// \param[in] path The path to the directory.
2768/// \note Only one path item can be specified at a time, i.e. "path1:path2" is
2769/// \b NOT supported.
2770/// \warning Only the path to the directory should be specified, without
2771/// prepending the \c -I prefix, i.e.
2772/// <tt>gCling->AddIncludePath("/path/to/my/includes")</tt>. If the
2773/// \c -I prefix is used it will be ignored.
2774void TCling::AddIncludePath(const char *path)
2775{
2777 // Favorite source of annoyance: gSystem->AddIncludePath() needs "-I",
2778 // gCling->AddIncludePath() does not! Work around that inconsistency:
2779 if (path[0] == '-' && path[1] == 'I')
2780 path += 2;
2781 TString sPath(path);
2783#ifdef _MSC_VER
2784 if (sPath.BeginsWith("/")) {
2785 char drive[3];
2786 snprintf(drive, 3, "%c:", _getdrive() + 'A' - 1);
2787 sPath.Prepend(drive);
2788 }
2789#endif
2790 fInterpreter->AddIncludePath(sPath.Data());
2791}
2792
2793////////////////////////////////////////////////////////////////////////////////
2794/// Visit all members over members, recursing over base classes.
2795
2797 const TClass* cl, Bool_t isTransient)
2798{
2799 if (insp.GetObjectValidity() == TMemberInspector::kUnset) {
2800 insp.SetObjectValidity(obj ? TMemberInspector::kValidObjectGiven
2802 }
2803
2804 if (!cl || cl->GetCollectionProxy()) {
2805 // We do not need to investigate the content of the STL
2806 // collection, they are opaque to us (and details are
2807 // uninteresting).
2808 return;
2809 }
2810
2811 static const TClassRef clRefString("std::string");
2812 if (clRefString == cl) {
2813 // We stream std::string without going through members..
2814 return;
2815 }
2816
2817 if (TClassEdit::IsStdArray(cl->GetName())) {
2818 // We treat std arrays as C arrays
2819 return;
2820 }
2821
2822 const char* cobj = (const char*) obj; // for ptr arithmetics
2823
2824 // Treat the case of std::complex in a special manner. We want to enforce
2825 // the layout of a stl implementation independent class, which is the
2826 // complex as implemented in ROOT5.
2827
2828 // A simple lambda to simplify the code
2829 auto inspInspect = [&] (ptrdiff_t offset){
2830 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_real", cobj, isTransient);
2831 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_imag", cobj + offset, isTransient);
2832 };
2833
2835 switch(complexType) {
2837 {
2838 break;
2839 }
2841 {
2842 inspInspect(sizeof(float));
2843 return;
2844 }
2846 {
2847 inspInspect(sizeof(double));
2848 return;
2849 }
2851 {
2852 inspInspect(sizeof(int));
2853 return;
2854 }
2856 {
2857 inspInspect(sizeof(long));
2858 return;
2859 }
2860 }
2861
2862 static clang::PrintingPolicy
2863 printPol(fInterpreter->getCI()->getLangOpts());
2864 if (printPol.Indentation) {
2865 // not yet initialized
2866 printPol.Indentation = 0;
2867 printPol.SuppressInitializers = true;
2868 }
2869
2870 const char* clname = cl->GetName();
2871 // Printf("Inspecting class %s\n", clname);
2872
2873 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2874 const clang::Decl *scopeDecl = nullptr;
2875 const clang::Type *recordType = nullptr;
2876
2877 if (cl->GetClassInfo()) {
2879 scopeDecl = clingCI->GetDecl();
2880 recordType = clingCI->GetType();
2881 } else {
2882 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2883 // Diags will complain about private classes:
2884 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2885 &recordType);
2886 }
2887 if (!scopeDecl) {
2888 Error("InspectMembers", "Cannot find Decl for class %s", clname);
2889 return;
2890 }
2891 const clang::CXXRecordDecl* recordDecl
2892 = llvm::dyn_cast<const clang::CXXRecordDecl>(scopeDecl);
2893 if (!recordDecl) {
2894 Error("InspectMembers", "Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2895 return;
2896 }
2897
2898 {
2899 // Force possible deserializations first. We need to have no pending
2900 // Transaction when passing control flow to the inspector below (ROOT-7779).
2901 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2902
2903 astContext.getASTRecordLayout(recordDecl);
2904
2905 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2906 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2907 }
2908
2909 const clang::ASTRecordLayout& recLayout
2910 = astContext.getASTRecordLayout(recordDecl);
2911
2912 // TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
2913 // if (proxy && ( proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated ) ) {
2914 // Error("InspectMembers","The TClass for %s has an emulated proxy but we are looking at a compiled version of the collection!\n",
2915 // cl->GetName());
2916 // }
2917 if (cl->Size() != recLayout.getSize().getQuantity()) {
2918 Error("InspectMembers","TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2919 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2920 }
2921
2922 unsigned iNField = 0;
2923 // iterate over fields
2924 // FieldDecls are non-static, else it would be a VarDecl.
2925 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2926 eField = recordDecl->field_end(); iField != eField;
2927 ++iField, ++iNField) {
2928
2929
2930 clang::QualType memberQT = iField->getType();
2931 if (recordType) {
2932 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2934 }
2935 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2936 if (memberQT.isNull()) {
2937 std::string memberName;
2938 llvm::raw_string_ostream stream(memberName);
2939 // Don't trigger fopen of the source file to count lines:
2940 printPol.AnonymousTagLocations = false;
2941 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2942 stream.flush();
2943 Error("InspectMembers",
2944 "Cannot retrieve QualType for member %s while inspecting class %s",
2945 memberName.c_str(), clname);
2946 continue; // skip member
2947 }
2948 const clang::Type* memType = memberQT.getTypePtr();
2949 if (!memType) {
2950 std::string memberName;
2951 llvm::raw_string_ostream stream(memberName);
2952 // Don't trigger fopen of the source file to count lines:
2953 printPol.AnonymousTagLocations = false;
2954 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2955 stream.flush();
2956 Error("InspectMembers",
2957 "Cannot retrieve Type for member %s while inspecting class %s",
2958 memberName.c_str(), clname);
2959 continue; // skip member
2960 }
2961
2962 const clang::Type* memNonPtrType = memType;
2963 Bool_t ispointer = false;
2964 if (memNonPtrType->isPointerType()) {
2965 ispointer = true;
2966 clang::QualType ptrQT
2967 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2968 if (recordType) {
2969 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2971 }
2972 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2973 if (ptrQT.isNull()) {
2974 std::string memberName;
2975 llvm::raw_string_ostream stream(memberName);
2976 // Don't trigger fopen of the source file to count lines:
2977 printPol.AnonymousTagLocations = false;
2978 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2979 stream.flush();
2980 Error("InspectMembers",
2981 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2982 memberName.c_str(), clname);
2983 continue; // skip member
2984 }
2985 memNonPtrType = ptrQT.getTypePtr();
2986 }
2987
2988 // assemble array size(s): "[12][4][]"
2989 llvm::SmallString<8> arraySize;
2990 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2991 unsigned arrLevel = 0;
2992 bool haveErrorDueToArray = false;
2993 while (arrType) {
2994 ++arrLevel;
2995 arraySize += '[';
2996 const clang::ConstantArrayType* constArrType =
2997 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2998 if (constArrType) {
2999 constArrType->getSize().toStringUnsigned(arraySize);
3000 }
3001 arraySize += ']';
3002 clang::QualType subArrQT = arrType->getElementType();
3003 if (subArrQT.isNull()) {
3004 std::string memberName;
3005 llvm::raw_string_ostream stream(memberName);
3006 // Don't trigger fopen of the source file to count lines:
3007 printPol.AnonymousTagLocations = false;
3008 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
3009 stream.flush();
3010 Error("InspectMembers",
3011 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
3012 arrLevel, subArrQT.getAsString(printPol).c_str(),
3013 memberName.c_str(), clname);
3014 haveErrorDueToArray = true;
3015 break;
3016 }
3017 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
3018 }
3019 if (haveErrorDueToArray) {
3020 continue; // skip member
3021 }
3022
3023 // construct member name
3024 std::string fieldName;
3025 if (memType->isPointerType()) {
3026 fieldName = "*";
3027 }
3028
3029 // Check if this field has a custom ioname, if not, just use the one of the decl
3030 std::string ioname(iField->getName());
3032 fieldName += ioname;
3033 fieldName += arraySize;
3034
3035 // get member offset
3036 // NOTE currently we do not support bitfield and do not support
3037 // member that are not aligned on 'bit' boundaries.
3038 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
3039 ptrdiff_t fieldOffset = offset.getQuantity();
3040
3041 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fBits[2]", fBits);
3042 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fName", &fName);
3043 // R__insp.InspectMember(fName, "fName.");
3044 // R__insp.Inspect(R__cl, R__insp.GetParent(), "*fClass", &fClass);
3045
3046 // If the class has a custom streamer and the type of the filed is a
3047 // private enum, struct or class, skip it.
3048 if (!insp.IsTreatingNonAccessibleTypes()){
3049 auto iFiledQtype = iField->getType();
3050 if (auto tagDecl = iFiledQtype->getAsTagDecl()){
3051 auto declAccess = tagDecl->getAccess();
3053 continue;
3054 }
3055 }
3056 }
3057
3058 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
3059
3060 if (!ispointer) {
3061 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
3062 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
3063 // nested objects get an extra call to InspectMember
3064 // R__insp.InspectMember("FileStat_t", (void*)&fFileStat, "fFileStat.", false);
3065 std::string sFieldRecName;
3068 clang::QualType(memNonPtrType,0),
3069 *fInterpreter,
3071 }
3072
3073 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
3074 // if we can not find the member (which should not really happen),
3075 // let's consider it transient.
3076 Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();
3077 if (!mbr || !mbr->IsPersistent())
3078 insp.IncrementNestedTransient();
3079 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
3080 (fieldName + '.').c_str(), transient);
3081 if (!mbr || !mbr->IsPersistent())
3082 insp.DecrementNestedTransient();
3083
3084 }
3085 }
3086 } // loop over fields
3087
3088 // inspect bases
3089 // TNamed::ShowMembers(R__insp);
3090 unsigned iNBase = 0;
3091 for (clang::CXXRecordDecl::base_class_const_iterator iBase
3092 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
3093 iBase != eBase; ++iBase, ++iNBase) {
3094 clang::QualType baseQT = iBase->getType();
3095 if (baseQT.isNull()) {
3096 Error("InspectMembers",
3097 "Cannot find QualType for base number %d while inspecting class %s",
3098 iNBase, clname);
3099 continue;
3100 }
3101 const clang::CXXRecordDecl* baseDecl
3102 = baseQT->getAsCXXRecordDecl();
3103 if (!baseDecl) {
3104 Error("InspectMembers",
3105 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
3106 iNBase, clname);
3107 continue;
3108 }
3109 TClass* baseCl=nullptr;
3110 std::string sBaseName;
3111 // Try with the DeclId
3112 std::vector<TClass*> foundClasses;
3114 if (foundClasses.size()==1){
3116 } else {
3117 // Try with the normalised Name, as a fallback
3118 if (!baseCl){
3120 baseQT,
3121 *fInterpreter,
3124 }
3125 }
3126
3127 if (!baseCl){
3128 std::string qualNameForDiag;
3130 Error("InspectMembers",
3131 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
3132 continue;
3133 }
3134
3135 int64_t baseOffset;
3136 if (iBase->isVirtual()) {
3137 if (insp.GetObjectValidity() == TMemberInspector::kNoObjectGiven) {
3138 if (!isTransient) {
3139 Error("InspectMembers",
3140 "Base %s of class %s is virtual but no object provided",
3141 sBaseName.c_str(), clname);
3142 }
3144 } else {
3145 // We have an object to determine the vbase offset.
3147 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
3148 if (ci && baseCi) {
3149 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
3150 true /*isDerivedObj*/);
3151 if (baseOffset == -1) {
3152 Error("InspectMembers",
3153 "Error calculating offset of virtual base %s of class %s",
3154 sBaseName.c_str(), clname);
3155 }
3156 } else {
3157 Error("InspectMembers",
3158 "Cannot calculate offset of virtual base %s of class %s",
3159 sBaseName.c_str(), clname);
3160 continue;
3161 }
3162 }
3163 } else {
3164 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
3165 }
3166 // TOFIX: baseCl can be null here!
3167 if (baseCl->IsLoaded()) {
3168 // For loaded class, CallShowMember will (especially for TObject)
3169 // call the virtual ShowMember rather than the class specific version
3170 // resulting in an infinite recursion.
3172 } else {
3173 baseCl->CallShowMembers(cobj + baseOffset,
3174 insp, isTransient);
3175 }
3176 } // loop over bases
3177}
3178
3179////////////////////////////////////////////////////////////////////////////////
3180/// Check if constructor exited correctly, ie the instance is in a valid state
3181/// \return true if there is a compiler instance available, false otherwise
3183{
3184 return fInterpreter->getCI() != nullptr;
3185}
3186
3187////////////////////////////////////////////////////////////////////////////////
3188/// Reset the interpreter internal state in case a previous action was not correctly
3189/// terminated.
3190
3192{
3193 // No-op there is not equivalent state (to be cleared) in Cling.
3194}
3195
3196////////////////////////////////////////////////////////////////////////////////
3197/// Delete existing temporary values.
3198
3200{
3201 // No-op for cling due to cling::Value.
3202}
3203
3204namespace {
3205 // Re-enable JIT symbol library autoloading (independently of class/dictionary
3206 // autoloading) for the lifetime of the object. See its use in TCling::Declare
3207 // and #16601.
3208 class EnableAutoLoadingForJITSymbolsRAII {
3209 TClingCallbacks *fCallbacks;
3210 bool fOldValue = false;
3211
3212 public:
3213 EnableAutoLoadingForJITSymbolsRAII(TClingCallbacks *callbacks) : fCallbacks(callbacks)
3214 {
3215 if (fCallbacks) {
3216 fOldValue = fCallbacks->IsAutoLoadingForJITSymbols();
3217 fCallbacks->SetAutoLoadingForJITSymbols(true);
3218 }
3219 }
3221 {
3222 if (fCallbacks)
3223 fCallbacks->SetAutoLoadingForJITSymbols(fOldValue);
3224 }
3225 };
3226}
3227
3228////////////////////////////////////////////////////////////////////////////////
3229/// Declare code to the interpreter, without any of the interpreter actions
3230/// that could trigger a re-interpretation of the code. I.e. make cling
3231/// behave like a compiler: no dynamic lookup, no input wrapping for
3232/// subsequent execution, no automatic provision of declarations but just a
3233/// plain `#include`.
3234/// Returns true on success, false on failure.
3235
3236bool TCling::Declare(const char* code)
3237{
3239
3242
3243 // The suspensions above make parsing behave like a plain compiler, but they also
3244 // gate the JIT's library autoloading - and a declared global's static initializer
3245 // may still need symbols from a not-yet-loaded library (e.g. TVectorT<float> from
3246 // libMatrix). Re-allow autoloading for such genuine JIT symbol resolution. #16601
3247 EnableAutoLoadingForJITSymbolsRAII autoLoadJITOn(fClingCallbacks);
3248
3249 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
3250 fInterpreter->enableDynamicLookup(false);
3251 bool oldRawInput = fInterpreter->isRawInputEnabled();
3252 fInterpreter->enableRawInput(true);
3253
3254 Bool_t ret = LoadText(code);
3255
3256 fInterpreter->enableRawInput(oldRawInput);
3257 fInterpreter->enableDynamicLookup(oldDynLookup);
3258 return ret;
3259}
3260
3261////////////////////////////////////////////////////////////////////////////////
3262/// It calls a "fantom" method to synchronize user keyboard input
3263/// and ROOT prompt line.
3264
3269
3270// This static function is a hop of TCling::IsLibraryLoaded, which is taking a lock and calling
3271// into this function. This is because we wanted to avoid a duplication in TCling::IsLoaded, which
3272// was already taking a lock.
3273static Bool_t s_IsLibraryLoaded(const char* libname, cling::Interpreter* fInterpreter)
3274{
3275 // Check shared library.
3278 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
3279 return false;
3280}
3281
3287
3288////////////////////////////////////////////////////////////////////////////////
3289/// Return true if ROOT has cxxmodules pcm for a given library name.
3290// FIXME: We need to be able to support lazy loading of pcm generated by ACLiC.
3292{
3293 llvm::StringRef ModuleName(libname);
3294 ModuleName = llvm::sys::path::stem(ModuleName);
3295 ModuleName.consume_front("lib");
3296
3297 // FIXME: In case when the modulemap is not yet loaded we will return the
3298 // wrong result. Consider a call to HasPCMForLibrary(../test/libEvent.so)
3299 // We will only load the modulemap for libEvent.so after we dlopen libEvent
3300 // which may happen after calling this interface. Maybe we should also check
3301 // if there is a Event.pcm file and a module.modulemap, load it and return
3302 // true.
3303 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
3304 clang::Module *M = moduleMap.findModule(ModuleName);
3305 return M && !M->IsUnimportable && M->getASTFile();
3306}
3307
3308////////////////////////////////////////////////////////////////////////////////
3309/// Return true if the file has already been loaded by cint.
3310/// We will try in this order:
3311/// actual filename
3312/// filename as a path relative to
3313/// the include path
3314/// the shared library path
3315
3317{
3319
3320 //FIXME: if we use llvm::sys::fs::make_absolute all this can go away. See
3321 // cling::DynamicLibraryManager.
3322
3323 std::string file_name = filename;
3324 size_t at = std::string::npos;
3325 while ((at = file_name.find("/./")) != std::string::npos)
3326 file_name.replace(at, 3, "/");
3327
3328 std::string filesStr = "";
3329 llvm::raw_string_ostream filesOS(filesStr);
3330 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3331 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
3332 filesOS.flush();
3333
3334 llvm::SmallVector<llvm::StringRef, 100> files;
3335 llvm::StringRef(filesStr).split(files, "\n");
3336
3337 std::set<std::string> fileMap;
3338 llvm::StringRef file_name_ref(file_name);
3339 // Fill fileMap; return early on exact match.
3341 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
3342 if ((*iF) == file_name_ref) return kTRUE; // exact match
3343 fileMap.insert(iF->str());
3344 }
3345
3346 if (fileMap.empty()) return kFALSE;
3347
3348 // Check MacroPath.
3349 TString sFilename(file_name.c_str());
3351 && fileMap.count(sFilename.Data())) {
3352 return kTRUE;
3353 }
3354
3355 // Check IncludePath.
3356 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
3357 incPath.Append(":").Prepend(" "); // to match " -I" (note leading ' ')
3358 incPath.ReplaceAll(" -I", ":"); // of form :dir1 :dir2:dir3
3359 while (incPath.Index(" :") != -1) {
3360 incPath.ReplaceAll(" :", ":");
3361 }
3362 incPath.Prepend(".:");
3363 sFilename = file_name.c_str();
3365 && fileMap.count(sFilename.Data())) {
3366 return kTRUE;
3367 }
3368
3369 // Check shared library.
3371 return kTRUE;
3372
3373 //FIXME: We must use the cling::Interpreter::lookupFileOrLibrary iface.
3374 clang::ConstSearchDirIterator *CurDir = nullptr;
3375 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
3376 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
3377 auto FE = HS.LookupFile(file_name.c_str(),
3378 clang::SourceLocation(),
3379 /*isAngled*/ false,
3380 /*FromDir*/ nullptr, CurDir,
3381 clang::ArrayRef<std::pair<clang::OptionalFileEntryRef,
3382 clang::DirectoryEntryRef>>(),
3383 /*SearchPath*/ nullptr,
3384 /*RelativePath*/ nullptr,
3385 /*RequestingModule*/ nullptr,
3386 /*SuggestedModule*/ nullptr,
3387 /*IsMapped*/ nullptr,
3388 /*IsFrameworkFound*/ nullptr,
3389 /*SkipCache*/ false,
3390 /*BuildSystemModule*/ false,
3391 /*OpenFile*/ false,
3392 /*CacheFail*/ false);
3393 if (FE) {
3394 // check in the source manager if the file is actually loaded
3395 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3396 // this works only with header (and source) files...
3397 clang::FileID FID = SM.translateFile(*FE);
3398 if (!FID.isInvalid() && FID.getHashValue() == 0)
3399 return kFALSE;
3400 else {
3401 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
3402 if (SLocE.isFile() && !SLocE.getFile().getContentCache().getBufferIfLoaded())
3403 return kFALSE;
3404 if (!FID.isInvalid())
3405 return kTRUE;
3406 }
3407 // ...then check shared library again, but with full path now
3408 sFilename = FE->getName().str();
3410 && fileMap.count(sFilename.Data())) {
3411 return kTRUE;
3412 }
3413 }
3414 return kFALSE;
3415}
3416
3417
3418#if defined(R__MACOSX)
3419
3420////////////////////////////////////////////////////////////////////////////////
3421/// Check if lib is in the dynamic linker cache, returns true if it is, and if so,
3422/// modifies the library file name parameter `lib` from `/usr/lib/libFOO.dylib`
3423/// to `-lFOO` such that it can be passed to the linker.
3424/// This is a unique feature of macOS 11.
3425
3426static bool R__UpdateLibFileForLinking(TString &lib)
3427{
3428 const char *mapfile = nullptr;
3429#if __x86_64__
3430 mapfile = "/System/Library/dyld/dyld_shared_cache_x86_64.map";
3431#elif __arm64__
3432 mapfile = "/System/Library/dyld/dyld_shared_cache_arm64e.map";
3433#else
3434 #error unsupported architecture
3435#endif
3436 if (std::ifstream cacheMap{mapfile}) {
3437 std::string line;
3438 while (getline(cacheMap, line)) {
3439 if (line.find(lib) != std::string::npos) {
3440 lib.ReplaceAll("/usr/lib/lib","-l");
3441 lib.ReplaceAll(".dylib","");
3442 return true;
3443 }
3444 }
3445 return false;
3446 }
3447 return false;
3448}
3449#endif // R__MACOSX
3450
3451#if defined (R__LINUX) || defined (R__FBSD)
3452
3453////////////////////////////////////////////////////////////////////////////////
3454/// Callback for dl_iterate_phdr(), see `man dl_iterate_phdr`.
3455/// Collects opened libraries.
3456
3457static int callback_for_dl_iterate_phdr(struct dl_phdr_info *info, size_t size, void *data)
3458{
3459 // This function is called through UpdateListOfLoadedSharedLibraries() which is locked.
3460 static std::unordered_set<decltype(info->dlpi_addr)> sKnownLoadedLibBaseAddrs;
3461
3462 auto newLibs = static_cast<std::vector<std::string>*>(data);
3463 if (!sKnownLoadedLibBaseAddrs.count(info->dlpi_addr)) {
3464 // Skip \0, "", and kernel pseudo-libs linux-vdso.so.1 or linux-gate.so.1
3465 if (info->dlpi_name && info->dlpi_name[0]
3466#if defined(R__FBSD)
3467 //skip the executable (with null addr)
3468 && info->dlpi_addr
3469 //has no path
3470 && strncmp(info->dlpi_name, "[vdso]", 6)
3471 //the linker does not like to be mmapped
3472 //causes a crash in cling::DynamicLibraryManager::loadLibrary())
3473 //with error message "mmap of entire address space failed: Cannot allocate memory"
3474 && strncmp(info->dlpi_name, "/libexec/ld-elf.so.1", 20)
3475#endif
3476 && strncmp(info->dlpi_name, "linux-vdso.so", 13)
3477 && strncmp(info->dlpi_name, "linux-vdso32.so", 15)
3478 && strncmp(info->dlpi_name, "linux-vdso64.so", 15)
3479 && strncmp(info->dlpi_name, "linux-gate.so", 13))
3480 newLibs->emplace_back(info->dlpi_name);
3481 sKnownLoadedLibBaseAddrs.insert(info->dlpi_addr);
3482 }
3483 // No matter what the doc says, return != 0 means "stop the iteration".
3484 return 0;
3485}
3486
3487#endif // R__LINUX || R__FBSD
3488
3489
3490////////////////////////////////////////////////////////////////////////////////
3491
3493{
3494#if defined(R__WIN32) || defined(__CYGWIN__)
3495 HMODULE hModules[1024];
3496 void *hProcess;
3497 unsigned long cbModules;
3498 unsigned int i;
3499 hProcess = (void *)::GetCurrentProcess();
3501 // start at 1 to skip the executable itself
3502 for (i = 1; i < (cbModules / sizeof(void *)); i++) {
3503 static const int bufsize = 260;
3504 wchar_t winname[bufsize];
3505 char posixname[bufsize];
3507#if defined(__CYGWIN__)
3509#else
3510 std::wstring wpath = winname;
3511 std::replace(wpath.begin(), wpath.end(), '\\', '/');
3512 string path(wpath.begin(), wpath.end());
3513 strncpy(posixname, path.c_str(), bufsize);
3514#endif
3517 }
3518 }
3519#elif defined(R__MACOSX)
3520 // fPrevLoadedDynLibInfo stores the *next* image index to look at
3521 uint32_t imageIndex = (uint32_t) (size_t) fPrevLoadedDynLibInfo;
3522
3524 // Skip non-dylibs
3525 if (mh->filetype == MH_DYLIB) {
3526 if (const char* imageName = _dyld_get_image_name(imageIndex)) {
3528 }
3529 }
3530
3531 ++imageIndex;
3532 }
3533 fPrevLoadedDynLibInfo = (void*)(size_t)imageIndex;
3534#elif defined(R__LINUX) || defined(R__FBSD)
3535 // fPrevLoadedDynLibInfo is unused on Linux.
3536 (void) fPrevLoadedDynLibInfo;
3537
3538 std::vector<std::string> newLibs;
3540 for (auto &&lib: newLibs)
3541 RegisterLoadedSharedLibrary(lib.c_str());
3542#else
3543 Error("TCling::UpdateListOfLoadedSharedLibraries",
3544 "Platform not supported!");
3545#endif
3546}
3547
3548namespace {
3549template <int N>
3550static bool StartsWithStrLit(const char *haystack, const char (&needle)[N]) {
3551 return !strncmp(haystack, needle, N - 1);
3552}
3553}
3554
3555////////////////////////////////////////////////////////////////////////////////
3556/// Register that a library was autoloaded either to provide a 'missing' symbol
3557/// or to provide a class (see TClass::GetClass and TROOT::LoadClass).
3559{
3561}
3562
3563////////////////////////////////////////////////////////////////////////////////
3564/// Register a new shared library name with the interpreter; add it to
3565/// fSharedLibs.
3566
3568{
3569 // Ignore NULL filenames, aka "the process".
3570 if (!filename) return;
3571
3572 // Tell the interpreter that this library is available; all libraries can be
3573 // used to resolve symbols.
3574 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3575 if (!DLM->isLibraryLoaded(filename)) {
3576 DLM->loadLibrary(filename, true /*permanent*/, true /*resolved*/);
3577 }
3578
3579#if defined(R__MACOSX)
3580 // Check that this is not a system library that does not exist on disk.
3581 auto lenFilename = strlen(filename);
3582 auto isInMacOSSystemDir = [](const char *fn) {
3583 return StartsWithStrLit(fn, "/usr/lib/") || StartsWithStrLit(fn, "/System/Library/");
3584 };
3585 if (!strcmp(filename, "cl_kernels") // yepp, no directory
3586
3587 // These we should not link with (e.g. because they forward to .tbd):
3588 || StartsWithStrLit(filename, "/usr/lib/system/")
3589 || StartsWithStrLit(filename, "/usr/lib/libc++")
3590 || StartsWithStrLit(filename, "/System/Library/Frameworks/")
3591 || StartsWithStrLit(filename, "/System/Library/PrivateFrameworks/")
3592 || StartsWithStrLit(filename, "/System/Library/CoreServices/")
3593 || StartsWithStrLit(filename, "/usr/lib/libSystem")
3594 || StartsWithStrLit(filename, "/usr/lib/libstdc++")
3595 || StartsWithStrLit(filename, "/usr/lib/libicucore")
3596 || StartsWithStrLit(filename, "/usr/lib/libbsm")
3597 || StartsWithStrLit(filename, "/usr/lib/libobjc")
3598 || StartsWithStrLit(filename, "/usr/lib/libresolv")
3599 || StartsWithStrLit(filename, "/usr/lib/libauto")
3600 || StartsWithStrLit(filename, "/usr/lib/libcups")
3601 || StartsWithStrLit(filename, "/usr/lib/libDiagnosticMessagesClient")
3602 || StartsWithStrLit(filename, "/usr/lib/liblangid")
3603 || StartsWithStrLit(filename, "/usr/lib/libCRFSuite")
3604 || StartsWithStrLit(filename, "/usr/lib/libpam")
3605 || StartsWithStrLit(filename, "/usr/lib/libOpenScriptingUtil")
3606 || StartsWithStrLit(filename, "/usr/lib/libextension")
3607 || StartsWithStrLit(filename, "/usr/lib/libAudioToolboxUtility")
3608 || StartsWithStrLit(filename, "/usr/lib/liboah")
3609 || StartsWithStrLit(filename, "/usr/lib/libRosetta")
3610 || StartsWithStrLit(filename, "/usr/lib/libCoreEntitlements")
3611 || StartsWithStrLit(filename, "/usr/lib/libssl.")
3612 || StartsWithStrLit(filename, "/usr/lib/libcrypto.")
3613
3614 // The system lib is likely in macOS's blob.
3616
3617 // "Link against the umbrella framework 'System.framework' instead"
3618 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_kernel")
3619 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_platform")
3620 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_pthread")
3621
3622 // "cannot link directly with dylib/framework, your binary is not an allowed client of
3623 // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
3624 // SDKs/MacOSX.sdk/usr/lib/libAudioToolboxUtility.tbd for architecture x86_64
3625 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4, ".tbd")))
3626 return;
3629 filename = sFileName.Data();
3630#elif defined(__CYGWIN__)
3631 // Check that this is not a system library
3632 static const int bufsize = 260;
3633 char posixwindir[bufsize];
3634 char *windir = std::getenv("WINDIR");
3635 if (windir)
3637 else
3638 snprintf(posixwindir, sizeof(posixwindir), "/Windows/");
3639 if (strstr(filename, posixwindir) ||
3640 strstr(filename, "/usr/bin/cyg"))
3641 return;
3642#elif defined(R__WIN32)
3643 if (strstr(filename, "/Windows/"))
3644 return;
3645#elif defined (R__LINUX)
3646 if (strstr(filename, "/ld-linux")
3647 || strstr(filename, "linux-gnu/")
3648 || strstr(filename, "/libstdc++.")
3649 || strstr(filename, "/libgcc")
3650 || strstr(filename, "/libc.")
3651 || strstr(filename, "/libdl.")
3652 || strstr(filename, "/libm."))
3653 return;
3654#endif
3655 // Update string of available libraries.
3656 if (!fSharedLibs.IsNull()) {
3657 fSharedLibs.Append(" ");
3658 }
3660}
3661
3662////////////////////////////////////////////////////////////////////////////////
3663/// Load a library file in cling's memory.
3664/// if 'system' is true, the library is never unloaded.
3665/// Return 0 on success, -1 on failure.
3666
3668{
3669 assert(!IsFromRootCling() && "Trying to load library from rootcling!");
3670
3671 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3673 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3674 std::string canonLib = DLM->lookupLibrary(filename);
3675 cling::DynamicLibraryManager::LoadLibResult res
3676 = cling::DynamicLibraryManager::kLoadLibNotFound;
3677 if (!canonLib.empty()) {
3678 if (system)
3679 res = DLM->loadLibrary(filename, system, true);
3680 else {
3681 // For the non system libs, we'd like to be able to unload them.
3682 // FIXME: Here we lose the information about kLoadLibAlreadyLoaded case.
3683 cling::Interpreter::CompilationResult compRes;
3684 HandleInterpreterException(GetMetaProcessorImpl(), Form(".L %s", canonLib.c_str()), compRes, /*cling::Value*/nullptr);
3685 if (compRes == cling::Interpreter::kSuccess)
3686 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3687 }
3688 }
3689
3690 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3692 }
3693 switch (res) {
3694 case cling::DynamicLibraryManager::kLoadLibSuccess: return 0;
3695 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return 1;
3696 default: break;
3697 };
3698 return -1;
3699}
3700
3701////////////////////////////////////////////////////////////////////////////////
3702/// Load a macro file in cling's memory.
3703
3704void TCling::LoadMacro(const char* filename, EErrorCode* error)
3705{
3706 ProcessLine(Form(".L %s", filename), error);
3707}
3708
3709////////////////////////////////////////////////////////////////////////////////
3710/// Let cling process a command line asynch.
3711
3713{
3714 return ProcessLine(line, error);
3715}
3716
3717////////////////////////////////////////////////////////////////////////////////
3718/// Let cling process a command line synchronously, i.e we are waiting
3719/// it will be finished.
3720
3722{
3724 if (gApplication) {
3725 if (gApplication->IsCmdThread()) {
3726 return ProcessLine(line, error);
3727 }
3728 return 0;
3729 }
3730 return ProcessLine(line, error);
3731}
3732
3733////////////////////////////////////////////////////////////////////////////////
3734/// Directly execute an executable statement (e.g. "func()", "3+5", etc.
3735/// however not declarations, like "Int_t x;").
3736
3738{
3739#ifdef R__WIN32
3740 // Test on ApplicationImp not being 0 is needed because only at end of
3741 // TApplication ctor the IsLineProcessing flag is set to 0, so before
3742 // we can not use it.
3744 while (gROOT->IsLineProcessing() && !gApplication) {
3745 Warning("Calc", "waiting for cling thread to free");
3746 gSystem->Sleep(500);
3747 }
3748 gROOT->SetLineIsProcessing();
3749 }
3750#endif // R__WIN32
3752 if (error) {
3753 *error = TInterpreter::kNoError;
3754 }
3755 cling::Value valRef;
3756 cling::Interpreter::CompilationResult cr = cling::Interpreter::kFailure;
3757 try {
3758 cr = fInterpreter->evaluate(line, valRef);
3759 }
3760 catch (cling::InterpreterException& ex)
3761 {
3762 Error("Calc", "%s.\n%s", ex.what(), "Evaluation of your expression was aborted.");
3763 ex.diagnose();
3764 cr = cling::Interpreter::kFailure;
3765 }
3766
3767 if (cr != cling::Interpreter::kSuccess) {
3768 // Failure in compilation.
3769 if (error) {
3770 // Note: Yes these codes are weird.
3772 }
3773 return 0L;
3774 }
3775 if (!valRef.isValid()) {
3776 // Failure at runtime.
3777 if (error) {
3778 // Note: Yes these codes are weird.
3779 *error = TInterpreter::kDangerous;
3780 }
3781 return 0L;
3782 }
3783
3784 if (valRef.isVoid()) {
3785 return 0;
3786 }
3787
3789#ifdef R__WIN32
3791 gROOT->SetLineHasBeenProcessed();
3792 }
3793#endif // R__WIN32
3794 return valRef.castAs<Longptr_t>();
3795}
3796
3797////////////////////////////////////////////////////////////////////////////////
3798/// Set a getline function to call when input is needed.
3799
3800void TCling::SetGetline(const char * (*getlineFunc)(const char* prompt),
3801 void (*histaddFunc)(const char* line))
3802{
3803 // If cling offers a replacement for G__pause(), it would need to
3804 // also offer a way to customize at least the history recording.
3805
3806#if defined(R__MUST_REVISIT)
3807#if R__MUST_REVISIT(6,2)
3808 Warning("SetGetline","Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3809#endif
3810#endif
3811}
3812
3813////////////////////////////////////////////////////////////////////////////////
3814/// Helper function to increase the internal Cling count of transactions
3815/// that change the AST.
3816
3817Bool_t TCling::HandleNewTransaction(const cling::Transaction &T)
3818{
3820
3821 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3822 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3823 || T.macros_begin() != T.macros_end()
3824 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3826 return true;
3827 }
3828 return false;
3829}
3830
3831////////////////////////////////////////////////////////////////////////////////
3832/// Delete object from cling symbol table so it can not be used anymore.
3833/// cling objects are always on the heap.
3834
3836{
3837 // NOTE: When replacing the mutex by a ReadWrite mutex, we **must**
3838 // put in place the Read/Write part here. Keeping the write lock
3839 // here is 'catasptrophic' for scaling as it means that ALL calls
3840 // to RecursiveRemove will take the write lock and performance
3841 // of many threads trying to access the write lock at the same
3842 // time is relatively bad.
3844 // Note that fgSetOfSpecials is supposed to be updated by TClingCallbacks::tryFindROOTSpecialInternal
3845 // (but isn't at the moment).
3846 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3847 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3848 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3850 DeleteGlobal(obj);
3851 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3852 }
3853 }
3854}
3855
3856////////////////////////////////////////////////////////////////////////////////
3857/// Pressing Ctrl+C should forward here. In the case where we have had
3858/// continuation requested we must reset it.
3859
3861{
3862 fMetaProcessor->cancelContinuation();
3863 // Reset the Cling state to the state saved by the last call to
3864 // TCling::SaveContext().
3865#if defined(R__MUST_REVISIT)
3866#if R__MUST_REVISIT(6,2)
3868 Warning("Reset","Cling should support the equivalent of scratch_upto(&fDictPos)");
3869#endif
3870#endif
3871}
3872
3873////////////////////////////////////////////////////////////////////////////////
3874/// Reset the Cling state to its initial state.
3875
3877{
3878#if defined(R__MUST_REVISIT)
3879#if R__MUST_REVISIT(6,2)
3881 Warning("ResetAll","Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3882#endif
3883#endif
3884}
3885
3886////////////////////////////////////////////////////////////////////////////////
3887/// Reset in Cling the list of global variables to the state saved by the last
3888/// call to TCling::SaveGlobalsContext().
3889///
3890/// Note: Right now, all we do is run the global destructors.
3891
3893{
3895 // TODO:
3896 // Here we should iterate over the transactions (N-3) and revert.
3897 // N-3 because the first three internal to cling.
3898
3899 fInterpreter->runAndRemoveStaticDestructors();
3900}
3901
3902////////////////////////////////////////////////////////////////////////////////
3903/// Reset the Cling 'user' global objects/variables state to the state saved by the last
3904/// call to TCling::SaveGlobalsContext().
3905
3907{
3908#if defined(R__MUST_REVISIT)
3909#if R__MUST_REVISIT(6,2)
3911 Warning("ResetGlobalVar","Cling should support the equivalent of resetglobalvar(obj)");
3912#endif
3913#endif
3914}
3915
3916////////////////////////////////////////////////////////////////////////////////
3917/// Rewind Cling dictionary to the point where it was before executing
3918/// the current macro. This function is typically called after SEGV or
3919/// ctlr-C after doing a longjmp back to the prompt.
3920
3922{
3923#if defined(R__MUST_REVISIT)
3924#if R__MUST_REVISIT(6,2)
3926 Warning("RewindDictionary","Cling should provide a way to revert transaction similar to rewinddictionary()");
3927#endif
3928#endif
3929}
3930
3931////////////////////////////////////////////////////////////////////////////////
3932/// Delete obj from Cling symbol table so it cannot be accessed anymore.
3933/// Returns 1 in case of success and 0 in case object was not in table.
3934
3936{
3937#if defined(R__MUST_REVISIT)
3938#if R__MUST_REVISIT(6,2)
3940 Warning("DeleteGlobal","Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3941#endif
3942#endif
3943 return 0;
3944}
3945
3946////////////////////////////////////////////////////////////////////////////////
3947/// Undeclare obj called name.
3948/// Returns 1 in case of success, 0 for failure.
3949
3951{
3952#if defined(R__MUST_REVISIT)
3953#if R__MUST_REVISIT(6,2)
3954 Warning("DeleteVariable","should do more that just reseting the value to zero");
3955#endif
3956#endif
3957
3959 llvm::StringRef srName(name);
3960 const char* unscopedName = name;
3961 llvm::StringRef::size_type posScope = srName.rfind("::");
3962 const clang::DeclContext* declCtx = nullptr;
3963 if (posScope != llvm::StringRef::npos) {
3964 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3965 const clang::Decl* scopeDecl
3966 = lh.findScope(srName.substr(0, posScope),
3967 cling::LookupHelper::WithDiagnostics);
3968 if (!scopeDecl) {
3969 Error("DeleteVariable", "Cannot find enclosing scope for variable %s",
3970 name);
3971 return 0;
3972 }
3973 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3974 if (!declCtx) {
3975 Error("DeleteVariable",
3976 "Enclosing scope for variable %s is not a declaration context",
3977 name);
3978 return 0;
3979 }
3980 unscopedName += posScope + 2;
3981 }
3982 // Could trigger deserialization of decls.
3983 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
3984 clang::NamedDecl* nVarDecl
3985 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3986 if (!nVarDecl) {
3987 Error("DeleteVariable", "Unknown variable %s", name);
3988 return 0;
3989 }
3990 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3991 if (!varDecl) {
3992 Error("DeleteVariable", "Entity %s is not a variable", name);
3993 return 0;
3994 }
3995
3996 clang::QualType qType = varDecl->getType();
3997 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3998 // Cannot set a reference's address to nullptr; the JIT can place it
3999 // into read-only memory (ROOT-7100).
4000 if (type->isPointerType()) {
4001 int** ppInt = (int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
4002 // set pointer to invalid.
4003 if (ppInt) *ppInt = nullptr;
4004 }
4005 return 1;
4006}
4007
4008////////////////////////////////////////////////////////////////////////////////
4009/// Save the current Cling state.
4010
4012{
4013#if defined(R__MUST_REVISIT)
4014#if R__MUST_REVISIT(6,2)
4016 Warning("SaveContext","Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
4017#endif
4018#endif
4019}
4020
4021////////////////////////////////////////////////////////////////////////////////
4022/// Save the current Cling state of global objects.
4023
4025{
4026#if defined(R__MUST_REVISIT)
4027#if R__MUST_REVISIT(6,2)
4029 Warning("SaveGlobalsContext","Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
4030#endif
4031#endif
4032}
4033
4034////////////////////////////////////////////////////////////////////////////////
4035/// No op: see TClingCallbacks (used to update the list of globals)
4036
4040
4041////////////////////////////////////////////////////////////////////////////////
4042/// No op: see TClingCallbacks (used to update the list of global functions)
4043
4047
4048////////////////////////////////////////////////////////////////////////////////
4049/// No op: see TClingCallbacks (used to update the list of types)
4050
4052{
4053}
4054
4055////////////////////////////////////////////////////////////////////////////////
4056/// Check in what order the member of a tuple are layout.
4057enum class ETupleOrdering {
4058 kAscending,
4061};
4062
4068
4074
4076{
4077 std::tuple<int,double> value;
4080
4081 size_t offset0 = ((char*)&(std::get<0>(value))) - ((char*)&value);
4082 size_t offset1 = ((char*)&(std::get<1>(value))) - ((char*)&value);
4083
4084 size_t ascOffset0 = ((char*)&(asc._0)) - ((char*)&asc);
4085 size_t ascOffset1 = ((char*)&(asc._1)) - ((char*)&asc);
4086
4087 size_t desOffset0 = ((char*)&(des._0)) - ((char*)&des);
4088 size_t desOffset1 = ((char*)&(des._1)) - ((char*)&des);
4089
4090 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
4092 } else if (offset0 == desOffset0 && offset1 == desOffset1) {
4094 } else {
4096 }
4097}
4098
4099static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh, Bool_t silent)
4100{
4102 std::string alternateName = "TEmulatedTuple";
4103 alternateName.append( classname + 5 );
4104
4105 std::string fullname = "ROOT::Internal::" + alternateName;
4106 if (lh.findScope(fullname, cling::LookupHelper::NoDiagnostics,
4107 /*resultType*/nullptr, /* intantiateTemplate= */ false))
4108 return fullname;
4109
4110 {
4111 // Check if we can produce the tuple
4112 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
4113 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
4114 auto deleter = [](TypeInfo_t *type) {
4115 gInterpreter->TypeInfo_Delete(type);
4116 };
4117 std::unique_ptr<TypeInfo_t, decltype(deleter)> type{ gInterpreter->TypeInfo_Factory(), deleter };
4118 while (iter != theEnd) {
4119 gInterpreter->TypeInfo_Init(type.get(), iter->c_str());
4120 if (gInterpreter->TypeInfo_Property(type.get()) & kIsNotReacheable) {
4121 if (!silent)
4122 Error("Load","Could not declare alternate type for %s since %s (or one of its context) is private or protected",
4123 classname, iter->c_str());
4124 return "";
4125 }
4126 ++iter;
4127 }
4128 }
4129
4130 std::string guard_name;
4132 std::ostringstream guard;
4133 guard << "ROOT_INTERNAL_TEmulated_";
4134 guard << guard_name;
4135
4136 std::ostringstream alternateTuple;
4137 std::ostringstream initializers;
4138
4139 alternateTuple << "#ifndef " << guard.str() << "\n";
4140 alternateTuple << "#define " << guard.str() << "\n";
4141 alternateTuple << "namespace ROOT { namespace Internal {\n";
4142 alternateTuple << "template <class... Types> struct TEmulatedTuple;\n";
4143 alternateTuple << "template <> struct " << alternateName << " {\n";
4144
4145 // This could also be a compile time choice ...
4146 switch(IsTupleAscending()) {
4148 unsigned int nMember = 0;
4149 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
4150 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
4151 auto sep = ':';
4152 while (iter != theEnd) {
4153 alternateTuple << " " << *iter << " _" << nMember << ";\n";
4154 initializers << " " << sep << " _" << nMember << "(std::get<" << nMember << ">(std::forward<Tuple>(t)))\n";
4155 ++iter;
4156 ++nMember;
4157 sep = ',';
4158 }
4159 break;
4160 }
4162 unsigned int nMember = tupleContent.fElements.size() - 3;
4163 auto iter = tupleContent.fElements.rbegin() + 1; // skip the 'stars'.
4164 auto theEnd = tupleContent.fElements.rend() - 1; // Skip the template name (tuple).
4165 auto sep = ':';
4166 while (iter != theEnd) {
4167 alternateTuple << " " << *iter << " _" << nMember << ";\n";
4168 initializers << " " << sep << " _" << nMember << "(std::get<" << nMember << ">(std::forward<Tuple>(t)))\n";
4169 ++iter;
4170 --nMember;
4171 sep = ',';
4172 }
4173 break;
4174 }
4176 Fatal("TCling::SetClassInfo::AlternateTuple",
4177 "Layout of std::tuple on this platform is unexpected.");
4178 break;
4179 }
4180 }
4181
4182 // default constructor
4183 alternateTuple << " TEmulatedTuple() = default;\n";
4184
4185 // constructor from other tuple-like types, like std::tuple
4186 alternateTuple << " template <typename Tuple>\n";
4187 alternateTuple << " TEmulatedTuple(Tuple&& t)\n";
4189 alternateTuple << " {}\n";
4190
4191 alternateTuple << "};\n";
4192 alternateTuple << "}}\n";
4193 alternateTuple << "#endif\n";
4194 if (!gCling->Declare(alternateTuple.str().c_str()))
4195 {
4196 // Declare is not silent (yet?), so add an explicit error message
4197 // to indicate the consequence of the syntax errors.
4198 Error("Load","Could not declare %s",alternateName.c_str());
4199 return "";
4200 }
4201 alternateName = "ROOT::Internal::" + alternateName;
4202 return alternateName;
4203}
4204
4205////////////////////////////////////////////////////////////////////////////////
4206/// Set pointer to the TClingClassInfo in TClass.
4207/// If 'reload' is true, (attempt to) generate a new ClassInfo even if we
4208/// already have one.
4209/// If 'classInfo' is non-null, take ownership of it and use it instead of
4210/// looking up the class again; it must have been obtained from a call to
4211/// CheckClassInfo(cl->GetName(), ...).
4212
4214{
4215 // Whether we use it below or not, we own the passed class info.
4216 std::unique_ptr<TClingClassInfo> providedInfo{(TClingClassInfo *)classInfo};
4217
4218 // A provided class info is a cached lookup result; honoring it would defeat
4219 // the point of a reload, which is to redo the lookup.
4220 if (reload)
4221 providedInfo.reset();
4222
4223 // We are shutting down, there is no point in reloading, it only triggers
4224 // redundant deserializations.
4225 if (fIsShuttingDown) {
4226 // Remove the decl_id from the DeclIdToTClass map
4227 if (cl->fClassInfo) {
4230 // Test again as another thread may have set fClassInfo to nullptr.
4231 if (TClinginfo) {
4233 }
4234 delete TClinginfo;
4235 cl->fClassInfo = nullptr;
4236 }
4237 return;
4238 }
4239
4241 if (cl->fClassInfo && !reload) {
4242 return;
4243 }
4244 //Remove the decl_id from the DeclIdToTClass map
4246 if (TClinginfo) {
4248 }
4249 delete TClinginfo;
4250 cl->fClassInfo = nullptr;
4251 std::string name(cl->GetName());
4252
4253 auto SetWithoutClassInfoState = [](TClass *cl)
4254 {
4255 if (cl->fState != TClass::kHasTClassInit) {
4256 if (cl->fStreamerInfo->GetEntries() != 0) {
4258 } else {
4260 }
4261 }
4262 };
4263 // Handle the special case of 'tuple' where we ignore the real implementation
4264 // details and just overlay a 'simpler'/'simplistic' version that is easy
4265 // for the I/O to understand and handle.
4266 if (strncmp(cl->GetName(),"tuple<",std::char_traits<char>::length("tuple<"))==0) {
4267 // A provided class info would describe the real std::tuple, not the
4268 // alternate version overlaid below: it cannot be used.
4269 providedInfo.reset();
4270 if (!reload)
4271 name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper(), silent);
4272 if (reload || name.empty()) {
4273 // We could not generate the alternate
4275 return;
4276 }
4277 }
4278
4280 // FIXME: Rather than adding an option to the TClingClassInfo, we should consider combining code
4281 // that is currently in the caller (like SetUnloaded) that disable AutoLoading and AutoParsing and
4282 // code is in the callee (disabling template instantiation) and end up with a more explicit class:
4283 // TClingClassInfoReadOnly.
4286 if (!info->IsValid()) {
4288 delete info;
4289 return;
4290 }
4291 cl->fClassInfo = (ClassInfo_t*)info; // Note: We are transferring ownership here.
4292 // In case a class contains an external enum, the enum will be seen as a
4293 // class. We must detect this special case and make the class a Zombie.
4294 // Here we assume that a class has at least one method.
4295 // We can NOT call TClass::Property from here, because this method
4296 // assumes that the TClass is well formed to do a lot of information
4297 // caching. The method SetClassInfo (i.e. here) is usually called during
4298 // the building phase of the TClass, hence it is NOT well formed yet.
4300 if (
4301 info->IsValid() &&
4302 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
4303 ) {
4305 }
4306 if (!info->IsLoaded()) {
4307 if (info->Property() & (kIsNamespace)) {
4308 // Namespaces can have info but no corresponding CINT dictionary
4309 // because they are auto-created if one of their contained
4310 // classes has a dictionary.
4312 }
4313 // this happens when no dictionary is available
4314 delete info;
4315 cl->fClassInfo = nullptr;
4316 }
4317 if (zombieCandidate && !cl->GetCollectionType()) {
4318 cl->MakeZombie();
4319 }
4320 // If we reach here, the info was valid (See early returns).
4321 if (cl->fState != TClass::kHasTClassInit) {
4322 if (cl->fClassInfo) {
4324 } else {
4325// if (TClassEdit::IsSTLCont(cl->GetName()) {
4326// There will be an emulated collection proxy, is that the same?
4327// cl->fState = TClass::kEmulated;
4328// } else {
4329 if (cl->fStreamerInfo->GetEntries() != 0) {
4331 } else {
4333 }
4334// }
4335 }
4336 }
4337 if (cl->fClassInfo) {
4338 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
4339 }
4340}
4341
4342////////////////////////////////////////////////////////////////////////////////
4343/// Checks if an entity with the specified name is defined in Cling.
4344/// Returns kUnknown if the entity is not defined.
4345/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
4346/// Returns kKnown if the entity is defined.
4347///
4348/// By default, structs, namespaces, classes, enums and unions are looked for.
4349/// If the flag isClassOrNamespaceOnly is true, classes, structs and
4350/// namespaces only are considered. I.e. if the name is an enum or a union,
4351/// the returned value is false.
4352///
4353/// In the case where the class is not loaded and belongs to a namespace
4354/// or is nested, looking for the full class name is outputting a lots of
4355/// (expected) error messages. Currently the only way to avoid this is to
4356/// specifically check that each level of nesting is already loaded.
4357/// In case of templates the idea is that everything between the outer
4358/// '<' and '>' has to be skipped, e.g.: `aap<pippo<noot>::klaas>::a_class`
4359///
4360/// If 'classInfo' is non-null and the lookup found a declaration (which
4361/// findScope only returns if it points to a complete definition, i.e. when no
4362/// template instantiation would be needed to create it), '*classInfo' is set
4363/// to a newly allocated TClingClassInfo for that declaration, owned by the
4364/// caller. Passing it to SetClassInfo() avoids repeating the lookup there.
4365
4367 Bool_t isClassOrNamespaceOnly /* = kFALSE*/,
4368 ClassInfo_t **classInfo /* = nullptr*/)
4369{
4371 if (classInfo)
4372 *classInfo = nullptr;
4373 static const char *anonEnum = "anonymous enum ";
4374 static const int cmplen = strlen(anonEnum);
4375
4376 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
4377 return kUnknown;
4378 }
4379
4380 // Do not turn on the AutoLoading if it is globally off.
4382
4383 // Avoid the double search below in case the name is a fundamental type
4384 // or typedef to a fundamental type.
4385 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
4386 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
4387
4389 && fundType->GetType() > 0) {
4390 // Fundamental type, no a class.
4391 return kUnknown;
4392 }
4393
4394 // Migrated from within TClass::GetClass
4395 // If we want to know if a class or a namespace with this name exists in the
4396 // interpreter and this is an enum in the type system, before or after loading
4397 // according to the autoload function argument, return kUnknown.
4399 return kUnknown;
4400
4401 const char *classname = name;
4402
4403 // RAII to suspend and restore auto-loading and auto-parsing based on some external conditions.
4405 int fStoreAutoLoad = 0;
4406 int fStoreAutoParse = 0;
4407 bool fSuspendedAutoParse = false;
4408 public:
4410 fStoreAutoLoad = ((TCling*)gCling)->SetClassAutoLoading(autoload);
4411 }
4412
4413 void SuspendAutoParsing() {
4414 fSuspendedAutoParse = true;
4415 fStoreAutoParse = ((TCling*)gCling)->SetSuspendAutoParsing(true);
4416 }
4417
4420 ((TCling*)gCling)->SetSuspendAutoParsing(fStoreAutoParse);
4421 ((TCling*)gCling)->SetClassAutoLoading(fStoreAutoLoad);
4422 }
4423 };
4424
4426 if (TClassEdit::IsStdPair(classname) || TClassEdit::IsStdPairBase(classname))
4427 autoLoadParseRAII.SuspendAutoParsing();
4428
4429 // First we want to check whether the decl exist, but _without_
4430 // generating any template instantiation. However, the lookup
4431 // still will create a forward declaration of the class template instance
4432 // if it exist. In this case, the return value of findScope will still
4433 // be zero but the type will be initialized.
4434 // Note in the corresponding code in ROOT 5, CINT was not instantiating
4435 // this forward declaration.
4436 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4437 const clang::Type *type = nullptr;
4438 const clang::Decl *decl
4439 = lh.findScope(classname,
4440 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4441 : cling::LookupHelper::NoDiagnostics,
4442 &type, /* intantiateTemplate= */ false );
4443 if (!decl) {
4444 // Use a separate output type for the retry: findScope does not write it
4445 // on every path (e.g. when finding a namespace), and the type left over
4446 // from the lookup above must not be paired with this lookup's decl.
4447 const clang::Type *typeFromStd = nullptr;
4448 std::string buf = TClassEdit::InsertStd(classname);
4449 decl = lh.findScope(buf, gDebug > 5 ? cling::LookupHelper::WithDiagnostics : cling::LookupHelper::NoDiagnostics,
4450 &typeFromStd, false);
4451 if (decl || typeFromStd)
4452 type = typeFromStd;
4453 }
4454
4455 // If requested and an entity was found by the lookup above, hand a class
4456 // info for it out to the caller (see the function documentation).
4457 auto provideClassInfo = [this, classInfo, &decl, &type] {
4458 if (classInfo && decl && !decl->isInvalidDecl())
4460 };
4461
4462 if (type) {
4463 // If decl==0 and the type is valid, then we have a forward declaration.
4464 if (!decl) {
4465 // If we have a forward declaration for a class template instantiation,
4466 // we want to ignore it if it was produced/induced by the call to
4467 // findScope, however we can not distinguish those from the
4468 // instantiation induce by 'soft' use (and thus also induce by the
4469 // same underlying code paths)
4470 // ['soft' use = use not requiring a complete definition]
4471 // So to reduce the amount of disruption to the existing code we
4472 // would just ignore those for STL collection, for which we really
4473 // need to have the compiled collection proxy (and thus the TClass
4474 // bootstrap).
4475 clang::ClassTemplateSpecializationDecl *tmpltDecl =
4476 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
4477 (type->getAsCXXRecordDecl());
4478 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
4479 // Since the point of instantiation is invalid, we 'guess' that
4480 // the 'instantiation' of the forwarded type appended in
4481 // findscope.
4483 // For STL Collection we return kUnknown.
4484 return kUnknown;
4485 }
4486 }
4487 }
4489 if (!tci.IsValid()) {
4490 return kUnknown;
4491 }
4494
4495 if (tci.Property() & propertiesMask) {
4496 bool hasClassDefInline = false;
4498 // We do not need to check for ClassDefInline when this is called from
4499 // TClass::Init, we only do it for the call from TClass::GetClass.
4500 auto hasDictionary = tci.GetMethod("Dictionary", "", false, nullptr, ROOT::kExactMatch);
4501 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, nullptr, ROOT::kExactMatch);
4502
4503 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
4504 int lineNumber = 0;
4505 bool success = false;
4506 std::tie(success, lineNumber) =
4509 }
4510 }
4511
4512 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
4513 // , hasClassDefInline);
4514
4515 // We are now sure that the entry is not in fact an autoload entry.
4518 return kWithClassDefInline;
4519 else
4520 return kKnown;
4521 } else {
4522 // We are now sure that the entry is not in fact an autoload entry.
4523 return kUnknown;
4524 }
4525 }
4526
4527 if (decl) {
4529 return kKnown;
4530 } else
4531 return kUnknown;
4532
4533 // Setting up iterator part of TClingTypedefInfo is too slow.
4534 // Copy the lookup code instead:
4535 /*
4536 TClingTypedefInfo t(fInterpreter, name);
4537 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
4538 delete[] classname;
4539 return kTRUE;
4540 }
4541 */
4542
4543// const clang::Decl *decl = lh.findScope(name);
4544// if (!decl) {
4545// std::string buf = TClassEdit::InsertStd(name);
4546// decl = lh.findScope(buf);
4547// }
4548
4549// return (decl);
4550}
4551
4552////////////////////////////////////////////////////////////////////////////////
4553/// Return true if there is a class template by the given name ...
4554
4556{
4557 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4558 // Interpreter transaction ahead, needs locking
4560 const clang::Decl *decl
4561 = lh.findClassTemplate(name,
4562 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4563 : cling::LookupHelper::NoDiagnostics);
4564 if (!decl) {
4565 std::string strname = "std::";
4566 strname += name;
4567 decl = lh.findClassTemplate(strname,
4568 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4569 : cling::LookupHelper::NoDiagnostics);
4570 }
4571 return nullptr != decl;
4572}
4573
4574////////////////////////////////////////////////////////////////////////////////
4575/// Create list of pointers to base class(es) for TClass cl.
4576
4578{
4580 if (cl->fBase) {
4581 return;
4582 }
4583 // Ignore the base class (e.g. `std::_Complex_base` on Windows)
4585 cl->fBase = new TList();
4586 return;
4587 }
4589 if (!tci) return;
4591 TList *listOfBase = new TList;
4592 while (t.Next()) {
4593 // if name cannot be obtained no use to put in list
4594 if (t.IsValid() && t.Name()) {
4596 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
4597 }
4598 }
4599 // Now that is complete, publish it.
4600 cl->fBase = listOfBase;
4601}
4602
4603////////////////////////////////////////////////////////////////////////////////
4604/// Create list of pointers to enums for TClass cl.
4605
4607{
4609
4610 const Decl * D;
4611 TClass* cl = enumList.GetClass();
4612 if (cl) {
4613 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4614 }
4615 else {
4616 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4617 }
4618 // Iterate on the decl of the class and get the enums.
4619 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4620 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4621 // Collect all contexts of the namespace.
4622 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4623 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4625 declIter != declEnd; ++declIter) {
4626 // Iterate on all decls for each context.
4627 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4628 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4629 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4630 // Get name of the enum type.
4631 std::string buf;
4632 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4633 llvm::raw_string_ostream stream(buf);
4634 // Don't trigger fopen of the source file to count lines:
4635 Policy.AnonymousTagLocations = false;
4636 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
4637 stream.flush();
4638 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
4639 if (!buf.empty()) {
4640 const char* name = buf.c_str();
4641 // Add the enum to the list of loaded enums.
4642 enumList.Get(ED, name);
4643 }
4644 }
4645 }
4646 }
4647 }
4648}
4649
4650////////////////////////////////////////////////////////////////////////////////
4651/// Create list of pointers to function templates for TClass cl.
4652
4654{
4656
4657 const Decl * D;
4659 if (cl) {
4660 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4662 }
4663 else {
4664 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4665 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4666 }
4667 // Iterate on the decl of the class and get the enums.
4668 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4669 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4670 // Collect all contexts of the namespace.
4671 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4672 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4675 // Iterate on all decls for each context.
4676 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4677 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4678 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4679 funcTempList->Get(FTD);
4680 }
4681 }
4682 }
4683 }
4684}
4685
4686////////////////////////////////////////////////////////////////////////////////
4687/// Get the scopes representing using declarations of namespace
4688
4689std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4690{
4692 return ci->GetUsingNamespaces();
4693}
4694
4695////////////////////////////////////////////////////////////////////////////////
4696/// Create list of pointers to data members for TClass cl.
4697/// This is now a nop. The creation and updating is handled in
4698/// TListOfDataMembers.
4699
4701{
4702}
4703
4704////////////////////////////////////////////////////////////////////////////////
4705/// Create list of pointers to methods for TClass cl.
4706/// This is now a nop. The creation and updating is handled in
4707/// TListOfFunctions.
4708
4710{
4711}
4712
4713////////////////////////////////////////////////////////////////////////////////
4714/// Update the list of pointers to method for TClass cl
4715/// This is now a nop. The creation and updating is handled in
4716/// TListOfFunctions.
4717
4719{
4720}
4721
4722////////////////////////////////////////////////////////////////////////////////
4723/// Update the list of pointers to data members for TClass cl
4724/// This is now a nop. The creation and updating is handled in
4725/// TListOfDataMembers.
4726
4728{
4729}
4730
4731////////////////////////////////////////////////////////////////////////////////
4732/// Create list of pointers to method arguments for TMethod m.
4733
4735{
4737 if (m->fMethodArgs) {
4738 return;
4739 }
4740 TList *arglist = new TList;
4742 while (t.Next()) {
4743 if (t.IsValid()) {
4745 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4746 }
4747 }
4748 m->fMethodArgs = arglist;
4749}
4750
4751////////////////////////////////////////////////////////////////////////////////
4752/// Return whether we are waiting for more input either because the collected
4753/// input contains unbalanced braces or last seen token was a `\` (backslash-newline)
4754
4756{
4757 return fMetaProcessor->awaitingMoreInput();
4758}
4759
4760////////////////////////////////////////////////////////////////////////////////
4761/// Generate a TClass for the given class.
4762/// Since the caller has already check the ClassInfo, let it give use the
4763/// result (via the value of emulation) rather than recalculate it.
4764
4765TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4766{
4767// For now the following line would lead to the (unwanted) instantiation
4768// of class template. This could/would need to be resurrected only if
4769// we re-introduce so sort of automatic instantiation. However this would
4770// have to include carefull look at the template parameter to avoid
4771// creating instance we can not really use (if the parameter are only forward
4772// declaration or do not have all the necessary interfaces).
4773
4774 // TClingClassInfo tci(fInterpreter, classname);
4775 // if (1 || !tci.IsValid()) {
4776
4777 Version_t version = 1;
4778 if (TClassEdit::IsSTLCont(classname)) {
4779 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4780 }
4782 TClass *cl = new TClass(classname, version, silent);
4783 if (!emulation) {
4784 // Set the class version if the class is versioned.
4785 // Note that we cannot just call CLASS::Class_Version() as we might not have
4786 // an execution engine (when invoked from rootcling).
4787
4788 // Do not call cl->GetClassVersion(), it has side effects!
4790 if (oldvers == version && cl->GetClassInfo()) {
4791 // We have a version and it might need an update.
4793 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4794 // Namespaces don't have class versions.
4795 return cl;
4796 }
4797 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", nullptr /*poffset*/,
4800 if (!mi.IsValid()) {
4801 if (cl->TestBit(TClass::kIsTObject)) {
4802 Error("GenerateTClass",
4803 "Cannot find %s::Class_Version()! Class version might be wrong.",
4804 cl->GetName());
4805 }
4806 return cl;
4807 }
4808 Version_t newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4809 *fInterpreter);
4810 if (newvers == -1) {
4811 // Didn't manage to determine the class version from the AST.
4812 // Use runtime instead.
4813 if ((mi.Property() & kIsStatic)
4814 && !fInterpreter->isInSyntaxOnlyMode()) {
4815 // This better be a static function.
4817 callfunc.SetFunc(&mi);
4818 newvers = callfunc.ExecInt(nullptr);
4819 } else {
4820 Error("GenerateTClass",
4821 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4822 cl->GetName());
4823 }
4824 }
4825 if (newvers != oldvers) {
4826 cl->fClassVersion = newvers;
4827 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4828 }
4829 }
4830 }
4831
4832 return cl;
4833
4834// } else {
4835// return GenerateTClass(&tci,silent);
4836// }
4837}
4838
4839#if 0
4840////////////////////////////////////////////////////////////////////////////////
4841
4842static void GenerateTClass_GatherInnerIncludes(cling::Interpreter *interp, TString &includes,TClingClassInfo *info)
4843{
4844 includes += info->FileName();
4845
4846 const clang::ClassTemplateSpecializationDecl *templateCl
4847 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4848 if (templateCl) {
4849 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4850 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4851 if (arg.getKind() == clang::TemplateArgument::Type) {
4852 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4853
4854 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4855 // We really need a header file.
4856 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4857 if (argdecl) {
4858 includes += ";";
4859 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4861 } else {
4862 std::string Result;
4863 llvm::raw_string_ostream OS(Result);
4864 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4865 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4866 }
4867 }
4868 }
4869 }
4870 }
4871}
4872#endif
4873
4874////////////////////////////////////////////////////////////////////////////////
4875/// Generate a TClass for the given class.
4876
4878{
4880 if (!info || !info->IsValid()) {
4881 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4882 return nullptr;
4883 }
4884 // We are in the case where we have AST nodes for this class.
4885 TClass *cl = nullptr;
4886 std::string classname;
4887 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4888 if (TClassEdit::IsSTLCont(classname)) {
4889#if 0
4890 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4891 // We need to build up the list of required headers, by
4892 // looking at each template arguments.
4893 TString includes;
4895
4896 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4897 // 0 means success.
4898 cl = TClass::LoadClass(classnam.c_str(), silent);
4899 if (cl == 0) {
4900 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4901 }
4902 }
4903#endif
4904 if (cl == nullptr) {
4905 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4906 cl = new TClass(classinfo, version, nullptr, nullptr, -1, -1, silent);
4907 }
4908 } else {
4909 // For regular class, just create a TClass on the fly ...
4910 // Not quite useful yet, but that what CINT used to do anyway.
4911 cl = new TClass(classinfo, 1, nullptr, nullptr, -1, -1, silent);
4912 }
4913 // Add the new TClass to the map of declid and TClass*.
4914 if (cl) {
4916 }
4917 return cl;
4918}
4919
4920////////////////////////////////////////////////////////////////////////////////
4921/// Generate the dictionary for the C++ classes listed in the first
4922/// argument (in a semi-colon separated list).
4923/// 'includes' contains a semi-colon separated list of file to
4924/// `#include` in the dictionary.
4925/// For example:
4926/// ~~~ {.cpp}
4927/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4928/// ~~~
4929/// or
4930/// ~~~ {.cpp}
4931/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4932/// ~~~
4933
4934Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4935{
4936 if (classes == nullptr || classes[0] == 0) {
4937 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4938 return 0;
4939 }
4940 // Split the input list
4941 std::vector<std::string> listClasses;
4942 for (
4943 const char* current = classes, *prev = classes;
4944 *current != 0;
4945 ++current
4946 ) {
4947 if (*current == ';') {
4948 listClasses.push_back(std::string(prev, current - prev));
4949 prev = current + 1;
4950 }
4951 else if (*(current + 1) == 0) {
4952 listClasses.push_back(std::string(prev, current + 1 - prev));
4953 prev = current + 1;
4954 }
4955 }
4956 std::vector<std::string> listIncludes;
4957 if (!includes)
4958 includes = "";
4959 for (
4960 const char* current = includes, *prev = includes;
4961 *current != 0;
4962 ++current
4963 ) {
4964 if (*current == ';') {
4965 listIncludes.push_back(std::string(prev, current - prev));
4966 prev = current + 1;
4967 }
4968 else if (*(current + 1) == 0) {
4969 listIncludes.push_back(std::string(prev, current + 1 - prev));
4970 prev = current + 1;
4971 }
4972 }
4973 // Generate the temporary dictionary file
4975 std::vector<std::string>(), std::vector<std::string>());
4976}
4977
4978////////////////////////////////////////////////////////////////////////////////
4979/// Return pointer to cling Decl of global/static variable that is located
4980/// at the address given by addr.
4981
4983{
4985 DeclId_t d;
4987
4988 // Could trigger deserialization of decls.
4989 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4990
4991 if (cl) {
4992 d = cl->GetDataMember(name);
4993 // We check if the decl of the data member has an annotation which indicates
4994 // an ioname.
4995 // In case this is true, if the name requested is not the ioname, we
4996 // return 0, as if the member did not exist. In some sense we override
4997 // the information in the TClassInfo instance, isolating the typesystem in
4998 // TClass from the one in the AST.
4999 if (const ValueDecl* decl = (const ValueDecl*) d){
5000 std::string ioName;
5002 if (hasIoName && ioName != name) return nullptr;
5003 }
5004 return d;
5005 }
5006 // We are looking up for something on the TU scope.
5007 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
5008 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
5009 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
5010 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
5011 // are only fulfilling ROOT's understanding for a Data Member.
5012 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
5013 // similar as below.
5014 using namespace clang;
5015 Sema& SemaR = fInterpreter->getSema();
5016 DeclarationName DName = &SemaR.Context.Idents.get(name);
5017
5018 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
5019 RedeclarationKind::ForExternalRedeclaration);
5020
5021 cling::utils::Lookup::Named(&SemaR, R);
5022
5023 LookupResult::Filter F = R.makeFilter();
5024 // Filter the data-member looking decls.
5025 while (F.hasNext()) {
5026 NamedDecl *D = F.next();
5029 continue;
5030 F.erase();
5031 }
5032 F.done();
5033
5034 if (R.isSingleResult())
5035 return R.getFoundDecl();
5036 return nullptr;
5037}
5038
5039////////////////////////////////////////////////////////////////////////////////
5040/// Return pointer to cling Decl of global/static variable that is located
5041/// at the address given by addr.
5042
5044{
5046
5047 const clang::Decl* possibleEnum = nullptr;
5048 // FInd the context of the decl.
5049 if (cl) {
5051 if (cci) {
5052 const clang::DeclContext* dc = nullptr;
5053 if (const clang::Decl* D = cci->GetDecl()) {
5054 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
5056 }
5057 }
5058 if (dc) {
5059 // If it is a data member enum.
5060 // Could trigger deserialization of decls.
5061 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
5062 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
5063 } else {
5064 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
5065 }
5066 }
5067 } else {
5068 // If it is a global enum.
5069 // Could trigger deserialization of decls.
5070 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
5071 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
5072 }
5073 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
5075 return possibleEnum;
5076 }
5077 return nullptr;
5078}
5079
5080////////////////////////////////////////////////////////////////////////////////
5081/// Return pointer to cling DeclId for a global value
5082
5083TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
5084{
5085 if (!gv) return nullptr;
5086
5087 llvm::StringRef mangled_name = gv->getName();
5088
5089 int err = 0;
5091 if (err) {
5092 if (err == -2) {
5093 // It might simply be an unmangled global name.
5094 DeclId_t d;
5096 d = gcl.GetDataMember(mangled_name.str().c_str());
5097 return d;
5098 }
5099 return nullptr;
5100 }
5101
5102 std::string scopename(demangled_name_c);
5104
5105 //
5106 // Separate out the class or namespace part of the
5107 // function name.
5108 //
5109 std::string dataname;
5110
5111 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
5112 scopename.erase(0, sizeof("typeinfo for ")-1);
5113 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
5114 scopename.erase(0, sizeof("vtable for ")-1);
5115 } else {
5116 // See if it is a function
5117 std::string::size_type pos = scopename.rfind('(');
5118 if (pos != std::string::npos) {
5119 return nullptr;
5120 }
5121 // Separate the scope and member name
5122 pos = scopename.rfind(':');
5123 if (pos != std::string::npos) {
5124 if ((pos != 0) && (scopename[pos-1] == ':')) {
5125 dataname = scopename.substr(pos+1);
5126 scopename.erase(pos-1);
5127 }
5128 } else {
5129 scopename.clear();
5131 }
5132 }
5133 //fprintf(stderr, "name: '%s'\n", name.c_str());
5134 // Now we have the class or namespace name, so do the lookup.
5135
5136
5137 DeclId_t d;
5138 if (scopename.size()) {
5140 d = cl.GetDataMember(dataname.c_str());
5141 }
5142 else {
5144 d = gcl.GetDataMember(dataname.c_str());
5145 }
5146 return d;
5147}
5148
5149////////////////////////////////////////////////////////////////////////////////
5150/// NOT IMPLEMENTED.
5151
5153{
5154 Error("GetDataMemberWithValue()", "not implemented");
5155 return nullptr;
5156}
5157
5158////////////////////////////////////////////////////////////////////////////////
5159/// Return pointer to cling DeclId for a data member with a given name.
5160
5162{
5163 // NOT IMPLEMENTED.
5164 Error("GetDataMemberAtAddr()", "not implemented");
5165 return nullptr;
5166}
5167
5168////////////////////////////////////////////////////////////////////////////////
5169/// Return the cling mangled name for a method of a class with parameters
5170/// params (params is a string of actual arguments, not formal ones). If the
5171/// class is 0 the global function list will be searched.
5172
5174 const char* params, Bool_t objectIsConst /* = kFALSE */)
5175{
5178 if (cl) {
5181 &offset);
5182 }
5183 else {
5186 func.SetFunc(&gcl, method, params, &offset);
5187 }
5189 if (!mi) return "";
5190 TString mangled_name( mi->GetMangledName() );
5191 delete mi;
5192 return mangled_name;
5193}
5194
5195////////////////////////////////////////////////////////////////////////////////
5196/// Return the cling mangled name for a method of a class with a certain
5197/// prototype, i.e. "char*,int,float". If the class is 0 the global function
5198/// list will be searched.
5199
5201 const char* proto, Bool_t objectIsConst /* = kFALSE */,
5202 EFunctionMatchMode mode /* = kConversionMatch */)
5203{
5205 if (cl) {
5206 return ((TClingClassInfo*)cl->GetClassInfo())->
5207 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
5208 }
5210 return gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
5211}
5212
5213////////////////////////////////////////////////////////////////////////////////
5214/// Return pointer to cling interface function for a method of a class with
5215/// parameters params (params is a string of actual arguments, not formal
5216/// ones). If the class is 0 the global function list will be searched.
5217
5219 const char* params, Bool_t objectIsConst /* = kFALSE */)
5220{
5223 if (cl) {
5226 &offset);
5227 }
5228 else {
5231 func.SetFunc(&gcl, method, params, &offset);
5232 }
5233 return (void*) func.InterfaceMethod();
5234}
5235
5236////////////////////////////////////////////////////////////////////////////////
5237/// Return pointer to cling interface function for a method of a class with
5238/// a certain name.
5239
5241{
5243 DeclId_t f;
5245 if (cl) {
5246 f = cl->GetMethod(method).GetDeclId();
5247 }
5248 else {
5250 f = gcl.GetMethod(method).GetDeclId();
5251 }
5252 return f;
5253
5254}
5255
5256////////////////////////////////////////////////////////////////////////////////
5257/// Insert overloads of name in cl to res.
5258
5260 std::vector<DeclId_t>& res) const
5261{
5262 clang::Sema& S = fInterpreter->getSema();
5263 clang::ASTContext& Ctx = S.Context;
5264 const clang::Decl* CtxDecl
5265 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
5266 Ctx.getTranslationUnitDecl();
5267 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
5268 const clang::DeclContext* DeclCtx = RecDecl;
5269
5270 if (!DeclCtx)
5272 if (!DeclCtx) return;
5273
5274 clang::DeclarationName DName;
5275 // The DeclarationName is funcname, unless it's a ctor or dtor.
5276 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
5277
5278 if (RecDecl) {
5279 if (RecDecl->getNameAsString() == funcname) {
5280 clang::CanQualType QT = Ctx.getCanonicalTagType(RecDecl);
5281 DName = Ctx.DeclarationNames.getCXXConstructorName(QT);
5282 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
5283 clang::CanQualType QT = Ctx.getCanonicalTagType(RecDecl);
5284 DName = Ctx.DeclarationNames.getCXXDestructorName(QT);
5285 } else {
5286 DName = &Ctx.Idents.get(funcname);
5287 }
5288 } else {
5289 DName = &Ctx.Idents.get(funcname);
5290 }
5291
5292 // NotForRedeclaration: we want to find names in inline namespaces etc.
5293 clang::LookupResult R(S, DName, clang::SourceLocation(), Sema::LookupOrdinaryName,
5294 RedeclarationKind::NotForRedeclaration);
5295 R.suppressDiagnostics(); // else lookup with NotForRedeclaration will check access etc
5296 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
5297 if (R.empty()) return;
5298 R.resolveKind();
5299 res.reserve(res.size() + (R.end() - R.begin()));
5300 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
5301 IR != ER; ++IR) {
5302 if (const clang::FunctionDecl* FD
5303 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
5304 if (!FD->getDescribedFunctionTemplate()) {
5305 res.push_back(FD);
5306 }
5307 } else if (const auto *USD = llvm::dyn_cast<const clang::UsingShadowDecl>(*IR)) {
5308 // FIXME: multi-level using
5309 if (llvm::isa<clang::FunctionDecl>(USD->getTargetDecl())) {
5310 res.push_back(USD);
5311 }
5312 }
5313 }
5314}
5315
5316////////////////////////////////////////////////////////////////////////////////
5317/// Return pointer to cling interface function for a method of a class with
5318/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5319/// function list will be searched.
5320
5322 const char* proto,
5323 Bool_t objectIsConst /* = kFALSE */,
5324 EFunctionMatchMode mode /* = kConversionMatch */)
5325{
5327 void* f;
5328 if (cl) {
5329 f = ((TClingClassInfo*)cl->GetClassInfo())->
5330 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5331 }
5332 else {
5334 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5335 }
5336 return f;
5337}
5338
5339////////////////////////////////////////////////////////////////////////////////
5340/// Return pointer to cling DeclId for a method of a class with
5341/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5342/// function list will be searched.
5343
5345 const char* params,
5346 Bool_t objectIsConst /* = kFALSE */)
5347{
5349 DeclId_t f;
5351 if (cl) {
5352 f = cl->GetMethodWithArgs(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5353 }
5354 else {
5356 f = gcl.GetMethod(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5357 }
5358 return f;
5359}
5360
5361////////////////////////////////////////////////////////////////////////////////
5362/// Return pointer to cling interface function for a method of a class with
5363/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5364/// function list will be searched.
5365
5367 const char* proto,
5368 Bool_t objectIsConst /* = kFALSE */,
5369 EFunctionMatchMode mode /* = kConversionMatch */)
5370{
5372 DeclId_t f;
5374 if (cl) {
5375 f = cl->GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5376 }
5377 else {
5379 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5380 }
5381 return f;
5382}
5383
5384////////////////////////////////////////////////////////////////////////////////
5385/// Return pointer to cling interface function for a method of a class with
5386/// a certain name.
5387
5389{
5391 DeclId_t f;
5393 if (cl) {
5394 f = cl->GetFunctionTemplate(name);
5395 }
5396 else {
5398 f = gcl.GetFunctionTemplate(name);
5399 }
5400 return f;
5401
5402}
5403
5404////////////////////////////////////////////////////////////////////////////////
5405/// The 'name' is known to the interpreter, this function returns
5406/// the internal version of this name (usually just resolving typedefs)
5407/// This is used in particular to synchronize between the name used
5408/// by rootcling and by the run-time environment (TClass)
5409/// Return 0 if the name is not known.
5410
5411void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
5412{
5413 output.clear();
5414
5416
5418 if (!cl.IsValid()) {
5419 return ;
5420 }
5421 if (full) {
5422 cl.FullName(output,*fNormalizedCtxt);
5423 return;
5424 }
5425 // Well well well, for backward compatibility we need to act a bit too
5426 // much like CINT.
5428 splitname.ShortType(output, TClassEdit::kDropStd );
5429
5430 return;
5431}
5432
5433////////////////////////////////////////////////////////////////////////////////
5434/// Execute a global function with arguments params.
5435///
5436/// FIXME: The cint-based version of this code does not check if the
5437/// SetFunc() call works, and does not do any real checking
5438/// for errors from the Exec() call. It did fetch the most
5439/// recent cint security error and return that in error, but
5440/// this does not really translate well to cling/clang. We
5441/// should enhance these interfaces so that we can report
5442/// compilation and runtime errors properly.
5443
5444void TCling::Execute(const char* function, const char* params, int* error)
5445{
5447 if (error) {
5448 *error = TInterpreter::kNoError;
5449 }
5451 Longptr_t offset = 0L;
5453 func.SetFunc(&cl, function, params, &offset);
5454 func.Exec(nullptr);
5455}
5456
5457////////////////////////////////////////////////////////////////////////////////
5458/// Execute a method from class cl with arguments params.
5459///
5460/// FIXME: The cint-based version of this code does not check if the
5461/// SetFunc() call works, and does not do any real checking
5462/// for errors from the Exec() call. It did fetch the most
5463/// recent cint security error and return that in error, but
5464/// this does not really translate well to cling/clang. We
5465/// should enhance these interfaces so that we can report
5466/// compilation and runtime errors properly.
5467
5468void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5469 const char* params, Bool_t objectIsConst, int* error)
5470{
5472 if (error) {
5473 *error = TInterpreter::kNoError;
5474 }
5475 // If the actual class of this object inherits 2nd (or more) from TObject,
5476 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5477 // hence gInterpreter->Execute will improperly correct the offset.
5478 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5479 Longptr_t offset = 0L;
5482 void* address = (void*)((Longptr_t)addr + offset);
5483 func.Exec(address);
5484}
5485
5486////////////////////////////////////////////////////////////////////////////////
5487
5488void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5489 const char* params, int* error)
5490{
5491 Execute(obj,cl,method,params,false,error);
5492}
5493
5494////////////////////////////////////////////////////////////////////////////////
5495/// Execute a method from class cl with the arguments in array params
5496/// (params[0] ... params[n] = array of TObjString parameters).
5497/// Convert the TObjArray array of TObjString parameters to a character
5498/// string of comma separated parameters.
5499/// The parameters of type 'char' are enclosed in double quotes and all
5500/// internal quotes are escaped.
5501
5503 TObjArray* params, int* error)
5504{
5505 if (!method) {
5506 Error("Execute", "No method was defined");
5507 return;
5508 }
5509 TList* argList = method->GetListOfMethodArgs();
5510 // Check number of actual parameters against of expected formal ones
5511
5512 Int_t nparms = argList->LastIndex() + 1;
5513 Int_t argc = params ? params->GetEntries() : 0;
5514
5515 if (argc > nparms) {
5516 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
5517 return;
5518 }
5519 if (nparms != argc) {
5520 // Let's see if the 'missing' argument are all defaulted.
5521 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
5522 assert(nparms > 0);
5523
5524 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
5525 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5526 // There is a default value for the first missing
5527 // argument, so we are fine.
5528 } else {
5529 Int_t firstDefault = -1;
5530 for (Int_t i = 0; i < nparms; i ++) {
5531 arg = (TMethodArg *) argList->At( i );
5532 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5533 firstDefault = i;
5534 break;
5535 }
5536 }
5537 if (firstDefault >= 0) {
5538 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);
5539 } else {
5540 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
5541 }
5542 return;
5543 }
5544 }
5545
5546 const char* listpar = "";
5547 TString complete(10);
5548 if (params) {
5549 // Create a character string of parameters from TObjArray
5550 TIter next(params);
5551 for (Int_t i = 0; i < argc; i ++) {
5552 TMethodArg* arg = (TMethodArg*) argList->At(i);
5554 TObjString* nxtpar = (TObjString*) next();
5555 if (i) {
5556 complete += ',';
5557 }
5558 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
5559 TString chpar('\"');
5560 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
5561 // At this point we have to check if string contains \\"
5562 // and apply some more sophisticated parser. Not implemented yet!
5563 complete += chpar;
5564 complete += '\"';
5565 }
5566 else {
5567 complete += nxtpar->String();
5568 }
5569 }
5570 listpar = complete.Data();
5571 }
5572
5573 // And now execute it.
5575 if (error) {
5576 *error = TInterpreter::kNoError;
5577 }
5578 // If the actual class of this object inherits 2nd (or more) from TObject,
5579 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5580 // hence gInterpreter->Execute will improperly correct the offset.
5581 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5584 func.Init(*minfo);
5585 func.SetArgs(listpar);
5586 // Now calculate the 'this' pointer offset for the method
5587 // when starting from the class described by cl.
5588 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetTargetFunctionDecl());
5589 Longptr_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
5590 void* address = (void*)((Longptr_t)addr + offset);
5591 func.Exec(address);
5592}
5593
5594////////////////////////////////////////////////////////////////////////////////
5595
5597 const void* args[] /*=0*/,
5598 int nargs /*=0*/,
5599 void* ret/*= 0*/) const
5600{
5601 if (!method) {
5602 Error("ExecuteWithArgsAndReturn", "No method was defined");
5603 return;
5604 }
5605
5607 TClingCallFunc func(*minfo);
5608 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5609}
5610
5611////////////////////////////////////////////////////////////////////////////////
5612/// Execute a cling macro.
5613
5615{
5617 fCurExecutingMacros.push_back(filename);
5619 fCurExecutingMacros.pop_back();
5620 return result;
5621}
5622
5623////////////////////////////////////////////////////////////////////////////////
5624/// Return the file name of the current un-included interpreted file.
5625/// See the documentation for GetCurrentMacroName().
5626
5628{
5629 Warning("GetTopLevelMacroName", "Must change return type!");
5630 return fCurExecutingMacros.empty() ? nullptr : fCurExecutingMacros.back();
5631}
5632
5633////////////////////////////////////////////////////////////////////////////////
5634/// Return the file name of the currently interpreted file,
5635/// included or not. Example to illustrate the difference between
5636/// GetCurrentMacroName() and GetTopLevelMacroName():
5637/// ~~~ {.cpp}
5638/// void inclfile() {
5639/// std::cout << "In inclfile.C" << std::endl;
5640/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5641/// TCling::GetCurrentMacroName() << std::endl;
5642/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5643/// TCling::GetTopLevelMacroName() << std::endl;
5644/// }
5645/// ~~~
5646/// ~~~ {.cpp}
5647/// void mymacro() {
5648/// std::cout << "In mymacro.C" << std::endl;
5649/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5650/// TCling::GetCurrentMacroName() << std::endl;
5651/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5652/// TCling::GetTopLevelMacroName() << std::endl;
5653/// std::cout << " Now calling inclfile..." << std::endl;
5654/// gInterpreter->ProcessLine(".x inclfile.C");
5655/// }
5656/// ~~~
5657/// Running mymacro.C will print:
5658///
5659/// ~~~ {.cpp}
5660/// root [0] .x mymacro.C
5661/// ~~~
5662/// In mymacro.C
5663/// ~~~ {.cpp}
5664/// TCling::GetCurrentMacroName() returns ./mymacro.C
5665/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5666/// ~~~
5667/// Now calling inclfile...
5668/// In inclfile.h
5669/// ~~~ {.cpp}
5670/// TCling::GetCurrentMacroName() returns inclfile.C
5671/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5672/// ~~~
5673
5675{
5676#if defined(R__MUST_REVISIT)
5677#if R__MUST_REVISIT(6,0)
5678 Warning("GetCurrentMacroName", "Must change return type!");
5679#endif
5680#endif
5681 return fCurExecutingMacros.empty() ? nullptr : fCurExecutingMacros.back();
5682}
5683
5684////////////////////////////////////////////////////////////////////////////////
5685/// Return the absolute type of typeDesc.
5686/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
5687/// You need to use the result immediately before it is being overwritten.
5688
5689const char* TCling::TypeName(const char* typeDesc)
5690{
5691 TTHREAD_TLS_DECL(std::string,t);
5692
5693 if (!strstr(typeDesc, "(*)(")) {
5694 const char *s = strchr(typeDesc, ' ');
5695 const char *template_start = strchr(typeDesc, '<');
5696 if (!strcmp(typeDesc, "long long")) {
5697 t = typeDesc;
5698 }
5699 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5700 t = typeDesc;
5701 }
5702 // s is the position of the second 'word' (if any)
5703 // except in the case of templates where there will be a space
5704 // just before any closing '>': eg.
5705 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5706 else if (s && (template_start == nullptr || (s < template_start))) {
5707 t = s + 1;
5708 }
5709 else {
5710 t = typeDesc;
5711 }
5712 }
5713 else {
5714 t = typeDesc;
5715 }
5716 auto l = t.length();
5717 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&'))
5718 --l;
5719 t.resize(l);
5720 return t.c_str(); // NOLINT
5721}
5722
5723static bool requiresRootMap(const char* rootmapfile)
5724{
5726
5727 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5728 libName.consume_back(".rootmap");
5729
5730 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5731}
5732
5733////////////////////////////////////////////////////////////////////////////////
5734/// Read and parse a rootmapfile in its new format, and return 0 in case of
5735/// success, -1 if the file has already been read, and -3 in case its format
5736/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5737/// error.
5738
5740{
5741 if (!(rootmapfile && *rootmapfile))
5742 return 0;
5743
5745 return 0; // success
5746
5747 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5748 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5749
5751#ifdef _MSC_VER
5752 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5753#endif
5754 // Add content of a specific rootmap file
5756 return -1;
5757
5758 // Line 1 is `{ decls }`
5759 std::string lineDirective = std::string("\n#line 2 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n";
5760
5761 std::ifstream file(rootmapfileNoBackslash);
5762 std::string line;
5763 line.reserve(200);
5764 std::string lib_name;
5765 line.reserve(100);
5766 bool newFormat = false;
5767 while (getline(file, line, '\n')) {
5768 if (!newFormat && (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5769 file.close();
5770 return -3; // old format
5771 }
5772 newFormat = true;
5773
5774 if (line.compare(0, 9, "{ decls }") == 0) {
5775 // forward declarations
5776
5777 while (getline(file, line, '\n')) {
5778 if (line[0] == '[')
5779 break;
5780 if (!uniqueString) {
5781 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5782 rootmapfileNoBackslash.c_str());
5783 return -4;
5784 }
5785 if (!lineDirective.empty())
5786 uniqueString->Append(lineDirective);
5787 uniqueString->Append(line + '\n');
5788 }
5789 }
5790 const char firstChar = line[0];
5791 if (firstChar == '[') {
5792 // new section (library)
5793 auto brpos = line.find(']');
5794 if (brpos == string::npos)
5795 continue;
5796 lib_name = line.substr(1, brpos - 1);
5797 // Remove spaces at the beginning and at the end of the library name
5798 lib_name.erase(lib_name.find_last_not_of(' ') + 1);
5799 lib_name.erase(0, lib_name.find_first_not_of(' '));
5800 if (gDebug > 3) {
5801 TString lib_nameTstr(lib_name.c_str());
5802 TObjArray *tokens = lib_nameTstr.Tokenize(" ");
5803 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5804 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5805 if (wlib) {
5806 Info("ReadRootmapFile", "%s: New section for %s", rootmapfile, lib_nameTstr.Data());
5807 } else {
5808 Info("ReadRootmapFile", "%s: Section for %s (library does not exist)", rootmapfile, lib_nameTstr.Data());
5809 }
5810 delete[] wlib;
5811 delete tokens;
5812 }
5813 } else {
5814 auto keyLenIt = keyLenMap.find(firstChar);
5815 if (keyLenIt == keyLenMap.end())
5816 continue;
5817 unsigned int keyLen = keyLenIt->second;
5818 // Do not make a copy, just start after the key
5819 const char *keyname = line.c_str() + keyLen;
5820 if (gDebug > 6)
5821 Info("ReadRootmapFile", "%s: class %s in %s", rootmapfile, keyname, lib_name.c_str());
5823 if (isThere) {
5824 if (lib_name != isThere->GetValue()) { // the same key for two different libs
5825 if (firstChar == 'n') {
5826 if (gDebug > 3)
5827 Info("ReadRootmapFile",
5828 "While processing %s, namespace %s was found to be associated to %s although it is already "
5829 "associated to %s",
5830 rootmapfile, keyname, lib_name.c_str(), isThere->GetValue());
5831 } else if (firstChar == 'h') { // it is a header: add the libname to the list of libs to be loaded.
5832 lib_name += " ";
5833 lib_name += isThere->GetValue();
5834 fMapfile->SetValue(keyname, lib_name.c_str());
5835 } else if (!TClassEdit::IsSTLCont(keyname)) {
5836 Warning("ReadRootmapFile",
5837 "While processing %s, %s %s was found to be associated to %s although it is already "
5838 "associated to %s",
5839 rootmapfile, line.substr(0, keyLen - 1).c_str(), keyname, lib_name.c_str(),
5840 isThere->GetValue());
5841 }
5842 } else { // the same key for the same lib
5843 if (gDebug > 3)
5844 Info("ReadRootmapFile", "While processing %s, key %s was found to be already defined for %s",
5845 rootmapfile, keyname, lib_name.c_str());
5846 }
5847 } else {
5848 fMapfile->SetValue(keyname, lib_name.c_str());
5849 }
5850 }
5851 }
5852 file.close();
5853 return 0;
5854}
5855
5856////////////////////////////////////////////////////////////////////////////////
5857/// Create a resource table and read the (possibly) three resource files,
5858/// i.e. `$ROOTSYS/etc/system<name>` (or `ROOTETCDIR/system<name>`), `$HOME/<name>`
5859/// and `$PWD/<name>`. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You
5860/// can read additional user defined resource files by creating additional TEnv
5861/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5862/// the `$HOME/<name>` resource file will be skipped. This might be useful in
5863/// case the home directory resides on an automounted remote file system
5864/// and one wants to avoid the file system from being mounted.
5865
5867{
5868 assert(requiresRootMap(name) && "We have a module!");
5869
5870 if (!requiresRootMap(name))
5871 return;
5872
5874
5876
5877 TString sname = "system";
5878 sname += name;
5881
5883 if (ret == -3) // old format
5885 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5889 if (ret == -3) // old format
5893 if (ret == -3) // old format
5895 }
5896 } else {
5898 if (ret == -3) // old format
5900 }
5902}
5903
5904
5905namespace {
5906 using namespace clang;
5907
5908 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5909 // This class is to be considered an helper for AutoLoading.
5910 // It is a recursive visitor is used to inspect namespaces and specializations
5911 // coming from forward declarations in rootmaps and to set the external visible
5912 // storage flag for them.
5913 public:
5914 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5915 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5916 // We want to enable the external lookup for this namespace
5917 // because it may shadow the lookup of other names contained
5918 // in that namespace
5919
5920 nsDecl->setHasExternalVisibleStorage();
5921 fNSSet.insert(nsDecl);
5922 return true;
5923 }
5925 // We want to enable the external lookup for this specialization
5926 // because we can provide a definition for it!
5927 if (specDecl->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
5928 //SpecSet.insert(specDecl);
5929 specDecl->setHasExternalLexicalStorage();
5930
5931 // No need to recurse. On the contrary, recursing is actively harmful:
5932 // NOTE: must not recurse to prevent this visitor from triggering loading from
5933 // the external AST source (i.e. autoloading). This would be triggered right here,
5934 // before autoloading is even set up, as rootmap file parsing happens before that.
5935 // Even if autoloading is off and has no effect, triggering loading from external
5936 // AST source resets the flag setHasExternalLexicalStorage(), hiding this specialization
5937 // from subsequent autoloads!
5938 return false;
5939 }
5940 private:
5941 std::unordered_set<const NamespaceDecl*>& fNSSet;
5942 };
5943}
5944
5945////////////////////////////////////////////////////////////////////////////////
5946/// Load map between class and library. If rootmapfile is specified a
5947/// specific rootmap file can be added (typically used by ACLiC).
5948/// In case of error -1 is returned, 0 otherwise.
5949/// The interpreter uses this information to automatically load the shared
5950/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5951
5953{
5955 return 0;
5956
5958
5959 // open the [system].rootmap files
5960 if (!fMapfile) {
5961 fMapfile = new TEnv();
5965 InitRootmapFile(".rootmap");
5966 }
5967
5968 // Prepare a list of all forward declarations for cling
5969 // For some experiments it is easily as big as 500k characters. To be on the
5970 // safe side, we go for 1M.
5971 TUniqueString uniqueString(1048576);
5972
5973 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5974 // A rootmap file must end with the string ".rootmap".
5976 if (ldpath != fRootmapLoadPath) {
5978#ifdef WIN32
5979 TObjArray* paths = ldpath.Tokenize(";");
5980#else
5981 TObjArray* paths = ldpath.Tokenize(":");
5982#endif
5983 TString d;
5984 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5985 d = ((TObjString *)paths->At(i))->GetString();
5986 // check if directory already scanned
5987 Int_t skip = 0;
5988 for (Int_t j = 0; j < i; j++) {
5989 TString pd = ((TObjString *)paths->At(j))->GetString();
5990 if (pd == d) {
5991 skip++;
5992 break;
5993 }
5994 }
5995 if (!skip) {
5996 void* dirp = gSystem->OpenDirectory(d);
5997 if (dirp) {
5998 if (gDebug > 3) {
5999 Info("LoadLibraryMap", "%s", d.Data());
6000 }
6001 const char* f1;
6002 while ((f1 = gSystem->GetDirEntry(dirp))) {
6003 TString f = f1;
6004 if (f.EndsWith(".rootmap")) {
6005 TString p;
6006 p = d + "/" + f;
6008 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
6009 if (gDebug > 4) {
6010 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
6011 }
6013
6014 if (ret == 0)
6015 fRootmapFiles->Add(new TNamed(gSystem->BaseName(f), p.Data()));
6016 if (ret == -3) {
6017 // old format
6019 fRootmapFiles->Add(new TNamed(f, p));
6020 }
6021 }
6022 // else {
6023 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
6024 // fRootmapFiles->FindObject(f)->ls();
6025 // }
6026 }
6027 }
6028 if (f.BeginsWith("rootmap")) {
6029 TString p;
6030 p = d + "/" + f;
6032 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
6033 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
6034 }
6035 }
6036 }
6037 }
6039 }
6040 }
6041 delete paths;
6042 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
6043 return -1;
6044 }
6045 }
6046 if (rootmapfile && *rootmapfile) {
6048 if (res == 0) {
6049 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
6050 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
6052 }
6053 else if (res == -3) {
6054 // old format
6059 }
6060 }
6061 TEnvRec* rec;
6062 TIter next(fMapfile->GetTable());
6063 while ((rec = (TEnvRec*) next())) {
6064 TString cls = rec->GetName();
6065 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
6066 // get the first lib from the list of lib and dependent libs
6067 TString libs = rec->GetValue();
6068 if (libs == "") {
6069 continue;
6070 }
6071 TString delim(" ");
6072 TObjArray* tokens = libs.Tokenize(delim);
6073 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6074 // convert "@@" to "::", we used "@@" because TEnv
6075 // considers "::" a terminator
6076 cls.Remove(0, 8);
6077 cls.ReplaceAll("@@", "::");
6078 // convert "-" to " ", since class names may have
6079 // blanks and TEnv considers a blank a terminator
6080 cls.ReplaceAll("-", " ");
6081 if (gDebug > 6) {
6082 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
6083 if (wlib) {
6084 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
6085 }
6086 else {
6087 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
6088 }
6089 delete[] wlib;
6090 }
6091 delete tokens;
6092 }
6093 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
6094 cls.Remove(0, 8);
6095 // convert "-" to " ", since class names may have
6096 // blanks and TEnv considers a blank a terminator
6097 cls.ReplaceAll("-", " ");
6098 fInterpreter->declare(cls.Data());
6099 }
6100 }
6101
6102 // Process the forward declarations collected
6103 cling::Transaction* T = nullptr;
6104 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
6105 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
6106
6107 if (compRes!=cling::Interpreter::kSuccess){
6108 Warning("LoadLibraryMap",
6109 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
6110 }
6111
6112 if (T) {
6113 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
6114 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
6115 if (declIt->m_DGR.isSingleDecl()) {
6116 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
6117 if (clang::isa<TagDecl>(D) || clang::isa<NamespaceDecl>(D)) {
6118 evsAdder.TraverseDecl(D);
6119 }
6120 }
6121 }
6122 }
6123 }
6124
6125 // clear duplicates
6126
6127 return 0;
6128}
6129
6130////////////////////////////////////////////////////////////////////////////////
6131/// Scan again along the dynamic path for library maps. Entries for the loaded
6132/// shared libraries are unloaded first. This can be useful after reseting
6133/// the dynamic path through TSystem::SetDynamicPath()
6134/// In case of error -1 is returned, 0 otherwise.
6135
6142
6143////////////////////////////////////////////////////////////////////////////////
6144/// Reload the library map entries coming from all the loaded shared libraries,
6145/// after first unloading the current ones.
6146/// In case of error -1 is returned, 0 otherwise.
6147
6149{
6151 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
6152 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
6153 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
6154 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
6157 if (ret < 0) {
6158 continue;
6159 }
6161 if (sharedLibBaseStr.EndsWith(".dll")) {
6162 rootMapBaseStr.ReplaceAll(".dll", "");
6163 }
6164 else if (sharedLibBaseStr.EndsWith(".DLL")) {
6165 rootMapBaseStr.ReplaceAll(".DLL", "");
6166 }
6167 else if (sharedLibBaseStr.EndsWith(".so")) {
6168 rootMapBaseStr.ReplaceAll(".so", "");
6169 }
6170 else if (sharedLibBaseStr.EndsWith(".sl")) {
6171 rootMapBaseStr.ReplaceAll(".sl", "");
6172 }
6173 else if (sharedLibBaseStr.EndsWith(".dl")) {
6174 rootMapBaseStr.ReplaceAll(".dl", "");
6175 }
6176 else if (sharedLibBaseStr.EndsWith(".a")) {
6177 rootMapBaseStr.ReplaceAll(".a", "");
6178 }
6179 else {
6180 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
6181 delete sharedLibL;
6182 return -1;
6183 }
6184 rootMapBaseStr += ".rootmap";
6186 if (!rootMap) {
6187 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
6188 delete[] rootMap;
6189 delete sharedLibL;
6190 return -1;
6191 }
6192 const Int_t status = LoadLibraryMap(rootMap);
6193 if (status < 0) {
6194 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
6195 delete[] rootMap;
6196 delete sharedLibL;
6197 return -1;
6198 }
6199 delete[] rootMap;
6200 }
6201 delete sharedLibL;
6202 return 0;
6203}
6204
6205////////////////////////////////////////////////////////////////////////////////
6206/// Unload the library map entries coming from all the loaded shared libraries.
6207/// Returns 0 if succesful
6208
6210{
6212 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
6213 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
6214 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
6217 }
6218 delete sharedLibL;
6219 return 0;
6220}
6221
6222////////////////////////////////////////////////////////////////////////////////
6223/// Unload library map entries coming from the specified library.
6224/// Returns -1 in case no entries for the specified library were found,
6225/// 0 otherwise.
6226
6228{
6229 if (!fMapfile || !library || !*library) {
6230 return 0;
6231 }
6233 Ssiz_t idx = libname.Last('.');
6234 if (idx != kNPOS) {
6235 libname.Remove(idx);
6236 }
6237 size_t len = libname.Length();
6238 TEnvRec *rec;
6239 TIter next(fMapfile->GetTable());
6241 Int_t ret = 0;
6242 while ((rec = (TEnvRec *) next())) {
6243 TString cls = rec->GetName();
6244 if (cls.Length() > 2) {
6245 // get the first lib from the list of lib and dependent libs
6246 TString libs = rec->GetValue();
6247 if (libs == "") {
6248 continue;
6249 }
6250 TString delim(" ");
6251 TObjArray* tokens = libs.Tokenize(delim);
6252 const char* lib = ((TObjString *)tokens->At(0))->GetName();
6253 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
6254 // convert "@@" to "::", we used "@@" because TEnv
6255 // considers "::" a terminator
6256 cls.Remove(0, 8);
6257 cls.ReplaceAll("@@", "::");
6258 // convert "-" to " ", since class names may have
6259 // blanks and TEnv considers a blank a terminator
6260 cls.ReplaceAll("-", " ");
6261 }
6262 if (!strncmp(lib, libname.Data(), len)) {
6263 if (fMapfile->GetTable()->Remove(rec) == nullptr) {
6264 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
6265 ret = -1;
6266 }
6267 }
6268 delete tokens;
6269 }
6270 }
6271 if (ret >= 0) {
6273 if (!library_rootmap.EndsWith(".rootmap"))
6274 library_rootmap.Append(".rootmap");
6275 TNamed* mfile = nullptr;
6278 delete mfile;
6279 }
6281 }
6282 return ret;
6283}
6284
6285////////////////////////////////////////////////////////////////////////////////
6286/// Register the AutoLoading information for a class.
6287/// libs is a space separated list of libraries.
6288
6289Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
6290{
6291 if (!cls || !*cls)
6292 return 0;
6293
6294 TString key = TString("Library.") + cls;
6295 // convert "::" to "@@", we used "@@" because TEnv
6296 // considers "::" a terminator
6297 key.ReplaceAll("::", "@@");
6298 // convert "-" to " ", since class names may have
6299 // blanks and TEnv considers a blank a terminator
6300 key.ReplaceAll(" ", "-");
6301
6303 if (!fMapfile) {
6304 fMapfile = new TEnv();
6306
6309
6310 InitRootmapFile(".rootmap");
6311 }
6312 //fMapfile->SetValue(key, libs);
6314 return 1;
6315}
6316
6317////////////////////////////////////////////////////////////////////////////////
6318/// Demangle the name (from the typeinfo) and then request the class
6319/// via the usual name based interface (TClass::GetClass).
6320
6321TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
6322{
6323 int err = 0;
6325 if (err) return nullptr;
6328 return theClass;
6329}
6330
6331////////////////////////////////////////////////////////////////////////////////
6332/// Load library containing the specified class. Returns 0 in case of error
6333/// and 1 in case if success.
6334
6335Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
6336{
6337 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6338
6339 int err = 0;
6341 if (err) {
6342 return 0;
6343 }
6344
6345 std::string demangled_name(demangled_name_c);
6347
6348 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
6349 // shortened name.
6352
6353 // No need to worry about typedef, they aren't any ... but there are
6354 // inlined namespaces ...
6355
6357 if (result == 0) {
6360 }
6361
6362 return result;
6363}
6364
6365////////////////////////////////////////////////////////////////////////////////
6366// Get the list of 'published'/'known' library for the class and load them.
6368{
6369 Int_t status = 0;
6370
6371 // lookup class to find list of dependent libraries
6373 if (!deplibs.IsNull()) {
6374 TString delim(" ");
6375 TObjArray* tokens = deplibs.Tokenize(delim);
6376 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
6377 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
6378 if (gROOT->LoadClass(cls, deplib) == 0) {
6379 if (gDebug > 0) {
6380 gCling->Info("TCling::AutoLoad",
6381 "loaded dependent library %s for %s", deplib, cls);
6382 }
6383 }
6384 else {
6385 gCling->Error("TCling::AutoLoad",
6386 "failure loading dependent library %s for %s",
6387 deplib, cls);
6388 }
6389 }
6390 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6391 if (lib && lib[0]) {
6392 if (gROOT->LoadClass(cls, lib) == 0) {
6393 if (gDebug > 0) {
6394 gCling->Info("TCling::AutoLoad",
6395 "loaded library %s for %s", lib, cls);
6396 }
6397 status = 1;
6398 }
6399 else {
6400 gCling->Error("TCling::AutoLoad",
6401 "failure loading library %s for %s", lib, cls);
6402 }
6403 }
6404 delete tokens;
6405 }
6406
6407 return status;
6408}
6409
6410////////////////////////////////////////////////////////////////////////////////
6411// Iterate through the data member of the class (either through the TProtoClass
6412// or through Cling) and trigger, recursively, the loading the necessary libraries.
6413// \note `cls` is expected to be already normalized!
6414// \returns 1 on success.
6415Int_t TCling::DeepAutoLoadImpl(const char *cls, std::unordered_set<std::string> &visited,
6416 bool nameIsNormalized)
6417{
6418 // Try to insert; if insertion failed because the entry existed, DeepAutoLoadImpl()
6419 // has previously (within the same call to `AutoLoad()`) tried to load this class
6420 // and we are done, whether success or not, as it won't work better now than before,
6421 // because there is no additional information now compared to before.
6422 if (!visited.insert(std::string(cls)).second)
6423 return 1;
6424
6425 if (ShallowAutoLoadImpl(cls) == 0) {
6426 // If ShallowAutoLoadImpl() has an error, we have an error.
6427 return 0;
6428 }
6429
6430 // Now look through the TProtoClass to load the required library/dictionary
6432 for (auto element : proto->GetData()) {
6433 if (element->IsBasic())
6434 continue;
6435 const char *subtypename = element->GetTypeName();
6437 // Failure to load a dictionary is not (quite) a failure load
6438 // the top-level library. If we return false here, then
6439 // we would end up in a situation where the library and thus
6440 // the dictionary is loaded for "cls" but the TClass is
6441 // not created and/or marked as unavailable (in case where
6442 // AutoLoad is called from TClass::GetClass).
6443 DeepAutoLoadImpl(subtypename, visited, true /*normalized*/);
6444 }
6445 }
6446 return 1;
6447 }
6448
6449 // We found no TProtoClass for cls.
6450 auto classinfo = gInterpreter->ClassInfo_Factory(cls);
6451 if (classinfo && gInterpreter->ClassInfo_IsValid(classinfo)
6452 && !(gInterpreter->ClassInfo_Property(classinfo) & kIsEnum))
6453 {
6455 while (gInterpreter->DataMemberInfo_Next(memberinfo)) {
6456 if (gInterpreter->DataMemberInfo_TypeProperty(memberinfo) & ::kIsFundamental)
6457 continue;
6458 auto membertypename = TClassEdit::GetLong64_Name(gInterpreter->TypeName(gInterpreter->DataMemberInfo_TypeTrueName(memberinfo)));
6460 // Failure to load a dictionary is not (quite) a failure load
6461 // the top-level library. See detailed comment in the TProtoClass
6462 // branch (above).
6463 (void)DeepAutoLoadImpl(membertypename.c_str(), visited, true /*normalized*/);
6464 }
6465 }
6466 gInterpreter->DataMemberInfo_Delete(memberinfo);
6467 }
6468 gInterpreter->ClassInfo_Delete(classinfo);
6469 return 1;
6470}
6471
6472////////////////////////////////////////////////////////////////////////////////
6473/// Load library containing the specified class. Returns 0 in case of error
6474/// and 1 in case if success.
6475
6477{
6478 // Prevent update to IsClassAutoloading between our check and our actions.
6480
6481 // TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
6482 // rootcling (in *_rdict.pcm file generation) it is a no op.
6483 // FIXME: We should avoid calling autoload when we know we are not supposed
6484 // to and transform this check into an assert.
6486 // Never load any library from rootcling/genreflex.
6487 if (gDebug > 2) {
6488 Info("TCling::AutoLoad", "Explicitly disabled (the class name is %s)", cls);
6489 }
6490 return 0;
6491 }
6492
6493 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6494
6496
6498 // The library is already loaded as the class's dictionary is known.
6499 // Return success.
6500 // Note: the name (cls) is expected to be normalized as it comes either
6501 // from a callbacks (that can/should calculate the normalized name from the
6502 // decl) or from TClass::GetClass (which does also calculate the normalized
6503 // name).
6504 return 1;
6505 }
6506
6507 if (gDebug > 2) {
6508 Info("TCling::AutoLoad",
6509 "Trying to autoload for %s", cls);
6510 }
6511
6512 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
6513 if (gDebug > 2) {
6514 Info("TCling::AutoLoad",
6515 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
6516 }
6517 return 0;
6518 }
6519 // Prevent the recursion when the library dictionary are loaded.
6521 // Try using externally provided callback first.
6522 if (fAutoLoadCallBack) {
6524 if (success)
6525 return success;
6526 }
6527
6528 // During the 'Deep' part of the search we will call GetClassSharedLibsForModule
6529 // (when module are enabled) which might end up calling AutoParsing but
6530 // that should only be for the cases where the library has no generated pcm
6531 // and in that case a rootmap should be available.
6532 // This avoids a very costly operation (for generally no gain) but reduce the
6533 // quality of the search (i.e. bad in case of library with no pcm and no rootmap
6534 // file).
6536 std::unordered_set<std::string> visited;
6537 return DeepAutoLoadImpl(cls, visited, false /*normalized*/);
6538}
6539
6540////////////////////////////////////////////////////////////////////////////////
6541/// Parse the payload or header.
6542
6543static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
6544 Bool_t header,
6545 cling::Interpreter *interpreter)
6546{
6547 std::string code = gNonInterpreterClassDef ;
6548 if (!header) {
6549 // This is the complete header file content and not the
6550 // name of a header.
6551 code += what;
6552
6553 } else {
6554 code += ("#include \"");
6555 code += what;
6556 code += "\"\n";
6557 }
6558 code += ("#ifdef __ROOTCLING__\n"
6559 "#undef __ROOTCLING__\n"
6561 "#endif");
6562
6563 cling::Interpreter::CompilationResult cr;
6564 {
6565 // scope within which diagnostics are de-activated
6566 // For now we disable diagnostics because we saw them already at
6567 // dictionary generation time. That won't be an issue with the PCMs.
6568
6569 Sema &SemaR = interpreter->getSema();
6571 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
6572
6573 #if defined(R__MUST_REVISIT)
6574 #if R__MUST_REVISIT(6,2)
6575 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
6576 #endif
6577 #endif
6578
6579 cr = interpreter->parseForModule(code);
6580 }
6581 return cr;
6582}
6583
6584////////////////////////////////////////////////////////////////////////////////
6585/// Helper routine for TCling::AutoParse implementing the actual call to the
6586/// parser and looping over template parameters (if
6587/// any) and when they don't have a registered header to autoparse,
6588/// recurse over their template parameters.
6589///
6590/// Returns the number of header parsed.
6591
6593{
6594 // We assume the lock has already been taken.
6595 // R__LOCKGUARD(gInterpreterMutex);
6596
6598 unsigned long offset = 0;
6599 if (strncmp(cls, "const ", 6) == 0) {
6600 offset = 6;
6601 }
6602
6603 // Loop on the possible autoparse keys
6604 bool skipFirstEntry = false;
6605 std::vector<std::string> autoparseKeys;
6606 if (strchr(cls, '<')) {
6607 int nestedLoc = 0;
6609 // Check if we can skip the name of the template in the autoparses
6610 // Take all the scopes one by one. If all of them are in the AST, we do not
6611 // need to autoparse for that particular template.
6612 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
6613 // autoparseKeys[0] is empty when the input is not a template instance.
6614 // The case strchr(cls, '<') != 0 but still not a template instance can
6615 // happens 'just' for string (GetSplit replaces the template by the short name
6616 // and then use that for thew splitting)
6618 auto tokens = templateName.Tokenize("::");
6619 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
6620 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
6622 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
6623 auto nTokens = tokens->GetEntriesFast();
6624 for (Int_t tk = 0; tk < nTokens; ++tk) {
6625 auto scopeObj = tokens->UncheckedAt(tk);
6626 auto scopeName = ((TObjString*) scopeObj)->String().Data();
6627 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
6628 // Check if we have multiple nodes in the AST with this name
6629 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
6630 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
6631 if (!previousScopeAsContext) break; // this is not a context
6632 }
6633 delete tokens;
6634 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
6635 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
6636 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
6637 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
6638 skipFirstEntry = templatedDecl->hasDefinition();
6639 }
6640 }
6641 }
6642
6643 }
6644 }
6645 if (topLevel) autoparseKeys.emplace_back(cls);
6646
6647 for (const auto & apKeyStr : autoparseKeys) {
6648 if (skipFirstEntry) {
6649 skipFirstEntry=false;
6650 continue;
6651 }
6652 if (apKeyStr.empty()) continue;
6653 const char *apKey = apKeyStr.c_str();
6655 // If the class was not looked up
6656 if (gDebug > 1) {
6657 Info("TCling::AutoParse",
6658 "Starting autoparse for %s\n", apKey);
6659 }
6660 if (fLookedUpClasses.insert(normNameHash).second) {
6661 auto const &iter = fClassesHeadersMap.find(normNameHash);
6662 if (iter != fClassesHeadersMap.end()) {
6663 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
6665 auto const &hNamesPtrs = iter->second;
6666 if (gDebug > 1) {
6667 Info("TCling::AutoParse",
6668 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
6669 }
6670 for (auto & hName : hNamesPtrs) {
6671 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
6672 if (0 != fPayloads.count(normNameHash)) {
6673 float initRSSval=0.f, initVSIZEval=0.f;
6674 (void) initRSSval; // Avoid unused var warning
6675 (void) initVSIZEval;
6676 if (gDebug > 0) {
6677 Info("AutoParse",
6678 "Parsing full payload for %s", apKey);
6681 initRSSval = 1e-3*info.fMemResident;
6682 initVSIZEval = 1e-3*info.fMemVirtual;
6683 }
6685 if (cRes != cling::Interpreter::kSuccess) {
6686 if (hName[0] == '\n')
6687 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
6688 } else {
6691 if (gDebug > 0){
6694 float endRSSval = 1e-3*info.fMemResident;
6695 float endVSIZEval = 1e-3*info.fMemVirtual;
6696 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6697 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6698 }
6699 }
6700 } else if (!IsLoaded(hName)) {
6701 if (gDebug > 0) {
6702 Info("AutoParse",
6703 "Parsing single header %s", hName);
6704 }
6706 if (cRes != cling::Interpreter::kSuccess) {
6707 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
6708 } else {
6710 }
6711 }
6712 }
6713 }
6714 else {
6715 // There is no header registered for this class, if this a
6716 // template, it will be instantiated if/when it is requested
6717 // and if we do no load/parse its components we might end up
6718 // not using an eventual specialization.
6719 if (strchr(apKey, '<')) {
6721 }
6722 }
6723 }
6724 }
6725
6726 if (nHheadersParsed) {
6727 // Register that we did autoparsing for this class.
6728 fAutoParseClasses.insert(cls);
6729 if (gDebug)
6730 Info("AutoParse", "Parsed %d headers for %s", nHheadersParsed, cls);
6731 }
6732 return nHheadersParsed;
6733
6734}
6735
6736////////////////////////////////////////////////////////////////////////////////
6737/// Parse the headers relative to the class
6738/// Returns 1 in case of success, 0 in case of failure
6739
6741{
6742 if (llvm::StringRef(cls).contains("(lambda)"))
6743 return 0;
6744
6747 return AutoLoad(cls);
6748 } else {
6749 return 0;
6750 }
6751 }
6752
6754
6755 if (gDebug > 1) {
6756 Info("TCling::AutoParse",
6757 "Trying to autoparse for %s", cls);
6758 }
6759
6760 // The catalogue of headers is in the dictionary
6762 && !gClassTable->GetDictNorm(cls)) {
6763 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
6765 fInterpreter->getSema());
6766 AutoLoad(cls, true /*knowDictNotLoaded*/);
6767 }
6768
6769 // Prevent the recursion when the library dictionary are loaded.
6771
6772 // No recursive header parsing on demand; we require headers to be standalone.
6774
6775 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
6776
6778
6779 return nHheadersParsed > 0 ? 1 : 0;
6780}
6781
6782// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6783// Try to solve the problem by AutoLoading. Return true when AutoLoading success, return
6784// false if not.
6785bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6786{
6788 if (errMsg.contains("undefined symbol: ")) {
6789 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6790 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6791 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6792 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6793 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6794 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6795 return true;
6796 } else {
6797 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6799 return true;
6800 }
6801
6802 return false;
6803}
6804
6805////////////////////////////////////////////////////////////////////////////////
6806/// Autoload a library based on a missing symbol.
6807
6810
6811 // We have already loaded the library.
6812 if (void* Addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name))
6813 return Addr;
6814
6815 const cling::DynamicLibraryManager &DLM = *GetInterpreterImpl()->getDynamicLibraryManager();
6817
6818 auto LibLoader = [](const std::string& LibName) -> bool {
6819 if (gSystem->Load(LibName.c_str(), "", false) < 0) {
6820 ::Error("TCling__LazyFunctionCreatorAutoloadForModule",
6821 "Failed to load library %s", LibName.c_str());
6822 return false;
6823 }
6824 return true; //success.
6825 };
6826
6827 std::string libName = DLM.searchLibrariesForSymbol(mangled_name,
6828 /*searchSystem=*/ true);
6829
6830 assert(!llvm::StringRef(libName).starts_with("libNew") && "We must not resolve symbols from libNew!");
6831
6832 if (libName.empty())
6833 return nullptr;
6834
6835 if (!LibLoader(libName))
6836 return nullptr;
6837
6839 return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name);
6840}
6841
6842////////////////////////////////////////////////////////////////////////////////
6843
6845{
6846 return fNSFromRootmaps.count(nsDecl) != 0;
6847}
6848
6849////////////////////////////////////////////////////////////////////////////////
6850/// Internal function. Actually do the update of the ClassInfo when seeing
6851// new TagDecl or NamespaceDecl.
6852void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6853{
6854
6856 if (cci) {
6857 // If we only had a forward declaration then update the
6858 // TClingClassInfo with the definition if we have it now.
6859 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6860 if (!oldDef || (def && def != oldDef)) {
6861 cl->ResetCaches();
6862 TClass::RemoveClassDeclId(cci->GetDeclId());
6863 if (def) {
6864 if (cci->GetType()) {
6865 // It's a tag decl, not a namespace decl.
6866 cci->Init(*cci->GetType());
6867 TClass::AddClassToDeclIdMap(cci->GetDeclId(), cl);
6868 } else {
6869 Error("RefreshClassInfo", "Should not need to update the classInfo a non type decl: %s", oldDef->getNameAsString().c_str());
6870 }
6871 }
6872 }
6873 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6874 cl->ResetCaches();
6875 if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
6876 // We need to use the Emulated Tuple but we should not trigger parsing
6877 // yet, so delay the creation of the ClassInfo
6878 delete ((TClingClassInfo *)cl->fClassInfo);
6879 cl->fClassInfo = nullptr;
6880 cl->fCanLoadClassInfo = true;
6882 if (cl->fState != TClass::kHasTClassInit) {
6884 }
6885 return;
6886 }
6887 // yes, this is almost a waste of time, but we do need to lookup
6888 // the 'type' corresponding to the TClass anyway in order to
6889 // preserve the opaque typedefs (Double32_t)
6890 if (!alias && def != nullptr)
6892 else
6894 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6895 // We now need to update the state and bits.
6896 if (cl->fState != TClass::kHasTClassInit) {
6897 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6899 }
6900 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6901 } else {
6902 delete ((TClingClassInfo *)cl->fClassInfo);
6903 cl->fClassInfo = nullptr;
6904 }
6905 }
6906}
6907
6908////////////////////////////////////////////////////////////////////////////////
6909/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6911{
6912 const TagDecl *td = dyn_cast<TagDecl>(ND);
6914 const NamedDecl *canon = nullptr;
6915
6916 std::string name;
6917 TagDecl* tdDef = nullptr;
6918 if (td) {
6919 canon = tdDef = td->getDefinition();
6920 // Let's pass the decl to the TClass only if it has a definition.
6921 if (!tdDef) return;
6922
6923 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6924 // Ignore incomplete definition.
6925 // Ignore declaration within a function.
6926 return;
6927 }
6928
6929 auto declName = tdDef->getNameAsString();
6930 // Check if we have registered the unqualified name into the list
6931 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6932 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6933 // the unqualified name is sufficient (and the fully qualified name might be
6934 // 'wrong' if there is difference in spelling in the template paramters (for example)
6936 // 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() );
6937 return;
6938 }
6939
6940 clang::QualType type = tdDef->getASTContext().getCanonicalTagType(tdDef);
6942 } else if (ns) {
6943 canon = ns->getCanonicalDecl();
6944 name = ND->getQualifiedNameAsString();
6945 } else {
6946 name = ND->getQualifiedNameAsString();
6947 }
6948
6949 // Supposedly we are being called while something is being
6950 // loaded ... let's now tell the autoloader to do the work
6951 // yet another time.
6953 // FIXME: There can be more than one TClass for a single decl.
6954 // for example vector<double> and vector<Double32_t>
6955 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6956 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6957 RefreshClassInfo(cl, canon, false);
6958 }
6959 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6960 // and update them too:
6961 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6962 // RefreshClassInfo(cl, tdDef, true);
6963}
6964
6965////////////////////////////////////////////////////////////////////////////////
6966/// No op: see TClingCallbacks
6967
6971
6972//______________________________________________________________________________
6973//FIXME: Factor out that function in TClass, because TClass does it already twice
6975{
6976 // This is a no-op as part of the API.
6977 // TCling uses UpdateClassInfoWithDecl() instead.
6978}
6979
6980////////////////////////////////////////////////////////////////////////////////
6981/// Update all canvases at end the terminal input command.
6982
6984{
6985 TIter next(gROOT->GetListOfCanvases());
6986 TVirtualPad* canvas;
6987 while ((canvas = (TVirtualPad*)next())) {
6988 canvas->Update();
6989 }
6990}
6991
6992////////////////////////////////////////////////////////////////////////////////
6993
6994void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6995 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6996
6997 // If the transaction does not contain anything we can return earlier.
6998 if (!HandleNewTransaction(T)) return;
6999
7000 bool isTUTransaction = false;
7001 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
7002 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
7003 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
7004 // The is the first transaction, we have to expose to meta
7005 // what's already in the AST.
7006 isTUTransaction = true;
7007 }
7008 }
7009
7010 std::set<const void*> TransactionDeclSet;
7011 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
7012 const clang::Decl* WrapperFD = T.getWrapperFD();
7013 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
7014 I != E; ++I) {
7015 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
7016 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
7017 continue;
7018
7019 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
7020 DE = I->m_DGR.end(); DI != DE; ++DI) {
7021 if (*DI == WrapperFD)
7022 continue;
7023 TransactionDeclSet.insert(*DI);
7024 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
7025 }
7026 }
7027 }
7028
7029 // The above might trigger more decls to be deserialized.
7030 // Thus the iteration over the deserialized decls must be last.
7031 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
7032 E = T.deserialized_decls_end(); I != E; ++I) {
7033 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
7034 DE = I->m_DGR.end(); DI != DE; ++DI)
7035 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
7036 //FIXME: HandleNewDecl should take DeclGroupRef
7037 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
7039 }
7040 }
7041
7042
7043 // When fully building the reflection info in TClass, a deserialization
7044 // could be triggered, which may result in request for building the
7045 // reflection info for the same TClass. This in turn will clear the caches
7046 // for the TClass in-flight and cause null ptr derefs.
7047 // FIXME: This is a quick fix, solving most of the issues. The actual
7048 // question is: Shouldn't TClass provide a lock mechanism on update or lock
7049 // itself until the update is done.
7050 //
7051 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
7052 std::vector<TClass*>::iterator it;
7054 ((TCling*)gCling)->GetModTClasses().begin(),
7055 ((TCling*)gCling)->GetModTClasses().end(),
7058
7059 // Lock the TClass for updates
7060 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
7062 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
7063 E = modifiedTClassesDiff.end(); I != E; ++I) {
7064 // Make sure the TClass has not been deleted.
7065 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
7066 continue;
7067 }
7068 // Could trigger deserialization of decls.
7069 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
7070 // Unlock the TClass for updates
7071 ((TCling*)gCling)->GetModTClasses().erase(*I);
7072
7073 }
7074}
7075
7076///\brief Invalidate stored TCling state for declarations included in transaction `T'.
7077///
7078void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
7079{
7081
7082 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
7083 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
7084 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
7085 (TListOfEnums *)gROOT->GetListOfEnums());
7086
7087 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
7088 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
7089 I != E; ++I) {
7090 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
7091 continue;
7092 if (I->m_Call == cling::Transaction::kCCINone) {
7094 ++iNested;
7095 continue;
7096 }
7097
7098 for (auto &D : I->m_DGR)
7100 }
7101}
7102
7103///\brief Invalidate cached TCling information for the given global declaration.
7104///
7106 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
7107 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
7108 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
7109 (TListOfEnums *)gROOT->GetListOfEnums());
7111}
7112
7113///\brief Invalidate cached TCling information for the given declaration, and
7114/// removed it from the appropriate object list.
7115///\param[in] Lists - std::tuple<TListOfDataMembers&, TListOfFunctions&,
7116/// TListOfFunctionTemplates&, TListOfEnums&>
7117/// of pointers to the (global/class) object lists.
7118///\param[in] D - Decl to discard.
7119///
7123 TListOfEnums*> &Lists, const Decl *D) {
7124 if (D->isFromASTFile()) // `D' came from the PCH; ignore
7125 return;
7126
7127 TListOfDataMembers &LODM = *(std::get<0>(Lists));
7128 TListOfFunctions &LOF = *(std::get<1>(Lists));
7129 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
7130 TListOfEnums &LOE = *(std::get<3>(Lists));
7131
7133 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
7134 if (LODM.GetClass())
7135 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
7136 else
7137 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
7138 } else if (isa<FunctionDecl>(D)) {
7140 } else if (isa<FunctionTemplateDecl>(D)) {
7142 } else if (isa<EnumDecl>(D)) {
7143 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
7144 if (!E)
7145 return;
7146
7147 // Try to invalidate enumerators (for unscoped enumerations).
7148 for (TIter I = E->GetConstants(); auto EC = (TEnumConstant *)I(); )
7150 (TEnumConstant *)LODM.FindObject(EC->GetName()));
7151
7153 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
7155 return;
7156
7157 std::vector<TClass *> Classes;
7158 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
7159 return;
7160 for (auto &C : Classes) {
7161 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
7162 (TListOfFunctions *)C->GetListOfMethods(),
7163 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
7164 (TListOfEnums *)C->GetListOfEnums());
7165 for (auto &I : cast<DeclContext>(D)->decls())
7167
7168 // For NamespaceDecl (redeclarable), only invalidate this redecl.
7169 if (D->getKind() != Decl::Namespace || cast<NamespaceDecl>(D)->isFirstDecl())
7170 C->ResetClassInfo();
7171 }
7172 }
7173}
7174
7175////////////////////////////////////////////////////////////////////////////////
7176// If an autoparse was done during a transaction and that it is rolled back,
7177// we need to make sure the next request for the same autoparse will be
7178// honored.
7179void TCling::TransactionRollback(const cling::Transaction &T) {
7180 auto const &triter = fTransactionHeadersMap.find(&T);
7181 if (triter != fTransactionHeadersMap.end()) {
7182 std::size_t normNameHash = triter->second;
7183
7185
7186 auto const &iter = fClassesHeadersMap.find(normNameHash);
7187 if (iter != fClassesHeadersMap.end()) {
7188 auto const &hNamesPtrs = iter->second;
7189 for (auto &hName : hNamesPtrs) {
7190 if (gDebug > 0) {
7191 Info("TransactionRollback",
7192 "Restoring ability to autoaparse: %s", hName);
7193 }
7195 }
7196 }
7197 }
7198}
7199
7200////////////////////////////////////////////////////////////////////////////////
7201
7202void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
7203// R__LOCKGUARD_CLING(gInterpreterMutex);
7204// UpdateListOfLoadedSharedLibraries();
7205}
7206
7207////////////////////////////////////////////////////////////////////////////////
7208
7209void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
7210 fPrevLoadedDynLibInfo = nullptr;
7211 fSharedLibs = "";
7212}
7213
7214////////////////////////////////////////////////////////////////////////////////
7215/// Return the list of shared libraries loaded into the process.
7216
7223
7224static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH, bool skipCore)
7225{
7226 if (!cls || !*cls)
7227 return {};
7228
7229 using namespace clang;
7230 if (const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
7231 /*type*/ nullptr, /*instantiate*/ false)) {
7232 if (!D->isFromASTFile()) {
7233 if (gDebug > 5)
7234 Warning("GetClassSharedLibsForModule", "Decl found for %s is not part of a module", cls);
7235 return {};
7236 }
7237 class ModuleCollector : public ConstDeclVisitor<ModuleCollector> {
7238 llvm::DenseSet<Module *> &m_TopLevelModules;
7239
7240 public:
7241 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
7242 void Collect(const Decl *D) { Visit(D); }
7243
7244 void VisitDecl(const Decl *D)
7245 {
7246 // FIXME: Such case is described ROOT-7765 where
7247 // ROOT_GENERATE_DICTIONARY does not contain the list of headers.
7248 // They are specified as #includes in the LinkDef file. This leads to
7249 // generation of incomplete modulemap files and this logic fails to
7250 // compute the corresponding module of D.
7251 // FIXME: If we want to support such a case, we should not rely on
7252 // the contents of the modulemap but mangle D and look it up in the
7253 // .so files.
7254 if (!D->hasOwningModule())
7255 return;
7256 if (Module *M = D->getOwningModule()->getTopLevelModule())
7257 m_TopLevelModules.insert(M);
7258 }
7259
7261 {
7262 switch (TA.getKind()) {
7263 case TemplateArgument::Null:
7264 case TemplateArgument::Integral:
7265 case TemplateArgument::Pack:
7266 case TemplateArgument::NullPtr:
7267 case TemplateArgument::StructuralValue:
7268 case TemplateArgument::Expression:
7269 case TemplateArgument::Template:
7270 case TemplateArgument::TemplateExpansion: return;
7271 case TemplateArgument::Type:
7272 if (const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
7273 return Visit(TagTy->getDecl());
7274 return;
7275 case TemplateArgument::Declaration: return Visit(TA.getAsDecl());
7276 }
7277 llvm_unreachable("Invalid TemplateArgument::Kind!");
7278 }
7279
7281 {
7282 if (CTSD->getOwningModule())
7283 VisitDecl(CTSD);
7284 else
7285 VisitDecl(CTSD->getSpecializedTemplate());
7286 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
7287 for (const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
7289 }
7290 }
7291 };
7292
7293 llvm::DenseSet<Module *> TopLevelModules;
7295 m.Collect(D);
7296 std::string result;
7297 for (auto M : TopLevelModules) {
7298 // ROOT-unaware modules (i.e. not processed by rootcling) do not have a
7299 // link declaration.
7300 if (!M->LinkLibraries.size())
7301 continue;
7302 // We have preloaded the Core module thus libCore.so
7303 if (M->Name == "Core" && skipCore)
7304 continue;
7305 assert(M->LinkLibraries.size() == 1);
7306 if (!result.empty())
7307 result += ' ';
7308 result += M->LinkLibraries[0].Library;
7309 }
7310 return result;
7311 }
7312 return {};
7313}
7314
7315////////////////////////////////////////////////////////////////////////////////
7316/// Get the list of shared libraries containing the code for class cls.
7317/// The first library in the list is the one containing the class, the
7318/// others are the libraries the first one depends on. Returns 0
7319/// in case the library is not found.
7320/// \param cls the name of the class
7321/// \param skipCore if true (default), remove "Core" from the returned list
7322
7323const char* TCling::GetClassSharedLibs(const char* cls, bool skipCore)
7324{
7325 if (fCxxModulesEnabled) {
7326 // Lock the interpreter mutex before interacting with cling.
7327 // TODO: Can we move this further deep? In principle the lock should be in
7328 // GetClassSharedLibsForModule, but it might be needed also for
7329 // getLookupHelper?
7331 llvm::StringRef className = cls;
7332 // If we get a class name containing lambda, we cannot parse it and we
7333 // can exit early.
7334 // FIXME: This works around a bug when we are instantiating a template
7335 // make_unique and the substitution fails. Seen in most of the dataframe
7336 // tests.
7337 if (className.contains("(lambda)"))
7338 return nullptr;
7339 // Limit the recursion which can be induced by GetClassSharedLibsForModule.
7341 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
7343 if (!libs.empty()) {
7344 fAutoLoadLibStorage.push_back(libs);
7345 return fAutoLoadLibStorage.back().c_str();
7346 }
7347 }
7348
7349 if (!cls || !*cls) {
7350 return nullptr;
7351 }
7352 // lookup class to find list of libraries
7353 if (fMapfile) {
7354 TEnvRec* libs_record = nullptr;
7356 if (libs_record) {
7357 const char* libs = libs_record->GetValue();
7358 return (*libs) ? libs : nullptr;
7359 }
7360 else {
7361 // Try the old format...
7362 TString c = TString("Library.") + cls;
7363 // convert "::" to "@@", we used "@@" because TEnv
7364 // considers "::" a terminator
7365 c.ReplaceAll("::", "@@");
7366 // convert "-" to " ", since class names may have
7367 // blanks and TEnv considers a blank a terminator
7368 c.ReplaceAll(" ", "-");
7369 // Use TEnv::Lookup here as the rootmap file must start with Library.
7370 // and do not support using any stars (so we do not need to waste time
7371 // with the search made by TEnv::GetValue).
7372 TEnvRec* libs_record = nullptr;
7374 if (libs_record) {
7375 const char* libs = libs_record->GetValue();
7376 return (*libs) ? libs : nullptr;
7377 }
7378 }
7379 }
7380 return nullptr;
7381}
7382
7383/// This interface returns a list of dependent libraries in the form:
7384/// lib libA.so libB.so libC.so. The first library is the library we are
7385/// searching dependencies for.
7386/// Note: In order to speed up the search, we display the dependencies of the
7387/// libraries which are not yet loaded. For instance, if libB.so was already
7388/// loaded the list would contain: lib libA.so libC.so.
7389static std::string GetSharedLibImmediateDepsSlow(std::string lib,
7390 cling::Interpreter *interp,
7391 bool skipLoadedLibs = true)
7392{
7393 TString LibFullPath(lib);
7394 if (!llvm::sys::path::is_absolute(lib)) {
7395 if (!gSystem->FindDynamicLibrary(LibFullPath, /*quiet=*/true)) {
7396 Error("TCling__GetSharedLibImmediateDepsSlow", "Cannot find library '%s'", lib.c_str());
7397 return "";
7398 }
7399 } else {
7400 assert(llvm::sys::fs::exists(lib) && "Must exist!");
7401 lib = llvm::sys::path::filename(lib).str();
7402 }
7403
7404 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
7405 if (!ObjF) {
7406 Warning("TCling__GetSharedLibImmediateDepsSlow", "Failed to read object file %s", lib.c_str());
7407 return "";
7408 }
7409
7410 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7411
7412 std::set<string> DedupSet;
7413 std::string Result = lib + ' ';
7414 for (const auto &S : BinObjFile->symbols()) {
7415 uint32_t Flags = llvm::cantFail(S.getFlags());
7416 // Skip defined symbols: we have them.
7417 if (!(Flags & llvm::object::SymbolRef::SF_Undefined))
7418 continue;
7419 // Skip undefined weak symbols: if we don't have them we won't need them.
7420 // `__gmon_start__` being a typical example.
7421 if (Flags & llvm::object::SymbolRef::SF_Weak)
7422 continue;
7423 llvm::Expected<StringRef> SymNameErr = S.getName();
7424 if (!SymNameErr) {
7425 Warning("GetSharedLibDepsForModule", "Failed to read symbol");
7426 continue;
7427 }
7428 llvm::StringRef SymName = SymNameErr.get();
7429 if (SymName.empty())
7430 continue;
7431
7432 if (BinObjFile->isELF()) {
7433 // Skip the symbols which are part of the C/C++ runtime and have a
7434 // fixed library version. See binutils ld VERSION. Those reside in
7435 // 'system' libraries, which we avoid in FindLibraryForSymbol.
7436 if (SymName.contains("@GLIBCXX") || SymName.contains("@CXXABI") ||
7437 SymName.contains("@GLIBC") || SymName.contains("@GCC"))
7438 continue;
7439
7440 // Those are 'weak undefined' symbols produced by gcc. We can
7441 // ignore them.
7442 // FIXME: It is unclear whether we can ignore all weak undefined
7443 // symbols:
7444 // http://lists.llvm.org/pipermail/llvm-dev/2017-October/118177.html
7445 static constexpr llvm::StringRef RegisterClasses("_Jv_RegisterClasses");
7446 static constexpr llvm::StringRef RegisterCloneTable("_ITM_registerTMCloneTable");
7447 static constexpr llvm::StringRef DeregisterCloneTable("_ITM_deregisterTMCloneTable");
7448 if (SymName == RegisterClasses ||
7451 continue;
7452 }
7453
7454 // If we can find the address of the symbol, we have loaded it. Skip.
7455 if (skipLoadedLibs) {
7457 if (llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymNameForDlsym))
7458 continue;
7459 }
7460
7462 std::string found = interp->getDynamicLibraryManager()->searchLibrariesForSymbol(SymName, /*searchSystem*/false);
7463 // The expected output is just filename without the full path, which
7464 // is not very accurate, because our Dyld implementation might find
7465 // a match in location a/b/c.so and if we return just c.so ROOT might
7466 // resolve it to y/z/c.so and there we might not be ABI compatible.
7467 // FIXME: Teach the users of GetSharedLibDeps to work with full paths.
7468 if (!found.empty()) {
7469 std::string cand = llvm::sys::path::filename(found).str();
7470 if (!DedupSet.insert(cand).second)
7471 continue;
7472
7473 Result += cand + ' ';
7474 }
7475 }
7476
7477 return Result;
7478}
7479
7480static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
7481{
7482 // Check if we have parsed a rootmap file.
7483 llvm::SmallString<256> rootmapName;
7484 if (!lib.starts_with("lib"))
7485 rootmapName.append("lib");
7486
7487 rootmapName.append(llvm::sys::path::filename(lib));
7488 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7489
7490 if (gCling->GetRootMapFiles()->FindObject(rootmapName.c_str()))
7491 return true;
7492
7493 // Perform a last resort by dropping the lib prefix.
7494 llvm::StringRef rootmapNameNoLib = rootmapName.str();
7495 if (rootmapNameNoLib.consume_front("lib"))
7496 return gCling->GetRootMapFiles()->FindObject(rootmapNameNoLib.data());
7497
7498 return false;
7499}
7500
7501static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
7502{
7503 if (gCling->HasPCMForLibrary(lib.data()))
7504 return true;
7505
7506 return hasParsedRootmapForLibrary(lib);
7507}
7508
7509////////////////////////////////////////////////////////////////////////////////
7510/// Get the list a libraries on which the specified lib depends. The
7511/// returned string contains as first element the lib itself.
7512/// Returns 0 in case the lib does not exist or does not have
7513/// any dependencies. If useDyld is true, we iterate through all available
7514/// libraries and try to construct the dependency chain by resolving each
7515/// symbol.
7516
7517const char* TCling::GetSharedLibDeps(const char* lib, bool useDyld/* = false*/)
7518{
7519 if (llvm::sys::path::is_absolute(lib) && !llvm::sys::fs::exists(lib))
7520 return nullptr;
7521
7522 if (!hasParsedRootmapForLibrary(lib)) {
7523 llvm::SmallString<512> rootmapName(lib);
7524 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7525 if (llvm::sys::fs::exists(rootmapName)) {
7526 if (gDebug > 0)
7527 Info("Load", "loading %s", rootmapName.c_str());
7528 gInterpreter->LoadLibraryMap(rootmapName.c_str());
7529 }
7530 }
7531
7532 if (hasPrecomputedLibraryDeps(lib) && useDyld) {
7533 if (gDebug > 0)
7534 Warning("TCling::GetSharedLibDeps", "Precomputed dependencies available but scanning '%s'", lib);
7535 }
7536
7537 if (useDyld) {
7539 if (!libs.empty()) {
7540 fAutoLoadLibStorage.push_back(libs);
7541 return fAutoLoadLibStorage.back().c_str();
7542 }
7543 }
7544
7545 if (!fMapfile || !lib || !lib[0]) {
7546 return nullptr;
7547 }
7548 TString libname(lib);
7549 Ssiz_t idx = libname.Last('.');
7550 if (idx != kNPOS) {
7551 libname.Remove(idx);
7552 }
7553 TEnvRec* rec;
7554 TIter next(fMapfile->GetTable());
7555 size_t len = libname.Length();
7556 while ((rec = (TEnvRec*) next())) {
7557 const char* libs = rec->GetValue();
7558 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7559 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
7560 return libs;
7561 }
7562 }
7563 return nullptr;
7564}
7565
7566////////////////////////////////////////////////////////////////////////////////
7567/// If error messages are disabled, the interpreter should suppress its
7568/// failures and warning messages from stdout.
7569
7571{
7572#if defined(R__MUST_REVISIT)
7573#if R__MUST_REVISIT(6,2)
7574 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
7575#endif
7576#endif
7577 return kTRUE;
7578}
7579
7580////////////////////////////////////////////////////////////////////////////////
7581/// If error messages are disabled, the interpreter should suppress its
7582/// failures and warning messages from stdout. Return the previous state.
7583
7585{
7586#if defined(R__MUST_REVISIT)
7587#if R__MUST_REVISIT(6,2)
7588 Warning("SetErrorMessages", "Interface not available yet.");
7589#endif
7590#endif
7592}
7593
7594////////////////////////////////////////////////////////////////////////////////
7595/// Refresh the list of include paths known to the interpreter and return it
7596/// with -I prepended.
7597
7599{
7601
7602 fIncludePath = "";
7603
7604 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7605 //false - no system header, true - with flags.
7606 fInterpreter->GetIncludePaths(includePaths, false, true);
7607 if (const size_t nPaths = includePaths.size()) {
7608 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
7609
7610 for (size_t i = 0; i < nPaths; i += 2) {
7611 if (i)
7612 fIncludePath.Append(' ');
7613 fIncludePath.Append(includePaths[i].c_str());
7614
7615 if (includePaths[i] != "-I")
7616 fIncludePath.Append(' ');
7617 fIncludePath.Append('"');
7619 fIncludePath.Append('"');
7620 }
7621 }
7622
7623 return fIncludePath;
7624}
7625
7626////////////////////////////////////////////////////////////////////////////////
7627/// Return the directory containing CINT's stl cintdlls.
7628
7629const char* TCling::GetSTLIncludePath() const
7630{
7631 return "";
7632}
7633
7634//______________________________________________________________________________
7635// M I S C
7636//______________________________________________________________________________
7637
7638int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
7639{
7640 // Interface to cling function
7641 return 0;
7642}
7643
7644////////////////////////////////////////////////////////////////////////////////
7645/// Interface to cling function
7646
7648{
7649 assert(fout != nullptr && "DisplayIncludePath, 'fout' parameter is null");
7650
7651 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7652 //false - no system header, true - with flags.
7653 fInterpreter->GetIncludePaths(includePaths, false, true);
7654 if (const size_t nPaths = includePaths.size()) {
7655 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
7656
7657 std::string allIncludes("include path:");
7658 for (size_t i = 0; i < nPaths; i += 2) {
7659 allIncludes += ' ';
7661
7662 if (includePaths[i] != "-I")
7663 allIncludes += ' ';
7664 allIncludes += includePaths[i + 1];
7665 }
7666
7667 fprintf(fout, "%s\n", allIncludes.c_str());
7668 }
7669
7670 return 0;
7671}
7672
7673////////////////////////////////////////////////////////////////////////////////
7674/// Interface to cling function
7675
7676void* TCling::FindSym(const char* entry) const
7677{
7679 return fInterpreter->getAddressOfGlobal(entry);
7680}
7681
7682////////////////////////////////////////////////////////////////////////////////
7683/// Let the interpreter issue a generic error, and set its error state.
7684
7685void TCling::GenericError(const char* error) const
7686{
7687#if defined(R__MUST_REVISIT)
7688#if R__MUST_REVISIT(6,2)
7689 Warning("GenericError","Interface not available yet.");
7690#endif
7691#endif
7692}
7693
7694////////////////////////////////////////////////////////////////////////////////
7695/// This routines used to return the address of the internal wrapper
7696/// function (of the interpreter) that was used to call *all* the
7697/// interpreted functions that were bytecode compiled (no longer
7698/// interpreted line by line). In Cling, there is no such
7699/// wrapper function.
7700/// In practice this routines was use to decipher whether the
7701/// pointer returns by InterfaceMethod could be used to uniquely
7702/// represent the function. In Cling if the function is in a
7703/// useable state (its compiled version is available), this is
7704/// always the case.
7705/// See TClass::GetMethod.
7706
7708{
7709 return 0;
7710}
7711
7712////////////////////////////////////////////////////////////////////////////////
7713/// Interface to cling function
7714
7716{
7717#if defined(R__MUST_REVISIT)
7718#if R__MUST_REVISIT(6,2)
7719 Warning("GetSecurityError", "Interface not available yet.");
7720#endif
7721#endif
7722 return 0;
7723}
7724
7725////////////////////////////////////////////////////////////////////////////////
7726/// Load a source file or library called path into the interpreter.
7727
7728int TCling::LoadFile(const char* path) const
7729{
7730 // Modifying the interpreter state needs locking.
7732 cling::Interpreter::CompilationResult compRes;
7733 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(".L %s", path), compRes, /*cling::Value*/nullptr);
7734 return compRes == cling::Interpreter::kFailure;
7735}
7736
7737////////////////////////////////////////////////////////////////////////////////
7738/// Load the declarations from text into the interpreter.
7739/// Note that this cannot be (top level) statements; text must contain
7740/// top level declarations.
7741/// Returns true on success, false on failure.
7742
7743Bool_t TCling::LoadText(const char* text) const
7744{
7745 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7746}
7747
7748////////////////////////////////////////////////////////////////////////////////
7749/// Interface to cling function
7750
7751const char* TCling::MapCppName(const char* name) const
7752{
7753 TTHREAD_TLS_DECL(std::string,buffer);
7755 return buffer.c_str(); // NOLINT
7756}
7757
7758////////////////////////////////////////////////////////////////////////////////
7759/// [Place holder for Mutex Lock]
7760/// Provide the interpreter with a way to
7761/// acquire a lock used to protect critical section
7762/// of its code (non-thread safe parts).
7763
7764void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7765{
7766 // nothing to do for now.
7767}
7768
7769////////////////////////////////////////////////////////////////////////////////
7770/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7771/// release a lock used to protect critical section
7772/// of its code (non-thread safe parts).
7773
7774void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7775{
7776 // nothing to do for now.
7777}
7778
7779////////////////////////////////////////////////////////////////////////////////
7780/// Returns if class AutoLoading is currently enabled.
7781
7783{
7784 if (IsFromRootCling())
7785 return false;
7786 if (!fClingCallbacks)
7787 return false;
7789}
7790
7791////////////////////////////////////////////////////////////////////////////////
7792/// Enable/Disable the AutoLoading of libraries.
7793/// Returns the old value, i.e whether it was enabled or not.
7794
7796{
7797 // If no state change is required, exit early.
7798 // FIXME: In future we probably want to complain if we made a request which
7799 // was with the same state as before in order to catch programming errors.
7800 if ((bool) autoload == IsClassAutoLoadingEnabled())
7801 return autoload;
7802
7803 assert(fClingCallbacks && "We must have callbacks!");
7806 return oldVal;
7807}
7808
7809////////////////////////////////////////////////////////////////////////////////
7810/// Enable/Disable the Autoparsing of headers.
7811/// Returns the old value, i.e whether it was enabled or not.
7812
7819
7820////////////////////////////////////////////////////////////////////////////////
7821/// Suspend the Autoparsing of headers.
7822/// Returns the old value, i.e whether it was suspended or not.
7823
7830
7831////////////////////////////////////////////////////////////////////////////////
7832/// Set a callback to receive error messages.
7833
7835{
7836#if defined(R__MUST_REVISIT)
7837#if R__MUST_REVISIT(6,2)
7838 Warning("SetErrmsgcallback", "Interface not available yet.");
7839#endif
7840#endif
7841}
7842
7844{
7845 if (enable) {
7847 &fInterpreter->getDiagnostics().getDiagnosticOptions(),
7848 fInterpreter->getCI()->getLangOpts(),
7849 [] (clang::DiagnosticsEngine::Level Level, const std::string &Info) {
7850 if (Level == clang::DiagnosticsEngine::Warning) {
7851 ::Warning("cling", "%s", Info.c_str());
7852 } else if (Level == clang::DiagnosticsEngine::Error
7853 || Level == clang::DiagnosticsEngine::Fatal) {
7854 ::Error("cling", "%s", Info.c_str());
7855 } else {
7856 ::Info("cling", "%s", Info.c_str());
7857 }
7858 });
7859 fInterpreter->replaceDiagnosticConsumer(consumer, /*Own=*/true);
7860 } else {
7861 fInterpreter->replaceDiagnosticConsumer(nullptr);
7862 }
7863}
7864
7865
7866////////////////////////////////////////////////////////////////////////////////
7867/// Create / close a scope for temporaries. No-op for cling; use
7868/// cling::Value instead.
7869
7870void TCling::SetTempLevel(int val) const
7871{
7872}
7873
7874////////////////////////////////////////////////////////////////////////////////
7875
7876int TCling::UnloadFile(const char* path) const
7877{
7878 // Modifying the interpreter state needs locking.
7880 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7881 std::string canonical = DLM->lookupLibrary(path);
7882 if (canonical.empty()) {
7883 canonical = path;
7884 }
7885 // Unload a shared library or a source file.
7886 cling::Interpreter::CompilationResult compRes;
7887 HandleInterpreterException(GetMetaProcessorImpl(), Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/nullptr);
7888 return compRes == cling::Interpreter::kFailure;
7889}
7890
7891std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7892 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7893}
7894
7895////////////////////////////////////////////////////////////////////////////////
7896/// The call to Cling's tab complition.
7897
7898void TCling::CodeComplete(const std::string& line, size_t& cursor,
7899 std::vector<std::string>& completions)
7900{
7901 fInterpreter->codeComplete(line, cursor, completions);
7902}
7903
7904////////////////////////////////////////////////////////////////////////////////
7905/// Get the interpreter value corresponding to the statement.
7907{
7909
7910 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7911 auto compRes = fInterpreter->evaluate(code, *V);
7912 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7913}
7914
7915////////////////////////////////////////////////////////////////////////////////
7916
7918{
7919 using namespace cling;
7920 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7922}
7923
7924////////////////////////////////////////////////////////////////////////////////
7925/// Register value as a temporary, extending its lifetime to that of the
7926/// interpreter. This is needed for TCling's compatibility interfaces
7927/// returning long - the address of the temporary objects.
7928/// As such, "simple" types don't need to be stored; they are returned by
7929/// value; only pointers / references / objects need to be stored.
7930
7931void TCling::RegisterTemporary(const cling::Value& value)
7932{
7933 if (value.isValid() && value.needsManagedAllocation()) {
7935 fTemporaries->push_back(value);
7936 }
7937}
7938
7939////////////////////////////////////////////////////////////////////////////////
7940/// If the interpreter encounters Name, check whether that is an object ROOT
7941/// could retrieve. To not re-read objects from disk, cache the name/object
7942/// pair for a given LookupCtx.
7943
7945{
7946 // The call to FindSpecialObject might induces any kind of use
7947 // of the interpreter ... (library loading, function calling, etc.)
7948 // ... and we _know_ we are in the middle of parsing, so let's make
7949 // sure to save the state and then restore it.
7950
7951 if (gDirectory) {
7953 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7954 auto iSpecObj = iSpecObjMap->second.find(Name);
7955 if (iSpecObj != iSpecObjMap->second.end()) {
7957 return iSpecObj->second;
7958 }
7959 }
7960 }
7961
7962 // Save state of the PP
7963 Sema &SemaR = fInterpreter->getSema();
7964 ASTContext& C = SemaR.getASTContext();
7965 Preprocessor &PP = SemaR.getPreprocessor();
7966 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7967 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7968 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7969 // After we have saved the token reset the current one to something which
7970 // is safe (semi colon usually means empty decl)
7971 Token& Tok = const_cast<Token&>(P.getCurToken());
7972 Tok.setKind(tok::semi);
7973
7974 // We can't PushDeclContext, because we go up and the routine that pops
7975 // the DeclContext assumes that we drill down always.
7976 // We have to be on the global context. At that point we are in a
7977 // wrapper function so the parent context must be the global.
7978 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7979 SemaR.TUScope);
7980
7981 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7982 if (specObj) {
7983 if (!LookupCtx) {
7984 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7985 } else {
7987 }
7988 }
7989 return specObj;
7990}
7991
7992////////////////////////////////////////////////////////////////////////////////
7993/// Inject function as a friend into klass.
7994/// With function being f in void f() {new N::PrivKlass(); } this enables
7995/// I/O of non-public classes.
7996
7997void TCling::AddFriendToClass(clang::FunctionDecl* function,
7998 clang::CXXRecordDecl* klass) const
7999{
8000 using namespace clang;
8001 ASTContext& Ctx = klass->getASTContext();
8002 FriendDecl::FriendUnion friendUnion(function);
8003 // one dummy object for the source location
8005 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
8006 klass->pushFriendDecl(friendDecl);
8007}
8008
8009//______________________________________________________________________________
8010//
8011// DeclId getter.
8012//
8013
8014////////////////////////////////////////////////////////////////////////////////
8015/// Return a unique identifier of the declaration represented by the
8016/// CallFunc
8017
8019{
8020 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
8021 return nullptr;
8022}
8023
8024////////////////////////////////////////////////////////////////////////////////
8025/// Return a (almost) unique identifier of the declaration represented by the
8026/// ClassInfo. In ROOT, this identifier can point to more than one TClass
8027/// when the underlying class is a template instance involving one of the
8028/// opaque typedef.
8029
8031{
8032 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
8033 return nullptr;
8034}
8035
8036////////////////////////////////////////////////////////////////////////////////
8037/// Return a unique identifier of the declaration represented by the
8038/// MethodInfo
8039
8041{
8042 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
8043 return nullptr;
8044}
8045
8046////////////////////////////////////////////////////////////////////////////////
8047/// Return a unique identifier of the declaration represented by the
8048/// MethodInfo
8049
8051{
8052 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
8053 return nullptr;
8054}
8055
8056////////////////////////////////////////////////////////////////////////////////
8057/// Return a unique identifier of the declaration represented by the
8058/// TypedefInfo
8059
8061{
8062 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
8063 return nullptr;
8064}
8065
8066//______________________________________________________________________________
8067//
8068// CallFunc interface
8069//
8070
8071////////////////////////////////////////////////////////////////////////////////
8072
8074{
8075 delete (TClingCallFunc*) func;
8076}
8077
8078////////////////////////////////////////////////////////////////////////////////
8079
8080void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
8081{
8082 TClingCallFunc* f = (TClingCallFunc*) func;
8083 f->Exec(address);
8084}
8085
8086////////////////////////////////////////////////////////////////////////////////
8087
8088void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
8089{
8090 TClingCallFunc* f = (TClingCallFunc*) func;
8091 f->Exec(address, &val);
8092}
8093
8094////////////////////////////////////////////////////////////////////////////////
8095
8096void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
8097{
8098 TClingCallFunc* f = (TClingCallFunc*) func;
8099 f->ExecWithReturn(address, ret);
8100}
8101
8102////////////////////////////////////////////////////////////////////////////////
8103
8105 const void* args[] /*=0*/,
8106 int nargs /*=0*/,
8107 void* ret/*=0*/) const
8108{
8109 TClingCallFunc* f = (TClingCallFunc*) func;
8110 f->ExecWithArgsAndReturn(address, args, nargs, ret);
8111}
8112
8113////////////////////////////////////////////////////////////////////////////////
8114
8116{
8117 TClingCallFunc* f = (TClingCallFunc*) func;
8118 return f->ExecInt(address);
8119}
8120
8121////////////////////////////////////////////////////////////////////////////////
8122
8124{
8125 TClingCallFunc* f = (TClingCallFunc*) func;
8126 return f->ExecInt64(address);
8127}
8128
8129////////////////////////////////////////////////////////////////////////////////
8130
8132{
8133 TClingCallFunc* f = (TClingCallFunc*) func;
8134 return f->ExecDouble(address);
8135}
8136
8137////////////////////////////////////////////////////////////////////////////////
8138
8144
8145////////////////////////////////////////////////////////////////////////////////
8146
8148{
8149 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
8150}
8151
8152////////////////////////////////////////////////////////////////////////////////
8153
8155{
8156 TClingCallFunc* f = (TClingCallFunc*) func;
8157 return (MethodInfo_t*) f->FactoryMethod();
8158}
8159
8160////////////////////////////////////////////////////////////////////////////////
8161
8163{
8164 TClingCallFunc* f = (TClingCallFunc*) func;
8165 f->IgnoreExtraArgs(ignore);
8166}
8167
8168////////////////////////////////////////////////////////////////////////////////
8169
8171{
8173 TClingCallFunc* f = (TClingCallFunc*) func;
8174 f->Init();
8175}
8176
8177////////////////////////////////////////////////////////////////////////////////
8178
8180{
8181 TClingCallFunc* f = (TClingCallFunc*) func;
8182 return f->IsValid();
8183}
8184
8185////////////////////////////////////////////////////////////////////////////////
8186
8189{
8190 TClingCallFunc* f = (TClingCallFunc*) func;
8191 return f->IFacePtr();
8192}
8193
8194////////////////////////////////////////////////////////////////////////////////
8195
8197{
8198 TClingCallFunc* f = (TClingCallFunc*) func;
8199 f->ResetArg();
8200}
8201
8202////////////////////////////////////////////////////////////////////////////////
8203
8205{
8206 TClingCallFunc* f = (TClingCallFunc*) func;
8207 f->SetArg(param);
8208}
8209
8210////////////////////////////////////////////////////////////////////////////////
8211
8213{
8214 TClingCallFunc* f = (TClingCallFunc*) func;
8215 f->SetArg(param);
8216}
8217
8218////////////////////////////////////////////////////////////////////////////////
8219
8221{
8222 TClingCallFunc* f = (TClingCallFunc*) func;
8223 f->SetArg(param);
8224}
8225
8226////////////////////////////////////////////////////////////////////////////////
8227
8229{
8230 TClingCallFunc* f = (TClingCallFunc*) func;
8231 f->SetArg(param);
8232}
8233
8234////////////////////////////////////////////////////////////////////////////////
8235
8237{
8238 TClingCallFunc* f = (TClingCallFunc*) func;
8239 f->SetArg(param);
8240}
8241
8242////////////////////////////////////////////////////////////////////////////////
8243
8245{
8246 TClingCallFunc* f = (TClingCallFunc*) func;
8247 f->SetArg(param);
8248}
8249
8250////////////////////////////////////////////////////////////////////////////////
8251
8253{
8254 TClingCallFunc* f = (TClingCallFunc*) func;
8255 f->SetArgArray(paramArr, nparam);
8256}
8257
8258////////////////////////////////////////////////////////////////////////////////
8259
8260void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
8261{
8262 TClingCallFunc* f = (TClingCallFunc*) func;
8263 f->SetArgs(param);
8264}
8265
8266////////////////////////////////////////////////////////////////////////////////
8267
8268void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Longptr_t* offset) const
8269{
8270 TClingCallFunc* f = (TClingCallFunc*) func;
8272 f->SetFunc(ci, method, params, offset);
8273}
8274
8275////////////////////////////////////////////////////////////////////////////////
8276
8277void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Longptr_t* offset) const
8278{
8279 TClingCallFunc* f = (TClingCallFunc*) func;
8281 f->SetFunc(ci, method, params, objectIsConst, offset);
8282}
8283////////////////////////////////////////////////////////////////////////////////
8284
8285void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
8286{
8287 TClingCallFunc* f = (TClingCallFunc*) func;
8289 f->SetFunc(minfo);
8290}
8291
8292////////////////////////////////////////////////////////////////////////////////
8293/// Interface to cling function
8294
8295void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8296{
8297 TClingCallFunc* f = (TClingCallFunc*) func;
8299 f->SetFuncProto(ci, method, proto, offset, mode);
8300}
8301
8302////////////////////////////////////////////////////////////////////////////////
8303/// Interface to cling function
8304
8305void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8306{
8307 TClingCallFunc* f = (TClingCallFunc*) func;
8309 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
8310}
8311
8312////////////////////////////////////////////////////////////////////////////////
8313/// Interface to cling function
8314
8315void 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
8316{
8317 TClingCallFunc* f = (TClingCallFunc*) func;
8319 llvm::SmallVector<clang::QualType, 4> funcProto;
8320 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8321 iter != end; ++iter) {
8322 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8323 }
8324 f->SetFuncProto(ci, method, funcProto, offset, mode);
8325}
8326
8327////////////////////////////////////////////////////////////////////////////////
8328/// Interface to cling function
8329
8330void 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
8331{
8332 TClingCallFunc* f = (TClingCallFunc*) func;
8334 llvm::SmallVector<clang::QualType, 4> funcProto;
8335 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8336 iter != end; ++iter) {
8337 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8338 }
8339 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
8340}
8341
8343{
8344 TClingCallFunc *f = (TClingCallFunc *)func;
8345 std::string wrapper_name;
8346 std::string wrapper;
8347 f->get_wrapper_code(wrapper_name, wrapper);
8348 return wrapper;
8349}
8350
8351//______________________________________________________________________________
8352//
8353// ClassInfo interface
8354//
8355
8356////////////////////////////////////////////////////////////////////////////////
8357
8359{
8361 return TClinginfo->GetAlignOf();
8362}
8363
8364////////////////////////////////////////////////////////////////////////////////
8365/// Return true if the entity pointed to by 'declid' is declared in
8366/// the context described by 'info'. If info is null, look into the
8367/// global scope (translation unit scope).
8368
8370{
8371 if (!declid)
8372 return kFALSE;
8373
8374 const clang::DeclContext *ctxt = nullptr;
8375 if (info) {
8376 ctxt = clang::Decl::castToDeclContext(((TClingClassInfo*)info)->GetDecl());
8377 } else {
8378 ctxt = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
8379 }
8380 if (!ctxt)
8381 return kFALSE;
8382
8383 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
8384 if (!decl)
8385 return kFALSE;
8386
8387 const clang::DeclContext *declDC = decl->getDeclContext();
8388 // ClassInfo_t-s are always "spellable" scopes, never unnamed or inline ones.
8389 while (true) {
8390 if (declDC->isTransparentContext()) {
8391 declDC = declDC->getParent();
8392 continue;
8393 }
8394 if (const auto *declRD = llvm::dyn_cast<clang::RecordDecl>(declDC)) {
8395 if (declRD->isAnonymousStructOrUnion()) {
8396 declDC = declRD->getParent();
8397 continue;
8398 }
8399 }
8400 if (const auto *declNS = llvm::dyn_cast<clang::NamespaceDecl>(declDC)) {
8401 if (declNS->isAnonymousNamespace() || declNS->isInlineNamespace()) {
8402 declDC = declNS->getParent();
8403 continue;
8404 }
8405 }
8406 break;
8407 }
8408
8409 return declDC->Equals(ctxt);
8410}
8411
8412////////////////////////////////////////////////////////////////////////////////
8413
8419
8420////////////////////////////////////////////////////////////////////////////////
8421
8423{
8424 delete (TClingClassInfo*) cinfo;
8425}
8426
8427////////////////////////////////////////////////////////////////////////////////
8428
8434
8435////////////////////////////////////////////////////////////////////////////////
8436
8442
8443////////////////////////////////////////////////////////////////////////////////
8444
8450
8451////////////////////////////////////////////////////////////////////////////////
8452
8458
8459////////////////////////////////////////////////////////////////////////////////
8460
8465
8466////////////////////////////////////////////////////////////////////////////////
8467
8473
8479
8480
8481////////////////////////////////////////////////////////////////////////////////
8482
8483int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
8484{
8486 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
8487}
8488
8489////////////////////////////////////////////////////////////////////////////////
8490
8496
8497////////////////////////////////////////////////////////////////////////////////
8498
8500{
8502 return TClinginfo->HasMethod(name);
8503}
8504
8505////////////////////////////////////////////////////////////////////////////////
8506
8513
8514////////////////////////////////////////////////////////////////////////////////
8515
8522
8523////////////////////////////////////////////////////////////////////////////////
8524
8526{
8528 return TClinginfo->IsBase(name);
8529}
8530
8531////////////////////////////////////////////////////////////////////////////////
8532
8533bool TCling::ClassInfo_IsEnum(const char* name) const
8534{
8536}
8537
8538////////////////////////////////////////////////////////////////////////////////
8539
8545
8546
8547////////////////////////////////////////////////////////////////////////////////
8548
8554
8555
8556////////////////////////////////////////////////////////////////////////////////
8557
8559{
8561 return TClinginfo->IsLoaded();
8562}
8563
8564////////////////////////////////////////////////////////////////////////////////
8565
8567{
8569 return TClinginfo->IsValid();
8570}
8571
8572////////////////////////////////////////////////////////////////////////////////
8573
8574bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8575{
8577 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
8578}
8579
8580////////////////////////////////////////////////////////////////////////////////
8581
8583{
8585 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8586}
8587
8588////////////////////////////////////////////////////////////////////////////////
8589
8595
8596////////////////////////////////////////////////////////////////////////////////
8597
8603
8604////////////////////////////////////////////////////////////////////////////////
8605
8611
8612////////////////////////////////////////////////////////////////////////////////
8613
8615{
8617 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8618}
8619
8620////////////////////////////////////////////////////////////////////////////////
8621
8627
8628////////////////////////////////////////////////////////////////////////////////
8629
8635
8636////////////////////////////////////////////////////////////////////////////////
8637
8643
8644////////////////////////////////////////////////////////////////////////////////
8645
8651
8652////////////////////////////////////////////////////////////////////////////////
8653
8655{
8657 return TClinginfo->FileName();
8658}
8659
8660////////////////////////////////////////////////////////////////////////////////
8661
8663{
8665 TTHREAD_TLS_DECL(std::string,output);
8666 TClinginfo->FullName(output,*fNormalizedCtxt);
8667 return output.c_str(); // NOLINT
8668}
8669
8670////////////////////////////////////////////////////////////////////////////////
8671
8673{
8675 return TClinginfo->Name();
8676}
8677
8678////////////////////////////////////////////////////////////////////////////////
8679
8681{
8683 return TClinginfo->Title();
8684}
8685
8686////////////////////////////////////////////////////////////////////////////////
8687
8689{
8691 return TClinginfo->TmpltName();
8692}
8693
8694
8695
8696//______________________________________________________________________________
8697//
8698// BaseClassInfo interface
8699//
8700
8701////////////////////////////////////////////////////////////////////////////////
8702
8707
8708////////////////////////////////////////////////////////////////////////////////
8709
8716
8717////////////////////////////////////////////////////////////////////////////////
8718
8727
8728////////////////////////////////////////////////////////////////////////////////
8729
8735
8736////////////////////////////////////////////////////////////////////////////////
8737
8743
8744////////////////////////////////////////////////////////////////////////////////
8745
8751
8752////////////////////////////////////////////////////////////////////////////////
8753
8755{
8758 // Offset to the class itself.
8759 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8760 return 0;
8761 }
8762 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8763}
8764
8765////////////////////////////////////////////////////////////////////////////////
8766
8772
8773////////////////////////////////////////////////////////////////////////////////
8774
8780
8781////////////////////////////////////////////////////////////////////////////////
8782
8788
8789////////////////////////////////////////////////////////////////////////////////
8790
8792{
8794 TTHREAD_TLS_DECL(std::string,output);
8795 TClinginfo->FullName(output,*fNormalizedCtxt);
8796 return output.c_str(); // NOLINT
8797}
8798
8799////////////////////////////////////////////////////////////////////////////////
8800
8806
8807////////////////////////////////////////////////////////////////////////////////
8808
8814
8815//______________________________________________________________________________
8816//
8817// DataMemberInfo interface
8818//
8819
8820////////////////////////////////////////////////////////////////////////////////
8821
8827
8828////////////////////////////////////////////////////////////////////////////////
8829
8834
8835////////////////////////////////////////////////////////////////////////////////
8836
8843
8844////////////////////////////////////////////////////////////////////////////////
8845
8847{
8849 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8850 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8852}
8853
8854////////////////////////////////////////////////////////////////////////////////
8855
8861
8862////////////////////////////////////////////////////////////////////////////////
8863
8869
8870////////////////////////////////////////////////////////////////////////////////
8871
8877
8878////////////////////////////////////////////////////////////////////////////////
8879
8885
8886////////////////////////////////////////////////////////////////////////////////
8887
8893
8894////////////////////////////////////////////////////////////////////////////////
8895
8901
8902////////////////////////////////////////////////////////////////////////////////
8903
8909
8910////////////////////////////////////////////////////////////////////////////////
8911
8917
8918////////////////////////////////////////////////////////////////////////////////
8919
8925
8926////////////////////////////////////////////////////////////////////////////////
8927
8933
8934////////////////////////////////////////////////////////////////////////////////
8935
8941
8942////////////////////////////////////////////////////////////////////////////////
8943
8949
8950////////////////////////////////////////////////////////////////////////////////
8951
8953{
8954 TTHREAD_TLS_DECL(std::string,result);
8955
8957 result = TClinginfo->ValidArrayIndex().str();
8958 return result.c_str(); // NOLINT
8959}
8960
8961////////////////////////////////////////////////////////////////////////////////
8962
8963void TCling::SetDeclAttr(DeclId_t declId, const char* attribute)
8964{
8965 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8966 ASTContext &C = decl->getASTContext();
8967 decl->addAttr(AnnotateAttr::CreateImplicit(C, attribute, nullptr, 0));
8968}
8969
8970//______________________________________________________________________________
8971//
8972// Function Template interface
8973//
8974
8975////////////////////////////////////////////////////////////////////////////////
8976
8977static void ConstructorName(std::string &name, const clang::Decl *decl,
8978 cling::Interpreter &interp,
8980{
8981 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8982 if (!td) return;
8983
8984 clang::QualType qualType = td->getASTContext().getTypeDeclType(td);
8986 unsigned int level = 0;
8987 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8988 if (name[cursor] == '>') ++level;
8989 else if (name[cursor] == '<' && level) --level;
8990 else if (level == 0 && name[cursor] == ':') {
8991 name.erase(0,cursor+1);
8992 break;
8993 }
8994 }
8995}
8996
8997////////////////////////////////////////////////////////////////////////////////
8998
8999void TCling::GetFunctionName(const clang::Decl *decl, std::string &output) const
9000{
9001 output.clear();
9002
9003 const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(decl);
9004 if (const auto *USD = llvm::dyn_cast<clang::UsingShadowDecl>(decl)) {
9005 FD = llvm::dyn_cast<clang::FunctionDecl>(USD->getTargetDecl());
9006 }
9007 if (!FD) {
9008 Error("GetFunctionName", "NULL Decl!");
9009 return;
9010 }
9011
9012 // For using-decls, show "Derived", not "Base", i.e. use the
9013 // name of the decl context of the UsingShadowDecl (aka `decl`)
9014 // not the name of FD's decl context.
9015 if (llvm::isa<clang::CXXConstructorDecl>(FD))
9016 {
9018
9019 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
9020 {
9022 output.insert(output.begin(), '~');
9023 } else {
9024 llvm::raw_string_ostream stream(output);
9025 auto printPolicy = decl->getASTContext().getPrintingPolicy();
9026 // Don't trigger fopen of the source file to count lines:
9027 printPolicy.AnonymousTagLocations = false;
9028 FD->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
9029 }
9030}
9031
9032////////////////////////////////////////////////////////////////////////////////
9033/// Return a unique identifier of the declaration represented by the
9034/// FuncTempInfo
9035
9040
9041////////////////////////////////////////////////////////////////////////////////
9042/// Delete the FuncTempInfo_t
9043
9045{
9046 // Currently the address of ft_info is actually the decl itself,
9047 // so we have nothing to do.
9048}
9049
9050////////////////////////////////////////////////////////////////////////////////
9051/// Construct a FuncTempInfo_t
9052
9054{
9055 // Currently the address of ft_info is actually the decl itself,
9056 // so we have nothing to do.
9057
9058 return (FuncTempInfo_t*)const_cast<void*>(declid);
9059}
9060
9061////////////////////////////////////////////////////////////////////////////////
9062/// Construct a FuncTempInfo_t
9063
9065{
9066 // Currently the address of ft_info is actually the decl itself,
9067 // so we have nothing to do.
9068
9069 return (FuncTempInfo_t*)ft_info;
9070}
9071
9072////////////////////////////////////////////////////////////////////////////////
9073/// Check validity of a FuncTempInfo_t
9074
9076{
9077 // Currently the address of ft_info is actually the decl itself,
9078 // so we have nothing to do.
9079
9080 return t_info != nullptr;
9081}
9082
9083////////////////////////////////////////////////////////////////////////////////
9084/// Return the maximum number of template arguments of the
9085/// function template described by ft_info.
9086
9088{
9089 if (!ft_info) return 0;
9090 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
9091 return ft->getTemplateParameters()->size();
9092}
9093
9094////////////////////////////////////////////////////////////////////////////////
9095/// Return the number of required template arguments of the
9096/// function template described by ft_info.
9097
9099{
9100 if (!ft_info) return 0;
9101 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9102 return ft->getTemplateParameters()->getMinRequiredArguments();
9103}
9104
9105////////////////////////////////////////////////////////////////////////////////
9106/// Return the property of the function template.
9107
9109{
9110 if (!ft_info) return 0;
9111
9112 long property = 0L;
9113 property |= kIsCompiled;
9114
9115 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9116
9117 switch (ft->getAccess()) {
9118 case clang::AS_public:
9119 property |= kIsPublic;
9120 break;
9121 case clang::AS_protected:
9122 property |= kIsProtected;
9123 break;
9124 case clang::AS_private:
9125 property |= kIsPrivate;
9126 break;
9127 case clang::AS_none:
9128 if (ft->getDeclContext()->isNamespace())
9130 break;
9131 default:
9132 // IMPOSSIBLE
9133 assert(false && "Unexpected value for the access property value in Clang");
9134 break;
9135 }
9136
9137 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
9138
9139 if (fd && fd->getStorageClass() == clang::SC_Static)
9140 property |= kIsStatic;
9141
9142 if (const clang::CXXMethodDecl *md =
9143 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
9144 if (md->getMethodQualifiers().hasConst()) {
9145 property |= kIsConstant | kIsConstMethod;
9146 }
9147 if (md->isVirtual()) {
9148 property |= kIsVirtual;
9149 }
9150 if (md->isPureVirtual()) {
9151 property |= kIsPureVirtual;
9152 }
9153 if (const clang::CXXConstructorDecl *cd =
9154 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
9155 if (cd->isExplicit()) {
9156 property |= kIsExplicit;
9157 }
9158 }
9159 else if (const clang::CXXConversionDecl *cd =
9160 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
9161 if (cd->isExplicit()) {
9162 property |= kIsExplicit;
9163 }
9164 }
9165 }
9166 return property;
9167}
9168
9169////////////////////////////////////////////////////////////////////////////////
9170/// Return the property not already defined in Property
9171/// See TDictionary's EFunctionProperty
9172
9174{
9175 if (!ft_info) return 0;
9176
9177 long property = 0L;
9178 property |= kIsCompiled;
9179
9180 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9181 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
9182
9183 if (fd->isOverloadedOperator())
9185 if (llvm::isa<clang::CXXConversionDecl>(fd))
9187 if (llvm::isa<clang::CXXConstructorDecl>(fd))
9189 if (llvm::isa<clang::CXXDestructorDecl>(fd))
9191 if (fd->isInlined())
9193 return property;
9194}
9195
9196////////////////////////////////////////////////////////////////////////////////
9197/// Return the name of this function template.
9198
9200{
9201 output.Clear();
9202 if (!ft_info) return;
9203 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
9204 std::string buf;
9205 GetFunctionName(ft->getTemplatedDecl(), buf);
9206 output = buf;
9207}
9208
9209////////////////////////////////////////////////////////////////////////////////
9210/// Return the comments associates with this function template.
9211
9213{
9214 output.Clear();
9215 if (!ft_info) return;
9216 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
9217
9218 // Iterate over the redeclarations, we can have multiple definitions in the
9219 // redecl chain (came from merging of pcms).
9222 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
9223 output = A->getAnnotation().str();
9224 return;
9225 }
9226 }
9227 if (!ft->isFromASTFile()) {
9228 // Try to get the comment from the header file if present
9229 // but not for decls from AST file, where rootcling would have
9230 // created an annotation
9231 output = ROOT::TMetaUtils::GetComment(*ft).str();
9232 }
9233}
9234
9235
9236//______________________________________________________________________________
9237//
9238// MethodInfo interface
9239//
9240
9241////////////////////////////////////////////////////////////////////////////////
9242/// Interface to cling function
9243
9244void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
9245{
9246 delete(TClingMethodInfo*) minfo;
9247}
9248
9249////////////////////////////////////////////////////////////////////////////////
9250
9252{
9254 // The next call locks the interpreter mutex.
9255 info->CreateSignature(signature);
9256}
9257
9258////////////////////////////////////////////////////////////////////////////////
9259
9260MethodInfo_t* TCling::MethodInfo_Factory() const
9261{
9263 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl());
9264}
9265
9266////////////////////////////////////////////////////////////////////////////////
9267
9269{
9271 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
9272}
9273
9274////////////////////////////////////////////////////////////////////////////////
9275
9277{
9278 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
9280 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), decl);
9281}
9282
9283////////////////////////////////////////////////////////////////////////////////
9284
9285MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
9286{
9287 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
9288}
9289
9290////////////////////////////////////////////////////////////////////////////////
9291
9293{
9295 // The next call locks the interpreter mutex.
9296 return info->InterfaceMethod();
9297}
9298
9299////////////////////////////////////////////////////////////////////////////////
9300
9301bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
9302{
9304 return info->IsValid();
9305}
9306
9307////////////////////////////////////////////////////////////////////////////////
9308
9309int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
9310{
9312 return info->NArg();
9313}
9314
9315////////////////////////////////////////////////////////////////////////////////
9316
9318{
9320 return info->NDefaultArg();
9321}
9322
9323////////////////////////////////////////////////////////////////////////////////
9324
9325int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
9326{
9328 return info->Next();
9329}
9330
9331////////////////////////////////////////////////////////////////////////////////
9332
9334{
9336 // The next call locks the interpreter mutex.
9337 return info->Property();
9338}
9339
9340////////////////////////////////////////////////////////////////////////////////
9341
9343{
9345 // The next call locks the interpreter mutex.
9346 return info->ExtraProperty();
9347}
9348
9349////////////////////////////////////////////////////////////////////////////////
9350
9352{
9354 // The next call locks the interpreter mutex.
9355 return (TypeInfo_t*)info->Type();
9356}
9357
9358////////////////////////////////////////////////////////////////////////////////
9359
9360const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
9361{
9364 // The next call locks the interpreter mutex.
9365 mangled_name = info->GetMangledName();
9366 return mangled_name;
9367}
9368
9369////////////////////////////////////////////////////////////////////////////////
9370
9371const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
9372{
9374 // The next call locks the interpreter mutex.
9375 return info->GetPrototype();
9376}
9377
9378////////////////////////////////////////////////////////////////////////////////
9379
9380const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
9381{
9383 // The next call locks the interpreter mutex.
9384 return info->Name();
9385}
9386
9387////////////////////////////////////////////////////////////////////////////////
9388
9389const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
9390{
9392 // The next call locks the interpreter mutex.
9393 return info->TypeName();
9394}
9395
9396////////////////////////////////////////////////////////////////////////////////
9397
9398std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
9399{
9401 // The next part locks the interpreter mutex.
9402 if (info && info->IsValid())
9403 return info->Type()->NormalizedName(*fNormalizedCtxt);
9404 else
9405 return "";
9406}
9407
9408////////////////////////////////////////////////////////////////////////////////
9409
9410const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
9411{
9413 // The next call locks the interpreter mutex.
9414 return info->Title();
9415}
9416
9417////////////////////////////////////////////////////////////////////////////////
9418
9420{
9421 if (func) {
9422 return MethodInfo_MethodCallReturnType(func->fInfo);
9423 } else {
9424 return EReturnType::kOther;
9425 }
9426}
9427
9428////////////////////////////////////////////////////////////////////////////////
9429
9431{
9433 if (info && info->IsValid()) {
9434 TClingTypeInfo *typeinfo = info->Type();
9435 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
9436 if (QT->isEnumeralType()) {
9437 return EReturnType::kLong;
9438 } else if (QT->isPointerType()) {
9439 // Look for char*
9440 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
9441 if ( QT->isCharType() ) {
9442 return EReturnType::kString;
9443 } else {
9444 return EReturnType::kOther;
9445 }
9446 } else if ( QT->isFloatingType() ) {
9447 int sz = typeinfo->Size();
9448 if (sz == 4 || sz == 8) {
9449 // Support only float and double.
9450 return EReturnType::kDouble;
9451 } else {
9452 return EReturnType::kOther;
9453 }
9454 } else if ( QT->isIntegerType() ) {
9455 int sz = typeinfo->Size();
9456 if (sz <= 8) {
9457 // Support only up to long long ... but
9458 // FIXME the TMethodCall::Execute only
9459 // return long (4 bytes) ...
9460 // The v5 implementation of TMethodCall::ReturnType
9461 // was not making the distinction so we let it go
9462 // as is for now, but we really need to upgrade
9463 // TMethodCall::Execute ...
9464 return EReturnType::kLong;
9465 } else {
9466 return EReturnType::kOther;
9467 }
9468 } else {
9469 return EReturnType::kOther;
9470 }
9471 } else {
9472 return EReturnType::kOther;
9473 }
9474}
9475
9476//______________________________________________________________________________
9477//
9478// MethodArgInfo interface
9479//
9480
9481////////////////////////////////////////////////////////////////////////////////
9482
9487
9488////////////////////////////////////////////////////////////////////////////////
9489
9495
9496////////////////////////////////////////////////////////////////////////////////
9497
9503
9504////////////////////////////////////////////////////////////////////////////////
9505
9511
9512////////////////////////////////////////////////////////////////////////////////
9513
9519
9520////////////////////////////////////////////////////////////////////////////////
9521
9527
9528////////////////////////////////////////////////////////////////////////////////
9529
9535
9536////////////////////////////////////////////////////////////////////////////////
9537
9539{
9541 return info->DefaultValue();
9542}
9543
9544////////////////////////////////////////////////////////////////////////////////
9545
9547{
9549 return info->Name();
9550}
9551
9552////////////////////////////////////////////////////////////////////////////////
9553
9555{
9557 return info->TypeName();
9558}
9559
9560////////////////////////////////////////////////////////////////////////////////
9561
9563{
9565 return info->Type()->NormalizedName(*fNormalizedCtxt);
9566}
9567
9568////////////////////////////////////////////////////////////////////////////////
9569
9575
9576//______________________________________________________________________________
9577//
9578// TypeInfo interface
9579//
9580
9581////////////////////////////////////////////////////////////////////////////////
9582
9584{
9585 delete (TClingTypeInfo*) tinfo;
9586}
9587
9588////////////////////////////////////////////////////////////////////////////////
9589
9595
9596////////////////////////////////////////////////////////////////////////////////
9597
9603
9604////////////////////////////////////////////////////////////////////////////////
9605
9610
9611////////////////////////////////////////////////////////////////////////////////
9612
9619
9620////////////////////////////////////////////////////////////////////////////////
9621
9623{
9625 return TClinginfo->IsValid();
9626}
9627
9628////////////////////////////////////////////////////////////////////////////////
9629
9631{
9633 return TClinginfo->Name();
9634}
9635
9636////////////////////////////////////////////////////////////////////////////////
9637
9643
9644////////////////////////////////////////////////////////////////////////////////
9645
9647{
9649 return TClinginfo->RefType();
9650}
9651
9652////////////////////////////////////////////////////////////////////////////////
9653
9655{
9657 return TClinginfo->Size();
9658}
9659
9660////////////////////////////////////////////////////////////////////////////////
9661
9663{
9665 return TClinginfo->TrueName(*fNormalizedCtxt);
9666}
9667
9668////////////////////////////////////////////////////////////////////////////////
9669
9671{
9673 return TClinginfo->QualTypePtr();
9674}
9675
9676
9677//______________________________________________________________________________
9678//
9679// TypedefInfo interface
9680//
9681
9682////////////////////////////////////////////////////////////////////////////////
9683
9688
9689////////////////////////////////////////////////////////////////////////////////
9690
9696
9697////////////////////////////////////////////////////////////////////////////////
9698
9704
9705////////////////////////////////////////////////////////////////////////////////
9706
9711
9712////////////////////////////////////////////////////////////////////////////////
9713
9721
9722////////////////////////////////////////////////////////////////////////////////
9723
9729
9730////////////////////////////////////////////////////////////////////////////////
9731
9737
9738////////////////////////////////////////////////////////////////////////////////
9739
9745
9746////////////////////////////////////////////////////////////////////////////////
9747
9753
9754////////////////////////////////////////////////////////////////////////////////
9755
9761
9762////////////////////////////////////////////////////////////////////////////////
9763
9765{
9767 return TClinginfo->Name();
9768}
9769
9770////////////////////////////////////////////////////////////////////////////////
9771
9773{
9775 return TClinginfo->Title();
9776}
9777
9778////////////////////////////////////////////////////////////////////////////////
9779
9780bool TCling::IsSameType(const void * QualTypePtr1, const void * QualTypePtr2) const
9781{
9782 clang::QualType QT1 = clang::QualType::getFromOpaquePtr(QualTypePtr1);
9783 clang::QualType QT2 = clang::QualType::getFromOpaquePtr(QualTypePtr2);
9784 return fInterpreter->getCI()->getASTContext().hasSameType(QT1, QT2);
9785}
9786
9787////////////////////////////////////////////////////////////////////////////////
9788
9789bool TCling::IsIntegerType(const void * QualTypePtr) const
9790{
9791 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9792 return QT->hasIntegerRepresentation();
9793}
9794
9795////////////////////////////////////////////////////////////////////////////////
9796
9797bool TCling::IsSignedIntegerType(const void * QualTypePtr) const
9798{
9799 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9800 return QT->hasSignedIntegerRepresentation();
9801}
9802
9803////////////////////////////////////////////////////////////////////////////////
9804
9805bool TCling::IsUnsignedIntegerType(const void * QualTypePtr) const
9806{
9807 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9808 return QT->hasUnsignedIntegerRepresentation();
9809}
9810
9811////////////////////////////////////////////////////////////////////////////////
9812
9813bool TCling::IsFloatingType(const void * QualTypePtr) const
9814{
9815 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9816 return QT->hasFloatingRepresentation();
9817}
9818
9819////////////////////////////////////////////////////////////////////////////////
9820
9821bool TCling::IsPointerType(const void * QualTypePtr) const
9822{
9823 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9824 return QT->hasPointerRepresentation();
9825}
9826
9827////////////////////////////////////////////////////////////////////////////////
9828
9829bool TCling::IsVoidPointerType(const void * QualTypePtr) const
9830{
9831 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9832 return QT->isVoidPointerType();
9833}
9834
9835////////////////////////////////////////////////////////////////////////////////
9836
9838{
9839 if (!fInitialMutex) {
9841 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
9842 }
9843 fInitialMutex.fState = mtx->GetStateBefore();
9844 }
9845 // We will "forget" this lock once we backed out of all interpreter frames.
9846 // Here we are entering one, so ++.
9848}
9849
9850////////////////////////////////////////////////////////////////////////////////
9851
9853{
9854 if (!fInitialMutex)
9855 return;
9856 if (fInitialMutex.fRecurseCount == 0) {
9857 Error("ForgetMutexState", "mutex state's recurse count already 0!");
9858 }
9859 else if (--fInitialMutex.fRecurseCount == 0) {
9860 // We have returned from all interpreter frames. Reset the initial lock state.
9861 fInitialMutex.fState.reset();
9862 }
9863}
9864
9865////////////////////////////////////////////////////////////////////////////////
9866/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
9867
9869{
9870 if (gInterpreterMutex) {
9871 if (delta) {
9872 auto typedDelta = static_cast<MutexStateAndRecurseCountDelta *>(delta);
9873 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP{typedDelta};
9874 gCoreMutex->Apply(std::move(typedDelta->fDelta));
9875 // Now that we have the lock, update the global
9876 R__ASSERT(fInitialMutex.fRecurseCount == 0 && "Inconsistent state of fInitialMutex! Another thread within Interpreter critical section.");
9877 std::swap(fInitialMutex, typedDelta->fInitialState);
9878 } else {
9879 // This case happens when EnableThreadSafety is first called from
9880 // the interpreter function we just handled.
9881 // Since thread safety was not enabled at the time we rewound, there was
9882 // no lock taken and even-though we should be locking the rest of this
9883 // interpreter handling/modifying code (since there might be threads in
9884 // flight), we can't because there would not be any lock guard to release the
9885 // locks
9887 Error("ApplyToInterpreterMutex",
9888 "After returning from user code that turned on thread safety support, we notice that fInitialMutex is already used ... "
9889 "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.");
9890 }
9891 }
9892}
9893
9894////////////////////////////////////////////////////////////////////////////////
9895/// Reset the interpreter lock to the state it had before interpreter-related
9896/// calls happened.
9897
9899{
9900 if (fInitialMutex) {
9901 // Need to start a new recurse count.
9902 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP(new MutexStateAndRecurseCountDelta());
9903 std::swap(uniqueP->fInitialState, fInitialMutex);
9904 uniqueP->fDelta = gCoreMutex->Rewind(*uniqueP->fInitialState.fState);
9905 return uniqueP.release();
9906 }
9908 return nullptr;
9909}
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:359
void TCling__TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:597
static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
Definition TCling.cxx:1344
static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
Definition TCling.cxx:7480
void TCling__InvalidateGlobal(const clang::Decl *D)
Definition TCling.cxx:592
bool TClingLookupHelper__AutoParse(const char *cname)
Allow calling autoparsing from TMetaUtils.
Definition TCling.cxx:912
R__EXTERN int optind
Definition TCling.cxx:334
void * TCling__LockCompilationDuringUserCodeExecution()
Lock the interpreter.
Definition TCling.cxx:386
void TCling__UpdateListsOnUnloaded(const cling::Transaction &T)
Definition TCling.cxx:587
void TCling__GetNormalizedContext(const ROOT::TMetaUtils::TNormalizedCtxt *&normCtxt)
Definition TCling.cxx:575
int TCling__LoadLibrary(const char *library)
Load a library.
Definition TCling.cxx:350
void TCling__DEBUG__dump(clang::DeclContext *DC)
Definition TCling.cxx:227
bool TClingLookupHelper__CheckInClassTable(const std::string &tname, std::string &result)
Check if the class name is present in TClassTable.
Definition TCling.cxx:1021
ETupleOrdering
Check in what order the member of a tuple are layout.
Definition TCling.cxx:4057
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:369
static const std::unordered_set< std::string > gIgnoredPCMNames
List of dicts that have the PCM information already in the PCH.
Definition TCling.cxx:2007
static Bool_t s_IsLibraryLoaded(const char *libname, cling::Interpreter *fInterpreter)
Definition TCling.cxx:3273
const char * TCling__GetClassSharedLibs(const char *className, bool skipCore)
Definition TCling.cxx:651
static GlobalModuleIndex * loadGlobalModuleIndex(cling::Interpreter &interp)
Definition TCling.cxx:1116
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:921
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:1101
void TCling__UnlockCompilationDuringUserCodeExecution(void *)
Unlock the interpreter.
Definition TCling.cxx:397
static std::string AlternateTuple(const char *classname, const cling::LookupHelper &lh, Bool_t silent)
Definition TCling.cxx:4099
static bool R__InitStreamerInfoFactory()
Helper to initialize TVirtualStreamerInfo's factor early.
Definition TCling.cxx:1730
int TCling__AutoParseCallback(const char *className)
Definition TCling.cxx:646
clang::RecordDecl * TCling__DEBUG__DCtoRecordDecl(clang::DeclContext *DC)
Definition TCling.cxx:224
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:717
static bool HaveFullGlobalModuleIndex
Definition TCling.cxx:1115
bool TCling__TEST_isInvalidDecl(clang::Decl *D)
Definition TCling.cxx:254
void TCling__LibraryUnloadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:611
void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter *)
Definition TCling.cxx:582
const Decl * TCling__GetObjectDecl(TObject *obj)
Definition TCling.cxx:622
static ETupleOrdering IsTupleAscending()
Definition TCling.cxx:4075
void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Definition TCling.cxx:606
static void TCling__UpdateClassInfo(const NamedDecl *TD)
Update TClingClassInfo for a class (e.g. upon seeing a definition).
Definition TCling.cxx:407
clang::DeclContext * TCling__DEBUG__getDeclContext(clang::Decl *D)
Definition TCling.cxx:218
int TCling__CompileMacro(const char *fileName, const char *options)
Definition TCling.cxx:662
#define R__DLLEXPORT
Definition TCling.cxx:154
void * TCling__ResetInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:378
void TCling__DEBUG__decl_dump(void *D)
Definition TCling.cxx:236
int TCling__AutoLoadCallback(const char *className)
Definition TCling.cxx:641
static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
Definition TCling.cxx:1066
static void RegisterCxxModules(cling::Interpreter &clingInterp)
Definition TCling.cxx:1219
static void ConstructorName(std::string &name, const clang::Decl *decl, cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition TCling.cxx:8977
void TCling__PrintStackTrace()
Print a StackTrace!
Definition TCling.cxx:343
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:2507
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:7389
void TCling__DEBUG__printName(clang::Decl *D)
Definition TCling.cxx:239
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:698
static void PrintDlError(const char *dyLibName, const char *modulename)
Definition TCling.cxx:2032
TInterpreter * CreateInterpreter(void *interpLibHandle, const char *argv[])
Definition TCling.cxx:626
static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH, bool skipCore)
Definition TCling.cxx:7224
const char * fantomline
Definition TCling.cxx:859
void TCling__LibraryLoadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:601
static cling::Interpreter::CompilationResult ExecAutoParse(const char *what, Bool_t header, cling::Interpreter *interpreter)
Parse the payload or header.
Definition TCling.cxx:6543
static bool requiresRootMap(const char *rootmapfile)
Definition TCling.cxx:5723
clang::NamespaceDecl * TCling__DEBUG__DCtoNamespace(clang::DeclContext *DC)
Definition TCling.cxx:221
TObject * TCling__GetObjectAddress(const char *Name, void *&LookupCtx)
Definition TCling.cxx:618
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:1088
int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:657
void DestroyInterpreter(TInterpreter *interp)
Definition TCling.cxx:634
static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
Definition TCling.cxx:7501
void TCling__SplitAclicMode(const char *fileName, string &mode, string &args, string &io, string &fname)
Definition TCling.cxx:669
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:2571
@ 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:1042
bool Append(const std::string &str)
Append string to the storage if not added already.
Definition TCling.cxx:1050
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:6415
const char * MethodArgInfo_DefaultValue(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9538
bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const final
Definition TCling.cxx:8540
const char * TypeInfo_Name(TypeInfo_t *) const final
Definition TCling.cxx:9630
void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const final
Definition TCling.cxx:9292
void LoadEnums(TListOfEnums &cl) const final
Create list of pointers to enums for TClass cl.
Definition TCling.cxx:4606
void UpdateListOfGlobals() final
No op: see TClingCallbacks (used to update the list of globals)
Definition TCling.cxx:4037
bool TypedefInfo_IsValid(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9724
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE) final
Load library containing the specified class.
Definition TCling.cxx:6476
void CallFunc_Init(CallFunc_t *func) const final
Definition TCling.cxx:8170
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:3800
bool LibraryLoadingFailed(const std::string &, const std::string &, bool, bool)
Definition TCling.cxx:6785
void GenericError(const char *error) const final
Let the interpreter issue a generic error, and set its error state.
Definition TCling.cxx:7685
std::vector< void * > fRegisterModuleDyLibs
Definition TCling.h:140
void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const final
Definition TCling.cxx:8096
bool IsIntegerType(const void *QualTypePtr) const final
Definition TCling.cxx:9789
TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const final
Definition TCling.cxx:9351
std::vector< std::string > fAutoLoadLibStorage
Definition TCling.h:118
void CallFunc_Delete(CallFunc_t *func) const final
Definition TCling.cxx:8073
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:7728
void ResetAll() final
Reset the Cling state to its initial state.
Definition TCling.cxx:3876
void SetDeclAttr(DeclId_t, const char *) final
Definition TCling.cxx:8963
void HandleNewDecl(const void *DV, bool isDeserialized, std::set< TClass * > &modifiedClasses)
Definition TCling.cxx:514
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:7120
Long_t MethodInfo_Property(MethodInfo_t *minfo) const final
Definition TCling.cxx:9333
void LoadFunctionTemplates(TClass *cl) const final
Create list of pointers to function templates for TClass cl.
Definition TCling.cxx:4653
bool ClassInfo_IsValidMethod(ClassInfo_t *info, const char *method, const char *proto, Longptr_t *offset, ROOT::EFunctionMatchMode=ROOT::kConversionMatch) const final
Definition TCling.cxx:8574
Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8896
int SetClassAutoparsing(int) final
Enable/Disable the Autoparsing of headers.
Definition TCling.cxx:7813
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:4700
void RewindDictionary() final
Rewind Cling dictionary to the point where it was before executing the current macro.
Definition TCling.cxx:3921
bool ClassInfo_IsValid(ClassInfo_t *info) const final
Definition TCling.cxx:8566
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition TCling.cxx:6994
int TypeInfo_RefType(TypeInfo_t *) const final
Definition TCling.cxx:9646
void CreateListOfBaseClasses(TClass *cl) const final
Create list of pointers to base class(es) for TClass cl.
Definition TCling.cxx:4577
ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const final
Definition TCling.cxx:8453
const char * MethodInfo_Name(MethodInfo_t *minfo) const final
Definition TCling.cxx:9380
BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const final
Definition TCling.cxx:8710
Bool_t LoadText(const char *text) const final
Load the declarations from text into the interpreter.
Definition TCling.cxx:7743
const char * GetSharedLibDeps(const char *lib, bool tryDyld=false) final
Get the list a libraries on which the specified lib depends.
Definition TCling.cxx:7517
EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const final
Definition TCling.cxx:9430
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition TCling.cxx:7944
Longptr_t ProcessLineAsynch(const char *line, EErrorCode *error=nullptr)
Let cling process a command line asynch.
Definition TCling.cxx:3712
bool MethodInfo_IsValid(MethodInfo_t *minfo) const final
Definition TCling.cxx:9301
FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:9053
TypeInfo_t * TypeInfo_Factory() const final
Definition TCling.cxx:9590
bool IsClassAutoLoadingEnabled() const
Returns if class AutoLoading is currently enabled.
Definition TCling.cxx:7782
void InvalidateGlobal(const clang::Decl *D)
Invalidate cached TCling information for the given global declaration.
Definition TCling.cxx:7105
bool IsSameType(const void *QualTypePtr1, const void *QualTypePtr2) const final
Definition TCling.cxx:9780
int Evaluate(const char *, TInterpreterValue &) final
Get the interpreter value corresponding to the statement.
Definition TCling.cxx:7906
std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const final
Definition TCling.cxx:7891
void UpdateListOfLoadedSharedLibraries()
Definition TCling.cxx:3492
const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9772
~TCling() final
Destroy the interpreter interface.
Definition TCling.cxx:1682
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:8295
void InitRootmapFile(const char *name)
Create a resource table and read the (possibly) three resource files, i.e.
Definition TCling.cxx:5866
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:6740
void LoadPCM(std::string pcmFileNameFullPath)
Tries to load a rdict PCM, issues diagnostics if it fails.
Definition TCling.cxx:1879
void UpdateListOfMethods(TClass *cl) const final
Update the list of pointers to method for TClass cl This is now a nop.
Definition TCling.cxx:4718
void AddFriendToClass(clang::FunctionDecl *, clang::CXXRecordDecl *) const
Inject function as a friend into klass.
Definition TCling.cxx:7997
void PrintIntro() final
No-op; see TRint instead.
Definition TCling.cxx:2732
Bool_t fCxxModulesEnabled
Definition TCling.h:130
int BaseClassInfo_Next(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8730
void RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
Internal function. Actually do the update of the ClassInfo when seeing.
Definition TCling.cxx:6852
CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const final
Definition TCling.cxx:8147
Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const final
Definition TCling.cxx:8131
std::set< std::string > fAutoLoadedLibraries
Definition TCling.h:125
void CallFunc_ResetArg(CallFunc_t *func) const final
Definition TCling.cxx:8196
const char * GetCurrentMacroName() const final
Return the file name of the currently interpreted file, included or not.
Definition TCling.cxx:5674
Bool_t IsLoaded(const char *filename) const final
Return true if the file has already been loaded by cint.
Definition TCling.cxx:3316
void SaveGlobalsContext() final
Save the current Cling state of global objects.
Definition TCling.cxx:4024
void CallFunc_IgnoreExtraArgs(CallFunc_t *func, bool ignore) const final
Definition TCling.cxx:8162
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:9868
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition TCling.cxx:6808
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:4934
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:8369
Bool_t IsLibraryLoaded(const char *libname) const final
Definition TCling.cxx:3282
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:7707
int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8822
DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8856
Bool_t HandleNewTransaction(const cling::Transaction &T)
Helper function to increase the internal Cling count of transactions that change the AST.
Definition TCling.cxx:3817
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:5739
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition TCling.h:155
int ClassInfo_Next(ClassInfo_t *info) const final
Definition TCling.cxx:8590
void SetErrmsgcallback(void *p) const final
Set a callback to receive error messages.
Definition TCling.cxx:7834
bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9514
int TypeInfo_Size(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9654
Int_t DeleteGlobal(void *obj) final
Delete obj from Cling symbol table so it cannot be accessed anymore.
Definition TCling.cxx:3935
int GetSecurityError() const final
Interface to cling function.
Definition TCling.cxx:7715
void SetTempLevel(int val) const final
Create / close a scope for temporaries.
Definition TCling.cxx:7870
void Print(Option_t *option="") const final
Print information about the interpreter.
Definition TCling.cxx:2742
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:9087
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:5366
TypedefInfo_t * TypedefInfo_Factory() const final
Definition TCling.cxx:9691
TObjArray * fRootmapFiles
Definition TCling.h:128
Longptr_t ProcessLine(const char *line, EErrorCode *error=nullptr) final
Definition TCling.cxx:2537
int ClassInfo_Size(ClassInfo_t *info) const final
Definition TCling.cxx:8638
const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9554
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:5614
std::vector< std::pair< TClass *, DictFuncPtr_t > > fClassesToUpdate
Definition TCling.h:148
int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8880
const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9764
void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8703
Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const final
Definition TCling.cxx:9342
void LoadMacro(const char *filename, EErrorCode *error=nullptr) final
Load a macro file in cling's memory.
Definition TCling.cxx:3704
FuncTempInfo_t * FuncTempInfo_FactoryCopy(FuncTempInfo_t *) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:9064
int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const final
Definition TCling.cxx:8872
Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const final
Check validity of a FuncTempInfo_t.
Definition TCling.cxx:9075
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:2774
bool ClassInfo_IsBase(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8525
void RecursiveRemove(TObject *obj) final
Delete object from cling symbol table so it can not be used anymore.
Definition TCling.cxx:3835
const char * DataMemberInfo_TypeName(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8920
DeclId_t GetDataMemberAtAddr(const void *addr) const final
Return pointer to cling DeclId for a data member with a given name.
Definition TCling.cxx:5161
void CallFunc_SetArgArray(CallFunc_t *func, Longptr_t *paramArr, Int_t nparam) const final
Definition TCling.cxx:8252
std::string CallFunc_GetWrapperCode(CallFunc_t *func) const final
Definition TCling.cxx:8342
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:9898
const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9546
Bool_t HasPCMForLibrary(const char *libname) const final
Return true if ROOT has cxxmodules pcm for a given library name.
Definition TCling.cxx:3291
void TypedefInfo_Init(TypedefInfo_t *tinfo, const char *name) const final
Definition TCling.cxx:9714
const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8944
Longptr_t CallFunc_ExecInt(CallFunc_t *func, void *address) const final
Definition TCling.cxx:8115
void ClearStack() final
Delete existing temporary values.
Definition TCling.cxx:3199
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:7764
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:7584
MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const final
Definition TCling.cxx:8154
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:3558
TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9707
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:5259
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:2477
std::string MethodArgInfo_TypeNormalizedName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9562
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:5043
Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9530
int TypedefInfo_Size(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9748
void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:8104
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:5411
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:6974
Int_t Load(const char *filenam, Bool_t system=kFALSE) final
Load a library file in cling's memory.
Definition TCling.cxx:3667
int TypedefInfo_Next(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9732
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:5218
void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const final
Definition TCling.cxx:9613
Bool_t SetSuspendAutoParsing(Bool_t value) final
Suspend the Autoparsing of headers.
Definition TCling.cxx:7824
int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8912
static void * fgSetOfSpecials
Definition TCling.h:105
const char * ClassInfo_Title(ClassInfo_t *info) const final
Definition TCling.cxx:8680
const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8936
const char * TypeName(const char *typeDesc) final
Return the absolute type of typeDesc.
Definition TCling.cxx:5689
ROOT::TMetaUtils::TNormalizedCtxt * fNormalizedCtxt
Definition TCling.h:136
void ForgetMutexState() final
Definition TCling.cxx:9852
int MethodInfo_Next(MethodInfo_t *minfo) const final
Definition TCling.cxx:9325
Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const final
Definition TCling.cxx:8414
void MethodInfo_Delete(MethodInfo_t *minfo) const final
Interface to cling function.
Definition TCling.cxx:9244
bool fIsShuttingDown
Definition TCling.h:189
void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9483
bool IsSignedIntegerType(const void *QualTypePtr) const final
Definition TCling.cxx:9797
DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo, TDictionary::EMemberSelection selection) const final
Definition TCling.cxx:8837
void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const final
Definition TCling.cxx:8445
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:6321
Int_t UnloadAllSharedLibraryMaps() final
Unload the library map entries coming from all the loaded shared libraries.
Definition TCling.cxx:6209
void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const final
Definition TCling.cxx:8507
std::set< TClass * > & GetModTClasses()
Definition TCling.h:591
ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const final
Definition TCling.cxx:8775
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:4366
TClingCallbacks * fClingCallbacks
Definition TCling.h:141
Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const final
Definition TCling.cxx:8123
Long_t ClassInfo_Property(ClassInfo_t *info) const final
Definition TCling.cxx:8630
Longptr_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8754
void UpdateEnumConstants(TEnum *enumObj, TClass *cl) const final
Definition TCling.cxx:439
void ExecuteWithArgsAndReturn(TMethod *method, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:5596
Bool_t IsErrorMessagesEnabled() const final
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition TCling.cxx:7570
TString fIncludePath
Definition TCling.h:115
int DisplayIncludePath(FILE *fout) const final
Interface to cling function.
Definition TCling.cxx:7647
void TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:7179
Long_t FuncTempInfo_Property(FuncTempInfo_t *) const final
Return the property of the function template.
Definition TCling.cxx:9108
TEnum * CreateEnum(void *VD, TClass *cl) const final
Definition TCling.cxx:487
const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9662
Int_t UnloadLibraryMap(const char *library) final
Unload library map entries coming from the specified library.
Definition TCling.cxx:6227
void RegisterTemporary(const TInterpreterValue &value)
Definition TCling.cxx:7917
MutexStateAndRecurseCount fInitialMutex
Definition TCling.h:176
const char * GetSharedLibs() final
Return the list of shared libraries loaded into the process.
Definition TCling.cxx:7217
int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9522
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx) final
Definition TCling.cxx:9837
Long_t TypeInfo_Property(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9638
const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const final
Definition TCling.cxx:9371
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:9098
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:2079
static Int_t ShallowAutoLoadImpl(const char *cls)
Definition TCling.cxx:6367
void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const final
Definition TCling.cxx:9251
Bool_t CheckClassTemplate(const char *name) final
Return true if there is a class template by the given name ...
Definition TCling.cxx:4555
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:7202
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:2468
bool IsVoidPointerType(const void *QualTypePtr) const final
Definition TCling.cxx:9829
TObjArray * GetRootMapFiles() const final
Definition TCling.h:226
bool DataMemberInfo_IsValid(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8864
bool ClassInfo_IsEnum(const char *name) const final
Definition TCling.cxx:8533
int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9317
bool IsFloatingType(const void *QualTypePtr) const final
Definition TCling.cxx:9813
void CreateListOfMethods(TClass *cl) const final
Create list of pointers to methods for TClass cl.
Definition TCling.cxx:4709
Int_t RescanLibraryMap() final
Scan again along the dynamic path for library maps.
Definition TCling.cxx:6136
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:7843
const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9360
TypeInfo_t * MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9570
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:5321
void * ClassInfo_New(ClassInfo_t *info) const final
Definition TCling.cxx:8598
int DisplayClass(FILE *fout, const char *name, int base, int start) const final
Definition TCling.cxx:7638
void GetFunctionName(const clang::Decl *decl, std::string &name) const
Definition TCling.cxx:8999
void CreateListOfMethodArgs(TFunction *m) const final
Create list of pointers to method arguments for TMethod m.
Definition TCling.cxx:4734
const char * GetSTLIncludePath() const final
Return the directory containing CINT's stl cintdlls.
Definition TCling.cxx:7629
MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9506
Longptr_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8746
void * FindSym(const char *entry) const final
Interface to cling function.
Definition TCling.cxx:7676
void RegisterLoadedSharedLibrary(const char *name)
Register a new shared library name with the interpreter; add it to fSharedLibs.
Definition TCling.cxx:3567
void TypeInfo_Delete(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9583
int MethodInfo_NArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9309
DeclId_t GetDataMemberWithValue(const void *ptrvalue) const final
NOT IMPLEMENTED.
Definition TCling.cxx:5152
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition TCling.h:127
EReturnType MethodCallReturnType(TFunction *func) const final
Definition TCling.cxx:9419
void ProcessClassesToUpdate()
Definition TCling.cxx:2048
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:5344
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:5173
const char * MethodInfo_Title(MethodInfo_t *minfo) const final
Definition TCling.cxx:9410
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:4213
const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8809
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:3236
const char * BaseClassInfo_FullName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8791
void CallFunc_SetArgs(CallFunc_t *func, const char *param) const final
Definition TCling.cxx:8260
int UnloadFile(const char *path) const final
Definition TCling.cxx:7876
void CallFunc_Exec(CallFunc_t *func, void *address) const final
Definition TCling.cxx:8080
Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const final
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition TCling.cxx:9173
bool CallFunc_IsValid(CallFunc_t *func) const final
Definition TCling.cxx:8179
const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8801
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition TCling.h:137
const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8952
Int_t GetMore() const final
Return whether we are waiting for more input either because the collected input contains unbalanced b...
Definition TCling.cxx:4755
Bool_t fIsAutoParsingSuspended
Definition TCling.h:184
std::string ToString(const char *type, void *obj) final
Definition TCling.cxx:1059
DeclId_t GetDeclId(const llvm::GlobalValue *gv) const
Return pointer to cling DeclId for a global value.
Definition TCling.cxx:5083
void Execute(const char *function, const char *params, int *error=nullptr) final
Execute a global function with arguments params.
Definition TCling.cxx:5444
bool ClassInfo_IsLoaded(ClassInfo_t *info) const final
Definition TCling.cxx:8558
Longptr_t ClassInfo_Tagnum(ClassInfo_t *info) const final
Definition TCling.cxx:8646
Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8767
void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Longptr_t *Offset) const final
Definition TCling.cxx:8268
std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const final
Get the scopes representing using declarations of namespace.
Definition TCling.cxx:4689
const char * ClassInfo_FileName(ClassInfo_t *info) const final
Definition TCling.cxx:8654
void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const final
Return the comments associates with this function template.
Definition TCling.cxx:9212
const char * ClassInfo_TmpltName(ClassInfo_t *info) const final
Definition TCling.cxx:8688
void SaveContext() final
Save the current Cling state.
Definition TCling.cxx:4011
void LoadPCMImpl(TFile &pcmFile)
Tries to load a PCM from TFile; returns true on success.
Definition TCling.cxx:1763
Bool_t IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:6844
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:3892
void CodeComplete(const std::string &, size_t &, std::vector< std::string > &) final
The call to Cling's tab complition.
Definition TCling.cxx:7898
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:3906
const char * MapCppName(const char *) const final
Interface to cling function.
Definition TCling.cxx:7751
Longptr_t Calc(const char *line, EErrorCode *error=nullptr) final
Directly execute an executable statement (e.g.
Definition TCling.cxx:3737
Int_t ReloadAllSharedLibraryMaps() final
Reload the library map entries coming from all the loaded shared libraries, after first unloading the...
Definition TCling.cxx:6148
void UpdateListOfGlobalFunctions() final
No op: see TClingCallbacks (used to update the list of global functions)
Definition TCling.cxx:4044
void DataMemberInfo_Delete(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8830
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:5627
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:4727
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:2796
Int_t SetClassSharedLibs(const char *cls, const char *libs) final
Register the AutoLoading information for a class.
Definition TCling.cxx:6289
MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const final
Definition TCling.cxx:9285
std::set< const char * > fParsedPayloadsAddresses
Definition TCling.h:123
CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const final
Definition TCling.cxx:8188
MethodArgInfo_t * MethodArgInfo_Factory() const final
Definition TCling.cxx:9490
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition TCling.cxx:6968
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:5240
void ClassInfo_Delete(ClassInfo_t *info) const final
Definition TCling.cxx:8422
std::unique_ptr< cling::Interpreter > fInterpreter
Definition TCling.h:132
EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const final
Definition TCling.cxx:8549
void FuncTempInfo_Delete(FuncTempInfo_t *) const final
Delete the FuncTempInfo_t.
Definition TCling.cxx:9044
bool IsUnsignedIntegerType(const void *QualTypePtr) const final
Definition TCling.cxx:9805
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:5388
Int_t DeleteVariable(const char *name) final
Undeclare obj called name.
Definition TCling.cxx:3950
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:7323
Longptr_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8888
CallFunc_t * CallFunc_Factory() const final
Definition TCling.cxx:8139
MethodInfo_t * MethodInfo_Factory() const final
Definition TCling.cxx:9260
Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8904
void ClearFileBusy() final
Reset the interpreter internal state in case a previous action was not correctly terminated.
Definition TCling.cxx:3191
cling::MetaProcessor * GetMetaProcessorImpl() const
Definition TCling.h:657
bool DiagnoseIfInterpreterException(const std::exception &e) const final
Definition TCling.cxx:2526
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:7774
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:3182
void AddAvailableIndentifiers(TSeqCollection &Idents) final
Definition TCling.cxx:2442
void TypedefInfo_Delete(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9684
void Reset() final
Pressing Ctrl+C should forward here.
Definition TCling.cxx:3860
const char * TypedefInfo_TrueName(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9756
int SetClassAutoLoading(int) const final
Enable/Disable the AutoLoading of libraries.
Definition TCling.cxx:7795
const char * ClassInfo_FullName(ClassInfo_t *info) const final
Definition TCling.cxx:8662
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:6592
const char * MethodInfo_TypeName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9389
void CallFunc_SetArg(CallFunc_t *func, Long_t param) const final
Definition TCling.cxx:8204
const char * GetIncludePath() final
Refresh the list of include paths known to the interpreter and return it with -I prepended.
Definition TCling.cxx:7598
void UpdateListsOnUnloaded(const cling::Transaction &T)
Invalidate stored TCling state for declarations included in transaction ‘T’.
Definition TCling.cxx:7078
void UpdateClassInfoWithDecl(const clang::NamedDecl *ND)
Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
Definition TCling.cxx:6910
void Initialize() final
Initialize the interpreter, once TROOT::fInterpreter is set.
Definition TCling.cxx:1700
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:8483
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:4982
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:9199
std::unique_ptr< cling::MetaProcessor > fMetaProcessor
Definition TCling.h:133
bool TypeInfo_IsValid(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9622
bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const final
Definition TCling.cxx:1974
std::string MethodInfo_TypeNormalizedName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9398
const char * ClassInfo_Name(ClassInfo_t *info) const final
Definition TCling.cxx:8672
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE) final
Generate a TClass for the given class.
Definition TCling.cxx:4765
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:8491
void EndOfLineAction() final
It calls a "fantom" method to synchronize user keyboard input and ROOT prompt line.
Definition TCling.cxx:3265
TypeInfo_t * TypeInfo_FactoryCopy(TypeInfo_t *) const final
Definition TCling.cxx:9606
size_t ClassInfo_AlignOf(ClassInfo_t *info) const final
Definition TCling.cxx:8358
bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8499
void ClassInfo_DeleteArray(ClassInfo_t *info, void *arena, bool dtorOnly) const final
Definition TCling.cxx:8437
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:8928
void ShutDown() final
Definition TCling.cxx:1721
void UpdateListOfTypes() final
No op: see TClingCallbacks (used to update the list of types)
Definition TCling.cxx:4051
void * TypeInfo_QualTypePtr(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9670
Long_t TypedefInfo_Property(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9740
void RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Register Rdict data for future loading by LoadPCM;.
Definition TCling.cxx:1744
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:3721
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:5200
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition TCling.cxx:6983
Int_t LoadLibraryMap(const char *rootmapfile=nullptr) final
Load map between class and library.
Definition TCling.cxx:5952
Longptr_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8783
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:7209
bool IsPointerType(const void *QualTypePtr) const final
Definition TCling.cxx:9821
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:1082
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:424
static TClass * Class()
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1096
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1124
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:1070
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:1242
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:2460
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:1290
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition TSystem.cxx:860
virtual void * OpenDirectory(const char *name)
Open a directory.
Definition TSystem.cxx:851
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1681
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:1554
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition TSystem.cxx:1873
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:1414
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition TSystem.cxx:1097
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:1312
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition TSystem.cxx:868
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition TSystem.cxx:2510
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:949
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition TSystem.cxx:1811
virtual const char * FindDynamicLibrary(TString &lib, Bool_t quiet=kFALSE)
Find a dynamic library using the system search paths.
Definition TSystem.cxx:2050
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition TSystem.cxx:440
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:886
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1564
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition TSystem.cxx:1665
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition TSystem.cxx:902
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1047
virtual void StackTrace()
Print a stack trace.
Definition TSystem.cxx:748
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
Definition TSystem.cxx:2036
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