Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TCling.cxx
Go to the documentation of this file.
1// @(#)root/meta:$Id$
2// vim: sw=3 ts=3 expandtab foldmethod=indent
3
4/*************************************************************************
5 * Copyright (C) 1995-2012, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TCling
13
14This class defines an interface to the cling C++ interpreter.
15
16Cling is a full ANSI compliant C++-11 interpreter based on
17clang/LLVM technology.
18*/
19
20#include "TCling.h"
21
23
24#include "TClingBaseClassInfo.h"
25#include "TClingCallFunc.h"
26#include "TClingClassInfo.h"
28#include "TClingMethodArgInfo.h"
29#include "TClingMethodInfo.h"
31#include "TClingTypedefInfo.h"
32#include "TClingTypeInfo.h"
33#include "TClingValue.h"
34
35#include "TROOT.h"
36#include "TApplication.h"
37#include "TGlobal.h"
38#include "TDataType.h"
39#include "TClass.h"
40#include "TClassEdit.h"
41#include "TClassTable.h"
42#include "TClingCallbacks.h"
43#include "TClingDiagnostics.h"
44#include "TBaseClass.h"
45#include "TDataMember.h"
46#include "TMemberInspector.h"
47#include "TMethod.h"
48#include "TMethodArg.h"
49#include "TFunctionTemplate.h"
50#include "TObjArray.h"
51#include "TObjString.h"
52#include "TString.h"
53#include "THashList.h"
54#include "TVirtualPad.h"
55#include "TSystem.h"
56#include "TVirtualMutex.h"
57#include "TError.h"
58#include "TEnv.h"
59#include "TEnum.h"
60#include "TEnumConstant.h"
61#include "THashTable.h"
63#include "RConfigure.h"
64#include "compiledata.h"
65#include "strlcpy.h"
66#include "snprintf.h"
67#include "TClingUtils.h"
70#include "TListOfDataMembers.h"
71#include "TListOfEnums.h"
73#include "TListOfFunctions.h"
75#include "TMemFile.h"
76#include "TProtoClass.h"
77#include "TStreamerInfo.h" // This is here to avoid to use the plugin manager
78#include "ThreadLocalStorage.h"
79#include "TFile.h"
80#include "TKey.h"
81#include "ClingRAII.h"
82
83#include "clang/AST/ASTContext.h"
84#include "clang/AST/Decl.h"
85#include "clang/AST/DeclarationName.h"
86#include "clang/AST/GlobalDecl.h"
87#include "clang/AST/RecordLayout.h"
88#include "clang/AST/DeclVisitor.h"
89#include "clang/AST/RecursiveASTVisitor.h"
90#include "clang/AST/Type.h"
91#include "clang/Basic/SourceLocation.h"
92#include "clang/Basic/Specifiers.h"
93#include "clang/Basic/TargetInfo.h"
94#include "clang/CodeGen/ModuleBuilder.h"
95#include "clang/Frontend/CompilerInstance.h"
96#include "clang/Frontend/FrontendDiagnostic.h"
97#include "clang/Lex/HeaderSearch.h"
98#include "clang/Lex/Preprocessor.h"
99#include "clang/Lex/PreprocessorOptions.h"
100#include "clang/Parse/Parser.h"
101#include "clang/Sema/Lookup.h"
102#include "clang/Sema/Sema.h"
103#include "clang/Serialization/ASTReader.h"
104#include "clang/Serialization/GlobalModuleIndex.h"
105
106#include "cling/Interpreter/ClangInternalState.h"
107#include "cling/Interpreter/DynamicLibraryManager.h"
108#include "cling/Interpreter/Interpreter.h"
109#include "cling/Interpreter/LookupHelper.h"
110#include "cling/Interpreter/Value.h"
111#include "cling/Interpreter/Transaction.h"
112#include "cling/MetaProcessor/MetaProcessor.h"
113#include "cling/Utils/AST.h"
114#include "cling/Utils/ParserStateRAII.h"
115#include "cling/Utils/SourceNormalization.h"
116#include "cling/Interpreter/Exception.h"
117
118#include "llvm/IR/GlobalValue.h"
119#include "llvm/IR/Module.h"
120
121#include "llvm/Support/DynamicLibrary.h"
122#include "llvm/Support/raw_ostream.h"
123#include "llvm/Support/Path.h"
124#include "llvm/Support/Process.h"
125#include "llvm/Object/ELFObjectFile.h"
126#include "llvm/Object/ObjectFile.h"
127#include "llvm/Object/SymbolicFile.h"
128#include "llvm/Support/FileSystem.h"
129
130#include <algorithm>
131#include <iostream>
132#include <cassert>
133#include <map>
134#include <set>
135#include <stdexcept>
136#include <stdint.h>
137#include <fstream>
138#include <sstream>
139#include <string>
140#include <tuple>
141#include <typeinfo>
142#include <unordered_map>
143#include <unordered_set>
144#include <utility>
145#include <vector>
146#include <functional>
147
148#ifndef R__WIN32
149#include <cxxabi.h>
150#define R__DLLEXPORT __attribute__ ((visibility ("default")))
151#include <sys/stat.h>
152#endif
153#include <limits.h>
154#include <stdio.h>
155
156#ifdef __APPLE__
157#include <dlfcn.h>
158#include <mach-o/dyld.h>
159#include <mach-o/loader.h>
160#endif // __APPLE__
161
162#ifdef R__UNIX
163#include <dlfcn.h>
164#endif
165
166#if defined(R__LINUX) || defined(R__FBSD)
167# ifndef _GNU_SOURCE
168# define _GNU_SOURCE
169# endif
170# include <link.h> // dl_iterate_phdr()
171#endif
172
173#if defined(__CYGWIN__)
174#include <sys/cygwin.h>
175#define HMODULE void *
176extern "C" {
177 __declspec(dllimport) void * __stdcall GetCurrentProcess();
178 __declspec(dllimport) bool __stdcall EnumProcessModules(void *, void **, unsigned long, unsigned long *);
179 __declspec(dllimport) unsigned long __stdcall GetModuleFileNameExW(void *, void *, wchar_t *, unsigned long);
180}
181#endif
182
183// Fragment copied from LLVM's raw_ostream.cpp
184#if defined(_MSC_VER)
185#ifndef STDIN_FILENO
186# define STDIN_FILENO 0
187#endif
188#ifndef STDOUT_FILENO
189# define STDOUT_FILENO 1
190#endif
191#ifndef STDERR_FILENO
192# define STDERR_FILENO 2
193#endif
194#ifndef R__WIN32
195//#if defined(HAVE_UNISTD_H)
196# include <unistd.h>
197//#endif
198#else
199#include "Windows4Root.h"
200#include <Psapi.h>
201#undef GetModuleFileName
202#define RTLD_DEFAULT ((void *)::GetModuleHandle(NULL))
203#define dlsym(library, function_name) ::GetProcAddress((HMODULE)library, function_name)
204#define dlopen(library_name, flags) ::LoadLibraryA(library_name)
205#define dlclose(library) ::FreeLibrary((HMODULE)library)
206#define R__DLLEXPORT __declspec(dllexport)
207#endif
208#endif
209
210//______________________________________________________________________________
211// These functions are helpers for debugging issues with non-LLVMDEV builds.
212//
213R__DLLEXPORT clang::DeclContext* TCling__DEBUG__getDeclContext(clang::Decl* D) {
214 return D->getDeclContext();
215}
216R__DLLEXPORT clang::NamespaceDecl* TCling__DEBUG__DCtoNamespace(clang::DeclContext* DC) {
217 return llvm::dyn_cast<clang::NamespaceDecl>(DC);
218}
219R__DLLEXPORT clang::RecordDecl* TCling__DEBUG__DCtoRecordDecl(clang::DeclContext* DC) {
220 return llvm::dyn_cast<clang::RecordDecl>(DC);
221}
222R__DLLEXPORT void TCling__DEBUG__dump(clang::DeclContext* DC) {
223 return DC->dumpDeclContext();
224}
225R__DLLEXPORT void TCling__DEBUG__dump(clang::Decl* D) {
226 return D->dump();
227}
228R__DLLEXPORT void TCling__DEBUG__dump(clang::FunctionDecl* FD) {
229 return FD->dump();
230}
232 return ((clang::Decl*)D)->dump();
233}
235 if (clang::NamedDecl* ND = llvm::dyn_cast<clang::NamedDecl>(D)) {
236 std::string name;
237 {
238 llvm::raw_string_ostream OS(name);
239 ND->getNameForDiagnostic(OS, D->getASTContext().getPrintingPolicy(),
240 true /*Qualified*/);
241 }
242 printf("%s\n", name.c_str());
243 }
244}
245//______________________________________________________________________________
246// These functions are helpers for testing issues directly rather than
247// relying on side effects.
248// This is used for the test for ROOT-7462/ROOT-6070
250 return D->isInvalidDecl();
251}
254 assert(info && info->IsValid());
255 return info->GetDecl()->isInvalidDecl();
256}
257
258using namespace std;
259using namespace clang;
260using namespace ROOT;
261
262namespace {
263 static const std::string gInterpreterClassDef = R"ICF(
264#undef ClassDef
265#define ClassDef(name, id) \
266_ClassDefInterp_(name,id,virtual,) \
267static int DeclFileLine() { return __LINE__; }
268#undef ClassDefNV
269#define ClassDefNV(name, id) \
270_ClassDefInterp_(name,id,,) \
271static int DeclFileLine() { return __LINE__; }
272#undef ClassDefOverride
273#define ClassDefOverride(name, id) \
274_ClassDefInterp_(name,id,,override) \
275static int DeclFileLine() { return __LINE__; }
276)ICF";
277
278 static const std::string gNonInterpreterClassDef = R"ICF(
279#define __ROOTCLING__ 1
280#undef ClassDef
281#define ClassDef(name,id) \
282_ClassDefOutline_(name,id,virtual,) \
283static int DeclFileLine() { return __LINE__; }
284#undef ClassDefNV
285#define ClassDefNV(name, id)\
286_ClassDefOutline_(name,id,,)\
287static int DeclFileLine() { return __LINE__; }
288#undef ClassDefOverride
289#define ClassDefOverride(name, id)\
290_ClassDefOutline_(name,id,,override)\
291static int DeclFileLine() { return __LINE__; }
292)ICF";
293
294// The macros below use ::Error, so let's ensure it is included
295 static const std::string gClassDefInterpMacro = R"ICF(
296#include "TError.h"
297
298#define _ClassDefInterp_(name,id,virtual_keyword, overrd) \
299private: \
300public: \
301 static TClass *Class() { static TClass* sIsA = 0; if (!sIsA) sIsA = TClass::GetClass(#name); return sIsA; } \
302 static const char *Class_Name() { return #name; } \
303 virtual_keyword Bool_t CheckTObjectHashConsistency() const overrd { return true; } \
304 static Version_t Class_Version() { return id; } \
305 static TClass *Dictionary() { return 0; } \
306 virtual_keyword TClass *IsA() const overrd { return name::Class(); } \
307 virtual_keyword void ShowMembers(TMemberInspector&insp) const overrd { ::ROOT::Class_ShowMembers(name::Class(), this, insp); } \
308 virtual_keyword void Streamer(TBuffer&) overrd { ::Error("Streamer", "Cannot stream interpreted class."); } \
309 void StreamerNVirtual(TBuffer&ClassDef_StreamerNVirtual_b) { name::Streamer(ClassDef_StreamerNVirtual_b); } \
310 static const char *DeclFileName() { return __FILE__; } \
311 static int ImplFileLine() { return 0; } \
312 static const char *ImplFileName() { return __FILE__; }
313)ICF";
314}
316
317// The functions are used to bridge cling/clang/llvm compiled with no-rtti and
318// ROOT (which uses rtti)
319
320////////////////////////////////////////////////////////////////////////////////
321/// Print a StackTrace!
322
323extern "C"
326}
327
328////////////////////////////////////////////////////////////////////////////////
329/// Load a library.
330
331extern "C" int TCling__LoadLibrary(const char *library)
332{
333 return gSystem->Load(library, "", false);
334}
335
336////////////////////////////////////////////////////////////////////////////////
337/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
338
339extern "C" void TCling__RestoreInterpreterMutex(void *delta)
340{
341 ((TCling*)gCling)->ApplyToInterpreterMutex(delta);
342}
343
344////////////////////////////////////////////////////////////////////////////////
345/// Lookup libraries in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH with mangled_name,
346/// which is extracted by error messages we get from callback from cling. Return true
347/// when the missing library was autoloaded.
348
349extern "C" bool TCling__LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
350{
351 return ((TCling*)gCling)->LibraryLoadingFailed(errmessage, libStem, permanent, resolved);
352}
353
354////////////////////////////////////////////////////////////////////////////////
355/// Reset the interpreter lock to the state it had before interpreter-related
356/// calls happened.
357
359{
360 return ((TCling*)gCling)->RewindInterpreterMutex();
361}
362
363////////////////////////////////////////////////////////////////////////////////
364/// Lock the interpreter.
365
367{
368 if (gInterpreterMutex) {
370 }
371 return nullptr;
372}
373
374////////////////////////////////////////////////////////////////////////////////
375/// Unlock the interpreter.
376
378{
379 if (gInterpreterMutex) {
381 }
382}
383
384////////////////////////////////////////////////////////////////////////////////
385/// Update TClingClassInfo for a class (e.g. upon seeing a definition).
386
387static void TCling__UpdateClassInfo(const NamedDecl* TD)
388{
389 static Bool_t entered = kFALSE;
390 static vector<const NamedDecl*> updateList;
391 Bool_t topLevel;
392
393 if (entered) topLevel = kFALSE;
394 else {
395 entered = kTRUE;
396 topLevel = kTRUE;
397 }
398 if (topLevel) {
399 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(TD);
400 } else {
401 // If we are called indirectly from within another call to
402 // TCling::UpdateClassInfo, we delay the update until the dictionary loading
403 // is finished (i.e. when we return to the top level TCling::UpdateClassInfo).
404 // This allows for the dictionary to be fully populated when we actually
405 // update the TClass object. The updating of the TClass sometimes
406 // (STL containers and when there is an emulated class) forces the building
407 // of the TClass object's real data (which needs the dictionary info).
408 updateList.push_back(TD);
409 }
410 if (topLevel) {
411 while (!updateList.empty()) {
412 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(updateList.back());
413 updateList.pop_back();
414 }
415 entered = kFALSE;
416 }
417}
418
419void TCling::UpdateEnumConstants(TEnum* enumObj, TClass* cl) const {
420 const clang::Decl* D = static_cast<const clang::Decl*>(enumObj->GetDeclId());
421 if(const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(D)) {
422 // Add the constants to the enum type.
423 for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin(),
424 EDE = ED->enumerator_end(); EDI != EDE; ++EDI) {
425 // Get name of the enum type.
426 std::string constbuf;
427 if (const NamedDecl* END = llvm::dyn_cast<NamedDecl>(*EDI)) {
428 PrintingPolicy Policy((*EDI)->getASTContext().getPrintingPolicy());
429 llvm::raw_string_ostream stream(constbuf);
430 // Don't trigger fopen of the source file to count lines:
431 Policy.AnonymousTagLocations = false;
432 (END)->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
433 }
434 const char* constantName = constbuf.c_str();
435
436 // Get value of the constant.
438 const llvm::APSInt valAPSInt = (*EDI)->getInitVal();
439 if (valAPSInt.isSigned()) {
440 value = valAPSInt.getSExtValue();
441 } else {
442 value = valAPSInt.getZExtValue();
443 }
444
445 // Create the TEnumConstant or update it if existing
446 TEnumConstant* enumConstant = nullptr;
447 TClingClassInfo* tcCInfo = (TClingClassInfo*)(cl ? cl->GetClassInfo() : nullptr);
448 TClingDataMemberInfo* tcDmInfo = new TClingDataMemberInfo(GetInterpreterImpl(), *EDI, tcCInfo);
449 DataMemberInfo_t* dmInfo = (DataMemberInfo_t*) tcDmInfo;
450 if (TObject* encAsTObj = enumObj->GetConstants()->FindObject(constantName)){
451 ((TEnumConstant*)encAsTObj)->Update(dmInfo);
452 } else {
453 enumConstant = new TEnumConstant(dmInfo, constantName, value, enumObj);
454 }
455
456 // Add the global constants to the list of Globals.
457 if (!cl) {
458 TCollection* globals = gROOT->GetListOfGlobals(false);
459 if (!globals->FindObject(constantName)) {
460 globals->Add(enumConstant);
461 }
462 }
463 }
464 }
465}
466
467TEnum* TCling::CreateEnum(void *VD, TClass *cl) const
468{
469 // Handle new enum declaration for either global and nested enums.
470
471 // Create the enum type.
472 TEnum* enumType = nullptr;
473 const clang::Decl* D = static_cast<const clang::Decl*>(VD);
474 std::string buf;
475 if (const EnumDecl* ED = llvm::dyn_cast<EnumDecl>(D)) {
476 // Get name of the enum type.
477 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
478 llvm::raw_string_ostream stream(buf);
479 // Don't trigger fopen of the source file to count lines:
480 Policy.AnonymousTagLocations = false;
481 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
482 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
483 }
484 if (buf.empty()) {
485 return nullptr;
486 }
487 const char* name = buf.c_str();
488 enumType = new TEnum(name, VD, cl);
489 UpdateEnumConstants(enumType, cl);
490
491 return enumType;
492}
493
494void TCling::HandleNewDecl(const void* DV, bool isDeserialized, std::set<TClass*> &modifiedTClasses) {
495 // Handle new declaration.
496 // Record the modified class, struct and namespaces in 'modifiedTClasses'.
497
498 const clang::Decl* D = static_cast<const clang::Decl*>(DV);
499
500 if (!D->isCanonicalDecl() && !isa<clang::NamespaceDecl>(D)
501 && !dyn_cast<clang::RecordDecl>(D)) return;
502
503 if (isa<clang::FunctionDecl>(D->getDeclContext())
504 || isa<clang::TagDecl>(D->getDeclContext()))
505 return;
506
507 // Don't list templates.
508 if (const clang::CXXRecordDecl* RD = dyn_cast<clang::CXXRecordDecl>(D)) {
509 if (RD->getDescribedClassTemplate())
510 return;
511 } else if (const clang::FunctionDecl* FD = dyn_cast<clang::FunctionDecl>(D)) {
512 if (FD->getDescribedFunctionTemplate())
513 return;
514 }
515
516 if (const RecordDecl *TD = dyn_cast<RecordDecl>(D)) {
517 if (TD->isCanonicalDecl() || TD->isThisDeclarationADefinition())
519 }
520 else if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
521
522 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
523 // Mostly just for EnumDecl (the other TagDecl are handled
524 // by the 'RecordDecl' if statement.
526 } else if (const NamespaceDecl* NSD = dyn_cast<NamespaceDecl>(D)) {
528 }
529
530 // We care about declarations on the global scope.
531 if (!isa<TranslationUnitDecl>(ND->getDeclContext()))
532 return;
533
534 // Enums are lazyly created, thus we don not need to handle them here.
535 if (isa<EnumDecl>(ND))
536 return;
537
538 // ROOT says that global is enum(lazylycreated)/var/field declared on the global
539 // scope.
540 if (!(isa<VarDecl>(ND)))
541 return;
542
543 // Skip if already in the list.
544 if (gROOT->GetListOfGlobals()->FindObject(ND->getNameAsString().c_str()))
545 return;
546
547 // Put the global constants and global enums in the corresponding lists.
548 gROOT->GetListOfGlobals()->Add(new TGlobal((DataMemberInfo_t *)
550 cast<ValueDecl>(ND), nullptr)));
551 }
552}
553
554extern "C"
556{
557 // We are sure in this context of the type of the interpreter
558 normCtxt = &( (TCling*) gInterpreter)->GetNormalizedContext();
559}
560
561extern "C"
562void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter*) {
563 ((TCling*)gCling)->UpdateListsOnCommitted(T);
564}
565
566extern "C"
567void TCling__UpdateListsOnUnloaded(const cling::Transaction &T) {
568 ((TCling*)gCling)->UpdateListsOnUnloaded(T);
569}
570
571extern "C"
572void TCling__InvalidateGlobal(const clang::Decl *D) {
573 ((TCling*)gCling)->InvalidateGlobal(D);
574}
575
576extern "C"
577void TCling__TransactionRollback(const cling::Transaction &T) {
578 ((TCling*)gCling)->TransactionRollback(T);
579}
580
581extern "C" void TCling__LibraryLoadedRTTI(const void* dyLibHandle,
582 const char* canonicalName) {
583 ((TCling*)gCling)->LibraryLoaded(dyLibHandle, canonicalName);
584}
585
586extern "C" void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
587{
588 ((TCling *)gCling)->RegisterRdictForLoadPCM(pcmFileNameFullPath, pcmContent);
589}
590
591extern "C" void TCling__LibraryUnloadedRTTI(const void* dyLibHandle,
592 const char* canonicalName) {
593 ((TCling*)gCling)->LibraryUnloaded(dyLibHandle, canonicalName);
594}
595
596
597extern "C"
598TObject* TCling__GetObjectAddress(const char *Name, void *&LookupCtx) {
599 return ((TCling*)gCling)->GetObjectAddress(Name, LookupCtx);
600}
601
602extern "C" const Decl* TCling__GetObjectDecl(TObject *obj) {
603 return ((TClingClassInfo*)obj->IsA()->GetClassInfo())->GetDecl();
604}
605
606extern "C" R__DLLEXPORT TInterpreter *CreateInterpreter(void* interpLibHandle,
607 const char* argv[])
608{
609 auto tcling = new TCling("C++", "cling C++ Interpreter", argv, interpLibHandle);
610
611 return tcling;
612}
613
615{
616 delete interp;
617}
618
619// Load library containing specified class. Returns 0 in case of error
620// and 1 in case if success.
621extern "C" int TCling__AutoLoadCallback(const char* className)
622{
623 return ((TCling*)gCling)->AutoLoad(className);
624}
625
626extern "C" int TCling__AutoParseCallback(const char* className)
627{
628 return ((TCling*)gCling)->AutoParse(className);
629}
630
631extern "C" const char* TCling__GetClassSharedLibs(const char* className)
632{
633 return ((TCling*)gCling)->GetClassSharedLibs(className);
634}
635
636// Returns 0 for failure 1 for success
637extern "C" int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
638{
639 return ((TCling*)gCling)->IsAutoLoadNamespaceCandidate(nsDecl);
640}
641
642extern "C" int TCling__CompileMacro(const char *fileName, const char *options)
643{
644 string file(fileName);
645 string opt(options);
646 return gSystem->CompileMacro(file.c_str(), opt.c_str());
648
649extern "C" void TCling__SplitAclicMode(const char* fileName, string &mode,
650 string &args, string &io, string &fname)
651{
652 string file(fileName);
653 TString f, amode, arguments, aclicio;
654 f = gSystem->SplitAclicMode(file.c_str(), amode, arguments, aclicio);
655 mode = amode.Data(); args = arguments.Data();
656 io = aclicio.Data(); fname = f.Data();
657}
658
659//______________________________________________________________________________
660//
661//
662//
663
664#ifdef R__WIN32
665extern "C" {
666 char *__unDName(char *demangled, const char *mangled, int out_len,
667 void * (* pAlloc )(size_t), void (* pFree )(void *),
668 unsigned short int flags);
669}
670#endif
671
672////////////////////////////////////////////////////////////////////////////////
673/// Find a template decl within N nested namespaces, 0<=N<inf
674/// Assumes 1 and only 1 template present and 1 and only 1 entity contained
675/// by the namespace. Example: `ns1::ns2::..::%nsN::%myTemplate`
676/// Returns nullptr in case of error
677
678static clang::ClassTemplateDecl* FindTemplateInNamespace(clang::Decl* decl)
679{
680 using namespace clang;
681 if (NamespaceDecl* nsd = llvm::dyn_cast<NamespaceDecl>(decl)){
682 return FindTemplateInNamespace(*nsd->decls_begin());
683 }
684
685 if (ClassTemplateDecl* ctd = llvm::dyn_cast<ClassTemplateDecl>(decl)){
686 return ctd;
687 }
688
689 return nullptr; // something went wrong.
690}
691
692//______________________________________________________________________________
693//
694//
695//
696
697int TCling_GenerateDictionary(const std::vector<std::string> &classes,
698 const std::vector<std::string> &headers,
699 const std::vector<std::string> &fwdDecls,
700 const std::vector<std::string> &unknown)
701{
702 //This function automatically creates the "LinkDef.h" file for templated
703 //classes then executes CompileMacro on it.
704 //The name of the file depends on the class name, and it's not generated again
705 //if the file exist.
706 if (classes.empty()) {
707 return 0;
708 }
709 // Use the name of the first class as the main name.
710 const std::string& className = classes[0];
711 //(0) prepare file name
712 TString fileName = "AutoDict_";
713 std::string::const_iterator sIt;
714 for (sIt = className.begin(); sIt != className.end(); ++sIt) {
715 if (*sIt == '<' || *sIt == '>' ||
716 *sIt == ' ' || *sIt == '*' ||
717 *sIt == ',' || *sIt == '&' ||
718 *sIt == ':') {
719 fileName += '_';
720 }
721 else {
722 fileName += *sIt;
723 }
724 }
725 if (classes.size() > 1) {
726 Int_t chk = 0;
727 std::vector<std::string>::const_iterator it = classes.begin();
728 while ((++it) != classes.end()) {
729 for (UInt_t cursor = 0; cursor != it->length(); ++cursor) {
730 chk = chk * 3 + it->at(cursor);
731 }
732 }
733 fileName += TString::Format("_%u", chk);
734 }
735 fileName += ".cxx";
736 if (gSystem->AccessPathName(fileName) != 0) {
737 //file does not exist
738 //(1) prepare file data
739 // If STL, also request iterators' operators.
740 // vector is special: we need to check whether
741 // vector::iterator is a typedef to pointer or a
742 // class.
743 static const std::set<std::string> sSTLTypes {
744 "vector","list","forward_list","deque","map","unordered_map","multimap",
745 "unordered_multimap","set","unordered_set","multiset","unordered_multiset",
746 "queue","priority_queue","stack","iterator"};
747 std::vector<std::string>::const_iterator it;
748 std::string fileContent("");
749 for (it = headers.begin(); it != headers.end(); ++it) {
750 fileContent += "#include \"" + *it + "\"\n";
751 }
752 for (it = unknown.begin(); it != unknown.end(); ++it) {
753 TClass* cl = TClass::GetClass(it->c_str());
754 if (cl && cl->GetDeclFileName()) {
755 TString header = gSystem->BaseName(cl->GetDeclFileName());
757 TString dirbase(gSystem->BaseName(dir));
758 while (dirbase.Length() && dirbase != "."
759 && dirbase != "include" && dirbase != "inc"
760 && dirbase != "prec_stl") {
761 gSystem->PrependPathName(dirbase, header);
762 dir = gSystem->GetDirName(dir);
763 }
764 fileContent += TString("#include \"") + header + "\"\n";
765 }
766 }
767 for (it = fwdDecls.begin(); it != fwdDecls.end(); ++it) {
768 fileContent += "class " + *it + ";\n";
769 }
770 fileContent += "#ifdef __CLING__ \n";
771 fileContent += "#pragma link C++ nestedclasses;\n";
772 fileContent += "#pragma link C++ nestedtypedefs;\n";
773 for (it = classes.begin(); it != classes.end(); ++it) {
774 std::string n(*it);
775 size_t posTemplate = n.find('<');
776 std::set<std::string>::const_iterator iSTLType = sSTLTypes.end();
777 if (posTemplate != std::string::npos) {
778 n.erase(posTemplate, std::string::npos);
779 if (n.compare(0, 5, "std::") == 0) {
780 n.erase(0, 5);
781 }
782 iSTLType = sSTLTypes.find(n);
783 }
784 fileContent += "#pragma link C++ class ";
785 fileContent += *it + "+;\n" ;
786 fileContent += "#pragma link C++ class ";
787 if (iSTLType != sSTLTypes.end()) {
788 // STL class; we cannot (and don't need to) store iterators;
789 // their shadow and the compiler's version don't agree. So
790 // don't ask for the '+'
791 fileContent += *it + "::*;\n" ;
792 }
793 else {
794 // Not an STL class; we need to allow the I/O of contained
795 // classes (now that we have a dictionary for them).
796 fileContent += *it + "::*+;\n" ;
797 }
798 }
799 fileContent += "#endif\n";
800 //end(1)
801 //(2) prepare the file
802 FILE* filePointer;
803 filePointer = fopen(fileName, "w");
804 if (filePointer == nullptr) {
805 //can't open a file
806 return 1;
807 }
808 //end(2)
809 //write data into the file
810 fprintf(filePointer, "%s", fileContent.c_str());
811 fclose(filePointer);
812 }
813 //(3) checking if we can compile a macro, if not then cleaning
814 Int_t oldErrorIgnoreLevel = gErrorIgnoreLevel;
815 gErrorIgnoreLevel = kWarning; // no "Info: creating library..."
816 Int_t ret = gSystem->CompileMacro(fileName, "k");
817 gErrorIgnoreLevel = oldErrorIgnoreLevel;
818 if (ret == 0) { //can't compile a macro
819 return 2;
820 }
821 //end(3)
822 return 0;
823}
824
825int TCling_GenerateDictionary(const std::string& className,
826 const std::vector<std::string> &headers,
827 const std::vector<std::string> &fwdDecls,
828 const std::vector<std::string> &unknown)
829{
830 //This function automatically creates the "LinkDef.h" file for templated
831 //classes then executes CompileMacro on it.
832 //The name of the file depends on the class name, and it's not generated again
833 //if the file exist.
834 std::vector<std::string> classes;
835 classes.push_back(className);
836 return TCling_GenerateDictionary(classes, headers, fwdDecls, unknown);
837}
838
839//______________________________________________________________________________
840//
841//
842//
843
844// It is a "fantom" method to synchronize user keyboard input
845// and ROOT prompt line (for WIN32)
846const char* fantomline = "TRint::EndOfLineAction();";
847
848//______________________________________________________________________________
849//
850//
851//
852
853void* TCling::fgSetOfSpecials = nullptr;
854
855//______________________________________________________________________________
856//
857// llvm error handler through exceptions; see also cling/UserInterface
858//
859namespace {
860 // Handle fatal llvm errors by throwing an exception.
861 // Yes, throwing exceptions in error handlers is bad.
862 // Doing nothing is pretty terrible, too.
863 void exceptionErrorHandler(void * /*user_data*/,
864 const std::string& reason,
865 bool /*gen_crash_diag*/) {
866 throw std::runtime_error(std::string(">>> Interpreter compilation error:\n") + reason);
867 }
868}
869
870//______________________________________________________________________________
871//
872//
873//
874
875////////////////////////////////////////////////////////////////////////////////
876
877namespace{
878 // An instance of this class causes the diagnostics of clang to be suppressed
879 // during its lifetime
880 class clangDiagSuppr {
881 public:
882 clangDiagSuppr(clang::DiagnosticsEngine& diag): fDiagEngine(diag){
883 fOldDiagValue = fDiagEngine.getIgnoreAllWarnings();
884 fDiagEngine.setIgnoreAllWarnings(true);
885 }
886
887 ~clangDiagSuppr() {
888 fDiagEngine.setIgnoreAllWarnings(fOldDiagValue);
889 }
890 private:
891 clang::DiagnosticsEngine& fDiagEngine;
892 bool fOldDiagValue;
893 };
894
895}
896
897////////////////////////////////////////////////////////////////////////////////
898/// Allow calling autoparsing from TMetaUtils
900{
901 return gCling->AutoParse(cname);
902}
903
904////////////////////////////////////////////////////////////////////////////////
905/// Try hard to avoid looking up in the Cling database as this could enduce
906/// an unwanted autoparsing.
907
908bool TClingLookupHelper__ExistingTypeCheck(const std::string &tname,
909 std::string &result)
910{
911 result.clear();
912
913 unsigned long offset = 0;
914 if (strncmp(tname.c_str(), "const ", 6) == 0) {
915 offset = 6;
916 }
917 unsigned long end = tname.length();
918 while( end && (tname[end-1]=='&' || tname[end-1]=='*' || tname[end-1]==']') ) {
919 if ( tname[end-1]==']' ) {
920 --end;
921 while ( end && tname[end-1]!='[' ) --end;
922 }
923 --end;
924 }
925 std::string innerbuf;
926 const char *inner;
927 if (end != tname.length()) {
928 innerbuf = tname.substr(offset,end-offset);
929 inner = innerbuf.c_str();
930 } else {
931 inner = tname.c_str()+offset;
932 }
933
934 //if (strchr(tname.c_str(),'[')!=0) fprintf(stderr,"DEBUG: checking on %s vs %s %lu %lu\n",tname.c_str(),inner,offset,end);
935 if (gROOT->GetListOfClasses()->FindObject(inner)
936 || TClassTable::Check(inner,result) ) {
937 // This is a known class.
938 return true;
939 }
940
941 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
942 TDataType *type = (TDataType *)typeTable->THashTable::FindObject( inner );
943 if (type) {
944 // This is a raw type and an already loaded typedef.
945 const char *newname = type->GetFullTypeName();
946 if (type->GetType() == kLong64_t) {
947 newname = "Long64_t";
948 } else if (type->GetType() == kULong64_t) {
949 newname = "ULong64_t";
950 }
951 if (strcmp(inner,newname) == 0) {
952 return true;
953 }
954 if (offset) result = "const ";
955 result += newname;
956 if ( end != tname.length() ) {
957 result += tname.substr(end,tname.length()-end);
958 }
959 if (result == tname) result.clear();
960 return true;
961 }
962
963 // Check if the name is an enumerator
964 const auto lastPos = TClassEdit::GetUnqualifiedName(inner);
965 if (lastPos != inner) // Main switch: case 1 - scoped enum, case 2 global enum
966 {
967 // We have a scope
968 // All of this C gymnastic is to avoid allocations on the heap
969 const auto enName = lastPos;
970 const auto scopeNameSize = ((Long64_t)lastPos - (Long64_t)inner) / sizeof(decltype(*lastPos)) - 2;
971 char *scopeName = new char[scopeNameSize + 1];
972 strncpy(scopeName, inner, scopeNameSize);
973 scopeName[scopeNameSize] = '\0';
974 // Check if the scope is in the list of classes
975 if (auto scope = static_cast<TClass *>(gROOT->GetListOfClasses()->FindObject(scopeName))) {
976 auto enumTable = dynamic_cast<const THashList *>(scope->GetListOfEnums(false));
977 if (enumTable && enumTable->THashList::FindObject(enName)) { delete [] scopeName; return true; }
978 }
979 // It may still be in one of the loaded protoclasses
980 else if (auto scope = static_cast<TProtoClass *>(gClassTable->GetProtoNorm(scopeName))) {
981 auto listOfEnums = scope->GetListOfEnums();
982 if (listOfEnums) { // it could be null: no enumerators in the protoclass
983 auto enumTable = dynamic_cast<const THashList *>(listOfEnums);
984 if (enumTable && enumTable->THashList::FindObject(enName)) { delete [] scopeName; return true; }
985 }
986 }
987 delete [] scopeName;
988 } else
989 {
990 // We don't have any scope: this could only be a global enum
991 auto enumTable = dynamic_cast<const THashList *>(gROOT->GetListOfEnums());
992 if (enumTable && enumTable->THashList::FindObject(inner)) return true;
993 }
994
995 if (gCling->GetClassSharedLibs(inner))
996 {
997 // This is a class name.
998 return true;
999 }
1000
1001 return false;
1002}
1003
1004////////////////////////////////////////////////////////////////////////////////
1005
1007{
1008 fContent.reserve(size);
1009}
1010
1011////////////////////////////////////////////////////////////////////////////////
1012
1014{
1015 return fContent.c_str();
1016}
1017
1018////////////////////////////////////////////////////////////////////////////////
1019/// Append string to the storage if not added already.
1020
1021inline bool TCling::TUniqueString::Append(const std::string& str)
1022{
1023 bool notPresent = fLinesHashSet.emplace(fHashFunc(str)).second;
1024 if (notPresent){
1025 fContent+=str;
1026 }
1027 return notPresent;
1028}
1029
1030std::string TCling::ToString(const char* type, void* obj)
1031{
1032 return fInterpreter->toString(type, obj);
1033}
1034
1035////////////////////////////////////////////////////////////////////////////////
1036///\returns true if the module was loaded.
1037static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
1038{
1039 // When starting up ROOT, cling would load all modulemap files on the include
1040 // paths. However, in a ROOT session, it is very common to run aclic which
1041 // will invoke rootcling and possibly produce a modulemap and a module in
1042 // the current folder.
1043 //
1044 // Before failing, try loading the modulemap in the current folder and try
1045 // loading the requested module from it.
1046 std::string currentDir = gSystem->WorkingDirectory();
1047 assert(!currentDir.empty());
1049 if (gDebug > 2)
1050 ::Info("TCling::__LoadModule", "Preloading module %s. \n",
1051 ModuleName.c_str());
1052
1053 return interp.loadModule(ModuleName, /*Complain=*/true);
1054}
1055
1056////////////////////////////////////////////////////////////////////////////////
1057/// Loads the C++ modules that we require to run any ROOT program. This is just
1058/// supposed to make a C++ module from a modulemap available to the interpreter.
1059static void LoadModules(const std::vector<std::string> &modules, cling::Interpreter &interp)
1060{
1061 for (const auto &modName : modules)
1062 LoadModule(modName, interp);
1063}
1064
1065static bool IsFromRootCling() {
1066 // rootcling also uses TCling for generating the dictionary ROOT files.
1067 const static bool foundSymbol = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
1068 return foundSymbol;
1069}
1070
1071/// Checks if there is an ASTFile on disk for the given module \c M.
1072static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName = nullptr)
1073{
1074 const HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
1075
1076 std::string ModuleFileName;
1077 if (!HSOpts.PrebuiltModulePaths.empty())
1078 // Load the module from *only* in the prebuilt module path.
1079 ModuleFileName = PP.getHeaderSearchInfo().getPrebuiltModuleFileName(M->Name);
1080 if (FullFileName)
1081 *FullFileName = ModuleFileName;
1082
1083 return !ModuleFileName.empty();
1084}
1085
1086static bool HaveFullGlobalModuleIndex = false;
1087static GlobalModuleIndex *loadGlobalModuleIndex(cling::Interpreter &interp)
1088{
1089 CompilerInstance &CI = *interp.getCI();
1090 Preprocessor &PP = CI.getPreprocessor();
1091 auto ModuleManager = CI.getASTReader();
1092 assert(ModuleManager);
1093 // StringRef ModuleIndexPath = HSI.getModuleCachePath();
1094 // HeaderSearch& HSI = PP.getHeaderSearchInfo();
1095 // HSI.setModuleCachePath(TROOT::GetSharedLibDir().Data());
1096 std::string ModuleIndexPath = TROOT::GetSharedLibDir().Data();
1097 if (ModuleIndexPath.empty())
1098 return nullptr;
1099 // Get an existing global index. This loads it if not already loaded.
1100 ModuleManager->resetForReload();
1101 ModuleManager->loadGlobalIndex();
1102 GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex();
1103
1104 // For finding modules needing to be imported for fixit messages,
1105 // we need to make the global index cover all modules, so we do that here.
1106 if (!GlobalIndex && !HaveFullGlobalModuleIndex) {
1107 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1108 bool RecreateIndex = false;
1109 for (ModuleMap::module_iterator I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1110 Module *TheModule = I->second;
1111 // We want the index only of the prebuilt modules.
1112 if (!HasASTFileOnDisk(TheModule, PP))
1113 continue;
1114 LoadModule(TheModule->Name, interp);
1115 RecreateIndex = true;
1116 }
1117 if (RecreateIndex) {
1118 cling::Interpreter::PushTransactionRAII deserRAII(&interp);
1119 clang::GlobalModuleIndex::UserDefinedInterestingIDs IDs;
1120
1121 struct DefinitionFinder : public RecursiveASTVisitor<DefinitionFinder> {
1122 DefinitionFinder(clang::GlobalModuleIndex::UserDefinedInterestingIDs& IDs,
1123 clang::TranslationUnitDecl* TU) : DefinitionIDs(IDs) {
1124 TraverseDecl(TU);
1125 }
1126 bool VisitNamedDecl(NamedDecl *ND) {
1127 if (!ND->isFromASTFile())
1128 return true;
1129 if (!ND->getIdentifier())
1130 return true;
1131
1132 if (ND->getAccess() == AS_protected || ND->getAccess() == AS_private)
1133 return true;
1134
1135 if (TagDecl *TD = llvm::dyn_cast<TagDecl>(ND)) {
1136 if (TD->isCompleteDefinition())
1137 Register(TD);
1138 } else if (NamespaceDecl *NSD = llvm::dyn_cast<NamespaceDecl>(ND)) {
1139 Register(NSD, /*AddSingleEntry=*/ false);
1140 }
1141 else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(ND))
1142 Register(TND);
1143 // FIXME: Add the rest...
1144 return true; // continue decending
1145 }
1146 private:
1147 clang::GlobalModuleIndex::UserDefinedInterestingIDs &DefinitionIDs;
1148 void Register(const NamedDecl* ND, bool AddSingleEntry = true) {
1149 assert(ND->isFromASTFile());
1150 // FIXME: All decls should have an owning module once rootcling
1151 // updates its generated decls from within the LookupHelper & co.
1152 if (!ND->hasOwningModule()) {
1153#ifndef NDEBUG
1154 SourceManager &SM = ND->getASTContext().getSourceManager();
1155 SourceLocation Loc = ND->getLocation();
1156 const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Loc));
1157 (void)FE;
1158 assert(FE->getName().contains("input_line_"));
1159#endif
1160 return;
1161 }
1162
1163 Module *OwningModule = ND->getOwningModule()->getTopLevelModule();
1164 assert(OwningModule);
1165 assert(!ND->getName().empty() && "Empty name");
1166 if (AddSingleEntry && DefinitionIDs.count(ND->getName()))
1167 return;
1168 // FIXME: The FileEntry in not stable to serialize.
1169 // FIXME: We might end up with many times with the same module.
1170 // FIXME: We might end up two modules containing a definition.
1171 // FIXME: What do we do if no definition is found.
1172 DefinitionIDs[ND->getName()].push_back(OwningModule->getASTFile());
1173 }
1174 };
1175 DefinitionFinder defFinder(IDs, CI.getASTContext().getTranslationUnitDecl());
1176
1177 llvm::cantFail(GlobalModuleIndex::writeIndex(CI.getFileManager(),
1178 CI.getPCHContainerReader(),
1179 ModuleIndexPath,
1180 &IDs));
1181 ModuleManager->resetForReload();
1182 ModuleManager->loadGlobalIndex();
1183 GlobalIndex = ModuleManager->getGlobalIndex();
1184 }
1186 }
1187 return GlobalIndex;
1188}
1189
1190static void RegisterCxxModules(cling::Interpreter &clingInterp)
1191{
1192 if (!clingInterp.getCI()->getLangOpts().Modules)
1193 return;
1194
1195 // Loading of a module might deserialize.
1196 cling::Interpreter::PushTransactionRAII deserRAII(&clingInterp);
1197
1198 // Setup core C++ modules if we have any to setup.
1199
1200 // Load libc and stl first.
1201 // Load vcruntime module for windows
1202#ifdef R__WIN32
1203 LoadModule("vcruntime", clingInterp);
1204 LoadModule("services", clingInterp);
1205#endif
1206
1207#ifdef R__MACOSX
1208 LoadModule("Darwin", clingInterp);
1209#else
1210 LoadModule("libc", clingInterp);
1211#endif
1212 LoadModule("std", clingInterp);
1213
1214 LoadModule("_Builtin_intrinsics", clingInterp);
1215
1216 // Load core modules
1217 // This should be vector in order to be able to pass it to LoadModules
1218 std::vector<std::string> CoreModules = {"ROOT_Foundation_C",
1219 "ROOT_Config",
1220 "ROOT_Rtypes",
1221 "ROOT_Foundation_Stage1_NoRTTI",
1222 "Core",
1223 "Rint",
1224 "RIO"};
1225
1226 LoadModules(CoreModules, clingInterp);
1227
1228 // Take this branch only from ROOT because we don't need to preload modules in rootcling
1229 if (!IsFromRootCling()) {
1230 std::vector<std::string> CommonModules = {"MathCore"};
1231 LoadModules(CommonModules, clingInterp);
1232
1233 // These modules should not be preloaded but they fix issues.
1234 // FIXME: Hist is not a core module but is very entangled to MathCore and
1235 // causes issues.
1236 std::vector<std::string> FIXMEModules = {"Hist"};
1237 clang::CompilerInstance &CI = *clingInterp.getCI();
1238 clang::Preprocessor &PP = CI.getPreprocessor();
1239 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1240 if (MMap.findModule("RInterface"))
1241 FIXMEModules.push_back("RInterface");
1242
1243 LoadModules(FIXMEModules, clingInterp);
1244
1245 GlobalModuleIndex *GlobalIndex = nullptr;
1246 loadGlobalModuleIndex(clingInterp);
1247 // FIXME: The ASTReader still calls loadGlobalIndex and loads the file
1248 // We should investigate how to suppress it completely.
1249 GlobalIndex = CI.getASTReader()->getGlobalIndex();
1250
1251 llvm::StringSet<> KnownModuleFileNames;
1252 if (GlobalIndex)
1253 GlobalIndex->getKnownModuleFileNames(KnownModuleFileNames);
1254
1255 std::vector<std::string> PendingModules;
1256 PendingModules.reserve(256);
1257 for (auto I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1258 clang::Module *M = I->second;
1259 assert(M);
1260
1261 // We want to load only already created modules.
1262 std::string FullASTFilePath;
1263 if (!HasASTFileOnDisk(M, PP, &FullASTFilePath))
1264 continue;
1265
1266 if (GlobalIndex && KnownModuleFileNames.count(FullASTFilePath))
1267 continue;
1268
1269 if (M->IsUnimportable)
1270 continue;
1271
1272 if (GlobalIndex)
1273 LoadModule(M->Name, clingInterp);
1274 else {
1275 // FIXME: We may be able to remove those checks as cling::loadModule
1276 // checks if a module was alredy loaded.
1277 if (std::find(CoreModules.begin(), CoreModules.end(), M->Name) != CoreModules.end())
1278 continue; // This is a core module which was already loaded.
1279
1280 // Load system modules now and delay the other modules after we have
1281 // loaded all system ones.
1282 if (M->IsSystem)
1283 LoadModule(M->Name, clingInterp);
1284 else
1285 PendingModules.push_back(M->Name);
1286 }
1287 }
1288 LoadModules(PendingModules, clingInterp);
1289 }
1290
1291 // Check that the gROOT macro was exported by any core module.
1292 assert(clingInterp.getMacro("gROOT") && "Couldn't load gROOT macro?");
1293
1294 // `ERROR` and `PI` are from loading R related modules, which conflict with
1295 // user's code.
1296 clingInterp.declare(R"CODE(
1297#ifdef PI
1298# undef PI
1299#endif
1300#ifdef ERROR
1301# undef ERROR
1302#endif
1303 )CODE");
1304}
1305
1306static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
1307{
1308 std::string PreIncludes;
1309 bool hasCxxModules = clingInterp.getCI()->getLangOpts().Modules;
1310
1311 // For the list to also include string, we have to include it now.
1312 // rootcling does parts already if needed, e.g. genreflex does not want using
1313 // namespace std.
1314 if (IsFromRootCling()) {
1315 PreIncludes += "#include \"RtypesCore.h\"\n";
1316 } else {
1317 if (!hasCxxModules)
1318 PreIncludes += "#include \"Rtypes.h\"\n";
1319
1320 PreIncludes += gClassDefInterpMacro + "\n"
1321 + gInterpreterClassDef + "\n"
1322 "#undef ClassImp\n"
1323 "#define ClassImp(X);\n";
1324 }
1325 if (!hasCxxModules)
1326 PreIncludes += "#include <string>\n";
1327
1328 // We must include it even when we have modules because it is marked as
1329 // textual in the modulemap due to the nature of the assert header.
1330#ifndef R__WIN32
1331 PreIncludes += "#include <cassert>\n";
1332#endif
1333 PreIncludes += "using namespace std;\n";
1334 clingInterp.declare(PreIncludes);
1335}
1336
1337////////////////////////////////////////////////////////////////////////////////
1338/// Initialize the cling interpreter interface.
1339/// \param name name for TInterpreter
1340/// \param title title for TInterpreter
1341/// \param argv - array of arguments passed to the cling::Interpreter constructor
1342/// e.g. `-DFOO=bar`. The last element of the array must be `nullptr`.
1343
1344TCling::TCling(const char *name, const char *title, const char* const argv[], void *interpLibHandle)
1345: TInterpreter(name, title), fGlobalsListSerial(-1), fMapfile(nullptr),
1346 fRootmapFiles(nullptr), fLockProcessLine(true), fNormalizedCtxt(nullptr),
1347 fPrevLoadedDynLibInfo(nullptr), fClingCallbacks(nullptr), fAutoLoadCallBack(nullptr),
1349{
1350 fPrompt[0] = 0;
1351 const bool fromRootCling = IsFromRootCling();
1352
1353 fCxxModulesEnabled = false;
1354#ifdef R__USE_CXXMODULES
1355 fCxxModulesEnabled = true;
1356#endif
1357
1358 llvm::install_fatal_error_handler(&exceptionErrorHandler);
1359
1360 fTemporaries = new std::vector<cling::Value>();
1361
1362 std::vector<std::string> clingArgsStorage;
1363 clingArgsStorage.push_back("cling4root");
1364 for (const char* const* arg = argv; *arg; ++arg)
1365 clingArgsStorage.push_back(*arg);
1366
1367 // rootcling sets its arguments through TROOT::GetExtraInterpreterArgs().
1368 if (!fromRootCling) {
1370
1371 // Add -I early so ASTReader can find the headers.
1372 std::string interpInclude(TROOT::GetEtcDir().Data());
1373 clingArgsStorage.push_back("-I" + interpInclude);
1374
1375 // Add include path to etc/cling.
1376 clingArgsStorage.push_back("-I" + interpInclude + "/cling");
1377
1378 // Add include path to etc/cling.
1379 clingArgsStorage.push_back("-I" + interpInclude + "/cling/plugins/include");
1380
1381 // Add the root include directory and etc/ to list searched by default.
1382 clingArgsStorage.push_back(std::string(("-I" + TROOT::GetIncludeDir()).Data()));
1383
1384 // Add the current path to the include path
1385 // TCling::AddIncludePath(".");
1386
1387 // Attach the PCH (unless we have C++ modules enabled which provide the
1388 // same functionality).
1389 if (!fCxxModulesEnabled) {
1390 std::string pchFilename = interpInclude + "/allDict.cxx.pch";
1391 if (gSystem->Getenv("ROOT_PCH")) {
1392 pchFilename = gSystem->Getenv("ROOT_PCH");
1393 }
1394
1395 clingArgsStorage.push_back("-include-pch");
1396 clingArgsStorage.push_back(pchFilename);
1397 }
1398
1399 clingArgsStorage.push_back("-Wno-undefined-inline");
1400 clingArgsStorage.push_back("-fsigned-char");
1401 // The -O1 optimization flag has nasty side effects on Windows (32 bit)
1402 // See the GitHub issues #9809 and #9944
1403#if !defined(_MSC_VER) || defined(_WIN64)
1404 clingArgsStorage.push_back("-O1");
1405 // Disable optimized register allocation which is turned on automatically
1406 // by -O1, but seems to require -O2 to not explode in run time.
1407 clingArgsStorage.push_back("-mllvm");
1408 clingArgsStorage.push_back("-optimize-regalloc=0");
1409#endif
1410 }
1411
1412 // Process externally passed arguments if present.
1413 llvm::Optional<std::string> EnvOpt = llvm::sys::Process::GetEnv("EXTRA_CLING_ARGS");
1414 if (EnvOpt.hasValue()) {
1415 StringRef Env(*EnvOpt);
1416 while (!Env.empty()) {
1417 StringRef Arg;
1418 std::tie(Arg, Env) = Env.split(' ');
1419 clingArgsStorage.push_back(Arg.str());
1420 }
1421 }
1422
1423 auto GetEnvVarPath = [](const std::string &EnvVar,
1424 std::vector<std::string> &Paths) {
1425 llvm::Optional<std::string> EnvOpt = llvm::sys::Process::GetEnv(EnvVar);
1426 if (EnvOpt.hasValue()) {
1427 StringRef Env(*EnvOpt);
1428 while (!Env.empty()) {
1429 StringRef Arg;
1430 std::tie(Arg, Env) = Env.split(ROOT::FoundationUtils::GetEnvPathSeparator());
1431 if (std::find(Paths.begin(), Paths.end(), Arg.str()) == Paths.end())
1432 Paths.push_back(Arg.str());
1433 }
1434 }
1435 };
1436
1437 if (fCxxModulesEnabled) {
1438 std::vector<std::string> Paths;
1439 // ROOT usually knows better where its libraries are. This way we can
1440 // discover modules without having to should thisroot.sh and should fix
1441 // gnuinstall.
1442 Paths.push_back(TROOT::GetSharedLibDir().Data());
1443 GetEnvVarPath("CLING_PREBUILT_MODULE_PATH", Paths);
1444 std::string EnvVarPath;
1445 for (const std::string& P : Paths)
1447 // FIXME: We should make cling -fprebuilt-module-path work.
1448 gSystem->Setenv("CLING_PREBUILT_MODULE_PATH", EnvVarPath.c_str());
1449 }
1450
1451 // FIXME: This only will enable frontend timing reports.
1452 EnvOpt = llvm::sys::Process::GetEnv("ROOT_CLING_TIMING");
1453 if (EnvOpt.hasValue())
1454 clingArgsStorage.push_back("-ftime-report");
1455
1456 // Add the overlay file. Note that we cannot factor it out for both root
1457 // and rootcling because rootcling activates modules only if -cxxmodule
1458 // flag is passed.
1459 if (fCxxModulesEnabled && !fromRootCling) {
1460 // For now we prefer rootcling to enumerate explicitly its modulemaps.
1461 std::vector<std::string> ModuleMaps;
1462 std::string ModuleMapSuffix = ROOT::FoundationUtils::GetPathSeparator() + "ROOT.modulemap";
1463 ModuleMaps.push_back(TROOT::GetIncludeDir().Data() + ModuleMapSuffix);
1464 GetEnvVarPath("CLING_MODULEMAP_FILES", ModuleMaps);
1465
1466 std::string cwd = gSystem->WorkingDirectory();
1467 // Give highest precedence of the modulemap in the cwd if any.
1468 if (llvm::sys::fs::exists(cwd + ModuleMapSuffix))
1469 ModuleMaps.push_back(cwd + ModuleMapSuffix);
1470
1471 for (const std::string& M : ModuleMaps)
1472 clingArgsStorage.push_back("-fmodule-map-file=" + M);
1473
1474 std::string ModulesCachePath;
1475 EnvOpt = llvm::sys::Process::GetEnv("CLING_MODULES_CACHE_PATH");
1476 if (EnvOpt.hasValue()){
1477 StringRef Env(*EnvOpt);
1478 assert(llvm::sys::fs::exists(Env) && "Path does not exist!");
1479 ModulesCachePath = Env.str();
1480 } else {
1481 ModulesCachePath = TROOT::GetSharedLibDir();
1482 }
1483
1484 clingArgsStorage.push_back("-fmodules-cache-path=" + ModulesCachePath);
1485 }
1486
1487 std::vector<const char*> interpArgs;
1488 for (std::vector<std::string>::const_iterator iArg = clingArgsStorage.begin(),
1489 eArg = clingArgsStorage.end(); iArg != eArg; ++iArg)
1490 interpArgs.push_back(iArg->c_str());
1491
1492 // Activate C++ modules support. If we are running within rootcling, it's up
1493 // to rootcling to set this flag depending on whether it wants to produce
1494 // C++ modules.
1495 TString vfsArg;
1496 if (fCxxModulesEnabled) {
1497 if (!fromRootCling) {
1498 // We only set this flag, rest is done by the CIFactory.
1499 interpArgs.push_back("-fmodules");
1500 interpArgs.push_back("-fno-implicit-module-maps");
1501 // We should never build modules during runtime, so let's enable the
1502 // module build remarks from clang to make it easier to spot when we do
1503 // this by accident.
1504 interpArgs.push_back("-Rmodule-build");
1505 }
1506 // ROOT implements its AutoLoading upon module's link directives. We
1507 // generate module A { header "A.h" link "A.so" export * } where ROOT's
1508 // facilities use the link directive to dynamically load the relevant
1509 // library. So, we need to suppress clang's default autolink behavior.
1510 interpArgs.push_back("-fno-autolink");
1511 }
1512
1513#ifdef R__FAST_MATH
1514 // Same setting as in rootcling_impl.cxx.
1515 interpArgs.push_back("-ffast-math");
1516#endif
1517
1518 TString llvmResourceDir = TROOT::GetEtcDir() + "/cling";
1519 // Add statically injected extra arguments, usually coming from rootcling.
1520 for (const char** extraArgs = TROOT::GetExtraInterpreterArgs();
1521 extraArgs && *extraArgs; ++extraArgs) {
1522 if (!strcmp(*extraArgs, "-resource-dir")) {
1523 // Take the next arg as the llvm resource directory.
1524 llvmResourceDir = *(++extraArgs);
1525 } else {
1526 interpArgs.push_back(*extraArgs);
1527 }
1528 }
1529
1530 std::vector<std::string> _empty;
1531 auto args = TROOT::AddExtraInterpreterArgs(_empty);
1532 for (const auto &arg: args)
1533 interpArgs.emplace_back(arg.c_str());
1534
1535 // Add the Rdict module file extension.
1536 cling::Interpreter::ModuleFileExtensions extensions;
1537 EnvOpt = llvm::sys::Process::GetEnv("ROOTDEBUG_RDICT");
1538 if (!EnvOpt.hasValue())
1539 extensions.push_back(std::make_shared<TClingRdictModuleFileExtension>());
1540
1541 fInterpreter = std::make_unique<cling::Interpreter>(interpArgs.size(),
1542 &(interpArgs[0]),
1543 llvmResourceDir, extensions,
1544 interpLibHandle);
1545
1546 // Don't check whether modules' files exist.
1547 fInterpreter->getCI()->getPreprocessorOpts().DisablePCHOrModuleValidation =
1548 DisableValidationForModuleKind::All;
1549
1550 // Until we can disable AutoLoading during Sema::CorrectTypo() we have
1551 // to disable spell checking.
1552 fInterpreter->getCI()->getLangOpts().SpellChecking = false;
1553
1554 // Sync modules on/off between clang and us: clang turns it on for C++ >= 20.
1555 auto isModulesArg = [](const char* arg) { return !strcmp(arg, "-fmodules"); };
1556 bool hasModulesArg = std::find_if(interpArgs.begin(), interpArgs.end(), isModulesArg) != interpArgs.end();
1557 fInterpreter->getCI()->getLangOpts().Modules = hasModulesArg;
1558
1559 // We need stream that doesn't close its file descriptor, thus we are not
1560 // using llvm::outs. Keeping file descriptor open we will be able to use
1561 // the results in pipes (Savannah #99234).
1562 static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO, /*ShouldClose*/false);
1563 fMetaProcessor = std::make_unique<cling::MetaProcessor>(*fInterpreter, fMPOuts);
1564
1567
1568 // We are now ready (enough is loaded) to init the list of opaque typedefs.
1575
1576 // Disallow auto-parsing in rootcling
1577 fIsAutoParsingSuspended = fromRootCling;
1578
1579 ResetAll();
1580
1581 // Enable dynamic lookup
1582 if (!fromRootCling) {
1583 fInterpreter->enableDynamicLookup();
1584 }
1585
1586 // Enable ClinG's DefinitionShadower for ROOT.
1587 fInterpreter->getRuntimeOptions().AllowRedefinition = 1;
1588 auto &Policy = const_cast<clang::PrintingPolicy &>(fInterpreter->getCI()->getASTContext().getPrintingPolicy());
1589 // Print 'a<b<c> >' rather than 'a<b<c>>'.
1590 // FIXME: We should probably switch to the default printing policy setting
1591 // after adjusting tons of reference files.
1592 Policy.SplitTemplateClosers = true;
1593 // Keep default templare arguments, required for dictionary generation.
1594 Policy.SuppressDefaultTemplateArgs = false;
1595
1596
1597 // Attach cling callbacks last; they might need TROOT::fInterpreter
1598 // and should thus not be triggered during the equivalent of
1599 // TROOT::fInterpreter = new TCling;
1600 std::unique_ptr<TClingCallbacks>
1601 clingCallbacks(new TClingCallbacks(GetInterpreterImpl(), /*hasCodeGen*/ !fromRootCling));
1602 fClingCallbacks = clingCallbacks.get();
1604 fInterpreter->setCallbacks(std::move(clingCallbacks));
1605
1606 if (!fromRootCling) {
1607 cling::DynamicLibraryManager& DLM = *fInterpreter->getDynamicLibraryManager();
1608 // Make sure cling looks into ROOT's libdir, even if not part of LD_LIBRARY_PATH
1609 // e.g. because of an RPATH build.
1610 DLM.addSearchPath(TROOT::GetSharedLibDir().Data(), /*isUser=*/true,
1611 /*prepend=*/true);
1612 auto ShouldPermanentlyIgnore = [](llvm::StringRef FileName) -> bool{
1613 llvm::StringRef stem = llvm::sys::path::stem(FileName);
1614 return stem.startswith("libNew") || stem.startswith("libcppyy_backend");
1615 };
1616 // Initialize the dyld for AutoloadLibraryGenerator.
1617 DLM.initializeDyld(ShouldPermanentlyIgnore);
1618 }
1619}
1620
1621
1622////////////////////////////////////////////////////////////////////////////////
1623/// Destroy the interpreter interface.
1624
1626{
1627 // ROOT's atexit functions require the interepreter to be available.
1628 // Run them before shutting down.
1629 if (!IsFromRootCling())
1630 GetInterpreterImpl()->runAtExitFuncs();
1631 fIsShuttingDown = true;
1632 delete fMapfile;
1633 delete fRootmapFiles;
1634 delete fTemporaries;
1635 delete fNormalizedCtxt;
1636 delete fLookupHelper;
1637 gCling = nullptr;
1638}
1639
1640////////////////////////////////////////////////////////////////////////////////
1641/// Initialize the interpreter, once TROOT::fInterpreter is set.
1642
1644{
1646
1647 // We are set up. Enable ROOT's AutoLoading.
1648 if (IsFromRootCling())
1649 return;
1650
1651 // Read the rules before enabling the auto loading to not inadvertently
1652 // load the libraries for the classes concerned even-though the user is
1653 // *not* using them.
1654 // Note this call must happen before the first call to LoadLibraryMap.
1655 assert(GetRootMapFiles() == nullptr && "Must be called before LoadLibraryMap!");
1656 TClass::ReadRules(); // Read the default customization rules ...
1657
1659 SetClassAutoLoading(true);
1660}
1661
1663{
1664 fIsShuttingDown = true;
1665 ResetGlobals();
1666}
1667
1668////////////////////////////////////////////////////////////////////////////////
1669/// Helper to initialize TVirtualStreamerInfo's factor early.
1670/// Use static initialization to insure only one TStreamerInfo is created.
1672{
1673 // Use lambda since SetFactory return void.
1674 auto setFactory = []() {
1676 return kTRUE;
1677 };
1678 static bool doneFactory = setFactory();
1679 return doneFactory; // avoid unused variable warning.
1680}
1681
1682////////////////////////////////////////////////////////////////////////////////
1683/// Register Rdict data for future loading by LoadPCM;
1684
1685void TCling::RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
1686{
1687 if (IsFromRootCling())
1688 return;
1689
1690 if (llvm::sys::fs::exists(pcmFileNameFullPath)) {
1691 ::Error("TCling::RegisterRdictForLoadPCM", "Rdict '%s' is both in Module extension and in File system.", pcmFileNameFullPath.c_str());
1692 return;
1693 }
1694
1695 // The pcmFileNameFullPath must be resolved already because we cannot resolve
1696 // a link to a non-existent file.
1697 fPendingRdicts[pcmFileNameFullPath] = *pcmContent;
1698}
1699
1700////////////////////////////////////////////////////////////////////////////////
1701/// Tries to load a PCM from TFile; returns true on success.
1702
1704{
1705 auto listOfKeys = pcmFile.GetListOfKeys();
1706
1707 // This is an empty pcm
1708 if (listOfKeys && ((listOfKeys->GetSize() == 0) || // Nothing here, or
1709 ((listOfKeys->GetSize() == 1) && // only one, and
1710 !strcmp(((TKey *)listOfKeys->At(0))->GetName(), "EMPTY") // name is EMPTY
1711 ))) {
1712 return;
1713 }
1714
1715 TObjArray *protoClasses;
1716 if (gDebug > 1)
1717 ::Info("TCling::LoadPCMImpl", "reading protoclasses for %s \n", pcmFile.GetName());
1718
1719 TObjArray *enums;
1720 pcmFile.GetObject("__Enums", enums);
1721 if (enums) {
1722 // Cache the pointers
1723 auto listOfGlobals = gROOT->GetListOfGlobals();
1724 auto listOfEnums = dynamic_cast<THashList *>(gROOT->GetListOfEnums());
1725 // Loop on enums and then on enum constants
1726 for (auto selEnum : *enums) {
1727 const char *enumScope = selEnum->GetTitle();
1728 const char *enumName = selEnum->GetName();
1729 if (strcmp(enumScope, "") == 0) {
1730 // This is a global enum and is added to the
1731 // list of enums and its constants to the list of globals
1732 if (!listOfEnums->THashList::FindObject(enumName)) {
1733 ((TEnum *)selEnum)->SetClass(nullptr);
1734 listOfEnums->Add(selEnum);
1735 }
1736 for (auto enumConstant : *static_cast<TEnum *>(selEnum)->GetConstants()) {
1737 if (!listOfGlobals->FindObject(enumConstant)) {
1738 listOfGlobals->Add(enumConstant);
1739 }
1740 }
1741 } else {
1742 // This enum is in a namespace. A TClass entry is bootstrapped if
1743 // none exists yet and the enum is added to it
1744 TClass *nsTClassEntry = TClass::GetClass(enumScope);
1745 if (!nsTClassEntry) {
1746 nsTClassEntry = new TClass(enumScope, 0, TClass::kNamespaceForMeta, true);
1747 }
1748 auto listOfEnums = nsTClassEntry->fEnums.load();
1749 if (!listOfEnums) {
1750 if ((kIsClass | kIsStruct | kIsUnion) & nsTClassEntry->Property()) {
1751 // For this case, the list will be immutable once constructed
1752 // (i.e. in this case, by the end of this routine).
1753 listOfEnums = nsTClassEntry->fEnums = new TListOfEnums(nsTClassEntry);
1754 } else {
1755 // namespaces can have enums added to them
1756 listOfEnums = nsTClassEntry->fEnums = new TListOfEnumsWithLock(nsTClassEntry);
1757 }
1758 }
1759 if (listOfEnums && !listOfEnums->THashList::FindObject(enumName)) {
1760 ((TEnum *)selEnum)->SetClass(nsTClassEntry);
1761 listOfEnums->Add(selEnum);
1762 }
1763 }
1764 }
1765 enums->Clear();
1766 delete enums;
1767 }
1768
1769 pcmFile.GetObject("__ProtoClasses", protoClasses);
1770
1771 if (protoClasses) {
1772 for (auto obj : *protoClasses) {
1773 TProtoClass *proto = (TProtoClass *)obj;
1775 }
1776 // Now that all TClass-es know how to set them up we can update
1777 // existing TClasses, which might cause the creation of e.g. TBaseClass
1778 // objects which in turn requires the creation of TClasses, that could
1779 // come from the PCH, but maybe later in the loop. Instead of resolving
1780 // a dependency graph the addition to the TClassTable above allows us
1781 // to create these dependent TClasses as needed below.
1782 for (auto proto : *protoClasses) {
1783 if (TClass *existingCl = (TClass *)gROOT->GetListOfClasses()->FindObject(proto->GetName())) {
1784 // We have an existing TClass object. It might be emulated
1785 // or interpreted; we now have more information available.
1786 // Make that available.
1787 if (existingCl->GetState() != TClass::kHasTClassInit) {
1788 DictFuncPtr_t dict = gClassTable->GetDict(proto->GetName());
1789 if (!dict) {
1790 ::Error("TCling::LoadPCM", "Inconsistent TClassTable for %s", proto->GetName());
1791 } else {
1792 // This will replace the existing TClass.
1793 TClass *ncl = (*dict)();
1794 if (ncl)
1795 ncl->PostLoadCheck();
1796 }
1797 }
1798 }
1799 }
1800
1801 protoClasses->Clear(); // Ownership was transfered to TClassTable.
1802 delete protoClasses;
1803 }
1804
1805 TObjArray *dataTypes;
1806 pcmFile.GetObject("__Typedefs", dataTypes);
1807 if (dataTypes) {
1808 for (auto typedf : *dataTypes)
1809 gROOT->GetListOfTypes()->Add(typedf);
1810 dataTypes->Clear(); // Ownership was transfered to TListOfTypes.
1811 delete dataTypes;
1812 }
1813}
1814
1815////////////////////////////////////////////////////////////////////////////////
1816/// Tries to load a rdict PCM, issues diagnostics if it fails.
1817
1818void TCling::LoadPCM(std::string pcmFileNameFullPath)
1819{
1820 SuspendAutoLoadingRAII autoloadOff(this);
1821 SuspendAutoParsing autoparseOff(this);
1822 assert(!pcmFileNameFullPath.empty());
1823 assert(llvm::sys::path::is_absolute(pcmFileNameFullPath));
1824
1825 // Easier to work with the ROOT interfaces.
1826 TString pcmFileName = pcmFileNameFullPath;
1827
1828 // Prevent the ROOT-PCMs hitting this during auto-load during
1829 // JITting - which will cause recursive compilation.
1830 // Avoid to call the plugin manager at all.
1832
1834 llvm::SaveAndRestore<Int_t> SaveGDebug(gDebug);
1835 if (gDebug > 5) {
1836 gDebug -= 5;
1837 ::Info("TCling::LoadPCM", "Loading ROOT PCM %s", pcmFileName.Data());
1838 } else {
1839 gDebug = 0;
1840 }
1841
1842 if (llvm::sys::fs::is_symlink_file(pcmFileNameFullPath))
1843 pcmFileNameFullPath = ROOT::TMetaUtils::GetRealPath(pcmFileNameFullPath);
1844
1845 auto pendingRdict = fPendingRdicts.find(pcmFileNameFullPath);
1846 if (pendingRdict != fPendingRdicts.end()) {
1847 llvm::StringRef pcmContent = pendingRdict->second;
1848 TMemFile::ZeroCopyView_t range{pcmContent.data(), pcmContent.size()};
1849 std::string RDictFileOpts = pcmFileNameFullPath + "?filetype=pcm";
1850 TMemFile pcmMemFile(RDictFileOpts.c_str(), range);
1851
1852 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
1853 LoadPCMImpl(pcmMemFile);
1854 // Currently the module file are never unloaded (even if the library is
1855 // unloaded) and, of course, never reloaded.
1856 // Consequently, we must NOT remove the `pendingRdict` from the list
1857 // of pending dictionary, otherwise if a library is unloaded and then
1858 // reload we will be unable to update properly the TClass object
1859 // (because we wont be able to load the rootpcm file by executing the
1860 // above lines)
1861
1862 return;
1863 }
1864
1865 if (!llvm::sys::fs::exists(pcmFileNameFullPath)) {
1866 ::Error("TCling::LoadPCM", "ROOT PCM %s file does not exist",
1867 pcmFileNameFullPath.data());
1868 if (!fPendingRdicts.empty())
1869 for (const auto &rdict : fPendingRdicts)
1870 ::Info("TCling::LoadPCM", "In-memory ROOT PCM candidate %s\n",
1871 rdict.first.c_str());
1872 return;
1873 }
1874
1875 if (!gROOT->IsRootFile(pcmFileName)) {
1876 Fatal("LoadPCM", "The file %s is not a ROOT as was expected\n", pcmFileName.Data());
1877 return;
1878 }
1879 TFile pcmFile(pcmFileName + "?filetype=pcm", "READ");
1880 LoadPCMImpl(pcmFile);
1881}
1882
1883//______________________________________________________________________________
1884
1885namespace {
1886 using namespace clang;
1887
1888 class ExtLexicalStorageAdder: public RecursiveASTVisitor<ExtLexicalStorageAdder>{
1889 // This class is to be considered an helper for autoparsing.
1890 // It visits the AST and marks all classes (in all of their redeclarations)
1891 // with the setHasExternalLexicalStorage method.
1892 public:
1893 bool VisitRecordDecl(clang::RecordDecl* rcd){
1894 if (gDebug > 2)
1895 Info("ExtLexicalStorageAdder",
1896 "Adding external lexical storage to class %s",
1897 rcd->getNameAsString().c_str());
1898 auto reDeclPtr = rcd->getMostRecentDecl();
1899 do {
1900 reDeclPtr->setHasExternalLexicalStorage();
1901 } while ((reDeclPtr = reDeclPtr->getPreviousDecl()));
1902
1903 return false;
1904 }
1905 };
1906
1907
1908}
1909
1910////////////////////////////////////////////////////////////////////////////////
1911///\returns true if the module map was loaded, false on error or if the map was
1912/// already loaded.
1913bool TCling::RegisterPrebuiltModulePath(const std::string &FullPath,
1914 const std::string &ModuleMapName /*= "module.modulemap"*/) const
1915{
1916 assert(llvm::sys::path::is_absolute(FullPath));
1917 Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
1918 FileManager &FM = PP.getFileManager();
1919 // FIXME: In a ROOT session we can add an include path (through .I /inc/path)
1920 // We should look for modulemap files there too.
1921 if (auto DE = FM.getOptionalDirectoryRef(FullPath)) {
1922 HeaderSearch &HS = PP.getHeaderSearchInfo();
1923 HeaderSearchOptions &HSOpts = HS.getHeaderSearchOpts();
1924 const auto &ModPaths = HSOpts.PrebuiltModulePaths;
1925 bool pathExists = std::find(ModPaths.begin(), ModPaths.end(), FullPath) != ModPaths.end();
1926 if (!pathExists)
1927 HSOpts.AddPrebuiltModulePath(FullPath);
1928 // We cannot use HS.lookupModuleMapFile(DE, /*IsFramework*/ false);
1929 // because its internal call to getFile has CacheFailure set to true.
1930 // In our case, modulemaps can appear any time due to ACLiC.
1931 // Code copied from HS.lookupModuleMapFile.
1932 llvm::SmallString<256> ModuleMapFileName(DE->getName());
1933 llvm::sys::path::append(ModuleMapFileName, ModuleMapName);
1934 if (auto FE = FM.getOptionalFileRef(ModuleMapFileName, /*openFile*/ false,
1935 /*CacheFailure*/ false)) {
1936 if (!HS.loadModuleMapFile(*FE, /*IsSystem*/ false))
1937 return true;
1938 Error("RegisterPrebuiltModulePath", "Could not load modulemap in %s", ModuleMapFileName.c_str());
1939 }
1940 }
1941 return false;
1942}
1943
1944////////////////////////////////////////////////////////////////////////////////
1945/// List of dicts that have the PCM information already in the PCH.
1946static const std::unordered_set<std::string> gIgnoredPCMNames = {"libCore",
1947 "libRint",
1948 "libThread",
1949 "libRIO",
1950 "libImt",
1951 "libMultiProc",
1952 "libcomplexDict",
1953 "libdequeDict",
1954 "liblistDict",
1955 "libforward_listDict",
1956 "libvectorDict",
1957 "libmapDict",
1958 "libmultimap2Dict",
1959 "libmap2Dict",
1960 "libmultimapDict",
1961 "libsetDict",
1962 "libmultisetDict",
1963 "libunordered_setDict",
1964 "libunordered_multisetDict",
1965 "libunordered_mapDict",
1966 "libunordered_multimapDict",
1967 "libvalarrayDict",
1968 "G__GenVector32",
1969 "G__Smatrix32"};
1970
1971static void PrintDlError(const char *dyLibName, const char *modulename)
1972{
1973#ifdef R__WIN32
1974 char dyLibError[1000];
1975 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1976 dyLibError, sizeof(dyLibError), NULL);
1977#else
1978 const char *dyLibError = dlerror();
1979#endif
1980 ::Error("TCling::RegisterModule", "Cannot open shared library %s for dictionary %s:\n %s", dyLibName, modulename,
1981 (dyLibError) ? dyLibError : "");
1982}
1983
1984////////////////////////////////////////////////////////////////////////////////
1985// Update all the TClass registered in fClassesToUpdate
1986
1988{
1989 while (!fClassesToUpdate.empty()) {
1990 TClass *oldcl = fClassesToUpdate.back().first;
1991 // If somehow the TClass has already been loaded (maybe it was registered several time),
1992 // we skip it. Otherwise, the existing TClass is in mode kInterpreted, kEmulated or
1993 // maybe even kForwardDeclared and needs to replaced.
1994 if (oldcl->GetState() != TClass::kHasTClassInit) {
1995 // if (gDebug > 2) Info("RegisterModule", "Forcing TClass init for %s", oldcl->GetName());
1996 DictFuncPtr_t dict = fClassesToUpdate.back().second;
1997 fClassesToUpdate.pop_back();
1998 // Calling func could manipulate the list so, let maintain the list
1999 // then call the dictionary function.
2000 TClass *ncl = dict();
2001 if (ncl) ncl->PostLoadCheck();
2002 } else {
2003 fClassesToUpdate.pop_back();
2004 }
2005 }
2006}
2007////////////////////////////////////////////////////////////////////////////////
2008/// Inject the module named "modulename" into cling; load all headers.
2009/// headers is a 0-terminated array of header files to `#include` after
2010/// loading the module. The module is searched for in all $LD_LIBRARY_PATH
2011/// entries (or %PATH% on Windows).
2012/// This function gets called by the static initialization of dictionary
2013/// libraries.
2014/// The payload code is injected "as is" in the interpreter.
2015/// The value of 'triggerFunc' is used to find the shared library location.
2016
2017void TCling::RegisterModule(const char* modulename,
2018 const char** headers,
2019 const char** includePaths,
2020 const char* payloadCode,
2021 const char* fwdDeclsCode,
2022 void (*triggerFunc)(),
2023 const FwdDeclArgsToKeepCollection_t& fwdDeclsArgToSkip,
2024 const char** classesHeaders,
2025 Bool_t lateRegistration /*=false*/,
2026 Bool_t hasCxxModule /*=false*/)
2027{
2028 const bool fromRootCling = IsFromRootCling();
2029 // We need the dictionary initialization but we don't want to inject the
2030 // declarations into the interpreter, except for those we really need for
2031 // I/O; see rootcling.cxx after the call to TCling__GetInterpreter().
2032 if (fromRootCling) return;
2033
2034 // When we cannot provide a module for the library we should enable header
2035 // parsing. This 'mixed' mode ensures gradual migration to modules.
2036 llvm::SaveAndRestore<bool> SaveHeaderParsing(fHeaderParsingOnDemand);
2037 fHeaderParsingOnDemand = !hasCxxModule;
2038
2039 // Treat Aclic Libs in a special way. Do not delay the parsing.
2040 bool hasHeaderParsingOnDemand = fHeaderParsingOnDemand;
2041 bool isACLiC = strstr(modulename, "_ACLiC_dict") != nullptr;
2042 if (hasHeaderParsingOnDemand && isACLiC) {
2043 if (gDebug>1)
2044 Info("TCling::RegisterModule",
2045 "Header parsing on demand is active but this is an Aclic library. Disabling it for this library.");
2046 hasHeaderParsingOnDemand = false;
2047 }
2048
2049
2050 // Make sure we relookup symbols that were search for before we loaded
2051 // their autoparse information. We could be more subtil and remove only
2052 // the failed one or only the one in this module, but for now this is
2053 // better than nothing.
2054 fLookedUpClasses.clear();
2055
2056 // Make sure we do not set off AutoLoading or autoparsing during the
2057 // module registration!
2058 SuspendAutoLoadingRAII autoLoadOff(this);
2059
2060 for (const char** inclPath = includePaths; *inclPath; ++inclPath) {
2061 TCling::AddIncludePath(*inclPath);
2062 }
2063 cling::Transaction* T = nullptr;
2064 // Put the template decls and the number of arguments to skip in the TNormalizedCtxt
2065 for (auto& fwdDeclArgToSkipPair : fwdDeclsArgToSkip){
2066 const std::string& fwdDecl = fwdDeclArgToSkipPair.first;
2067 const int nArgsToSkip = fwdDeclArgToSkipPair.second;
2068 auto compRes = fInterpreter->declare(fwdDecl.c_str(), &T);
2069 assert(cling::Interpreter::kSuccess == compRes &&
2070 "A fwd declaration could not be compiled");
2071 if (compRes!=cling::Interpreter::kSuccess){
2072 Warning("TCling::RegisterModule",
2073 "Problems in declaring string '%s' were encountered.",
2074 fwdDecl.c_str()) ;
2075 continue;
2076 }
2077
2078 // Drill through namespaces recursively until the template is found
2079 if(ClassTemplateDecl* TD = FindTemplateInNamespace(T->getFirstDecl().getSingleDecl())){
2080 fNormalizedCtxt->AddTemplAndNargsToKeep(TD->getCanonicalDecl(), nArgsToSkip);
2081 }
2082
2083 }
2084
2085 // FIXME: Remove #define __ROOTCLING__ once PCMs are there.
2086 // This is used to give Sema the same view on ACLiC'ed files (which
2087 // are then #included through the dictionary) as rootcling had.
2088 TString code = gNonInterpreterClassDef;
2089 if (payloadCode)
2090 code += payloadCode;
2091
2092 std::string dyLibName = cling::DynamicLibraryManager::getSymbolLocation(triggerFunc);
2093 assert(!llvm::sys::fs::is_symlink_file(dyLibName));
2094
2095 if (dyLibName.empty()) {
2096 ::Error("TCling::RegisterModule", "Dictionary trigger function for %s not found", modulename);
2097 return;
2098 }
2099
2100 // The triggerFunc may not be in a shared object but in an executable.
2101 bool isSharedLib = cling::DynamicLibraryManager::isSharedLibrary(dyLibName);
2102
2103 bool wasDlopened = false;
2104
2105 // If this call happens after dlopen has finished (i.e. late registration)
2106 // there is no need to dlopen the library recursively. See ROOT-8437 where
2107 // the dyLibName would correspond to the binary.
2108 if (!lateRegistration) {
2109
2110 if (isSharedLib) {
2111 // We need to open the dictionary shared library, to resolve symbols
2112 // requested by the JIT from it: as the library is currently being dlopen'ed,
2113 // its symbols are not yet reachable from the process.
2114 // Recursive dlopen seems to work just fine.
2115 void* dyLibHandle = dlopen(dyLibName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
2116 if (dyLibHandle) {
2117 fRegisterModuleDyLibs.push_back(dyLibHandle);
2118 wasDlopened = true;
2119 } else {
2120 PrintDlError(dyLibName.c_str(), modulename);
2121 }
2122 }
2123 } // if (!lateRegistration)
2124
2125 if (hasHeaderParsingOnDemand && fwdDeclsCode){
2126 // We now parse the forward declarations. All the classes are then modified
2127 // in order for them to have an external lexical storage.
2128 std::string fwdDeclsCodeLessEnums;
2129 {
2130 // Search for enum forward decls and only declare them if no
2131 // declaration exists yet.
2132 std::string fwdDeclsLine;
2133 std::istringstream fwdDeclsCodeStr(fwdDeclsCode);
2134 std::vector<std::string> scopes;
2135 while (std::getline(fwdDeclsCodeStr, fwdDeclsLine)) {
2136 const auto enumPos = fwdDeclsLine.find("enum __attribute__((annotate(\"");
2137 // We check if the line contains a fwd declaration of an enum
2138 if (enumPos != std::string::npos) {
2139 // We clear the scopes which we may have carried from a previous iteration
2140 scopes.clear();
2141 // We check if the enum is not in a scope. If yes, save its name
2142 // and the names of the enclosing scopes.
2143 if (enumPos != 0) {
2144 // it's enclosed in namespaces. We need to understand what they are
2145 auto nsPos = fwdDeclsLine.find("namespace");
2146 R__ASSERT(nsPos < enumPos && "Inconsistent enum and enclosing scope parsing!");
2147 while (nsPos < enumPos && nsPos != std::string::npos) {
2148 // we have a namespace, let's put it in the collection of scopes
2149 const auto nsNameStart = nsPos + 10;
2150 const auto nsNameEnd = fwdDeclsLine.find('{', nsNameStart);
2151 const auto nsName = fwdDeclsLine.substr(nsNameStart, nsNameEnd - nsNameStart);
2152 scopes.push_back(nsName);
2153 nsPos = fwdDeclsLine.find("namespace", nsNameEnd);
2154 }
2155 }
2156 clang::DeclContext* DC = nullptr;
2157 for (auto &&aScope: scopes) {
2158 DC = cling::utils::Lookup::Namespace(&fInterpreter->getSema(), aScope.c_str(), DC);
2159 if (!DC) {
2160 // No decl context means we have to fwd declare the enum.
2161 break;
2162 }
2163 }
2164 if (scopes.empty() || DC) {
2165 // We know the scope; let's look for the enum. For that, look
2166 // for the *last* closing parentheses of an attribute because
2167 // there can be multiple.
2168 size_t posEnumName = fwdDeclsLine.rfind("\"))) ");
2169 R__ASSERT(posEnumName != std::string::npos && "Inconsistent enum fwd decl!");
2170 posEnumName += 5; // skip "\"))) "
2171 while (isspace(fwdDeclsLine[posEnumName]))
2172 ++posEnumName;
2173 size_t posEnumNameEnd = fwdDeclsLine.find(" : ", posEnumName);
2174 R__ASSERT(posEnumNameEnd != std::string::npos && "Inconsistent enum fwd decl (end)!");
2175 while (isspace(fwdDeclsLine[posEnumNameEnd]))
2176 --posEnumNameEnd;
2177 // posEnumNameEnd now points to the last character of the name.
2178
2179 std::string enumName = fwdDeclsLine.substr(posEnumName,
2180 posEnumNameEnd - posEnumName + 1);
2181
2182 if (clang::NamedDecl* enumDecl
2183 = cling::utils::Lookup::Named(&fInterpreter->getSema(),
2184 enumName.c_str(), DC)) {
2185 // We have an existing enum decl (forward or definition);
2186 // skip this.
2187 R__ASSERT(llvm::dyn_cast<clang::EnumDecl>(enumDecl) && "not an enum decl!");
2188 (void)enumDecl;
2189 continue;
2190 }
2191 }
2192 }
2193
2194 fwdDeclsCodeLessEnums += fwdDeclsLine + "\n";
2195 }
2196 }
2197
2198 if (!fwdDeclsCodeLessEnums.empty()){ // Avoid the overhead if nothing is to be declared
2199 auto compRes = fInterpreter->declare(fwdDeclsCodeLessEnums, &T);
2200 assert(cling::Interpreter::kSuccess == compRes &&
2201 "The forward declarations could not be compiled");
2202 if (compRes!=cling::Interpreter::kSuccess){
2203 Warning("TCling::RegisterModule",
2204 "Problems in compiling forward declarations for module %s: '%s'",
2205 modulename, fwdDeclsCodeLessEnums.c_str()) ;
2206 }
2207 else if (T){
2208 // Loop over all decls in the transaction and go through them all
2209 // to mark them properly.
2210 // In order to do that, we first iterate over all the DelayedCallInfos
2211 // within the transaction. Then we loop over all Decls in the DeclGroupRef
2212 // contained in the DelayedCallInfos. For each decl, we traverse.
2213 ExtLexicalStorageAdder elsa;
2214 for (auto dciIt = T->decls_begin();dciIt!=T->decls_end();dciIt++){
2215 cling::Transaction::DelayCallInfo& dci = *dciIt;
2216 for(auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) {
2217 clang::Decl* declPtr = *dit;
2218 elsa.TraverseDecl(declPtr);
2219 }
2220 }
2221 }
2222 }
2223
2224 // Now we register all the headers necessary for the class
2225 // Typical format of the array:
2226 // {"A", "classes.h", "@",
2227 // "vector<A>", "vector", "@",
2228 // "myClass", payloadCode, "@",
2229 // nullptr};
2230
2231 std::string temp;
2232 for (const char** classesHeader = classesHeaders; *classesHeader; ++classesHeader) {
2233 temp=*classesHeader;
2234
2235 size_t theTemplateHash = 0;
2236 bool addTemplate = false;
2237 size_t posTemplate = temp.find('<');
2238 if (posTemplate != std::string::npos) {
2239 // Add an entry for the template itself.
2240 std::string templateName = temp.substr(0, posTemplate);
2241 theTemplateHash = fStringHashFunction(templateName);
2242 addTemplate = true;
2243 }
2244 size_t theHash = fStringHashFunction(temp);
2245 classesHeader++;
2246 for (const char** classesHeader_inner = classesHeader; 0!=strcmp(*classesHeader_inner,"@"); ++classesHeader_inner,++classesHeader){
2247 // This is done in order to distinguish headers from files and from the payloadCode
2248 if (payloadCode == *classesHeader_inner ){
2249 fPayloads.insert(theHash);
2250 if (addTemplate) fPayloads.insert(theTemplateHash);
2251 }
2252 if (gDebug > 2)
2253 Info("TCling::RegisterModule",
2254 "Adding a header for %s", temp.c_str());
2255 fClassesHeadersMap[theHash].push_back(*classesHeader_inner);
2256 if (addTemplate) {
2257 if (fClassesHeadersMap.find(theTemplateHash) == fClassesHeadersMap.end()) {
2258 fClassesHeadersMap[theTemplateHash].push_back(*classesHeader_inner);
2259 }
2260 addTemplate = false;
2261 }
2262 }
2263 }
2264 }
2265
2266 clang::Sema &TheSema = fInterpreter->getSema();
2267
2268 bool ModuleWasSuccessfullyLoaded = false;
2269 if (hasCxxModule) {
2270 std::string ModuleName = modulename;
2271 if (llvm::StringRef(modulename).startswith("lib"))
2272 ModuleName = llvm::StringRef(modulename).substr(3).str();
2273
2274 // In case we are directly loading the library via gSystem->Load() without
2275 // specifying the relevant include paths we should try loading the
2276 // modulemap next to the library location.
2277 clang::Preprocessor &PP = TheSema.getPreprocessor();
2278 std::string ModuleMapName;
2279 if (isACLiC)
2280 ModuleMapName = ModuleName + ".modulemap";
2281 else
2282 ModuleMapName = "module.modulemap";
2283 RegisterPrebuiltModulePath(llvm::sys::path::parent_path(dyLibName).str(),
2284 ModuleMapName);
2285
2286 // FIXME: We should only complain for modules which we know to exist. For example, we should not complain about
2287 // modules such as GenVector32 because it needs to fall back to GenVector.
2288 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2289 ModuleWasSuccessfullyLoaded = LoadModule(ModuleName, *fInterpreter);
2290 if (!ModuleWasSuccessfullyLoaded) {
2291 // Only report if we found the module in the modulemap.
2292 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
2293 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
2294 if (moduleMap.findModule(ModuleName))
2295 Info("TCling::RegisterModule", "Module %s in modulemap failed to load.", ModuleName.c_str());
2296 }
2297 }
2298
2299 if (gIgnoredPCMNames.find(modulename) == gIgnoredPCMNames.end()) {
2300 llvm::SmallString<256> pcmFileNameFullPath(dyLibName);
2301 // The path dyLibName might not be absolute. This can happen if dyLibName
2302 // is linked to an executable in the same folder.
2303 llvm::sys::fs::make_absolute(pcmFileNameFullPath);
2304 llvm::sys::path::remove_filename(pcmFileNameFullPath);
2305 llvm::sys::path::append(pcmFileNameFullPath,
2307 LoadPCM(pcmFileNameFullPath.str().str());
2308 }
2309
2310 { // scope within which diagnostics are de-activated
2311 // For now we disable diagnostics because we saw them already at
2312 // dictionary generation time. That won't be an issue with the PCMs.
2313
2314 clangDiagSuppr diagSuppr(TheSema.getDiagnostics());
2315
2316#if defined(R__MUST_REVISIT)
2317#if R__MUST_REVISIT(6,2)
2318 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
2319#endif
2320#endif
2321
2322 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand){
2323 SuspendAutoParsing autoParseRaii(this);
2324
2325 const cling::Transaction* watermark = fInterpreter->getLastTransaction();
2326 cling::Interpreter::CompilationResult compRes = fInterpreter->parseForModule(code.Data());
2327 if (isACLiC) {
2328 // Register an unload point.
2329 fMetaProcessor->registerUnloadPoint(watermark, headers[0]);
2330 }
2331
2332 assert(cling::Interpreter::kSuccess == compRes &&
2333 "Payload code of a dictionary could not be parsed correctly.");
2334 if (compRes!=cling::Interpreter::kSuccess) {
2335 Warning("TCling::RegisterModule",
2336 "Problems declaring payload for module %s.", modulename) ;
2337 }
2338 }
2339 }
2340
2341 // Now that all the header have been registered/compiled, let's
2342 // make sure to 'reset' the TClass that have a class init in this module
2343 // but already had their type information available (using information/header
2344 // loaded from other modules or from class rules or from opening a TFile
2345 // or from loading header in a way that did not provoke the loading of
2346 // the library we just loaded).
2348
2349 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand) {
2350 // __ROOTCLING__ might be pulled in through PCH
2351 fInterpreter->declare("#ifdef __ROOTCLING__\n"
2352 "#undef __ROOTCLING__\n"
2353 + gInterpreterClassDef +
2354 "#endif");
2355 }
2356
2357 if (wasDlopened) {
2358 assert(isSharedLib);
2359 void* dyLibHandle = fRegisterModuleDyLibs.back();
2360 fRegisterModuleDyLibs.pop_back();
2361 dlclose(dyLibHandle);
2362 }
2363}
2364
2366 clang::CompilerInstance& CI = *GetInterpreterImpl()->getCI();
2367 ASTContext &C = CI.getASTContext();
2368
2369 // Do not do anything if we have no global module index.
2370 // FIXME: This is mostly to real with false positives in the TTabCom
2371 // interface for non-modules.
2372 if (!fCxxModulesEnabled)
2373 return;
2374
2375 if (IdentifierInfoLookup *External = C.Idents.getExternalIdentifierLookup()) {
2376 std::unique_ptr<IdentifierIterator> Iter(External->getIdentifiers());
2377 for (llvm::StringRef Ident = Iter->Next(); !Ident.empty(); Ident = Iter->Next()) {
2378 std::string I = Ident.str();
2379 if (!Idents.Contains(I.data()))
2380 Idents.Add(new TObjString(I.c_str()));
2381 }
2382 }
2383}
2384
2385
2386////////////////////////////////////////////////////////////////////////////////
2387/// Register classes that already existed prior to their dictionary loading
2388/// and that already had a ClassInfo (and thus would not be refresh via
2389/// UpdateClassInfo.
2390
2392{
2393 fClassesToUpdate.push_back(std::make_pair(oldcl,dict));
2394}
2395
2396////////////////////////////////////////////////////////////////////////////////
2397/// If the dictionary is loaded, we can remove the class from the list
2398/// (otherwise the class might be loaded twice).
2399
2401{
2402 typedef std::vector<std::pair<TClass*,DictFuncPtr_t> >::iterator iterator;
2403 iterator stop = fClassesToUpdate.end();
2404 for(iterator i = fClassesToUpdate.begin();
2405 i != stop;
2406 ++i)
2407 {
2408 if ( i->first == oldcl ) {
2409 fClassesToUpdate.erase(i);
2410 return;
2411 }
2412 }
2413}
2414
2415
2416////////////////////////////////////////////////////////////////////////////////
2417/// Let cling process a command line.
2418///
2419/// If the command is executed and the error is 0, then the return value
2420/// is the int value corresponding to the result of the executed command
2421/// (float and double return values will be truncated).
2422///
2423
2424// Method for handling the interpreter exceptions.
2425// the MetaProcessor is passing in as argument to teh function, because
2426// cling::Interpreter::CompilationResult is a nested class and it cannot be
2427// forward declared, thus this method cannot be a static member function
2428// of TCling.
2429
2430static int HandleInterpreterException(cling::MetaProcessor* metaProcessor,
2431 const char* input_line,
2432 cling::Interpreter::CompilationResult& compRes,
2433 cling::Value* result)
2434{
2435 try {
2436 return metaProcessor->process(input_line, compRes, result);
2437 }
2438 catch (cling::InterpreterException& ex)
2439 {
2440 Error("HandleInterpreterException", "%s\n%s", ex.what(), "Execution of your code was aborted.");
2441 ex.diagnose();
2442 compRes = cling::Interpreter::kFailure;
2443 }
2444 return 0;
2445}
2446
2447////////////////////////////////////////////////////////////////////////////////
2448
2449bool TCling::DiagnoseIfInterpreterException(const std::exception &e) const
2450{
2451 if (auto ie = dynamic_cast<const cling::InterpreterException*>(&e)) {
2452 ie->diagnose();
2453 return true;
2454 }
2455 return false;
2456}
2457
2458////////////////////////////////////////////////////////////////////////////////
2459
2461{
2462 // Copy the passed line, it comes from a static buffer in TApplication
2463 // which can be reentered through the Cling evaluation routines,
2464 // which would overwrite the static buffer and we would forget what we
2465 // were doing.
2466 //
2467 TString sLine(line);
2468 if (strstr(line,fantomline)) {
2469 // End-Of-Line action
2470 // See the comment (copied from above):
2471 // It is a "fantom" method to synchronize user keyboard input
2472 // and ROOT prompt line (for WIN32)
2473 // and is implemented by
2474 if (gApplication) {
2475 if (gApplication->IsCmdThread()) {
2477 gROOT->SetLineIsProcessing();
2478
2480
2481 gROOT->SetLineHasBeenProcessed();
2482 }
2483 }
2484 return 0;
2485 }
2486
2488 gGlobalMutex->Lock();
2489 if (!gInterpreterMutex)
2492 }
2494 gROOT->SetLineIsProcessing();
2495
2496 struct InterpreterFlagsRAII {
2497 cling::Interpreter* fInterpreter;
2498 bool fWasDynamicLookupEnabled;
2499
2500 InterpreterFlagsRAII(cling::Interpreter* interp):
2501 fInterpreter(interp),
2502 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2503 {
2504 fInterpreter->enableDynamicLookup(true);
2505 }
2506 ~InterpreterFlagsRAII() {
2507 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2508 gROOT->SetLineHasBeenProcessed();
2509 }
2510 } interpreterFlagsRAII(GetInterpreterImpl());
2511
2512 // A non-zero returned value means the given line was
2513 // not a complete statement.
2514 int indent = 0;
2515 // This will hold the resulting value of the evaluation the given line.
2516 cling::Value result;
2517 cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess;
2518 if (!strncmp(sLine.Data(), ".L", 2) || !strncmp(sLine.Data(), ".x", 2) ||
2519 !strncmp(sLine.Data(), ".X", 2)) {
2520 // If there was a trailing "+", then CINT compiled the code above,
2521 // and we will need to strip the "+" before passing the line to cling.
2522 TString mod_line(sLine);
2523 TString aclicMode;
2524 TString arguments;
2525 TString io;
2526 TString fname = gSystem->SplitAclicMode(sLine.Data() + 3,
2527 aclicMode, arguments, io);
2528 if (aclicMode.Length()) {
2529 // Remove the leading '+'
2530 R__ASSERT(aclicMode[0]=='+' && "ACLiC mode must start with a +");
2531 aclicMode[0]='k'; // We always want to keep the .so around.
2532 if (aclicMode[1]=='+') {
2533 // We have a 2nd +
2534 aclicMode[1]='f'; // We want to force the recompilation.
2535 }
2536 if (!gSystem->CompileMacro(fname,aclicMode)) {
2537 // ACLiC failed.
2538 compRes = cling::Interpreter::kFailure;
2539 } else {
2540 if (strncmp(sLine.Data(), ".L", 2) != 0) {
2541 // if execution was requested.
2542
2543 if (arguments.Length()==0) {
2544 arguments = "()";
2545 }
2546 // We need to remove the extension.
2547 Ssiz_t ext = fname.Last('.');
2548 if (ext != kNPOS) {
2549 fname.Remove(ext);
2550 }
2551 const char *function = gSystem->BaseName(fname);
2552 mod_line = function + arguments + io;
2554 }
2555 }
2556 } else {
2557 // not ACLiC
2558 size_t unnamedMacroOpenCurly;
2559 {
2560 std::string code;
2561 std::string codeline;
2562 // Windows requires std::ifstream::binary to properly handle
2563 // CRLF and LF line endings
2564 std::ifstream in(fname, std::ifstream::binary);
2565 while (in) {
2566 std::getline(in, codeline);
2567 code += codeline + "\n";
2568 }
2569 unnamedMacroOpenCurly
2570 = cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
2571 }
2572
2573 fCurExecutingMacros.push_back(fname);
2574 if (unnamedMacroOpenCurly != std::string::npos) {
2575 compRes = fMetaProcessor->readInputFromFile(fname.Data(), &result,
2576 unnamedMacroOpenCurly);
2577 } else {
2578 // No DynLookup for .x, .L of named macros.
2579 fInterpreter->enableDynamicLookup(false);
2581 }
2582 fCurExecutingMacros.pop_back();
2583 }
2584 } // .L / .X / .x
2585 else {
2586 if (0!=strncmp(sLine.Data(), ".autodict ",10) && sLine != ".autodict") {
2587 // explicitly ignore .autodict without having to support it
2588 // in cling.
2589
2590 // Turn off autoparsing if this is an include directive
2591 bool isInclusionDirective = sLine.Contains("\n#include") || sLine.BeginsWith("#include");
2592 if (isInclusionDirective) {
2593 SuspendAutoParsing autoParseRaii(this);
2595 } else {
2597 }
2598 }
2599 }
2600 if (result.isValid())
2602 if (indent) {
2603 if (error)
2604 *error = kProcessing;
2605 return 0;
2606 }
2607 if (error) {
2608 switch (compRes) {
2609 case cling::Interpreter::kSuccess: *error = kNoError; break;
2610 case cling::Interpreter::kFailure: *error = kRecoverable; break;
2611 case cling::Interpreter::kMoreInputExpected: *error = kProcessing; break;
2612 }
2613 }
2614 if (compRes == cling::Interpreter::kSuccess
2615 && result.isValid()
2616 && !result.isVoid())
2617 {
2618 return result.castAs<Longptr_t>();
2619 }
2620 return 0;
2621}
2622
2623////////////////////////////////////////////////////////////////////////////////
2624/// No-op; see TRint instead.
2625
2627{
2628}
2629
2630////////////////////////////////////////////////////////////////////////////////
2631/// \brief Add a directory to the list of directories in which the
2632/// interpreter looks for include files.
2633/// \param[in] path The path to the directory.
2634/// \note Only one path item can be specified at a time, i.e. "path1:path2" is
2635/// \b NOT supported.
2636/// \warning Only the path to the directory should be specified, without
2637/// prepending the \c -I prefix, i.e.
2638/// <tt>gCling->AddIncludePath("/path/to/my/includes")</tt>. If the
2639/// \c -I prefix is used it will be ignored.
2640void TCling::AddIncludePath(const char *path)
2641{
2643 // Favorite source of annoyance: gSystem->AddIncludePath() needs "-I",
2644 // gCling->AddIncludePath() does not! Work around that inconsistency:
2645 if (path[0] == '-' && path[1] == 'I')
2646 path += 2;
2647 TString sPath(path);
2648 gSystem->ExpandPathName(sPath);
2649 fInterpreter->AddIncludePath(sPath.Data());
2650}
2651
2652////////////////////////////////////////////////////////////////////////////////
2653/// Visit all members over members, recursing over base classes.
2654
2655void TCling::InspectMembers(TMemberInspector& insp, const void* obj,
2656 const TClass* cl, Bool_t isTransient)
2657{
2661 }
2662
2663 if (!cl || cl->GetCollectionProxy()) {
2664 // We do not need to investigate the content of the STL
2665 // collection, they are opaque to us (and details are
2666 // uninteresting).
2667 return;
2668 }
2669
2670 static const TClassRef clRefString("std::string");
2671 if (clRefString == cl) {
2672 // We stream std::string without going through members..
2673 return;
2674 }
2675
2676 if (TClassEdit::IsStdArray(cl->GetName())) {
2677 // We treat std arrays as C arrays
2678 return;
2679 }
2680
2681 if (TClassEdit::IsUniquePtr(cl->GetName())) {
2682 // Ignore error caused by the inside of std::unique_ptr
2683 // This is needed solely because of rootclingIO's IsUnsupportedUniquePointer
2684 // which checks the number of elements in the GetListOfRealData.
2685 // If this usage is removed, this can be replaced with a return statement.
2686 // See https://github.com/root-project/root/issues/13574
2687 isTransient = true;
2688 }
2689
2690 const char* cobj = (const char*) obj; // for ptr arithmetics
2691
2692 // Treat the case of std::complex in a special manner. We want to enforce
2693 // the layout of a stl implementation independent class, which is the
2694 // complex as implemented in ROOT5.
2695
2696 // A simple lambda to simplify the code
2697 auto inspInspect = [&] (ptrdiff_t offset){
2698 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_real", cobj, isTransient);
2699 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_imag", cobj + offset, isTransient);
2700 };
2701
2702 auto complexType = TClassEdit::GetComplexType(cl->GetName());
2703 switch(complexType) {
2705 {
2706 break;
2707 }
2709 {
2710 inspInspect(sizeof(float));
2711 return;
2712 }
2714 {
2715 inspInspect(sizeof(double));
2716 return;
2717 }
2719 {
2720 inspInspect(sizeof(int));
2721 return;
2722 }
2724 {
2725 inspInspect(sizeof(long));
2726 return;
2727 }
2728 }
2729
2730 static clang::PrintingPolicy
2731 printPol(fInterpreter->getCI()->getLangOpts());
2732 if (printPol.Indentation) {
2733 // not yet initialized
2734 printPol.Indentation = 0;
2735 printPol.SuppressInitializers = true;
2736 }
2737
2738 const char* clname = cl->GetName();
2739 // Printf("Inspecting class %s\n", clname);
2740
2741 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2742 const clang::Decl *scopeDecl = nullptr;
2743 const clang::Type *recordType = nullptr;
2744
2745 if (cl->GetClassInfo()) {
2746 TClingClassInfo * clingCI = (TClingClassInfo *)cl->GetClassInfo();
2747 scopeDecl = clingCI->GetDecl();
2748 recordType = clingCI->GetType();
2749 } else {
2750 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2751 // Diags will complain about private classes:
2752 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2753 &recordType);
2754 }
2755 if (!scopeDecl) {
2756 Error("InspectMembers", "Cannot find Decl for class %s", clname);
2757 return;
2758 }
2759 const clang::CXXRecordDecl* recordDecl
2760 = llvm::dyn_cast<const clang::CXXRecordDecl>(scopeDecl);
2761 if (!recordDecl) {
2762 Error("InspectMembers", "Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2763 return;
2764 }
2765
2766 {
2767 // Force possible deserializations first. We need to have no pending
2768 // Transaction when passing control flow to the inspector below (ROOT-7779).
2769 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2770
2771 astContext.getASTRecordLayout(recordDecl);
2772
2773 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2774 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2775 }
2776
2777 const clang::ASTRecordLayout& recLayout
2778 = astContext.getASTRecordLayout(recordDecl);
2779
2780 // TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
2781 // if (proxy && ( proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated ) ) {
2782 // Error("InspectMembers","The TClass for %s has an emulated proxy but we are looking at a compiled version of the collection!\n",
2783 // cl->GetName());
2784 // }
2785 if (cl->Size() != recLayout.getSize().getQuantity()) {
2786 Error("InspectMembers","TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2787 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2788 }
2789
2790 unsigned iNField = 0;
2791 // iterate over fields
2792 // FieldDecls are non-static, else it would be a VarDecl.
2793 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2794 eField = recordDecl->field_end(); iField != eField;
2795 ++iField, ++iNField) {
2796
2797
2798 clang::QualType memberQT = iField->getType();
2799 if (recordType) {
2800 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2801 memberQT = ROOT::TMetaUtils::ReSubstTemplateArg(memberQT, recordType);
2802 }
2803 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2804 if (memberQT.isNull()) {
2805 std::string memberName;
2806 llvm::raw_string_ostream stream(memberName);
2807 // Don't trigger fopen of the source file to count lines:
2808 printPol.AnonymousTagLocations = false;
2809 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2810 stream.flush();
2811 Error("InspectMembers",
2812 "Cannot retrieve QualType for member %s while inspecting class %s",
2813 memberName.c_str(), clname);
2814 continue; // skip member
2815 }
2816 const clang::Type* memType = memberQT.getTypePtr();
2817 if (!memType) {
2818 std::string memberName;
2819 llvm::raw_string_ostream stream(memberName);
2820 // Don't trigger fopen of the source file to count lines:
2821 printPol.AnonymousTagLocations = false;
2822 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2823 stream.flush();
2824 Error("InspectMembers",
2825 "Cannot retrieve Type for member %s while inspecting class %s",
2826 memberName.c_str(), clname);
2827 continue; // skip member
2828 }
2829
2830 const clang::Type* memNonPtrType = memType;
2831 Bool_t ispointer = false;
2832 if (memNonPtrType->isPointerType()) {
2833 ispointer = true;
2834 clang::QualType ptrQT
2835 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2836 if (recordType) {
2837 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2838 ptrQT = ROOT::TMetaUtils::ReSubstTemplateArg(ptrQT, recordType);
2839 }
2840 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2841 if (ptrQT.isNull()) {
2842 std::string memberName;
2843 llvm::raw_string_ostream stream(memberName);
2844 // Don't trigger fopen of the source file to count lines:
2845 printPol.AnonymousTagLocations = false;
2846 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2847 stream.flush();
2848 Error("InspectMembers",
2849 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2850 memberName.c_str(), clname);
2851 continue; // skip member
2852 }
2853 memNonPtrType = ptrQT.getTypePtr();
2854 }
2855
2856 // assemble array size(s): "[12][4][]"
2857 llvm::SmallString<8> arraySize;
2858 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2859 unsigned arrLevel = 0;
2860 bool haveErrorDueToArray = false;
2861 while (arrType) {
2862 ++arrLevel;
2863 arraySize += '[';
2864 const clang::ConstantArrayType* constArrType =
2865 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2866 if (constArrType) {
2867 constArrType->getSize().toStringUnsigned(arraySize);
2868 }
2869 arraySize += ']';
2870 clang::QualType subArrQT = arrType->getElementType();
2871 if (subArrQT.isNull()) {
2872 std::string memberName;
2873 llvm::raw_string_ostream stream(memberName);
2874 // Don't trigger fopen of the source file to count lines:
2875 printPol.AnonymousTagLocations = false;
2876 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2877 stream.flush();
2878 Error("InspectMembers",
2879 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
2880 arrLevel, subArrQT.getAsString(printPol).c_str(),
2881 memberName.c_str(), clname);
2882 haveErrorDueToArray = true;
2883 break;
2884 }
2885 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
2886 }
2887 if (haveErrorDueToArray) {
2888 continue; // skip member
2889 }
2890
2891 // construct member name
2892 std::string fieldName;
2893 if (memType->isPointerType()) {
2894 fieldName = "*";
2895 }
2896
2897 // Check if this field has a custom ioname, if not, just use the one of the decl
2898 std::string ioname(iField->getName());
2899 ROOT::TMetaUtils::ExtractAttrPropertyFromName(**iField,"ioname",ioname);
2900 fieldName += ioname;
2901 fieldName += arraySize;
2902
2903 // get member offset
2904 // NOTE currently we do not support bitfield and do not support
2905 // member that are not aligned on 'bit' boundaries.
2906 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
2907 ptrdiff_t fieldOffset = offset.getQuantity();
2908
2909 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fBits[2]", fBits);
2910 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fName", &fName);
2911 // R__insp.InspectMember(fName, "fName.");
2912 // R__insp.Inspect(R__cl, R__insp.GetParent(), "*fClass", &fClass);
2913
2914 // If the class has a custom streamer and the type of the filed is a
2915 // private enum, struct or class, skip it.
2916 if (!insp.IsTreatingNonAccessibleTypes()){
2917 auto iFiledQtype = iField->getType();
2918 if (auto tagDecl = iFiledQtype->getAsTagDecl()){
2919 auto declAccess = tagDecl->getAccess();
2920 if (declAccess == AS_private || declAccess == AS_protected) {
2921 continue;
2922 }
2923 }
2924 }
2925
2926 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
2927
2928 if (!ispointer) {
2929 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
2930 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
2931 // nested objects get an extra call to InspectMember
2932 // R__insp.InspectMember("FileStat_t", (void*)&fFileStat, "fFileStat.", false);
2933 std::string sFieldRecName;
2934 if (!ROOT::TMetaUtils::ExtractAttrPropertyFromName(*fieldRecDecl,"iotype",sFieldRecName)){
2936 clang::QualType(memNonPtrType,0),
2937 *fInterpreter,
2939 }
2940
2941 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
2942 // if we can not find the member (which should not really happen),
2943 // let's consider it transient.
2944 Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();
2945
2946 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
2947 (fieldName + '.').c_str(), transient);
2948
2949 }
2950 }
2951 } // loop over fields
2952
2953 // inspect bases
2954 // TNamed::ShowMembers(R__insp);
2955 unsigned iNBase = 0;
2956 for (clang::CXXRecordDecl::base_class_const_iterator iBase
2957 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
2958 iBase != eBase; ++iBase, ++iNBase) {
2959 clang::QualType baseQT = iBase->getType();
2960 if (baseQT.isNull()) {
2961 Error("InspectMembers",
2962 "Cannot find QualType for base number %d while inspecting class %s",
2963 iNBase, clname);
2964 continue;
2965 }
2966 const clang::CXXRecordDecl* baseDecl
2967 = baseQT->getAsCXXRecordDecl();
2968 if (!baseDecl) {
2969 Error("InspectMembers",
2970 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
2971 iNBase, clname);
2972 continue;
2973 }
2974 TClass* baseCl=nullptr;
2975 std::string sBaseName;
2976 // Try with the DeclId
2977 std::vector<TClass*> foundClasses;
2978 TClass::GetClass(static_cast<DeclId_t>(baseDecl), foundClasses);
2979 if (foundClasses.size()==1){
2980 baseCl=foundClasses[0];
2981 } else {
2982 // Try with the normalised Name, as a fallback
2983 if (!baseCl){
2985 baseQT,
2986 *fInterpreter,
2988 baseCl = TClass::GetClass(sBaseName.c_str());
2989 }
2990 }
2991
2992 if (!baseCl){
2993 std::string qualNameForDiag;
2994 ROOT::TMetaUtils::GetQualifiedName(qualNameForDiag, *baseDecl);
2995 Error("InspectMembers",
2996 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
2997 continue;
2998 }
2999
3000 int64_t baseOffset;
3001 if (iBase->isVirtual()) {
3003 if (!isTransient) {
3004 Error("InspectMembers",
3005 "Base %s of class %s is virtual but no object provided",
3006 sBaseName.c_str(), clname);
3007 }
3009 } else {
3010 // We have an object to determine the vbase offset.
3012 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
3013 if (ci && baseCi) {
3014 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
3015 true /*isDerivedObj*/);
3016 if (baseOffset == -1) {
3017 Error("InspectMembers",
3018 "Error calculating offset of virtual base %s of class %s",
3019 sBaseName.c_str(), clname);
3020 }
3021 } else {
3022 Error("InspectMembers",
3023 "Cannot calculate offset of virtual base %s of class %s",
3024 sBaseName.c_str(), clname);
3025 continue;
3026 }
3027 }
3028 } else {
3029 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
3030 }
3031 // TOFIX: baseCl can be null here!
3032 if (baseCl->IsLoaded()) {
3033 // For loaded class, CallShowMember will (especially for TObject)
3034 // call the virtual ShowMember rather than the class specific version
3035 // resulting in an infinite recursion.
3036 InspectMembers(insp, cobj + baseOffset, baseCl, isTransient);
3037 } else {
3038 baseCl->CallShowMembers(cobj + baseOffset,
3039 insp, isTransient);
3040 }
3041 } // loop over bases
3042}
3043
3044////////////////////////////////////////////////////////////////////////////////
3045/// Reset the interpreter internal state in case a previous action was not correctly
3046/// terminated.
3047
3049{
3050 // No-op there is not equivalent state (to be cleared) in Cling.
3051}
3052
3053////////////////////////////////////////////////////////////////////////////////
3054/// Delete existing temporary values.
3055
3057{
3058 // No-op for cling due to cling::Value.
3059}
3060
3061////////////////////////////////////////////////////////////////////////////////
3062/// Declare code to the interpreter, without any of the interpreter actions
3063/// that could trigger a re-interpretation of the code. I.e. make cling
3064/// behave like a compiler: no dynamic lookup, no input wrapping for
3065/// subsequent execution, no automatic provision of declarations but just a
3066/// plain `#include`.
3067/// Returns true on success, false on failure.
3068
3069bool TCling::Declare(const char* code)
3070{
3072
3073 SuspendAutoLoadingRAII autoLoadOff(this);
3074 SuspendAutoParsing autoParseRaii(this);
3075
3076 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
3077 fInterpreter->enableDynamicLookup(false);
3078 bool oldRawInput = fInterpreter->isRawInputEnabled();
3079 fInterpreter->enableRawInput(true);
3080
3081 Bool_t ret = LoadText(code);
3082
3083 fInterpreter->enableRawInput(oldRawInput);
3084 fInterpreter->enableDynamicLookup(oldDynLookup);
3085 return ret;
3086}
3087
3088////////////////////////////////////////////////////////////////////////////////
3089/// It calls a "fantom" method to synchronize user keyboard input
3090/// and ROOT prompt line.
3091
3093{
3095}
3096
3097// This static function is a hop of TCling::IsLibraryLoaded, which is taking a lock and calling
3098// into this function. This is because we wanted to avoid a duplication in TCling::IsLoaded, which
3099// was already taking a lock.
3100static Bool_t s_IsLibraryLoaded(const char* libname, cling::Interpreter* fInterpreter)
3101{
3102 // Check shared library.
3103 TString tLibName(libname);
3104 if (gSystem->FindDynamicLibrary(tLibName, kTRUE))
3105 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
3106 return false;
3107}
3108
3109Bool_t TCling::IsLibraryLoaded(const char* libname) const
3110{
3112 return s_IsLibraryLoaded(libname, GetInterpreterImpl());
3113}
3114
3115////////////////////////////////////////////////////////////////////////////////
3116/// Return true if ROOT has cxxmodules pcm for a given library name.
3117// FIXME: We need to be able to support lazy loading of pcm generated by ACLiC.
3118Bool_t TCling::HasPCMForLibrary(const char *libname) const
3119{
3120 llvm::StringRef ModuleName(libname);
3121 ModuleName = llvm::sys::path::stem(ModuleName);
3122 ModuleName.consume_front("lib");
3123
3124 // FIXME: In case when the modulemap is not yet loaded we will return the
3125 // wrong result. Consider a call to HasPCMForLibrary(../test/libEvent.so)
3126 // We will only load the modulemap for libEvent.so after we dlopen libEvent
3127 // which may happen after calling this interface. Maybe we should also check
3128 // if there is a Event.pcm file and a module.modulemap, load it and return
3129 // true.
3130 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
3131 clang::Module *M = moduleMap.findModule(ModuleName);
3132 return M && !M->IsUnimportable && M->getASTFile();
3133}
3134
3135////////////////////////////////////////////////////////////////////////////////
3136/// Return true if the file has already been loaded by cint.
3137/// We will try in this order:
3138/// actual filename
3139/// filename as a path relative to
3140/// the include path
3141/// the shared library path
3142
3144{
3146
3147 //FIXME: if we use llvm::sys::fs::make_absolute all this can go away. See
3148 // cling::DynamicLibraryManager.
3149
3150 std::string file_name = filename;
3151 size_t at = std::string::npos;
3152 while ((at = file_name.find("/./")) != std::string::npos)
3153 file_name.replace(at, 3, "/");
3154
3155 std::string filesStr = "";
3156 llvm::raw_string_ostream filesOS(filesStr);
3157 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3158 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
3159 filesOS.flush();
3160
3161 llvm::SmallVector<llvm::StringRef, 100> files;
3162 llvm::StringRef(filesStr).split(files, "\n");
3163
3164 std::set<std::string> fileMap;
3165 llvm::StringRef file_name_ref(file_name);
3166 // Fill fileMap; return early on exact match.
3167 for (llvm::SmallVector<llvm::StringRef, 100>::const_iterator
3168 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
3169 if ((*iF) == file_name_ref) return kTRUE; // exact match
3170 fileMap.insert(iF->str());
3171 }
3172
3173 if (fileMap.empty()) return kFALSE;
3174
3175 // Check MacroPath.
3176 TString sFilename(file_name.c_str());
3178 && fileMap.count(sFilename.Data())) {
3179 return kTRUE;
3180 }
3181
3182 // Check IncludePath.
3183 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
3184 incPath.Append(":").Prepend(" "); // to match " -I" (note leading ' ')
3185 incPath.ReplaceAll(" -I", ":"); // of form :dir1 :dir2:dir3
3186 while (incPath.Index(" :") != -1) {
3187 incPath.ReplaceAll(" :", ":");
3188 }
3189 incPath.Prepend(".:");
3190 sFilename = file_name.c_str();
3191 if (gSystem->FindFile(incPath, sFilename, kReadPermission)
3192 && fileMap.count(sFilename.Data())) {
3193 return kTRUE;
3194 }
3195
3196 // Check shared library.
3197 if (s_IsLibraryLoaded(file_name.c_str(), GetInterpreterImpl()))
3198 return kTRUE;
3199
3200 //FIXME: We must use the cling::Interpreter::lookupFileOrLibrary iface.
3201 const clang::DirectoryLookup *CurDir = nullptr;
3202 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
3203 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
3204 auto FE = HS.LookupFile(file_name.c_str(),
3205 clang::SourceLocation(),
3206 /*isAngled*/ false,
3207 /*FromDir*/ nullptr, CurDir,
3208 clang::ArrayRef<std::pair<const clang::FileEntry *,
3209 const clang::DirectoryEntry *>>(),
3210 /*SearchPath*/ nullptr,
3211 /*RelativePath*/ nullptr,
3212 /*RequestingModule*/ nullptr,
3213 /*SuggestedModule*/ nullptr,
3214 /*IsMapped*/ nullptr,
3215 /*IsFrameworkFound*/ nullptr,
3216 /*SkipCache*/ false,
3217 /*BuildSystemModule*/ false,
3218 /*OpenFile*/ false,
3219 /*CacheFail*/ false);
3220 if (FE && FE->isValid()) {
3221 // check in the source manager if the file is actually loaded
3222 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3223 // this works only with header (and source) files...
3224 clang::FileID FID = SM.translateFile(*FE);
3225 if (!FID.isInvalid() && FID.getHashValue() == 0)
3226 return kFALSE;
3227 else {
3228 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
3229 if (SLocE.isFile() && !SLocE.getFile().getContentCache().getBufferIfLoaded())
3230 return kFALSE;
3231 if (!FID.isInvalid())
3232 return kTRUE;
3233 }
3234 // ...then check shared library again, but with full path now
3235 sFilename = FE->getName().str();
3236 if (gSystem->FindDynamicLibrary(sFilename, kTRUE)
3237 && fileMap.count(sFilename.Data())) {
3238 return kTRUE;
3239 }
3240 }
3241 return kFALSE;
3242}
3243
3244
3245#if defined(R__MACOSX)
3246
3247////////////////////////////////////////////////////////////////////////////////
3248/// Check if lib is in the dynamic linker cache, returns true if it is, and if so,
3249/// modifies the library file name parameter `lib` from `/usr/lib/libFOO.dylib`
3250/// to `-lFOO` such that it can be passed to the linker.
3251/// This is a unique feature of macOS 11.
3252
3253static bool R__UpdateLibFileForLinking(TString &lib)
3254{
3255 const char *mapfile = nullptr;
3256#if __x86_64__
3257 mapfile = "/System/Library/dyld/dyld_shared_cache_x86_64.map";
3258#elif __arm64__
3259 mapfile = "/System/Library/dyld/dyld_shared_cache_arm64e.map";
3260#else
3261 #error unsupported architecture
3262#endif
3263 if (std::ifstream cacheMap{mapfile}) {
3264 std::string line;
3265 while (getline(cacheMap, line)) {
3266 if (line.find(lib) != std::string::npos) {
3267 lib.ReplaceAll("/usr/lib/lib","-l");
3268 lib.ReplaceAll(".dylib","");
3269 return true;
3270 }
3271 }
3272 return false;
3273 }
3274 return false;
3275}
3276#endif // R__MACOSX
3277
3278#if defined (R__LINUX) || defined (R__FBSD)
3279
3280////////////////////////////////////////////////////////////////////////////////
3281/// Callback for dl_iterate_phdr(), see `man dl_iterate_phdr`.
3282/// Collects opened libraries.
3283
3284static int callback_for_dl_iterate_phdr(struct dl_phdr_info *info, size_t size, void *data)
3285{
3286 // This function is called through UpdateListOfLoadedSharedLibraries() which is locked.
3287 static std::unordered_set<decltype(info->dlpi_addr)> sKnownLoadedLibBaseAddrs;
3288
3289 auto newLibs = static_cast<std::vector<std::string>*>(data);
3290 if (!sKnownLoadedLibBaseAddrs.count(info->dlpi_addr)) {
3291 // Skip \0, "", and kernel pseudo-libs linux-vdso.so.1 or linux-gate.so.1
3292 if (info->dlpi_name && info->dlpi_name[0]
3293#if defined(R__FBSD)
3294 //skip the executable (with null addr)
3295 && info->dlpi_addr
3296 //has no path
3297 && strncmp(info->dlpi_name, "[vdso]", 6)
3298 //the linker does not like to be mmapped
3299 //causes a crash in cling::DynamicLibraryManager::loadLibrary())
3300 //with error message "mmap of entire address space failed: Cannot allocate memory"
3301 && strncmp(info->dlpi_name, "/libexec/ld-elf.so.1", 20)
3302#endif
3303 && strncmp(info->dlpi_name, "linux-vdso.so", 13)
3304 && strncmp(info->dlpi_name, "linux-vdso32.so", 15)
3305 && strncmp(info->dlpi_name, "linux-vdso64.so", 15)
3306 && strncmp(info->dlpi_name, "linux-gate.so", 13))
3307 newLibs->emplace_back(info->dlpi_name);
3308 sKnownLoadedLibBaseAddrs.insert(info->dlpi_addr);
3309 }
3310 // No matter what the doc says, return != 0 means "stop the iteration".
3311 return 0;
3312}
3313
3314#endif // R__LINUX || R__FBSD
3315
3316
3317////////////////////////////////////////////////////////////////////////////////
3318
3320{
3321#if defined(R__WIN32) || defined(__CYGWIN__)
3322 HMODULE hModules[1024];
3323 void *hProcess;
3324 unsigned long cbModules;
3325 unsigned int i;
3326 hProcess = (void *)::GetCurrentProcess();
3327 ::EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbModules);
3328 // start at 1 to skip the executable itself
3329 for (i = 1; i < (cbModules / sizeof(void *)); i++) {
3330 static const int bufsize = 260;
3331 wchar_t winname[bufsize];
3332 char posixname[bufsize];
3333 ::GetModuleFileNameExW(hProcess, hModules[i], winname, bufsize);
3334#if defined(__CYGWIN__)
3335 cygwin_conv_path(CCP_WIN_W_TO_POSIX, winname, posixname, bufsize);
3336#else
3337 std::wstring wpath = winname;
3338 std::replace(wpath.begin(), wpath.end(), '\\', '/');
3339 string path(wpath.begin(), wpath.end());
3340 strncpy(posixname, path.c_str(), bufsize);
3341#endif
3342 if (!fSharedLibs.Contains(posixname)) {
3343 RegisterLoadedSharedLibrary(posixname);
3344 }
3345 }
3346#elif defined(R__MACOSX)
3347 // fPrevLoadedDynLibInfo stores the *next* image index to look at
3348 uint32_t imageIndex = (uint32_t) (size_t) fPrevLoadedDynLibInfo;
3349
3350 while (const mach_header* mh = _dyld_get_image_header(imageIndex)) {
3351 // Skip non-dylibs
3352 if (mh->filetype == MH_DYLIB) {
3353 if (const char* imageName = _dyld_get_image_name(imageIndex)) {
3354 RegisterLoadedSharedLibrary(imageName);
3355 }
3356 }
3357
3358 ++imageIndex;
3359 }
3360 fPrevLoadedDynLibInfo = (void*)(size_t)imageIndex;
3361#elif defined(R__LINUX) || defined(R__FBSD)
3362 // fPrevLoadedDynLibInfo is unused on Linux.
3363 (void) fPrevLoadedDynLibInfo;
3364
3365 std::vector<std::string> newLibs;
3366 dl_iterate_phdr(callback_for_dl_iterate_phdr, &newLibs);
3367 for (auto &&lib: newLibs)
3368 RegisterLoadedSharedLibrary(lib.c_str());
3369#else
3370 Error("TCling::UpdateListOfLoadedSharedLibraries",
3371 "Platform not supported!");
3372#endif
3373}
3374
3375namespace {
3376template <int N>
3377static bool StartsWithStrLit(const char *haystack, const char (&needle)[N]) {
3378 return !strncmp(haystack, needle, N - 1);
3379}
3380}
3381
3382////////////////////////////////////////////////////////////////////////////////
3383/// Register a new shared library name with the interpreter; add it to
3384/// fSharedLibs.
3385
3387{
3388 // Ignore NULL filenames, aka "the process".
3389 if (!filename) return;
3390
3391 // Tell the interpreter that this library is available; all libraries can be
3392 // used to resolve symbols.
3393 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3394 if (!DLM->isLibraryLoaded(filename)) {
3395 DLM->loadLibrary(filename, true /*permanent*/, true /*resolved*/);
3396 }
3397
3398#if defined(R__MACOSX)
3399 // Check that this is not a system library that does not exist on disk.
3400 auto lenFilename = strlen(filename);
3401 auto isInMacOSSystemDir = [](const char *fn) {
3402 return StartsWithStrLit(fn, "/usr/lib/") || StartsWithStrLit(fn, "/System/Library/");
3403 };
3404 if (!strcmp(filename, "cl_kernels") // yepp, no directory
3405
3406 // These we should not link with (e.g. because they forward to .tbd):
3407 || StartsWithStrLit(filename, "/usr/lib/system/")
3408 || StartsWithStrLit(filename, "/usr/lib/libc++")
3409 || StartsWithStrLit(filename, "/System/Library/Frameworks/")
3410 || StartsWithStrLit(filename, "/System/Library/PrivateFrameworks/")
3411 || StartsWithStrLit(filename, "/System/Library/CoreServices/")
3412 || StartsWithStrLit(filename, "/usr/lib/libSystem")
3413 || StartsWithStrLit(filename, "/usr/lib/libstdc++")
3414 || StartsWithStrLit(filename, "/usr/lib/libicucore")
3415 || StartsWithStrLit(filename, "/usr/lib/libbsm")
3416 || StartsWithStrLit(filename, "/usr/lib/libobjc")
3417 || StartsWithStrLit(filename, "/usr/lib/libresolv")
3418 || StartsWithStrLit(filename, "/usr/lib/libauto")
3419 || StartsWithStrLit(filename, "/usr/lib/libcups")
3420 || StartsWithStrLit(filename, "/usr/lib/libDiagnosticMessagesClient")
3421 || StartsWithStrLit(filename, "/usr/lib/liblangid")
3422 || StartsWithStrLit(filename, "/usr/lib/libCRFSuite")
3423 || StartsWithStrLit(filename, "/usr/lib/libpam")
3424 || StartsWithStrLit(filename, "/usr/lib/libOpenScriptingUtil")
3425 || StartsWithStrLit(filename, "/usr/lib/libextension")
3426 || StartsWithStrLit(filename, "/usr/lib/libAudioToolboxUtility")
3427 || StartsWithStrLit(filename, "/usr/lib/liboah")
3428 || StartsWithStrLit(filename, "/usr/lib/libRosetta")
3429 || StartsWithStrLit(filename, "/usr/lib/libCoreEntitlements")
3430 || StartsWithStrLit(filename, "/usr/lib/libssl.")
3431 || StartsWithStrLit(filename, "/usr/lib/libcrypto.")
3432
3433 // The system lib is likely in macOS's blob.
3434 || (isInMacOSSystemDir(filename) && gSystem->AccessPathName(filename))
3435
3436 // "Link against the umbrella framework 'System.framework' instead"
3437 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_kernel")
3438 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_platform")
3439 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_pthread")
3440
3441 // "cannot link directly with dylib/framework, your binary is not an allowed client of
3442 // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
3443 // SDKs/MacOSX.sdk/usr/lib/libAudioToolboxUtility.tbd for architecture x86_64
3444 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4, ".tbd")))
3445 return;
3446 TString sFileName(filename);
3447 R__UpdateLibFileForLinking(sFileName);
3448 filename = sFileName.Data();
3449#elif defined(__CYGWIN__)
3450 // Check that this is not a system library
3451 static const int bufsize = 260;
3452 char posixwindir[bufsize];
3453 char *windir = getenv("WINDIR");
3454 if (windir)
3455 cygwin_conv_path(CCP_WIN_A_TO_POSIX, windir, posixwindir, bufsize);
3456 else
3457 snprintf(posixwindir, sizeof(posixwindir), "/Windows/");
3458 if (strstr(filename, posixwindir) ||
3459 strstr(filename, "/usr/bin/cyg"))
3460 return;
3461#elif defined(R__WIN32)
3462 if (strstr(filename, "/Windows/"))
3463 return;
3464#elif defined (R__LINUX)
3465 if (strstr(filename, "/ld-linux")
3466 || strstr(filename, "linux-gnu/")
3467 || strstr(filename, "/libstdc++.")
3468 || strstr(filename, "/libgcc")
3469 || strstr(filename, "/libc.")
3470 || strstr(filename, "/libdl.")
3471 || strstr(filename, "/libm."))
3472 return;
3473#endif
3474 // Update string of available libraries.
3475 if (!fSharedLibs.IsNull()) {
3476 fSharedLibs.Append(" ");
3477 }
3479}
3480
3481////////////////////////////////////////////////////////////////////////////////
3482/// Load a library file in cling's memory.
3483/// if 'system' is true, the library is never unloaded.
3484/// Return 0 on success, -1 on failure.
3485
3486Int_t TCling::Load(const char* filename, Bool_t system)
3487{
3488 assert(!IsFromRootCling() && "Trying to load library from rootcling!");
3489
3490 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3492 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3493 std::string canonLib = DLM->lookupLibrary(filename);
3494 cling::DynamicLibraryManager::LoadLibResult res
3495 = cling::DynamicLibraryManager::kLoadLibNotFound;
3496 if (!canonLib.empty()) {
3497 if (system)
3498 res = DLM->loadLibrary(filename, system, true);
3499 else {
3500 // For the non system libs, we'd like to be able to unload them.
3501 // FIXME: Here we lose the information about kLoadLibAlreadyLoaded case.
3502 cling::Interpreter::CompilationResult compRes;
3503 HandleInterpreterException(GetMetaProcessorImpl(), Form(".L %s", canonLib.c_str()), compRes, /*cling::Value*/nullptr);
3504 if (compRes == cling::Interpreter::kSuccess)
3505 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3506 }
3507 }
3508
3509 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3511 }
3512 switch (res) {
3513 case cling::DynamicLibraryManager::kLoadLibSuccess: return 0;
3514 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return 1;
3515 default: break;
3516 };
3517 return -1;
3518}
3519
3520////////////////////////////////////////////////////////////////////////////////
3521/// Load a macro file in cling's memory.
3522
3523void TCling::LoadMacro(const char* filename, EErrorCode* error)
3524{
3525 ProcessLine(Form(".L %s", filename), error);
3526}
3527
3528////////////////////////////////////////////////////////////////////////////////
3529/// Let cling process a command line asynch.
3530
3532{
3533 return ProcessLine(line, error);
3534}
3535
3536////////////////////////////////////////////////////////////////////////////////
3537/// Let cling process a command line synchronously, i.e we are waiting
3538/// it will be finished.
3539
3541{
3543 if (gApplication) {
3544 if (gApplication->IsCmdThread()) {
3545 return ProcessLine(line, error);
3546 }
3547 return 0;
3548 }
3549 return ProcessLine(line, error);
3550}
3551
3552////////////////////////////////////////////////////////////////////////////////
3553/// Directly execute an executable statement (e.g. "func()", "3+5", etc.
3554/// however not declarations, like "Int_t x;").
3555
3557{
3558#ifdef R__WIN32
3559 // Test on ApplicationImp not being 0 is needed because only at end of
3560 // TApplication ctor the IsLineProcessing flag is set to 0, so before
3561 // we can not use it.
3563 while (gROOT->IsLineProcessing() && !gApplication) {
3564 Warning("Calc", "waiting for cling thread to free");
3565 gSystem->Sleep(500);
3566 }
3567 gROOT->SetLineIsProcessing();
3568 }
3569#endif // R__WIN32
3571 if (error) {
3572 *error = TInterpreter::kNoError;
3573 }
3574 cling::Value valRef;
3575 cling::Interpreter::CompilationResult cr = cling::Interpreter::kFailure;
3576 try {
3577 cr = fInterpreter->evaluate(line, valRef);
3578 }
3579 catch (cling::InterpreterException& ex)
3580 {
3581 Error("Calc", "%s.\n%s", ex.what(), "Evaluation of your expression was aborted.");
3582 ex.diagnose();
3583 cr = cling::Interpreter::kFailure;
3584 }
3585
3586 if (cr != cling::Interpreter::kSuccess) {
3587 // Failure in compilation.
3588 if (error) {
3589 // Note: Yes these codes are weird.
3591 }
3592 return 0L;
3593 }
3594 if (!valRef.isValid()) {
3595 // Failure at runtime.
3596 if (error) {
3597 // Note: Yes these codes are weird.
3598 *error = TInterpreter::kDangerous;
3599 }
3600 return 0L;
3601 }
3602
3603 if (valRef.isVoid()) {
3604 return 0;
3605 }
3606
3607 RegisterTemporary(valRef);
3608#ifdef R__WIN32
3610 gROOT->SetLineHasBeenProcessed();
3611 }
3612#endif // R__WIN32
3613 return valRef.castAs<Longptr_t>();
3614}
3615
3616////////////////////////////////////////////////////////////////////////////////
3617/// Set a getline function to call when input is needed.
3618
3619void TCling::SetGetline(const char * (*getlineFunc)(const char* prompt),
3620 void (*histaddFunc)(const char* line))
3621{
3622 // If cling offers a replacement for G__pause(), it would need to
3623 // also offer a way to customize at least the history recording.
3624
3625#if defined(R__MUST_REVISIT)
3626#if R__MUST_REVISIT(6,2)
3627 Warning("SetGetline","Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3628#endif
3629#endif
3630}
3631
3632////////////////////////////////////////////////////////////////////////////////
3633/// Helper function to increase the internal Cling count of transactions
3634/// that change the AST.
3635
3636Bool_t TCling::HandleNewTransaction(const cling::Transaction &T)
3637{
3639
3640 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3641 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3642 || T.macros_begin() != T.macros_end()
3643 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3645 return true;
3646 }
3647 return false;
3648}
3649
3650////////////////////////////////////////////////////////////////////////////////
3651/// Delete object from cling symbol table so it can not be used anymore.
3652/// cling objects are always on the heap.
3653
3655{
3656 // NOTE: When replacing the mutex by a ReadWrite mutex, we **must**
3657 // put in place the Read/Write part here. Keeping the write lock
3658 // here is 'catasptrophic' for scaling as it means that ALL calls
3659 // to RecursiveRemove will take the write lock and performance
3660 // of many threads trying to access the write lock at the same
3661 // time is relatively bad.
3663 // Note that fgSetOfSpecials is supposed to be updated by TClingCallbacks::tryFindROOTSpecialInternal
3664 // (but isn't at the moment).
3665 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3666 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3667 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3669 DeleteGlobal(obj);
3670 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3671 }
3672 }
3673}
3674
3675////////////////////////////////////////////////////////////////////////////////
3676/// Pressing Ctrl+C should forward here. In the case where we have had
3677/// continuation requested we must reset it.
3678
3680{
3681 fMetaProcessor->cancelContinuation();
3682 // Reset the Cling state to the state saved by the last call to
3683 // TCling::SaveContext().
3684#if defined(R__MUST_REVISIT)
3685#if R__MUST_REVISIT(6,2)
3687 Warning("Reset","Cling should support the equivalent of scratch_upto(&fDictPos)");
3688#endif
3689#endif
3690}
3691
3692////////////////////////////////////////////////////////////////////////////////
3693/// Reset the Cling state to its initial state.
3694
3696{
3697#if defined(R__MUST_REVISIT)
3698#if R__MUST_REVISIT(6,2)
3700 Warning("ResetAll","Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3701#endif
3702#endif
3703}
3704
3705////////////////////////////////////////////////////////////////////////////////
3706/// Reset in Cling the list of global variables to the state saved by the last
3707/// call to TCling::SaveGlobalsContext().
3708///
3709/// Note: Right now, all we do is run the global destructors.
3710
3712{
3714 // TODO:
3715 // Here we should iterate over the transactions (N-3) and revert.
3716 // N-3 because the first three internal to cling.
3717
3718 fInterpreter->runAndRemoveStaticDestructors();
3719}
3720
3721////////////////////////////////////////////////////////////////////////////////
3722/// Reset the Cling 'user' global objects/variables state to the state saved by the last
3723/// call to TCling::SaveGlobalsContext().
3724
3726{
3727#if defined(R__MUST_REVISIT)
3728#if R__MUST_REVISIT(6,2)
3730 Warning("ResetGlobalVar","Cling should support the equivalent of resetglobalvar(obj)");
3731#endif
3732#endif
3733}
3734
3735////////////////////////////////////////////////////////////////////////////////
3736/// Rewind Cling dictionary to the point where it was before executing
3737/// the current macro. This function is typically called after SEGV or
3738/// ctlr-C after doing a longjmp back to the prompt.
3739
3741{
3742#if defined(R__MUST_REVISIT)
3743#if R__MUST_REVISIT(6,2)
3745 Warning("RewindDictionary","Cling should provide a way to revert transaction similar to rewinddictionary()");
3746#endif
3747#endif
3748}
3749
3750////////////////////////////////////////////////////////////////////////////////
3751/// Delete obj from Cling symbol table so it cannot be accessed anymore.
3752/// Returns 1 in case of success and 0 in case object was not in table.
3753
3755{
3756#if defined(R__MUST_REVISIT)
3757#if R__MUST_REVISIT(6,2)
3759 Warning("DeleteGlobal","Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3760#endif
3761#endif
3762 return 0;
3763}
3764
3765////////////////////////////////////////////////////////////////////////////////
3766/// Undeclare obj called name.
3767/// Returns 1 in case of success, 0 for failure.
3768
3770{
3771#if defined(R__MUST_REVISIT)
3772#if R__MUST_REVISIT(6,2)
3773 Warning("DeleteVariable","should do more that just reseting the value to zero");
3774#endif
3775#endif
3776
3778 llvm::StringRef srName(name);
3779 const char* unscopedName = name;
3780 llvm::StringRef::size_type posScope = srName.rfind("::");
3781 const clang::DeclContext* declCtx = nullptr;
3782 if (posScope != llvm::StringRef::npos) {
3783 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3784 const clang::Decl* scopeDecl
3785 = lh.findScope(srName.substr(0, posScope),
3786 cling::LookupHelper::WithDiagnostics);
3787 if (!scopeDecl) {
3788 Error("DeleteVariable", "Cannot find enclosing scope for variable %s",
3789 name);
3790 return 0;
3791 }
3792 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3793 if (!declCtx) {
3794 Error("DeleteVariable",
3795 "Enclosing scope for variable %s is not a declaration context",
3796 name);
3797 return 0;
3798 }
3799 unscopedName += posScope + 2;
3800 }
3801 // Could trigger deserialization of decls.
3802 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
3803 clang::NamedDecl* nVarDecl
3804 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3805 if (!nVarDecl) {
3806 Error("DeleteVariable", "Unknown variable %s", name);
3807 return 0;
3808 }
3809 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3810 if (!varDecl) {
3811 Error("DeleteVariable", "Entity %s is not a variable", name);
3812 return 0;
3813 }
3814
3815 clang::QualType qType = varDecl->getType();
3816 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3817 // Cannot set a reference's address to nullptr; the JIT can place it
3818 // into read-only memory (ROOT-7100).
3819 if (type->isPointerType()) {
3820 int** ppInt = (int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
3821 // set pointer to invalid.
3822 if (ppInt) *ppInt = nullptr;
3823 }
3824 return 1;
3825}
3826
3827////////////////////////////////////////////////////////////////////////////////
3828/// Save the current Cling state.
3829
3831{
3832#if defined(R__MUST_REVISIT)
3833#if R__MUST_REVISIT(6,2)
3835 Warning("SaveContext","Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
3836#endif
3837#endif
3838}
3839
3840////////////////////////////////////////////////////////////////////////////////
3841/// Save the current Cling state of global objects.
3842
3844{
3845#if defined(R__MUST_REVISIT)
3846#if R__MUST_REVISIT(6,2)
3848 Warning("SaveGlobalsContext","Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
3849#endif
3850#endif
3851}
3852
3853////////////////////////////////////////////////////////////////////////////////
3854/// No op: see TClingCallbacks (used to update the list of globals)
3855
3857{
3858}
3859
3860////////////////////////////////////////////////////////////////////////////////
3861/// No op: see TClingCallbacks (used to update the list of global functions)
3862
3864{
3865}
3866
3867////////////////////////////////////////////////////////////////////////////////
3868/// No op: see TClingCallbacks (used to update the list of types)
3869
3871{
3872}
3873
3874////////////////////////////////////////////////////////////////////////////////
3875/// Check in what order the member of a tuple are layout.
3876enum class ETupleOrdering {
3877 kAscending,
3880};
3881
3883{
3886};
3887
3889{
3892};
3893
3895{
3896 std::tuple<int,double> value;
3899
3900 size_t offset0 = ((char*)&(std::get<0>(value))) - ((char*)&value);
3901 size_t offset1 = ((char*)&(std::get<1>(value))) - ((char*)&value);
3902
3903 size_t ascOffset0 = ((char*)&(asc._0)) - ((char*)&asc);
3904 size_t ascOffset1 = ((char*)&(asc._1)) - ((char*)&asc);
3905
3906 size_t desOffset0 = ((char*)&(des._0)) - ((char*)&des);
3907 size_t desOffset1 = ((char*)&(des._1)) - ((char*)&des);
3908
3909 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
3911 } else if (offset0 == desOffset0 && offset1 == desOffset1) {
3913 } else {
3915 }
3916}
3917
3918static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh, Bool_t silent)
3919{
3920 TClassEdit::TSplitType tupleContent(classname);
3921 std::string alternateName = "TEmulatedTuple";
3922 alternateName.append( classname + 5 );
3923
3924 std::string fullname = "ROOT::Internal::" + alternateName;
3925 if (lh.findScope(fullname, cling::LookupHelper::NoDiagnostics,
3926 /*resultType*/nullptr, /* intantiateTemplate= */ false))
3927 return fullname;
3928
3929 {
3930 // Check if we can produce the tuple
3931 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
3932 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
3933 auto deleter = [](TypeInfo_t *type) {
3934 gInterpreter->TypeInfo_Delete(type);
3935 };
3936 std::unique_ptr<TypeInfo_t, decltype(deleter)> type{ gInterpreter->TypeInfo_Factory(), deleter };
3937 while (iter != theEnd) {
3938 gInterpreter->TypeInfo_Init(type.get(), iter->c_str());
3939 if (gInterpreter->TypeInfo_Property(type.get()) & kIsNotReacheable) {
3940 if (!silent)
3941 Error("Load","Could not declare alternate type for %s since %s (or one of its context) is private or protected",
3942 classname, iter->c_str());
3943 return "";
3944 }
3945 ++iter;
3946 }
3947 }
3948
3949 std::string guard_name;
3950 ROOT::TMetaUtils::GetCppName(guard_name,alternateName.c_str());
3951 std::ostringstream guard;
3952 guard << "ROOT_INTERNAL_TEmulated_";
3953 guard << guard_name;
3954
3955 std::ostringstream alternateTuple;
3956 alternateTuple << "#ifndef " << guard.str() << "\n";
3957 alternateTuple << "#define " << guard.str() << "\n";
3958 alternateTuple << "namespace ROOT { namespace Internal {\n";
3959 alternateTuple << "template <class... Types> struct TEmulatedTuple;\n";
3960 alternateTuple << "template <> struct " << alternateName << " {\n";
3961
3962 // This could also be a compile time choice ...
3963 switch(IsTupleAscending()) {
3965 unsigned int nMember = 0;
3966 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
3967 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
3968 while (iter != theEnd) {
3969 alternateTuple << " " << *iter << " _" << nMember << ";\n";
3970 ++iter;
3971 ++nMember;
3972 }
3973 break;
3974 }
3976 unsigned int nMember = tupleContent.fElements.size() - 3;
3977 auto iter = tupleContent.fElements.rbegin() + 1; // skip the 'stars'.
3978 auto theEnd = tupleContent.fElements.rend() - 1; // Skip the template name (tuple).
3979 while (iter != theEnd) {
3980 alternateTuple << " " << *iter << " _" << nMember << ";\n";
3981 ++iter;
3982 --nMember;
3983 }
3984 break;
3985 }
3987 Fatal("TCling::SetClassInfo::AlternateTuple",
3988 "Layout of std::tuple on this platform is unexpected.");
3989 break;
3990 }
3991 }
3992
3993 alternateTuple << "};\n";
3994 alternateTuple << "}}\n";
3995 alternateTuple << "#endif\n";
3996 if (!gCling->Declare(alternateTuple.str().c_str()))
3997 {
3998 // Declare is not silent (yet?), so add an explicit error message
3999 // to indicate the consequence of the syntax errors.
4000 Error("Load","Could not declare %s",alternateName.c_str());
4001 return "";
4002 }
4003 alternateName = "ROOT::Internal::" + alternateName;
4004 return alternateName;
4005}
4006
4007////////////////////////////////////////////////////////////////////////////////
4008/// Set pointer to the TClingClassInfo in TClass.
4009/// If 'reload' is true, (attempt to) generate a new ClassInfo even if we
4010/// already have one.
4011
4012void TCling::SetClassInfo(TClass* cl, Bool_t reload, Bool_t silent)
4013{
4014 // We are shutting down, there is no point in reloading, it only triggers
4015 // redundant deserializations.
4016 if (fIsShuttingDown) {
4017 // Remove the decl_id from the DeclIdToTClass map
4018 if (cl->fClassInfo) {
4020 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4021 // Test again as another thread may have set fClassInfo to nullptr.
4022 if (TClinginfo) {
4023 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4024 }
4025 delete TClinginfo;
4026 cl->fClassInfo = nullptr;
4027 }
4028 return;
4029 }
4030
4032 if (cl->fClassInfo && !reload) {
4033 return;
4034 }
4035 //Remove the decl_id from the DeclIdToTClass map
4036 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4037 if (TClinginfo) {
4038 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4039 }
4040 delete TClinginfo;
4041 cl->fClassInfo = nullptr;
4042 std::string name(cl->GetName());
4043
4044 auto SetWithoutClassInfoState = [](TClass *cl)
4045 {
4046 if (cl->fState != TClass::kHasTClassInit) {
4047 if (cl->fStreamerInfo->GetEntries() != 0) {
4049 } else {
4051 }
4052 }
4053 };
4054 // Handle the special case of 'tuple' where we ignore the real implementation
4055 // details and just overlay a 'simpler'/'simplistic' version that is easy
4056 // for the I/O to understand and handle.
4057 if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
4058 if (!reload)
4059 name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper(), silent);
4060 if (reload || name.empty()) {
4061 // We could not generate the alternate
4062 SetWithoutClassInfoState(cl);
4063 return;
4064 }
4065 }
4066
4067 bool instantiateTemplate = !cl->TestBit(TClass::kUnloading);
4068 // FIXME: Rather than adding an option to the TClingClassInfo, we should consider combining code
4069 // that is currently in the caller (like SetUnloaded) that disable AutoLoading and AutoParsing and
4070 // code is in the callee (disabling template instantiation) and end up with a more explicit class:
4071 // TClingClassInfoReadOnly.
4072 TClingClassInfo* info = new TClingClassInfo(GetInterpreterImpl(), name.c_str(), instantiateTemplate);
4073 if (!info->IsValid()) {
4074 SetWithoutClassInfoState(cl);
4075 delete info;
4076 return;
4077 }
4078 cl->fClassInfo = (ClassInfo_t*)info; // Note: We are transferring ownership here.
4079 // In case a class contains an external enum, the enum will be seen as a
4080 // class. We must detect this special case and make the class a Zombie.
4081 // Here we assume that a class has at least one method.
4082 // We can NOT call TClass::Property from here, because this method
4083 // assumes that the TClass is well formed to do a lot of information
4084 // caching. The method SetClassInfo (i.e. here) is usually called during
4085 // the building phase of the TClass, hence it is NOT well formed yet.
4086 Bool_t zombieCandidate = kFALSE;
4087 if (
4088 info->IsValid() &&
4089 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
4090 ) {
4091 zombieCandidate = kTRUE;
4092 }
4093 if (!info->IsLoaded()) {
4094 if (info->Property() & (kIsNamespace)) {
4095 // Namespaces can have info but no corresponding CINT dictionary
4096 // because they are auto-created if one of their contained
4097 // classes has a dictionary.
4098 zombieCandidate = kTRUE;
4099 }
4100 // this happens when no dictionary is available
4101 delete info;
4102 cl->fClassInfo = nullptr;
4103 }
4104 if (zombieCandidate && !cl->GetCollectionType()) {
4105 cl->MakeZombie();
4106 }
4107 // If we reach here, the info was valid (See early returns).
4108 if (cl->fState != TClass::kHasTClassInit) {
4109 if (cl->fClassInfo) {
4111 } else {
4112// if (TClassEdit::IsSTLCont(cl->GetName()) {
4113// There will be an emulated collection proxy, is that the same?
4114// cl->fState = TClass::kEmulated;
4115// } else {
4116 if (cl->fStreamerInfo->GetEntries() != 0) {
4118 } else {
4120 }
4121// }
4122 }
4123 }
4124 if (cl->fClassInfo) {
4125 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
4126 }
4127}
4128
4129////////////////////////////////////////////////////////////////////////////////
4130/// Checks if an entity with the specified name is defined in Cling.
4131/// Returns kUnknown if the entity is not defined.
4132/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
4133/// Returns kKnown if the entity is defined.
4134///
4135/// By default, structs, namespaces, classes, enums and unions are looked for.
4136/// If the flag isClassOrNamespaceOnly is true, classes, structs and
4137/// namespaces only are considered. I.e. if the name is an enum or a union,
4138/// the returned value is false.
4139///
4140/// In the case where the class is not loaded and belongs to a namespace
4141/// or is nested, looking for the full class name is outputting a lots of
4142/// (expected) error messages. Currently the only way to avoid this is to
4143/// specifically check that each level of nesting is already loaded.
4144/// In case of templates the idea is that everything between the outer
4145/// '<' and '>' has to be skipped, e.g.: `aap<pippo<noot>::klaas>::a_class`
4146
4148TCling::CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly /* = kFALSE*/)
4149{
4151 static const char *anonEnum = "anonymous enum ";
4152 static const int cmplen = strlen(anonEnum);
4153
4154 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
4155 return kUnknown;
4156 }
4157
4158 // Do not turn on the AutoLoading if it is globally off.
4159 autoload = autoload && IsClassAutoLoadingEnabled();
4160
4161 // Avoid the double search below in case the name is a fundamental type
4162 // or typedef to a fundamental type.
4163 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
4164 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
4165
4166 if (fundType && fundType->GetType() < TVirtualStreamerInfo::kObject
4167 && fundType->GetType() > 0) {
4168 // Fundamental type, no a class.
4169 return kUnknown;
4170 }
4171
4172 // Migrated from within TClass::GetClass
4173 // If we want to know if a class or a namespace with this name exists in the
4174 // interpreter and this is an enum in the type system, before or after loading
4175 // according to the autoload function argument, return kUnknown.
4176 if (isClassOrNamespaceOnly && TEnum::GetEnum(name, autoload ? TEnum::kAutoload : TEnum::kNone))
4177 return kUnknown;
4178
4179 const char *classname = name;
4180
4181 // RAII to suspend and restore auto-loading and auto-parsing based on some external conditions.
4182 class MaybeSuspendAutoLoadParse {
4183 int fStoreAutoLoad = 0;
4184 int fStoreAutoParse = 0;
4185 bool fSuspendedAutoParse = false;
4186 public:
4187 MaybeSuspendAutoLoadParse(int autoload) {
4188 fStoreAutoLoad = ((TCling*)gCling)->SetClassAutoLoading(autoload);
4189 }
4190
4191 void SuspendAutoParsing() {
4192 fSuspendedAutoParse = true;
4193 fStoreAutoParse = ((TCling*)gCling)->SetSuspendAutoParsing(true);
4194 }
4195
4196 ~MaybeSuspendAutoLoadParse() {
4197 if (fSuspendedAutoParse)
4198 ((TCling*)gCling)->SetSuspendAutoParsing(fStoreAutoParse);
4199 ((TCling*)gCling)->SetClassAutoLoading(fStoreAutoLoad);
4200 }
4201 };
4202
4203 MaybeSuspendAutoLoadParse autoLoadParseRAII( autoload );
4204 if (TClassEdit::IsStdPair(classname) || TClassEdit::IsStdPairBase(classname))
4205 autoLoadParseRAII.SuspendAutoParsing();
4206
4207 // First we want to check whether the decl exist, but _without_
4208 // generating any template instantiation. However, the lookup
4209 // still will create a forward declaration of the class template instance
4210 // if it exist. In this case, the return value of findScope will still
4211 // be zero but the type will be initialized.
4212 // Note in the corresponding code in ROOT 5, CINT was not instantiating
4213 // this forward declaration.
4214 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4215 const clang::Type *type = nullptr;
4216 const clang::Decl *decl
4217 = lh.findScope(classname,
4218 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4219 : cling::LookupHelper::NoDiagnostics,
4220 &type, /* intantiateTemplate= */ false );
4221 if (!decl) {
4222 std::string buf = TClassEdit::InsertStd(classname);
4223 decl = lh.findScope(buf,
4224 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4225 : cling::LookupHelper::NoDiagnostics,
4226 &type,false);
4227 }
4228
4229 if (type) {
4230 // If decl==0 and the type is valid, then we have a forward declaration.
4231 if (!decl) {
4232 // If we have a forward declaration for a class template instantiation,
4233 // we want to ignore it if it was produced/induced by the call to
4234 // findScope, however we can not distinguish those from the
4235 // instantiation induce by 'soft' use (and thus also induce by the
4236 // same underlying code paths)
4237 // ['soft' use = use not requiring a complete definition]
4238 // So to reduce the amount of disruption to the existing code we
4239 // would just ignore those for STL collection, for which we really
4240 // need to have the compiled collection proxy (and thus the TClass
4241 // bootstrap).
4242 clang::ClassTemplateSpecializationDecl *tmpltDecl =
4243 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
4244 (type->getAsCXXRecordDecl());
4245 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
4246 // Since the point of instantiation is invalid, we 'guess' that
4247 // the 'instantiation' of the forwarded type appended in
4248 // findscope.
4249 if (ROOT::TMetaUtils::IsSTLCont(*tmpltDecl)) {
4250 // For STL Collection we return kUnknown.
4251 return kUnknown;
4252 }
4253 }
4254 }
4256 if (!tci.IsValid()) {
4257 return kUnknown;
4258 }
4259 auto propertiesMask = isClassOrNamespaceOnly ? kIsClass | kIsStruct | kIsNamespace :
4261
4262 if (tci.Property() & propertiesMask) {
4263 bool hasClassDefInline = false;
4264 if (isClassOrNamespaceOnly) {
4265 // We do not need to check for ClassDefInline when this is called from
4266 // TClass::Init, we only do it for the call from TClass::GetClass.
4267 auto hasDictionary = tci.GetMethod("Dictionary", "", false, nullptr, ROOT::kExactMatch);
4268 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, nullptr, ROOT::kExactMatch);
4269
4270 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
4271 int lineNumber = 0;
4272 bool success = false;
4273 std::tie(success, lineNumber) =
4274 ROOT::TMetaUtils::GetTrivialIntegralReturnValue(implLineFunc.GetAsFunctionDecl(), *fInterpreter);
4275 hasClassDefInline = success && (lineNumber == -1);
4276 }
4277 }
4278
4279 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
4280 // , hasClassDefInline);
4281
4282 // We are now sure that the entry is not in fact an autoload entry.
4283 if (hasClassDefInline)
4284 return kWithClassDefInline;
4285 else
4286 return kKnown;
4287 } else {
4288 // We are now sure that the entry is not in fact an autoload entry.
4289 return kUnknown;
4290 }
4291 }
4292
4293 if (decl)
4294 return kKnown;
4295 else
4296 return kUnknown;
4297
4298 // Setting up iterator part of TClingTypedefInfo is too slow.
4299 // Copy the lookup code instead:
4300 /*
4301 TClingTypedefInfo t(fInterpreter, name);
4302 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
4303 delete[] classname;
4304 return kTRUE;
4305 }
4306 */
4307
4308// const clang::Decl *decl = lh.findScope(name);
4309// if (!decl) {
4310// std::string buf = TClassEdit::InsertStd(name);
4311// decl = lh.findScope(buf);
4312// }
4313
4314// return (decl);
4315}
4316
4317////////////////////////////////////////////////////////////////////////////////
4318/// Return true if there is a class template by the given name ...
4319
4321{
4322 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4323 // Interpreter transaction ahead, needs locking
4325 const clang::Decl *decl
4326 = lh.findClassTemplate(name,
4327 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4328 : cling::LookupHelper::NoDiagnostics);
4329 if (!decl) {
4330 std::string strname = "std::";
4331 strname += name;
4332 decl = lh.findClassTemplate(strname,
4333 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4334 : cling::LookupHelper::NoDiagnostics);
4335 }
4336 return nullptr != decl;
4337}
4338
4339////////////////////////////////////////////////////////////////////////////////
4340/// Create list of pointers to base class(es) for TClass cl.
4341
4343{
4345 if (cl->fBase) {
4346 return;
4347 }
4349 if (!tci) return;
4351 TList *listOfBase = new TList;
4352 while (t.Next()) {
4353 // if name cannot be obtained no use to put in list
4354 if (t.IsValid() && t.Name()) {
4356 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
4357 }
4358 }
4359 // Now that is complete, publish it.
4360 cl->fBase = listOfBase;
4361}
4362
4363////////////////////////////////////////////////////////////////////////////////
4364/// Create list of pointers to enums for TClass cl.
4365
4366void TCling::LoadEnums(TListOfEnums& enumList) const
4367{
4369
4370 const Decl * D;
4371 TClass* cl = enumList.GetClass();
4372 if (cl) {
4373 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4374 }
4375 else {
4376 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4377 }
4378 // Iterate on the decl of the class and get the enums.
4379 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4380 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4381 // Collect all contexts of the namespace.
4382 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4383 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4384 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(), declEnd = allDeclContexts.end();
4385 declIter != declEnd; ++declIter) {
4386 // Iterate on all decls for each context.
4387 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4388 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4389 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4390 // Get name of the enum type.
4391 std::string buf;
4392 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4393 llvm::raw_string_ostream stream(buf);
4394 // Don't trigger fopen of the source file to count lines:
4395 Policy.AnonymousTagLocations = false;
4396 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
4397 stream.flush();
4398 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
4399 if (!buf.empty()) {
4400 const char* name = buf.c_str();
4401 // Add the enum to the list of loaded enums.
4402 enumList.Get(ED, name);
4403 }
4404 }
4405 }
4406 }
4407 }
4408}
4409
4410////////////////////////////////////////////////////////////////////////////////
4411/// Create list of pointers to function templates for TClass cl.
4412
4414{
4416
4417 const Decl * D;
4418 TListOfFunctionTemplates* funcTempList;
4419 if (cl) {
4420 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4421 funcTempList = (TListOfFunctionTemplates*)cl->GetListOfFunctionTemplates(false);
4422 }
4423 else {
4424 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4425 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4426 }
4427 // Iterate on the decl of the class and get the enums.
4428 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4429 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4430 // Collect all contexts of the namespace.
4431 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4432 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4433 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(),
4434 declEnd = allDeclContexts.end(); declIter != declEnd; ++declIter) {
4435 // Iterate on all decls for each context.
4436 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4437 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4438 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4439 funcTempList->Get(FTD);
4440 }
4441 }
4442 }
4443 }
4444}
4445
4446////////////////////////////////////////////////////////////////////////////////
4447/// Get the scopes representing using declarations of namespace
4448
4449std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4450{
4452 return ci->GetUsingNamespaces();
4453}
4454
4455////////////////////////////////////////////////////////////////////////////////
4456/// Create list of pointers to data members for TClass cl.
4457/// This is now a nop. The creation and updating is handled in
4458/// TListOfDataMembers.
4459
4461{
4462}
4463
4464////////////////////////////////////////////////////////////////////////////////
4465/// Create list of pointers to methods for TClass cl.
4466/// This is now a nop. The creation and updating is handled in
4467/// TListOfFunctions.
4468
4470{
4471}
4472
4473////////////////////////////////////////////////////////////////////////////////
4474/// Update the list of pointers to method for TClass cl
4475/// This is now a nop. The creation and updating is handled in
4476/// TListOfFunctions.
4477
4479{
4480}
4481
4482////////////////////////////////////////////////////////////////////////////////
4483/// Update the list of pointers to data members for TClass cl
4484/// This is now a nop. The creation and updating is handled in
4485/// TListOfDataMembers.
4486
4488{
4489}
4490
4491////////////////////////////////////////////////////////////////////////////////
4492/// Create list of pointers to method arguments for TMethod m.
4493
4495{
4497 if (m->fMethodArgs) {
4498 return;
4499 }
4500 TList *arglist = new TList;
4502 while (t.Next()) {
4503 if (t.IsValid()) {
4505 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4506 }
4507 }
4508 m->fMethodArgs = arglist;
4509}
4510
4511////////////////////////////////////////////////////////////////////////////////
4512/// Return whether we are waiting for more input either because the collected
4513/// input contains unbalanced braces or last seen token was a `\` (backslash-newline)
4514
4516{
4517 return fMetaProcessor->awaitingMoreInput();
4518}
4519
4520////////////////////////////////////////////////////////////////////////////////
4521/// Generate a TClass for the given class.
4522/// Since the caller has already check the ClassInfo, let it give use the
4523/// result (via the value of emulation) rather than recalculate it.
4524
4525TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4526{
4527// For now the following line would lead to the (unwanted) instantiation
4528// of class template. This could/would need to be resurrected only if
4529// we re-introduce so sort of automatic instantiation. However this would
4530// have to include carefull look at the template parameter to avoid
4531// creating instance we can not really use (if the parameter are only forward
4532// declaration or do not have all the necessary interfaces).
4533
4534 // TClingClassInfo tci(fInterpreter, classname);
4535 // if (1 || !tci.IsValid()) {
4536
4537 Version_t version = 1;
4538 if (TClassEdit::IsSTLCont(classname)) {
4539 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4540 }
4542 TClass *cl = new TClass(classname, version, silent);
4543 if (!emulation) {
4544 // Set the class version if the class is versioned.
4545 // Note that we cannot just call CLASS::Class_Version() as we might not have
4546 // an execution engine (when invoked from rootcling).
4547
4548 // Do not call cl->GetClassVersion(), it has side effects!
4549 Version_t oldvers = cl->fClassVersion;
4550 if (oldvers == version && cl->GetClassInfo()) {
4551 // We have a version and it might need an update.
4553 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4554 // Namespaces don't have class versions.
4555 return cl;
4556 }
4557 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", nullptr /*poffset*/,
4560 if (!mi.IsValid()) {
4561 if (cl->TestBit(TClass::kIsTObject)) {
4562 Error("GenerateTClass",
4563 "Cannot find %s::Class_Version()! Class version might be wrong.",
4564 cl->GetName());
4565 }
4566 return cl;
4567 }
4568 Version_t newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4569 *fInterpreter);
4570 if (newvers == -1) {
4571 // Didn't manage to determine the class version from the AST.
4572 // Use runtime instead.
4573 if ((mi.Property() & kIsStatic)
4574 && !fInterpreter->isInSyntaxOnlyMode()) {
4575 // This better be a static function.
4577 callfunc.SetFunc(&mi);
4578 newvers = callfunc.ExecInt(nullptr);
4579 } else {
4580 Error("GenerateTClass",
4581 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4582 cl->GetName());
4583 }
4584 }
4585 if (newvers != oldvers) {
4586 cl->fClassVersion = newvers;
4587 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4588 }
4589 }
4590 }
4591
4592 return cl;
4593
4594// } else {
4595// return GenerateTClass(&tci,silent);
4596// }
4597}
4598
4599#if 0
4600////////////////////////////////////////////////////////////////////////////////
4601
4602static void GenerateTClass_GatherInnerIncludes(cling::Interpreter *interp, TString &includes,TClingClassInfo *info)
4603{
4604 includes += info->FileName();
4605
4606 const clang::ClassTemplateSpecializationDecl *templateCl
4607 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4608 if (templateCl) {
4609 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4610 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4611 if (arg.getKind() == clang::TemplateArgument::Type) {
4612 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4613
4614 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4615 // We really need a header file.
4616 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4617 if (argdecl) {
4618 includes += ";";
4619 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4620 GenerateTClass_GatherInnerIncludes(interp, includes, &subinfo);
4621 } else {
4622 std::string Result;
4623 llvm::raw_string_ostream OS(Result);
4624 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4625 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4626 }
4627 }
4628 }
4629 }
4630 }
4631}
4632#endif
4633
4634////////////////////////////////////////////////////////////////////////////////
4635/// Generate a TClass for the given class.
4636
4637TClass *TCling::GenerateTClass(ClassInfo_t *classinfo, Bool_t silent /* = kFALSE */)
4638{
4639 TClingClassInfo *info = (TClingClassInfo*)classinfo;
4640 if (!info || !info->IsValid()) {
4641 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4642 return nullptr;
4643 }
4644 // We are in the case where we have AST nodes for this class.
4645 TClass *cl = nullptr;
4646 std::string classname;
4647 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4648 if (TClassEdit::IsSTLCont(classname)) {
4649#if 0
4650 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4651 // We need to build up the list of required headers, by
4652 // looking at each template arguments.
4653 TString includes;
4654 GenerateTClass_GatherInnerIncludes(fInterpreter,includes,info);
4655
4656 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4657 // 0 means success.
4658 cl = TClass::LoadClass(classnam.c_str(), silent);
4659 if (cl == 0) {
4660 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4661 }
4662 }
4663#endif
4664 if (cl == nullptr) {
4665 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4666 cl = new TClass(classinfo, version, nullptr, nullptr, -1, -1, silent);
4667 }
4668 } else {
4669 // For regular class, just create a TClass on the fly ...
4670 // Not quite useful yet, but that what CINT used to do anyway.
4671 cl = new TClass(classinfo, 1, nullptr, nullptr, -1, -1, silent);
4672 }
4673 // Add the new TClass to the map of declid and TClass*.
4674 if (cl) {
4676 }
4677 return cl;
4678}
4679
4680////////////////////////////////////////////////////////////////////////////////
4681/// Generate the dictionary for the C++ classes listed in the first
4682/// argument (in a semi-colon separated list).
4683/// 'includes' contains a semi-colon separated list of file to
4684/// `#include` in the dictionary.
4685/// For example:
4686/// ~~~ {.cpp}
4687/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4688/// ~~~
4689/// or
4690/// ~~~ {.cpp}
4691/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4692/// ~~~
4693
4694Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4695{
4696 if (classes == nullptr || classes[0] == 0) {
4697 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4698 return 0;
4699 }
4700 // Split the input list
4701 std::vector<std::string> listClasses;
4702 for (
4703 const char* current = classes, *prev = classes;
4704 *current != 0;
4705 ++current
4706 ) {
4707 if (*current == ';') {
4708 listClasses.push_back(std::string(prev, current - prev));
4709 prev = current + 1;
4710 }
4711 else if (*(current + 1) == 0) {
4712 listClasses.push_back(std::string(prev, current + 1 - prev));
4713 prev = current + 1;
4714 }
4715 }
4716 std::vector<std::string> listIncludes;
4717 if (!includes)
4718 includes = "";
4719 for (
4720 const char* current = includes, *prev = includes;
4721 *current != 0;
4722 ++current
4723 ) {
4724 if (*current == ';') {
4725 listIncludes.push_back(std::string(prev, current - prev));
4726 prev = current + 1;
4727 }
4728 else if (*(current + 1) == 0) {
4729 listIncludes.push_back(std::string(prev, current + 1 - prev));
4730 prev = current + 1;
4731 }
4732 }
4733 // Generate the temporary dictionary file
4734 return !TCling_GenerateDictionary(listClasses, listIncludes,
4735 std::vector<std::string>(), std::vector<std::string>());
4736}
4737
4738////////////////////////////////////////////////////////////////////////////////
4739/// Return pointer to cling Decl of global/static variable that is located
4740/// at the address given by addr.
4741
4742TInterpreter::DeclId_t TCling::GetDataMember(ClassInfo_t *opaque_cl, const char *name) const
4743{
4745 DeclId_t d;
4746 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4747
4748 // Could trigger deserialization of decls.
4749 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4750
4751 if (cl) {
4752 d = cl->GetDataMember(name);
4753 // We check if the decl of the data member has an annotation which indicates
4754 // an ioname.
4755 // In case this is true, if the name requested is not the ioname, we
4756 // return 0, as if the member did not exist. In some sense we override
4757 // the information in the TClassInfo instance, isolating the typesystem in
4758 // TClass from the one in the AST.
4759 if (const ValueDecl* decl = (const ValueDecl*) d){
4760 std::string ioName;
4761 bool hasIoName = ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"ioname",ioName);
4762 if (hasIoName && ioName != name) return nullptr;
4763 }
4764 return d;
4765 }
4766 // We are looking up for something on the TU scope.
4767 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
4768 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
4769 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
4770 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
4771 // are only fulfilling ROOT's understanding for a Data Member.
4772 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
4773 // similar as below.
4774 using namespace clang;
4775 Sema& SemaR = fInterpreter->getSema();
4776 DeclarationName DName = &SemaR.Context.Idents.get(name);
4777
4778 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
4779 Sema::ForExternalRedeclaration);
4780
4781 cling::utils::Lookup::Named(&SemaR, R);
4782
4783 LookupResult::Filter F = R.makeFilter();
4784 // Filter the data-member looking decls.
4785 while (F.hasNext()) {
4786 NamedDecl *D = F.next();
4787 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) ||
4788 isa<IndirectFieldDecl>(D))
4789 continue;
4790 F.erase();
4791 }
4792 F.done();
4793
4794 if (R.isSingleResult())
4795 return R.getFoundDecl();
4796 return nullptr;
4797}
4798
4799////////////////////////////////////////////////////////////////////////////////
4800/// Return pointer to cling Decl of global/static variable that is located
4801/// at the address given by addr.
4802
4804{
4806
4807 const clang::Decl* possibleEnum = nullptr;
4808 // FInd the context of the decl.
4809 if (cl) {
4811 if (cci) {
4812 const clang::DeclContext* dc = nullptr;
4813 if (const clang::Decl* D = cci->GetDecl()) {
4814 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
4815 dc = dyn_cast<clang::RecordDecl>(D);
4816 }
4817 }
4818 if (dc) {
4819 // If it is a data member enum.
4820 // Could trigger deserialization of decls.
4821 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4822 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
4823 } else {
4824 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
4825 }
4826 }
4827 } else {
4828 // If it is a global enum.
4829 // Could trigger deserialization of decls.
4830 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4831 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
4832 }
4833 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
4834 && isa<clang::EnumDecl>(possibleEnum)) {
4835 return possibleEnum;
4836 }
4837 return nullptr;
4838}
4839
4840////////////////////////////////////////////////////////////////////////////////
4841/// Return pointer to cling DeclId for a global value
4842
4843TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
4844{
4845 if (!gv) return nullptr;
4846
4847 llvm::StringRef mangled_name = gv->getName();
4848
4849 int err = 0;
4850 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.str().c_str(), err);
4851 if (err) {
4852 if (err == -2) {
4853 // It might simply be an unmangled global name.
4854 DeclId_t d;
4856 d = gcl.GetDataMember(mangled_name.str().c_str());
4857 return d;
4858 }
4859 return nullptr;
4860 }
4861
4862 std::string scopename(demangled_name_c);
4863 free(demangled_name_c);
4864
4865 //
4866 // Separate out the class or namespace part of the
4867 // function name.
4868 //
4869 std::string dataname;
4870
4871 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
4872 scopename.erase(0, sizeof("typeinfo for ")-1);
4873 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
4874 scopename.erase(0, sizeof("vtable for ")-1);
4875 } else {
4876 // See if it is a function
4877 std::string::size_type pos = scopename.rfind('(');
4878 if (pos != std::string::npos) {
4879 return nullptr;
4880 }
4881 // Separate the scope and member name
4882 pos = scopename.rfind(':');
4883 if (pos != std::string::npos) {
4884 if ((pos != 0) && (scopename[pos-1] == ':')) {
4885 dataname = scopename.substr(pos+1);
4886 scopename.erase(pos-1);
4887 }
4888 } else {
4889 scopename.clear();
4890 dataname = scopename;
4891 }
4892 }
4893 //fprintf(stderr, "name: '%s'\n", name.c_str());
4894 // Now we have the class or namespace name, so do the lookup.
4895
4896
4897 DeclId_t d;
4898 if (scopename.size()) {
4899 TClingClassInfo cl(GetInterpreterImpl(), scopename.c_str());
4900 d = cl.GetDataMember(dataname.c_str());
4901 }
4902 else {
4904 d = gcl.GetDataMember(dataname.c_str());
4905 }
4906 return d;
4907}
4908
4909////////////////////////////////////////////////////////////////////////////////
4910/// NOT IMPLEMENTED.
4911
4913{
4914 Error("GetDataMemberWithValue()", "not implemented");
4915 return nullptr;
4916}
4917
4918////////////////////////////////////////////////////////////////////////////////
4919/// Return pointer to cling DeclId for a data member with a given name.
4920
4922{
4923 // NOT IMPLEMENTED.
4924 Error("GetDataMemberAtAddr()", "not implemented");
4925 return nullptr;
4926}
4927
4928////////////////////////////////////////////////////////////////////////////////
4929/// Return the cling mangled name for a method of a class with parameters
4930/// params (params is a string of actual arguments, not formal ones). If the
4931/// class is 0 the global function list will be searched.
4932
4933TString TCling::GetMangledName(TClass* cl, const char* method,
4934 const char* params, Bool_t objectIsConst /* = kFALSE */)
4935{
4938 if (cl) {
4940 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4941 &offset);
4942 }
4943 else {
4946 func.SetFunc(&gcl, method, params, &offset);
4947 }
4949 if (!mi) return "";
4950 TString mangled_name( mi->GetMangledName() );
4951 delete mi;
4952 return mangled_name;
4953}
4954
4955////////////////////////////////////////////////////////////////////////////////
4956/// Return the cling mangled name for a method of a class with a certain
4957/// prototype, i.e. "char*,int,float". If the class is 0 the global function
4958/// list will be searched.
4959
4961 const char* proto, Bool_t objectIsConst /* = kFALSE */,
4962 EFunctionMatchMode mode /* = kConversionMatch */)
4963{
4965 if (cl) {
4966 return ((TClingClassInfo*)cl->GetClassInfo())->
4967 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
4968 }
4970 return gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
4971}
4972
4973////////////////////////////////////////////////////////////////////////////////
4974/// Return pointer to cling interface function for a method of a class with
4975/// parameters params (params is a string of actual arguments, not formal
4976/// ones). If the class is 0 the global function list will be searched.
4977
4978void* TCling::GetInterfaceMethod(TClass* cl, const char* method,
4979 const char* params, Bool_t objectIsConst /* = kFALSE */)
4980{
4983 if (cl) {
4985 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4986 &offset);
4987 }
4988 else {
4991 func.SetFunc(&gcl, method, params, &offset);
4992 }
4993 return (void*) func.InterfaceMethod();
4994}
4995
4996////////////////////////////////////////////////////////////////////////////////
4997/// Return pointer to cling interface function for a method of a class with
4998/// a certain name.
4999
5000TInterpreter::DeclId_t TCling::GetFunction(ClassInfo_t *opaque_cl, const char* method)
5001{
5003 DeclId_t f;
5004 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5005 if (cl) {
5006 f = cl->GetMethod(method).GetDeclId();
5007 }
5008 else {
5010 f = gcl.GetMethod(method).GetDeclId();
5011 }
5012 return f;
5013
5014}
5015
5016////////////////////////////////////////////////////////////////////////////////
5017/// Insert overloads of name in cl to res.
5018
5019void TCling::GetFunctionOverloads(ClassInfo_t *cl, const char *funcname,
5020 std::vector<DeclId_t>& res) const
5021{
5022 clang::Sema& S = fInterpreter->getSema();
5023 clang::ASTContext& Ctx = S.Context;
5024 const clang::Decl* CtxDecl
5025 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
5026 Ctx.getTranslationUnitDecl();
5027 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
5028 const clang::DeclContext* DeclCtx = RecDecl;
5029
5030 if (!DeclCtx)
5031 DeclCtx = dyn_cast<clang::NamespaceDecl>(CtxDecl);
5032 if (!DeclCtx) return;
5033
5034 clang::DeclarationName DName;
5035 // The DeclarationName is funcname, unless it's a ctor or dtor.
5036 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
5037
5038 if (RecDecl) {
5039 if (RecDecl->getNameAsString() == funcname) {
5040 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5041 DName = Ctx.DeclarationNames.getCXXConstructorName(Ctx.getCanonicalType(QT));
5042 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
5043 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5044 DName = Ctx.DeclarationNames.getCXXDestructorName(Ctx.getCanonicalType(QT));
5045 } else {
5046 DName = &Ctx.Idents.get(funcname);
5047 }
5048 } else {
5049 DName = &Ctx.Idents.get(funcname);
5050 }
5051
5052 // NotForRedeclaration: we want to find names in inline namespaces etc.
5053 clang::LookupResult R(S, DName, clang::SourceLocation(),
5054 Sema::LookupOrdinaryName, clang::Sema::NotForRedeclaration);
5055 R.suppressDiagnostics(); // else lookup with NotForRedeclaration will check access etc
5056 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
5057 if (R.empty()) return;
5058 R.resolveKind();
5059 res.reserve(res.size() + (R.end() - R.begin()));
5060 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
5061 IR != ER; ++IR) {
5062 if (const clang::FunctionDecl* FD
5063 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
5064 if (!FD->getDescribedFunctionTemplate()) {
5065 res.push_back(FD);
5066 }
5067 } else if (const auto *USD = llvm::dyn_cast<const clang::UsingShadowDecl>(*IR)) {
5068 // FIXME: multi-level using
5069 if (llvm::isa<clang::FunctionDecl>(USD->getTargetDecl())) {
5070 res.push_back(USD);
5071 }
5072 }
5073 }
5074}
5075
5076////////////////////////////////////////////////////////////////////////////////
5077/// Return pointer to cling interface function for a method of a class with
5078/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5079/// function list will be searched.
5080
5082 const char* proto,
5083 Bool_t objectIsConst /* = kFALSE */,
5084 EFunctionMatchMode mode /* = kConversionMatch */)
5085{
5087 void* f;
5088 if (cl) {
5089 f = ((TClingClassInfo*)cl->GetClassInfo())->
5090 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5091 }
5092 else {
5094 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5095 }
5096 return f;
5097}
5098
5099////////////////////////////////////////////////////////////////////////////////
5100/// Return pointer to cling DeclId for a method of a class with
5101/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5102/// function list will be searched.
5103
5104TInterpreter::DeclId_t TCling::GetFunctionWithValues(ClassInfo_t *opaque_cl, const char* method,
5105 const char* params,
5106 Bool_t objectIsConst /* = kFALSE */)
5107{
5109 DeclId_t f;
5110 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5111 if (cl) {
5112 f = cl->GetMethodWithArgs(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5113 }
5114 else {
5116 f = gcl.GetMethod(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5117 }
5118 return f;
5119}
5120
5121////////////////////////////////////////////////////////////////////////////////
5122/// Return pointer to cling interface function for a method of a class with
5123/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5124/// function list will be searched.
5125
5126TInterpreter::DeclId_t TCling::GetFunctionWithPrototype(ClassInfo_t *opaque_cl, const char* method,
5127 const char* proto,
5128 Bool_t objectIsConst /* = kFALSE */,
5129 EFunctionMatchMode mode /* = kConversionMatch */)
5130{
5132 DeclId_t f;
5133 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5134 if (cl) {
5135 f = cl->GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5136 }
5137 else {
5139 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5140 }
5141 return f;
5142}
5143
5144////////////////////////////////////////////////////////////////////////////////
5145/// Return pointer to cling interface function for a method of a class with
5146/// a certain name.
5147
5148TInterpreter::DeclId_t TCling::GetFunctionTemplate(ClassInfo_t *opaque_cl, const char* name)
5149{
5151 DeclId_t f;
5152 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5153 if (cl) {
5154 f = cl->GetFunctionTemplate(name);
5155 }
5156 else {
5158 f = gcl.GetFunctionTemplate(name);
5159 }
5160 return f;
5161
5162}
5163
5164////////////////////////////////////////////////////////////////////////////////
5165/// The 'name' is known to the interpreter, this function returns
5166/// the internal version of this name (usually just resolving typedefs)
5167/// This is used in particular to synchronize between the name used
5168/// by rootcling and by the run-time environment (TClass)
5169/// Return 0 if the name is not known.
5170
5171void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
5172{
5173 output.clear();
5174
5176
5178 if (!cl.IsValid()) {
5179 return ;
5180 }
5181 if (full) {
5183 return;
5184 }
5185 // Well well well, for backward compatibility we need to act a bit too
5186 // much like CINT.
5189
5190 return;
5191}
5192
5193////////////////////////////////////////////////////////////////////////////////
5194/// Execute a global function with arguments params.
5195///
5196/// FIXME: The cint-based version of this code does not check if the
5197/// SetFunc() call works, and does not do any real checking
5198/// for errors from the Exec() call. It did fetch the most
5199/// recent cint security error and return that in error, but
5200/// this does not really translate well to cling/clang. We
5201/// should enhance these interfaces so that we can report
5202/// compilation and runtime errors properly.
5203
5204void TCling::Execute(const char* function, const char* params, int* error)
5205{
5207 if (error) {
5208 *error = TInterpreter::kNoError;
5209 }
5211 Longptr_t offset = 0L;
5213 func.SetFunc(&cl, function, params, &offset);
5214 func.Exec(nullptr);
5215}
5216
5217////////////////////////////////////////////////////////////////////////////////
5218/// Execute a method from class cl with arguments params.
5219///
5220/// FIXME: The cint-based version of this code does not check if the
5221/// SetFunc() call works, and does not do any real checking
5222/// for errors from the Exec() call. It did fetch the most
5223/// recent cint security error and return that in error, but
5224/// this does not really translate well to cling/clang. We
5225/// should enhance these interfaces so that we can report
5226/// compilation and runtime errors properly.
5227
5228void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5229 const char* params, Bool_t objectIsConst, int* error)
5230{
5232 if (error) {
5233 *error = TInterpreter::kNoError;
5234 }
5235 // If the actual class of this object inherits 2nd (or more) from TObject,
5236 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5237 // hence gInterpreter->Execute will improperly correct the offset.
5238 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5239 Longptr_t offset = 0L;
5241 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst, &offset);
5242 void* address = (void*)((Longptr_t)addr + offset);
5243 func.Exec(address);
5244}
5245
5246////////////////////////////////////////////////////////////////////////////////
5247
5248void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5249 const char* params, int* error)
5250{
5251 Execute(obj,cl,method,params,false,error);
5252}
5253
5254////////////////////////////////////////////////////////////////////////////////
5255/// Execute a method from class cl with the arguments in array params
5256/// (params[0] ... params[n] = array of TObjString parameters).
5257/// Convert the TObjArray array of TObjString parameters to a character
5258/// string of comma separated parameters.
5259/// The parameters of type 'char' are enclosed in double quotes and all
5260/// internal quotes are escaped.
5261
5262void TCling::Execute(TObject* obj, TClass* cl, TMethod* method,
5263 TObjArray* params, int* error)
5264{
5265 if (!method) {
5266 Error("Execute", "No method was defined");
5267 return;
5268 }
5269 TList* argList = method->GetListOfMethodArgs();
5270 // Check number of actual parameters against of expected formal ones
5271
5272 Int_t nparms = argList->LastIndex() + 1;
5273 Int_t argc = params ? params->GetEntries() : 0;
5274
5275 if (argc > nparms) {
5276 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
5277 return;
5278 }
5279 if (nparms != argc) {
5280 // Let's see if the 'missing' argument are all defaulted.
5281 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
5282 assert(nparms > 0);
5283
5284 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
5285 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5286 // There is a default value for the first missing
5287 // argument, so we are fine.
5288 } else {
5289 Int_t firstDefault = -1;
5290 for (Int_t i = 0; i < nparms; i ++) {
5291 arg = (TMethodArg *) argList->At( i );
5292 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5293 firstDefault = i;
5294 break;
5295 }
5296 }
5297 if (firstDefault >= 0) {
5298 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);
5299 } else {
5300 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
5301 }
5302 return;
5303 }
5304 }
5305
5306 const char* listpar = "";
5307 TString complete(10);
5308 if (params) {
5309 // Create a character string of parameters from TObjArray
5310 TIter next(params);
5311 for (Int_t i = 0; i < argc; i ++) {
5312 TMethodArg* arg = (TMethodArg*) argList->At(i);
5314 TObjString* nxtpar = (TObjString*) next();
5315 if (i) {
5316 complete += ',';
5317 }
5318 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
5319 TString chpar('\"');
5320 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
5321 // At this point we have to check if string contains \\"
5322 // and apply some more sophisticated parser. Not implemented yet!
5323 complete += chpar;
5324 complete += '\"';
5325 }
5326 else {
5327 complete += nxtpar->String();
5328 }
5329 }
5330 listpar = complete.Data();
5331 }
5332
5333 // And now execute it.
5335 if (error) {
5336 *error = TInterpreter::kNoError;
5337 }
5338 // If the actual class of this object inherits 2nd (or more) from TObject,
5339 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5340 // hence gInterpreter->Execute will improperly correct the offset.
5341 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5343 TClingMethodInfo *minfo = (TClingMethodInfo*)method->fInfo;
5344 func.Init(*minfo);
5345 func.SetArgs(listpar);
5346 // Now calculate the 'this' pointer offset for the method
5347 // when starting from the class described by cl.
5348 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetTargetFunctionDecl());
5349 Longptr_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
5350 void* address = (void*)((Longptr_t)addr + offset);
5351 func.Exec(address);
5352}
5353
5354////////////////////////////////////////////////////////////////////////////////
5355
5356void TCling::ExecuteWithArgsAndReturn(TMethod* method, void* address,
5357 const void* args[] /*=0*/,
5358 int nargs /*=0*/,
5359 void* ret/*= 0*/) const
5360{
5361 if (!method) {
5362 Error("ExecuteWithArgsAndReturn", "No method was defined");
5363 return;
5364 }
5365
5366 TClingMethodInfo* minfo = (TClingMethodInfo*) method->fInfo;
5367 TClingCallFunc func(*minfo);
5368 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5369}
5370
5371////////////////////////////////////////////////////////////////////////////////
5372/// Execute a cling macro.
5373
5375{
5377 fCurExecutingMacros.push_back(filename);
5379 fCurExecutingMacros.pop_back();
5380 return result;
5381}
5382
5383////////////////////////////////////////////////////////////////////////////////
5384/// Return the file name of the current un-included interpreted file.
5385/// See the documentation for GetCurrentMacroName().
5386
5388{
5389 Warning("GetTopLevelMacroName", "Must change return type!");
5390 return fCurExecutingMacros.back();
5391}
5392
5393////////////////////////////////////////////////////////////////////////////////
5394/// Return the file name of the currently interpreted file,
5395/// included or not. Example to illustrate the difference between
5396/// GetCurrentMacroName() and GetTopLevelMacroName():
5397/// ~~~ {.cpp}
5398/// void inclfile() {
5399/// std::cout << "In inclfile.C" << std::endl;
5400/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5401/// TCling::GetCurrentMacroName() << std::endl;
5402/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5403/// TCling::GetTopLevelMacroName() << std::endl;
5404/// }
5405/// ~~~
5406/// ~~~ {.cpp}
5407/// void mymacro() {
5408/// std::cout << "In mymacro.C" << std::endl;
5409/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5410/// TCling::GetCurrentMacroName() << std::endl;
5411/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5412/// TCling::GetTopLevelMacroName() << std::endl;
5413/// std::cout << " Now calling inclfile..." << std::endl;
5414/// gInterpreter->ProcessLine(".x inclfile.C");;
5415/// }
5416/// ~~~
5417/// Running mymacro.C will print:
5418///
5419/// ~~~ {.cpp}
5420/// root [0] .x mymacro.C
5421/// ~~~
5422/// In mymacro.C
5423/// ~~~ {.cpp}
5424/// TCling::GetCurrentMacroName() returns ./mymacro.C
5425/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5426/// ~~~
5427/// Now calling inclfile...
5428/// In inclfile.h
5429/// ~~~ {.cpp}
5430/// TCling::GetCurrentMacroName() returns inclfile.C
5431/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5432/// ~~~
5433
5435{
5436#if defined(R__MUST_REVISIT)
5437#if R__MUST_REVISIT(6,0)
5438 Warning("GetCurrentMacroName", "Must change return type!");
5439#endif
5440#endif
5441 return fCurExecutingMacros.back();
5442}
5443
5444////////////////////////////////////////////////////////////////////////////////
5445/// Return the absolute type of typeDesc.
5446/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
5447/// You need to use the result immediately before it is being overwritten.
5448
5449const char* TCling::TypeName(const char* typeDesc)
5450{
5451 TTHREAD_TLS_DECL(std::string,t);
5452
5453 if (!strstr(typeDesc, "(*)(")) {
5454 const char *s = strchr(typeDesc, ' ');
5455 const char *template_start = strchr(typeDesc, '<');
5456 if (!strcmp(typeDesc, "long long")) {
5457 t = typeDesc;
5458 }
5459 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5460 t = typeDesc;
5461 }
5462 // s is the position of the second 'word' (if any)
5463 // except in the case of templates where there will be a space
5464 // just before any closing '>': eg.
5465 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5466 else if (s && (template_start == nullptr || (s < template_start))) {
5467 t = s + 1;
5468 }
5469 else {
5470 t = typeDesc;
5471 }
5472 }
5473 else {
5474 t = typeDesc;
5475 }
5476 auto l = t.length();
5477 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&'))
5478 --l;
5479 t.resize(l);
5480 return t.c_str(); // NOLINT
5481}
5482
5483static bool requiresRootMap(const char* rootmapfile)
5484{
5485 assert(rootmapfile && *rootmapfile);
5486
5487 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5488 libName.consume_back(".rootmap");
5489
5490 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5491}
5492
5493////////////////////////////////////////////////////////////////////////////////
5494/// Read and parse a rootmapfile in its new format, and return 0 in case of
5495/// success, -1 if the file has already been read, and -3 in case its format
5496/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5497/// error.
5498
5499int TCling::ReadRootmapFile(const char *rootmapfile, TUniqueString *uniqueString)
5500{
5501 if (!(rootmapfile && *rootmapfile))
5502 return 0;
5503
5504 if (!requiresRootMap(rootmapfile))
5505 return 0; // success
5506
5507 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5508 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5509
5510 std::string rootmapfileNoBackslash(rootmapfile);
5511#ifdef _MSC_VER
5512 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5513#endif
5514 // Add content of a specific rootmap file
5515 if (fRootmapFiles->FindObject(rootmapfileNoBackslash.c_str()))
5516 return -1;
5517
5518 // Line 1 is `{ decls }`
5519 std::string lineDirective = std::string("\n#line 2 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n";
5520
5521 std::ifstream file(rootmapfileNoBackslash);
5522 std::string line;
5523 line.reserve(200);
5524 std::string lib_name;
5525 line.reserve(100);
5526 bool newFormat = false;
5527 while (getline(file, line, '\n')) {
5528 if (!newFormat && (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5529 file.close();
5530 return -3; // old format
5531 }
5532 newFormat = true;
5533
5534 if (line.compare(0, 9, "{ decls }") == 0) {
5535 // forward declarations
5536
5537 while (getline(file, line, '\n')) {
5538 if (line[0] == '[')
5539 break;
5540 if (!uniqueString) {
5541 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5542 rootmapfileNoBackslash.c_str());
5543 return -4;
5544 }
5545 if (!lineDirective.empty())
5546 uniqueString->Append(lineDirective);
5547 uniqueString->Append(line + '\n');
5548 }
5549 }
5550 const char firstChar = line[0];
5551 if (firstChar == '[') {
5552 // new section (library)
5553 auto brpos = line.find(']');
5554 if (brpos == string::npos)
5555 continue;
5556 lib_name = line.substr(1, brpos - 1);
5557 // Remove spaces at the beginning and at the end of the library name
5558 lib_name.erase(lib_name.find_last_not_of(' ') + 1);
5559 lib_name.erase(0, lib_name.find_first_not_of(' '));
5560 if (gDebug > 3) {
5561 TString lib_nameTstr(lib_name.c_str());
5562 TObjArray *tokens = lib_nameTstr.Tokenize(" ");
5563 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5564 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5565 if (wlib) {
5566 Info("ReadRootmapFile", "%s: New section for %s", rootmapfile, lib_nameTstr.Data());
5567 } else {
5568 Info("ReadRootmapFile", "%s: Section for %s (library does not exist)", rootmapfile, lib_nameTstr.Data());
5569 }
5570 delete[] wlib;
5571 delete tokens;
5572 }
5573 } else {
5574 auto keyLenIt = keyLenMap.find(firstChar);
5575 if (keyLenIt == keyLenMap.end())
5576 continue;
5577 unsigned int keyLen = keyLenIt->second;
5578 // Do not make a copy, just start after the key
5579 const char *keyname = line.c_str() + keyLen;
5580 if (gDebug > 6)
5581 Info("ReadRootmapFile", "%s: class %s in %s", rootmapfile, keyname, lib_name.c_str());
5582 TEnvRec *isThere = fMapfile->Lookup(keyname);
5583 if (isThere) {
5584 if (lib_name != isThere->GetValue()) { // the same key for two different libs
5585 if (firstChar == 'n') {
5586 if (gDebug > 3)
5587 Info("ReadRootmapFile",
5588 "While processing %s, namespace %s was found to be associated to %s although it is already "
5589 "associated to %s",
5590 rootmapfile, keyname, lib_name.c_str(), isThere->GetValue());
5591 } else if (firstChar == 'h') { // it is a header: add the libname to the list of libs to be loaded.
5592 lib_name += " ";
5593 lib_name += isThere->GetValue();
5594 fMapfile->SetValue(keyname, lib_name.c_str());
5595 } else if (!TClassEdit::IsSTLCont(keyname)) {
5596 Warning("ReadRootmapFile",
5597 "While processing %s, %s %s was found to be associated to %s although it is already "
5598 "associated to %s",
5599 rootmapfile, line.substr(0, keyLen - 1).c_str(), keyname, lib_name.c_str(),
5600 isThere->GetValue());
5601 }
5602 } else { // the same key for the same lib
5603 if (gDebug > 3)
5604 Info("ReadRootmapFile", "While processing %s, key %s was found to be already defined for %s",
5605 rootmapfile, keyname, lib_name.c_str());
5606 }
5607 } else {
5608 fMapfile->SetValue(keyname, lib_name.c_str());
5609 }
5610 }
5611 }
5612 file.close();
5613 return 0;
5614}
5615
5616////////////////////////////////////////////////////////////////////////////////
5617/// Create a resource table and read the (possibly) three resource files,
5618/// i.e. `$ROOTSYS/etc/system<name>` (or `ROOTETCDIR/system<name>`), `$HOME/<name>`
5619/// and `$PWD/<name>`. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You
5620/// can read additional user defined resource files by creating additional TEnv
5621/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5622/// the `$HOME/<name>` resource file will be skipped. This might be useful in
5623/// case the home directory resides on an automounted remote file system
5624/// and one wants to avoid the file system from being mounted.
5625
5627{
5628 assert(requiresRootMap(name) && "We have a module!");
5629
5630 if (!requiresRootMap(name))
5631 return;
5632
5634
5636
5637 TString sname = "system";
5638 sname += name;
5639 char *s = gSystem->ConcatFileName(TROOT::GetEtcDir(), sname);
5640
5641 Int_t ret = ReadRootmapFile(s);
5642 if (ret == -3) // old format
5644 delete [] s;
5645 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5647 ret = ReadRootmapFile(s);
5648 if (ret == -3) // old format
5650 delete [] s;
5651 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
5652 ret = ReadRootmapFile(name);
5653 if (ret == -3) // old format
5655 }
5656 } else {
5657 ret = ReadRootmapFile(name);
5658 if (ret == -3) // old format
5660 }
5661 fMapfile->IgnoreDuplicates(ignore);
5662}
5663
5664
5665namespace {
5666 using namespace clang;
5667
5668 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5669 // This class is to be considered an helper for AutoLoading.
5670 // It is a recursive visitor is used to inspect namespaces and specializations
5671 // coming from forward declarations in rootmaps and to set the external visible
5672 // storage flag for them.
5673 public:
5674 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5675 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5676 // We want to enable the external lookup for this namespace
5677 // because it may shadow the lookup of other names contained
5678 // in that namespace
5679
5680 nsDecl->setHasExternalVisibleStorage();
5681 fNSSet.insert(nsDecl);
5682 return true;
5683 }
5684 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl* specDecl) {
5685 // We want to enable the external lookup for this specialization
5686 // because we can provide a definition for it!
5687 if (specDecl->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
5688 //SpecSet.insert(specDecl);
5689 specDecl->setHasExternalLexicalStorage();
5690
5691 // No need to recurse. On the contrary, recursing is actively harmful:
5692 // NOTE: must not recurse to prevent this visitor from triggering loading from
5693 // the external AST source (i.e. autoloading). This would be triggered right here,
5694 // before autoloading is even set up, as rootmap file parsing happens before that.
5695 // Even if autoloading is off and has no effect, triggering loading from external
5696 // AST source resets the flag setHasExternalLexicalStorage(), hiding this specialization
5697 // from subsequent autoloads!
5698 return false;
5699 }
5700 private:
5701 std::unordered_set<const NamespaceDecl*>& fNSSet;
5702 };
5703}
5704
5705////////////////////////////////////////////////////////////////////////////////
5706/// Load map between class and library. If rootmapfile is specified a
5707/// specific rootmap file can be added (typically used by ACLiC).
5708/// In case of error -1 is returned, 0 otherwise.
5709/// The interpreter uses this information to automatically load the shared
5710/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5711
5712Int_t TCling::LoadLibraryMap(const char* rootmapfile)
5713{
5714 if (rootmapfile && *rootmapfile && !requiresRootMap(rootmapfile))
5715 return 0;
5716
5718
5719 // open the [system].rootmap files
5720 if (!fMapfile) {
5721 fMapfile = new TEnv();
5725 InitRootmapFile(".rootmap");
5726 }
5727
5728 // Prepare a list of all forward declarations for cling
5729 // For some experiments it is easily as big as 500k characters. To be on the
5730 // safe side, we go for 1M.
5731 TUniqueString uniqueString(1048576);
5732
5733 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5734 // A rootmap file must end with the string ".rootmap".
5735 TString ldpath = gSystem->GetDynamicPath();
5736 if (ldpath != fRootmapLoadPath) {
5737 fRootmapLoadPath = ldpath;
5738#ifdef WIN32
5739 TObjArray* paths = ldpath.Tokenize(";");
5740#else
5741 TObjArray* paths = ldpath.Tokenize(":");
5742#endif
5743 TString d;
5744 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5745 d = ((TObjString *)paths->At(i))->GetString();
5746 // check if directory already scanned
5747 Int_t skip = 0;
5748 for (Int_t j = 0; j < i; j++) {
5749 TString pd = ((TObjString *)paths->At(j))->GetString();
5750 if (pd == d) {
5751 skip++;
5752 break;
5753 }
5754 }
5755 if (!skip) {
5756 void* dirp = gSystem->OpenDirectory(d);
5757 if (dirp) {
5758 if (gDebug > 3) {
5759 Info("LoadLibraryMap", "%s", d.Data());
5760 }
5761 const char* f1;
5762 while ((f1 = gSystem->GetDirEntry(dirp))) {
5763 TString f = f1;
5764 if (f.EndsWith(".rootmap")) {
5765 TString p;
5766 p = d + "/" + f;
5768 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
5769 if (gDebug > 4) {
5770 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
5771 }
5772 Int_t ret = ReadRootmapFile(p, &uniqueString);
5773
5774 if (ret == 0)
5775 fRootmapFiles->Add(new TNamed(gSystem->BaseName(f), p.Data()));
5776 if (ret == -3) {
5777 // old format
5779 fRootmapFiles->Add(new TNamed(f, p));
5780 }
5781 }
5782 // else {
5783 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
5784 // fRootmapFiles->FindObject(f)->ls();
5785 // }
5786 }
5787 }
5788 if (f.BeginsWith("rootmap")) {
5789 TString p;
5790 p = d + "/" + f;
5791 FileStat_t stat;
5792 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
5793 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
5794 }
5795 }
5796 }
5797 }
5798 gSystem->FreeDirectory(dirp);
5799 }
5800 }
5801 delete paths;
5802 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
5803 return -1;
5804 }
5805 }
5806 if (rootmapfile && *rootmapfile) {
5807 Int_t res = ReadRootmapFile(rootmapfile, &uniqueString);
5808 if (res == 0) {
5809 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
5810 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
5811 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5812 }
5813 else if (res == -3) {
5814 // old format
5816 fMapfile->ReadFile(rootmapfile, kEnvGlobal);
5817 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5818 fMapfile->IgnoreDuplicates(ignore);
5819 }
5820 }
5821 TEnvRec* rec;
5822 TIter next(fMapfile->GetTable());
5823 while ((rec = (TEnvRec*) next())) {
5824 TString cls = rec->GetName();
5825 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5826 // get the first lib from the list of lib and dependent libs
5827 TString libs = rec->GetValue();
5828 if (libs == "") {
5829 continue;
5830 }
5831 TString delim(" ");
5832 TObjArray* tokens = libs.Tokenize(delim);
5833 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5834 // convert "@@" to "::", we used "@@" because TEnv
5835 // considers "::" a terminator
5836 cls.Remove(0, 8);
5837 cls.ReplaceAll("@@", "::");
5838 // convert "-" to " ", since class names may have
5839 // blanks and TEnv considers a blank a terminator
5840 cls.ReplaceAll("-", " ");
5841 if (gDebug > 6) {
5842 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
5843 if (wlib) {
5844 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
5845 }
5846 else {
5847 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
5848 }
5849 delete[] wlib;
5850 }
5851 delete tokens;
5852 }
5853 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
5854 cls.Remove(0, 8);
5855 // convert "-" to " ", since class names may have
5856 // blanks and TEnv considers a blank a terminator
5857 cls.ReplaceAll("-", " ");
5858 fInterpreter->declare(cls.Data());
5859 }
5860 }
5861
5862 // Process the forward declarations collected
5863 cling::Transaction* T = nullptr;
5864 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
5865 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
5866
5867 if (compRes!=cling::Interpreter::kSuccess){
5868 Warning("LoadLibraryMap",
5869 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
5870 }
5871
5872 if (T) {
5873 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
5874 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
5875 if (declIt->m_DGR.isSingleDecl()) {
5876 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
5877 if (clang::isa<TagDecl>(D) || clang::isa<NamespaceDecl>(D)) {
5878 evsAdder.TraverseDecl(D);
5879 }
5880 }
5881 }
5882 }
5883 }
5884
5885 // clear duplicates
5886
5887 return 0;
5888}
5889
5890////////////////////////////////////////////////////////////////////////////////
5891/// Scan again along the dynamic path for library maps. Entries for the loaded
5892/// shared libraries are unloaded first. This can be useful after reseting
5893/// the dynamic path through TSystem::SetDynamicPath()
5894/// In case of error -1 is returned, 0 otherwise.
5895
5897{
5900 return 0;
5901}
5902
5903////////////////////////////////////////////////////////////////////////////////
5904/// Reload the library map entries coming from all the loaded shared libraries,
5905/// after first unloading the current ones.
5906/// In case of error -1 is returned, 0 otherwise.
5907
5909{
5910 const TString sharedLibLStr = GetSharedLibs();
5911 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5912 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
5913 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
5914 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5915 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5916 const Int_t ret = UnloadLibraryMap(sharedLibBaseStr);
5917 if (ret < 0) {
5918 continue;
5919 }
5920 TString rootMapBaseStr = sharedLibBaseStr;
5921 if (sharedLibBaseStr.EndsWith(".dll")) {
5922 rootMapBaseStr.ReplaceAll(".dll", "");
5923 }
5924 else if (sharedLibBaseStr.EndsWith(".DLL")) {
5925 rootMapBaseStr.ReplaceAll(".DLL", "");
5926 }
5927 else if (sharedLibBaseStr.EndsWith(".so")) {
5928 rootMapBaseStr.ReplaceAll(".so", "");
5929 }
5930 else if (sharedLibBaseStr.EndsWith(".sl")) {
5931 rootMapBaseStr.ReplaceAll(".sl", "");
5932 }
5933 else if (sharedLibBaseStr.EndsWith(".dl")) {
5934 rootMapBaseStr.ReplaceAll(".dl", "");
5935 }
5936 else if (sharedLibBaseStr.EndsWith(".a")) {
5937 rootMapBaseStr.ReplaceAll(".a", "");
5938 }
5939 else {
5940 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
5941 delete sharedLibL;
5942 return -1;
5943 }
5944 rootMapBaseStr += ".rootmap";
5945 const char* rootMap = gSystem->Which(gSystem->GetDynamicPath(), rootMapBaseStr);
5946 if (!rootMap) {
5947 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
5948 delete[] rootMap;
5949 delete sharedLibL;
5950 return -1;
5951 }
5952 const Int_t status = LoadLibraryMap(rootMap);
5953 if (status < 0) {
5954 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
5955 delete[] rootMap;
5956 delete sharedLibL;
5957 return -1;
5958 }
5959 delete[] rootMap;
5960 }
5961 delete sharedLibL;
5962 return 0;
5963}
5964
5965////////////////////////////////////////////////////////////////////////////////
5966/// Unload the library map entries coming from all the loaded shared libraries.
5967/// Returns 0 if succesful
5968
5970{
5971 const TString sharedLibLStr = GetSharedLibs();
5972 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5973 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
5974 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5975 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5976 UnloadLibraryMap(sharedLibBaseStr);
5977 }
5978 delete sharedLibL;
5979 return 0;
5980}
5981
5982////////////////////////////////////////////////////////////////////////////////
5983/// Unload library map entries coming from the specified library.
5984/// Returns -1 in case no entries for the specified library were found,
5985/// 0 otherwise.
5986
5988{
5989 if (!fMapfile || !library || !*library) {
5990 return 0;
5991 }
5992 TString libname(library);
5993 Ssiz_t idx = libname.Last('.');
5994 if (idx != kNPOS) {
5995 libname.Remove(idx);
5996 }
5997 size_t len = libname.Length();
5998 TEnvRec *rec;
5999 TIter next(fMapfile->GetTable());
6001 Int_t ret = 0;
6002 while ((rec = (TEnvRec *) next())) {
6003 TString cls = rec->GetName();
6004 if (cls.Length() > 2) {
6005 // get the first lib from the list of lib and dependent libs
6006 TString libs = rec->GetValue();
6007 if (libs == "") {
6008 continue;
6009 }
6010 TString delim(" ");
6011 TObjArray* tokens = libs.Tokenize(delim);
6012 const char* lib = ((TObjString *)tokens->At(0))->GetName();
6013 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
6014 // convert "@@" to "::", we used "@@" because TEnv
6015 // considers "::" a terminator
6016 cls.Remove(0, 8);
6017 cls.ReplaceAll("@@", "::");
6018 // convert "-" to " ", since class names may have
6019 // blanks and TEnv considers a blank a terminator
6020 cls.ReplaceAll("-", " ");
6021 }
6022 if (!strncmp(lib, libname.Data(), len)) {
6023 if (fMapfile->GetTable()->Remove(rec) == nullptr) {
6024 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
6025 ret = -1;
6026 }
6027 }
6028 delete tokens;
6029 }
6030 }
6031 if (ret >= 0) {
6032 TString library_rootmap(library);
6033 if (!library_rootmap.EndsWith(".rootmap"))
6034 library_rootmap.Append(".rootmap");
6035 TNamed* mfile = nullptr;
6036 while ((mfile = (TNamed *)fRootmapFiles->FindObject(library_rootmap))) {
6037 fRootmapFiles->Remove(mfile);
6038 delete mfile;
6039 }
6041 }
6042 return ret;
6043}
6044
6045////////////////////////////////////////////////////////////////////////////////
6046/// Register the AutoLoading information for a class.
6047/// libs is a space separated list of libraries.
6048
6049Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
6050{
6051 if (!cls || !*cls)
6052 return 0;
6053
6054 TString key = TString("Library.") + cls;
6055 // convert "::" to "@@", we used "@@" because TEnv
6056 // considers "::" a terminator
6057 key.ReplaceAll("::", "@@");
6058 // convert "-" to " ", since class names may have
6059 // blanks and TEnv considers a blank a terminator
6060 key.ReplaceAll(" ", "-");
6061
6063 if (!fMapfile) {
6064 fMapfile = new TEnv();
6066
6069
6070 InitRootmapFile(".rootmap");
6071 }
6072 //fMapfile->SetValue(key, libs);
6073 fMapfile->SetValue(cls, libs);
6074 return 1;
6075}
6076
6077////////////////////////////////////////////////////////////////////////////////
6078/// Demangle the name (from the typeinfo) and then request the class
6079/// via the usual name based interface (TClass::GetClass).
6080
6081TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
6082{
6083 int err = 0;
6084 char* demangled_name = TClassEdit::DemangleTypeIdName(typeinfo, err);
6085 if (err) return nullptr;
6086 TClass* theClass = TClass::GetClass(demangled_name, load, kTRUE);
6087 free(demangled_name);
6088 return theClass;
6089}
6090
6091////////////////////////////////////////////////////////////////////////////////
6092/// Load library containing the specified class. Returns 0 in case of error
6093/// and 1 in case if success.
6094
6095Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
6096{
6097 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6098
6099 int err = 0;
6100 char* demangled_name_c = TClassEdit::DemangleTypeIdName(typeinfo, err);
6101 if (err) {
6102 return 0;
6103 }
6104
6105 std::string demangled_name(demangled_name_c);
6106 free(demangled_name_c);
6107
6108 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
6109 // shortened name.
6111 splitname.ShortType(demangled_name, TClassEdit::kDropStlDefault | TClassEdit::kDropStd);
6112
6113 // No need to worry about typedef, they aren't any ... but there are
6114 // inlined namespaces ...
6115
6116 Int_t result = AutoLoad(demangled_name.c_str());
6117 if (result == 0) {
6118 demangled_name = TClassEdit::GetLong64_Name(demangled_name);
6119 result = AutoLoad(demangled_name.c_str(), knowDictNotLoaded);
6120 }
6121
6122 return result;
6123}
6124
6125////////////////////////////////////////////////////////////////////////////////
6126// Get the list of 'published'/'known' library for the class and load them.
6128{
6129 Int_t status = 0;
6130
6131 // lookup class to find list of dependent libraries
6132 TString deplibs = gCling->GetClassSharedLibs(cls);
6133 if (!deplibs.IsNull()) {
6134 TString delim(" ");
6135 TObjArray* tokens = deplibs.Tokenize(delim);
6136 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
6137 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
6138 if (gROOT->LoadClass(cls, deplib) == 0) {
6139 if (gDebug > 0) {
6140 gCling->Info("TCling::AutoLoad",
6141 "loaded dependent library %s for %s", deplib, cls);
6142 }
6143 }
6144 else {
6145 gCling->Error("TCling::AutoLoad",
6146 "failure loading dependent library %s for %s",
6147 deplib, cls);
6148 }
6149 }
6150 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6151 if (lib && lib[0]) {
6152 if (gROOT->LoadClass(cls, lib) == 0) {
6153 if (gDebug > 0) {
6154 gCling->Info("TCling::AutoLoad",
6155 "loaded library %s for %s", lib, cls);
6156 }
6157 status = 1;
6158 }
6159 else {
6160 gCling->Error("TCling::AutoLoad",
6161 "failure loading library %s for %s", lib, cls);
6162 }
6163 }
6164 delete tokens;
6165 }
6166
6167 return status;
6168}
6169
6170////////////////////////////////////////////////////////////////////////////////
6171// Iterate through the data member of the class (either through the TProtoClass
6172// or through Cling) and trigger, recursively, the loading the necessary libraries.
6173// \note `cls` is expected to be already normalized!
6174// \returns 1 on success.
6175Int_t TCling::DeepAutoLoadImpl(const char *cls, std::unordered_set<std::string> &visited,
6176 bool nameIsNormalized)
6177{
6178 // Try to insert; if insertion failed because the entry existed, DeepAutoLoadImpl()
6179 // has previously (within the same call to `AutoLoad()`) tried to load this class
6180 // and we are done, whether success or not, as it won't work better now than before,
6181 // because there is no additional information now compared to before.
6182 if (!visited.insert(std::string(cls)).second)
6183 return 1;
6184
6185 if (ShallowAutoLoadImpl(cls) == 0) {
6186 // If ShallowAutoLoadImpl() has an error, we have an error.
6187 return 0;
6188 }
6189
6190 // Now look through the TProtoClass to load the required library/dictionary
6191 if (TProtoClass *proto = nameIsNormalized ? TClassTable::GetProtoNorm(cls) : TClassTable::GetProto(cls)) {
6192 for (auto element : proto->GetData()) {
6193 if (element->IsBasic())
6194 continue;
6195 const char *subtypename = element->GetTypeName();
6196 if (!TClassTable::GetDictNorm(subtypename)) {
6197 // Failure to load a dictionary is not (quite) a failure load
6198 // the top-level library. If we return false here, then
6199 // we would end up in a situation where the library and thus
6200 // the dictionary is loaded for "cls" but the TClass is
6201 // not created and/or marked as unavailable (in case where
6202 // AutoLoad is called from TClass::GetClass).
6203 DeepAutoLoadImpl(subtypename, visited, true /*normalized*/);
6204 }
6205 }
6206 return 1;
6207 }
6208
6209 // We found no TProtoClass for cls.
6210 auto classinfo = gInterpreter->ClassInfo_Factory(cls);
6211 if (classinfo && gInterpreter->ClassInfo_IsValid(classinfo)
6212 && !(gInterpreter->ClassInfo_Property(classinfo) & kIsEnum))
6213 {
6214 DataMemberInfo_t *memberinfo = gInterpreter->DataMemberInfo_Factory(classinfo, TDictionary::EMemberSelection::kNoUsingDecls);
6215 while (gInterpreter->DataMemberInfo_Next(memberinfo)) {
6216 if (gInterpreter->DataMemberInfo_TypeProperty(memberinfo) & ::kIsFundamental)
6217 continue;
6218 auto membertypename = TClassEdit::GetLong64_Name(gInterpreter->TypeName(gInterpreter->DataMemberInfo_TypeTrueName(memberinfo)));
6219 if (!TClassTable::GetDictNorm(membertypename.c_str())) {
6220 // Failure to load a dictionary is not (quite) a failure load
6221 // the top-level library. See detailed comment in the TProtoClass
6222 // branch (above).
6223 (void)DeepAutoLoadImpl(membertypename.c_str(), visited, true /*normalized*/);
6224 }
6225 }
6226 gInterpreter->DataMemberInfo_Delete(memberinfo);
6227 }
6228 gInterpreter->ClassInfo_Delete(classinfo);
6229 return 1;
6230}
6231
6232////////////////////////////////////////////////////////////////////////////////
6233/// Load library containing the specified class. Returns 0 in case of error
6234/// and 1 in case if success.
6235
6236Int_t TCling::AutoLoad(const char *cls, Bool_t knowDictNotLoaded /* = kFALSE */)
6237{
6238 // Prevent update to IsClassAutoloading between our check and our actions.
6240
6241 // TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
6242 // rootcling (in *_rdict.pcm file generation) it is a no op.
6243 // FIXME: We should avoid calling autoload when we know we are not supposed
6244 // to and transform this check into an assert.
6246 // Never load any library from rootcling/genreflex.
6247 if (gDebug > 2) {
6248 Info("TCling::AutoLoad", "Explicitly disabled (the class name is %s)", cls);
6249 }
6250 return 0;
6251 }
6252
6253 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6254
6256
6257 if (!knowDictNotLoaded && gClassTable->GetDictNorm(cls)) {
6258 // The library is already loaded as the class's dictionary is known.
6259 // Return success.
6260 // Note: the name (cls) is expected to be normalized as it comes either
6261 // from a callbacks (that can/should calculate the normalized name from the
6262 // decl) or from TClass::GetClass (which does also calculate the normalized
6263 // name).
6264 return 1;
6265 }
6266
6267 if (gDebug > 2) {
6268 Info("TCling::AutoLoad",
6269 "Trying to autoload for %s", cls);
6270 }
6271
6272 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
6273 if (gDebug > 2) {
6274 Info("TCling::AutoLoad",
6275 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
6276 }
6277 return 0;
6278 }
6279 // Prevent the recursion when the library dictionary are loaded.
6280 SuspendAutoLoadingRAII autoLoadOff(this);
6281 // Try using externally provided callback first.
6282 if (fAutoLoadCallBack) {
6283 int success = (*(AutoLoadCallBack_t)fAutoLoadCallBack)(cls);
6284 if (success)
6285 return success;
6286 }
6287
6288 // During the 'Deep' part of the search we will call GetClassSharedLibsForModule
6289 // (when module are enabled) which might end up calling AutoParsing but
6290 // that should only be for the cases where the library has no generated pcm
6291 // and in that case a rootmap should be available.
6292 // This avoids a very costly operation (for generally no gain) but reduce the
6293 // quality of the search (i.e. bad in case of library with no pcm and no rootmap
6294 // file).
6295 TInterpreter::SuspendAutoParsing autoParseRaii(this);
6296 std::unordered_set<std::string> visited;
6297 return DeepAutoLoadImpl(cls, visited, false /*normalized*/);
6298}
6299
6300////////////////////////////////////////////////////////////////////////////////
6301/// Parse the payload or header.
6302
6303static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
6304 Bool_t header,
6305 cling::Interpreter *interpreter)
6306{
6307 std::string code = gNonInterpreterClassDef ;
6308 if (!header) {
6309 // This is the complete header file content and not the
6310 // name of a header.
6311 code += what;
6312
6313 } else {
6314 code += ("#include \"");
6315 code += what;
6316 code += "\"\n";
6317 }
6318 code += ("#ifdef __ROOTCLING__\n"
6319 "#undef __ROOTCLING__\n"
6320 + gInterpreterClassDef +
6321 "#endif");
6322
6323 cling::Interpreter::CompilationResult cr;
6324 {
6325 // scope within which diagnostics are de-activated
6326 // For now we disable diagnostics because we saw them already at
6327 // dictionary generation time. That won't be an issue with the PCMs.
6328
6329 Sema &SemaR = interpreter->getSema();
6330 ROOT::Internal::ParsingStateRAII parsingStateRAII(interpreter->getParser(), SemaR);
6331 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
6332
6333 #if defined(R__MUST_REVISIT)
6334 #if R__MUST_REVISIT(6,2)
6335 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
6336 #endif
6337 #endif
6338
6339 cr = interpreter->parseForModule(code);
6340 }
6341 return cr;
6342}
6343
6344////////////////////////////////////////////////////////////////////////////////
6345/// Helper routine for TCling::AutoParse implementing the actual call to the
6346/// parser and looping over template parameters (if
6347/// any) and when they don't have a registered header to autoparse,
6348/// recurse over their template parameters.
6349///
6350/// Returns the number of header parsed.
6351
6352UInt_t TCling::AutoParseImplRecurse(const char *cls, bool topLevel)
6353{
6354 // We assume the lock has already been taken.
6355 // R__LOCKGUARD(gInterpreterMutex);
6356
6357 Int_t nHheadersParsed = 0;
6358 unsigned long offset = 0;
6359 if (strncmp(cls, "const ", 6) == 0) {
6360 offset = 6;
6361 }
6362
6363 // Loop on the possible autoparse keys
6364 bool skipFirstEntry = false;
6365 std::vector<std::string> autoparseKeys;
6366 if (strchr(cls, '<')) {
6367 int nestedLoc = 0;
6368 TClassEdit::GetSplit(cls + offset, autoparseKeys, nestedLoc, TClassEdit::kDropTrailStar);
6369 // Check if we can skip the name of the template in the autoparses
6370 // Take all the scopes one by one. If all of them are in the AST, we do not
6371 // need to autoparse for that particular template.
6372 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
6373 // autoparseKeys[0] is empty when the input is not a template instance.
6374 // The case strchr(cls, '<') != 0 but still not a template instance can
6375 // happens 'just' for string (GetSplit replaces the template by the short name
6376 // and then use that for thew splitting)
6377 TString templateName(autoparseKeys[0]);
6378 auto tokens = templateName.Tokenize("::");
6379 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
6380 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
6381 if (TClassEdit::IsStdClass(cls + offset))
6382 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
6383 auto nTokens = tokens->GetEntriesFast();
6384 for (Int_t tk = 0; tk < nTokens; ++tk) {
6385 auto scopeObj = tokens->UncheckedAt(tk);
6386 auto scopeName = ((TObjString*) scopeObj)->String().Data();
6387 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
6388 // Check if we have multiple nodes in the AST with this name
6389 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
6390 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
6391 if (!previousScopeAsContext) break; // this is not a context
6392 }
6393 delete tokens;
6394 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
6395 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
6396 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
6397 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
6398 skipFirstEntry = templatedDecl->hasDefinition();
6399 }
6400 }
6401 }
6402
6403 }
6404 }
6405 if (topLevel) autoparseKeys.emplace_back(cls);
6406
6407 for (const auto & apKeyStr : autoparseKeys) {
6408 if (skipFirstEntry) {
6409 skipFirstEntry=false;
6410 continue;
6411 }
6412 if (apKeyStr.empty()) continue;
6413 const char *apKey = apKeyStr.c_str();
6414 std::size_t normNameHash(fStringHashFunction(apKey));
6415 // If the class was not looked up
6416 if (gDebug > 1) {
6417 Info("TCling::AutoParse",
6418 "Starting autoparse for %s\n", apKey);
6419 }
6420 if (fLookedUpClasses.insert(normNameHash).second) {
6421 auto const &iter = fClassesHeadersMap.find(normNameHash);
6422 if (iter != fClassesHeadersMap.end()) {
6423 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
6424 fTransactionHeadersMap.insert({T,normNameHash});
6425 auto const &hNamesPtrs = iter->second;
6426 if (gDebug > 1) {
6427 Info("TCling::AutoParse",
6428 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
6429 }
6430 for (auto & hName : hNamesPtrs) {
6431 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
6432 if (0 != fPayloads.count(normNameHash)) {
6433 float initRSSval=0.f, initVSIZEval=0.f;
6434 (void) initRSSval; // Avoid unused var warning
6435 (void) initVSIZEval;
6436 if (gDebug > 0) {
6437 Info("AutoParse",
6438 "Parsing full payload for %s", apKey);
6439 ProcInfo_t info;
6440 gSystem->GetProcInfo(&info);
6441 initRSSval = 1e-3*info.fMemResident;
6442 initVSIZEval = 1e-3*info.fMemVirtual;
6443 }
6444 auto cRes = ExecAutoParse(hName, kFALSE, GetInterpreterImpl());
6445 if (cRes != cling::Interpreter::kSuccess) {
6446 if (hName[0] == '\n')
6447 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
6448 } else {
6449 fParsedPayloadsAddresses.insert(hName);
6450 nHheadersParsed++;
6451 if (gDebug > 0){
6452 ProcInfo_t info;
6453 gSystem->GetProcInfo(&info);
6454 float endRSSval = 1e-3*info.fMemResident;
6455 float endVSIZEval = 1e-3*info.fMemVirtual;
6456 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6457 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6458 }
6459 }
6460 } else if (!IsLoaded(hName)) {
6461 if (gDebug > 0) {
6462 Info("AutoParse",
6463 "Parsing single header %s", hName);
6464 }
6465 auto cRes = ExecAutoParse(hName, kTRUE, GetInterpreterImpl());
6466 if (cRes != cling::Interpreter::kSuccess) {
6467 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
6468 } else {
6469 nHheadersParsed++;
6470 }
6471 }
6472 }
6473 }
6474 else {
6475 // There is no header registered for this class, if this a
6476 // template, it will be instantiated if/when it is requested
6477 // and if we do no load/parse its components we might end up
6478 // not using an eventual specialization.
6479 if (strchr(apKey, '<')) {
6480 nHheadersParsed += AutoParseImplRecurse(apKey, false);
6481 }
6482 }
6483 }
6484 }
6485
6486 return nHheadersParsed;
6487
6488}
6489
6490////////////////////////////////////////////////////////////////////////////////
6491/// Parse the headers relative to the class
6492/// Returns 1 in case of success, 0 in case of failure
6493
6494Int_t TCling::AutoParse(const char *cls)
6495{
6496 if (llvm::StringRef(cls).contains("(lambda)"))
6497 return 0;
6498
6501 return AutoLoad(cls);
6502 } else {
6503 return 0;
6504 }
6505 }
6506
6508
6509 if (gDebug > 1) {
6510 Info("TCling::AutoParse",
6511 "Trying to autoparse for %s", cls);
6512 }
6513
6514 // The catalogue of headers is in the dictionary
6516 && !gClassTable->GetDictNorm(cls)) {
6517 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
6518 ROOT::Internal::ParsingStateRAII parsingStateRAII(fInterpreter->getParser(),
6519 fInterpreter->getSema());
6520 AutoLoad(cls, true /*knowDictNotLoaded*/);
6521 }
6522
6523 // Prevent the recursion when the library dictionary are loaded.
6524 SuspendAutoLoadingRAII autoLoadOff(this);
6525
6526 // No recursive header parsing on demand; we require headers to be standalone.
6527 SuspendAutoParsing autoParseRAII(this);
6528
6529 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
6530
6532
6533 return nHheadersParsed > 0 ? 1 : 0;
6534}
6535
6536// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6537// Try to solve the problem by AutoLoading. Return true when AutoLoading success, return
6538// false if not.
6539bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6540{
6541 StringRef errMsg(errmessage);
6542 if (errMsg.contains("undefined symbol: ")) {
6543 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6544 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6545 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6546 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6547 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6548 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6549 return true;
6550 } else {
6551 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6552 if ( ((TCling*)gCling)->LazyFunctionCreatorAutoload(errmessage))
6553 return true;
6554 }
6555
6556 return false;
6557}
6558
6559////////////////////////////////////////////////////////////////////////////////
6560/// Autoload a library based on a missing symbol.
6561
6562void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {
6563 std::string dlsym_mangled_name = ROOT::TMetaUtils::DemangleNameForDlsym(mangled_name);
6564
6565 // We have already loaded the library.
6566 if (void* Addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name))
6567 return Addr;
6568
6569 const cling::DynamicLibraryManager &DLM = *GetInterpreterImpl()->getDynamicLibraryManager();
6571
6572 auto LibLoader = [](const std::string& LibName) -> bool {
6573 if (gSystem->Load(LibName.c_str(), "", false) < 0) {
6574 ::Error("TCling__LazyFunctionCreatorAutoloadForModule",
6575 "Failed to load library %s", LibName.c_str());
6576 return false;
6577 }
6578 return true; //success.
6579 };
6580
6581 std::string libName = DLM.searchLibrariesForSymbol(mangled_name,
6582 /*searchSystem=*/ true);
6583
6584 assert(!llvm::StringRef(libName).startswith("libNew") &&
6585 "We must not resolve symbols from libNew!");
6586
6587 if (libName.empty())
6588 return nullptr;
6589
6590 if (!LibLoader(libName))
6591 return nullptr;
6592
6593 return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name);
6594}
6595
6596////////////////////////////////////////////////////////////////////////////////
6597
6598Bool_t TCling::IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
6599{
6600 return fNSFromRootmaps.count(nsDecl) != 0;
6601}
6602
6603////////////////////////////////////////////////////////////////////////////////
6604/// Internal function. Actually do the update of the ClassInfo when seeing
6605// new TagDecl or NamespaceDecl.
6606void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6607{
6608
6610 if (cci) {
6611 // If we only had a forward declaration then update the
6612 // TClingClassInfo with the definition if we have it now.
6613 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6614 if (!oldDef || (def && def != oldDef)) {
6615 cl->ResetCaches();
6617 if (def) {
6618 // It's a tag decl, not a namespace decl.
6619 cci->Init(*cci->GetType());
6621 }
6622 }
6623 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6624 cl->ResetCaches();
6625 // yes, this is almost a waste of time, but we do need to lookup
6626 // the 'type' corresponding to the TClass anyway in order to
6627 // preserve the opaque typedefs (Double32_t)
6628 if (!alias && def != nullptr)
6629 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), def);
6630 else
6631 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), cl->GetName());
6632 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6633 // We now need to update the state and bits.
6634 if (cl->fState != TClass::kHasTClassInit) {
6635 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6637 }
6638 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6639 } else {
6640 delete ((TClingClassInfo *)cl->fClassInfo);
6641 cl->fClassInfo = nullptr;
6642 }
6643 }
6644}
6645
6646////////////////////////////////////////////////////////////////////////////////
6647/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6648void TCling::UpdateClassInfoWithDecl(const NamedDecl* ND)
6649{
6650 const TagDecl *td = dyn_cast<TagDecl>(ND);
6651 const NamespaceDecl *ns = dyn_cast<NamespaceDecl>(ND);
6652 const NamedDecl *canon = nullptr;
6653
6654 std::string name;
6655 TagDecl* tdDef = nullptr;
6656 if (td) {
6657 canon = tdDef = td->getDefinition();
6658 // Let's pass the decl to the TClass only if it has a definition.
6659 if (!tdDef) return;
6660
6661 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6662 // Ignore incomplete definition.
6663 // Ignore declaration within a function.
6664 return;
6665 }
6666
6667 auto declName = tdDef->getNameAsString();
6668 // Check if we have registered the unqualified name into the list
6669 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6670 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6671 // the unqualified name is sufficient (and the fully qualified name might be
6672 // 'wrong' if there is difference in spelling in the template paramters (for example)
6673 if (!TClass::HasNoInfoOrEmuOrFwdDeclaredDecl(declName.c_str())){
6674 // 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() );
6675 return;
6676 }
6677
6678 clang::QualType type(tdDef->getTypeForDecl(), 0);
6680 } else if (ns) {
6681 canon = ns->getCanonicalDecl();
6682 name = ND->getQualifiedNameAsString();
6683 } else {
6684 name = ND->getQualifiedNameAsString();
6685 }
6686
6687 // Supposedly we are being called while something is being
6688 // loaded ... let's now tell the autoloader to do the work
6689 // yet another time.
6690 SuspendAutoLoadingRAII autoLoadOff(this);
6691 // FIXME: There can be more than one TClass for a single decl.
6692 // for example vector<double> and vector<Double32_t>
6693 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6694 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6695 RefreshClassInfo(cl, canon, false);
6696 }
6697 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6698 // and update them too:
6699 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6700 // RefreshClassInfo(cl, tdDef, true);
6701}
6702
6703////////////////////////////////////////////////////////////////////////////////
6704/// No op: see TClingCallbacks
6705
6706void TCling::UpdateClassInfo(char* item, Long_t tagnum)
6707{
6708}
6709
6710//______________________________________________________________________________
6711//FIXME: Factor out that function in TClass, because TClass does it already twice
6712void TCling::UpdateClassInfoWork(const char* item)
6713{
6714 // This is a no-op as part of the API.
6715 // TCling uses UpdateClassInfoWithDecl() instead.
6716}
6717
6718////////////////////////////////////////////////////////////////////////////////
6719/// Update all canvases at end the terminal input command.
6720
6722{
6723 TIter next(gROOT->GetListOfCanvases());
6724 TVirtualPad* canvas;
6725 while ((canvas = (TVirtualPad*)next())) {
6726 canvas->Update();
6727 }
6728}
6729
6730////////////////////////////////////////////////////////////////////////////////
6731
6732void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6733 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6734
6735 // If the transaction does not contain anything we can return earlier.
6736 if (!HandleNewTransaction(T)) return;
6737
6738 bool isTUTransaction = false;
6739 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
6740 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
6741 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
6742 // The is the first transaction, we have to expose to meta
6743 // what's already in the AST.
6744 isTUTransaction = true;
6745 }
6746 }
6747
6748 std::set<const void*> TransactionDeclSet;
6749 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
6750 const clang::Decl* WrapperFD = T.getWrapperFD();
6751 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6752 I != E; ++I) {
6753 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
6754 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
6755 continue;
6756
6757 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6758 DE = I->m_DGR.end(); DI != DE; ++DI) {
6759 if (*DI == WrapperFD)
6760 continue;
6761 TransactionDeclSet.insert(*DI);
6762 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
6763 }
6764 }
6765 }
6766
6767 // The above might trigger more decls to be deserialized.
6768 // Thus the iteration over the deserialized decls must be last.
6769 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
6770 E = T.deserialized_decls_end(); I != E; ++I) {
6771 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6772 DE = I->m_DGR.end(); DI != DE; ++DI)
6773 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
6774 //FIXME: HandleNewDecl should take DeclGroupRef
6775 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
6776 modifiedTClasses);
6777 }
6778 }
6779
6780
6781 // When fully building the reflection info in TClass, a deserialization
6782 // could be triggered, which may result in request for building the
6783 // reflection info for the same TClass. This in turn will clear the caches
6784 // for the TClass in-flight and cause null ptr derefs.
6785 // FIXME: This is a quick fix, solving most of the issues. The actual
6786 // question is: Shouldn't TClass provide a lock mechanism on update or lock
6787 // itself until the update is done.
6788 //
6789 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
6790 std::vector<TClass*>::iterator it;
6791 it = set_difference(modifiedTClasses.begin(), modifiedTClasses.end(),
6792 ((TCling*)gCling)->GetModTClasses().begin(),
6793 ((TCling*)gCling)->GetModTClasses().end(),
6794 modifiedTClassesDiff.begin());
6795 modifiedTClassesDiff.resize(it - modifiedTClassesDiff.begin());
6796
6797 // Lock the TClass for updates
6798 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
6799 modifiedTClassesDiff.end());
6800 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
6801 E = modifiedTClassesDiff.end(); I != E; ++I) {
6802 // Make sure the TClass has not been deleted.
6803 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
6804 continue;
6805 }
6806 // Could trigger deserialization of decls.
6807 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
6808 // Unlock the TClass for updates
6809 ((TCling*)gCling)->GetModTClasses().erase(*I);
6810
6811 }
6812}
6813
6814///\brief Invalidate stored TCling state for declarations included in transaction `T'.
6815///
6816void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
6817{
6819
6820 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6821 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6822 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6823 (TListOfEnums *)gROOT->GetListOfEnums());
6824
6825 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
6826 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6827 I != E; ++I) {
6828 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
6829 continue;
6830 if (I->m_Call == cling::Transaction::kCCINone) {
6831 UpdateListsOnUnloaded(*(*iNested));
6832 ++iNested;
6833 continue;
6834 }
6835
6836 for (auto &D : I->m_DGR)
6837 InvalidateCachedDecl(Lists, D);
6838 }
6839}
6840
6841///\brief Invalidate cached TCling information for the given global declaration.
6842///
6843void TCling::InvalidateGlobal(const Decl *D) {
6844 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6845 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6846 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6847 (TListOfEnums *)gROOT->GetListOfEnums());
6848 InvalidateCachedDecl(Lists, D);
6849}
6850
6851///\brief Invalidate cached TCling information for the given declaration, and
6852/// removed it from the appropriate object list.
6853///\param[in] Lists - std::tuple<TListOfDataMembers&, TListOfFunctions&,
6854/// TListOfFunctionTemplates&, TListOfEnums&>
6855/// of pointers to the (global/class) object lists.
6856///\param[in] D - Decl to discard.
6857///
6861 TListOfEnums*> &Lists, const Decl *D) {
6862 if (D->isFromASTFile()) // `D' came from the PCH; ignore
6863 return;
6864
6865 TListOfDataMembers &LODM = *(std::get<0>(Lists));
6866 TListOfFunctions &LOF = *(std::get<1>(Lists));
6867 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
6868 TListOfEnums &LOE = *(std::get<3>(Lists));
6869
6870 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D)) {
6871 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
6872 if (LODM.GetClass())
6873 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
6874 else
6875 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
6876 } else if (isa<FunctionDecl>(D)) {
6878 } else if (isa<FunctionTemplateDecl>(D)) {
6880 } else if (isa<EnumDecl>(D)) {
6881 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
6882 if (!E)
6883 return;
6884
6885 // Try to invalidate enumerators (for unscoped enumerations).
6886 for (TIter I = E->GetConstants(); auto EC = (TEnumConstant *)I(); )
6888 (TEnumConstant *)LODM.FindObject(EC->GetName()));
6889
6891 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
6892 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->isCompleteDefinition())
6893 return;
6894
6895 std::vector<TClass *> Classes;
6896 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
6897 return;
6898 for (auto &C : Classes) {
6899 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
6900 (TListOfFunctions *)C->GetListOfMethods(),
6901 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
6902 (TListOfEnums *)C->GetListOfEnums());
6903 for (auto &I : cast<DeclContext>(D)->decls())
6904 InvalidateCachedDecl(Lists, I);
6905
6906 // For NamespaceDecl (redeclarable), only invalidate this redecl.
6907 if (D->getKind() != Decl::Namespace
6908 || cast<NamespaceDecl>(D)->isOriginalNamespace())
6909 C->ResetClassInfo();
6910 }
6911 }
6912}
6913
6914////////////////////////////////////////////////////////////////////////////////
6915// If an autoparse was done during a transaction and that it is rolled back,
6916// we need to make sure the next request for the same autoparse will be
6917// honored.
6918void TCling::TransactionRollback(const cling::Transaction &T) {
6919 auto const &triter = fTransactionHeadersMap.find(&T);
6920 if (triter != fTransactionHeadersMap.end()) {
6921 std::size_t normNameHash = triter->second;
6922
6923 fLookedUpClasses.erase(normNameHash);
6924
6925 auto const &iter = fClassesHeadersMap.find(normNameHash);
6926 if (iter != fClassesHeadersMap.end()) {
6927 auto const &hNamesPtrs = iter->second;
6928 for (auto &hName : hNamesPtrs) {
6929 if (gDebug > 0) {
6930 Info("TransactionRollback",
6931 "Restoring ability to autoaparse: %s", hName);
6932 }
6933 fParsedPayloadsAddresses.erase(hName);
6934 }
6935 }
6936 }
6937}
6938
6939////////////////////////////////////////////////////////////////////////////////
6940
6941void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
6942// R__LOCKGUARD_CLING(gInterpreterMutex);
6943// UpdateListOfLoadedSharedLibraries();
6944}
6945
6946////////////////////////////////////////////////////////////////////////////////
6947
6948void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
6949 fPrevLoadedDynLibInfo = nullptr;
6950 fSharedLibs = "";
6951}
6952
6953////////////////////////////////////////////////////////////////////////////////
6954/// Return the list of shared libraries loaded into the process.
6955
6957{
6960 return fSharedLibs;
6961}
6962
6963static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
6964{
6965 if (!cls || !*cls)
6966 return {};
6967
6968 using namespace clang;
6969 if (const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
6970 /*type*/ nullptr, /*instantiate*/ false)) {
6971 if (!D->isFromASTFile()) {
6972 if (gDebug > 5)
6973 Warning("GetClassSharedLibsForModule", "Decl found for %s is not part of a module", cls);
6974 return {};
6975 }
6976 class ModuleCollector : public ConstDeclVisitor<ModuleCollector> {
6977 llvm::DenseSet<Module *> &m_TopLevelModules;
6978
6979 public:
6980 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
6981 void Collect(const Decl *D) { Visit(D); }
6982
6983 void VisitDecl(const Decl *D)
6984 {
6985 // FIXME: Such case is described ROOT-7765 where
6986 // ROOT_GENERATE_DICTIONARY does not contain the list of headers.
6987 // They are specified as #includes in the LinkDef file. This leads to
6988 // generation of incomplete modulemap files and this logic fails to
6989 // compute the corresponding module of D.
6990 // FIXME: If we want to support such a case, we should not rely on
6991 // the contents of the modulemap but mangle D and look it up in the
6992 // .so files.
6993 if (!D->hasOwningModule())
6994 return;
6995 if (Module *M = D->getOwningModule()->getTopLevelModule())
6996 m_TopLevelModules.insert(M);
6997 }
6998
6999 void VisitTemplateArgument(const TemplateArgument &TA)
7000 {
7001 switch (TA.getKind()) {
7002 case TemplateArgument::Null:
7003 case TemplateArgument::Integral:
7004 case TemplateArgument::Pack:
7005 case TemplateArgument::NullPtr:
7006 case TemplateArgument::Expression:
7007 case TemplateArgument::Template:
7008 case TemplateArgument::TemplateExpansion: return;
7009 case TemplateArgument::Type:
7010 if (const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
7011 return Visit(TagTy->getDecl());
7012 return;
7013 case TemplateArgument::Declaration: return Visit(TA.getAsDecl());
7014 }
7015 llvm_unreachable("Invalid TemplateArgument::Kind!");
7016 }
7017
7018 void VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *CTSD)
7019 {
7020 if (CTSD->getOwningModule())
7021 VisitDecl(CTSD);
7022 else
7023 VisitDecl(CTSD->getSpecializedTemplate());
7024 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
7025 for (const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
7026 VisitTemplateArgument(*Arg);
7027 }
7028 }
7029 };
7030
7031 llvm::DenseSet<Module *> TopLevelModules;
7032 ModuleCollector m(TopLevelModules);
7033 m.Collect(D);
7034 std::string result;
7035 for (auto M : TopLevelModules) {
7036 // ROOT-unaware modules (i.e. not processed by rootcling) do not have a
7037 // link declaration.
7038 if (!M->LinkLibraries.size())
7039 continue;
7040 // We have preloaded the Core module thus libCore.so
7041 if (M->Name == "Core")
7042 continue;
7043 assert(M->LinkLibraries.size() == 1);
7044 if (!result.empty())
7045 result += ' ';
7046 result += M->LinkLibraries[0].Library;
7047 }
7048 return result;
7049 }
7050 return {};
7051}
7052
7053////////////////////////////////////////////////////////////////////////////////
7054/// Get the list of shared libraries containing the code for class cls.
7055/// The first library in the list is the one containing the class, the
7056/// others are the libraries the first one depends on. Returns 0
7057/// in case the library is not found.
7058
7059const char* TCling::GetClassSharedLibs(const char* cls)
7060{
7061 if (fCxxModulesEnabled) {
7062 // Lock the interpreter mutex before interacting with cling.
7063 // TODO: Can we move this further deep? In principle the lock should be in
7064 // GetClassSharedLibsForModule, but it might be needed also for
7065 // getLookupHelper?
7067 llvm::StringRef className = cls;
7068 // If we get a class name containing lambda, we cannot parse it and we
7069 // can exit early.
7070 // FIXME: This works around a bug when we are instantiating a template
7071 // make_unique and the substitution fails. Seen in most of the dataframe
7072 // tests.
7073 if (className.contains("(lambda)"))
7074 return nullptr;
7075 // Limit the recursion which can be induced by GetClassSharedLibsForModule.
7076 SuspendAutoLoadingRAII AutoLoadingDisabled(this);
7077 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
7078 std::string libs = GetClassSharedLibsForModule(cls, LH);
7079 if (!libs.empty()) {
7080 fAutoLoadLibStorage.push_back(libs);
7081 return fAutoLoadLibStorage.back().c_str();
7082 }
7083 }
7084
7085 if (!cls || !*cls) {
7086 return nullptr;
7087 }
7088 // lookup class to find list of libraries
7089 if (fMapfile) {
7090 TEnvRec* libs_record = nullptr;
7091 libs_record = fMapfile->Lookup(cls);
7092 if (libs_record) {
7093 const char* libs = libs_record->GetValue();
7094 return (*libs) ? libs : nullptr;
7095 }
7096 else {
7097 // Try the old format...
7098 TString c = TString("Library.") + cls;
7099 // convert "::" to "@@", we used "@@" because TEnv
7100 // considers "::" a terminator
7101 c.ReplaceAll("::", "@@");
7102 // convert "-" to " ", since class names may have
7103 // blanks and TEnv considers a blank a terminator
7104 c.ReplaceAll(" ", "-");
7105 // Use TEnv::Lookup here as the rootmap file must start with Library.
7106 // and do not support using any stars (so we do not need to waste time
7107 // with the search made by TEnv::GetValue).
7108 TEnvRec* libs_record = nullptr;
7109 libs_record = fMapfile->Lookup(c);
7110 if (libs_record) {
7111 const char* libs = libs_record->GetValue();
7112 return (*libs) ? libs : nullptr;
7113 }
7114 }
7115 }
7116 return nullptr;
7117}
7118
7119/// This interface returns a list of dependent libraries in the form:
7120/// lib libA.so libB.so libC.so. The first library is the library we are
7121/// searching dependencies for.
7122/// Note: In order to speed up the search, we display the dependencies of the
7123/// libraries which are not yet loaded. For instance, if libB.so was already
7124/// loaded the list would contain: lib libA.so libC.so.
7125static std::string GetSharedLibImmediateDepsSlow(std::string lib,
7126 cling::Interpreter *interp,
7127 bool skipLoadedLibs = true)
7128{
7129 TString LibFullPath(lib);
7130 if (!llvm::sys::path::is_absolute(lib)) {
7131 if (!gSystem->FindDynamicLibrary(LibFullPath, /*quiet=*/true)) {
7132 Error("TCling__GetSharedLibImmediateDepsSlow", "Cannot find library '%s'", lib.c_str());
7133 return "";
7134 }
7135 } else {
7136 assert(llvm::sys::fs::exists(lib) && "Must exist!");
7137 lib = llvm::sys::path::filename(lib).str();
7138 }
7139
7140 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
7141 if (!ObjF) {
7142 Warning("TCling__GetSharedLibImmediateDepsSlow", "Failed to read object file %s", lib.c_str());
7143 return "";
7144 }
7145
7146 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7147
7148 std::set<string> DedupSet;
7149 std::string Result = lib + ' ';
7150 for (const auto &S : BinObjFile->symbols()) {
7151 uint32_t Flags = llvm::cantFail(S.getFlags());
7152 // Skip defined symbols: we have them.
7153 if (!(Flags & llvm::object::SymbolRef::SF_Undefined))
7154 continue;
7155 // Skip undefined weak symbols: if we don't have them we won't need them.
7156 // `__gmon_start__` being a typical example.
7157 if (Flags & llvm::object::SymbolRef::SF_Weak)
7158 continue;
7159 llvm::Expected<StringRef> SymNameErr = S.getName();
7160 if (!SymNameErr) {
7161 Warning("GetSharedLibDepsForModule", "Failed to read symbol");
7162 continue;
7163 }
7164 llvm::StringRef SymName = SymNameErr.get();
7165 if (SymName.empty())
7166 continue;
7167
7168 if (BinObjFile->isELF()) {
7169 // Skip the symbols which are part of the C/C++ runtime and have a
7170 // fixed library version. See binutils ld VERSION. Those reside in
7171 // 'system' libraries, which we avoid in FindLibraryForSymbol.
7172 if (SymName.contains("@GLIBCXX") || SymName.contains("@CXXABI") ||
7173 SymName.contains("@GLIBC") || SymName.contains("@GCC"))
7174 continue;
7175
7176 // Those are 'weak undefined' symbols produced by gcc. We can
7177 // ignore them.
7178 // FIXME: It is unclear whether we can ignore all weak undefined
7179 // symbols:
7180 // http://lists.llvm.org/pipermail/llvm-dev/2017-October/118177.html
7181 static constexpr llvm::StringRef RegisterClasses("_Jv_RegisterClasses");
7182 static constexpr llvm::StringRef RegisterCloneTable("_ITM_registerTMCloneTable");
7183 static constexpr llvm::StringRef DeregisterCloneTable("_ITM_deregisterTMCloneTable");
7184 if (SymName == RegisterClasses ||
7185 SymName == RegisterCloneTable ||
7186 SymName == DeregisterCloneTable)
7187 continue;
7188 }
7189
7190 // If we can find the address of the symbol, we have loaded it. Skip.
7191 if (skipLoadedLibs) {
7192 std::string SymNameForDlsym = ROOT::TMetaUtils::DemangleNameForDlsym(SymName.str());
7193 if (llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymNameForDlsym))
7194 continue;
7195 }
7196
7198 std::string found = interp->getDynamicLibraryManager()->searchLibrariesForSymbol(SymName, /*searchSystem*/false);
7199 // The expected output is just filename without the full path, which
7200 // is not very accurate, because our Dyld implementation might find
7201 // a match in location a/b/c.so and if we return just c.so ROOT might
7202 // resolve it to y/z/c.so and there we might not be ABI compatible.
7203 // FIXME: Teach the users of GetSharedLibDeps to work with full paths.
7204 if (!found.empty()) {
7205 std::string cand = llvm::sys::path::filename(found).str();
7206 if (!DedupSet.insert(cand).second)
7207 continue;
7208
7209 Result += cand + ' ';
7210 }
7211 }
7212
7213 return Result;
7214}
7215
7216static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
7217{
7218 // Check if we have parsed a rootmap file.
7219 llvm::SmallString<256> rootmapName;
7220 if (!lib.startswith("lib"))
7221 rootmapName.append("lib");
7222
7223 rootmapName.append(llvm::sys::path::filename(lib));
7224 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7225
7226 if (gCling->GetRootMapFiles()->FindObject(rootmapName.c_str()))
7227 return true;
7228
7229 // Perform a last resort by dropping the lib prefix.
7230 llvm::StringRef rootmapNameNoLib = rootmapName.str();
7231 if (rootmapNameNoLib.consume_front("lib"))
7232 return gCling->GetRootMapFiles()->FindObject(rootmapNameNoLib.data());
7233
7234 return false;
7235}
7236
7237static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
7238{
7239 if (gCling->HasPCMForLibrary(lib.data()))
7240 return true;
7241
7242 return hasParsedRootmapForLibrary(lib);
7243}
7244
7245////////////////////////////////////////////////////////////////////////////////
7246/// Get the list a libraries on which the specified lib depends. The
7247/// returned string contains as first element the lib itself.
7248/// Returns 0 in case the lib does not exist or does not have
7249/// any dependencies. If useDyld is true, we iterate through all available
7250/// libraries and try to construct the dependency chain by resolving each
7251/// symbol.
7252
7253const char* TCling::GetSharedLibDeps(const char* lib, bool useDyld/* = false*/)
7254{
7255 if (llvm::sys::path::is_absolute(lib) && !llvm::sys::fs::exists(lib))
7256 return nullptr;
7257
7258 if (!hasParsedRootmapForLibrary(lib)) {
7259 llvm::SmallString<512> rootmapName(lib);
7260 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7261 if (llvm::sys::fs::exists(rootmapName)) {
7262 if (gDebug > 0)
7263 Info("Load", "loading %s", rootmapName.c_str());
7264 gInterpreter->LoadLibraryMap(rootmapName.c_str());
7265 }
7266 }
7267
7268 if (hasPrecomputedLibraryDeps(lib) && useDyld) {
7269 if (gDebug > 0)
7270 Warning("TCling::GetSharedLibDeps", "Precomputed dependencies available but scanning '%s'", lib);
7271 }
7272
7273 if (useDyld) {
7274 std::string libs = GetSharedLibImmediateDepsSlow(lib, GetInterpreterImpl());
7275 if (!libs.empty()) {
7276 fAutoLoadLibStorage.push_back(libs);
7277 return fAutoLoadLibStorage.back().c_str();
7278 }
7279 }
7280
7281 if (!fMapfile || !lib || !lib[0]) {
7282 return nullptr;
7283 }
7284 TString libname(lib);
7285 Ssiz_t idx = libname.Last('.');
7286 if (idx != kNPOS) {
7287 libname.Remove(idx);
7288 }
7289 TEnvRec* rec;
7290 TIter next(fMapfile->GetTable());
7291 size_t len = libname.Length();
7292 while ((rec = (TEnvRec*) next())) {
7293 const char* libs = rec->GetValue();
7294 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7295 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
7296 return libs;
7297 }
7298 }
7299 return nullptr;
7300}
7301
7302////////////////////////////////////////////////////////////////////////////////
7303/// If error messages are disabled, the interpreter should suppress its
7304/// failures and warning messages from stdout.
7305
7307{
7308#if defined(R__MUST_REVISIT)
7309#if R__MUST_REVISIT(6,2)
7310 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
7311#endif
7312#endif
7313 return kTRUE;
7314}
7315
7316////////////////////////////////////////////////////////////////////////////////
7317/// If error messages are disabled, the interpreter should suppress its
7318/// failures and warning messages from stdout. Return the previous state.
7319
7321{
7322#if defined(R__MUST_REVISIT)
7323#if R__MUST_REVISIT(6,2)
7324 Warning("SetErrorMessages", "Interface not available yet.");
7325#endif
7326#endif
7328}
7329
7330////////////////////////////////////////////////////////////////////////////////
7331/// Refresh the list of include paths known to the interpreter and return it
7332/// with -I prepended.
7333
7335{
7337
7338 fIncludePath = "";
7339
7340 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7341 //false - no system header, true - with flags.
7342 fInterpreter->GetIncludePaths(includePaths, false, true);
7343 if (const size_t nPaths = includePaths.size()) {
7344 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
7345
7346 for (size_t i = 0; i < nPaths; i += 2) {
7347 if (i)
7348 fIncludePath.Append(' ');
7349 fIncludePath.Append(includePaths[i].c_str());
7350
7351 if (includePaths[i] != "-I")
7352 fIncludePath.Append(' ');
7353 fIncludePath.Append('"');
7354 fIncludePath.Append(includePaths[i + 1], includePaths[i + 1].length());
7355 fIncludePath.Append('"');
7356 }
7357 }
7358
7359 return fIncludePath;
7360}
7361
7362////////////////////////////////////////////////////////////////////////////////
7363/// Return the directory containing CINT's stl cintdlls.
7364
7365const char* TCling::GetSTLIncludePath() const
7366{
7367 return "";
7368}
7369
7370//______________________________________________________________________________
7371// M I S C
7372//______________________________________________________________________________
7373
7374int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
7375{
7376 // Interface to cling function
7377 return 0;
7378}
7379
7380////////////////////////////////////////////////////////////////////////////////
7381/// Interface to cling function
7382
7383int TCling::DisplayIncludePath(FILE *fout) const
7384{
7385 assert(fout != nullptr && "DisplayIncludePath, 'fout' parameter is null");
7386
7387 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7388 //false - no system header, true - with flags.
7389 fInterpreter->GetIncludePaths(includePaths, false, true);
7390 if (const size_t nPaths = includePaths.size()) {
7391 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
7392
7393 std::string allIncludes("include path:");
7394 for (size_t i = 0; i < nPaths; i += 2) {
7395 allIncludes += ' ';
7396 allIncludes += includePaths[i];
7397
7398 if (includePaths[i] != "-I")
7399 allIncludes += ' ';
7400 allIncludes += includePaths[i + 1];
7401 }
7402
7403 fprintf(fout, "%s\n", allIncludes.c_str());
7404 }
7405
7406 return 0;
7407}
7408
7409////////////////////////////////////////////////////////////////////////////////
7410/// Interface to cling function
7411
7412void* TCling::FindSym(const char* entry) const
7413{
7415 return fInterpreter->getAddressOfGlobal(entry);
7416}
7417
7418////////////////////////////////////////////////////////////////////////////////
7419/// Let the interpreter issue a generic error, and set its error state.
7420
7421void TCling::GenericError(const char* error) const
7422{
7423#if defined(R__MUST_REVISIT)
7424#if R__MUST_REVISIT(6,2)
7425 Warning("GenericError","Interface not available yet.");
7426#endif
7427#endif
7428}
7429
7430////////////////////////////////////////////////////////////////////////////////
7431/// This routines used to return the address of the internal wrapper
7432/// function (of the interpreter) that was used to call *all* the
7433/// interpreted functions that were bytecode compiled (no longer
7434/// interpreted line by line). In Cling, there is no such
7435/// wrapper function.
7436/// In practice this routines was use to decipher whether the
7437/// pointer returns by InterfaceMethod could be used to uniquely
7438/// represent the function. In Cling if the function is in a
7439/// useable state (its compiled version is available), this is
7440/// always the case.
7441/// See TClass::GetMethod.
7442
7444{
7445 return 0;
7446}
7447
7448////////////////////////////////////////////////////////////////////////////////
7449/// Interface to cling function
7450
7452{
7453#if defined(R__MUST_REVISIT)
7454#if R__MUST_REVISIT(6,2)
7455 Warning("GetSecurityError", "Interface not available yet.");
7456#endif
7457#endif
7458 return 0;
7459}
7460
7461////////////////////////////////////////////////////////////////////////////////
7462/// Load a source file or library called path into the interpreter.
7463
7464int TCling::LoadFile(const char* path) const
7465{
7466 // Modifying the interpreter state needs locking.
7468 cling::Interpreter::CompilationResult compRes;
7469 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(".L %s", path), compRes, /*cling::Value*/nullptr);
7470 return compRes == cling::Interpreter::kFailure;
7471}
7472
7473////////////////////////////////////////////////////////////////////////////////
7474/// Load the declarations from text into the interpreter.
7475/// Note that this cannot be (top level) statements; text must contain
7476/// top level declarations.
7477/// Returns true on success, false on failure.
7478
7479Bool_t TCling::LoadText(const char* text) const
7480{
7481 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7482}
7483
7484////////////////////////////////////////////////////////////////////////////////
7485/// Interface to cling function
7486
7487const char* TCling::MapCppName(const char* name) const
7488{
7489 TTHREAD_TLS_DECL(std::string,buffer);
7491 return buffer.c_str(); // NOLINT
7492}
7493
7494////////////////////////////////////////////////////////////////////////////////
7495/// [Place holder for Mutex Lock]
7496/// Provide the interpreter with a way to
7497/// acquire a lock used to protect critical section
7498/// of its code (non-thread safe parts).
7499
7500void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7501{
7502 // nothing to do for now.
7503}
7504
7505////////////////////////////////////////////////////////////////////////////////
7506/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7507/// release a lock used to protect critical section
7508/// of its code (non-thread safe parts).
7509
7510void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7511{
7512 // nothing to do for now.
7513}
7514
7515////////////////////////////////////////////////////////////////////////////////
7516/// Returns if class AutoLoading is currently enabled.
7517
7519{
7520 if (IsFromRootCling())
7521 return false;
7522 if (!fClingCallbacks)
7523 return false;
7525}
7526
7527////////////////////////////////////////////////////////////////////////////////
7528/// Enable/Disable the AutoLoading of libraries.
7529/// Returns the old value, i.e whether it was enabled or not.
7530
7531int TCling::SetClassAutoLoading(int autoload) const
7532{
7533 // If no state change is required, exit early.
7534 // FIXME: In future we probably want to complain if we made a request which
7535 // was with the same state as before in order to catch programming errors.
7536 if ((bool) autoload == IsClassAutoLoadingEnabled())
7537 return autoload;
7538
7539 assert(fClingCallbacks && "We must have callbacks!");
7540 bool oldVal = fClingCallbacks->IsAutoLoadingEnabled();
7542 return oldVal;
7543}
7544
7545////////////////////////////////////////////////////////////////////////////////
7546/// Enable/Disable the Autoparsing of headers.
7547/// Returns the old value, i.e whether it was enabled or not.
7548
7550{
7551 bool oldVal = fHeaderParsingOnDemand;
7552 fHeaderParsingOnDemand = autoparse;
7553 return oldVal;
7554}
7555
7556////////////////////////////////////////////////////////////////////////////////
7557/// Suspend the Autoparsing of headers.
7558/// Returns the old value, i.e whether it was suspended or not.
7559
7564 return old;
7565}
7566
7567////////////////////////////////////////////////////////////////////////////////
7568/// Set a callback to receive error messages.
7569
7571{
7572#if defined(R__MUST_REVISIT)
7573#if R__MUST_REVISIT(6,2)
7574 Warning("SetErrmsgcallback", "Interface not available yet.");
7575#endif
7576#endif
7577}
7578
7580{
7581 if (enable) {
7582 auto consumer = new TClingDelegateDiagnosticPrinter(
7583 &fInterpreter->getDiagnostics().getDiagnosticOptions(),
7584 fInterpreter->getCI()->getLangOpts(),
7585 [] (clang::DiagnosticsEngine::Level Level, const std::string &Info) {
7586 if (Level == clang::DiagnosticsEngine::Warning) {
7587 ::Warning("cling", "%s", Info.c_str());
7588 } else if (Level == clang::DiagnosticsEngine::Error
7589 || Level == clang::DiagnosticsEngine::Fatal) {
7590 ::Error("cling", "%s", Info.c_str());
7591 } else {
7592 ::Info("cling", "%s", Info.c_str());
7593 }
7594 });
7595 fInterpreter->replaceDiagnosticConsumer(consumer, /*Own=*/true);
7596 } else {
7597 fInterpreter->replaceDiagnosticConsumer(nullptr);
7598 }
7599}
7600
7601
7602////////////////////////////////////////////////////////////////////////////////
7603/// Create / close a scope for temporaries. No-op for cling; use
7604/// cling::Value instead.
7605
7606void TCling::SetTempLevel(int val) const
7607{
7608}
7609
7610////////////////////////////////////////////////////////////////////////////////
7611
7612int TCling::UnloadFile(const char* path) const
7613{
7614 // Modifying the interpreter state needs locking.
7616 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7617 std::string canonical = DLM->lookupLibrary(path);
7618 if (canonical.empty()) {
7619 canonical = path;
7620 }
7621 // Unload a shared library or a source file.
7622 cling::Interpreter::CompilationResult compRes;
7623 HandleInterpreterException(GetMetaProcessorImpl(), Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/nullptr);
7624 return compRes == cling::Interpreter::kFailure;
7625}
7626
7627std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7628 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7629}
7630
7631////////////////////////////////////////////////////////////////////////////////
7632/// The call to Cling's tab complition.
7633
7634void TCling::CodeComplete(const std::string& line, size_t& cursor,
7635 std::vector<std::string>& completions)
7636{
7637 fInterpreter->codeComplete(line, cursor, completions);
7638}
7639
7640////////////////////////////////////////////////////////////////////////////////
7641/// Get the interpreter value corresponding to the statement.
7643{
7644 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7645 auto compRes = fInterpreter->evaluate(code, *V);
7646 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7647}
7648
7649////////////////////////////////////////////////////////////////////////////////
7650
7652{
7653 using namespace cling;
7654 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7656}
7657
7658////////////////////////////////////////////////////////////////////////////////
7659/// Register value as a temporary, extending its lifetime to that of the
7660/// interpreter. This is needed for TCling's compatibility interfaces
7661/// returning long - the address of the temporary objects.
7662/// As such, "simple" types don't need to be stored; they are returned by
7663/// value; only pointers / references / objects need to be stored.
7664
7665void TCling::RegisterTemporary(const cling::Value& value)
7666{
7667 if (value.isValid() && value.needsManagedAllocation()) {
7669 fTemporaries->push_back(value);
7670 }
7671}
7672
7673////////////////////////////////////////////////////////////////////////////////
7674/// If the interpreter encounters Name, check whether that is an object ROOT
7675/// could retrieve. To not re-read objects from disk, cache the name/object
7676/// pair for a given LookupCtx.
7677
7678TObject* TCling::GetObjectAddress(const char *Name, void *&LookupCtx)
7679{
7680 // The call to FindSpecialObject might induces any kind of use
7681 // of the interpreter ... (library loading, function calling, etc.)
7682 // ... and we _know_ we are in the middle of parsing, so let's make
7683 // sure to save the state and then restore it.
7684
7685 if (gDirectory) {
7686 auto iSpecObjMap = fSpecialObjectMaps.find(gDirectory);
7687 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7688 auto iSpecObj = iSpecObjMap->second.find(Name);
7689 if (iSpecObj != iSpecObjMap->second.end()) {
7690 LookupCtx = gDirectory;
7691 return iSpecObj->second;
7692 }
7693 }
7694 }
7695
7696 // Save state of the PP
7697 Sema &SemaR = fInterpreter->getSema();
7698 ASTContext& C = SemaR.getASTContext();
7699 Preprocessor &PP = SemaR.getPreprocessor();
7700 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7701 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7702 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7703 // After we have saved the token reset the current one to something which
7704 // is safe (semi colon usually means empty decl)
7705 Token& Tok = const_cast<Token&>(P.getCurToken());
7706 Tok.setKind(tok::semi);
7707
7708 // We can't PushDeclContext, because we go up and the routine that pops
7709 // the DeclContext assumes that we drill down always.
7710 // We have to be on the global context. At that point we are in a
7711 // wrapper function so the parent context must be the global.
7712 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7713 SemaR.TUScope);
7714
7715 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7716 if (specObj) {
7717 if (!LookupCtx) {
7718 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7719 } else {
7720 fSpecialObjectMaps[LookupCtx][Name] = specObj;
7721 }
7722 }
7723 return specObj;
7724}
7725
7726////////////////////////////////////////////////////////////////////////////////
7727/// Inject function as a friend into klass.
7728/// With function being f in void f() {new N::PrivKlass(); } this enables
7729/// I/O of non-public classes.
7730
7731void TCling::AddFriendToClass(clang::FunctionDecl* function,
7732 clang::CXXRecordDecl* klass) const
7733{
7734 using namespace clang;
7735 ASTContext& Ctx = klass->getASTContext();
7736 FriendDecl::FriendUnion friendUnion(function);
7737 // one dummy object for the source location
7738 SourceLocation sl;
7739 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
7740 klass->pushFriendDecl(friendDecl);
7741}
7742
7743//______________________________________________________________________________
7744//
7745// DeclId getter.
7746//
7747
7748////////////////////////////////////////////////////////////////////////////////
7749/// Return a unique identifier of the declaration represented by the
7750/// CallFunc
7751
7753{
7754 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
7755 return nullptr;
7756}
7757
7758////////////////////////////////////////////////////////////////////////////////
7759/// Return a (almost) unique identifier of the declaration represented by the
7760/// ClassInfo. In ROOT, this identifier can point to more than one TClass
7761/// when the underlying class is a template instance involving one of the
7762/// opaque typedef.
7763
7765{
7766 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
7767 return nullptr;
7768}
7769
7770////////////////////////////////////////////////////////////////////////////////
7771/// Return a unique identifier of the declaration represented by the
7772/// MethodInfo
7773
7775{
7776 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
7777 return nullptr;
7778}
7779
7780////////////////////////////////////////////////////////////////////////////////
7781/// Return a unique identifier of the declaration represented by the
7782/// MethodInfo
7783
7785{
7786 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
7787 return nullptr;
7788}
7789
7790////////////////////////////////////////////////////////////////////////////////
7791/// Return a unique identifier of the declaration represented by the
7792/// TypedefInfo
7793
7795{
7796 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
7797 return nullptr;
7798}
7799
7800//______________________________________________________________________________
7801//
7802// CallFunc interface
7803//
7804
7805////////////////////////////////////////////////////////////////////////////////
7806
7807void TCling::CallFunc_Delete(CallFunc_t* func) const
7808{
7809 delete (TClingCallFunc*) func;
7810}
7811
7812////////////////////////////////////////////////////////////////////////////////
7813
7814void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
7815{
7816 TClingCallFunc* f = (TClingCallFunc*) func;
7817 f->Exec(address);
7818}
7819
7820////////////////////////////////////////////////////////////////////////////////
7821
7822void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
7823{
7824 TClingCallFunc* f = (TClingCallFunc*) func;
7825 f->Exec(address, &val);
7826}
7827
7828////////////////////////////////////////////////////////////////////////////////
7829
7830void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
7831{
7832 TClingCallFunc* f = (TClingCallFunc*) func;
7833 f->ExecWithReturn(address, ret);
7834}
7835
7836////////////////////////////////////////////////////////////////////////////////
7837
7838void TCling::CallFunc_ExecWithArgsAndReturn(CallFunc_t* func, void* address,
7839 const void* args[] /*=0*/,
7840 int nargs /*=0*/,
7841 void* ret/*=0*/) const
7842{
7843 TClingCallFunc* f = (TClingCallFunc*) func;
7844 f->ExecWithArgsAndReturn(address, args, nargs, ret);
7845}
7846
7847////////////////////////////////////////////////////////////////////////////////
7848
7849Longptr_t TCling::CallFunc_ExecInt(CallFunc_t* func, void* address) const
7850{
7851 TClingCallFunc* f = (TClingCallFunc*) func;
7852 return f->ExecInt(address);
7853}
7854
7855////////////////////////////////////////////////////////////////////////////////
7856
7857Long64_t TCling::CallFunc_ExecInt64(CallFunc_t* func, void* address) const
7858{
7859 TClingCallFunc* f = (TClingCallFunc*) func;
7860 return f->ExecInt64(address);
7861}
7862
7863////////////////////////////////////////////////////////////////////////////////
7864
7865Double_t TCling::CallFunc_ExecDouble(CallFunc_t* func, void* address) const
7866{
7867 TClingCallFunc* f = (TClingCallFunc*) func;
7868 return f->ExecDouble(address);
7869}
7870
7871////////////////////////////////////////////////////////////////////////////////
7872
7873CallFunc_t* TCling::CallFunc_Factory() const
7874{
7876 return (CallFunc_t*) new TClingCallFunc(GetInterpreterImpl());
7877}
7878
7879////////////////////////////////////////////////////////////////////////////////
7880
7881CallFunc_t* TCling::CallFunc_FactoryCopy(CallFunc_t* func) const
7882{
7883 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
7884}
7885
7886////////////////////////////////////////////////////////////////////////////////
7887
7888MethodInfo_t* TCling::CallFunc_FactoryMethod(CallFunc_t* func) const
7889{
7890 TClingCallFunc* f = (TClingCallFunc*) func;
7891 return (MethodInfo_t*) f->FactoryMethod();
7892}
7893
7894////////////////////////////////////////////////////////////////////////////////
7895
7896void TCling::CallFunc_IgnoreExtraArgs(CallFunc_t* func, bool ignore) const
7897{
7898 TClingCallFunc* f = (TClingCallFunc*) func;
7899 f->IgnoreExtraArgs(ignore);
7900}
7901
7902////////////////////////////////////////////////////////////////////////////////
7903
7904void TCling::CallFunc_Init(CallFunc_t* func) const
7905{
7907 TClingCallFunc* f = (TClingCallFunc*) func;
7908 f->Init();
7909}
7910
7911////////////////////////////////////////////////////////////////////////////////
7912
7913bool TCling::CallFunc_IsValid(CallFunc_t* func) const
7914{
7915 TClingCallFunc* f = (TClingCallFunc*) func;
7916 return f->IsValid();
7917}
7918
7919////////////////////////////////////////////////////////////////////////////////
7920
7922TCling::CallFunc_IFacePtr(CallFunc_t * func) const
7923{
7924 TClingCallFunc* f = (TClingCallFunc*) func;
7925 return f->IFacePtr();
7926}
7927
7928////////////////////////////////////////////////////////////////////////////////
7929
7930void TCling::CallFunc_ResetArg(CallFunc_t* func) const
7931{
7932 TClingCallFunc* f = (TClingCallFunc*) func;
7933 f->ResetArg();
7934}
7935
7936////////////////////////////////////////////////////////////////////////////////
7937
7938void TCling::CallFunc_SetArg(CallFunc_t* func, Long_t param) const
7939{
7940 TClingCallFunc* f = (TClingCallFunc*) func;
7941 f->SetArg(param);
7942}
7943
7944////////////////////////////////////////////////////////////////////////////////
7945
7946void TCling::CallFunc_SetArg(CallFunc_t* func, ULong_t param) const
7947{
7948 TClingCallFunc* f = (TClingCallFunc*) func;
7949 f->SetArg(param);
7950}
7951
7952////////////////////////////////////////////////////////////////////////////////
7953
7954void TCling::CallFunc_SetArg(CallFunc_t* func, Float_t param) const
7955{
7956 TClingCallFunc* f = (TClingCallFunc*) func;
7957 f->SetArg(param);
7958}
7959
7960////////////////////////////////////////////////////////////////////////////////
7961
7962void TCling::CallFunc_SetArg(CallFunc_t* func, Double_t param) const
7963{
7964 TClingCallFunc* f = (TClingCallFunc*) func;
7965 f->SetArg(param);
7966}
7967
7968////////////////////////////////////////////////////////////////////////////////
7969
7970void TCling::CallFunc_SetArg(CallFunc_t* func, Long64_t param) const
7971{
7972 TClingCallFunc* f = (TClingCallFunc*) func;
7973 f->SetArg(param);
7974}
7975
7976////////////////////////////////////////////////////////////////////////////////
7977
7978void TCling::CallFunc_SetArg(CallFunc_t* func, ULong64_t param) const
7979{
7980 TClingCallFunc* f = (TClingCallFunc*) func;
7981 f->SetArg(param);
7982}
7983
7984////////////////////////////////////////////////////////////////////////////////
7985
7986void TCling::CallFunc_SetArgArray(CallFunc_t* func, Longptr_t* paramArr, Int_t nparam) const
7987{
7988 TClingCallFunc* f = (TClingCallFunc*) func;
7989 f->SetArgArray(paramArr, nparam);
7990}
7991
7992////////////////////////////////////////////////////////////////////////////////
7993
7994void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
7995{
7996 TClingCallFunc* f = (TClingCallFunc*) func;
7997 f->SetArgs(param);
7998}
7999
8000////////////////////////////////////////////////////////////////////////////////
8001
8002void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Longptr_t* offset) const
8003{
8004 TClingCallFunc* f = (TClingCallFunc*) func;
8005 TClingClassInfo* ci = (TClingClassInfo*) info;
8006 f->SetFunc(ci, method, params, offset);
8007}
8008
8009////////////////////////////////////////////////////////////////////////////////
8010
8011void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Longptr_t* offset) const
8012{
8013 TClingCallFunc* f = (TClingCallFunc*) func;
8014 TClingClassInfo* ci = (TClingClassInfo*) info;
8015 f->SetFunc(ci, method, params, objectIsConst, offset);
8016}
8017////////////////////////////////////////////////////////////////////////////////
8018
8019void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
8020{
8021 TClingCallFunc* f = (TClingCallFunc*) func;
8022 TClingMethodInfo* minfo = (TClingMethodInfo*) info;
8023 f->SetFunc(minfo);
8024}
8025
8026////////////////////////////////////////////////////////////////////////////////
8027/// Interface to cling function
8028
8029void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8030{
8031 TClingCallFunc* f = (TClingCallFunc*) func;
8032 TClingClassInfo* ci = (TClingClassInfo*) info;
8033 f->SetFuncProto(ci, method, proto, offset, mode);
8034}
8035
8036////////////////////////////////////////////////////////////////////////////////
8037/// Interface to cling function
8038
8039void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8040{
8041 TClingCallFunc* f = (TClingCallFunc*) func;
8042 TClingClassInfo* ci = (TClingClassInfo*) info;
8043 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
8044}
8045
8046////////////////////////////////////////////////////////////////////////////////
8047/// Interface to cling function
8048
8049void 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
8050{
8051 TClingCallFunc* f = (TClingCallFunc*) func;
8052 TClingClassInfo* ci = (TClingClassInfo*) info;
8053 llvm::SmallVector<clang::QualType, 4> funcProto;
8054 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8055 iter != end; ++iter) {
8056 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8057 }
8058 f->SetFuncProto(ci, method, funcProto, offset, mode);
8059}
8060
8061////////////////////////////////////////////////////////////////////////////////
8062/// Interface to cling function
8063
8064void 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
8065{
8066 TClingCallFunc* f = (TClingCallFunc*) func;
8067 TClingClassInfo* ci = (TClingClassInfo*) info;
8068 llvm::SmallVector<clang::QualType, 4> funcProto;
8069 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8070 iter != end; ++iter) {
8071 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8072 }
8073 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
8074}
8075
8076std::string TCling::CallFunc_GetWrapperCode(CallFunc_t *func) const
8077{
8078 TClingCallFunc *f = (TClingCallFunc *)func;
8079 std::string wrapper_name;
8080 std::string wrapper;
8081 f->get_wrapper_code(wrapper_name, wrapper);
8082 return wrapper;
8083}
8084
8085//______________________________________________________________________________
8086//
8087// ClassInfo interface
8088//
8089
8090////////////////////////////////////////////////////////////////////////////////
8091/// Return true if the entity pointed to by 'declid' is declared in
8092/// the context described by 'info'. If info is null, look into the
8093/// global scope (translation unit scope).
8094
8095Bool_t TCling::ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const
8096{
8097 if (!declid)
8098 return kFALSE;
8099
8100 const clang::DeclContext *ctxt = nullptr;
8101 if (info) {
8102 ctxt = clang::Decl::castToDeclContext(((TClingClassInfo*)info)->GetDecl());
8103 } else {
8104 ctxt = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
8105 }
8106 if (!ctxt)
8107 return kFALSE;
8108
8109 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
8110 if (!decl)
8111 return kFALSE;
8112
8113 const clang::DeclContext *declDC = decl->getDeclContext();
8114 // ClassInfo_t-s are always "spellable" scopes, never unnamed or inline ones.
8115 while (true) {
8116 if (declDC->isTransparentContext()) {
8117 declDC = declDC->getParent();
8118 continue;
8119 }
8120 if (const auto *declRD = llvm::dyn_cast<clang::RecordDecl>(declDC)) {
8121 if (declRD->isAnonymousStructOrUnion()) {
8122 declDC = declRD->getParent();
8123 continue;
8124 }
8125 }
8126 if (const auto *declNS = llvm::dyn_cast<clang::NamespaceDecl>(declDC)) {
8127 if (declNS->isAnonymousNamespace() || declNS->isInlineNamespace()) {
8128 declDC = declNS->getParent();
8129 continue;
8130 }
8131 }
8132 break;
8133 }
8134
8135 return declDC->Equals(ctxt);
8136}
8137
8138////////////////////////////////////////////////////////////////////////////////
8139
8141{
8142 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8143 return TClinginfo->ClassProperty();
8144}
8145
8146////////////////////////////////////////////////////////////////////////////////
8147
8148void TCling::ClassInfo_Delete(ClassInfo_t* cinfo) const
8149{
8150 delete (TClingClassInfo*) cinfo;
8151}
8152
8153////////////////////////////////////////////////////////////////////////////////
8154
8155void TCling::ClassInfo_Delete(ClassInfo_t* cinfo, void* arena) const
8156{
8157 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8158 TClinginfo->Delete(arena,*fNormalizedCtxt);
8159}
8160
8161////////////////////////////////////////////////////////////////////////////////
8162
8163void TCling::ClassInfo_DeleteArray(ClassInfo_t* cinfo, void* arena, bool dtorOnly) const
8164{
8165 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8166 TClinginfo->DeleteArray(arena, dtorOnly,*fNormalizedCtxt);
8167}
8168
8169////////////////////////////////////////////////////////////////////////////////
8170
8171void TCling::ClassInfo_Destruct(ClassInfo_t* cinfo, void* arena) const
8172{
8173 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8174 TClinginfo->Destruct(arena,*fNormalizedCtxt);
8175}
8176
8177////////////////////////////////////////////////////////////////////////////////
8178
8179ClassInfo_t* TCling::ClassInfo_Factory(Bool_t all) const
8180{
8182 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), all);
8183}
8184
8185////////////////////////////////////////////////////////////////////////////////
8186
8187ClassInfo_t* TCling::ClassInfo_Factory(ClassInfo_t* cinfo) const
8188{
8189 return (ClassInfo_t*) new TClingClassInfo(*(TClingClassInfo*)cinfo);
8190}
8191
8192////////////////////////////////////////////////////////////////////////////////
8193
8194ClassInfo_t* TCling::ClassInfo_Factory(const char* name) const
8195{
8197 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), name);
8198}
8199
8200ClassInfo_t* TCling::ClassInfo_Factory(DeclId_t declid) const
8201{
8203 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), (const clang::Decl*)declid);
8204}
8205
8206
8207////////////////////////////////////////////////////////////////////////////////
8208
8209int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
8210{
8211 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8212 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
8213}
8214
8215////////////////////////////////////////////////////////////////////////////////
8216
8217bool TCling::ClassInfo_HasDefaultConstructor(ClassInfo_t* cinfo, Bool_t testio) const
8218{
8219 TClingClassInfo *TClinginfo = (TClingClassInfo *) cinfo;
8221}
8222
8223////////////////////////////////////////////////////////////////////////////////
8224
8225bool TCling::ClassInfo_HasMethod(ClassInfo_t* cinfo, const char* name) const
8226{
8227 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8228 return TClinginfo->HasMethod(name);
8229}
8230
8231////////////////////////////////////////////////////////////////////////////////
8232
8233void TCling::ClassInfo_Init(ClassInfo_t* cinfo, const char* name) const
8234{
8236 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8237 TClinginfo->Init(name);
8238}
8239
8240////////////////////////////////////////////////////////////////////////////////
8241
8242void TCling::ClassInfo_Init(ClassInfo_t* cinfo, int tagnum) const
8243{
8245 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8246 TClinginfo->Init(tagnum);
8247}
8248
8249////////////////////////////////////////////////////////////////////////////////
8250
8251bool TCling::ClassInfo_IsBase(ClassInfo_t* cinfo, const char* name) const
8252{
8253 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8254 return TClinginfo->IsBase(name);
8255}
8256
8257////////////////////////////////////////////////////////////////////////////////
8258
8259bool TCling::ClassInfo_IsEnum(const char* name) const
8260{
8262}
8263
8264////////////////////////////////////////////////////////////////////////////////
8265
8267{
8268 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8269 return TClinginfo->IsScopedEnum();
8270}
8271
8272
8273////////////////////////////////////////////////////////////////////////////////
8274
8276{
8277 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8278 return TClinginfo->GetUnderlyingType();
8279}
8280
8281
8282////////////////////////////////////////////////////////////////////////////////
8283
8284bool TCling::ClassInfo_IsLoaded(ClassInfo_t* cinfo) const
8285{
8286 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8287 return TClinginfo->IsLoaded();
8288}
8289
8290////////////////////////////////////////////////////////////////////////////////
8291
8292bool TCling::ClassInfo_IsValid(ClassInfo_t* cinfo) const
8293{
8294 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8295 return TClinginfo->IsValid();
8296}
8297
8298////////////////////////////////////////////////////////////////////////////////
8299
8300bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8301{
8302 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8303 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
8304}
8305
8306////////////////////////////////////////////////////////////////////////////////
8307
8308bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8309{
8310 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8311 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8312}
8313
8314////////////////////////////////////////////////////////////////////////////////
8315
8316int TCling::ClassInfo_Next(ClassInfo_t* cinfo) const
8317{
8318 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8319 return TClinginfo->Next();
8320}
8321
8322////////////////////////////////////////////////////////////////////////////////
8323
8324void* TCling::ClassInfo_New(ClassInfo_t* cinfo) const
8325{
8326 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8327 return TClinginfo->New(*fNormalizedCtxt);
8328}
8329
8330////////////////////////////////////////////////////////////////////////////////
8331
8332void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n) const
8333{
8334 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8335 return TClinginfo->New(n,*fNormalizedCtxt);
8336}
8337
8338////////////////////////////////////////////////////////////////////////////////
8339
8340void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n, void* arena) const
8341{
8342 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8343 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8344}
8345
8346////////////////////////////////////////////////////////////////////////////////
8347
8348void* TCling::ClassInfo_New(ClassInfo_t* cinfo, void* arena) const
8349{
8350 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8351 return TClinginfo->New(arena,*fNormalizedCtxt);
8352}
8353
8354////////////////////////////////////////////////////////////////////////////////
8355
8356Long_t TCling::ClassInfo_Property(ClassInfo_t* cinfo) const
8357{
8358 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8359 return TClinginfo->Property();
8360}
8361
8362////////////////////////////////////////////////////////////////////////////////
8363
8364int TCling::ClassInfo_Size(ClassInfo_t* cinfo) const
8365{
8366 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8367 return TClinginfo->Size();
8368}
8369
8370////////////////////////////////////////////////////////////////////////////////
8371
8372Longptr_t TCling::ClassInfo_Tagnum(ClassInfo_t* cinfo) const
8373{
8374 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8375 return TClinginfo->Tagnum();
8376}
8377
8378////////////////////////////////////////////////////////////////////////////////
8379
8380const char* TCling::ClassInfo_FileName(ClassInfo_t* cinfo) const
8381{
8382 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8383 return TClinginfo->FileName();
8384}
8385
8386////////////////////////////////////////////////////////////////////////////////
8387
8388const char* TCling::ClassInfo_FullName(ClassInfo_t* cinfo) const
8389{
8390 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8391 TTHREAD_TLS_DECL(std::string,output);
8392 TClinginfo->FullName(output,*fNormalizedCtxt);
8393 return output.c_str(); // NOLINT
8394}
8395
8396////////////////////////////////////////////////////////////////////////////////
8397
8398const char* TCling::ClassInfo_Name(ClassInfo_t* cinfo) const
8399{
8400 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8401 return TClinginfo->Name();
8402}
8403
8404////////////////////////////////////////////////////////////////////////////////
8405
8406const char* TCling::ClassInfo_Title(ClassInfo_t* cinfo) const
8407{
8408 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8409 return TClinginfo->Title();
8410}
8411
8412////////////////////////////////////////////////////////////////////////////////
8413
8414const char* TCling::ClassInfo_TmpltName(ClassInfo_t* cinfo) const
8415{
8416 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8417 return TClinginfo->TmpltName();
8418}
8419
8420
8421
8422//______________________________________________________________________________
8423//
8424// BaseClassInfo interface
8425//
8426
8427////////////////////////////////////////////////////////////////////////////////
8428
8429void TCling::BaseClassInfo_Delete(BaseClassInfo_t* bcinfo) const
8430{
8431 delete(TClingBaseClassInfo*) bcinfo;
8432}
8433
8434////////////////////////////////////////////////////////////////////////////////
8435
8436BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo) const
8437{
8439 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8440 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo);
8441}
8442
8443////////////////////////////////////////////////////////////////////////////////
8444
8445BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* derived,
8446 ClassInfo_t* base) const
8447{
8449 TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
8450 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) base;
8451 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo, TClinginfoBase);
8452}
8453
8454////////////////////////////////////////////////////////////////////////////////
8455
8456int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo) const
8457{
8458 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8459 return TClinginfo->Next();
8460}
8461
8462////////////////////////////////////////////////////////////////////////////////
8463
8464int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo, int onlyDirect) const
8465{
8466 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8467 return TClinginfo->Next(onlyDirect);
8468}
8469
8470////////////////////////////////////////////////////////////////////////////////
8471
8472Longptr_t TCling::BaseClassInfo_Offset(BaseClassInfo_t* toBaseClassInfo, void * address, bool isDerivedObject) const
8473{
8474 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) toBaseClassInfo;
8475 return TClinginfo->Offset(address, isDerivedObject);
8476}
8477
8478////////////////////////////////////////////////////////////////////////////////
8479
8480Longptr_t TCling::ClassInfo_GetBaseOffset(ClassInfo_t* fromDerived, ClassInfo_t* toBase, void * address, bool isDerivedObject) const
8481{
8482 TClingClassInfo* TClinginfo = (TClingClassInfo*) fromDerived;
8483 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) toBase;
8484 // Offset to the class itself.
8485 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8486 return 0;
8487 }
8488 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8489}
8490
8491////////////////////////////////////////////////////////////////////////////////
8492
8493Long_t TCling::BaseClassInfo_Property(BaseClassInfo_t* bcinfo) const
8494{
8495 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8496 return TClinginfo->Property();
8497}
8498
8499////////////////////////////////////////////////////////////////////////////////
8500
8501ClassInfo_t *TCling::BaseClassInfo_ClassInfo(BaseClassInfo_t *bcinfo) const
8502{
8503 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8504 return (ClassInfo_t *)TClinginfo->GetBase();
8505}
8506
8507////////////////////////////////////////////////////////////////////////////////
8508
8509Longptr_t TCling::BaseClassInfo_Tagnum(BaseClassInfo_t* bcinfo) const
8510{
8511 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8512 return TClinginfo->Tagnum();
8513}
8514
8515////////////////////////////////////////////////////////////////////////////////
8516
8517const char* TCling::BaseClassInfo_FullName(BaseClassInfo_t* bcinfo) const
8518{
8519 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8520 TTHREAD_TLS_DECL(std::string,output);
8521 TClinginfo->FullName(output,*fNormalizedCtxt);
8522 return output.c_str(); // NOLINT
8523}
8524
8525////////////////////////////////////////////////////////////////////////////////
8526
8527const char* TCling::BaseClassInfo_Name(BaseClassInfo_t* bcinfo) const
8528{
8529 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8530 return TClinginfo->Name();
8531}
8532
8533////////////////////////////////////////////////////////////////////////////////
8534
8535const char* TCling::BaseClassInfo_TmpltName(BaseClassInfo_t* bcinfo) const
8536{
8537 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8538 return TClinginfo->TmpltName();
8539}
8540
8541//______________________________________________________________________________
8542//
8543// DataMemberInfo interface
8544//
8545
8546////////////////////////////////////////////////////////////////////////////////
8547
8548int TCling::DataMemberInfo_ArrayDim(DataMemberInfo_t* dminfo) const
8549{
8550 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8551 return TClinginfo->ArrayDim();
8552}
8553
8554////////////////////////////////////////////////////////////////////////////////
8555
8556void TCling::DataMemberInfo_Delete(DataMemberInfo_t* dminfo) const
8557{
8558 delete(TClingDataMemberInfo*) dminfo;
8559}
8560
8561////////////////////////////////////////////////////////////////////////////////
8562
8563DataMemberInfo_t* TCling::DataMemberInfo_Factory(ClassInfo_t* clinfo, TDictionary::EMemberSelection selection) const
8564{
8566 TClingClassInfo* TClingclass_info = (TClingClassInfo*) clinfo;
8567 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), TClingclass_info, selection);
8568}
8569
8570////////////////////////////////////////////////////////////////////////////////
8571
8572DataMemberInfo_t* TCling::DataMemberInfo_Factory(DeclId_t declid, ClassInfo_t* clinfo) const
8573{
8575 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8576 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8577 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), vd, (TClingClassInfo*)clinfo);
8578}
8579
8580////////////////////////////////////////////////////////////////////////////////
8581
8582DataMemberInfo_t* TCling::DataMemberInfo_FactoryCopy(DataMemberInfo_t* dminfo) const
8583{
8584 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8585 return (DataMemberInfo_t*) new TClingDataMemberInfo(*TClinginfo);
8586}
8587
8588////////////////////////////////////////////////////////////////////////////////
8589
8590bool TCling::DataMemberInfo_IsValid(DataMemberInfo_t* dminfo) const
8591{
8592 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8593 return TClinginfo->IsValid();
8594}
8595
8596////////////////////////////////////////////////////////////////////////////////
8597
8598int TCling::DataMemberInfo_MaxIndex(DataMemberInfo_t* dminfo, Int_t dim) const
8599{
8600 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8601 return TClinginfo->MaxIndex(dim);
8602}
8603
8604////////////////////////////////////////////////////////////////////////////////
8605
8606int TCling::DataMemberInfo_Next(DataMemberInfo_t* dminfo) const
8607{
8608 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8609 return TClinginfo->Next();
8610}
8611
8612////////////////////////////////////////////////////////////////////////////////
8613
8614Longptr_t TCling::DataMemberInfo_Offset(DataMemberInfo_t* dminfo) const
8615{
8616 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8617 return TClinginfo->Offset();
8618}
8619
8620////////////////////////////////////////////////////////////////////////////////
8621
8622Long_t TCling::DataMemberInfo_Property(DataMemberInfo_t* dminfo) const
8623{
8624 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8625 return TClinginfo->Property();
8626}
8627
8628////////////////////////////////////////////////////////////////////////////////
8629
8630Long_t TCling::DataMemberInfo_TypeProperty(DataMemberInfo_t* dminfo) const
8631{
8632 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8633 return TClinginfo->TypeProperty();
8634}
8635
8636////////////////////////////////////////////////////////////////////////////////
8637
8638int TCling::DataMemberInfo_TypeSize(DataMemberInfo_t* dminfo) const
8639{
8640 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8641 return TClinginfo->TypeSize();
8642}
8643
8644////////////////////////////////////////////////////////////////////////////////
8645
8646const char* TCling::DataMemberInfo_TypeName(DataMemberInfo_t* dminfo) const
8647{
8648 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8649 return TClinginfo->TypeName();
8650}
8651
8652////////////////////////////////////////////////////////////////////////////////
8653
8654const char* TCling::DataMemberInfo_TypeTrueName(DataMemberInfo_t* dminfo) const
8655{
8656 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8657 return TClinginfo->TypeTrueName(*fNormalizedCtxt);
8658}
8659
8660////////////////////////////////////////////////////////////////////////////////
8661
8662const char* TCling::DataMemberInfo_Name(DataMemberInfo_t* dminfo) const
8663{
8664 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8665 return TClinginfo->Name();
8666}
8667
8668////////////////////////////////////////////////////////////////////////////////
8669
8670const char* TCling::DataMemberInfo_Title(DataMemberInfo_t* dminfo) const
8671{
8672 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8673 return TClinginfo->Title();
8674}
8675
8676////////////////////////////////////////////////////////////////////////////////
8677
8678const char* TCling::DataMemberInfo_ValidArrayIndex(DataMemberInfo_t* dminfo) const
8679{
8680 TTHREAD_TLS_DECL(std::string,result);
8681
8682 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8683 result = TClinginfo->ValidArrayIndex().str();
8684 return result.c_str(); // NOLINT
8685}
8686
8687////////////////////////////////////////////////////////////////////////////////
8688
8689void TCling::SetDeclAttr(DeclId_t declId, const char* attribute)
8690{
8691 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8692 ASTContext &C = decl->getASTContext();
8693 decl->addAttr(AnnotateAttr::CreateImplicit(C, attribute));
8694}
8695
8696//______________________________________________________________________________
8697//
8698// Function Template interface
8699//
8700
8701////////////////////////////////////////////////////////////////////////////////
8702
8703static void ConstructorName(std::string &name, const clang::Decl *decl,
8704 cling::Interpreter &interp,
8705 const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
8706{
8707 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8708 if (!td) return;
8709
8710 clang::QualType qualType(td->getTypeForDecl(),0);
8711 ROOT::TMetaUtils::GetNormalizedName(name, qualType, interp, normCtxt);
8712 unsigned int level = 0;
8713 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8714 if (name[cursor] == '>') ++level;
8715 else if (name[cursor] == '<' && level) --level;
8716 else if (level == 0 && name[cursor] == ':') {
8717 name.erase(0,cursor+1);
8718 break;
8719 }
8720 }
8721}
8722
8723////////////////////////////////////////////////////////////////////////////////
8724
8725void TCling::GetFunctionName(const clang::Decl *decl, std::string &output) const
8726{
8727 output.clear();
8728
8729 const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(decl);
8730 if (const auto *USD = llvm::dyn_cast<clang::UsingShadowDecl>(decl)) {
8731 FD = llvm::dyn_cast<clang::FunctionDecl>(USD->getTargetDecl());
8732 }
8733 if (!FD) {
8734 Error("GetFunctionName", "NULL Decl!");
8735 return;
8736 }
8737
8738 // For using-decls, show "Derived", not "Base", i.e. use the
8739 // name of the decl context of the UsingShadowDecl (aka `decl`)
8740 // not the name of FD's decl context.
8741 if (llvm::isa<clang::CXXConstructorDecl>(FD))
8742 {
8744
8745 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
8746 {
8748 output.insert(output.begin(), '~');
8749 } else {
8750 llvm::raw_string_ostream stream(output);
8751 auto printPolicy = decl->getASTContext().getPrintingPolicy();
8752 // Don't trigger fopen of the source file to count lines:
8753 printPolicy.AnonymousTagLocations = false;
8754 FD->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
8755 }
8756}
8757
8758////////////////////////////////////////////////////////////////////////////////
8759/// Return a unique identifier of the declaration represented by the
8760/// FuncTempInfo
8761
8763{
8764 return (DeclId_t)info;
8765}
8766
8767////////////////////////////////////////////////////////////////////////////////
8768/// Delete the FuncTempInfo_t
8769
8770void TCling::FuncTempInfo_Delete(FuncTempInfo_t * /* ft_info */) const
8771{
8772 // Currently the address of ft_info is actually the decl itself,
8773 // so we have nothing to do.
8774}
8775
8776////////////////////////////////////////////////////////////////////////////////
8777/// Construct a FuncTempInfo_t
8778
8779FuncTempInfo_t *TCling::FuncTempInfo_Factory(DeclId_t declid) const
8780{
8781 // Currently the address of ft_info is actually the decl itself,
8782 // so we have nothing to do.
8783
8784 return (FuncTempInfo_t*)const_cast<void*>(declid);
8785}
8786
8787////////////////////////////////////////////////////////////////////////////////
8788/// Construct a FuncTempInfo_t
8789
8790FuncTempInfo_t *TCling::FuncTempInfo_FactoryCopy(FuncTempInfo_t *ft_info) const
8791{
8792 // Currently the address of ft_info is actually the decl itself,
8793 // so we have nothing to do.
8794
8795 return (FuncTempInfo_t*)ft_info;
8796}
8797
8798////////////////////////////////////////////////////////////////////////////////
8799/// Check validity of a FuncTempInfo_t
8800
8801Bool_t TCling::FuncTempInfo_IsValid(FuncTempInfo_t *t_info) const
8802{
8803 // Currently the address of ft_info is actually the decl itself,
8804 // so we have nothing to do.
8805
8806 return t_info != nullptr;
8807}
8808
8809////////////////////////////////////////////////////////////////////////////////
8810/// Return the maximum number of template arguments of the
8811/// function template described by ft_info.
8812
8813UInt_t TCling::FuncTempInfo_TemplateNargs(FuncTempInfo_t *ft_info) const
8814{
8815 if (!ft_info) return 0;
8816 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8817 return ft->getTemplateParameters()->size();
8818}
8819
8820////////////////////////////////////////////////////////////////////////////////
8821/// Return the number of required template arguments of the
8822/// function template described by ft_info.
8823
8825{
8826 if (!ft_info) return 0;
8827 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8828 return ft->getTemplateParameters()->getMinRequiredArguments();
8829}
8830
8831////////////////////////////////////////////////////////////////////////////////
8832/// Return the property of the function template.
8833
8834Long_t TCling::FuncTempInfo_Property(FuncTempInfo_t *ft_info) const
8835{
8836 if (!ft_info) return 0;
8837
8838 long property = 0L;
8839 property |= kIsCompiled;
8840
8841 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8842
8843 switch (ft->getAccess()) {
8844 case clang::AS_public:
8845 property |= kIsPublic;
8846 break;
8847 case clang::AS_protected:
8848 property |= kIsProtected;
8849 break;
8850 case clang::AS_private:
8851 property |= kIsPrivate;
8852 break;
8853 case clang::AS_none:
8854 if (ft->getDeclContext()->isNamespace())
8856 break;
8857 default:
8858 // IMPOSSIBLE
8859 assert(false && "Unexpected value for the access property value in Clang");
8860 break;
8861 }
8862
8863 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8864 if (const clang::CXXMethodDecl *md =
8865 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
8866 if (md->getMethodQualifiers().hasConst()) {
8867 property |= kIsConstant | kIsConstMethod;
8868 }
8869 if (md->isVirtual()) {
8870 property |= kIsVirtual;
8871 }
8872 if (md->isPure()) {
8873 property |= kIsPureVirtual;
8874 }
8875 if (const clang::CXXConstructorDecl *cd =
8876 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
8877 if (cd->isExplicit()) {
8878 property |= kIsExplicit;
8879 }
8880 }
8881 else if (const clang::CXXConversionDecl *cd =
8882 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
8883 if (cd->isExplicit()) {
8884 property |= kIsExplicit;
8885 }
8886 }
8887 }
8888 return property;
8889}
8890
8891////////////////////////////////////////////////////////////////////////////////
8892/// Return the property not already defined in Property
8893/// See TDictionary's EFunctionProperty
8894
8895Long_t TCling::FuncTempInfo_ExtraProperty(FuncTempInfo_t* ft_info) const
8896{
8897 if (!ft_info) return 0;
8898
8899 long property = 0L;
8900 property |= kIsCompiled;
8901
8902 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8903 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8904
8905 if (fd->isOverloadedOperator())
8907 if (llvm::isa<clang::CXXConversionDecl>(fd))
8909 if (llvm::isa<clang::CXXConstructorDecl>(fd))
8911 if (llvm::isa<clang::CXXDestructorDecl>(fd))
8913 if (fd->isInlined())
8915 return property;
8916}
8917
8918////////////////////////////////////////////////////////////////////////////////
8919/// Return the name of this function template.
8920
8921void TCling::FuncTempInfo_Name(FuncTempInfo_t *ft_info, TString &output) const
8922{
8923 output.Clear();
8924 if (!ft_info) return;
8925 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8926 std::string buf;
8927 GetFunctionName(ft->getTemplatedDecl(), buf);
8928 output = buf;
8929}
8930
8931////////////////////////////////////////////////////////////////////////////////
8932/// Return the comments associates with this function template.
8933
8934void TCling::FuncTempInfo_Title(FuncTempInfo_t *ft_info, TString &output) const
8935{
8936 output.Clear();
8937 if (!ft_info) return;
8938 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8939
8940 // Iterate over the redeclarations, we can have multiple definitions in the
8941 // redecl chain (came from merging of pcms).
8942 if (const RedeclarableTemplateDecl *AnnotFD
8943 = ROOT::TMetaUtils::GetAnnotatedRedeclarable((const RedeclarableTemplateDecl*)ft)) {
8944 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
8945 output = A->getAnnotation().str();
8946 return;
8947 }
8948 }
8949 if (!ft->isFromASTFile()) {
8950 // Try to get the comment from the header file if present
8951 // but not for decls from AST file, where rootcling would have
8952 // created an annotation
8954 }
8955}
8956
8957
8958//______________________________________________________________________________
8959//
8960// MethodInfo interface
8961//
8962
8963////////////////////////////////////////////////////////////////////////////////
8964/// Interface to cling function
8965
8966void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
8967{
8968 delete(TClingMethodInfo*) minfo;
8969}
8970
8971////////////////////////////////////////////////////////////////////////////////
8972
8973void TCling::MethodInfo_CreateSignature(MethodInfo_t* minfo, TString& signature) const
8974{
8975 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8976 // The next call locks the interpreter mutex.
8977 info->CreateSignature(signature);
8978}
8979
8980////////////////////////////////////////////////////////////////////////////////
8981
8982MethodInfo_t* TCling::MethodInfo_Factory() const
8983{
8985 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl());
8986}
8987
8988////////////////////////////////////////////////////////////////////////////////
8989
8990MethodInfo_t* TCling::MethodInfo_Factory(ClassInfo_t* clinfo) const
8991{
8993 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
8994}
8995
8996////////////////////////////////////////////////////////////////////////////////
8997
8998MethodInfo_t* TCling::MethodInfo_Factory(DeclId_t declid) const
8999{
9000 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
9002 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), decl);
9003}
9004
9005////////////////////////////////////////////////////////////////////////////////
9006
9007MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
9008{
9009 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
9010}
9011
9012////////////////////////////////////////////////////////////////////////////////
9013
9014void* TCling::MethodInfo_InterfaceMethod(MethodInfo_t* minfo) const
9015{
9016 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9017 // The next call locks the interpreter mutex.
9018 return info->InterfaceMethod();
9019}
9020
9021////////////////////////////////////////////////////////////////////////////////
9022
9023bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
9024{
9025 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9026 return info->IsValid();
9027}
9028
9029////////////////////////////////////////////////////////////////////////////////
9030
9031int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
9032{
9033 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9034 return info->NArg();
9035}
9036
9037////////////////////////////////////////////////////////////////////////////////
9038
9039int TCling::MethodInfo_NDefaultArg(MethodInfo_t* minfo) const
9040{
9041 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9042 return info->NDefaultArg();
9043}
9044
9045////////////////////////////////////////////////////////////////////////////////
9046
9047int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
9048{
9049 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9050 return info->Next();
9051}
9052
9053////////////////////////////////////////////////////////////////////////////////
9054
9055Long_t TCling::MethodInfo_Property(MethodInfo_t* minfo) const
9056{
9057 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9058 // The next call locks the interpreter mutex.
9059 return info->Property();
9060}
9061
9062////////////////////////////////////////////////////////////////////////////////
9063
9065{
9066 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9067 // The next call locks the interpreter mutex.
9068 return info->ExtraProperty();
9069}
9070
9071////////////////////////////////////////////////////////////////////////////////
9072
9073TypeInfo_t* TCling::MethodInfo_Type(MethodInfo_t* minfo) const
9074{
9075 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9076 // The next call locks the interpreter mutex.
9077 return (TypeInfo_t*)info->Type();
9078}
9079
9080////////////////////////////////////////////////////////////////////////////////
9081
9082const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
9083{
9084 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9085 TTHREAD_TLS_DECL(TString, mangled_name);
9086 // The next call locks the interpreter mutex.
9087 mangled_name = info->GetMangledName();
9088 return mangled_name;
9089}
9090
9091////////////////////////////////////////////////////////////////////////////////
9092
9093const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
9094{
9095 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9096 // The next call locks the interpreter mutex.
9097 return info->GetPrototype();
9098}
9099
9100////////////////////////////////////////////////////////////////////////////////
9101
9102const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
9103{
9104 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9105 // The next call locks the interpreter mutex.
9106 return info->Name();
9107}
9108
9109////////////////////////////////////////////////////////////////////////////////
9110
9111const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
9112{
9113 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9114 // The next call locks the interpreter mutex.
9115 return info->TypeName();
9116}
9117
9118////////////////////////////////////////////////////////////////////////////////
9119
9120std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
9121{
9122 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9123 // The next part locks the interpreter mutex.
9124 if (info && info->IsValid())
9125 return info->Type()->NormalizedName(*fNormalizedCtxt);
9126 else
9127 return "";
9128}
9129
9130////////////////////////////////////////////////////////////////////////////////
9131
9132const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
9133{
9134 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9135 // The next call locks the interpreter mutex.
9136 return info->Title();
9137}
9138
9139////////////////////////////////////////////////////////////////////////////////
9140
9142{
9143 if (func) {
9144 return MethodInfo_MethodCallReturnType(func->fInfo);
9145 } else {
9146 return EReturnType::kOther;
9147 }
9148}
9149
9150////////////////////////////////////////////////////////////////////////////////
9151
9153{
9154 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9155 if (info && info->IsValid()) {
9156 TClingTypeInfo *typeinfo = info->Type();
9157 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
9158 if (QT->isEnumeralType()) {
9159 return EReturnType::kLong;
9160 } else if (QT->isPointerType()) {
9161 // Look for char*
9162 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
9163 if ( QT->isCharType() ) {
9164 return EReturnType::kString;
9165 } else {
9166 return EReturnType::kOther;
9167 }
9168 } else if ( QT->isFloatingType() ) {
9169 int sz = typeinfo->Size();
9170 if (sz == 4 || sz == 8) {
9171 // Support only float and double.
9172 return EReturnType::kDouble;
9173 } else {
9174 return EReturnType::kOther;
9175 }
9176 } else if ( QT->isIntegerType() ) {
9177 int sz = typeinfo->Size();
9178 if (sz <= 8) {
9179 // Support only up to long long ... but
9180 // FIXME the TMethodCall::Execute only
9181 // return long (4 bytes) ...
9182 // The v5 implementation of TMethodCall::ReturnType
9183 // was not making the distinction so we let it go
9184 // as is for now, but we really need to upgrade
9185 // TMethodCall::Execute ...
9186 return EReturnType::kLong;
9187 } else {
9188 return EReturnType::kOther;
9189 }
9190 } else {
9191 return EReturnType::kOther;
9192 }
9193 } else {
9194 return EReturnType::kOther;
9195 }
9196}
9197
9198//______________________________________________________________________________
9199//
9200// MethodArgInfo interface
9201//
9202
9203////////////////////////////////////////////////////////////////////////////////
9204
9205void TCling::MethodArgInfo_Delete(MethodArgInfo_t* marginfo) const
9206{
9207 delete(TClingMethodArgInfo*) marginfo;
9208}
9209
9210////////////////////////////////////////////////////////////////////////////////
9211
9212MethodArgInfo_t* TCling::MethodArgInfo_Factory() const
9213{
9215 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl());
9216}
9217
9218////////////////////////////////////////////////////////////////////////////////
9219
9220MethodArgInfo_t* TCling::MethodArgInfo_Factory(MethodInfo_t *minfo) const
9221{
9223 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl(), (TClingMethodInfo*)minfo);
9224}
9225
9226////////////////////////////////////////////////////////////////////////////////
9227
9228MethodArgInfo_t* TCling::MethodArgInfo_FactoryCopy(MethodArgInfo_t* marginfo) const
9229{
9230 return (MethodArgInfo_t*)
9232}
9233
9234////////////////////////////////////////////////////////////////////////////////
9235
9236bool TCling::MethodArgInfo_IsValid(MethodArgInfo_t* marginfo) const
9237{
9238 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9239 return info->IsValid();
9240}
9241
9242////////////////////////////////////////////////////////////////////////////////
9243
9244int TCling::MethodArgInfo_Next(MethodArgInfo_t* marginfo) const
9245{
9246 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9247 return info->Next();
9248}
9249
9250////////////////////////////////////////////////////////////////////////////////
9251
9252Long_t TCling::MethodArgInfo_Property(MethodArgInfo_t* marginfo) const
9253{
9254 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9255 return info->Property();
9256}
9257
9258////////////////////////////////////////////////////////////////////////////////
9259
9260const char* TCling::MethodArgInfo_DefaultValue(MethodArgInfo_t* marginfo) const
9261{
9262 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9263 return info->DefaultValue();
9264}
9265
9266////////////////////////////////////////////////////////////////////////////////
9267
9268const char* TCling::MethodArgInfo_Name(MethodArgInfo_t* marginfo) const
9269{
9270 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9271 return info->Name();
9272}
9273
9274////////////////////////////////////////////////////////////////////////////////
9275
9276const char* TCling::MethodArgInfo_TypeName(MethodArgInfo_t* marginfo) const
9277{
9278 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9279 return info->TypeName();
9280}
9281
9282////////////////////////////////////////////////////////////////////////////////
9283
9284std::string TCling::MethodArgInfo_TypeNormalizedName(MethodArgInfo_t* marginfo) const
9285{
9286 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9287 return info->Type()->NormalizedName(*fNormalizedCtxt);
9288}
9289
9290////////////////////////////////////////////////////////////////////////////////
9291
9292TypeInfo_t* TCling::MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
9293{
9294 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9295 return (TypeInfo_t*) info->Type();
9296}
9297
9298//______________________________________________________________________________
9299//
9300// TypeInfo interface
9301//
9302
9303////////////////////////////////////////////////////////////////////////////////
9304
9305void TCling::TypeInfo_Delete(TypeInfo_t* tinfo) const
9306{
9307 delete (TClingTypeInfo*) tinfo;
9308}
9309
9310////////////////////////////////////////////////////////////////////////////////
9311
9312TypeInfo_t* TCling::TypeInfo_Factory() const
9313{
9315 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl());
9316}
9317
9318////////////////////////////////////////////////////////////////////////////////
9319
9320TypeInfo_t* TCling::TypeInfo_Factory(const char *name) const
9321{
9323 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl(), name);
9324}
9325
9326////////////////////////////////////////////////////////////////////////////////
9327
9328TypeInfo_t* TCling::TypeInfo_FactoryCopy(TypeInfo_t* tinfo) const
9329{
9330 return (TypeInfo_t*) new TClingTypeInfo(*(TClingTypeInfo*)tinfo);
9331}
9332
9333////////////////////////////////////////////////////////////////////////////////
9334
9335void TCling::TypeInfo_Init(TypeInfo_t* tinfo, const char* name) const
9336{
9338 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9339 TClinginfo->Init(name);
9340}
9341
9342////////////////////////////////////////////////////////////////////////////////
9343
9344bool TCling::TypeInfo_IsValid(TypeInfo_t* tinfo) const
9345{
9346 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9347 return TClinginfo->IsValid();
9348}
9349
9350////////////////////////////////////////////////////////////////////////////////
9351
9352const char* TCling::TypeInfo_Name(TypeInfo_t* tinfo) const
9353{
9354 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9355 return TClinginfo->Name();
9356}
9357
9358////////////////////////////////////////////////////////////////////////////////
9359
9360Long_t TCling::TypeInfo_Property(TypeInfo_t* tinfo) const
9361{
9362 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9363 return TClinginfo->Property();
9364}
9365
9366////////////////////////////////////////////////////////////////////////////////
9367
9368int TCling::TypeInfo_RefType(TypeInfo_t* tinfo) const
9369{
9370 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9371 return TClinginfo->RefType();
9372}
9373
9374////////////////////////////////////////////////////////////////////////////////
9375
9376int TCling::TypeInfo_Size(TypeInfo_t* tinfo) const
9377{
9378 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9379 return TClinginfo->Size();
9380}
9381
9382////////////////////////////////////////////////////////////////////////////////
9383
9384const char* TCling::TypeInfo_TrueName(TypeInfo_t* tinfo) const
9385{
9386 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9387 return TClinginfo->TrueName(*fNormalizedCtxt);
9388}
9389
9390////////////////////////////////////////////////////////////////////////////////
9391
9392void* TCling::TypeInfo_QualTypePtr(TypeInfo_t* tinfo) const
9393{
9394 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9395 return TClinginfo->QualTypePtr();
9396}
9397
9398
9399//______________________________________________________________________________
9400//
9401// TypedefInfo interface
9402//
9403
9404////////////////////////////////////////////////////////////////////////////////
9405
9406void TCling::TypedefInfo_Delete(TypedefInfo_t* tinfo) const
9407{
9408 delete(TClingTypedefInfo*) tinfo;
9409}
9410
9411////////////////////////////////////////////////////////////////////////////////
9412
9413TypedefInfo_t* TCling::TypedefInfo_Factory() const
9414{
9416 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl());
9417}
9418
9419////////////////////////////////////////////////////////////////////////////////
9420
9421TypedefInfo_t* TCling::TypedefInfo_Factory(const char *name) const
9422{
9424 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl(), name);
9425}
9426
9427////////////////////////////////////////////////////////////////////////////////
9428
9429TypedefInfo_t* TCling::TypedefInfo_FactoryCopy(TypedefInfo_t* tinfo) const
9430{
9431 return (TypedefInfo_t*) new TClingTypedefInfo(*(TClingTypedefInfo*)tinfo);
9432}
9433
9434////////////////////////////////////////////////////////////////////////////////
9435
9436void TCling::TypedefInfo_Init(TypedefInfo_t* tinfo,
9437 const char* name) const
9438{
9440 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9441 TClinginfo->Init(name);
9442}
9443
9444////////////////////////////////////////////////////////////////////////////////
9445
9446bool TCling::TypedefInfo_IsValid(TypedefInfo_t* tinfo) const
9447{
9448 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9449 return TClinginfo->IsValid();
9450}
9451
9452////////////////////////////////////////////////////////////////////////////////
9453
9454Int_t TCling::TypedefInfo_Next(TypedefInfo_t* tinfo) const
9455{
9456 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9457 return TClinginfo->Next();
9458}
9459
9460////////////////////////////////////////////////////////////////////////////////
9461
9462Long_t TCling::TypedefInfo_Property(TypedefInfo_t* tinfo) const
9463{
9464 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9465 return TClinginfo->Property();
9466}
9467
9468////////////////////////////////////////////////////////////////////////////////
9469
9470int TCling::TypedefInfo_Size(TypedefInfo_t* tinfo) const
9471{
9472 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9473 return TClinginfo->Size();
9474}
9475
9476////////////////////////////////////////////////////////////////////////////////
9477
9478const char* TCling::TypedefInfo_TrueName(TypedefInfo_t* tinfo) const
9479{
9480 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9481 return TClinginfo->TrueName(*fNormalizedCtxt);
9482}
9483
9484////////////////////////////////////////////////////////////////////////////////
9485
9486const char* TCling::TypedefInfo_Name(TypedefInfo_t* tinfo) const
9487{
9488 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9489 return TClinginfo->Name();
9490}
9491
9492////////////////////////////////////////////////////////////////////////////////
9493
9494const char* TCling::TypedefInfo_Title(TypedefInfo_t* tinfo) const
9495{
9496 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9497 return TClinginfo->Title();
9498}
9499
9500////////////////////////////////////////////////////////////////////////////////
9501
9502bool TCling::IsSameType(const void * QualTypePtr1, const void * QualTypePtr2) const
9503{
9504 clang::QualType QT1 = clang::QualType::getFromOpaquePtr(QualTypePtr1);
9505 clang::QualType QT2 = clang::QualType::getFromOpaquePtr(QualTypePtr2);
9506 return fInterpreter->getCI()->getASTContext().hasSameType(QT1, QT2);
9507}
9508
9509////////////////////////////////////////////////////////////////////////////////
9510
9511bool TCling::IsIntegerType(const void * QualTypePtr) const
9512{
9513 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9514 return QT->hasIntegerRepresentation();
9515}
9516
9517////////////////////////////////////////////////////////////////////////////////
9518
9519bool TCling::IsSignedIntegerType(const void * QualTypePtr) const
9520{
9521 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9522 return QT->hasSignedIntegerRepresentation();
9523}
9524
9525////////////////////////////////////////////////////////////////////////////////
9526
9527bool TCling::IsUnsignedIntegerType(const void * QualTypePtr) const
9528{
9529 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9530 return QT->hasUnsignedIntegerRepresentation();
9531}
9532
9533////////////////////////////////////////////////////////////////////////////////
9534
9535bool TCling::IsFloatingType(const void * QualTypePtr) const
9536{
9537 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9538 return QT->hasFloatingRepresentation();
9539}
9540
9541////////////////////////////////////////////////////////////////////////////////
9542
9543bool TCling::IsPointerType(const void * QualTypePtr) const
9544{
9545 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9546 return QT->hasPointerRepresentation();
9547}
9548
9549////////////////////////////////////////////////////////////////////////////////
9550
9551bool TCling::IsVoidPointerType(const void * QualTypePtr) const
9552{
9553 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9554 return QT->isVoidPointerType();
9555}
9556
9557////////////////////////////////////////////////////////////////////////////////
9558
9560{
9561 clang::FunctionDecl *FD = (clang::FunctionDecl *) fdeclid;
9562 return llvm::isa_and_nonnull<clang::CXXMethodDecl>(FD);
9563}
9564
9565////////////////////////////////////////////////////////////////////////////////
9566
9568{
9569 if (!fInitialMutex) {
9571 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
9572 }
9574 }
9575 // We will "forget" this lock once we backed out of all interpreter frames.
9576 // Here we are entering one, so ++.
9578}
9579
9580////////////////////////////////////////////////////////////////////////////////
9581
9583{
9584 if (!fInitialMutex)
9585 return;
9586 if (fInitialMutex.fRecurseCount == 0) {
9587 Error("ForgetMutexState", "mutex state's recurse count already 0!");
9588 }
9589 else if (--fInitialMutex.fRecurseCount == 0) {
9590 // We have returned from all interpreter frames. Reset the initial lock state.
9591 fInitialMutex.fState.reset();
9592 }
9593}
9594
9595////////////////////////////////////////////////////////////////////////////////
9596/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
9597
9599{
9600 if (gInterpreterMutex) {
9601 if (delta) {
9602 auto typedDelta = static_cast<MutexStateAndRecurseCountDelta *>(delta);
9603 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP{typedDelta};
9604 gCoreMutex->Apply(std::move(typedDelta->fDelta));
9605 // Now that we have the lock, update the global
9606 R__ASSERT(fInitialMutex.fRecurseCount == 0 && "Inconsistent state of fInitialMutex! Another thread within Interpreter critical section.");
9607 std::swap(fInitialMutex, typedDelta->fInitialState);
9608 } else {
9609 // This case happens when EnableThreadSafety is first called from
9610 // the interpreter function we just handled.
9611 // Since thread safety was not enabled at the time we rewound, there was
9612 // no lock taken and even-though we should be locking the rest of this
9613 // interpreter handling/modifying code (since there might be threads in
9614 // flight), we can't because there would not be any lock guard to release the
9615 // locks
9617 Error("ApplyToInterpreterMutex",
9618 "After returning from user code that turned on thread safety support, we notice that fInitialMutex is already used ... "
9619 "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.");
9620 }
9621 }
9622}
9623
9624////////////////////////////////////////////////////////////////////////////////
9625/// Reset the interpreter lock to the state it had before interpreter-related
9626/// calls happened.
9627
9629{
9630 if (fInitialMutex) {
9631 // Need to start a new recurse count.
9632 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP(new MutexStateAndRecurseCountDelta());
9633 std::swap(uniqueP->fInitialState, fInitialMutex);
9634 uniqueP->fDelta = gCoreMutex->Rewind(*uniqueP->fInitialState.fState);
9635 return uniqueP.release();
9636 }
9638 return nullptr;
9639}
#define R__EXTERN
Definition DllImport.h:27
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 e(i)
Definition RSha256.hxx:103
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Definition RtypesCore.h:63
int Int_t
Definition RtypesCore.h:45
long Longptr_t
Definition RtypesCore.h:82
short Version_t
Definition RtypesCore.h:65
unsigned long ULong_t
Definition RtypesCore.h:55
long Long_t
Definition RtypesCore.h:54
unsigned int UInt_t
Definition RtypesCore.h:46
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
constexpr Ssiz_t kNPOS
Definition RtypesCore.h:124
long long Long64_t
Definition RtypesCore.h:80
unsigned long long ULong64_t
Definition RtypesCore.h:81
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
TClass *(* DictFuncPtr_t)()
Definition Rtypes.h:80
R__EXTERN TApplication * gApplication
R__EXTERN TClassTable * gClassTable
Definition TClassTable.h:97
static bool IsFromRootCling()
Definition TClass.cxx:174
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:339
void TCling__TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:577
static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
Definition TCling.cxx:1306
static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
Definition TCling.cxx:7216
static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
Definition TCling.cxx:6963
void TCling__InvalidateGlobal(const clang::Decl *D)
Definition TCling.cxx:572
bool TClingLookupHelper__AutoParse(const char *cname)
Allow calling autoparsing from TMetaUtils.
Definition TCling.cxx:899
R__EXTERN int optind
Definition TCling.cxx:315
void * TCling__LockCompilationDuringUserCodeExecution()
Lock the interpreter.
Definition TCling.cxx:366
void TCling__UpdateListsOnUnloaded(const cling::Transaction &T)
Definition TCling.cxx:567
void TCling__GetNormalizedContext(const ROOT::TMetaUtils::TNormalizedCtxt *&normCtxt)
Definition TCling.cxx:555
int TCling__LoadLibrary(const char *library)
Load a library.
Definition TCling.cxx:331
void TCling__DEBUG__dump(clang::DeclContext *DC)
Definition TCling.cxx:222
ETupleOrdering
Check in what order the member of a tuple are layout.
Definition TCling.cxx:3876
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:349
static const std::unordered_set< std::string > gIgnoredPCMNames
List of dicts that have the PCM information already in the PCH.
Definition TCling.cxx:1946
static Bool_t s_IsLibraryLoaded(const char *libname, cling::Interpreter *fInterpreter)
Definition TCling.cxx:3100
static GlobalModuleIndex * loadGlobalModuleIndex(cling::Interpreter &interp)
Definition TCling.cxx:1087
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:908
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:1072
void TCling__UnlockCompilationDuringUserCodeExecution(void *)
Unlock the interpreter.
Definition TCling.cxx:377
const char * TCling__GetClassSharedLibs(const char *className)
Definition TCling.cxx:631
static std::string AlternateTuple(const char *classname, const cling::LookupHelper &lh, Bool_t silent)
Definition TCling.cxx:3918
static bool R__InitStreamerInfoFactory()
Helper to initialize TVirtualStreamerInfo's factor early.
Definition TCling.cxx:1671
int TCling__AutoParseCallback(const char *className)
Definition TCling.cxx:626
clang::RecordDecl * TCling__DEBUG__DCtoRecordDecl(clang::DeclContext *DC)
Definition TCling.cxx:219
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:697
static bool HaveFullGlobalModuleIndex
Definition TCling.cxx:1086
bool TCling__TEST_isInvalidDecl(clang::Decl *D)
Definition TCling.cxx:249
void TCling__LibraryUnloadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:591
void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter *)
Definition TCling.cxx:562
const Decl * TCling__GetObjectDecl(TObject *obj)
Definition TCling.cxx:602
static ETupleOrdering IsTupleAscending()
Definition TCling.cxx:3894
void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Definition TCling.cxx:586
static void TCling__UpdateClassInfo(const NamedDecl *TD)
Update TClingClassInfo for a class (e.g. upon seeing a definition).
Definition TCling.cxx:387
clang::DeclContext * TCling__DEBUG__getDeclContext(clang::Decl *D)
Definition TCling.cxx:213
int TCling__CompileMacro(const char *fileName, const char *options)
Definition TCling.cxx:642
#define R__DLLEXPORT
Definition TCling.cxx:150
void * TCling__ResetInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:358
void TCling__DEBUG__decl_dump(void *D)
Definition TCling.cxx:231
int TCling__AutoLoadCallback(const char *className)
Definition TCling.cxx:621
static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
Definition TCling.cxx:1037
static void RegisterCxxModules(cling::Interpreter &clingInterp)
Definition TCling.cxx:1190
static void ConstructorName(std::string &name, const clang::Decl *decl, cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition TCling.cxx:8703
void TCling__PrintStackTrace()
Print a StackTrace!
Definition TCling.cxx:324
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:2430
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:7125
void TCling__DEBUG__printName(clang::Decl *D)
Definition TCling.cxx:234
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:678
static void PrintDlError(const char *dyLibName, const char *modulename)
Definition TCling.cxx:1971
TInterpreter * CreateInterpreter(void *interpLibHandle, const char *argv[])
Definition TCling.cxx:606
const char * fantomline
Definition TCling.cxx:846
void TCling__LibraryLoadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:581
static cling::Interpreter::CompilationResult ExecAutoParse(const char *what, Bool_t header, cling::Interpreter *interpreter)
Parse the payload or header.
Definition TCling.cxx:6303
static bool requiresRootMap(const char *rootmapfile)
Definition TCling.cxx:5483
clang::NamespaceDecl * TCling__DEBUG__DCtoNamespace(clang::DeclContext *DC)
Definition TCling.cxx:216
TObject * TCling__GetObjectAddress(const char *Name, void *&LookupCtx)
Definition TCling.cxx:598
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:1059
int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:637
void DestroyInterpreter(TInterpreter *interp)
Definition TCling.cxx:614
static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
Definition TCling.cxx:7237
void TCling__SplitAclicMode(const char *fileName, string &mode, string &args, string &io, string &fname)
Definition TCling.cxx:649
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:384
@ kEnvUser
Definition TEnv.h:71
@ kEnvGlobal
Definition TEnv.h:70
@ kEnvLocal
Definition TEnv.h:72
#define R__ASSERT(e)
Definition TError.h:118
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:218
constexpr Int_t kWarning
Definition TError.h:45
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:185
Int_t gErrorIgnoreLevel
Error handling routines.
Definition TError.cxx:31
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:229
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:244
#define N
winID h TVirtualViewer3D TVirtualGLPainter p
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:110
R__EXTERN TVirtualMutex * gInterpreterMutex
#define R__LOCKGUARD_CLING(mutex)
R__EXTERN TInterpreter * gCling
#define gInterpreter
Int_t gDebug
Definition TROOT.cxx:597
#define gROOT
Definition TROOT.h:407
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2467
@ kReadPermission
Definition TSystem.h:47
Bool_t R_ISREG(Int_t mode)
Definition TSystem.h:118
R__EXTERN TSystem * gSystem
Definition TSystem.h:560
R__EXTERN TVirtualMutex * gGlobalMutex
#define R__LOCKGUARD(mutex)
#define R__WRITE_LOCKGUARD(mutex)
#define R__READ_LOCKGUARD(mutex)
const char * proto
Definition civetweb.c:17536
#define free
Definition civetweb.c:1539
#define snprintf
Definition civetweb.c:1540
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
virtual std::unique_ptr< State > GetStateBefore()=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:28
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:81
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
Definition TClass.cxx:3439
EState GetState() const
Definition TClass.h:488
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition TClass.cxx:2886
EState fState
cached of the streaming method to use
Definition TClass.h:277
std::atomic< TList * > fBase
Definition TClass.h:201
static void AddClassToDeclIdMap(TDictionary::DeclId_t id, TClass *cl)
static: Add a TClass* to the map of classes.
Definition TClass.cxx:511
Version_t fClassVersion
Definition TClass.h:221
TList * GetListOfFunctionTemplates(Bool_t load=kTRUE)
Return TListOfFunctionTemplates for a class.
Definition TClass.cxx:3798
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:4915
static void RemoveClassDeclId(TDictionary::DeclId_t id)
Definition TClass.cxx:536
Bool_t CallShowMembers(const void *obj, TMemberInspector &insp, Bool_t isTransient=kFALSE) const
Call ShowMembers() on the obj of this class type, passing insp and parent.
Definition TClass.cxx:2205
std::atomic< TListOfEnums * > fEnums
Definition TClass.h:205
static Bool_t HasNoInfoOrEmuOrFwdDeclaredDecl(const char *)
Definition TClass.cxx:3398
virtual void PostLoadCheck()
Do the initialization that can only be done after the CINT dictionary has been fully populated and ca...
Definition TClass.cxx:5959
static TClass * LoadClass(const char *requestedname, Bool_t silent)
Helper function used by TClass::GetClass().
Definition TClass.cxx:5749
Int_t Size() const
Return size of object of this class.
Definition TClass.cxx:5704
@ kLoading
Definition TClass.h:332
@ kUnloading
Definition TClass.h:332
TObjArray * fStreamerInfo
Definition TClass.h:198
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition TClass.cxx:5912
ClassInfo_t * GetClassInfo() const
Definition TClass.h:433
ClassInfo_t * fClassInfo
Definition TClass.h:222
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:2897
void ResetCaches()
To clean out all caches.
Definition TClass.cxx:4215
Long_t Property() const override
Returns the properties of the TClass as a bit field stored as a Long_t value.
Definition TClass.cxx:6086
static Int_t ReadRules()
Read the class.rules files from the default location:.
Definition TClass.cxx:1820
@ kInterpreted
Definition TClass.h:126
@ kHasTClassInit
Definition TClass.h:127
@ kEmulated
Definition TClass.h:125
@ kForwardDeclared
Definition TClass.h:124
@ kNamespaceForMeta
Definition TClass.h:131
Version_t GetClassVersion() const
Definition TClass.h:420
std::atomic< Bool_t > fHasRootPcmInfo
C++ Property of the class (is abstract, has virtual table, etc.)
Definition TClass.h:259
const char * GetDeclFileName() const
Return name of the file containing the declaration of this class.
Definition TClass.cxx:3463
@ kIsTObject
Definition TClass.h:100
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:2968
Emulation of the CINT BaseClassInfo class.
const char * TmpltName() const
const char * Name() const
ptrdiff_t Offset(void *address=0, bool isDerivedObject=true) const
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
TClingClassInfo * GetBase() const
Emulation of the CINT CallFunc class.
void ExecWithReturn(void *address, void *ret=nullptr)
void SetArgs(const char *args)
double ExecDouble(void *address)
void SetArgArray(Longptr_t *argArr, int narg)
bool IsValid() const
Longptr_t ExecInt(void *address)
TInterpreter::CallFuncIFacePtr_t IFacePtr()
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
int get_wrapper_code(std::string &wrapper_name, std::string &wrapper)
void IgnoreExtraArgs(bool ignore)
void SetArg(T arg)
long long ExecInt64(void *address)
bool IsAutoLoadingEnabled() const
void SetAutoParsingSuspended(bool val=true)
void SetAutoLoadingEnabled(bool val=true)
Emulation of the CINT ClassInfo class.
const char * Title()
static bool IsEnum(cling::Interpreter *interp, const char *name)
long ClassProperty() const
void Init(const char *name)
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
EDataType GetUnderlyingType() const
const char * TmpltName() const
const clang::Type * GetType() const
ptrdiff_t GetBaseOffset(TClingClassInfo *toBase, void *address, bool isDerivedObject)
Longptr_t Tagnum() const
bool IsScopedEnum() const
ROOT::TMetaUtils::EIOCtorCategory HasDefaultConstructor(bool checkio=false, std::string *type_name=nullptr) const
TClingMethodInfo GetMethodWithArgs(const char *fname, const char *arglist, Longptr_t *poffset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch, EInheritanceMode imode=kWithInheritance) const
const clang::FunctionTemplateDecl * GetFunctionTemplate(const char *fname) const
int GetMethodNArg(const char *method, const char *proto, Bool_t objectIsConst, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
bool IsValidMethod(const char *method, const char *proto, Bool_t objectIsConst, Longptr_t *offset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
bool HasMethod(const char *name) const
TDictionary::DeclId_t GetDeclId() const
void DeleteArray(void *arena, bool dtorOnly, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
void * New(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
TClingMethodInfo GetMethod(const char *fname) const
bool IsLoaded() const
const clang::ValueDecl * GetDataMember(const char *name) const
void Destruct(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
std::vector< std::string > GetUsingNamespaces()
const char * FileName()
bool IsBase(const char *name) const
void Delete(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Emulation of the CINT DataMemberInfo class.
const char * TypeName() const
const char * TypeTrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
llvm::StringRef ValidArrayIndex() const
const char * Name() const override
virtual const char * Name() const
virtual bool IsValid() const
virtual const clang::Decl * GetDecl() const
Uses clang::TextDiagnosticPrinter to format diagnostics, which are then passed to a user-specified fu...
Emulation of the CINT MethodInfo class.
bool IsValid() const override
const char * DefaultValue() const
const TClingTypeInfo * Type() const
const char * TypeName() const
Emulation of the CINT MethodInfo class.
std::string GetMangledName() const
const char * TypeName() const
const char * Name() const override
const clang::FunctionDecl * GetTargetFunctionDecl() const
Get the FunctionDecl, or if this represents a UsingShadowDecl, the underlying target FunctionDecl.
const char * GetPrototype()
long ExtraProperty() const
void * InterfaceMethod() const
void CreateSignature(TString &signature) const
TDictionary::DeclId_t GetDeclId() const
TClingTypeInfo * Type() const
Emulation of the CINT TypeInfo class.
long Property() const
std::string NormalizedName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
const char * Name() const override
int RefType() const
void * QualTypePtr() const
Return the QualType as a void pointer.
bool IsValid() const override
clang::QualType GetQualType() const
void Init(const char *name)
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
Emulation of the CINT TypedefInfo class.
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Get the name of the underlying type of the current typedef.
long Property() const
Return a bit mask of metadata about the current typedef.
const char * Name() const override
Get the name of the current typedef.
void Init(const char *name)
Lookup named typedef and reset the iterator to point to it.
int Next()
Increment the iterator.
int Size() const
Return the size in bytes of the underlying type of the current typedef.
Bridge between cling::Value and ROOT.
Definition TClingValue.h:36
const char * Data()
Definition TCling.cxx:1013
bool Append(const std::string &str)
Append string to the storage if not added already.
Definition TCling.cxx:1021
std::string fContent
Definition TCling.h:619
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:6175
const char * MethodArgInfo_DefaultValue(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9260
bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const final
Definition TCling.cxx:8266
const char * TypeInfo_Name(TypeInfo_t *) const final
Definition TCling.cxx:9352
void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const final
Definition TCling.cxx:9014
void LoadEnums(TListOfEnums &cl) const final
Create list of pointers to enums for TClass cl.
Definition TCling.cxx:4366
void UpdateListOfGlobals() final
No op: see TClingCallbacks (used to update the list of globals)
Definition TCling.cxx:3856
bool TypedefInfo_IsValid(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9446
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE) final
Load library containing the specified class.
Definition TCling.cxx:6236
void CallFunc_Init(CallFunc_t *func) const final
Definition TCling.cxx:7904
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:3619
bool LibraryLoadingFailed(const std::string &, const std::string &, bool, bool)
Definition TCling.cxx:6539
void GenericError(const char *error) const final
Let the interpreter issue a generic error, and set its error state.
Definition TCling.cxx:7421
std::vector< void * > fRegisterModuleDyLibs
Definition TCling.h:138
void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const final
Definition TCling.cxx:7830
TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const final
Definition TCling.cxx:9073
std::vector< std::string > fAutoLoadLibStorage
Definition TCling.h:118
void CallFunc_Delete(CallFunc_t *func) const final
Definition TCling.cxx:7807
Bool_t fLockProcessLine
Definition TCling.h:127
int LoadFile(const char *path) const final
Load a source file or library called path into the interpreter.
Definition TCling.cxx:7464
void ResetAll() final
Reset the Cling state to its initial state.
Definition TCling.cxx:3695
void SetDeclAttr(DeclId_t, const char *) final
Definition TCling.cxx:8689
void HandleNewDecl(const void *DV, bool isDeserialized, std::set< TClass * > &modifiedClasses)
Definition TCling.cxx:494
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:6858
Long_t MethodInfo_Property(MethodInfo_t *minfo) const final
Definition TCling.cxx:9055
virtual void LoadFunctionTemplates(TClass *cl) const final
Create list of pointers to function templates for TClass cl.
Definition TCling.cxx:4413
bool ClassInfo_IsValidMethod(ClassInfo_t *info, const char *method, const char *proto, Longptr_t *offset, ROOT::EFunctionMatchMode=ROOT::kConversionMatch) const final
Definition TCling.cxx:8300
Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8622
int SetClassAutoparsing(int) final
Enable/Disable the Autoparsing of headers.
Definition TCling.cxx:7549
std::vector< const char * > fCurExecutingMacros
Definition TCling.h:149
void CreateListOfDataMembers(TClass *cl) const final
Create list of pointers to data members for TClass cl.
Definition TCling.cxx:4460
void RewindDictionary() final
Rewind Cling dictionary to the point where it was before executing the current macro.
Definition TCling.cxx:3740
bool ClassInfo_IsValid(ClassInfo_t *info) const final
Definition TCling.cxx:8292
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition TCling.cxx:6732
int TypeInfo_RefType(TypeInfo_t *) const final
Definition TCling.cxx:9368
void CreateListOfBaseClasses(TClass *cl) const final
Create list of pointers to base class(es) for TClass cl.
Definition TCling.cxx:4342
ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const final
Definition TCling.cxx:8179
const char * MethodInfo_Name(MethodInfo_t *minfo) const final
Definition TCling.cxx:9102
BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const final
Definition TCling.cxx:8436
Bool_t LoadText(const char *text) const final
Load the declarations from text into the interpreter.
Definition TCling.cxx:7479
const char * GetSharedLibDeps(const char *lib, bool tryDyld=false) final
Get the list a libraries on which the specified lib depends.
Definition TCling.cxx:7253
EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const final
Definition TCling.cxx:9152
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition TCling.cxx:7678
Longptr_t ProcessLineAsynch(const char *line, EErrorCode *error=nullptr)
Let cling process a command line asynch.
Definition TCling.cxx:3531
bool MethodInfo_IsValid(MethodInfo_t *minfo) const final
Definition TCling.cxx:9023
FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8779
TypeInfo_t * TypeInfo_Factory() const final
Definition TCling.cxx:9312
bool IsClassAutoLoadingEnabled() const
Returns if class AutoLoading is currently enabled.
Definition TCling.cxx:7518
void InvalidateGlobal(const clang::Decl *D)
Invalidate cached TCling information for the given global declaration.
Definition TCling.cxx:6843
int Evaluate(const char *, TInterpreterValue &) final
Get the interpreter value corresponding to the statement.
Definition TCling.cxx:7642
std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const final
Definition TCling.cxx:7627
void UpdateListOfLoadedSharedLibraries()
Definition TCling.cxx:3319
const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9494
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:8029
void InitRootmapFile(const char *name)
Create a resource table and read the (possibly) three resource files, i.e.
Definition TCling.cxx:5626
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:6494
bool FunctionDeclId_IsMethod(DeclId_t fdeclid) const
Definition TCling.cxx:9559
void LoadPCM(std::string pcmFileNameFullPath)
Tries to load a rdict PCM, issues diagnostics if it fails.
Definition TCling.cxx:1818
void UpdateListOfMethods(TClass *cl) const final
Update the list of pointers to method for TClass cl This is now a nop.
Definition TCling.cxx:4478
virtual ~TCling()
Destroy the interpreter interface.
Definition TCling.cxx:1625
void AddFriendToClass(clang::FunctionDecl *, clang::CXXRecordDecl *) const
Inject function as a friend into klass.
Definition TCling.cxx:7731
void PrintIntro() final
No-op; see TRint instead.
Definition TCling.cxx:2626
Bool_t fCxxModulesEnabled
Definition TCling.h:128
int BaseClassInfo_Next(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8456
void RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
Internal function. Actually do the update of the ClassInfo when seeing.
Definition TCling.cxx:6606
CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const final
Definition TCling.cxx:7881
Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7865
void CallFunc_ResetArg(CallFunc_t *func) const final
Definition TCling.cxx:7930
const char * GetCurrentMacroName() const final
Return the file name of the currently interpreted file, included or not.
Definition TCling.cxx:5434
Bool_t IsLoaded(const char *filename) const final
Return true if the file has already been loaded by cint.
Definition TCling.cxx:3143
void SaveGlobalsContext() final
Save the current Cling state of global objects.
Definition TCling.cxx:3843
void CallFunc_IgnoreExtraArgs(CallFunc_t *func, bool ignore) const final
Definition TCling.cxx:7896
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:9598
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition TCling.cxx:6562
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:4694
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:8095
Bool_t IsLibraryLoaded(const char *libname) const final
Definition TCling.cxx:3109
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:7443
int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8548
TypeInfo_t * MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9292
DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8582
Bool_t HandleNewTransaction(const cling::Transaction &T)
Helper function to increase the internal Cling count of transactions that change the AST.
Definition TCling.cxx:3636
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:5499
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition TCling.h:153
int ClassInfo_Next(ClassInfo_t *info) const final
Definition TCling.cxx:8316
void SetErrmsgcallback(void *p) const final
Set a callback to receive error messages.
Definition TCling.cxx:7570
bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9236
int TypeInfo_Size(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9376
Int_t DeleteGlobal(void *obj) final
Delete obj from Cling symbol table so it cannot be accessed anymore.
Definition TCling.cxx:3754
int GetSecurityError() const final
Interface to cling function.
Definition TCling.cxx:7451
void SetTempLevel(int val) const final
Create / close a scope for temporaries.
Definition TCling.cxx:7606
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:8813
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:5126
TypedefInfo_t * TypedefInfo_Factory() const final
Definition TCling.cxx:9413
TObjArray * fRootmapFiles
Definition TCling.h:126
bool IsVoidPointerType(const void *QualTypePtr) const
Definition TCling.cxx:9551
Longptr_t ProcessLine(const char *line, EErrorCode *error=nullptr) final
Definition TCling.cxx:2460
int ClassInfo_Size(ClassInfo_t *info) const final
Definition TCling.cxx:8364
const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9276
cling::Interpreter * GetInterpreterImpl() const
Definition TCling.h:644
Longptr_t ExecuteMacro(const char *filename, EErrorCode *error=nullptr) final
Execute a cling macro.
Definition TCling.cxx:5374
std::vector< std::pair< TClass *, DictFuncPtr_t > > fClassesToUpdate
Definition TCling.h:146
int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8606
const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9486
void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8429
Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const final
Definition TCling.cxx:9064
void LoadMacro(const char *filename, EErrorCode *error=nullptr) final
Load a macro file in cling's memory.
Definition TCling.cxx:3523
const char * GetClassSharedLibs(const char *cls) final
Get the list of shared libraries containing the code for class cls.
Definition TCling.cxx:7059
FuncTempInfo_t * FuncTempInfo_FactoryCopy(FuncTempInfo_t *) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8790
int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const final
Definition TCling.cxx:8598
Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const final
Check validity of a FuncTempInfo_t.
Definition TCling.cxx:8801
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:2640
bool ClassInfo_IsBase(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8251
void RecursiveRemove(TObject *obj) final
Delete object from cling symbol table so it can not be used anymore.
Definition TCling.cxx:3654
const char * DataMemberInfo_TypeName(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8646
DeclId_t GetDataMemberAtAddr(const void *addr) const final
Return pointer to cling DeclId for a data member with a given name.
Definition TCling.cxx:4921
void CallFunc_SetArgArray(CallFunc_t *func, Longptr_t *paramArr, Int_t nparam) const final
Definition TCling.cxx:7986
std::string CallFunc_GetWrapperCode(CallFunc_t *func) const final
Definition TCling.cxx:8076
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:9628
const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9268
Bool_t HasPCMForLibrary(const char *libname) const final
Return true if ROOT has cxxmodules pcm for a given library name.
Definition TCling.cxx:3118
void TypedefInfo_Init(TypedefInfo_t *tinfo, const char *name) const final
Definition TCling.cxx:9436
const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8670
Longptr_t CallFunc_ExecInt(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7849
void ClearStack() final
Delete existing temporary values.
Definition TCling.cxx:3056
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:7500
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:7320
MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const final
Definition TCling.cxx:7888
bool IsUnsignedIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9527
TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9429
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:5019
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:2400
std::string MethodArgInfo_TypeNormalizedName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9284
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:4803
Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9252
int TypedefInfo_Size(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9470
void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:7838
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:5171
Int_t fGlobalsListSerial
Definition TCling.h:114
TString fSharedLibs
Definition TCling.h:113
std::map< std::string, llvm::StringRef > fPendingRdicts
Definition TCling.h:634
static void UpdateClassInfoWork(const char *name)
Definition TCling.cxx:6712
Int_t Load(const char *filenam, Bool_t system=kFALSE) final
Load a library file in cling's memory.
Definition TCling.cxx:3486
int TypedefInfo_Next(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9454
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:4978
void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const final
Definition TCling.cxx:9335
Bool_t SetSuspendAutoParsing(Bool_t value) final
Suspend the Autoparsing of headers.
Definition TCling.cxx:7560
int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8638
static void * fgSetOfSpecials
Definition TCling.h:105
const char * ClassInfo_Title(ClassInfo_t *info) const final
Definition TCling.cxx:8406
const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8662
const char * TypeName(const char *typeDesc) final
Return the absolute type of typeDesc.
Definition TCling.cxx:5449
ROOT::TMetaUtils::TNormalizedCtxt * fNormalizedCtxt
Definition TCling.h:134
bool IsSignedIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9519
void ForgetMutexState() final
Definition TCling.cxx:9582
int MethodInfo_Next(MethodInfo_t *minfo) const final
Definition TCling.cxx:9047
Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const final
Definition TCling.cxx:8140
void MethodInfo_Delete(MethodInfo_t *minfo) const final
Interface to cling function.
Definition TCling.cxx:8966
bool fIsShuttingDown
Definition TCling.h:187
void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9205
DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo, TDictionary::EMemberSelection selection) const final
Definition TCling.cxx:8563
void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const final
Definition TCling.cxx:8171
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:6081
Int_t UnloadAllSharedLibraryMaps() final
Unload the library map entries coming from all the loaded shared libraries.
Definition TCling.cxx:5969
void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const final
Definition TCling.cxx:8233
std::set< TClass * > & GetModTClasses()
Definition TCling.h:579
ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const final
Definition TCling.cxx:8501
TClingCallbacks * fClingCallbacks
Definition TCling.h:139
Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7857
Long_t ClassInfo_Property(ClassInfo_t *info) const final
Definition TCling.cxx:8356
Longptr_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8480
void UpdateEnumConstants(TEnum *enumObj, TClass *cl) const final
Definition TCling.cxx:419
void ExecuteWithArgsAndReturn(TMethod *method, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:5356
Bool_t IsErrorMessagesEnabled() const final
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition TCling.cxx:7306
TString fIncludePath
Definition TCling.h:115
int DisplayIncludePath(FILE *fout) const final
Interface to cling function.
Definition TCling.cxx:7383
void TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:6918
Long_t FuncTempInfo_Property(FuncTempInfo_t *) const final
Return the property of the function template.
Definition TCling.cxx:8834
TEnum * CreateEnum(void *VD, TClass *cl) const final
Definition TCling.cxx:467
const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9384
Int_t UnloadLibraryMap(const char *library) final
Unload library map entries coming from the specified library.
Definition TCling.cxx:5987
void RegisterTemporary(const TInterpreterValue &value)
Definition TCling.cxx:7651
MutexStateAndRecurseCount fInitialMutex
Definition TCling.h:174
const char * GetSharedLibs() final
Return the list of shared libraries loaded into the process.
Definition TCling.cxx:6956
int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9244
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx) final
Definition TCling.cxx:9567
Long_t TypeInfo_Property(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9360
const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const final
Definition TCling.cxx:9093
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:8824
std::vector< cling::Value > * fTemporaries
Definition TCling.h:133
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:2017
static Int_t ShallowAutoLoadImpl(const char *cls)
Definition TCling.cxx:6127
void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const final
Definition TCling.cxx:8973
Bool_t CheckClassTemplate(const char *name) final
Return true if there is a class template by the given name ...
Definition TCling.cxx:4320
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6941
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:2391
TObjArray * GetRootMapFiles() const final
Definition TCling.h:223
bool DataMemberInfo_IsValid(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8590
bool ClassInfo_IsEnum(const char *name) const final
Definition TCling.cxx:8259
int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9039
void CreateListOfMethods(TClass *cl) const final
Create list of pointers to methods for TClass cl.
Definition TCling.cxx:4469
Int_t RescanLibraryMap() final
Scan again along the dynamic path for library maps.
Definition TCling.cxx:5896
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:7579
const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9082
Bool_t fHeaderParsingOnDemand
Definition TCling.h:181
bool IsIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9511
std::hash< std::string > fStringHashFunction
Definition TCling.h:124
TEnv * fMapfile
Definition TCling.h:117
static void RemoveAndInvalidateObject(List &L, Object *O)
Definition TCling.h:591
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:5081
void * ClassInfo_New(ClassInfo_t *info) const final
Definition TCling.cxx:8324
int DisplayClass(FILE *fout, const char *name, int base, int start) const final
Definition TCling.cxx:7374
virtual void GetFunctionName(const clang::Decl *decl, std::string &name) const
Definition TCling.cxx:8725
void CreateListOfMethodArgs(TFunction *m) const final
Create list of pointers to method arguments for TMethod m.
Definition TCling.cxx:4494
virtual const char * GetSTLIncludePath() const final
Return the directory containing CINT's stl cintdlls.
Definition TCling.cxx:7365
MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9228
Longptr_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8472
ECheckClassInfo CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly=kFALSE) final
Checks if an entity with the specified name is defined in Cling.
Definition TCling.cxx:4148
void * FindSym(const char *entry) const final
Interface to cling function.
Definition TCling.cxx:7412
void RegisterLoadedSharedLibrary(const char *name)
Register a new shared library name with the interpreter; add it to fSharedLibs.
Definition TCling.cxx:3386
void TypeInfo_Delete(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9305
int MethodInfo_NArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9031
DeclId_t GetDataMemberWithValue(const void *ptrvalue) const final
NOT IMPLEMENTED.
Definition TCling.cxx:4912
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition TCling.h:125
EReturnType MethodCallReturnType(TFunction *func) const final
Definition TCling.cxx:9141
void ProcessClassesToUpdate()
Definition TCling.cxx:1987
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:5104
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:4933
const char * MethodInfo_Title(MethodInfo_t *minfo) const final
Definition TCling.cxx:9132
TString fRootmapLoadPath
Definition TCling.h:116
const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8535
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:3069
const char * BaseClassInfo_FullName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8517
void CallFunc_SetArgs(CallFunc_t *func, const char *param) const final
Definition TCling.cxx:7994
int UnloadFile(const char *path) const final
Definition TCling.cxx:7612
void SetClassInfo(TClass *cl, Bool_t reload=kFALSE, Bool_t silent=kFALSE) final
Set pointer to the TClingClassInfo in TClass.
Definition TCling.cxx:4012
void CallFunc_Exec(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7814
bool IsPointerType(const void *QualTypePtr) const
Definition TCling.cxx:9543
bool IsFloatingType(const void *QualTypePtr) const
Definition TCling.cxx:9535
Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const final
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition TCling.cxx:8895
bool CallFunc_IsValid(CallFunc_t *func) const final
Definition TCling.cxx:7913
const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8527
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition TCling.h:135
const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8678
Int_t GetMore() const final
Return whether we are waiting for more input either because the collected input contains unbalanced b...
Definition TCling.cxx:4515
Bool_t fIsAutoParsingSuspended
Definition TCling.h:182
std::string ToString(const char *type, void *obj) final
Definition TCling.cxx:1030
DeclId_t GetDeclId(const llvm::GlobalValue *gv) const
Return pointer to cling DeclId for a global value.
Definition TCling.cxx:4843
void Execute(const char *function, const char *params, int *error=nullptr) final
Execute a global function with arguments params.
Definition TCling.cxx:5204
bool ClassInfo_IsLoaded(ClassInfo_t *info) const final
Definition TCling.cxx:8284
Longptr_t ClassInfo_Tagnum(ClassInfo_t *info) const final
Definition TCling.cxx:8372
Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8493
void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Longptr_t *Offset) const final
Definition TCling.cxx:8002
std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const final
Get the scopes representing using declarations of namespace.
Definition TCling.cxx:4449
const char * ClassInfo_FileName(ClassInfo_t *info) const final
Definition TCling.cxx:8380
void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const final
Return the comments associates with this function template.
Definition TCling.cxx:8934
const char * ClassInfo_TmpltName(ClassInfo_t *info) const final
Definition TCling.cxx:8414
void SaveContext() final
Save the current Cling state.
Definition TCling.cxx:3830
void LoadPCMImpl(TFile &pcmFile)
Tries to load a PCM from TFile; returns true on success.
Definition TCling.cxx:1703
Bool_t IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:6598
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:3711
void CodeComplete(const std::string &, size_t &, std::vector< std::string > &) final
The call to Cling's tab complition.
Definition TCling.cxx:7634
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:3725
const char * MapCppName(const char *) const final
Interface to cling function.
Definition TCling.cxx:7487
Longptr_t Calc(const char *line, EErrorCode *error=nullptr) final
Directly execute an executable statement (e.g.
Definition TCling.cxx:3556
Int_t ReloadAllSharedLibraryMaps() final
Reload the library map entries coming from all the loaded shared libraries, after first unloading the...
Definition TCling.cxx:5908
void UpdateListOfGlobalFunctions() final
No op: see TClingCallbacks (used to update the list of global functions)
Definition TCling.cxx:3863
void DataMemberInfo_Delete(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8556
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:5387
void * fPrevLoadedDynLibInfo
Definition TCling.h:137
void UpdateListOfDataMembers(TClass *cl) const
Update the list of pointers to data members for TClass cl This is now a nop.
Definition TCling.cxx:4487
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:2655
Int_t SetClassSharedLibs(const char *cls, const char *libs) final
Register the AutoLoading information for a class.
Definition TCling.cxx:6049
MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const final
Definition TCling.cxx:9007
std::set< const char * > fParsedPayloadsAddresses
Definition TCling.h:123
CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const final
Definition TCling.cxx:7922
MethodArgInfo_t * MethodArgInfo_Factory() const final
Definition TCling.cxx:9212
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition TCling.cxx:6706
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:5000
void ClassInfo_Delete(ClassInfo_t *info) const final
Definition TCling.cxx:8148
std::unique_ptr< cling::Interpreter > fInterpreter
Definition TCling.h:130
EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const final
Definition TCling.cxx:8275
void FuncTempInfo_Delete(FuncTempInfo_t *) const final
Delete the FuncTempInfo_t.
Definition TCling.cxx:8770
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:5148
Int_t DeleteVariable(const char *name) final
Undeclare obj called name.
Definition TCling.cxx:3769
Longptr_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8614
CallFunc_t * CallFunc_Factory() const final
Definition TCling.cxx:7873
MethodInfo_t * MethodInfo_Factory() const final
Definition TCling.cxx:8982
Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8630
void ClearFileBusy() final
Reset the interpreter internal state in case a previous action was not correctly terminated.
Definition TCling.cxx:3048
cling::MetaProcessor * GetMetaProcessorImpl() const
Definition TCling.h:645
bool DiagnoseIfInterpreterException(const std::exception &e) const final
Definition TCling.cxx:2449
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:7510
std::set< size_t > fLookedUpClasses
Definition TCling.h:121
virtual void AddAvailableIndentifiers(TSeqCollection &Idents) final
Definition TCling.cxx:2365
void TypedefInfo_Delete(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9406
void Reset() final
Pressing Ctrl+C should forward here.
Definition TCling.cxx:3679
const char * TypedefInfo_TrueName(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9478
int SetClassAutoLoading(int) const final
Enable/Disable the AutoLoading of libraries.
Definition TCling.cxx:7531
const char * ClassInfo_FullName(ClassInfo_t *info) const final
Definition TCling.cxx:8388
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:6352
const char * MethodInfo_TypeName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9111
void CallFunc_SetArg(CallFunc_t *func, Long_t param) const final
Definition TCling.cxx:7938
const char * GetIncludePath() final
Refresh the list of include paths known to the interpreter and return it with -I prepended.
Definition TCling.cxx:7334
void UpdateListsOnUnloaded(const cling::Transaction &T)
Invalidate stored TCling state for declarations included in transaction ‘T’.
Definition TCling.cxx:6816
void UpdateClassInfoWithDecl(const clang::NamedDecl *ND)
Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
Definition TCling.cxx:6648
bool IsSameType(const void *QualTypePtr1, const void *QualTypePtr2) const
Definition TCling.cxx:9502
virtual void Initialize() final
Initialize the interpreter, once TROOT::fInterpreter is set.
Definition TCling.cxx:1643
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:8209
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:4742
void * fAutoLoadCallBack
Definition TCling.h:147
void FuncTempInfo_Name(FuncTempInfo_t *, TString &name) const final
Return the name of this function template.
Definition TCling.cxx:8921
std::unique_ptr< cling::MetaProcessor > fMetaProcessor
Definition TCling.h:131
bool TypeInfo_IsValid(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9344
bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const final
Definition TCling.cxx:1913
std::string MethodInfo_TypeNormalizedName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9120
const char * ClassInfo_Name(ClassInfo_t *info) const final
Definition TCling.cxx:8398
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE) final
Generate a TClass for the given class.
Definition TCling.cxx:4525
ULong64_t fTransactionCount
Definition TCling.h:148
bool ClassInfo_HasDefaultConstructor(ClassInfo_t *info, Bool_t testio=kFALSE) const final
Definition TCling.cxx:8217
void EndOfLineAction() final
It calls a "fantom" method to synchronize user keyboard input and ROOT prompt line.
Definition TCling.cxx:3092
TypeInfo_t * TypeInfo_FactoryCopy(TypeInfo_t *) const final
Definition TCling.cxx:9328
void * TypeInfo_QualTypePtr(TypeInfo_t *tinfo) const
Definition TCling.cxx:9392
bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8225
void ClassInfo_DeleteArray(ClassInfo_t *info, void *arena, bool dtorOnly) const final
Definition TCling.cxx:8163
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:8654
virtual void ShutDown() final
Definition TCling.cxx:1662
void UpdateListOfTypes() final
No op: see TClingCallbacks (used to update the list of types)
Definition TCling.cxx:3870
Long_t TypedefInfo_Property(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9462
void RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Register Rdict data for future loading by LoadPCM;.
Definition TCling.cxx:1685
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:3540
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:4960
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition TCling.cxx:6721
Int_t LoadLibraryMap(const char *rootmapfile=nullptr) final
Load map between class and library.
Definition TCling.cxx:5712
Longptr_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8509
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6948
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.
virtual void Add(TObject *obj)=0
TObject * FindObject(const char *name) const override
Find an object in this collection using its name.
Bool_t Contains(const char *name) const
All ROOT classes may have RTTI (run time type identification) support added.
Definition TDataMember.h:31
Bool_t IsPersistent() const
Definition TDataMember.h:91
Basic data type descriptor (datatype information is obtained from CINT).
Definition TDataType.h:44
Int_t GetType() const
Definition TDataType.h:68
EMemberSelection
Kinds of members to include in lists.
const void * DeclId_t
TList * GetListOfKeys() const override
TDirectory::TContext keeps track and restore the current directory.
Definition TDirectory.h:89
void GetObject(const char *namecycle, T *&ptr)
Get an object with proper type checking.
Definition TDirectory.h:212
The TEnumConstant class implements the constants of the enum type.
The TEnum class implements the enum type.
Definition TEnum.h:33
const TSeqCollection * GetConstants() const
Definition TEnum.h:63
static TEnum * GetEnum(const std::type_info &ti, ESearchAction sa=kALoadAndInterpLookup)
Definition TEnum.cxx:175
DeclId_t GetDeclId() const
Definition TEnum.cxx:146
@ kNone
Definition TEnum.h:48
@ kAutoload
Definition TEnum.h:49
Definition TEnv.h:86
const char * GetValue() const
Definition TEnv.h:110
The TEnv class reads config files, by default named .rootrc.
Definition TEnv.h:124
THashList * GetTable() const
Definition TEnv.h:140
Bool_t IgnoreDuplicates(Bool_t ignore)
If set to true, no warnings in case of duplicates are issued.
Definition TEnv.cxx:793
virtual void SetRcName(const char *name)
Definition TEnv.h:145
virtual Int_t ReadFile(const char *fname, EEnvLevel level)
Read and parse the resource file for a certain level.
Definition TEnv.cxx:592
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:736
virtual TEnvRec * Lookup(const char *n) const
Loop over all resource records and return the one with name.
Definition TEnv.cxx:547
A ROOT file is composed of a header, followed by consecutive data records (TKey instances) with a wel...
Definition TFile.h:53
Global functions class (global functions are obtained from CINT).
Definition TFunction.h:30
MethodInfo_t * fInfo
Definition TFunction.h:36
Global variables class (global variables are obtained from CINT).
Definition TGlobal.h:28
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition THashList.h:34
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 const char * GetClassSharedLibs(const char *cls)=0
virtual Bool_t Declare(const char *code)=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...
TObject * FindObject(const char *name) const override
Specialize FindObject to do search for the a data member just by name or create it if its not already...
TDictionary * Find(DeclId_t id) const
Return (after creating it if necessary) the TDataMember describing the data member corresponding to t...
TClass * GetClass() const
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
TEnum * Find(DeclId_t id) const
Return the TEnum corresponding to the Decl 'id' or NULL if it does not exist.
TEnum * Get(DeclId_t id, const char *name)
Return (after creating it if necessary) the TEnum describing the enum corresponding to the Decl 'id'.
TClass * GetClass() const
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
TFunctionTemplate * Get(DeclId_t id)
Return (after creating it if necessary) the TMethod or TFunction describing the function correspondin...
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
TFunction * Find(DeclId_t id) const
Return the TMethod or TFunction describing the function corresponding to the Decl 'id'.
A doubly linked list.
Definition TList.h:38
void Add(TObject *obj) override
Definition TList.h:81
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:357
A TMemFile is like a normal TFile except that it reads and writes only from memory.
Definition TMemFile.h:19
Abstract base class for accessing the data-members of a class.
const char * GetParent() const
virtual void Inspect(TClass *cl, const char *parent, const char *name, const void *addr)
EObjectPointerState GetObjectValidity() const
virtual Bool_t IsTreatingNonAccessibleTypes()
void SetObjectValidity(EObjectPointerState val)
void InspectMember(const T &obj, const char *name, Bool_t isTransient)
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition TMethodArg.h:36
const char * GetFullTypeName() const
Get full type description of method argument, e.g.: "class TDirectory*".
const char * GetDefault() const
Get default value of method argument.
Each ROOT class (see TClass) has a linked list of methods.
Definition TMethod.h:38
virtual TList * GetListOfMethodArgs()
Returns methodarg list and additionally updates fDataMember in TMethod by calling FindDataMember();.
Definition TMethod.cxx:307
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:47
TNamed()
Definition TNamed.h:36
An array of TObjects.
Definition TObjArray.h:31
Int_t GetEntriesFast() const
Definition TObjArray.h:58
virtual void Expand(Int_t newSize)
Expand or shrink the array to newSize elements.
void Clear(Option_t *option="") override
Remove all objects from the array.
virtual void Compress()
Remove empty slots from array.
Int_t GetEntries() const override
Return the number of objects in array (i.e.
TObject * At(Int_t idx) const override
Definition TObjArray.h:164
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
TString & String()
Definition TObjString.h:48
Mother of all ROOT objects.
Definition TObject.h:41
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:199
R__ALWAYS_INLINE Bool_t IsOnHeap() const
Definition TObject.h:152
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:973
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:403
static TClass * Class()
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:987
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1015
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:483
virtual TClass * IsA() const
Definition TObject.h:243
void MakeZombie()
Definition TObject.h:53
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:72
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:961
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:3021
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition TROOT.cxx:2761
static const std::vector< std::string > & AddExtraInterpreterArgs(const std::vector< std::string > &args)
Provide command line arguments to the interpreter construction.
Definition TROOT.cxx:2931
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition TROOT.cxx:3031
static const char **& GetExtraInterpreterArgs()
INTERNAL function! Used by rootcling to inject interpreter arguments through a C-interface layer.
Definition TROOT.cxx:2941
static const TString & GetSharedLibDir()
Get the shared libraries directory in the installation. Static utility function.
Definition TROOT.cxx:3010
Sequenceable collection abstract base class.
Int_t LastIndex() const
void Add(TObject *obj) override
Describes a persistent version of a class.
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:421
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2222
const char * Data() const
Definition TString.h:380
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:704
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition TString.cxx:924
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition TString.cxx:2242
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:627
TString & Prepend(const char *cs)
Definition TString.h:673
Bool_t IsNull() const
Definition TString.h:418
TString & Remove(Ssiz_t pos)
Definition TString.h:685
TString & Append(const char *cs)
Definition TString.h:576
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:2356
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:636
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:651
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1261
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition TSystem.cxx:832
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition TSystem.cxx:823
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1650
virtual const char * GetIncludePath()
Get the list of include path.
Definition TSystem.cxx:3950
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition TSystem.cxx:4235
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition TSystem.cxx:1058
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1523
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition TSystem.cxx:1842
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:1385
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition TSystem.cxx:1068
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:1283
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition TSystem.cxx:840
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition TSystem.cxx:2474
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:921
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition TSystem.cxx:1780
virtual const char * FindDynamicLibrary(TString &lib, Bool_t quiet=kFALSE)
Find a dynamic library using the system search paths.
Definition TSystem.cxx:2019
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition TSystem.cxx:424
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:2815
virtual const char * WorkingDirectory()
Return working directory.
Definition TSystem.cxx:858
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1533
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition TSystem.cxx:1634
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition TSystem.cxx:874
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1019
virtual void StackTrace()
Print a stack trace.
Definition TSystem.cxx:721
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
Definition TSystem.cxx:2005
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
#define F(x, y, z)
#define I(x, y, z)
const std::string & GetPathSeparator()
const char & GetEnvPathSeparator()
const T * GetAnnotatedRedeclarable(const T *Redecl)
int GetClassVersion(const clang::RecordDecl *cl, const cling::Interpreter &interp)
Return the version number of the class or -1 if the function Class_Version does not exist.
void GetNormalizedName(std::string &norm_name, const clang::QualType &type, const cling::Interpreter &interpreter, const TNormalizedCtxt &normCtxt)
Return the type name normalized for ROOT, keeping only the ROOT opaque typedef (Double32_t,...
std::string GetModuleFileName(const char *moduleName)
Return the dictionary file name for a module.
clang::QualType ReSubstTemplateArg(clang::QualType input, const clang::Type *instance)
Check if 'input' or any of its template parameter was substituted when instantiating the class templa...
static std::string DemangleNameForDlsym(const std::string &name)
void GetCppName(std::string &output, const char *input)
Return (in the argument 'output') a mangled version of the C++ symbol/type (pass as 'input') that can...
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.
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
R__EXTERN TVirtualRWMutex * gCoreMutex
EFunctionMatchMode
@ kExactMatch
bool IsStdPairBase(std::string_view name)
Definition TClassEdit.h:196
bool IsStdArray(std::string_view name)
Definition TClassEdit.h:189
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
bool IsStdPair(std::string_view name)
Definition TClassEdit.h:191
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:218
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.
bool IsUniquePtr(std::string_view name)
Definition TClassEdit.h:187
@ kDropStlDefault
Definition TClassEdit.h:82
EComplexType GetComplexType(const char *)
Definition file.py:1
static const char * what
Definition stlLoader.cc:6
Int_t fMode
Definition TSystem.h:127
Long_t fMemVirtual
Definition TSystem.h:196
Long_t fMemResident
Definition TSystem.h:195
RAII used to store Parser, Sema, Preprocessor state for recursive parsing.
Definition ClingRAII.h:22
std::vector< std::string > fElements
Definition TClassEdit.h:141
void ShortType(std::string &answer, int mode)
Return the absolute type of typeDesc into the string answ.
std::unique_ptr< ROOT::TVirtualRWMutex::State > fState
State of gCoreMutex when the first interpreter-related function was invoked.
Definition TCling.h:157
Int_t fRecurseCount
Interpreter-related functions will push the "entry" lock state to *this.
Definition TCling.h:162
A read-only memory range which we do not control.
Definition TMemFile.h:23
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4
static void output()