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#include <optional>
148
149#ifndef R__WIN32
150#include <cxxabi.h>
151#define R__DLLEXPORT __attribute__ ((visibility ("default")))
152#include <sys/stat.h>
153#endif
154#include <limits.h>
155#include <stdio.h>
156
157#ifdef __APPLE__
158#include <dlfcn.h>
159#include <mach-o/dyld.h>
160#include <mach-o/loader.h>
161#endif // __APPLE__
162
163#ifdef R__UNIX
164#include <dlfcn.h>
165#endif
166
167#if defined(R__LINUX) || defined(R__FBSD)
168# ifndef _GNU_SOURCE
169# define _GNU_SOURCE
170# endif
171# include <link.h> // dl_iterate_phdr()
172#endif
173
174#if defined(__CYGWIN__)
175#include <sys/cygwin.h>
176#define HMODULE void *
177extern "C" {
178 __declspec(dllimport) void * __stdcall GetCurrentProcess();
179 __declspec(dllimport) bool __stdcall EnumProcessModules(void *, void **, unsigned long, unsigned long *);
180 __declspec(dllimport) unsigned long __stdcall GetModuleFileNameExW(void *, void *, wchar_t *, unsigned long);
181}
182#endif
183
184// Fragment copied from LLVM's raw_ostream.cpp
185#if defined(_MSC_VER)
186#ifndef STDIN_FILENO
187# define STDIN_FILENO 0
188#endif
189#ifndef STDOUT_FILENO
190# define STDOUT_FILENO 1
191#endif
192#ifndef STDERR_FILENO
193# define STDERR_FILENO 2
194#endif
195#ifndef R__WIN32
196//#if defined(HAVE_UNISTD_H)
197# include <unistd.h>
198//#endif
199#else
200#include "Windows4Root.h"
201#include <Psapi.h>
202#include <direct.h>
203#undef GetModuleFileName
204#define RTLD_DEFAULT ((void *)::GetModuleHandle(NULL))
205#define dlsym(library, function_name) ::GetProcAddress((HMODULE)library, function_name)
206#define dlopen(library_name, flags) ::LoadLibraryA(library_name)
207#define dlclose(library) ::FreeLibrary((HMODULE)library)
208#define R__DLLEXPORT __declspec(dllexport)
209#endif
210#endif
211
212//______________________________________________________________________________
213// These functions are helpers for debugging issues with non-LLVMDEV builds.
214//
215R__DLLEXPORT clang::DeclContext* TCling__DEBUG__getDeclContext(clang::Decl* D) {
216 return D->getDeclContext();
217}
218R__DLLEXPORT clang::NamespaceDecl* TCling__DEBUG__DCtoNamespace(clang::DeclContext* DC) {
219 return llvm::dyn_cast<clang::NamespaceDecl>(DC);
220}
221R__DLLEXPORT clang::RecordDecl* TCling__DEBUG__DCtoRecordDecl(clang::DeclContext* DC) {
222 return llvm::dyn_cast<clang::RecordDecl>(DC);
223}
224R__DLLEXPORT void TCling__DEBUG__dump(clang::DeclContext* DC) {
225 return DC->dumpDeclContext();
226}
227R__DLLEXPORT void TCling__DEBUG__dump(clang::Decl* D) {
228 return D->dump();
229}
230R__DLLEXPORT void TCling__DEBUG__dump(clang::FunctionDecl* FD) {
231 return FD->dump();
232}
234 return ((clang::Decl*)D)->dump();
235}
237 if (clang::NamedDecl* ND = llvm::dyn_cast<clang::NamedDecl>(D)) {
238 std::string name;
239 {
240 llvm::raw_string_ostream OS(name);
241 ND->getNameForDiagnostic(OS, D->getASTContext().getPrintingPolicy(),
242 true /*Qualified*/);
243 }
244 printf("%s\n", name.c_str());
245 }
246}
247//______________________________________________________________________________
248// These functions are helpers for testing issues directly rather than
249// relying on side effects.
250// This is used for the test for ROOT-7462/ROOT-6070
252 return D->isInvalidDecl();
253}
256 assert(info && info->IsValid());
257 return info->GetDecl()->isInvalidDecl();
258}
259
260using std::string, std::vector;
261using namespace clang;
262using namespace ROOT;
263
264namespace {
265 static const std::string gInterpreterClassDef = R"ICF(
266#undef ClassDef
267#define ClassDef(name, id) \
268_ClassDefInterp_(name,id,virtual,) \
269static int DeclFileLine() { return __LINE__; }
270#undef ClassDefNV
271#define ClassDefNV(name, id) \
272_ClassDefInterp_(name,id,,) \
273static int DeclFileLine() { return __LINE__; }
274#undef ClassDefOverride
275#define ClassDefOverride(name, id) \
276_ClassDefInterp_(name,id,,override) \
277static int DeclFileLine() { return __LINE__; }
278)ICF";
279
280 static const std::string gNonInterpreterClassDef = R"ICF(
281#define __ROOTCLING__ 1
282#undef ClassDef
283#define ClassDef(name,id) \
284_ClassDefOutline_(name,id,virtual,) \
285static int DeclFileLine() { return __LINE__; }
286#undef ClassDefNV
287#define ClassDefNV(name, id)\
288_ClassDefOutline_(name,id,,)\
289static int DeclFileLine() { return __LINE__; }
290#undef ClassDefOverride
291#define ClassDefOverride(name, id)\
292_ClassDefOutline_(name,id,,override)\
293static int DeclFileLine() { return __LINE__; }
294)ICF";
295
296// The macros below use ::Error, so let's ensure it is included
297 static const std::string gClassDefInterpMacro = R"ICF(
298#include "TError.h"
299
300#define _ClassDefInterp_(name,id,virtual_keyword, overrd) \
301private: \
302public: \
303 static TClass *Class() { static TClass* sIsA = 0; if (!sIsA) sIsA = TClass::GetClass(#name); return sIsA; } \
304 static const char *Class_Name() { return #name; } \
305 virtual_keyword Bool_t CheckTObjectHashConsistency() const overrd { return true; } \
306 static Version_t Class_Version() { return id; } \
307 static TClass *Dictionary() { return 0; } \
308 virtual_keyword TClass *IsA() const overrd { return name::Class(); } \
309 virtual_keyword void ShowMembers(TMemberInspector&insp) const overrd { ::ROOT::Class_ShowMembers(name::Class(), this, insp); } \
310 virtual_keyword void Streamer(TBuffer&) overrd { ::Error("Streamer", "Cannot stream interpreted class."); } \
311 void StreamerNVirtual(TBuffer&ClassDef_StreamerNVirtual_b) { name::Streamer(ClassDef_StreamerNVirtual_b); } \
312 static const char *DeclFileName() { return __FILE__; } \
313 static int ImplFileLine() { return 0; } \
314 static const char *ImplFileName() { return __FILE__; }
315)ICF";
316}
318
319// The functions are used to bridge cling/clang/llvm compiled with no-rtti and
320// ROOT (which uses rtti)
321
322////////////////////////////////////////////////////////////////////////////////
323/// Print a StackTrace!
324
325extern "C"
328}
329
330////////////////////////////////////////////////////////////////////////////////
331/// Load a library.
332
333extern "C" int TCling__LoadLibrary(const char *library)
334{
335 return gSystem->Load(library, "", false);
336}
337
338////////////////////////////////////////////////////////////////////////////////
339/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
340
341extern "C" void TCling__RestoreInterpreterMutex(void *delta)
342{
343 ((TCling*)gCling)->ApplyToInterpreterMutex(delta);
344}
345
346////////////////////////////////////////////////////////////////////////////////
347/// Lookup libraries in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH with mangled_name,
348/// which is extracted by error messages we get from callback from cling. Return true
349/// when the missing library was autoloaded.
350
351extern "C" bool TCling__LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
352{
353 return ((TCling*)gCling)->LibraryLoadingFailed(errmessage, libStem, permanent, resolved);
354}
355
356////////////////////////////////////////////////////////////////////////////////
357/// Reset the interpreter lock to the state it had before interpreter-related
358/// calls happened.
359
361{
362 return ((TCling*)gCling)->RewindInterpreterMutex();
363}
364
365////////////////////////////////////////////////////////////////////////////////
366/// Lock the interpreter.
367
369{
370 if (gInterpreterMutex) {
372 }
373 return nullptr;
374}
375
376////////////////////////////////////////////////////////////////////////////////
377/// Unlock the interpreter.
378
380{
381 if (gInterpreterMutex) {
383 }
384}
385
386////////////////////////////////////////////////////////////////////////////////
387/// Update TClingClassInfo for a class (e.g. upon seeing a definition).
388
389static void TCling__UpdateClassInfo(const NamedDecl* TD)
390{
391 static Bool_t entered = kFALSE;
392 static vector<const NamedDecl*> updateList;
393 Bool_t topLevel;
394
395 if (entered) topLevel = kFALSE;
396 else {
397 entered = kTRUE;
398 topLevel = kTRUE;
399 }
400 if (topLevel) {
401 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(TD);
402 } else {
403 // If we are called indirectly from within another call to
404 // TCling::UpdateClassInfo, we delay the update until the dictionary loading
405 // is finished (i.e. when we return to the top level TCling::UpdateClassInfo).
406 // This allows for the dictionary to be fully populated when we actually
407 // update the TClass object. The updating of the TClass sometimes
408 // (STL containers and when there is an emulated class) forces the building
409 // of the TClass object's real data (which needs the dictionary info).
410 updateList.push_back(TD);
411 }
412 if (topLevel) {
413 while (!updateList.empty()) {
414 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(updateList.back());
415 updateList.pop_back();
416 }
417 entered = kFALSE;
418 }
419}
420
421void TCling::UpdateEnumConstants(TEnum* enumObj, TClass* cl) const {
422 const clang::Decl* D = static_cast<const clang::Decl*>(enumObj->GetDeclId());
423 if(const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(D)) {
424 // Add the constants to the enum type.
425 for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin(),
426 EDE = ED->enumerator_end(); EDI != EDE; ++EDI) {
427 // Get name of the enum type.
428 std::string constbuf;
429 if (const NamedDecl* END = llvm::dyn_cast<NamedDecl>(*EDI)) {
430 PrintingPolicy Policy((*EDI)->getASTContext().getPrintingPolicy());
431 llvm::raw_string_ostream stream(constbuf);
432 // Don't trigger fopen of the source file to count lines:
433 Policy.AnonymousTagLocations = false;
434 (END)->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
435 }
436 const char* constantName = constbuf.c_str();
437
438 // Get value of the constant.
440 const llvm::APSInt valAPSInt = (*EDI)->getInitVal();
441 if (valAPSInt.isSigned()) {
442 value = valAPSInt.getSExtValue();
443 } else {
444 value = valAPSInt.getZExtValue();
445 }
446
447 // Create the TEnumConstant or update it if existing
448 TEnumConstant* enumConstant = nullptr;
449 TClingClassInfo* tcCInfo = (TClingClassInfo*)(cl ? cl->GetClassInfo() : nullptr);
450 TClingDataMemberInfo* tcDmInfo = new TClingDataMemberInfo(GetInterpreterImpl(), *EDI, tcCInfo);
451 DataMemberInfo_t* dmInfo = (DataMemberInfo_t*) tcDmInfo;
452 if (TObject* encAsTObj = enumObj->GetConstants()->FindObject(constantName)){
453 ((TEnumConstant*)encAsTObj)->Update(dmInfo);
454 } else {
455 enumConstant = new TEnumConstant(dmInfo, constantName, value, enumObj);
456 }
457
458 // Add the global constants to the list of Globals.
459 if (!cl) {
460 TCollection* globals = gROOT->GetListOfGlobals(false);
461 if (!globals->FindObject(constantName)) {
462 globals->Add(enumConstant);
463 }
464 }
465 }
466 }
467}
468
469TEnum* TCling::CreateEnum(void *VD, TClass *cl) const
470{
471 // Handle new enum declaration for either global and nested enums.
472
473 // Create the enum type.
474 TEnum* enumType = nullptr;
475 const clang::Decl* D = static_cast<const clang::Decl*>(VD);
476 std::string buf;
477 if (const EnumDecl* ED = llvm::dyn_cast<EnumDecl>(D)) {
478 // Get name of the enum type.
479 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
480 llvm::raw_string_ostream stream(buf);
481 // Don't trigger fopen of the source file to count lines:
482 Policy.AnonymousTagLocations = false;
483 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
484 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
485 }
486 if (buf.empty()) {
487 return nullptr;
488 }
489 const char* name = buf.c_str();
490 enumType = new TEnum(name, VD, cl);
491 UpdateEnumConstants(enumType, cl);
492
493 return enumType;
494}
495
496void TCling::HandleNewDecl(const void* DV, bool isDeserialized, std::set<TClass*> &modifiedTClasses) {
497 // Handle new declaration.
498 // Record the modified class, struct and namespaces in 'modifiedTClasses'.
499
500 const clang::Decl* D = static_cast<const clang::Decl*>(DV);
501
502 if (!D->isCanonicalDecl() && !isa<clang::NamespaceDecl>(D)
503 && !dyn_cast<clang::RecordDecl>(D)) return;
504
505 if (isa<clang::FunctionDecl>(D->getDeclContext())
506 || isa<clang::TagDecl>(D->getDeclContext()))
507 return;
508
509 // Don't list templates.
510 if (const clang::CXXRecordDecl* RD = dyn_cast<clang::CXXRecordDecl>(D)) {
511 if (RD->getDescribedClassTemplate())
512 return;
513 } else if (const clang::FunctionDecl* FD = dyn_cast<clang::FunctionDecl>(D)) {
514 if (FD->getDescribedFunctionTemplate())
515 return;
516 }
517
518 if (const RecordDecl *TD = dyn_cast<RecordDecl>(D)) {
519 if (TD->isCanonicalDecl() || TD->isThisDeclarationADefinition())
521 }
522 else if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
523
524 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
525 // Mostly just for EnumDecl (the other TagDecl are handled
526 // by the 'RecordDecl' if statement.
528 } else if (const NamespaceDecl* NSD = dyn_cast<NamespaceDecl>(D)) {
530 }
531
532 // We care about declarations on the global scope.
533 if (!isa<TranslationUnitDecl>(ND->getDeclContext()))
534 return;
535
536 // Enums are lazyly created, thus we don not need to handle them here.
537 if (isa<EnumDecl>(ND))
538 return;
539
540 // ROOT says that global is enum(lazylycreated)/var/field declared on the global
541 // scope.
542 if (!(isa<VarDecl>(ND)))
543 return;
544
545 // Skip if already in the list.
546 if (gROOT->GetListOfGlobals()->FindObject(ND->getNameAsString().c_str()))
547 return;
548
549 // Put the global constants and global enums in the corresponding lists.
550 gROOT->GetListOfGlobals()->Add(new TGlobal((DataMemberInfo_t *)
552 cast<ValueDecl>(ND), nullptr)));
553 }
554}
555
556extern "C"
558{
559 // We are sure in this context of the type of the interpreter
560 normCtxt = &( (TCling*) gInterpreter)->GetNormalizedContext();
561}
562
563extern "C"
564void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter*) {
565 ((TCling*)gCling)->UpdateListsOnCommitted(T);
566}
567
568extern "C"
569void TCling__UpdateListsOnUnloaded(const cling::Transaction &T) {
570 ((TCling*)gCling)->UpdateListsOnUnloaded(T);
571}
572
573extern "C"
574void TCling__InvalidateGlobal(const clang::Decl *D) {
575 ((TCling*)gCling)->InvalidateGlobal(D);
576}
577
578extern "C"
579void TCling__TransactionRollback(const cling::Transaction &T) {
580 ((TCling*)gCling)->TransactionRollback(T);
581}
582
583extern "C" void TCling__LibraryLoadedRTTI(const void* dyLibHandle,
584 const char* canonicalName) {
585 ((TCling*)gCling)->LibraryLoaded(dyLibHandle, canonicalName);
586}
587
588extern "C" void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
589{
590 ((TCling *)gCling)->RegisterRdictForLoadPCM(pcmFileNameFullPath, pcmContent);
591}
592
593extern "C" void TCling__LibraryUnloadedRTTI(const void* dyLibHandle,
594 const char* canonicalName) {
595 ((TCling*)gCling)->LibraryUnloaded(dyLibHandle, canonicalName);
596}
597
598
599extern "C"
600TObject* TCling__GetObjectAddress(const char *Name, void *&LookupCtx) {
601 return ((TCling*)gCling)->GetObjectAddress(Name, LookupCtx);
602}
603
604extern "C" const Decl* TCling__GetObjectDecl(TObject *obj) {
605 return ((TClingClassInfo*)obj->IsA()->GetClassInfo())->GetDecl();
606}
607
608extern "C" R__DLLEXPORT TInterpreter *CreateInterpreter(void* interpLibHandle,
609 const char* argv[])
610{
611 auto tcling = new TCling("C++", "cling C++ Interpreter", argv, interpLibHandle);
612
613 return tcling;
614}
615
617{
618 delete interp;
619}
620
621// Load library containing specified class. Returns 0 in case of error
622// and 1 in case if success.
623extern "C" int TCling__AutoLoadCallback(const char* className)
624{
625 return ((TCling*)gCling)->AutoLoad(className);
626}
627
628extern "C" int TCling__AutoParseCallback(const char* className)
629{
630 return ((TCling*)gCling)->AutoParse(className);
631}
632
633extern "C" const char* TCling__GetClassSharedLibs(const char* className, bool skipCore)
634{
635 return ((TCling*)gCling)->GetClassSharedLibs(className, skipCore);
636}
637
638// Returns 0 for failure 1 for success
639extern "C" int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
640{
641 return ((TCling*)gCling)->IsAutoLoadNamespaceCandidate(nsDecl);
642}
643
644extern "C" int TCling__CompileMacro(const char *fileName, const char *options)
645{
646 string file(fileName);
647 string opt(options);
648 return gSystem->CompileMacro(file.c_str(), opt.c_str());
649}
650
651extern "C" void TCling__SplitAclicMode(const char* fileName, string &mode,
652 string &args, string &io, string &fname)
653{
654 string file(fileName);
655 TString f, amode, arguments, aclicio;
656 f = gSystem->SplitAclicMode(file.c_str(), amode, arguments, aclicio);
657 mode = amode.Data(); args = arguments.Data();
658 io = aclicio.Data(); fname = f.Data();
659}
660
661//______________________________________________________________________________
662//
663//
664//
665
666#ifdef R__WIN32
667extern "C" {
668 char *__unDName(char *demangled, const char *mangled, int out_len,
669 void * (* pAlloc )(size_t), void (* pFree )(void *),
670 unsigned short int flags);
671}
672#endif
673
674////////////////////////////////////////////////////////////////////////////////
675/// Find a template decl within N nested namespaces, 0<=N<inf
676/// Assumes 1 and only 1 template present and 1 and only 1 entity contained
677/// by the namespace. Example: `ns1::ns2::..::%nsN::%myTemplate`
678/// Returns nullptr in case of error
679
680static clang::ClassTemplateDecl* FindTemplateInNamespace(clang::Decl* decl)
681{
682 using namespace clang;
683 if (NamespaceDecl* nsd = llvm::dyn_cast<NamespaceDecl>(decl)){
684 return FindTemplateInNamespace(*nsd->decls_begin());
685 }
686
687 if (ClassTemplateDecl* ctd = llvm::dyn_cast<ClassTemplateDecl>(decl)){
688 return ctd;
689 }
690
691 return nullptr; // something went wrong.
692}
693
694//______________________________________________________________________________
695//
696//
697//
698
699int TCling_GenerateDictionary(const std::vector<std::string> &classes,
700 const std::vector<std::string> &headers,
701 const std::vector<std::string> &fwdDecls,
702 const std::vector<std::string> &unknown)
703{
704 //This function automatically creates the "LinkDef.h" file for templated
705 //classes then executes CompileMacro on it.
706 //The name of the file depends on the class name, and it's not generated again
707 //if the file exist.
708 if (classes.empty()) {
709 return 0;
710 }
711 // Use the name of the first class as the main name.
712 const std::string& className = classes[0];
713 //(0) prepare file name
714 TString fileName = "AutoDict_";
715 std::string::const_iterator sIt;
716 for (sIt = className.begin(); sIt != className.end(); ++sIt) {
717 if (*sIt == '<' || *sIt == '>' ||
718 *sIt == ' ' || *sIt == '*' ||
719 *sIt == ',' || *sIt == '&' ||
720 *sIt == ':') {
721 fileName += '_';
722 }
723 else {
724 fileName += *sIt;
725 }
726 }
727 if (classes.size() > 1) {
728 Int_t chk = 0;
729 std::vector<std::string>::const_iterator it = classes.begin();
730 while ((++it) != classes.end()) {
731 for (UInt_t cursor = 0; cursor != it->length(); ++cursor) {
732 chk = chk * 3 + it->at(cursor);
733 }
734 }
735 fileName += TString::Format("_%u", chk);
736 }
737 fileName += ".cxx";
738 if (gSystem->AccessPathName(fileName) != 0) {
739 //file does not exist
740 //(1) prepare file data
741 // If STL, also request iterators' operators.
742 // vector is special: we need to check whether
743 // vector::iterator is a typedef to pointer or a
744 // class.
745 static const std::set<std::string> sSTLTypes {
746 "vector","list","forward_list","deque","map","unordered_map","multimap",
747 "unordered_multimap","set","unordered_set","multiset","unordered_multiset",
748 "queue","priority_queue","stack","iterator"};
749 std::vector<std::string>::const_iterator it;
750 std::string fileContent("");
751 for (it = headers.begin(); it != headers.end(); ++it) {
752 fileContent += "#include \"" + *it + "\"\n";
753 }
754 for (it = unknown.begin(); it != unknown.end(); ++it) {
755 TClass* cl = TClass::GetClass(it->c_str());
756 if (cl && cl->GetDeclFileName()) {
757 TString header = gSystem->BaseName(cl->GetDeclFileName());
759 TString dirbase(gSystem->BaseName(dir));
760 while (dirbase.Length() && dirbase != "."
761 && dirbase != "include" && dirbase != "inc"
762 && dirbase != "prec_stl") {
763 gSystem->PrependPathName(dirbase, header);
764 dir = gSystem->GetDirName(dir);
765 }
766 fileContent += TString("#include \"") + header + "\"\n";
767 }
768 }
769 for (it = fwdDecls.begin(); it != fwdDecls.end(); ++it) {
770 fileContent += "class " + *it + ";\n";
771 }
772 fileContent += "#ifdef __CLING__ \n";
773 fileContent += "#pragma link C++ nestedclasses;\n";
774 fileContent += "#pragma link C++ nestedtypedefs;\n";
775 for (it = classes.begin(); it != classes.end(); ++it) {
776 std::string n(*it);
777 size_t posTemplate = n.find('<');
778 std::set<std::string>::const_iterator iSTLType = sSTLTypes.end();
779 if (posTemplate != std::string::npos) {
780 n.erase(posTemplate, std::string::npos);
781 if (n.compare(0, 5, "std::") == 0) {
782 n.erase(0, 5);
783 }
784 iSTLType = sSTLTypes.find(n);
785 }
786 fileContent += "#pragma link C++ class ";
787 fileContent += *it + "+;\n" ;
788 if (iSTLType == sSTLTypes.end()) {
789 // Not an STL class; we need to allow the I/O of contained
790 // classes (now that we have a dictionary for them).
791 fileContent += "#pragma link C++ class " + *it + "::*+;\n" ;
792 }
793 }
794 fileContent += "#endif\n";
795 //end(1)
796 //(2) prepare the file
797 FILE* filePointer;
798 filePointer = fopen(fileName, "w");
799 if (filePointer == nullptr) {
800 //can't open a file
801 return 1;
802 }
803 //end(2)
804 //write data into the file
805 fprintf(filePointer, "%s", fileContent.c_str());
806 fclose(filePointer);
807 }
808 //(3) checking if we can compile a macro, if not then cleaning
809 Int_t oldErrorIgnoreLevel = gErrorIgnoreLevel;
810 gErrorIgnoreLevel = kWarning; // no "Info: creating library..."
811 Int_t ret = gSystem->CompileMacro(fileName, "k");
812 gErrorIgnoreLevel = oldErrorIgnoreLevel;
813 if (ret == 0) { //can't compile a macro
814 return 2;
815 }
816 //end(3)
817 return 0;
818}
819
820int TCling_GenerateDictionary(const std::string& className,
821 const std::vector<std::string> &headers,
822 const std::vector<std::string> &fwdDecls,
823 const std::vector<std::string> &unknown)
824{
825 //This function automatically creates the "LinkDef.h" file for templated
826 //classes then executes CompileMacro on it.
827 //The name of the file depends on the class name, and it's not generated again
828 //if the file exist.
829 std::vector<std::string> classes;
830 classes.push_back(className);
831 return TCling_GenerateDictionary(classes, headers, fwdDecls, unknown);
832}
833
834//______________________________________________________________________________
835//
836//
837//
838
839// It is a "fantom" method to synchronize user keyboard input
840// and ROOT prompt line (for WIN32)
841const char* fantomline = "TRint::EndOfLineAction();";
842
843//______________________________________________________________________________
844//
845//
846//
847
848void* TCling::fgSetOfSpecials = nullptr;
849
850//______________________________________________________________________________
851//
852// llvm error handler through exceptions; see also cling/UserInterface
853//
854namespace {
855 // Handle fatal llvm errors by throwing an exception.
856 // Yes, throwing exceptions in error handlers is bad.
857 // Doing nothing is pretty terrible, too.
858 void exceptionErrorHandler(void * /*user_data*/,
859 const char *reason,
860 bool /*gen_crash_diag*/) {
861 throw std::runtime_error(std::string(">>> Interpreter compilation error:\n") + reason);
862 }
863}
864
865//______________________________________________________________________________
866//
867//
868//
869
870////////////////////////////////////////////////////////////////////////////////
871
872namespace{
873 // An instance of this class causes the diagnostics of clang to be suppressed
874 // during its lifetime
875 class clangDiagSuppr {
876 public:
877 clangDiagSuppr(clang::DiagnosticsEngine& diag): fDiagEngine(diag){
878 fOldDiagValue = fDiagEngine.getIgnoreAllWarnings();
879 fDiagEngine.setIgnoreAllWarnings(true);
880 }
881
882 ~clangDiagSuppr() {
883 fDiagEngine.setIgnoreAllWarnings(fOldDiagValue);
884 }
885 private:
886 clang::DiagnosticsEngine& fDiagEngine;
887 bool fOldDiagValue;
888 };
889
890}
891
892////////////////////////////////////////////////////////////////////////////////
893/// Allow calling autoparsing from TMetaUtils
895{
896 return gCling->AutoParse(cname);
897}
898
899////////////////////////////////////////////////////////////////////////////////
900/// Try hard to avoid looking up in the Cling database as this could enduce
901/// an unwanted autoparsing.
902
903bool TClingLookupHelper__ExistingTypeCheck(const std::string &tname,
904 std::string &result)
905{
906 result.clear();
907
908 unsigned long offset = 0;
909 if (strncmp(tname.c_str(), "const ", 6) == 0) {
910 offset = 6;
911 }
912 unsigned long end = tname.length();
913 while( end && (tname[end-1]=='&' || tname[end-1]=='*' || tname[end-1]==']') ) {
914 if ( tname[end-1]==']' ) {
915 --end;
916 while ( end && tname[end-1]!='[' ) --end;
917 }
918 --end;
919 }
920 std::string innerbuf;
921 const char *inner;
922 if (end != tname.length()) {
923 innerbuf = tname.substr(offset,end-offset);
924 inner = innerbuf.c_str();
925 } else {
926 inner = tname.c_str()+offset;
927 }
928
929 //if (strchr(tname.c_str(),'[')!=0) fprintf(stderr,"DEBUG: checking on %s vs %s %lu %lu\n",tname.c_str(),inner,offset,end);
930 if (gROOT->GetListOfClasses()->FindObject(inner)
931 || TClassTable::Check(inner,result) ) {
932 // This is a known class.
933 return true;
934 }
935
936 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
937 TDataType *type = (TDataType *)typeTable->THashTable::FindObject( inner );
938 if (type) {
939 // This is a raw type and an already loaded typedef.
940 const char *newname = type->GetFullTypeName();
941 if (type->GetType() == kLong64_t) {
942 newname = "Long64_t";
943 } else if (type->GetType() == kULong64_t) {
944 newname = "ULong64_t";
945 }
946 if (strcmp(inner,newname) == 0) {
947 return true;
948 }
949 if (offset) result = "const ";
950 result += newname;
951 if ( end != tname.length() ) {
952 result += tname.substr(end,tname.length()-end);
953 }
954 if (result == tname) result.clear();
955 return true;
956 }
957
958 // Check if the name is an enumerator
959 const auto lastPos = TClassEdit::GetUnqualifiedName(inner);
960 if (lastPos != inner) // Main switch: case 1 - scoped enum, case 2 global enum
961 {
962 // We have a scope
963 const auto enName = lastPos;
964 const auto scopeNameSize = (lastPos - inner) / sizeof(decltype(*lastPos)) - 2;
965 std::string scopeName{inner, scopeNameSize};
966 // Check if the scope is in the list of classes
967 if (auto scope = static_cast<TClass *>(gROOT->GetListOfClasses()->FindObject(scopeName.c_str()))) {
968 auto enumTable = dynamic_cast<const THashList *>(scope->GetListOfEnums(false));
969 if (enumTable && enumTable->THashList::FindObject(enName))
970 return true;
971 }
972 // It may still be in one of the loaded protoclasses
973 else if (auto scope = static_cast<TProtoClass *>(gClassTable->GetProtoNorm(scopeName.c_str()))) {
974 auto listOfEnums = scope->GetListOfEnums();
975 if (listOfEnums) { // it could be null: no enumerators in the protoclass
976 auto enumTable = dynamic_cast<const THashList *>(listOfEnums);
977 if (enumTable && enumTable->THashList::FindObject(enName))
978 return true;
979 }
980 }
981 } else
982 {
983 // We don't have any scope: this could only be a global enum
984 auto enumTable = dynamic_cast<const THashList *>(gROOT->GetListOfEnums());
985 if (enumTable && enumTable->THashList::FindObject(inner)) return true;
986 }
987
988 if (gCling->GetClassSharedLibs(inner))
989 {
990 // This is a class name.
991 return true;
992 }
993
994 return false;
995}
996
997////////////////////////////////////////////////////////////////////////////////
998
1000{
1001 fContent.reserve(size);
1002}
1003
1004////////////////////////////////////////////////////////////////////////////////
1005
1007{
1008 return fContent.c_str();
1009}
1010
1011////////////////////////////////////////////////////////////////////////////////
1012/// Append string to the storage if not added already.
1013
1014inline bool TCling::TUniqueString::Append(const std::string& str)
1015{
1016 bool notPresent = fLinesHashSet.emplace(fHashFunc(str)).second;
1017 if (notPresent){
1018 fContent+=str;
1019 }
1020 return notPresent;
1021}
1022
1023std::string TCling::ToString(const char* type, void* obj)
1024{
1025 return fInterpreter->toString(type, obj);
1026}
1027
1028////////////////////////////////////////////////////////////////////////////////
1029///\returns true if the module was loaded.
1030static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
1031{
1032 // When starting up ROOT, cling would load all modulemap files on the include
1033 // paths. However, in a ROOT session, it is very common to run aclic which
1034 // will invoke rootcling and possibly produce a modulemap and a module in
1035 // the current folder.
1036 //
1037 // Before failing, try loading the modulemap in the current folder and try
1038 // loading the requested module from it.
1039 std::string currentDir = gSystem->WorkingDirectory();
1040 assert(!currentDir.empty());
1042 if (gDebug > 2)
1043 ::Info("TCling::__LoadModule", "Preloading module %s. \n",
1044 ModuleName.c_str());
1045
1046 return interp.loadModule(ModuleName, /*Complain=*/true);
1047}
1048
1049////////////////////////////////////////////////////////////////////////////////
1050/// Loads the C++ modules that we require to run any ROOT program. This is just
1051/// supposed to make a C++ module from a modulemap available to the interpreter.
1052static void LoadModules(const std::vector<std::string> &modules, cling::Interpreter &interp)
1053{
1054 for (const auto &modName : modules)
1055 LoadModule(modName, interp);
1056}
1057
1058static bool IsFromRootCling() {
1059 // rootcling also uses TCling for generating the dictionary ROOT files.
1060 const static bool foundSymbol = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
1061 return foundSymbol;
1062}
1063
1064/// Checks if there is an ASTFile on disk for the given module \c M.
1065static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName = nullptr)
1066{
1067 const HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
1068
1069 std::string ModuleFileName;
1070 if (!HSOpts.PrebuiltModulePaths.empty())
1071 // Load the module from *only* in the prebuilt module path.
1072 ModuleFileName = PP.getHeaderSearchInfo().getPrebuiltModuleFileName(M->Name);
1073 if (FullFileName)
1074 *FullFileName = ModuleFileName;
1075
1076 return !ModuleFileName.empty();
1077}
1078
1079static bool HaveFullGlobalModuleIndex = false;
1080static GlobalModuleIndex *loadGlobalModuleIndex(cling::Interpreter &interp)
1081{
1082 CompilerInstance &CI = *interp.getCI();
1083 Preprocessor &PP = CI.getPreprocessor();
1084 auto ModuleManager = CI.getASTReader();
1085 assert(ModuleManager);
1086 // StringRef ModuleIndexPath = HSI.getModuleCachePath();
1087 // HeaderSearch& HSI = PP.getHeaderSearchInfo();
1088 // HSI.setModuleCachePath(TROOT::GetSharedLibDir().Data());
1089 std::string ModuleIndexPath = TROOT::GetSharedLibDir().Data();
1090 if (ModuleIndexPath.empty())
1091 return nullptr;
1092 // Get an existing global index. This loads it if not already loaded.
1093 ModuleManager->resetForReload();
1094 ModuleManager->loadGlobalIndex();
1095 GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex();
1096
1097 // For finding modules needing to be imported for fixit messages,
1098 // we need to make the global index cover all modules, so we do that here.
1099 if (!GlobalIndex && !HaveFullGlobalModuleIndex) {
1100 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1101 bool RecreateIndex = false;
1102 for (ModuleMap::module_iterator I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1103 Module *TheModule = I->second;
1104 // We want the index only of the prebuilt modules.
1105 if (!HasASTFileOnDisk(TheModule, PP))
1106 continue;
1107 LoadModule(TheModule->Name, interp);
1108 RecreateIndex = true;
1109 }
1110 if (RecreateIndex) {
1111 cling::Interpreter::PushTransactionRAII deserRAII(&interp);
1112 clang::GlobalModuleIndex::UserDefinedInterestingIDs IDs;
1113
1114 struct DefinitionFinder : public RecursiveASTVisitor<DefinitionFinder> {
1115 DefinitionFinder(clang::GlobalModuleIndex::UserDefinedInterestingIDs& IDs,
1116 clang::TranslationUnitDecl* TU) : DefinitionIDs(IDs) {
1117 TraverseDecl(TU);
1118 }
1119 bool VisitNamedDecl(NamedDecl *ND) {
1120 if (!ND->isFromASTFile())
1121 return true;
1122 if (!ND->getIdentifier())
1123 return true;
1124
1125 if (ND->getAccess() == AS_protected || ND->getAccess() == AS_private)
1126 return true;
1127
1128 if (TagDecl *TD = llvm::dyn_cast<TagDecl>(ND)) {
1129 if (TD->isCompleteDefinition())
1130 Register(TD);
1131 } else if (NamespaceDecl *NSD = llvm::dyn_cast<NamespaceDecl>(ND)) {
1132 Register(NSD, /*AddSingleEntry=*/ false);
1133 }
1134 else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(ND))
1135 Register(TND);
1136 // FIXME: Add the rest...
1137 return true; // continue decending
1138 }
1139 private:
1140 clang::GlobalModuleIndex::UserDefinedInterestingIDs &DefinitionIDs;
1141 void Register(const NamedDecl* ND, bool AddSingleEntry = true) {
1142 assert(ND->isFromASTFile());
1143 // FIXME: All decls should have an owning module once rootcling
1144 // updates its generated decls from within the LookupHelper & co.
1145 if (!ND->hasOwningModule()) {
1146#ifndef NDEBUG
1147 SourceManager &SM = ND->getASTContext().getSourceManager();
1148 SourceLocation Loc = ND->getLocation();
1149 const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Loc));
1150 (void)FE;
1151 assert(FE->getName().contains("input_line_"));
1152#endif
1153 return;
1154 }
1155
1156 Module *OwningModule = ND->getOwningModule()->getTopLevelModule();
1157 assert(OwningModule);
1158 assert(!ND->getName().empty() && "Empty name");
1159 if (AddSingleEntry && DefinitionIDs.count(ND->getName()))
1160 return;
1161 // FIXME: The FileEntry in not stable to serialize.
1162 // FIXME: We might end up with many times with the same module.
1163 // FIXME: We might end up two modules containing a definition.
1164 // FIXME: What do we do if no definition is found.
1165 DefinitionIDs[ND->getName()].push_back(OwningModule->getASTFile());
1166 }
1167 };
1168 DefinitionFinder defFinder(IDs, CI.getASTContext().getTranslationUnitDecl());
1169
1170 llvm::cantFail(GlobalModuleIndex::writeIndex(CI.getFileManager(),
1171 CI.getPCHContainerReader(),
1172 ModuleIndexPath,
1173 &IDs));
1174 ModuleManager->resetForReload();
1175 ModuleManager->loadGlobalIndex();
1176 GlobalIndex = ModuleManager->getGlobalIndex();
1177 }
1179 }
1180 return GlobalIndex;
1181}
1182
1183static void RegisterCxxModules(cling::Interpreter &clingInterp)
1184{
1185 if (!clingInterp.getCI()->getLangOpts().Modules)
1186 return;
1187
1188 // Loading of a module might deserialize.
1189 cling::Interpreter::PushTransactionRAII deserRAII(&clingInterp);
1190
1191 // Setup core C++ modules if we have any to setup.
1192
1193 // Load libc and stl first.
1194 // Load vcruntime module for windows
1195#ifdef R__WIN32
1196 LoadModule("vcruntime", clingInterp);
1197 LoadModule("services", clingInterp);
1198#endif
1199
1200#ifdef R__MACOSX
1201 LoadModule("Darwin", clingInterp);
1202#else
1203 LoadModule("libc", clingInterp);
1204#endif
1205 LoadModule("std", clingInterp);
1206
1207 LoadModule("_Builtin_intrinsics", clingInterp);
1208
1209 // Load core modules
1210 // This should be vector in order to be able to pass it to LoadModules
1211 std::vector<std::string> CoreModules = {"ROOT_Foundation_C",
1212 "ROOT_Config",
1213 "ROOT_Rtypes",
1214 "ROOT_Foundation_Stage1_NoRTTI",
1215 "Core",
1216 "Rint",
1217 "RIO"};
1218
1219 LoadModules(CoreModules, clingInterp);
1220
1221 // Take this branch only from ROOT because we don't need to preload modules in rootcling
1222 if (!IsFromRootCling()) {
1223 std::vector<std::string> CommonModules = {"MathCore"};
1224 LoadModules(CommonModules, clingInterp);
1225
1226 // These modules should not be preloaded but they fix issues.
1227 // FIXME: Hist is not a core module but is very entangled to MathCore and
1228 // causes issues.
1229 std::vector<std::string> FIXMEModules = {"Hist"};
1230 clang::CompilerInstance &CI = *clingInterp.getCI();
1231 clang::Preprocessor &PP = CI.getPreprocessor();
1232 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1233 if (MMap.findModule("RInterface"))
1234 FIXMEModules.push_back("RInterface");
1235
1236 LoadModules(FIXMEModules, clingInterp);
1237
1238 GlobalModuleIndex *GlobalIndex = nullptr;
1239 loadGlobalModuleIndex(clingInterp);
1240 // FIXME: The ASTReader still calls loadGlobalIndex and loads the file
1241 // We should investigate how to suppress it completely.
1242 GlobalIndex = CI.getASTReader()->getGlobalIndex();
1243
1244 llvm::StringSet<> KnownModuleFileNames;
1245 if (GlobalIndex)
1246 GlobalIndex->getKnownModuleFileNames(KnownModuleFileNames);
1247
1248 std::vector<std::string> PendingModules;
1249 PendingModules.reserve(256);
1250 for (auto I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1251 clang::Module *M = I->second;
1252 assert(M);
1253
1254 // We want to load only already created modules.
1255 std::string FullASTFilePath;
1256 if (!HasASTFileOnDisk(M, PP, &FullASTFilePath))
1257 continue;
1258
1259 if (GlobalIndex && KnownModuleFileNames.count(FullASTFilePath))
1260 continue;
1261
1262 if (M->IsUnimportable)
1263 continue;
1264
1265 if (GlobalIndex)
1266 LoadModule(M->Name, clingInterp);
1267 else {
1268 // FIXME: We may be able to remove those checks as cling::loadModule
1269 // checks if a module was alredy loaded.
1270 if (std::find(CoreModules.begin(), CoreModules.end(), M->Name) != CoreModules.end())
1271 continue; // This is a core module which was already loaded.
1272
1273 // Load system modules now and delay the other modules after we have
1274 // loaded all system ones.
1275 if (M->IsSystem)
1276 LoadModule(M->Name, clingInterp);
1277 else
1278 PendingModules.push_back(M->Name);
1279 }
1280 }
1281 LoadModules(PendingModules, clingInterp);
1282 }
1283
1284 // Check that the gROOT macro was exported by any core module.
1285 assert(clingInterp.getMacro("gROOT") && "Couldn't load gROOT macro?");
1286
1287 // `ERROR` and `PI` are from loading R related modules, which conflict with
1288 // user's code.
1289 clingInterp.declare(R"CODE(
1290#ifdef PI
1291# undef PI
1292#endif
1293#ifdef ERROR
1294# undef ERROR
1295#endif
1296 )CODE");
1297}
1298
1299static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
1300{
1301 std::string PreIncludes;
1302 bool hasCxxModules = clingInterp.getCI()->getLangOpts().Modules;
1303
1304 // For the list to also include string, we have to include it now.
1305 // rootcling does parts already if needed, e.g. genreflex does not want using
1306 // namespace std.
1307 if (IsFromRootCling()) {
1308 PreIncludes += "#include \"RtypesCore.h\"\n";
1309 } else {
1310 if (!hasCxxModules)
1311 PreIncludes += "#include \"Rtypes.h\"\n";
1312
1313 PreIncludes += gClassDefInterpMacro + "\n"
1314 + gInterpreterClassDef + "\n"
1315 "#undef ClassImp\n"
1316 "#define ClassImp(X);\n";
1317 }
1318 if (!hasCxxModules)
1319 PreIncludes += "#include <string>\n";
1320
1321 // We must include it even when we have modules because it is marked as
1322 // textual in the modulemap due to the nature of the assert header.
1323#ifndef R__WIN32
1324 PreIncludes += "#include <cassert>\n";
1325#endif
1326 PreIncludes += "using namespace std;\n";
1327 clingInterp.declare(PreIncludes);
1328}
1329
1330////////////////////////////////////////////////////////////////////////////////
1331/// Initialize the cling interpreter interface.
1332/// \param name name for TInterpreter
1333/// \param title title for TInterpreter
1334/// \param argv - array of arguments passed to the cling::Interpreter constructor
1335/// e.g. `-DFOO=bar`. The last element of the array must be `nullptr`.
1336
1337TCling::TCling(const char *name, const char *title, const char* const argv[], void *interpLibHandle)
1338: TInterpreter(name, title), fGlobalsListSerial(-1), fMapfile(nullptr),
1339 fRootmapFiles(nullptr), fLockProcessLine(true), fNormalizedCtxt(nullptr),
1340 fPrevLoadedDynLibInfo(nullptr), fClingCallbacks(nullptr), fAutoLoadCallBack(nullptr),
1342{
1343 fPrompt[0] = 0;
1344 const bool fromRootCling = IsFromRootCling();
1345
1346 fCxxModulesEnabled = false;
1347#ifdef R__USE_CXXMODULES
1348 fCxxModulesEnabled = true;
1349#endif
1350
1351 llvm::install_fatal_error_handler(&exceptionErrorHandler);
1352
1353 fTemporaries = new std::vector<cling::Value>();
1354
1355 std::vector<std::string> clingArgsStorage;
1356 clingArgsStorage.push_back("cling4root");
1357 for (const char* const* arg = argv; *arg; ++arg)
1358 clingArgsStorage.push_back(*arg);
1359
1360 // rootcling sets its arguments through TROOT::GetExtraInterpreterArgs().
1361 if (!fromRootCling) {
1363
1364 // Add -I early so ASTReader can find the headers.
1365 std::string interpInclude(TROOT::GetEtcDir().Data());
1366 clingArgsStorage.push_back("-I" + interpInclude);
1367
1368 // Add include path to etc/cling.
1369 clingArgsStorage.push_back("-I" + interpInclude + "/cling");
1370
1371 // Add include path to etc/cling.
1372 clingArgsStorage.push_back("-I" + interpInclude + "/cling/plugins/include");
1373
1374 // Add the root include directory and etc/ to list searched by default.
1375 clingArgsStorage.push_back(std::string(("-I" + TROOT::GetIncludeDir()).Data()));
1376
1377 // Add the current path to the include path
1378 // TCling::AddIncludePath(".");
1379
1380 // Attach the PCH (unless we have C++ modules enabled which provide the
1381 // same functionality).
1382 if (!fCxxModulesEnabled) {
1383 std::string pchFilename = interpInclude + "/allDict.cxx.pch";
1384 if (gSystem->Getenv("ROOT_PCH")) {
1385 pchFilename = gSystem->Getenv("ROOT_PCH");
1386 }
1387
1388 clingArgsStorage.push_back("-include-pch");
1389 clingArgsStorage.push_back(pchFilename);
1390 }
1391
1392 clingArgsStorage.push_back("-Wno-undefined-inline");
1393 clingArgsStorage.push_back("-fsigned-char");
1394 // The -O1 optimization flag has nasty side effects on Windows (32 and 64 bit)
1395 // See the GitHub issues #9809 and #9944
1396 // TODO: to be reviewed after the upgrade of LLVM & Clang
1397#ifndef _MSC_VER
1398 clingArgsStorage.push_back("-O1");
1399 // Disable optimized register allocation which is turned on automatically
1400 // by -O1, but seems to require -O2 to not explode in run time.
1401 clingArgsStorage.push_back("-mllvm");
1402 clingArgsStorage.push_back("-optimize-regalloc=0");
1403#endif
1404 }
1405
1406 // Process externally passed arguments if present.
1407 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv("EXTRA_CLING_ARGS");
1408 if (EnvOpt.has_value()) {
1409 StringRef Env(*EnvOpt);
1410 while (!Env.empty()) {
1411 StringRef Arg;
1412 std::tie(Arg, Env) = Env.split(' ');
1413 clingArgsStorage.push_back(Arg.str());
1414 }
1415 }
1416
1417 auto GetEnvVarPath = [](const std::string &EnvVar, std::vector<std::string> &Paths) {
1418 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv(EnvVar);
1419 if (EnvOpt.has_value()) {
1420 StringRef Env(*EnvOpt);
1421 while (!Env.empty()) {
1422 StringRef Arg;
1423 std::tie(Arg, Env) = Env.split(ROOT::FoundationUtils::GetEnvPathSeparator());
1424 if (std::find(Paths.begin(), Paths.end(), Arg.str()) == Paths.end())
1425 Paths.push_back(Arg.str());
1426 }
1427 }
1428 };
1429
1430 if (fCxxModulesEnabled) {
1431 std::vector<std::string> Paths;
1432 // ROOT usually knows better where its libraries are. This way we can
1433 // discover modules without having to should thisroot.sh and should fix
1434 // gnuinstall.
1435 Paths.push_back(TROOT::GetSharedLibDir().Data());
1436 GetEnvVarPath("CLING_PREBUILT_MODULE_PATH", Paths);
1437 std::string EnvVarPath;
1438 for (const std::string& P : Paths)
1440 // FIXME: We should make cling -fprebuilt-module-path work.
1441 gSystem->Setenv("CLING_PREBUILT_MODULE_PATH", EnvVarPath.c_str());
1442 }
1443
1444 // FIXME: This only will enable frontend timing reports.
1445 EnvOpt = llvm::sys::Process::GetEnv("ROOT_CLING_TIMING");
1446 if (EnvOpt.has_value())
1447 clingArgsStorage.push_back("-ftime-report");
1448
1449 // Add the overlay file. Note that we cannot factor it out for both root
1450 // and rootcling because rootcling activates modules only if -cxxmodule
1451 // flag is passed.
1452 if (fCxxModulesEnabled && !fromRootCling) {
1453 // For now we prefer rootcling to enumerate explicitly its modulemaps.
1454 std::vector<std::string> ModuleMaps;
1455 std::string ModuleMapSuffix = ROOT::FoundationUtils::GetPathSeparator() + "ROOT.modulemap";
1456 ModuleMaps.push_back(TROOT::GetIncludeDir().Data() + ModuleMapSuffix);
1457 GetEnvVarPath("CLING_MODULEMAP_FILES", ModuleMaps);
1458
1459 std::string cwd = gSystem->WorkingDirectory();
1460 // Give highest precedence of the modulemap in the cwd if any.
1461 if (llvm::sys::fs::exists(cwd + ModuleMapSuffix))
1462 ModuleMaps.push_back(cwd + ModuleMapSuffix);
1463
1464 for (const std::string& M : ModuleMaps)
1465 clingArgsStorage.push_back("-fmodule-map-file=" + M);
1466
1467 std::string ModulesCachePath;
1468 EnvOpt = llvm::sys::Process::GetEnv("CLING_MODULES_CACHE_PATH");
1469 if (EnvOpt.has_value()){
1470 StringRef Env(*EnvOpt);
1471 assert(llvm::sys::fs::exists(Env) && "Path does not exist!");
1472 ModulesCachePath = Env.str();
1473 } else {
1474 ModulesCachePath = TROOT::GetSharedLibDir();
1475 }
1476
1477 clingArgsStorage.push_back("-fmodules-cache-path=" + ModulesCachePath);
1478 }
1479
1480 std::vector<const char*> interpArgs;
1481 for (std::vector<std::string>::const_iterator iArg = clingArgsStorage.begin(),
1482 eArg = clingArgsStorage.end(); iArg != eArg; ++iArg)
1483 interpArgs.push_back(iArg->c_str());
1484
1485 // Activate C++ modules support. If we are running within rootcling, it's up
1486 // to rootcling to set this flag depending on whether it wants to produce
1487 // C++ modules.
1488 TString vfsArg;
1489 if (fCxxModulesEnabled) {
1490 if (!fromRootCling) {
1491 // We only set this flag, rest is done by the CIFactory.
1492 interpArgs.push_back("-fmodules");
1493 interpArgs.push_back("-fno-implicit-module-maps");
1494 // We should never build modules during runtime, so let's enable the
1495 // module build remarks from clang to make it easier to spot when we do
1496 // this by accident.
1497 interpArgs.push_back("-Rmodule-build");
1498 }
1499 // ROOT implements its AutoLoading upon module's link directives. We
1500 // generate module A { header "A.h" link "A.so" export * } where ROOT's
1501 // facilities use the link directive to dynamically load the relevant
1502 // library. So, we need to suppress clang's default autolink behavior.
1503 interpArgs.push_back("-fno-autolink");
1504 }
1505
1506#ifdef R__FAST_MATH
1507 // Same setting as in rootcling_impl.cxx.
1508 interpArgs.push_back("-ffast-math");
1509#endif
1510
1511 TString llvmResourceDir = TROOT::GetEtcDir() + "/cling";
1512 // Add statically injected extra arguments, usually coming from rootcling.
1513 for (const char** extraArgs = TROOT::GetExtraInterpreterArgs();
1514 extraArgs && *extraArgs; ++extraArgs) {
1515 if (!strcmp(*extraArgs, "-resource-dir")) {
1516 // Take the next arg as the llvm resource directory.
1517 llvmResourceDir = *(++extraArgs);
1518 } else {
1519 interpArgs.push_back(*extraArgs);
1520 }
1521 }
1522
1523 std::vector<std::string> _empty;
1524 auto args = TROOT::AddExtraInterpreterArgs(_empty);
1525 for (const auto &arg: args)
1526 interpArgs.emplace_back(arg.c_str());
1527
1528 // Add the Rdict module file extension.
1529 cling::Interpreter::ModuleFileExtensions extensions;
1530 EnvOpt = llvm::sys::Process::GetEnv("ROOTDEBUG_RDICT");
1531 if (!EnvOpt.has_value())
1532 extensions.push_back(std::make_shared<TClingRdictModuleFileExtension>());
1533
1534 fInterpreter = std::make_unique<cling::Interpreter>(interpArgs.size(),
1535 &(interpArgs[0]),
1536 llvmResourceDir, extensions,
1537 interpLibHandle);
1538
1539 // Don't check whether modules' files exist.
1540 fInterpreter->getCI()->getPreprocessorOpts().DisablePCHOrModuleValidation =
1541 DisableValidationForModuleKind::All;
1542
1543 // Until we can disable AutoLoading during Sema::CorrectTypo() we have
1544 // to disable spell checking.
1545 fInterpreter->getCI()->getLangOpts().SpellChecking = false;
1546
1547 // Sync modules on/off between clang and us: clang turns it on for C++ >= 20.
1548 auto isModulesArg = [](const char* arg) { return !strcmp(arg, "-fmodules"); };
1549 bool hasModulesArg = std::find_if(interpArgs.begin(), interpArgs.end(), isModulesArg) != interpArgs.end();
1550 fInterpreter->getCI()->getLangOpts().Modules = hasModulesArg;
1551
1552 // We need stream that doesn't close its file descriptor, thus we are not
1553 // using llvm::outs. Keeping file descriptor open we will be able to use
1554 // the results in pipes (Savannah #99234).
1555 static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO, /*ShouldClose*/false);
1556 fMetaProcessor = std::make_unique<cling::MetaProcessor>(*fInterpreter, fMPOuts);
1557
1560
1561 // We are now ready (enough is loaded) to init the list of opaque typedefs.
1568
1569 // Disallow auto-parsing in rootcling
1570 fIsAutoParsingSuspended = fromRootCling;
1571
1572 ResetAll();
1573
1574 // Enable dynamic lookup
1575 if (!fromRootCling) {
1576 fInterpreter->enableDynamicLookup();
1577 }
1578
1579 // Enable ClinG's DefinitionShadower for ROOT.
1580 fInterpreter->getRuntimeOptions().AllowRedefinition = 1;
1581 auto &Policy = const_cast<clang::PrintingPolicy &>(fInterpreter->getCI()->getASTContext().getPrintingPolicy());
1582 // Print 'a<b<c> >' rather than 'a<b<c>>'.
1583 // FIXME: We should probably switch to the default printing policy setting
1584 // after adjusting tons of reference files.
1585 Policy.SplitTemplateClosers = true;
1586 // Keep default templare arguments, required for dictionary generation.
1587 Policy.SuppressDefaultTemplateArgs = false;
1588
1589
1590 // Attach cling callbacks last; they might need TROOT::fInterpreter
1591 // and should thus not be triggered during the equivalent of
1592 // TROOT::fInterpreter = new TCling;
1593 std::unique_ptr<TClingCallbacks>
1594 clingCallbacks(new TClingCallbacks(GetInterpreterImpl(), /*hasCodeGen*/ !fromRootCling));
1595 fClingCallbacks = clingCallbacks.get();
1597 fInterpreter->setCallbacks(std::move(clingCallbacks));
1598
1599 if (!fromRootCling) {
1600 cling::DynamicLibraryManager& DLM = *fInterpreter->getDynamicLibraryManager();
1601 // Make sure cling looks into ROOT's libdir, even if not part of LD_LIBRARY_PATH
1602 // e.g. because of an RPATH build.
1603 DLM.addSearchPath(TROOT::GetSharedLibDir().Data(), /*isUser=*/true,
1604 /*prepend=*/true);
1605 auto ShouldPermanentlyIgnore = [](llvm::StringRef FileName) -> bool{
1606 llvm::StringRef stem = llvm::sys::path::stem(FileName);
1607 return stem.startswith("libNew") || stem.startswith("libcppyy_backend");
1608 };
1609 // Initialize the dyld for AutoloadLibraryGenerator.
1610 DLM.initializeDyld(ShouldPermanentlyIgnore);
1611 }
1612}
1613
1614
1615////////////////////////////////////////////////////////////////////////////////
1616/// Destroy the interpreter interface.
1617
1619{
1620 // ROOT's atexit functions require the interepreter to be available.
1621 // Run them before shutting down.
1622 if (!IsFromRootCling())
1623 GetInterpreterImpl()->runAtExitFuncs();
1624 fIsShuttingDown = true;
1625 delete fMapfile;
1626 delete fRootmapFiles;
1627 delete fTemporaries;
1628 delete fNormalizedCtxt;
1629 delete fLookupHelper;
1630 gCling = nullptr;
1631}
1632
1633////////////////////////////////////////////////////////////////////////////////
1634/// Initialize the interpreter, once TROOT::fInterpreter is set.
1635
1637{
1639
1640 // We are set up. Enable ROOT's AutoLoading.
1641 if (IsFromRootCling())
1642 return;
1643
1644 // Read the rules before enabling the auto loading to not inadvertently
1645 // load the libraries for the classes concerned even-though the user is
1646 // *not* using them.
1647 // Note this call must happen before the first call to LoadLibraryMap.
1648 assert(GetRootMapFiles() == nullptr && "Must be called before LoadLibraryMap!");
1649 TClass::ReadRules(); // Read the default customization rules ...
1650
1652 SetClassAutoLoading(true);
1653}
1654
1656{
1657 fIsShuttingDown = true;
1658 ResetGlobals();
1659}
1660
1661////////////////////////////////////////////////////////////////////////////////
1662/// Helper to initialize TVirtualStreamerInfo's factor early.
1663/// Use static initialization to insure only one TStreamerInfo is created.
1665{
1666 // Use lambda since SetFactory return void.
1667 auto setFactory = []() {
1669 return kTRUE;
1670 };
1671 static bool doneFactory = setFactory();
1672 return doneFactory; // avoid unused variable warning.
1673}
1674
1675////////////////////////////////////////////////////////////////////////////////
1676/// Register Rdict data for future loading by LoadPCM;
1677
1678void TCling::RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
1679{
1680 if (IsFromRootCling())
1681 return;
1682
1683 if (llvm::sys::fs::exists(pcmFileNameFullPath)) {
1684 ::Error("TCling::RegisterRdictForLoadPCM", "Rdict '%s' is both in Module extension and in File system.", pcmFileNameFullPath.c_str());
1685 return;
1686 }
1687
1688 // The pcmFileNameFullPath must be resolved already because we cannot resolve
1689 // a link to a non-existent file.
1690 fPendingRdicts[pcmFileNameFullPath] = *pcmContent;
1691}
1692
1693////////////////////////////////////////////////////////////////////////////////
1694/// Tries to load a PCM from TFile; returns true on success.
1695
1697{
1698 auto listOfKeys = pcmFile.GetListOfKeys();
1699
1700 // This is an empty pcm
1701 if (listOfKeys && ((listOfKeys->GetSize() == 0) || // Nothing here, or
1702 ((listOfKeys->GetSize() == 1) && // only one, and
1703 !strcmp(((TKey *)listOfKeys->At(0))->GetName(), "EMPTY") // name is EMPTY
1704 ))) {
1705 return;
1706 }
1707
1708 TObjArray *protoClasses;
1709 if (gDebug > 1)
1710 ::Info("TCling::LoadPCMImpl", "reading protoclasses for %s \n", pcmFile.GetName());
1711
1712 TObjArray *enums;
1713 pcmFile.GetObject("__Enums", enums);
1714 if (enums) {
1715 // Cache the pointers
1716 auto listOfGlobals = gROOT->GetListOfGlobals();
1717 auto listOfEnums = dynamic_cast<THashList *>(gROOT->GetListOfEnums());
1718 // Loop on enums and then on enum constants
1719 for (auto selEnum : *enums) {
1720 const char *enumScope = selEnum->GetTitle();
1721 const char *enumName = selEnum->GetName();
1722 if (strcmp(enumScope, "") == 0) {
1723 // This is a global enum and is added to the
1724 // list of enums and its constants to the list of globals
1725 if (!listOfEnums->THashList::FindObject(enumName)) {
1726 ((TEnum *)selEnum)->SetClass(nullptr);
1727 listOfEnums->Add(selEnum);
1728 }
1729 for (auto enumConstant : *static_cast<TEnum *>(selEnum)->GetConstants()) {
1730 if (!listOfGlobals->FindObject(enumConstant)) {
1731 listOfGlobals->Add(enumConstant);
1732 }
1733 }
1734 } else {
1735 // This enum is in a namespace. A TClass entry is bootstrapped if
1736 // none exists yet and the enum is added to it
1737 TClass *nsTClassEntry = TClass::GetClass(enumScope);
1738 if (!nsTClassEntry) {
1739 nsTClassEntry = new TClass(enumScope, 0, TClass::kNamespaceForMeta, true);
1740 }
1741 auto listOfEnums = nsTClassEntry->fEnums.load();
1742 if (!listOfEnums) {
1743 if ((kIsClass | kIsStruct | kIsUnion) & nsTClassEntry->Property()) {
1744 // For this case, the list will be immutable once constructed
1745 // (i.e. in this case, by the end of this routine).
1746 listOfEnums = nsTClassEntry->fEnums = new TListOfEnums(nsTClassEntry);
1747 } else {
1748 // namespaces can have enums added to them
1749 listOfEnums = nsTClassEntry->fEnums = new TListOfEnumsWithLock(nsTClassEntry);
1750 }
1751 }
1752 if (listOfEnums && !listOfEnums->THashList::FindObject(enumName)) {
1753 ((TEnum *)selEnum)->SetClass(nsTClassEntry);
1754 listOfEnums->Add(selEnum);
1755 }
1756 }
1757 }
1758 enums->Clear();
1759 delete enums;
1760 }
1761
1762 pcmFile.GetObject("__ProtoClasses", protoClasses);
1763
1764 if (protoClasses) {
1765 for (auto obj : *protoClasses) {
1766 TProtoClass *proto = (TProtoClass *)obj;
1768 }
1769 // Now that all TClass-es know how to set them up we can update
1770 // existing TClasses, which might cause the creation of e.g. TBaseClass
1771 // objects which in turn requires the creation of TClasses, that could
1772 // come from the PCH, but maybe later in the loop. Instead of resolving
1773 // a dependency graph the addition to the TClassTable above allows us
1774 // to create these dependent TClasses as needed below.
1775 for (auto proto : *protoClasses) {
1776 if (TClass *existingCl = (TClass *)gROOT->GetListOfClasses()->FindObject(proto->GetName())) {
1777 // We have an existing TClass object. It might be emulated
1778 // or interpreted; we now have more information available.
1779 // Make that available.
1780 if (existingCl->GetState() != TClass::kHasTClassInit) {
1781 DictFuncPtr_t dict = gClassTable->GetDict(proto->GetName());
1782 if (!dict) {
1783 ::Error("TCling::LoadPCM", "Inconsistent TClassTable for %s", proto->GetName());
1784 } else {
1785 // This will replace the existing TClass.
1786 TClass *ncl = (*dict)();
1787 if (ncl)
1788 ncl->PostLoadCheck();
1789 }
1790 }
1791 }
1792 }
1793
1794 protoClasses->Clear(); // Ownership was transfered to TClassTable.
1795 delete protoClasses;
1796 }
1797
1798 TObjArray *dataTypes;
1799 pcmFile.GetObject("__Typedefs", dataTypes);
1800 if (dataTypes) {
1801 for (auto typedf : *dataTypes)
1802 gROOT->GetListOfTypes()->Add(typedf);
1803 dataTypes->Clear(); // Ownership was transfered to TListOfTypes.
1804 delete dataTypes;
1805 }
1806}
1807
1808////////////////////////////////////////////////////////////////////////////////
1809/// Tries to load a rdict PCM, issues diagnostics if it fails.
1810
1811void TCling::LoadPCM(std::string pcmFileNameFullPath)
1812{
1813 SuspendAutoLoadingRAII autoloadOff(this);
1814 SuspendAutoParsing autoparseOff(this);
1815 assert(!pcmFileNameFullPath.empty());
1816 assert(llvm::sys::path::is_absolute(pcmFileNameFullPath));
1817
1818 // Easier to work with the ROOT interfaces.
1819 TString pcmFileName = pcmFileNameFullPath;
1820
1821 // Prevent the ROOT-PCMs hitting this during auto-load during
1822 // JITting - which will cause recursive compilation.
1823 // Avoid to call the plugin manager at all.
1825
1827 llvm::SaveAndRestore<Int_t> SaveGDebug(gDebug);
1828 if (gDebug > 5) {
1829 gDebug -= 5;
1830 ::Info("TCling::LoadPCM", "Loading ROOT PCM %s", pcmFileName.Data());
1831 } else {
1832 gDebug = 0;
1833 }
1834
1835 if (llvm::sys::fs::is_symlink_file(pcmFileNameFullPath))
1836 pcmFileNameFullPath = ROOT::TMetaUtils::GetRealPath(pcmFileNameFullPath);
1837
1838 auto pendingRdict = fPendingRdicts.find(pcmFileNameFullPath);
1839 if (pendingRdict != fPendingRdicts.end()) {
1840 llvm::StringRef pcmContent = pendingRdict->second;
1841 TMemFile::ZeroCopyView_t range{pcmContent.data(), pcmContent.size()};
1842 std::string RDictFileOpts = pcmFileNameFullPath + "?filetype=pcm";
1843 TMemFile pcmMemFile(RDictFileOpts.c_str(), range);
1844
1845 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
1846 LoadPCMImpl(pcmMemFile);
1847 // Currently the module file are never unloaded (even if the library is
1848 // unloaded) and, of course, never reloaded.
1849 // Consequently, we must NOT remove the `pendingRdict` from the list
1850 // of pending dictionary, otherwise if a library is unloaded and then
1851 // reload we will be unable to update properly the TClass object
1852 // (because we wont be able to load the rootpcm file by executing the
1853 // above lines)
1854
1855 return;
1856 }
1857
1858 if (!llvm::sys::fs::exists(pcmFileNameFullPath)) {
1859 ::Error("TCling::LoadPCM", "ROOT PCM %s file does not exist",
1860 pcmFileNameFullPath.data());
1861 if (!fPendingRdicts.empty())
1862 for (const auto &rdict : fPendingRdicts)
1863 ::Info("TCling::LoadPCM", "In-memory ROOT PCM candidate %s\n",
1864 rdict.first.c_str());
1865 return;
1866 }
1867
1868 if (!gROOT->IsRootFile(pcmFileName)) {
1869 Fatal("LoadPCM", "The file %s is not a ROOT as was expected\n", pcmFileName.Data());
1870 return;
1871 }
1872 TFile pcmFile(pcmFileName + "?filetype=pcm", "READ");
1873 LoadPCMImpl(pcmFile);
1874}
1875
1876//______________________________________________________________________________
1877
1878namespace {
1879 using namespace clang;
1880
1881 class ExtLexicalStorageAdder: public RecursiveASTVisitor<ExtLexicalStorageAdder>{
1882 // This class is to be considered an helper for autoparsing.
1883 // It visits the AST and marks all classes (in all of their redeclarations)
1884 // with the setHasExternalLexicalStorage method.
1885 public:
1886 bool VisitRecordDecl(clang::RecordDecl* rcd){
1887 if (gDebug > 2)
1888 Info("ExtLexicalStorageAdder",
1889 "Adding external lexical storage to class %s",
1890 rcd->getNameAsString().c_str());
1891 auto reDeclPtr = rcd->getMostRecentDecl();
1892 do {
1893 reDeclPtr->setHasExternalLexicalStorage();
1894 } while ((reDeclPtr = reDeclPtr->getPreviousDecl()));
1895
1896 return false;
1897 }
1898 };
1899
1900
1901}
1902
1903////////////////////////////////////////////////////////////////////////////////
1904///\returns true if the module map was loaded, false on error or if the map was
1905/// already loaded.
1906bool TCling::RegisterPrebuiltModulePath(const std::string &FullPath,
1907 const std::string &ModuleMapName /*= "module.modulemap"*/) const
1908{
1909 assert(llvm::sys::path::is_absolute(FullPath));
1910 Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
1911 FileManager &FM = PP.getFileManager();
1912 // FIXME: In a ROOT session we can add an include path (through .I /inc/path)
1913 // We should look for modulemap files there too.
1914 if (auto DE = FM.getOptionalDirectoryRef(FullPath)) {
1915 HeaderSearch &HS = PP.getHeaderSearchInfo();
1916 HeaderSearchOptions &HSOpts = HS.getHeaderSearchOpts();
1917 const auto &ModPaths = HSOpts.PrebuiltModulePaths;
1918 bool pathExists = std::find(ModPaths.begin(), ModPaths.end(), FullPath) != ModPaths.end();
1919 if (!pathExists)
1920 HSOpts.AddPrebuiltModulePath(FullPath);
1921 // We cannot use HS.lookupModuleMapFile(DE, /*IsFramework*/ false);
1922 // because its internal call to getFile has CacheFailure set to true.
1923 // In our case, modulemaps can appear any time due to ACLiC.
1924 // Code copied from HS.lookupModuleMapFile.
1925 llvm::SmallString<256> ModuleMapFileName(DE->getName());
1926 llvm::sys::path::append(ModuleMapFileName, ModuleMapName);
1927 if (auto FE = FM.getOptionalFileRef(ModuleMapFileName, /*openFile*/ false,
1928 /*CacheFailure*/ false)) {
1929 if (!HS.loadModuleMapFile(*FE, /*IsSystem*/ false))
1930 return true;
1931 Error("RegisterPrebuiltModulePath", "Could not load modulemap in %s", ModuleMapFileName.c_str());
1932 }
1933 }
1934 return false;
1935}
1936
1937////////////////////////////////////////////////////////////////////////////////
1938/// List of dicts that have the PCM information already in the PCH.
1939static const std::unordered_set<std::string> gIgnoredPCMNames = {"libCore",
1940 "libRint",
1941 "libThread",
1942 "libRIO",
1943 "libImt",
1944 "libMultiProc",
1945 "libcomplexDict",
1946 "libdequeDict",
1947 "liblistDict",
1948 "libforward_listDict",
1949 "libvectorDict",
1950 "libmapDict",
1951 "libmultimap2Dict",
1952 "libmap2Dict",
1953 "libmultimapDict",
1954 "libsetDict",
1955 "libmultisetDict",
1956 "libunordered_setDict",
1957 "libunordered_multisetDict",
1958 "libunordered_mapDict",
1959 "libunordered_multimapDict",
1960 "libvalarrayDict",
1961 "G__GenVector32",
1962 "G__Smatrix32"};
1963
1964static void PrintDlError(const char *dyLibName, const char *modulename)
1965{
1966#ifdef R__WIN32
1967 char dyLibError[1000];
1968 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1969 dyLibError, sizeof(dyLibError), NULL);
1970#else
1971 const char *dyLibError = dlerror();
1972#endif
1973 ::Error("TCling::RegisterModule", "Cannot open shared library %s for dictionary %s:\n %s", dyLibName, modulename,
1974 (dyLibError) ? dyLibError : "");
1975}
1976
1977////////////////////////////////////////////////////////////////////////////////
1978// Update all the TClass registered in fClassesToUpdate
1979
1981{
1982 while (!fClassesToUpdate.empty()) {
1983 TClass *oldcl = fClassesToUpdate.back().first;
1984 // If somehow the TClass has already been loaded (maybe it was registered several time),
1985 // we skip it. Otherwise, the existing TClass is in mode kInterpreted, kEmulated or
1986 // maybe even kForwardDeclared and needs to replaced.
1987 if (oldcl->GetState() != TClass::kHasTClassInit) {
1988 // if (gDebug > 2) Info("RegisterModule", "Forcing TClass init for %s", oldcl->GetName());
1989 DictFuncPtr_t dict = fClassesToUpdate.back().second;
1990 fClassesToUpdate.pop_back();
1991 // Calling func could manipulate the list so, let maintain the list
1992 // then call the dictionary function.
1993 TClass *ncl = dict();
1994 if (ncl) ncl->PostLoadCheck();
1995 } else {
1996 fClassesToUpdate.pop_back();
1997 }
1998 }
1999}
2000////////////////////////////////////////////////////////////////////////////////
2001/// Inject the module named "modulename" into cling; load all headers.
2002/// headers is a 0-terminated array of header files to `#include` after
2003/// loading the module. The module is searched for in all $LD_LIBRARY_PATH
2004/// entries (or %PATH% on Windows).
2005/// This function gets called by the static initialization of dictionary
2006/// libraries.
2007/// The payload code is injected "as is" in the interpreter.
2008/// The value of 'triggerFunc' is used to find the shared library location.
2009
2010void TCling::RegisterModule(const char* modulename,
2011 const char** headers,
2012 const char** includePaths,
2013 const char* payloadCode,
2014 const char* fwdDeclsCode,
2015 void (*triggerFunc)(),
2016 const FwdDeclArgsToKeepCollection_t& fwdDeclsArgToSkip,
2017 const char** classesHeaders,
2018 Bool_t lateRegistration /*=false*/,
2019 Bool_t hasCxxModule /*=false*/)
2020{
2021 const bool fromRootCling = IsFromRootCling();
2022 // We need the dictionary initialization but we don't want to inject the
2023 // declarations into the interpreter, except for those we really need for
2024 // I/O; see rootcling.cxx after the call to TCling__GetInterpreter().
2025 if (fromRootCling) return;
2026
2027 // When we cannot provide a module for the library we should enable header
2028 // parsing. This 'mixed' mode ensures gradual migration to modules.
2029 llvm::SaveAndRestore<bool> SaveHeaderParsing(fHeaderParsingOnDemand);
2030 fHeaderParsingOnDemand = !hasCxxModule;
2031
2032 // Treat Aclic Libs in a special way. Do not delay the parsing.
2033 bool hasHeaderParsingOnDemand = fHeaderParsingOnDemand;
2034 bool isACLiC = strstr(modulename, "_ACLiC_dict") != nullptr;
2035 if (hasHeaderParsingOnDemand && isACLiC) {
2036 if (gDebug>1)
2037 Info("TCling::RegisterModule",
2038 "Header parsing on demand is active but this is an Aclic library. Disabling it for this library.");
2039 hasHeaderParsingOnDemand = false;
2040 }
2041
2042
2043 // Make sure we relookup symbols that were search for before we loaded
2044 // their autoparse information. We could be more subtil and remove only
2045 // the failed one or only the one in this module, but for now this is
2046 // better than nothing.
2047 fLookedUpClasses.clear();
2048
2049 // Make sure we do not set off AutoLoading or autoparsing during the
2050 // module registration!
2051 SuspendAutoLoadingRAII autoLoadOff(this);
2052
2053 for (const char** inclPath = includePaths; *inclPath; ++inclPath) {
2054 TCling::AddIncludePath(*inclPath);
2055 }
2056 cling::Transaction* T = nullptr;
2057 // Put the template decls and the number of arguments to skip in the TNormalizedCtxt
2058 for (auto& fwdDeclArgToSkipPair : fwdDeclsArgToSkip){
2059 const std::string& fwdDecl = fwdDeclArgToSkipPair.first;
2060 const int nArgsToSkip = fwdDeclArgToSkipPair.second;
2061 auto compRes = fInterpreter->declare(fwdDecl.c_str(), &T);
2062 assert(cling::Interpreter::kSuccess == compRes &&
2063 "A fwd declaration could not be compiled");
2064 if (compRes!=cling::Interpreter::kSuccess){
2065 Warning("TCling::RegisterModule",
2066 "Problems in declaring string '%s' were encountered.",
2067 fwdDecl.c_str()) ;
2068 continue;
2069 }
2070
2071 // Drill through namespaces recursively until the template is found
2072 if(ClassTemplateDecl* TD = FindTemplateInNamespace(T->getFirstDecl().getSingleDecl())){
2073 fNormalizedCtxt->AddTemplAndNargsToKeep(TD->getCanonicalDecl(), nArgsToSkip);
2074 }
2075
2076 }
2077
2078 // FIXME: Remove #define __ROOTCLING__ once PCMs are there.
2079 // This is used to give Sema the same view on ACLiC'ed files (which
2080 // are then #included through the dictionary) as rootcling had.
2081 TString code = gNonInterpreterClassDef;
2082 if (payloadCode)
2083 code += payloadCode;
2084
2085 std::string dyLibName = cling::DynamicLibraryManager::getSymbolLocation(triggerFunc);
2086 assert(!llvm::sys::fs::is_symlink_file(dyLibName));
2087
2088 if (dyLibName.empty()) {
2089 ::Error("TCling::RegisterModule", "Dictionary trigger function for %s not found", modulename);
2090 return;
2091 }
2092
2093 // The triggerFunc may not be in a shared object but in an executable.
2094 bool isSharedLib = cling::DynamicLibraryManager::isSharedLibrary(dyLibName);
2095
2096 bool wasDlopened = false;
2097
2098 // If this call happens after dlopen has finished (i.e. late registration)
2099 // there is no need to dlopen the library recursively. See ROOT-8437 where
2100 // the dyLibName would correspond to the binary.
2101 if (!lateRegistration) {
2102
2103 if (isSharedLib) {
2104 // We need to open the dictionary shared library, to resolve symbols
2105 // requested by the JIT from it: as the library is currently being dlopen'ed,
2106 // its symbols are not yet reachable from the process.
2107 // Recursive dlopen seems to work just fine.
2108 void* dyLibHandle = dlopen(dyLibName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
2109 if (dyLibHandle) {
2110 fRegisterModuleDyLibs.push_back(dyLibHandle);
2111 wasDlopened = true;
2112 } else {
2113 PrintDlError(dyLibName.c_str(), modulename);
2114 }
2115 }
2116 } // if (!lateRegistration)
2117
2118 if (hasHeaderParsingOnDemand && fwdDeclsCode){
2119 // We now parse the forward declarations. All the classes are then modified
2120 // in order for them to have an external lexical storage.
2121 std::string fwdDeclsCodeLessEnums;
2122 {
2123 // Search for enum forward decls and only declare them if no
2124 // declaration exists yet.
2125 std::string fwdDeclsLine;
2126 std::istringstream fwdDeclsCodeStr(fwdDeclsCode);
2127 std::vector<std::string> scopes;
2128 while (std::getline(fwdDeclsCodeStr, fwdDeclsLine)) {
2129 const auto enumPos = fwdDeclsLine.find("enum __attribute__((annotate(\"");
2130 // We check if the line contains a fwd declaration of an enum
2131 if (enumPos != std::string::npos) {
2132 // We clear the scopes which we may have carried from a previous iteration
2133 scopes.clear();
2134 // We check if the enum is not in a scope. If yes, save its name
2135 // and the names of the enclosing scopes.
2136 if (enumPos != 0) {
2137 // it's enclosed in namespaces. We need to understand what they are
2138 auto nsPos = fwdDeclsLine.find("namespace");
2139 R__ASSERT(nsPos < enumPos && "Inconsistent enum and enclosing scope parsing!");
2140 while (nsPos < enumPos && nsPos != std::string::npos) {
2141 // we have a namespace, let's put it in the collection of scopes
2142 const auto nsNameStart = nsPos + 10;
2143 const auto nsNameEnd = fwdDeclsLine.find('{', nsNameStart);
2144 const auto nsName = fwdDeclsLine.substr(nsNameStart, nsNameEnd - nsNameStart);
2145 scopes.push_back(nsName);
2146 nsPos = fwdDeclsLine.find("namespace", nsNameEnd);
2147 }
2148 }
2149 clang::DeclContext* DC = nullptr;
2150 for (auto &&aScope: scopes) {
2151 DC = cling::utils::Lookup::Namespace(&fInterpreter->getSema(), aScope.c_str(), DC);
2152 if (!DC) {
2153 // No decl context means we have to fwd declare the enum.
2154 break;
2155 }
2156 }
2157 if (scopes.empty() || DC) {
2158 // We know the scope; let's look for the enum. For that, look
2159 // for the *last* closing parentheses of an attribute because
2160 // there can be multiple.
2161 size_t posEnumName = fwdDeclsLine.rfind("\"))) ");
2162 R__ASSERT(posEnumName != std::string::npos && "Inconsistent enum fwd decl!");
2163 posEnumName += 5; // skip "\"))) "
2164 while (isspace(fwdDeclsLine[posEnumName]))
2165 ++posEnumName;
2166 size_t posEnumNameEnd = fwdDeclsLine.find(" : ", posEnumName);
2167 R__ASSERT(posEnumNameEnd != std::string::npos && "Inconsistent enum fwd decl (end)!");
2168 while (isspace(fwdDeclsLine[posEnumNameEnd]))
2169 --posEnumNameEnd;
2170 // posEnumNameEnd now points to the last character of the name.
2171
2172 std::string enumName = fwdDeclsLine.substr(posEnumName,
2173 posEnumNameEnd - posEnumName + 1);
2174
2175 if (clang::NamedDecl* enumDecl
2176 = cling::utils::Lookup::Named(&fInterpreter->getSema(),
2177 enumName.c_str(), DC)) {
2178 // We have an existing enum decl (forward or definition);
2179 // skip this.
2180 R__ASSERT(llvm::dyn_cast<clang::EnumDecl>(enumDecl) && "not an enum decl!");
2181 (void)enumDecl;
2182 continue;
2183 }
2184 }
2185 }
2186
2187 fwdDeclsCodeLessEnums += fwdDeclsLine + "\n";
2188 }
2189 }
2190
2191 if (!fwdDeclsCodeLessEnums.empty()){ // Avoid the overhead if nothing is to be declared
2192 auto compRes = fInterpreter->declare(fwdDeclsCodeLessEnums, &T);
2193 assert(cling::Interpreter::kSuccess == compRes &&
2194 "The forward declarations could not be compiled");
2195 if (compRes!=cling::Interpreter::kSuccess){
2196 Warning("TCling::RegisterModule",
2197 "Problems in compiling forward declarations for module %s: '%s'",
2198 modulename, fwdDeclsCodeLessEnums.c_str()) ;
2199 }
2200 else if (T){
2201 // Loop over all decls in the transaction and go through them all
2202 // to mark them properly.
2203 // In order to do that, we first iterate over all the DelayedCallInfos
2204 // within the transaction. Then we loop over all Decls in the DeclGroupRef
2205 // contained in the DelayedCallInfos. For each decl, we traverse.
2206 ExtLexicalStorageAdder elsa;
2207 for (auto dciIt = T->decls_begin();dciIt!=T->decls_end();dciIt++){
2208 cling::Transaction::DelayCallInfo& dci = *dciIt;
2209 for(auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) {
2210 clang::Decl* declPtr = *dit;
2211 elsa.TraverseDecl(declPtr);
2212 }
2213 }
2214 }
2215 }
2216
2217 // Now we register all the headers necessary for the class
2218 // Typical format of the array:
2219 // {"A", "classes.h", "@",
2220 // "vector<A>", "vector", "@",
2221 // "myClass", payloadCode, "@",
2222 // nullptr};
2223
2224 std::string temp;
2225 for (const char** classesHeader = classesHeaders; *classesHeader; ++classesHeader) {
2226 temp=*classesHeader;
2227
2228 size_t theTemplateHash = 0;
2229 bool addTemplate = false;
2230 size_t posTemplate = temp.find('<');
2231 if (posTemplate != std::string::npos) {
2232 // Add an entry for the template itself.
2233 std::string templateName = temp.substr(0, posTemplate);
2234 theTemplateHash = fStringHashFunction(templateName);
2235 addTemplate = true;
2236 }
2237 size_t theHash = fStringHashFunction(temp);
2238 classesHeader++;
2239 for (const char** classesHeader_inner = classesHeader; 0!=strcmp(*classesHeader_inner,"@"); ++classesHeader_inner,++classesHeader){
2240 // This is done in order to distinguish headers from files and from the payloadCode
2241 if (payloadCode == *classesHeader_inner ){
2242 fPayloads.insert(theHash);
2243 if (addTemplate) fPayloads.insert(theTemplateHash);
2244 }
2245 if (gDebug > 2)
2246 Info("TCling::RegisterModule",
2247 "Adding a header for %s", temp.c_str());
2248 fClassesHeadersMap[theHash].push_back(*classesHeader_inner);
2249 if (addTemplate) {
2250 if (fClassesHeadersMap.find(theTemplateHash) == fClassesHeadersMap.end()) {
2251 fClassesHeadersMap[theTemplateHash].push_back(*classesHeader_inner);
2252 }
2253 addTemplate = false;
2254 }
2255 }
2256 }
2257 }
2258
2259 clang::Sema &TheSema = fInterpreter->getSema();
2260
2261 bool ModuleWasSuccessfullyLoaded = false;
2262 if (hasCxxModule) {
2263 std::string ModuleName = modulename;
2264 if (llvm::StringRef(modulename).startswith("lib"))
2265 ModuleName = llvm::StringRef(modulename).substr(3).str();
2266
2267 // In case we are directly loading the library via gSystem->Load() without
2268 // specifying the relevant include paths we should try loading the
2269 // modulemap next to the library location.
2270 clang::Preprocessor &PP = TheSema.getPreprocessor();
2271 std::string ModuleMapName;
2272 if (isACLiC)
2273 ModuleMapName = ModuleName + ".modulemap";
2274 else
2275 ModuleMapName = "module.modulemap";
2276 RegisterPrebuiltModulePath(llvm::sys::path::parent_path(dyLibName).str(),
2277 ModuleMapName);
2278
2279 // FIXME: We should only complain for modules which we know to exist. For example, we should not complain about
2280 // modules such as GenVector32 because it needs to fall back to GenVector.
2281 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2282 ModuleWasSuccessfullyLoaded = LoadModule(ModuleName, *fInterpreter);
2283 if (!ModuleWasSuccessfullyLoaded) {
2284 // Only report if we found the module in the modulemap.
2285 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
2286 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
2287 if (moduleMap.findModule(ModuleName))
2288 Info("TCling::RegisterModule", "Module %s in modulemap failed to load.", ModuleName.c_str());
2289 }
2290 }
2291
2292 if (gIgnoredPCMNames.find(modulename) == gIgnoredPCMNames.end()) {
2293 llvm::SmallString<256> pcmFileNameFullPath(dyLibName);
2294 // The path dyLibName might not be absolute. This can happen if dyLibName
2295 // is linked to an executable in the same folder.
2296 llvm::sys::fs::make_absolute(pcmFileNameFullPath);
2297 llvm::sys::path::remove_filename(pcmFileNameFullPath);
2298 llvm::sys::path::append(pcmFileNameFullPath,
2300 LoadPCM(pcmFileNameFullPath.str().str());
2301 }
2302
2303 { // scope within which diagnostics are de-activated
2304 // For now we disable diagnostics because we saw them already at
2305 // dictionary generation time. That won't be an issue with the PCMs.
2306
2307 clangDiagSuppr diagSuppr(TheSema.getDiagnostics());
2308
2309#if defined(R__MUST_REVISIT)
2310#if R__MUST_REVISIT(6,2)
2311 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
2312#endif
2313#endif
2314
2315 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand){
2316 SuspendAutoParsing autoParseRaii(this);
2317
2318 const cling::Transaction* watermark = fInterpreter->getLastTransaction();
2319 cling::Interpreter::CompilationResult compRes = fInterpreter->parseForModule(code.Data());
2320 if (isACLiC) {
2321 // Register an unload point.
2322 fMetaProcessor->registerUnloadPoint(watermark, headers[0]);
2323 }
2324
2325 assert(cling::Interpreter::kSuccess == compRes &&
2326 "Payload code of a dictionary could not be parsed correctly.");
2327 if (compRes!=cling::Interpreter::kSuccess) {
2328 Warning("TCling::RegisterModule",
2329 "Problems declaring payload for module %s.", modulename) ;
2330 }
2331 }
2332 }
2333
2334 // Now that all the header have been registered/compiled, let's
2335 // make sure to 'reset' the TClass that have a class init in this module
2336 // but already had their type information available (using information/header
2337 // loaded from other modules or from class rules or from opening a TFile
2338 // or from loading header in a way that did not provoke the loading of
2339 // the library we just loaded).
2341
2342 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand) {
2343 // __ROOTCLING__ might be pulled in through PCH
2344 fInterpreter->declare("#ifdef __ROOTCLING__\n"
2345 "#undef __ROOTCLING__\n"
2346 + gInterpreterClassDef +
2347 "#endif");
2348 }
2349
2350 if (wasDlopened) {
2351 assert(isSharedLib);
2352 void* dyLibHandle = fRegisterModuleDyLibs.back();
2353 fRegisterModuleDyLibs.pop_back();
2354 dlclose(dyLibHandle);
2355 }
2356}
2357
2359 clang::CompilerInstance& CI = *GetInterpreterImpl()->getCI();
2360 ASTContext &C = CI.getASTContext();
2361
2362 // Do not do anything if we have no global module index.
2363 // FIXME: This is mostly to real with false positives in the TTabCom
2364 // interface for non-modules.
2365 if (!fCxxModulesEnabled)
2366 return;
2367
2368 if (IdentifierInfoLookup *External = C.Idents.getExternalIdentifierLookup()) {
2369 std::unique_ptr<IdentifierIterator> Iter(External->getIdentifiers());
2370 for (llvm::StringRef Ident = Iter->Next(); !Ident.empty(); Ident = Iter->Next()) {
2371 std::string I = Ident.str();
2372 if (!Idents.Contains(I.data()))
2373 Idents.Add(new TObjString(I.c_str()));
2374 }
2375 }
2376}
2377
2378
2379////////////////////////////////////////////////////////////////////////////////
2380/// Register classes that already existed prior to their dictionary loading
2381/// and that already had a ClassInfo (and thus would not be refresh via
2382/// UpdateClassInfo.
2383
2385{
2386 fClassesToUpdate.push_back(std::make_pair(oldcl,dict));
2387}
2388
2389////////////////////////////////////////////////////////////////////////////////
2390/// If the dictionary is loaded, we can remove the class from the list
2391/// (otherwise the class might be loaded twice).
2392
2394{
2395 typedef std::vector<std::pair<TClass*,DictFuncPtr_t> >::iterator iterator;
2396 iterator stop = fClassesToUpdate.end();
2397 for(iterator i = fClassesToUpdate.begin();
2398 i != stop;
2399 ++i)
2400 {
2401 if ( i->first == oldcl ) {
2402 fClassesToUpdate.erase(i);
2403 return;
2404 }
2405 }
2406}
2407
2408
2409////////////////////////////////////////////////////////////////////////////////
2410/// Let cling process a command line.
2411///
2412/// If the command is executed and the error is 0, then the return value
2413/// is the int value corresponding to the result of the executed command
2414/// (float and double return values will be truncated).
2415///
2416
2417// Method for handling the interpreter exceptions.
2418// the MetaProcessor is passing in as argument to teh function, because
2419// cling::Interpreter::CompilationResult is a nested class and it cannot be
2420// forward declared, thus this method cannot be a static member function
2421// of TCling.
2422
2423static int HandleInterpreterException(cling::MetaProcessor* metaProcessor,
2424 const char* input_line,
2425 cling::Interpreter::CompilationResult& compRes,
2426 cling::Value* result)
2427{
2428 try {
2429 return metaProcessor->process(input_line, compRes, result);
2430 }
2431 catch (cling::InterpreterException& ex)
2432 {
2433 Error("HandleInterpreterException", "%s\n%s", ex.what(), "Execution of your code was aborted.");
2434 ex.diagnose();
2435 compRes = cling::Interpreter::kFailure;
2436 }
2437 return 0;
2438}
2439
2440////////////////////////////////////////////////////////////////////////////////
2441
2442bool TCling::DiagnoseIfInterpreterException(const std::exception &e) const
2443{
2444 if (auto ie = dynamic_cast<const cling::InterpreterException*>(&e)) {
2445 ie->diagnose();
2446 return true;
2447 }
2448 return false;
2449}
2450
2451////////////////////////////////////////////////////////////////////////////////
2452
2454{
2455 // Copy the passed line, it comes from a static buffer in TApplication
2456 // which can be reentered through the Cling evaluation routines,
2457 // which would overwrite the static buffer and we would forget what we
2458 // were doing.
2459 //
2460 TString sLine(line);
2461 if (strstr(line,fantomline)) {
2462 // End-Of-Line action
2463 // See the comment (copied from above):
2464 // It is a "fantom" method to synchronize user keyboard input
2465 // and ROOT prompt line (for WIN32)
2466 // and is implemented by
2467 if (gApplication) {
2468 if (gApplication->IsCmdThread()) {
2470 gROOT->SetLineIsProcessing();
2471
2473
2474 gROOT->SetLineHasBeenProcessed();
2475 }
2476 }
2477 return 0;
2478 }
2479
2481 gGlobalMutex->Lock();
2482 if (!gInterpreterMutex)
2485 }
2487 gROOT->SetLineIsProcessing();
2488
2489 struct InterpreterFlagsRAII {
2490 cling::Interpreter* fInterpreter;
2491 bool fWasDynamicLookupEnabled;
2492
2493 InterpreterFlagsRAII(cling::Interpreter* interp):
2494 fInterpreter(interp),
2495 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2496 {
2497 fInterpreter->enableDynamicLookup(true);
2498 }
2499 ~InterpreterFlagsRAII() {
2500 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2501 gROOT->SetLineHasBeenProcessed();
2502 }
2503 } interpreterFlagsRAII(GetInterpreterImpl());
2504
2505 // A non-zero returned value means the given line was
2506 // not a complete statement.
2507 int indent = 0;
2508 // This will hold the resulting value of the evaluation the given line.
2509 cling::Value result;
2510 cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess;
2511 if (!strncmp(sLine.Data(), ".L", 2) || !strncmp(sLine.Data(), ".x", 2) ||
2512 !strncmp(sLine.Data(), ".X", 2)) {
2513 // If there was a trailing "+", then CINT compiled the code above,
2514 // and we will need to strip the "+" before passing the line to cling.
2515 TString mod_line(sLine);
2516 TString aclicMode;
2517 TString arguments;
2518 TString io;
2519 TString fname = gSystem->SplitAclicMode(sLine.Data() + 3,
2520 aclicMode, arguments, io);
2521 if (aclicMode.Length()) {
2522 // Remove the leading '+'
2523 R__ASSERT(aclicMode[0]=='+' && "ACLiC mode must start with a +");
2524 aclicMode[0]='k'; // We always want to keep the .so around.
2525 if (aclicMode[1]=='+') {
2526 // We have a 2nd +
2527 aclicMode[1]='f'; // We want to force the recompilation.
2528 }
2529 if (!gSystem->CompileMacro(fname,aclicMode)) {
2530 // ACLiC failed.
2531 compRes = cling::Interpreter::kFailure;
2532 } else {
2533 if (strncmp(sLine.Data(), ".L", 2) != 0) {
2534 // if execution was requested.
2535
2536 if (arguments.Length() == 0) {
2537 arguments = "()";
2538 }
2539 // We need to remove the extension.
2540 Ssiz_t ext = fname.Last('.');
2541 if (ext != kNPOS) {
2542 fname.Remove(ext);
2543 }
2544 const char *function = gSystem->BaseName(fname);
2545 mod_line = function + arguments + io;
2547 }
2548 }
2549 } else if (cling::DynamicLibraryManager::isSharedLibrary(fname.Data()) &&
2550 strncmp(sLine.Data(), ".L", 2) != 0) { // .x *.so or *.dll
2551 if (gSystem->Load(fname) < 0) {
2552 // Loading failed.
2553 compRes = cling::Interpreter::kFailure;
2554 } else {
2555 if (arguments.Length() == 0) {
2556 arguments = "()";
2557 }
2558 // We need to remove the extension. (*.so or *.dll)
2559 Ssiz_t ext = fname.Last('.');
2560 if (ext != kNPOS) {
2561 fname.Remove(ext);
2562 }
2563 // Now we try to find the 'main' function to run within this shared library
2564 // We distinguish two cases: a library.so with a function library(args),
2565 // or a precompiled ACLiC macro (macro_C.so) with a function macro(args).
2566 // Only in the second case, we need to strip the suffix _C or _cpp from fname.
2567 if (!gInterpreter->GetFunction(nullptr, gSystem->BaseName(fname))) { // AcLiC macro
2568 // We need to remove the automatically appended _ extension when compiling (macro_C from macro.C)
2569 ext = fname.Last('_');
2570 if (ext != kNPOS) {
2571 fname.Remove(ext);
2572 }
2573 }
2574 const char *function = gSystem->BaseName(fname);
2575 mod_line = function + arguments + io;
2577 }
2578 } else {
2579 // neither ACLiC nor run shared-library (.x)
2580 size_t unnamedMacroOpenCurly;
2581 {
2582 std::string code;
2583 std::string codeline;
2584 // Windows requires std::ifstream::binary to properly handle
2585 // CRLF and LF line endings
2586 std::ifstream in(fname, std::ifstream::binary);
2587 while (in) {
2588 std::getline(in, codeline);
2589 code += codeline + "\n";
2590 }
2591 unnamedMacroOpenCurly
2592 = cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
2593 }
2594
2595 fCurExecutingMacros.push_back(fname);
2596 if (unnamedMacroOpenCurly != std::string::npos) {
2597 compRes = fMetaProcessor->readInputFromFile(fname.Data(), &result,
2598 unnamedMacroOpenCurly);
2599 } else {
2600 // No DynLookup for .x, .L of named macros.
2601 fInterpreter->enableDynamicLookup(false);
2603 }
2604 fCurExecutingMacros.pop_back();
2605 }
2606 } // .L / .X / .x
2607 else {
2608 if (0!=strncmp(sLine.Data(), ".autodict ",10) && sLine != ".autodict") {
2609 // explicitly ignore .autodict without having to support it
2610 // in cling.
2611
2612 // Turn off autoparsing if this is an include directive
2613 bool isInclusionDirective = sLine.Contains("\n#include") || sLine.BeginsWith("#include");
2614 if (isInclusionDirective) {
2615 SuspendAutoParsing autoParseRaii(this);
2617 } else {
2619 }
2620 }
2621 }
2622 if (result.isValid())
2624 if (indent) {
2625 if (error)
2626 *error = kProcessing;
2627 return 0;
2628 }
2629 if (error) {
2630 switch (compRes) {
2631 case cling::Interpreter::kSuccess: *error = kNoError; break;
2632 case cling::Interpreter::kFailure: *error = kRecoverable; break;
2633 case cling::Interpreter::kMoreInputExpected: *error = kProcessing; break;
2634 }
2635 }
2636 if (compRes == cling::Interpreter::kSuccess
2637 && result.isValid()
2638 && !result.isVoid())
2639 {
2640 return result.castAs<Longptr_t>();
2641 }
2642 return 0;
2643}
2644
2645////////////////////////////////////////////////////////////////////////////////
2646/// No-op; see TRint instead.
2647
2649{
2650}
2651
2652////////////////////////////////////////////////////////////////////////////////
2653/// \brief Add a directory to the list of directories in which the
2654/// interpreter looks for include files.
2655/// \param[in] path The path to the directory.
2656/// \note Only one path item can be specified at a time, i.e. "path1:path2" is
2657/// \b NOT supported.
2658/// \warning Only the path to the directory should be specified, without
2659/// prepending the \c -I prefix, i.e.
2660/// <tt>gCling->AddIncludePath("/path/to/my/includes")</tt>. If the
2661/// \c -I prefix is used it will be ignored.
2662void TCling::AddIncludePath(const char *path)
2663{
2665 // Favorite source of annoyance: gSystem->AddIncludePath() needs "-I",
2666 // gCling->AddIncludePath() does not! Work around that inconsistency:
2667 if (path[0] == '-' && path[1] == 'I')
2668 path += 2;
2669 TString sPath(path);
2670 gSystem->ExpandPathName(sPath);
2671#ifdef _MSC_VER
2672 if (sPath.BeginsWith("/")) {
2673 char drive[3];
2674 snprintf(drive, 3, "%c:", _getdrive() + 'A' - 1);
2675 sPath.Prepend(drive);
2676 }
2677#endif
2678 fInterpreter->AddIncludePath(sPath.Data());
2679}
2680
2681////////////////////////////////////////////////////////////////////////////////
2682/// Visit all members over members, recursing over base classes.
2683
2684void TCling::InspectMembers(TMemberInspector& insp, const void* obj,
2685 const TClass* cl, Bool_t isTransient)
2686{
2690 }
2691
2692 if (!cl || cl->GetCollectionProxy()) {
2693 // We do not need to investigate the content of the STL
2694 // collection, they are opaque to us (and details are
2695 // uninteresting).
2696 return;
2697 }
2698
2699 static const TClassRef clRefString("std::string");
2700 if (clRefString == cl) {
2701 // We stream std::string without going through members..
2702 return;
2703 }
2704
2705 if (TClassEdit::IsStdArray(cl->GetName())) {
2706 // We treat std arrays as C arrays
2707 return;
2708 }
2709
2710 if (TClassEdit::IsUniquePtr(cl->GetName())) {
2711 // Ignore error caused by the inside of std::unique_ptr
2712 // This is needed solely because of rootclingIO's IsUnsupportedUniquePointer
2713 // which checks the number of elements in the GetListOfRealData.
2714 // If this usage is removed, this can be replaced with a return statement.
2715 // See https://github.com/root-project/root/issues/13574
2716 isTransient = true;
2717 }
2718
2719 const char* cobj = (const char*) obj; // for ptr arithmetics
2720
2721 // Treat the case of std::complex in a special manner. We want to enforce
2722 // the layout of a stl implementation independent class, which is the
2723 // complex as implemented in ROOT5.
2724
2725 // A simple lambda to simplify the code
2726 auto inspInspect = [&] (ptrdiff_t offset){
2727 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_real", cobj, isTransient);
2728 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_imag", cobj + offset, isTransient);
2729 };
2730
2731 auto complexType = TClassEdit::GetComplexType(cl->GetName());
2732 switch(complexType) {
2734 {
2735 break;
2736 }
2738 {
2739 inspInspect(sizeof(float));
2740 return;
2741 }
2743 {
2744 inspInspect(sizeof(double));
2745 return;
2746 }
2748 {
2749 inspInspect(sizeof(int));
2750 return;
2751 }
2753 {
2754 inspInspect(sizeof(long));
2755 return;
2756 }
2757 }
2758
2759 static clang::PrintingPolicy
2760 printPol(fInterpreter->getCI()->getLangOpts());
2761 if (printPol.Indentation) {
2762 // not yet initialized
2763 printPol.Indentation = 0;
2764 printPol.SuppressInitializers = true;
2765 }
2766
2767 const char* clname = cl->GetName();
2768 // Printf("Inspecting class %s\n", clname);
2769
2770 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2771 const clang::Decl *scopeDecl = nullptr;
2772 const clang::Type *recordType = nullptr;
2773
2774 if (cl->GetClassInfo()) {
2775 TClingClassInfo * clingCI = (TClingClassInfo *)cl->GetClassInfo();
2776 scopeDecl = clingCI->GetDecl();
2777 recordType = clingCI->GetType();
2778 } else {
2779 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2780 // Diags will complain about private classes:
2781 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2782 &recordType);
2783 }
2784 if (!scopeDecl) {
2785 Error("InspectMembers", "Cannot find Decl for class %s", clname);
2786 return;
2787 }
2788 const clang::CXXRecordDecl* recordDecl
2789 = llvm::dyn_cast<const clang::CXXRecordDecl>(scopeDecl);
2790 if (!recordDecl) {
2791 Error("InspectMembers", "Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2792 return;
2793 }
2794
2795 {
2796 // Force possible deserializations first. We need to have no pending
2797 // Transaction when passing control flow to the inspector below (ROOT-7779).
2798 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2799
2800 astContext.getASTRecordLayout(recordDecl);
2801
2802 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2803 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2804 }
2805
2806 const clang::ASTRecordLayout& recLayout
2807 = astContext.getASTRecordLayout(recordDecl);
2808
2809 // TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
2810 // if (proxy && ( proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated ) ) {
2811 // Error("InspectMembers","The TClass for %s has an emulated proxy but we are looking at a compiled version of the collection!\n",
2812 // cl->GetName());
2813 // }
2814 if (cl->Size() != recLayout.getSize().getQuantity()) {
2815 Error("InspectMembers","TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2816 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2817 }
2818
2819 unsigned iNField = 0;
2820 // iterate over fields
2821 // FieldDecls are non-static, else it would be a VarDecl.
2822 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2823 eField = recordDecl->field_end(); iField != eField;
2824 ++iField, ++iNField) {
2825
2826
2827 clang::QualType memberQT = iField->getType();
2828 if (recordType) {
2829 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2830 memberQT = ROOT::TMetaUtils::ReSubstTemplateArg(memberQT, recordType);
2831 }
2832 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2833 if (memberQT.isNull()) {
2834 std::string memberName;
2835 llvm::raw_string_ostream stream(memberName);
2836 // Don't trigger fopen of the source file to count lines:
2837 printPol.AnonymousTagLocations = false;
2838 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2839 stream.flush();
2840 Error("InspectMembers",
2841 "Cannot retrieve QualType for member %s while inspecting class %s",
2842 memberName.c_str(), clname);
2843 continue; // skip member
2844 }
2845 const clang::Type* memType = memberQT.getTypePtr();
2846 if (!memType) {
2847 std::string memberName;
2848 llvm::raw_string_ostream stream(memberName);
2849 // Don't trigger fopen of the source file to count lines:
2850 printPol.AnonymousTagLocations = false;
2851 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2852 stream.flush();
2853 Error("InspectMembers",
2854 "Cannot retrieve Type for member %s while inspecting class %s",
2855 memberName.c_str(), clname);
2856 continue; // skip member
2857 }
2858
2859 const clang::Type* memNonPtrType = memType;
2860 Bool_t ispointer = false;
2861 if (memNonPtrType->isPointerType()) {
2862 ispointer = true;
2863 clang::QualType ptrQT
2864 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2865 if (recordType) {
2866 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2867 ptrQT = ROOT::TMetaUtils::ReSubstTemplateArg(ptrQT, recordType);
2868 }
2869 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2870 if (ptrQT.isNull()) {
2871 std::string memberName;
2872 llvm::raw_string_ostream stream(memberName);
2873 // Don't trigger fopen of the source file to count lines:
2874 printPol.AnonymousTagLocations = false;
2875 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2876 stream.flush();
2877 Error("InspectMembers",
2878 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2879 memberName.c_str(), clname);
2880 continue; // skip member
2881 }
2882 memNonPtrType = ptrQT.getTypePtr();
2883 }
2884
2885 // assemble array size(s): "[12][4][]"
2886 llvm::SmallString<8> arraySize;
2887 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2888 unsigned arrLevel = 0;
2889 bool haveErrorDueToArray = false;
2890 while (arrType) {
2891 ++arrLevel;
2892 arraySize += '[';
2893 const clang::ConstantArrayType* constArrType =
2894 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2895 if (constArrType) {
2896 constArrType->getSize().toStringUnsigned(arraySize);
2897 }
2898 arraySize += ']';
2899 clang::QualType subArrQT = arrType->getElementType();
2900 if (subArrQT.isNull()) {
2901 std::string memberName;
2902 llvm::raw_string_ostream stream(memberName);
2903 // Don't trigger fopen of the source file to count lines:
2904 printPol.AnonymousTagLocations = false;
2905 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2906 stream.flush();
2907 Error("InspectMembers",
2908 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
2909 arrLevel, subArrQT.getAsString(printPol).c_str(),
2910 memberName.c_str(), clname);
2911 haveErrorDueToArray = true;
2912 break;
2913 }
2914 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
2915 }
2916 if (haveErrorDueToArray) {
2917 continue; // skip member
2918 }
2919
2920 // construct member name
2921 std::string fieldName;
2922 if (memType->isPointerType()) {
2923 fieldName = "*";
2924 }
2925
2926 // Check if this field has a custom ioname, if not, just use the one of the decl
2927 std::string ioname(iField->getName());
2928 ROOT::TMetaUtils::ExtractAttrPropertyFromName(**iField,"ioname",ioname);
2929 fieldName += ioname;
2930 fieldName += arraySize;
2931
2932 // get member offset
2933 // NOTE currently we do not support bitfield and do not support
2934 // member that are not aligned on 'bit' boundaries.
2935 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
2936 ptrdiff_t fieldOffset = offset.getQuantity();
2937
2938 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fBits[2]", fBits);
2939 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fName", &fName);
2940 // R__insp.InspectMember(fName, "fName.");
2941 // R__insp.Inspect(R__cl, R__insp.GetParent(), "*fClass", &fClass);
2942
2943 // If the class has a custom streamer and the type of the filed is a
2944 // private enum, struct or class, skip it.
2945 if (!insp.IsTreatingNonAccessibleTypes()){
2946 auto iFiledQtype = iField->getType();
2947 if (auto tagDecl = iFiledQtype->getAsTagDecl()){
2948 auto declAccess = tagDecl->getAccess();
2949 if (declAccess == AS_private || declAccess == AS_protected) {
2950 continue;
2951 }
2952 }
2953 }
2954
2955 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
2956
2957 if (!ispointer) {
2958 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
2959 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
2960 // nested objects get an extra call to InspectMember
2961 // R__insp.InspectMember("FileStat_t", (void*)&fFileStat, "fFileStat.", false);
2962 std::string sFieldRecName;
2963 if (!ROOT::TMetaUtils::ExtractAttrPropertyFromName(*fieldRecDecl,"iotype",sFieldRecName)){
2965 clang::QualType(memNonPtrType,0),
2966 *fInterpreter,
2968 }
2969
2970 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
2971 // if we can not find the member (which should not really happen),
2972 // let's consider it transient.
2973 Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();
2974
2975 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
2976 (fieldName + '.').c_str(), transient);
2977
2978 }
2979 }
2980 } // loop over fields
2981
2982 // inspect bases
2983 // TNamed::ShowMembers(R__insp);
2984 unsigned iNBase = 0;
2985 for (clang::CXXRecordDecl::base_class_const_iterator iBase
2986 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
2987 iBase != eBase; ++iBase, ++iNBase) {
2988 clang::QualType baseQT = iBase->getType();
2989 if (baseQT.isNull()) {
2990 Error("InspectMembers",
2991 "Cannot find QualType for base number %d while inspecting class %s",
2992 iNBase, clname);
2993 continue;
2994 }
2995 const clang::CXXRecordDecl* baseDecl
2996 = baseQT->getAsCXXRecordDecl();
2997 if (!baseDecl) {
2998 Error("InspectMembers",
2999 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
3000 iNBase, clname);
3001 continue;
3002 }
3003 TClass* baseCl=nullptr;
3004 std::string sBaseName;
3005 // Try with the DeclId
3006 std::vector<TClass*> foundClasses;
3007 TClass::GetClass(static_cast<DeclId_t>(baseDecl), foundClasses);
3008 if (foundClasses.size()==1){
3009 baseCl=foundClasses[0];
3010 } else {
3011 // Try with the normalised Name, as a fallback
3012 if (!baseCl){
3014 baseQT,
3015 *fInterpreter,
3017 baseCl = TClass::GetClass(sBaseName.c_str());
3018 }
3019 }
3020
3021 if (!baseCl){
3022 std::string qualNameForDiag;
3023 ROOT::TMetaUtils::GetQualifiedName(qualNameForDiag, *baseDecl);
3024 Error("InspectMembers",
3025 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
3026 continue;
3027 }
3028
3029 int64_t baseOffset;
3030 if (iBase->isVirtual()) {
3032 if (!isTransient) {
3033 Error("InspectMembers",
3034 "Base %s of class %s is virtual but no object provided",
3035 sBaseName.c_str(), clname);
3036 }
3038 } else {
3039 // We have an object to determine the vbase offset.
3041 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
3042 if (ci && baseCi) {
3043 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
3044 true /*isDerivedObj*/);
3045 if (baseOffset == -1) {
3046 Error("InspectMembers",
3047 "Error calculating offset of virtual base %s of class %s",
3048 sBaseName.c_str(), clname);
3049 }
3050 } else {
3051 Error("InspectMembers",
3052 "Cannot calculate offset of virtual base %s of class %s",
3053 sBaseName.c_str(), clname);
3054 continue;
3055 }
3056 }
3057 } else {
3058 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
3059 }
3060 // TOFIX: baseCl can be null here!
3061 if (baseCl->IsLoaded()) {
3062 // For loaded class, CallShowMember will (especially for TObject)
3063 // call the virtual ShowMember rather than the class specific version
3064 // resulting in an infinite recursion.
3065 InspectMembers(insp, cobj + baseOffset, baseCl, isTransient);
3066 } else {
3067 baseCl->CallShowMembers(cobj + baseOffset,
3068 insp, isTransient);
3069 }
3070 } // loop over bases
3071}
3072
3073////////////////////////////////////////////////////////////////////////////////
3074/// Reset the interpreter internal state in case a previous action was not correctly
3075/// terminated.
3076
3078{
3079 // No-op there is not equivalent state (to be cleared) in Cling.
3080}
3081
3082////////////////////////////////////////////////////////////////////////////////
3083/// Delete existing temporary values.
3084
3086{
3087 // No-op for cling due to cling::Value.
3088}
3089
3090////////////////////////////////////////////////////////////////////////////////
3091/// Declare code to the interpreter, without any of the interpreter actions
3092/// that could trigger a re-interpretation of the code. I.e. make cling
3093/// behave like a compiler: no dynamic lookup, no input wrapping for
3094/// subsequent execution, no automatic provision of declarations but just a
3095/// plain `#include`.
3096/// Returns true on success, false on failure.
3097
3098bool TCling::Declare(const char* code)
3099{
3101
3102 SuspendAutoLoadingRAII autoLoadOff(this);
3103 SuspendAutoParsing autoParseRaii(this);
3104
3105 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
3106 fInterpreter->enableDynamicLookup(false);
3107 bool oldRawInput = fInterpreter->isRawInputEnabled();
3108 fInterpreter->enableRawInput(true);
3109
3110 Bool_t ret = LoadText(code);
3111
3112 fInterpreter->enableRawInput(oldRawInput);
3113 fInterpreter->enableDynamicLookup(oldDynLookup);
3114 return ret;
3115}
3116
3117////////////////////////////////////////////////////////////////////////////////
3118/// It calls a "fantom" method to synchronize user keyboard input
3119/// and ROOT prompt line.
3120
3122{
3124}
3125
3126// This static function is a hop of TCling::IsLibraryLoaded, which is taking a lock and calling
3127// into this function. This is because we wanted to avoid a duplication in TCling::IsLoaded, which
3128// was already taking a lock.
3129static Bool_t s_IsLibraryLoaded(const char* libname, cling::Interpreter* fInterpreter)
3130{
3131 // Check shared library.
3132 TString tLibName(libname);
3133 if (gSystem->FindDynamicLibrary(tLibName, kTRUE))
3134 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
3135 return false;
3136}
3137
3138Bool_t TCling::IsLibraryLoaded(const char* libname) const
3139{
3141 return s_IsLibraryLoaded(libname, GetInterpreterImpl());
3142}
3143
3144////////////////////////////////////////////////////////////////////////////////
3145/// Return true if ROOT has cxxmodules pcm for a given library name.
3146// FIXME: We need to be able to support lazy loading of pcm generated by ACLiC.
3147Bool_t TCling::HasPCMForLibrary(const char *libname) const
3148{
3149 llvm::StringRef ModuleName(libname);
3150 ModuleName = llvm::sys::path::stem(ModuleName);
3151 ModuleName.consume_front("lib");
3152
3153 // FIXME: In case when the modulemap is not yet loaded we will return the
3154 // wrong result. Consider a call to HasPCMForLibrary(../test/libEvent.so)
3155 // We will only load the modulemap for libEvent.so after we dlopen libEvent
3156 // which may happen after calling this interface. Maybe we should also check
3157 // if there is a Event.pcm file and a module.modulemap, load it and return
3158 // true.
3159 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
3160 clang::Module *M = moduleMap.findModule(ModuleName);
3161 return M && !M->IsUnimportable && M->getASTFile();
3162}
3163
3164////////////////////////////////////////////////////////////////////////////////
3165/// Return true if the file has already been loaded by cint.
3166/// We will try in this order:
3167/// actual filename
3168/// filename as a path relative to
3169/// the include path
3170/// the shared library path
3171
3173{
3175
3176 //FIXME: if we use llvm::sys::fs::make_absolute all this can go away. See
3177 // cling::DynamicLibraryManager.
3178
3179 std::string file_name = filename;
3180 size_t at = std::string::npos;
3181 while ((at = file_name.find("/./")) != std::string::npos)
3182 file_name.replace(at, 3, "/");
3183
3184 std::string filesStr = "";
3185 llvm::raw_string_ostream filesOS(filesStr);
3186 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3187 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
3188 filesOS.flush();
3189
3190 llvm::SmallVector<llvm::StringRef, 100> files;
3191 llvm::StringRef(filesStr).split(files, "\n");
3192
3193 std::set<std::string> fileMap;
3194 llvm::StringRef file_name_ref(file_name);
3195 // Fill fileMap; return early on exact match.
3196 for (llvm::SmallVector<llvm::StringRef, 100>::const_iterator
3197 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
3198 if ((*iF) == file_name_ref) return kTRUE; // exact match
3199 fileMap.insert(iF->str());
3200 }
3201
3202 if (fileMap.empty()) return kFALSE;
3203
3204 // Check MacroPath.
3205 TString sFilename(file_name.c_str());
3207 && fileMap.count(sFilename.Data())) {
3208 return kTRUE;
3209 }
3210
3211 // Check IncludePath.
3212 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
3213 incPath.Append(":").Prepend(" "); // to match " -I" (note leading ' ')
3214 incPath.ReplaceAll(" -I", ":"); // of form :dir1 :dir2:dir3
3215 while (incPath.Index(" :") != -1) {
3216 incPath.ReplaceAll(" :", ":");
3217 }
3218 incPath.Prepend(".:");
3219 sFilename = file_name.c_str();
3220 if (gSystem->FindFile(incPath, sFilename, kReadPermission)
3221 && fileMap.count(sFilename.Data())) {
3222 return kTRUE;
3223 }
3224
3225 // Check shared library.
3226 if (s_IsLibraryLoaded(file_name.c_str(), GetInterpreterImpl()))
3227 return kTRUE;
3228
3229 //FIXME: We must use the cling::Interpreter::lookupFileOrLibrary iface.
3230 clang::ConstSearchDirIterator *CurDir = nullptr;
3231 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
3232 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
3233 auto FE = HS.LookupFile(file_name.c_str(),
3234 clang::SourceLocation(),
3235 /*isAngled*/ false,
3236 /*FromDir*/ nullptr, CurDir,
3237 clang::ArrayRef<std::pair<clang::OptionalFileEntryRef,
3238 clang::DirectoryEntryRef>>(),
3239 /*SearchPath*/ nullptr,
3240 /*RelativePath*/ nullptr,
3241 /*RequestingModule*/ nullptr,
3242 /*SuggestedModule*/ nullptr,
3243 /*IsMapped*/ nullptr,
3244 /*IsFrameworkFound*/ nullptr,
3245 /*SkipCache*/ false,
3246 /*BuildSystemModule*/ false,
3247 /*OpenFile*/ false,
3248 /*CacheFail*/ false);
3249 if (FE) {
3250 // check in the source manager if the file is actually loaded
3251 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3252 // this works only with header (and source) files...
3253 clang::FileID FID = SM.translateFile(*FE);
3254 if (!FID.isInvalid() && FID.getHashValue() == 0)
3255 return kFALSE;
3256 else {
3257 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
3258 if (SLocE.isFile() && !SLocE.getFile().getContentCache().getBufferIfLoaded())
3259 return kFALSE;
3260 if (!FID.isInvalid())
3261 return kTRUE;
3262 }
3263 // ...then check shared library again, but with full path now
3264 sFilename = FE->getName().str();
3265 if (gSystem->FindDynamicLibrary(sFilename, kTRUE)
3266 && fileMap.count(sFilename.Data())) {
3267 return kTRUE;
3268 }
3269 }
3270 return kFALSE;
3271}
3272
3273
3274#if defined(R__MACOSX)
3275
3276////////////////////////////////////////////////////////////////////////////////
3277/// Check if lib is in the dynamic linker cache, returns true if it is, and if so,
3278/// modifies the library file name parameter `lib` from `/usr/lib/libFOO.dylib`
3279/// to `-lFOO` such that it can be passed to the linker.
3280/// This is a unique feature of macOS 11.
3281
3282static bool R__UpdateLibFileForLinking(TString &lib)
3283{
3284 const char *mapfile = nullptr;
3285#if __x86_64__
3286 mapfile = "/System/Library/dyld/dyld_shared_cache_x86_64.map";
3287#elif __arm64__
3288 mapfile = "/System/Library/dyld/dyld_shared_cache_arm64e.map";
3289#else
3290 #error unsupported architecture
3291#endif
3292 if (std::ifstream cacheMap{mapfile}) {
3293 std::string line;
3294 while (getline(cacheMap, line)) {
3295 if (line.find(lib) != std::string::npos) {
3296 lib.ReplaceAll("/usr/lib/lib","-l");
3297 lib.ReplaceAll(".dylib","");
3298 return true;
3299 }
3300 }
3301 return false;
3302 }
3303 return false;
3304}
3305#endif // R__MACOSX
3306
3307#if defined (R__LINUX) || defined (R__FBSD)
3308
3309////////////////////////////////////////////////////////////////////////////////
3310/// Callback for dl_iterate_phdr(), see `man dl_iterate_phdr`.
3311/// Collects opened libraries.
3312
3313static int callback_for_dl_iterate_phdr(struct dl_phdr_info *info, size_t size, void *data)
3314{
3315 // This function is called through UpdateListOfLoadedSharedLibraries() which is locked.
3316 static std::unordered_set<decltype(info->dlpi_addr)> sKnownLoadedLibBaseAddrs;
3317
3318 auto newLibs = static_cast<std::vector<std::string>*>(data);
3319 if (!sKnownLoadedLibBaseAddrs.count(info->dlpi_addr)) {
3320 // Skip \0, "", and kernel pseudo-libs linux-vdso.so.1 or linux-gate.so.1
3321 if (info->dlpi_name && info->dlpi_name[0]
3322#if defined(R__FBSD)
3323 //skip the executable (with null addr)
3324 && info->dlpi_addr
3325 //has no path
3326 && strncmp(info->dlpi_name, "[vdso]", 6)
3327 //the linker does not like to be mmapped
3328 //causes a crash in cling::DynamicLibraryManager::loadLibrary())
3329 //with error message "mmap of entire address space failed: Cannot allocate memory"
3330 && strncmp(info->dlpi_name, "/libexec/ld-elf.so.1", 20)
3331#endif
3332 && strncmp(info->dlpi_name, "linux-vdso.so", 13)
3333 && strncmp(info->dlpi_name, "linux-vdso32.so", 15)
3334 && strncmp(info->dlpi_name, "linux-vdso64.so", 15)
3335 && strncmp(info->dlpi_name, "linux-gate.so", 13))
3336 newLibs->emplace_back(info->dlpi_name);
3337 sKnownLoadedLibBaseAddrs.insert(info->dlpi_addr);
3338 }
3339 // No matter what the doc says, return != 0 means "stop the iteration".
3340 return 0;
3341}
3342
3343#endif // R__LINUX || R__FBSD
3344
3345
3346////////////////////////////////////////////////////////////////////////////////
3347
3349{
3350#if defined(R__WIN32) || defined(__CYGWIN__)
3351 HMODULE hModules[1024];
3352 void *hProcess;
3353 unsigned long cbModules;
3354 unsigned int i;
3355 hProcess = (void *)::GetCurrentProcess();
3356 ::EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbModules);
3357 // start at 1 to skip the executable itself
3358 for (i = 1; i < (cbModules / sizeof(void *)); i++) {
3359 static const int bufsize = 260;
3360 wchar_t winname[bufsize];
3361 char posixname[bufsize];
3362 ::GetModuleFileNameExW(hProcess, hModules[i], winname, bufsize);
3363#if defined(__CYGWIN__)
3364 cygwin_conv_path(CCP_WIN_W_TO_POSIX, winname, posixname, bufsize);
3365#else
3366 std::wstring wpath = winname;
3367 std::replace(wpath.begin(), wpath.end(), '\\', '/');
3368 string path(wpath.begin(), wpath.end());
3369 strncpy(posixname, path.c_str(), bufsize);
3370#endif
3371 if (!fSharedLibs.Contains(posixname)) {
3372 RegisterLoadedSharedLibrary(posixname);
3373 }
3374 }
3375#elif defined(R__MACOSX)
3376 // fPrevLoadedDynLibInfo stores the *next* image index to look at
3377 uint32_t imageIndex = (uint32_t) (size_t) fPrevLoadedDynLibInfo;
3378
3379 while (const mach_header* mh = _dyld_get_image_header(imageIndex)) {
3380 // Skip non-dylibs
3381 if (mh->filetype == MH_DYLIB) {
3382 if (const char* imageName = _dyld_get_image_name(imageIndex)) {
3383 RegisterLoadedSharedLibrary(imageName);
3384 }
3385 }
3386
3387 ++imageIndex;
3388 }
3389 fPrevLoadedDynLibInfo = (void*)(size_t)imageIndex;
3390#elif defined(R__LINUX) || defined(R__FBSD)
3391 // fPrevLoadedDynLibInfo is unused on Linux.
3392 (void) fPrevLoadedDynLibInfo;
3393
3394 std::vector<std::string> newLibs;
3395 dl_iterate_phdr(callback_for_dl_iterate_phdr, &newLibs);
3396 for (auto &&lib: newLibs)
3397 RegisterLoadedSharedLibrary(lib.c_str());
3398#else
3399 Error("TCling::UpdateListOfLoadedSharedLibraries",
3400 "Platform not supported!");
3401#endif
3402}
3403
3404namespace {
3405template <int N>
3406static bool StartsWithStrLit(const char *haystack, const char (&needle)[N]) {
3407 return !strncmp(haystack, needle, N - 1);
3408}
3409}
3410
3411////////////////////////////////////////////////////////////////////////////////
3412/// Register a new shared library name with the interpreter; add it to
3413/// fSharedLibs.
3414
3416{
3417 // Ignore NULL filenames, aka "the process".
3418 if (!filename) return;
3419
3420 // Tell the interpreter that this library is available; all libraries can be
3421 // used to resolve symbols.
3422 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3423 if (!DLM->isLibraryLoaded(filename)) {
3424 DLM->loadLibrary(filename, true /*permanent*/, true /*resolved*/);
3425 }
3426
3427#if defined(R__MACOSX)
3428 // Check that this is not a system library that does not exist on disk.
3429 auto lenFilename = strlen(filename);
3430 auto isInMacOSSystemDir = [](const char *fn) {
3431 return StartsWithStrLit(fn, "/usr/lib/") || StartsWithStrLit(fn, "/System/Library/");
3432 };
3433 if (!strcmp(filename, "cl_kernels") // yepp, no directory
3434
3435 // These we should not link with (e.g. because they forward to .tbd):
3436 || StartsWithStrLit(filename, "/usr/lib/system/")
3437 || StartsWithStrLit(filename, "/usr/lib/libc++")
3438 || StartsWithStrLit(filename, "/System/Library/Frameworks/")
3439 || StartsWithStrLit(filename, "/System/Library/PrivateFrameworks/")
3440 || StartsWithStrLit(filename, "/System/Library/CoreServices/")
3441 || StartsWithStrLit(filename, "/usr/lib/libSystem")
3442 || StartsWithStrLit(filename, "/usr/lib/libstdc++")
3443 || StartsWithStrLit(filename, "/usr/lib/libicucore")
3444 || StartsWithStrLit(filename, "/usr/lib/libbsm")
3445 || StartsWithStrLit(filename, "/usr/lib/libobjc")
3446 || StartsWithStrLit(filename, "/usr/lib/libresolv")
3447 || StartsWithStrLit(filename, "/usr/lib/libauto")
3448 || StartsWithStrLit(filename, "/usr/lib/libcups")
3449 || StartsWithStrLit(filename, "/usr/lib/libDiagnosticMessagesClient")
3450 || StartsWithStrLit(filename, "/usr/lib/liblangid")
3451 || StartsWithStrLit(filename, "/usr/lib/libCRFSuite")
3452 || StartsWithStrLit(filename, "/usr/lib/libpam")
3453 || StartsWithStrLit(filename, "/usr/lib/libOpenScriptingUtil")
3454 || StartsWithStrLit(filename, "/usr/lib/libextension")
3455 || StartsWithStrLit(filename, "/usr/lib/libAudioToolboxUtility")
3456 || StartsWithStrLit(filename, "/usr/lib/liboah")
3457 || StartsWithStrLit(filename, "/usr/lib/libRosetta")
3458 || StartsWithStrLit(filename, "/usr/lib/libCoreEntitlements")
3459 || StartsWithStrLit(filename, "/usr/lib/libssl.")
3460 || StartsWithStrLit(filename, "/usr/lib/libcrypto.")
3461
3462 // The system lib is likely in macOS's blob.
3463 || (isInMacOSSystemDir(filename) && gSystem->AccessPathName(filename))
3464
3465 // "Link against the umbrella framework 'System.framework' instead"
3466 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_kernel")
3467 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_platform")
3468 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_pthread")
3469
3470 // "cannot link directly with dylib/framework, your binary is not an allowed client of
3471 // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
3472 // SDKs/MacOSX.sdk/usr/lib/libAudioToolboxUtility.tbd for architecture x86_64
3473 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4, ".tbd")))
3474 return;
3475 TString sFileName(filename);
3476 R__UpdateLibFileForLinking(sFileName);
3477 filename = sFileName.Data();
3478#elif defined(__CYGWIN__)
3479 // Check that this is not a system library
3480 static const int bufsize = 260;
3481 char posixwindir[bufsize];
3482 char *windir = getenv("WINDIR");
3483 if (windir)
3484 cygwin_conv_path(CCP_WIN_A_TO_POSIX, windir, posixwindir, bufsize);
3485 else
3486 snprintf(posixwindir, sizeof(posixwindir), "/Windows/");
3487 if (strstr(filename, posixwindir) ||
3488 strstr(filename, "/usr/bin/cyg"))
3489 return;
3490#elif defined(R__WIN32)
3491 if (strstr(filename, "/Windows/"))
3492 return;
3493#elif defined (R__LINUX)
3494 if (strstr(filename, "/ld-linux")
3495 || strstr(filename, "linux-gnu/")
3496 || strstr(filename, "/libstdc++.")
3497 || strstr(filename, "/libgcc")
3498 || strstr(filename, "/libc.")
3499 || strstr(filename, "/libdl.")
3500 || strstr(filename, "/libm."))
3501 return;
3502#endif
3503 // Update string of available libraries.
3504 if (!fSharedLibs.IsNull()) {
3505 fSharedLibs.Append(" ");
3506 }
3508}
3509
3510////////////////////////////////////////////////////////////////////////////////
3511/// Load a library file in cling's memory.
3512/// if 'system' is true, the library is never unloaded.
3513/// Return 0 on success, -1 on failure.
3514
3515Int_t TCling::Load(const char* filename, Bool_t system)
3516{
3517 assert(!IsFromRootCling() && "Trying to load library from rootcling!");
3518
3519 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3521 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3522 std::string canonLib = DLM->lookupLibrary(filename);
3523 cling::DynamicLibraryManager::LoadLibResult res
3524 = cling::DynamicLibraryManager::kLoadLibNotFound;
3525 if (!canonLib.empty()) {
3526 if (system)
3527 res = DLM->loadLibrary(filename, system, true);
3528 else {
3529 // For the non system libs, we'd like to be able to unload them.
3530 // FIXME: Here we lose the information about kLoadLibAlreadyLoaded case.
3531 cling::Interpreter::CompilationResult compRes;
3532 HandleInterpreterException(GetMetaProcessorImpl(), Form(".L %s", canonLib.c_str()), compRes, /*cling::Value*/nullptr);
3533 if (compRes == cling::Interpreter::kSuccess)
3534 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3535 }
3536 }
3537
3538 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3540 }
3541 switch (res) {
3542 case cling::DynamicLibraryManager::kLoadLibSuccess: return 0;
3543 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return 1;
3544 default: break;
3545 };
3546 return -1;
3547}
3548
3549////////////////////////////////////////////////////////////////////////////////
3550/// Load a macro file in cling's memory.
3551
3552void TCling::LoadMacro(const char* filename, EErrorCode* error)
3553{
3554 ProcessLine(Form(".L %s", filename), error);
3555}
3556
3557////////////////////////////////////////////////////////////////////////////////
3558/// Let cling process a command line asynch.
3559
3561{
3562 return ProcessLine(line, error);
3563}
3564
3565////////////////////////////////////////////////////////////////////////////////
3566/// Let cling process a command line synchronously, i.e we are waiting
3567/// it will be finished.
3568
3570{
3572 if (gApplication) {
3573 if (gApplication->IsCmdThread()) {
3574 return ProcessLine(line, error);
3575 }
3576 return 0;
3577 }
3578 return ProcessLine(line, error);
3579}
3580
3581////////////////////////////////////////////////////////////////////////////////
3582/// Directly execute an executable statement (e.g. "func()", "3+5", etc.
3583/// however not declarations, like "Int_t x;").
3584
3586{
3587#ifdef R__WIN32
3588 // Test on ApplicationImp not being 0 is needed because only at end of
3589 // TApplication ctor the IsLineProcessing flag is set to 0, so before
3590 // we can not use it.
3592 while (gROOT->IsLineProcessing() && !gApplication) {
3593 Warning("Calc", "waiting for cling thread to free");
3594 gSystem->Sleep(500);
3595 }
3596 gROOT->SetLineIsProcessing();
3597 }
3598#endif // R__WIN32
3600 if (error) {
3601 *error = TInterpreter::kNoError;
3602 }
3603 cling::Value valRef;
3604 cling::Interpreter::CompilationResult cr = cling::Interpreter::kFailure;
3605 try {
3606 cr = fInterpreter->evaluate(line, valRef);
3607 }
3608 catch (cling::InterpreterException& ex)
3609 {
3610 Error("Calc", "%s.\n%s", ex.what(), "Evaluation of your expression was aborted.");
3611 ex.diagnose();
3612 cr = cling::Interpreter::kFailure;
3613 }
3614
3615 if (cr != cling::Interpreter::kSuccess) {
3616 // Failure in compilation.
3617 if (error) {
3618 // Note: Yes these codes are weird.
3620 }
3621 return 0L;
3622 }
3623 if (!valRef.isValid()) {
3624 // Failure at runtime.
3625 if (error) {
3626 // Note: Yes these codes are weird.
3627 *error = TInterpreter::kDangerous;
3628 }
3629 return 0L;
3630 }
3631
3632 if (valRef.isVoid()) {
3633 return 0;
3634 }
3635
3636 RegisterTemporary(valRef);
3637#ifdef R__WIN32
3639 gROOT->SetLineHasBeenProcessed();
3640 }
3641#endif // R__WIN32
3642 return valRef.castAs<Longptr_t>();
3643}
3644
3645////////////////////////////////////////////////////////////////////////////////
3646/// Set a getline function to call when input is needed.
3647
3648void TCling::SetGetline(const char * (*getlineFunc)(const char* prompt),
3649 void (*histaddFunc)(const char* line))
3650{
3651 // If cling offers a replacement for G__pause(), it would need to
3652 // also offer a way to customize at least the history recording.
3653
3654#if defined(R__MUST_REVISIT)
3655#if R__MUST_REVISIT(6,2)
3656 Warning("SetGetline","Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3657#endif
3658#endif
3659}
3660
3661////////////////////////////////////////////////////////////////////////////////
3662/// Helper function to increase the internal Cling count of transactions
3663/// that change the AST.
3664
3665Bool_t TCling::HandleNewTransaction(const cling::Transaction &T)
3666{
3668
3669 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3670 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3671 || T.macros_begin() != T.macros_end()
3672 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3674 return true;
3675 }
3676 return false;
3677}
3678
3679////////////////////////////////////////////////////////////////////////////////
3680/// Delete object from cling symbol table so it can not be used anymore.
3681/// cling objects are always on the heap.
3682
3684{
3685 // NOTE: When replacing the mutex by a ReadWrite mutex, we **must**
3686 // put in place the Read/Write part here. Keeping the write lock
3687 // here is 'catasptrophic' for scaling as it means that ALL calls
3688 // to RecursiveRemove will take the write lock and performance
3689 // of many threads trying to access the write lock at the same
3690 // time is relatively bad.
3692 // Note that fgSetOfSpecials is supposed to be updated by TClingCallbacks::tryFindROOTSpecialInternal
3693 // (but isn't at the moment).
3694 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3695 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3696 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3698 DeleteGlobal(obj);
3699 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3700 }
3701 }
3702}
3703
3704////////////////////////////////////////////////////////////////////////////////
3705/// Pressing Ctrl+C should forward here. In the case where we have had
3706/// continuation requested we must reset it.
3707
3709{
3710 fMetaProcessor->cancelContinuation();
3711 // Reset the Cling state to the state saved by the last call to
3712 // TCling::SaveContext().
3713#if defined(R__MUST_REVISIT)
3714#if R__MUST_REVISIT(6,2)
3716 Warning("Reset","Cling should support the equivalent of scratch_upto(&fDictPos)");
3717#endif
3718#endif
3719}
3720
3721////////////////////////////////////////////////////////////////////////////////
3722/// Reset the Cling state to its initial state.
3723
3725{
3726#if defined(R__MUST_REVISIT)
3727#if R__MUST_REVISIT(6,2)
3729 Warning("ResetAll","Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3730#endif
3731#endif
3732}
3733
3734////////////////////////////////////////////////////////////////////////////////
3735/// Reset in Cling the list of global variables to the state saved by the last
3736/// call to TCling::SaveGlobalsContext().
3737///
3738/// Note: Right now, all we do is run the global destructors.
3739
3741{
3743 // TODO:
3744 // Here we should iterate over the transactions (N-3) and revert.
3745 // N-3 because the first three internal to cling.
3746
3747 fInterpreter->runAndRemoveStaticDestructors();
3748}
3749
3750////////////////////////////////////////////////////////////////////////////////
3751/// Reset the Cling 'user' global objects/variables state to the state saved by the last
3752/// call to TCling::SaveGlobalsContext().
3753
3755{
3756#if defined(R__MUST_REVISIT)
3757#if R__MUST_REVISIT(6,2)
3759 Warning("ResetGlobalVar","Cling should support the equivalent of resetglobalvar(obj)");
3760#endif
3761#endif
3762}
3763
3764////////////////////////////////////////////////////////////////////////////////
3765/// Rewind Cling dictionary to the point where it was before executing
3766/// the current macro. This function is typically called after SEGV or
3767/// ctlr-C after doing a longjmp back to the prompt.
3768
3770{
3771#if defined(R__MUST_REVISIT)
3772#if R__MUST_REVISIT(6,2)
3774 Warning("RewindDictionary","Cling should provide a way to revert transaction similar to rewinddictionary()");
3775#endif
3776#endif
3777}
3778
3779////////////////////////////////////////////////////////////////////////////////
3780/// Delete obj from Cling symbol table so it cannot be accessed anymore.
3781/// Returns 1 in case of success and 0 in case object was not in table.
3782
3784{
3785#if defined(R__MUST_REVISIT)
3786#if R__MUST_REVISIT(6,2)
3788 Warning("DeleteGlobal","Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3789#endif
3790#endif
3791 return 0;
3792}
3793
3794////////////////////////////////////////////////////////////////////////////////
3795/// Undeclare obj called name.
3796/// Returns 1 in case of success, 0 for failure.
3797
3799{
3800#if defined(R__MUST_REVISIT)
3801#if R__MUST_REVISIT(6,2)
3802 Warning("DeleteVariable","should do more that just reseting the value to zero");
3803#endif
3804#endif
3805
3807 llvm::StringRef srName(name);
3808 const char* unscopedName = name;
3809 llvm::StringRef::size_type posScope = srName.rfind("::");
3810 const clang::DeclContext* declCtx = nullptr;
3811 if (posScope != llvm::StringRef::npos) {
3812 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3813 const clang::Decl* scopeDecl
3814 = lh.findScope(srName.substr(0, posScope),
3815 cling::LookupHelper::WithDiagnostics);
3816 if (!scopeDecl) {
3817 Error("DeleteVariable", "Cannot find enclosing scope for variable %s",
3818 name);
3819 return 0;
3820 }
3821 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3822 if (!declCtx) {
3823 Error("DeleteVariable",
3824 "Enclosing scope for variable %s is not a declaration context",
3825 name);
3826 return 0;
3827 }
3828 unscopedName += posScope + 2;
3829 }
3830 // Could trigger deserialization of decls.
3831 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
3832 clang::NamedDecl* nVarDecl
3833 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3834 if (!nVarDecl) {
3835 Error("DeleteVariable", "Unknown variable %s", name);
3836 return 0;
3837 }
3838 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3839 if (!varDecl) {
3840 Error("DeleteVariable", "Entity %s is not a variable", name);
3841 return 0;
3842 }
3843
3844 clang::QualType qType = varDecl->getType();
3845 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3846 // Cannot set a reference's address to nullptr; the JIT can place it
3847 // into read-only memory (ROOT-7100).
3848 if (type->isPointerType()) {
3849 int** ppInt = (int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
3850 // set pointer to invalid.
3851 if (ppInt) *ppInt = nullptr;
3852 }
3853 return 1;
3854}
3855
3856////////////////////////////////////////////////////////////////////////////////
3857/// Save the current Cling state.
3858
3860{
3861#if defined(R__MUST_REVISIT)
3862#if R__MUST_REVISIT(6,2)
3864 Warning("SaveContext","Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
3865#endif
3866#endif
3867}
3868
3869////////////////////////////////////////////////////////////////////////////////
3870/// Save the current Cling state of global objects.
3871
3873{
3874#if defined(R__MUST_REVISIT)
3875#if R__MUST_REVISIT(6,2)
3877 Warning("SaveGlobalsContext","Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
3878#endif
3879#endif
3880}
3881
3882////////////////////////////////////////////////////////////////////////////////
3883/// No op: see TClingCallbacks (used to update the list of globals)
3884
3886{
3887}
3888
3889////////////////////////////////////////////////////////////////////////////////
3890/// No op: see TClingCallbacks (used to update the list of global functions)
3891
3893{
3894}
3895
3896////////////////////////////////////////////////////////////////////////////////
3897/// No op: see TClingCallbacks (used to update the list of types)
3898
3900{
3901}
3902
3903////////////////////////////////////////////////////////////////////////////////
3904/// Check in what order the member of a tuple are layout.
3905enum class ETupleOrdering {
3906 kAscending,
3909};
3910
3912{
3915};
3916
3918{
3921};
3922
3924{
3925 std::tuple<int,double> value;
3928
3929 size_t offset0 = ((char*)&(std::get<0>(value))) - ((char*)&value);
3930 size_t offset1 = ((char*)&(std::get<1>(value))) - ((char*)&value);
3931
3932 size_t ascOffset0 = ((char*)&(asc._0)) - ((char*)&asc);
3933 size_t ascOffset1 = ((char*)&(asc._1)) - ((char*)&asc);
3934
3935 size_t desOffset0 = ((char*)&(des._0)) - ((char*)&des);
3936 size_t desOffset1 = ((char*)&(des._1)) - ((char*)&des);
3937
3938 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
3940 } else if (offset0 == desOffset0 && offset1 == desOffset1) {
3942 } else {
3944 }
3945}
3946
3947static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh, Bool_t silent)
3948{
3949 TClassEdit::TSplitType tupleContent(classname);
3950 std::string alternateName = "TEmulatedTuple";
3951 alternateName.append( classname + 5 );
3952
3953 std::string fullname = "ROOT::Internal::" + alternateName;
3954 if (lh.findScope(fullname, cling::LookupHelper::NoDiagnostics,
3955 /*resultType*/nullptr, /* intantiateTemplate= */ false))
3956 return fullname;
3957
3958 {
3959 // Check if we can produce the tuple
3960 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
3961 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
3962 auto deleter = [](TypeInfo_t *type) {
3963 gInterpreter->TypeInfo_Delete(type);
3964 };
3965 std::unique_ptr<TypeInfo_t, decltype(deleter)> type{ gInterpreter->TypeInfo_Factory(), deleter };
3966 while (iter != theEnd) {
3967 gInterpreter->TypeInfo_Init(type.get(), iter->c_str());
3968 if (gInterpreter->TypeInfo_Property(type.get()) & kIsNotReacheable) {
3969 if (!silent)
3970 Error("Load","Could not declare alternate type for %s since %s (or one of its context) is private or protected",
3971 classname, iter->c_str());
3972 return "";
3973 }
3974 ++iter;
3975 }
3976 }
3977
3978 std::string guard_name;
3979 ROOT::TMetaUtils::GetCppName(guard_name,alternateName.c_str());
3980 std::ostringstream guard;
3981 guard << "ROOT_INTERNAL_TEmulated_";
3982 guard << guard_name;
3983
3984 std::ostringstream alternateTuple;
3985 alternateTuple << "#ifndef " << guard.str() << "\n";
3986 alternateTuple << "#define " << guard.str() << "\n";
3987 alternateTuple << "namespace ROOT { namespace Internal {\n";
3988 alternateTuple << "template <class... Types> struct TEmulatedTuple;\n";
3989 alternateTuple << "template <> struct " << alternateName << " {\n";
3990
3991 // This could also be a compile time choice ...
3992 switch(IsTupleAscending()) {
3994 unsigned int nMember = 0;
3995 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
3996 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
3997 while (iter != theEnd) {
3998 alternateTuple << " " << *iter << " _" << nMember << ";\n";
3999 ++iter;
4000 ++nMember;
4001 }
4002 break;
4003 }
4005 unsigned int nMember = tupleContent.fElements.size() - 3;
4006 auto iter = tupleContent.fElements.rbegin() + 1; // skip the 'stars'.
4007 auto theEnd = tupleContent.fElements.rend() - 1; // Skip the template name (tuple).
4008 while (iter != theEnd) {
4009 alternateTuple << " " << *iter << " _" << nMember << ";\n";
4010 ++iter;
4011 --nMember;
4012 }
4013 break;
4014 }
4016 Fatal("TCling::SetClassInfo::AlternateTuple",
4017 "Layout of std::tuple on this platform is unexpected.");
4018 break;
4019 }
4020 }
4021
4022 alternateTuple << "};\n";
4023 alternateTuple << "}}\n";
4024 alternateTuple << "#endif\n";
4025 if (!gCling->Declare(alternateTuple.str().c_str()))
4026 {
4027 // Declare is not silent (yet?), so add an explicit error message
4028 // to indicate the consequence of the syntax errors.
4029 Error("Load","Could not declare %s",alternateName.c_str());
4030 return "";
4031 }
4032 alternateName = "ROOT::Internal::" + alternateName;
4033 return alternateName;
4034}
4035
4036////////////////////////////////////////////////////////////////////////////////
4037/// Set pointer to the TClingClassInfo in TClass.
4038/// If 'reload' is true, (attempt to) generate a new ClassInfo even if we
4039/// already have one.
4040
4041void TCling::SetClassInfo(TClass* cl, Bool_t reload, Bool_t silent)
4042{
4043 // We are shutting down, there is no point in reloading, it only triggers
4044 // redundant deserializations.
4045 if (fIsShuttingDown) {
4046 // Remove the decl_id from the DeclIdToTClass map
4047 if (cl->fClassInfo) {
4049 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4050 // Test again as another thread may have set fClassInfo to nullptr.
4051 if (TClinginfo) {
4052 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4053 }
4054 delete TClinginfo;
4055 cl->fClassInfo = nullptr;
4056 }
4057 return;
4058 }
4059
4061 if (cl->fClassInfo && !reload) {
4062 return;
4063 }
4064 //Remove the decl_id from the DeclIdToTClass map
4065 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4066 if (TClinginfo) {
4067 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4068 }
4069 delete TClinginfo;
4070 cl->fClassInfo = nullptr;
4071 std::string name(cl->GetName());
4072
4073 auto SetWithoutClassInfoState = [](TClass *cl)
4074 {
4075 if (cl->fState != TClass::kHasTClassInit) {
4076 if (cl->fStreamerInfo->GetEntries() != 0) {
4078 } else {
4080 }
4081 }
4082 };
4083 // Handle the special case of 'tuple' where we ignore the real implementation
4084 // details and just overlay a 'simpler'/'simplistic' version that is easy
4085 // for the I/O to understand and handle.
4086 if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
4087 if (!reload)
4088 name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper(), silent);
4089 if (reload || name.empty()) {
4090 // We could not generate the alternate
4091 SetWithoutClassInfoState(cl);
4092 return;
4093 }
4094 }
4095
4096 bool instantiateTemplate = !cl->TestBit(TClass::kUnloading);
4097 // FIXME: Rather than adding an option to the TClingClassInfo, we should consider combining code
4098 // that is currently in the caller (like SetUnloaded) that disable AutoLoading and AutoParsing and
4099 // code is in the callee (disabling template instantiation) and end up with a more explicit class:
4100 // TClingClassInfoReadOnly.
4101 TClingClassInfo* info = new TClingClassInfo(GetInterpreterImpl(), name.c_str(), instantiateTemplate);
4102 if (!info->IsValid()) {
4103 SetWithoutClassInfoState(cl);
4104 delete info;
4105 return;
4106 }
4107 cl->fClassInfo = (ClassInfo_t*)info; // Note: We are transferring ownership here.
4108 // In case a class contains an external enum, the enum will be seen as a
4109 // class. We must detect this special case and make the class a Zombie.
4110 // Here we assume that a class has at least one method.
4111 // We can NOT call TClass::Property from here, because this method
4112 // assumes that the TClass is well formed to do a lot of information
4113 // caching. The method SetClassInfo (i.e. here) is usually called during
4114 // the building phase of the TClass, hence it is NOT well formed yet.
4115 Bool_t zombieCandidate = kFALSE;
4116 if (
4117 info->IsValid() &&
4118 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
4119 ) {
4120 zombieCandidate = kTRUE;
4121 }
4122 if (!info->IsLoaded()) {
4123 if (info->Property() & (kIsNamespace)) {
4124 // Namespaces can have info but no corresponding CINT dictionary
4125 // because they are auto-created if one of their contained
4126 // classes has a dictionary.
4127 zombieCandidate = kTRUE;
4128 }
4129 // this happens when no dictionary is available
4130 delete info;
4131 cl->fClassInfo = nullptr;
4132 }
4133 if (zombieCandidate && !cl->GetCollectionType()) {
4134 cl->MakeZombie();
4135 }
4136 // If we reach here, the info was valid (See early returns).
4137 if (cl->fState != TClass::kHasTClassInit) {
4138 if (cl->fClassInfo) {
4140 } else {
4141// if (TClassEdit::IsSTLCont(cl->GetName()) {
4142// There will be an emulated collection proxy, is that the same?
4143// cl->fState = TClass::kEmulated;
4144// } else {
4145 if (cl->fStreamerInfo->GetEntries() != 0) {
4147 } else {
4149 }
4150// }
4151 }
4152 }
4153 if (cl->fClassInfo) {
4154 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
4155 }
4156}
4157
4158////////////////////////////////////////////////////////////////////////////////
4159/// Checks if an entity with the specified name is defined in Cling.
4160/// Returns kUnknown if the entity is not defined.
4161/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
4162/// Returns kKnown if the entity is defined.
4163///
4164/// By default, structs, namespaces, classes, enums and unions are looked for.
4165/// If the flag isClassOrNamespaceOnly is true, classes, structs and
4166/// namespaces only are considered. I.e. if the name is an enum or a union,
4167/// the returned value is false.
4168///
4169/// In the case where the class is not loaded and belongs to a namespace
4170/// or is nested, looking for the full class name is outputting a lots of
4171/// (expected) error messages. Currently the only way to avoid this is to
4172/// specifically check that each level of nesting is already loaded.
4173/// In case of templates the idea is that everything between the outer
4174/// '<' and '>' has to be skipped, e.g.: `aap<pippo<noot>::klaas>::a_class`
4175
4177TCling::CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly /* = kFALSE*/)
4178{
4180 static const char *anonEnum = "anonymous enum ";
4181 static const int cmplen = strlen(anonEnum);
4182
4183 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
4184 return kUnknown;
4185 }
4186
4187 // Do not turn on the AutoLoading if it is globally off.
4188 autoload = autoload && IsClassAutoLoadingEnabled();
4189
4190 // Avoid the double search below in case the name is a fundamental type
4191 // or typedef to a fundamental type.
4192 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
4193 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
4194
4195 if (fundType && fundType->GetType() < TVirtualStreamerInfo::kObject
4196 && fundType->GetType() > 0) {
4197 // Fundamental type, no a class.
4198 return kUnknown;
4199 }
4200
4201 // Migrated from within TClass::GetClass
4202 // If we want to know if a class or a namespace with this name exists in the
4203 // interpreter and this is an enum in the type system, before or after loading
4204 // according to the autoload function argument, return kUnknown.
4205 if (isClassOrNamespaceOnly && TEnum::GetEnum(name, autoload ? TEnum::kAutoload : TEnum::kNone))
4206 return kUnknown;
4207
4208 const char *classname = name;
4209
4210 // RAII to suspend and restore auto-loading and auto-parsing based on some external conditions.
4211 class MaybeSuspendAutoLoadParse {
4212 int fStoreAutoLoad = 0;
4213 int fStoreAutoParse = 0;
4214 bool fSuspendedAutoParse = false;
4215 public:
4216 MaybeSuspendAutoLoadParse(int autoload) {
4217 fStoreAutoLoad = ((TCling*)gCling)->SetClassAutoLoading(autoload);
4218 }
4219
4220 void SuspendAutoParsing() {
4221 fSuspendedAutoParse = true;
4222 fStoreAutoParse = ((TCling*)gCling)->SetSuspendAutoParsing(true);
4223 }
4224
4225 ~MaybeSuspendAutoLoadParse() {
4226 if (fSuspendedAutoParse)
4227 ((TCling*)gCling)->SetSuspendAutoParsing(fStoreAutoParse);
4228 ((TCling*)gCling)->SetClassAutoLoading(fStoreAutoLoad);
4229 }
4230 };
4231
4232 MaybeSuspendAutoLoadParse autoLoadParseRAII( autoload );
4233 if (TClassEdit::IsStdPair(classname) || TClassEdit::IsStdPairBase(classname))
4234 autoLoadParseRAII.SuspendAutoParsing();
4235
4236 // First we want to check whether the decl exist, but _without_
4237 // generating any template instantiation. However, the lookup
4238 // still will create a forward declaration of the class template instance
4239 // if it exist. In this case, the return value of findScope will still
4240 // be zero but the type will be initialized.
4241 // Note in the corresponding code in ROOT 5, CINT was not instantiating
4242 // this forward declaration.
4243 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4244 const clang::Type *type = nullptr;
4245 const clang::Decl *decl
4246 = lh.findScope(classname,
4247 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4248 : cling::LookupHelper::NoDiagnostics,
4249 &type, /* intantiateTemplate= */ false );
4250 if (!decl) {
4251 std::string buf = TClassEdit::InsertStd(classname);
4252 decl = lh.findScope(buf,
4253 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4254 : cling::LookupHelper::NoDiagnostics,
4255 &type,false);
4256 }
4257
4258 if (type) {
4259 // If decl==0 and the type is valid, then we have a forward declaration.
4260 if (!decl) {
4261 // If we have a forward declaration for a class template instantiation,
4262 // we want to ignore it if it was produced/induced by the call to
4263 // findScope, however we can not distinguish those from the
4264 // instantiation induce by 'soft' use (and thus also induce by the
4265 // same underlying code paths)
4266 // ['soft' use = use not requiring a complete definition]
4267 // So to reduce the amount of disruption to the existing code we
4268 // would just ignore those for STL collection, for which we really
4269 // need to have the compiled collection proxy (and thus the TClass
4270 // bootstrap).
4271 clang::ClassTemplateSpecializationDecl *tmpltDecl =
4272 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
4273 (type->getAsCXXRecordDecl());
4274 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
4275 // Since the point of instantiation is invalid, we 'guess' that
4276 // the 'instantiation' of the forwarded type appended in
4277 // findscope.
4278 if (ROOT::TMetaUtils::IsSTLCont(*tmpltDecl)) {
4279 // For STL Collection we return kUnknown.
4280 return kUnknown;
4281 }
4282 }
4283 }
4285 if (!tci.IsValid()) {
4286 return kUnknown;
4287 }
4288 auto propertiesMask = isClassOrNamespaceOnly ? kIsClass | kIsStruct | kIsNamespace :
4290
4291 if (tci.Property() & propertiesMask) {
4292 bool hasClassDefInline = false;
4293 if (isClassOrNamespaceOnly) {
4294 // We do not need to check for ClassDefInline when this is called from
4295 // TClass::Init, we only do it for the call from TClass::GetClass.
4296 auto hasDictionary = tci.GetMethod("Dictionary", "", false, nullptr, ROOT::kExactMatch);
4297 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, nullptr, ROOT::kExactMatch);
4298
4299 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
4300 int lineNumber = 0;
4301 bool success = false;
4302 std::tie(success, lineNumber) =
4303 ROOT::TMetaUtils::GetTrivialIntegralReturnValue(implLineFunc.GetAsFunctionDecl(), *fInterpreter);
4304 hasClassDefInline = success && (lineNumber == -1);
4305 }
4306 }
4307
4308 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
4309 // , hasClassDefInline);
4310
4311 // We are now sure that the entry is not in fact an autoload entry.
4312 if (hasClassDefInline)
4313 return kWithClassDefInline;
4314 else
4315 return kKnown;
4316 } else {
4317 // We are now sure that the entry is not in fact an autoload entry.
4318 return kUnknown;
4319 }
4320 }
4321
4322 if (decl)
4323 return kKnown;
4324 else
4325 return kUnknown;
4326
4327 // Setting up iterator part of TClingTypedefInfo is too slow.
4328 // Copy the lookup code instead:
4329 /*
4330 TClingTypedefInfo t(fInterpreter, name);
4331 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
4332 delete[] classname;
4333 return kTRUE;
4334 }
4335 */
4336
4337// const clang::Decl *decl = lh.findScope(name);
4338// if (!decl) {
4339// std::string buf = TClassEdit::InsertStd(name);
4340// decl = lh.findScope(buf);
4341// }
4342
4343// return (decl);
4344}
4345
4346////////////////////////////////////////////////////////////////////////////////
4347/// Return true if there is a class template by the given name ...
4348
4350{
4351 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4352 // Interpreter transaction ahead, needs locking
4354 const clang::Decl *decl
4355 = lh.findClassTemplate(name,
4356 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4357 : cling::LookupHelper::NoDiagnostics);
4358 if (!decl) {
4359 std::string strname = "std::";
4360 strname += name;
4361 decl = lh.findClassTemplate(strname,
4362 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4363 : cling::LookupHelper::NoDiagnostics);
4364 }
4365 return nullptr != decl;
4366}
4367
4368////////////////////////////////////////////////////////////////////////////////
4369/// Create list of pointers to base class(es) for TClass cl.
4370
4372{
4374 if (cl->fBase) {
4375 return;
4376 }
4378 if (!tci) return;
4380 TList *listOfBase = new TList;
4381 while (t.Next()) {
4382 // if name cannot be obtained no use to put in list
4383 if (t.IsValid() && t.Name()) {
4385 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
4386 }
4387 }
4388 // Now that is complete, publish it.
4389 cl->fBase = listOfBase;
4390}
4391
4392////////////////////////////////////////////////////////////////////////////////
4393/// Create list of pointers to enums for TClass cl.
4394
4395void TCling::LoadEnums(TListOfEnums& enumList) const
4396{
4398
4399 const Decl * D;
4400 TClass* cl = enumList.GetClass();
4401 if (cl) {
4402 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4403 }
4404 else {
4405 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4406 }
4407 // Iterate on the decl of the class and get the enums.
4408 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4409 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4410 // Collect all contexts of the namespace.
4411 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4412 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4413 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(), declEnd = allDeclContexts.end();
4414 declIter != declEnd; ++declIter) {
4415 // Iterate on all decls for each context.
4416 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4417 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4418 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4419 // Get name of the enum type.
4420 std::string buf;
4421 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4422 llvm::raw_string_ostream stream(buf);
4423 // Don't trigger fopen of the source file to count lines:
4424 Policy.AnonymousTagLocations = false;
4425 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
4426 stream.flush();
4427 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
4428 if (!buf.empty()) {
4429 const char* name = buf.c_str();
4430 // Add the enum to the list of loaded enums.
4431 enumList.Get(ED, name);
4432 }
4433 }
4434 }
4435 }
4436 }
4437}
4438
4439////////////////////////////////////////////////////////////////////////////////
4440/// Create list of pointers to function templates for TClass cl.
4441
4443{
4445
4446 const Decl * D;
4447 TListOfFunctionTemplates* funcTempList;
4448 if (cl) {
4449 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4450 funcTempList = (TListOfFunctionTemplates*)cl->GetListOfFunctionTemplates(false);
4451 }
4452 else {
4453 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4454 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4455 }
4456 // Iterate on the decl of the class and get the enums.
4457 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4458 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4459 // Collect all contexts of the namespace.
4460 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4461 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4462 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(),
4463 declEnd = allDeclContexts.end(); declIter != declEnd; ++declIter) {
4464 // Iterate on all decls for each context.
4465 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4466 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4467 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4468 funcTempList->Get(FTD);
4469 }
4470 }
4471 }
4472 }
4473}
4474
4475////////////////////////////////////////////////////////////////////////////////
4476/// Get the scopes representing using declarations of namespace
4477
4478std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4479{
4481 return ci->GetUsingNamespaces();
4482}
4483
4484////////////////////////////////////////////////////////////////////////////////
4485/// Create list of pointers to data members for TClass cl.
4486/// This is now a nop. The creation and updating is handled in
4487/// TListOfDataMembers.
4488
4490{
4491}
4492
4493////////////////////////////////////////////////////////////////////////////////
4494/// Create list of pointers to methods for TClass cl.
4495/// This is now a nop. The creation and updating is handled in
4496/// TListOfFunctions.
4497
4499{
4500}
4501
4502////////////////////////////////////////////////////////////////////////////////
4503/// Update the list of pointers to method for TClass cl
4504/// This is now a nop. The creation and updating is handled in
4505/// TListOfFunctions.
4506
4508{
4509}
4510
4511////////////////////////////////////////////////////////////////////////////////
4512/// Update the list of pointers to data members for TClass cl
4513/// This is now a nop. The creation and updating is handled in
4514/// TListOfDataMembers.
4515
4517{
4518}
4519
4520////////////////////////////////////////////////////////////////////////////////
4521/// Create list of pointers to method arguments for TMethod m.
4522
4524{
4526 if (m->fMethodArgs) {
4527 return;
4528 }
4529 TList *arglist = new TList;
4531 while (t.Next()) {
4532 if (t.IsValid()) {
4534 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4535 }
4536 }
4537 m->fMethodArgs = arglist;
4538}
4539
4540////////////////////////////////////////////////////////////////////////////////
4541/// Return whether we are waiting for more input either because the collected
4542/// input contains unbalanced braces or last seen token was a `\` (backslash-newline)
4543
4545{
4546 return fMetaProcessor->awaitingMoreInput();
4547}
4548
4549////////////////////////////////////////////////////////////////////////////////
4550/// Generate a TClass for the given class.
4551/// Since the caller has already check the ClassInfo, let it give use the
4552/// result (via the value of emulation) rather than recalculate it.
4553
4554TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4555{
4556// For now the following line would lead to the (unwanted) instantiation
4557// of class template. This could/would need to be resurrected only if
4558// we re-introduce so sort of automatic instantiation. However this would
4559// have to include carefull look at the template parameter to avoid
4560// creating instance we can not really use (if the parameter are only forward
4561// declaration or do not have all the necessary interfaces).
4562
4563 // TClingClassInfo tci(fInterpreter, classname);
4564 // if (1 || !tci.IsValid()) {
4565
4566 Version_t version = 1;
4567 if (TClassEdit::IsSTLCont(classname)) {
4568 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4569 }
4571 TClass *cl = new TClass(classname, version, silent);
4572 if (!emulation) {
4573 // Set the class version if the class is versioned.
4574 // Note that we cannot just call CLASS::Class_Version() as we might not have
4575 // an execution engine (when invoked from rootcling).
4576
4577 // Do not call cl->GetClassVersion(), it has side effects!
4578 Version_t oldvers = cl->fClassVersion;
4579 if (oldvers == version && cl->GetClassInfo()) {
4580 // We have a version and it might need an update.
4582 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4583 // Namespaces don't have class versions.
4584 return cl;
4585 }
4586 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", nullptr /*poffset*/,
4589 if (!mi.IsValid()) {
4590 if (cl->TestBit(TClass::kIsTObject)) {
4591 Error("GenerateTClass",
4592 "Cannot find %s::Class_Version()! Class version might be wrong.",
4593 cl->GetName());
4594 }
4595 return cl;
4596 }
4597 Version_t newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4598 *fInterpreter);
4599 if (newvers == -1) {
4600 // Didn't manage to determine the class version from the AST.
4601 // Use runtime instead.
4602 if ((mi.Property() & kIsStatic)
4603 && !fInterpreter->isInSyntaxOnlyMode()) {
4604 // This better be a static function.
4606 callfunc.SetFunc(&mi);
4607 newvers = callfunc.ExecInt(nullptr);
4608 } else {
4609 Error("GenerateTClass",
4610 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4611 cl->GetName());
4612 }
4613 }
4614 if (newvers != oldvers) {
4615 cl->fClassVersion = newvers;
4616 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4617 }
4618 }
4619 }
4620
4621 return cl;
4622
4623// } else {
4624// return GenerateTClass(&tci,silent);
4625// }
4626}
4627
4628#if 0
4629////////////////////////////////////////////////////////////////////////////////
4630
4631static void GenerateTClass_GatherInnerIncludes(cling::Interpreter *interp, TString &includes,TClingClassInfo *info)
4632{
4633 includes += info->FileName();
4634
4635 const clang::ClassTemplateSpecializationDecl *templateCl
4636 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4637 if (templateCl) {
4638 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4639 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4640 if (arg.getKind() == clang::TemplateArgument::Type) {
4641 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4642
4643 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4644 // We really need a header file.
4645 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4646 if (argdecl) {
4647 includes += ";";
4648 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4649 GenerateTClass_GatherInnerIncludes(interp, includes, &subinfo);
4650 } else {
4651 std::string Result;
4652 llvm::raw_string_ostream OS(Result);
4653 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4654 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4655 }
4656 }
4657 }
4658 }
4659 }
4660}
4661#endif
4662
4663////////////////////////////////////////////////////////////////////////////////
4664/// Generate a TClass for the given class.
4665
4666TClass *TCling::GenerateTClass(ClassInfo_t *classinfo, Bool_t silent /* = kFALSE */)
4667{
4668 TClingClassInfo *info = (TClingClassInfo*)classinfo;
4669 if (!info || !info->IsValid()) {
4670 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4671 return nullptr;
4672 }
4673 // We are in the case where we have AST nodes for this class.
4674 TClass *cl = nullptr;
4675 std::string classname;
4676 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4677 if (TClassEdit::IsSTLCont(classname)) {
4678#if 0
4679 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4680 // We need to build up the list of required headers, by
4681 // looking at each template arguments.
4682 TString includes;
4683 GenerateTClass_GatherInnerIncludes(fInterpreter,includes,info);
4684
4685 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4686 // 0 means success.
4687 cl = TClass::LoadClass(classnam.c_str(), silent);
4688 if (cl == 0) {
4689 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4690 }
4691 }
4692#endif
4693 if (cl == nullptr) {
4694 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4695 cl = new TClass(classinfo, version, nullptr, nullptr, -1, -1, silent);
4696 }
4697 } else {
4698 // For regular class, just create a TClass on the fly ...
4699 // Not quite useful yet, but that what CINT used to do anyway.
4700 cl = new TClass(classinfo, 1, nullptr, nullptr, -1, -1, silent);
4701 }
4702 // Add the new TClass to the map of declid and TClass*.
4703 if (cl) {
4705 }
4706 return cl;
4707}
4708
4709////////////////////////////////////////////////////////////////////////////////
4710/// Generate the dictionary for the C++ classes listed in the first
4711/// argument (in a semi-colon separated list).
4712/// 'includes' contains a semi-colon separated list of file to
4713/// `#include` in the dictionary.
4714/// For example:
4715/// ~~~ {.cpp}
4716/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4717/// ~~~
4718/// or
4719/// ~~~ {.cpp}
4720/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4721/// ~~~
4722
4723Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4724{
4725 if (classes == nullptr || classes[0] == 0) {
4726 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4727 return 0;
4728 }
4729 // Split the input list
4730 std::vector<std::string> listClasses;
4731 for (
4732 const char* current = classes, *prev = classes;
4733 *current != 0;
4734 ++current
4735 ) {
4736 if (*current == ';') {
4737 listClasses.push_back(std::string(prev, current - prev));
4738 prev = current + 1;
4739 }
4740 else if (*(current + 1) == 0) {
4741 listClasses.push_back(std::string(prev, current + 1 - prev));
4742 prev = current + 1;
4743 }
4744 }
4745 std::vector<std::string> listIncludes;
4746 if (!includes)
4747 includes = "";
4748 for (
4749 const char* current = includes, *prev = includes;
4750 *current != 0;
4751 ++current
4752 ) {
4753 if (*current == ';') {
4754 listIncludes.push_back(std::string(prev, current - prev));
4755 prev = current + 1;
4756 }
4757 else if (*(current + 1) == 0) {
4758 listIncludes.push_back(std::string(prev, current + 1 - prev));
4759 prev = current + 1;
4760 }
4761 }
4762 // Generate the temporary dictionary file
4763 return !TCling_GenerateDictionary(listClasses, listIncludes,
4764 std::vector<std::string>(), std::vector<std::string>());
4765}
4766
4767////////////////////////////////////////////////////////////////////////////////
4768/// Return pointer to cling Decl of global/static variable that is located
4769/// at the address given by addr.
4770
4771TInterpreter::DeclId_t TCling::GetDataMember(ClassInfo_t *opaque_cl, const char *name) const
4772{
4774 DeclId_t d;
4775 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4776
4777 // Could trigger deserialization of decls.
4778 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4779
4780 if (cl) {
4781 d = cl->GetDataMember(name);
4782 // We check if the decl of the data member has an annotation which indicates
4783 // an ioname.
4784 // In case this is true, if the name requested is not the ioname, we
4785 // return 0, as if the member did not exist. In some sense we override
4786 // the information in the TClassInfo instance, isolating the typesystem in
4787 // TClass from the one in the AST.
4788 if (const ValueDecl* decl = (const ValueDecl*) d){
4789 std::string ioName;
4790 bool hasIoName = ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"ioname",ioName);
4791 if (hasIoName && ioName != name) return nullptr;
4792 }
4793 return d;
4794 }
4795 // We are looking up for something on the TU scope.
4796 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
4797 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
4798 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
4799 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
4800 // are only fulfilling ROOT's understanding for a Data Member.
4801 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
4802 // similar as below.
4803 using namespace clang;
4804 Sema& SemaR = fInterpreter->getSema();
4805 DeclarationName DName = &SemaR.Context.Idents.get(name);
4806
4807 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
4808 Sema::ForExternalRedeclaration);
4809
4810 cling::utils::Lookup::Named(&SemaR, R);
4811
4812 LookupResult::Filter F = R.makeFilter();
4813 // Filter the data-member looking decls.
4814 while (F.hasNext()) {
4815 NamedDecl *D = F.next();
4816 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) ||
4817 isa<IndirectFieldDecl>(D))
4818 continue;
4819 F.erase();
4820 }
4821 F.done();
4822
4823 if (R.isSingleResult())
4824 return R.getFoundDecl();
4825 return nullptr;
4826}
4827
4828////////////////////////////////////////////////////////////////////////////////
4829/// Return pointer to cling Decl of global/static variable that is located
4830/// at the address given by addr.
4831
4833{
4835
4836 const clang::Decl* possibleEnum = nullptr;
4837 // FInd the context of the decl.
4838 if (cl) {
4840 if (cci) {
4841 const clang::DeclContext* dc = nullptr;
4842 if (const clang::Decl* D = cci->GetDecl()) {
4843 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
4844 dc = dyn_cast<clang::RecordDecl>(D);
4845 }
4846 }
4847 if (dc) {
4848 // If it is a data member enum.
4849 // Could trigger deserialization of decls.
4850 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4851 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
4852 } else {
4853 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
4854 }
4855 }
4856 } else {
4857 // If it is a global enum.
4858 // Could trigger deserialization of decls.
4859 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4860 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
4861 }
4862 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
4863 && isa<clang::EnumDecl>(possibleEnum)) {
4864 return possibleEnum;
4865 }
4866 return nullptr;
4867}
4868
4869////////////////////////////////////////////////////////////////////////////////
4870/// Return pointer to cling DeclId for a global value
4871
4872TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
4873{
4874 if (!gv) return nullptr;
4875
4876 llvm::StringRef mangled_name = gv->getName();
4877
4878 int err = 0;
4879 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.str().c_str(), err);
4880 if (err) {
4881 if (err == -2) {
4882 // It might simply be an unmangled global name.
4883 DeclId_t d;
4885 d = gcl.GetDataMember(mangled_name.str().c_str());
4886 return d;
4887 }
4888 return nullptr;
4889 }
4890
4891 std::string scopename(demangled_name_c);
4892 free(demangled_name_c);
4893
4894 //
4895 // Separate out the class or namespace part of the
4896 // function name.
4897 //
4898 std::string dataname;
4899
4900 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
4901 scopename.erase(0, sizeof("typeinfo for ")-1);
4902 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
4903 scopename.erase(0, sizeof("vtable for ")-1);
4904 } else {
4905 // See if it is a function
4906 std::string::size_type pos = scopename.rfind('(');
4907 if (pos != std::string::npos) {
4908 return nullptr;
4909 }
4910 // Separate the scope and member name
4911 pos = scopename.rfind(':');
4912 if (pos != std::string::npos) {
4913 if ((pos != 0) && (scopename[pos-1] == ':')) {
4914 dataname = scopename.substr(pos+1);
4915 scopename.erase(pos-1);
4916 }
4917 } else {
4918 scopename.clear();
4919 dataname = scopename;
4920 }
4921 }
4922 //fprintf(stderr, "name: '%s'\n", name.c_str());
4923 // Now we have the class or namespace name, so do the lookup.
4924
4925
4926 DeclId_t d;
4927 if (scopename.size()) {
4928 TClingClassInfo cl(GetInterpreterImpl(), scopename.c_str());
4929 d = cl.GetDataMember(dataname.c_str());
4930 }
4931 else {
4933 d = gcl.GetDataMember(dataname.c_str());
4934 }
4935 return d;
4936}
4937
4938////////////////////////////////////////////////////////////////////////////////
4939/// NOT IMPLEMENTED.
4940
4942{
4943 Error("GetDataMemberWithValue()", "not implemented");
4944 return nullptr;
4945}
4946
4947////////////////////////////////////////////////////////////////////////////////
4948/// Return pointer to cling DeclId for a data member with a given name.
4949
4951{
4952 // NOT IMPLEMENTED.
4953 Error("GetDataMemberAtAddr()", "not implemented");
4954 return nullptr;
4955}
4956
4957////////////////////////////////////////////////////////////////////////////////
4958/// Return the cling mangled name for a method of a class with parameters
4959/// params (params is a string of actual arguments, not formal ones). If the
4960/// class is 0 the global function list will be searched.
4961
4962TString TCling::GetMangledName(TClass* cl, const char* method,
4963 const char* params, Bool_t objectIsConst /* = kFALSE */)
4964{
4967 if (cl) {
4969 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4970 &offset);
4971 }
4972 else {
4975 func.SetFunc(&gcl, method, params, &offset);
4976 }
4978 if (!mi) return "";
4979 TString mangled_name( mi->GetMangledName() );
4980 delete mi;
4981 return mangled_name;
4982}
4983
4984////////////////////////////////////////////////////////////////////////////////
4985/// Return the cling mangled name for a method of a class with a certain
4986/// prototype, i.e. "char*,int,float". If the class is 0 the global function
4987/// list will be searched.
4988
4990 const char* proto, Bool_t objectIsConst /* = kFALSE */,
4991 EFunctionMatchMode mode /* = kConversionMatch */)
4992{
4994 if (cl) {
4995 return ((TClingClassInfo*)cl->GetClassInfo())->
4996 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
4997 }
4999 return gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
5000}
5001
5002////////////////////////////////////////////////////////////////////////////////
5003/// Return pointer to cling interface function for a method of a class with
5004/// parameters params (params is a string of actual arguments, not formal
5005/// ones). If the class is 0 the global function list will be searched.
5006
5007void* TCling::GetInterfaceMethod(TClass* cl, const char* method,
5008 const char* params, Bool_t objectIsConst /* = kFALSE */)
5009{
5012 if (cl) {
5014 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
5015 &offset);
5016 }
5017 else {
5020 func.SetFunc(&gcl, method, params, &offset);
5021 }
5022 return (void*) func.InterfaceMethod();
5023}
5024
5025////////////////////////////////////////////////////////////////////////////////
5026/// Return pointer to cling interface function for a method of a class with
5027/// a certain name.
5028
5029TInterpreter::DeclId_t TCling::GetFunction(ClassInfo_t *opaque_cl, const char* method)
5030{
5032 DeclId_t f;
5033 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5034 if (cl) {
5035 f = cl->GetMethod(method).GetDeclId();
5036 }
5037 else {
5039 f = gcl.GetMethod(method).GetDeclId();
5040 }
5041 return f;
5042
5043}
5044
5045////////////////////////////////////////////////////////////////////////////////
5046/// Insert overloads of name in cl to res.
5047
5048void TCling::GetFunctionOverloads(ClassInfo_t *cl, const char *funcname,
5049 std::vector<DeclId_t>& res) const
5050{
5051 clang::Sema& S = fInterpreter->getSema();
5052 clang::ASTContext& Ctx = S.Context;
5053 const clang::Decl* CtxDecl
5054 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
5055 Ctx.getTranslationUnitDecl();
5056 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
5057 const clang::DeclContext* DeclCtx = RecDecl;
5058
5059 if (!DeclCtx)
5060 DeclCtx = dyn_cast<clang::NamespaceDecl>(CtxDecl);
5061 if (!DeclCtx) return;
5062
5063 clang::DeclarationName DName;
5064 // The DeclarationName is funcname, unless it's a ctor or dtor.
5065 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
5066
5067 if (RecDecl) {
5068 if (RecDecl->getNameAsString() == funcname) {
5069 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5070 DName = Ctx.DeclarationNames.getCXXConstructorName(Ctx.getCanonicalType(QT));
5071 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
5072 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5073 DName = Ctx.DeclarationNames.getCXXDestructorName(Ctx.getCanonicalType(QT));
5074 } else {
5075 DName = &Ctx.Idents.get(funcname);
5076 }
5077 } else {
5078 DName = &Ctx.Idents.get(funcname);
5079 }
5080
5081 // NotForRedeclaration: we want to find names in inline namespaces etc.
5082 clang::LookupResult R(S, DName, clang::SourceLocation(),
5083 Sema::LookupOrdinaryName, clang::Sema::NotForRedeclaration);
5084 R.suppressDiagnostics(); // else lookup with NotForRedeclaration will check access etc
5085 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
5086 if (R.empty()) return;
5087 R.resolveKind();
5088 res.reserve(res.size() + (R.end() - R.begin()));
5089 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
5090 IR != ER; ++IR) {
5091 if (const clang::FunctionDecl* FD
5092 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
5093 if (!FD->getDescribedFunctionTemplate()) {
5094 res.push_back(FD);
5095 }
5096 } else if (const auto *USD = llvm::dyn_cast<const clang::UsingShadowDecl>(*IR)) {
5097 // FIXME: multi-level using
5098 if (llvm::isa<clang::FunctionDecl>(USD->getTargetDecl())) {
5099 res.push_back(USD);
5100 }
5101 }
5102 }
5103}
5104
5105////////////////////////////////////////////////////////////////////////////////
5106/// Return pointer to cling interface function for a method of a class with
5107/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5108/// function list will be searched.
5109
5111 const char* proto,
5112 Bool_t objectIsConst /* = kFALSE */,
5113 EFunctionMatchMode mode /* = kConversionMatch */)
5114{
5116 void* f;
5117 if (cl) {
5118 f = ((TClingClassInfo*)cl->GetClassInfo())->
5119 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5120 }
5121 else {
5123 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5124 }
5125 return f;
5126}
5127
5128////////////////////////////////////////////////////////////////////////////////
5129/// Return pointer to cling DeclId for a method of a class with
5130/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5131/// function list will be searched.
5132
5133TInterpreter::DeclId_t TCling::GetFunctionWithValues(ClassInfo_t *opaque_cl, const char* method,
5134 const char* params,
5135 Bool_t objectIsConst /* = kFALSE */)
5136{
5138 DeclId_t f;
5139 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5140 if (cl) {
5141 f = cl->GetMethodWithArgs(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5142 }
5143 else {
5145 f = gcl.GetMethod(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5146 }
5147 return f;
5148}
5149
5150////////////////////////////////////////////////////////////////////////////////
5151/// Return pointer to cling interface function for a method of a class with
5152/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5153/// function list will be searched.
5154
5155TInterpreter::DeclId_t TCling::GetFunctionWithPrototype(ClassInfo_t *opaque_cl, const char* method,
5156 const char* proto,
5157 Bool_t objectIsConst /* = kFALSE */,
5158 EFunctionMatchMode mode /* = kConversionMatch */)
5159{
5161 DeclId_t f;
5162 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5163 if (cl) {
5164 f = cl->GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5165 }
5166 else {
5168 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5169 }
5170 return f;
5171}
5172
5173////////////////////////////////////////////////////////////////////////////////
5174/// Return pointer to cling interface function for a method of a class with
5175/// a certain name.
5176
5177TInterpreter::DeclId_t TCling::GetFunctionTemplate(ClassInfo_t *opaque_cl, const char* name)
5178{
5180 DeclId_t f;
5181 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5182 if (cl) {
5183 f = cl->GetFunctionTemplate(name);
5184 }
5185 else {
5187 f = gcl.GetFunctionTemplate(name);
5188 }
5189 return f;
5190
5191}
5192
5193////////////////////////////////////////////////////////////////////////////////
5194/// The 'name' is known to the interpreter, this function returns
5195/// the internal version of this name (usually just resolving typedefs)
5196/// This is used in particular to synchronize between the name used
5197/// by rootcling and by the run-time environment (TClass)
5198/// Return 0 if the name is not known.
5199
5200void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
5201{
5202 output.clear();
5203
5205
5207 if (!cl.IsValid()) {
5208 return ;
5209 }
5210 if (full) {
5212 return;
5213 }
5214 // Well well well, for backward compatibility we need to act a bit too
5215 // much like CINT.
5218
5219 return;
5220}
5221
5222////////////////////////////////////////////////////////////////////////////////
5223/// Execute a global function with arguments params.
5224///
5225/// FIXME: The cint-based version of this code does not check if the
5226/// SetFunc() call works, and does not do any real checking
5227/// for errors from the Exec() call. It did fetch the most
5228/// recent cint security error and return that in error, but
5229/// this does not really translate well to cling/clang. We
5230/// should enhance these interfaces so that we can report
5231/// compilation and runtime errors properly.
5232
5233void TCling::Execute(const char* function, const char* params, int* error)
5234{
5236 if (error) {
5237 *error = TInterpreter::kNoError;
5238 }
5240 Longptr_t offset = 0L;
5242 func.SetFunc(&cl, function, params, &offset);
5243 func.Exec(nullptr);
5244}
5245
5246////////////////////////////////////////////////////////////////////////////////
5247/// Execute a method from class cl with arguments params.
5248///
5249/// FIXME: The cint-based version of this code does not check if the
5250/// SetFunc() call works, and does not do any real checking
5251/// for errors from the Exec() call. It did fetch the most
5252/// recent cint security error and return that in error, but
5253/// this does not really translate well to cling/clang. We
5254/// should enhance these interfaces so that we can report
5255/// compilation and runtime errors properly.
5256
5257void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5258 const char* params, Bool_t objectIsConst, int* error)
5259{
5261 if (error) {
5262 *error = TInterpreter::kNoError;
5263 }
5264 // If the actual class of this object inherits 2nd (or more) from TObject,
5265 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5266 // hence gInterpreter->Execute will improperly correct the offset.
5267 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5268 Longptr_t offset = 0L;
5270 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst, &offset);
5271 void* address = (void*)((Longptr_t)addr + offset);
5272 func.Exec(address);
5273}
5274
5275////////////////////////////////////////////////////////////////////////////////
5276
5277void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5278 const char* params, int* error)
5279{
5280 Execute(obj,cl,method,params,false,error);
5281}
5282
5283////////////////////////////////////////////////////////////////////////////////
5284/// Execute a method from class cl with the arguments in array params
5285/// (params[0] ... params[n] = array of TObjString parameters).
5286/// Convert the TObjArray array of TObjString parameters to a character
5287/// string of comma separated parameters.
5288/// The parameters of type 'char' are enclosed in double quotes and all
5289/// internal quotes are escaped.
5290
5291void TCling::Execute(TObject* obj, TClass* cl, TMethod* method,
5292 TObjArray* params, int* error)
5293{
5294 if (!method) {
5295 Error("Execute", "No method was defined");
5296 return;
5297 }
5298 TList* argList = method->GetListOfMethodArgs();
5299 // Check number of actual parameters against of expected formal ones
5300
5301 Int_t nparms = argList->LastIndex() + 1;
5302 Int_t argc = params ? params->GetEntries() : 0;
5303
5304 if (argc > nparms) {
5305 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
5306 return;
5307 }
5308 if (nparms != argc) {
5309 // Let's see if the 'missing' argument are all defaulted.
5310 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
5311 assert(nparms > 0);
5312
5313 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
5314 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5315 // There is a default value for the first missing
5316 // argument, so we are fine.
5317 } else {
5318 Int_t firstDefault = -1;
5319 for (Int_t i = 0; i < nparms; i ++) {
5320 arg = (TMethodArg *) argList->At( i );
5321 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5322 firstDefault = i;
5323 break;
5324 }
5325 }
5326 if (firstDefault >= 0) {
5327 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);
5328 } else {
5329 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
5330 }
5331 return;
5332 }
5333 }
5334
5335 const char* listpar = "";
5336 TString complete(10);
5337 if (params) {
5338 // Create a character string of parameters from TObjArray
5339 TIter next(params);
5340 for (Int_t i = 0; i < argc; i ++) {
5341 TMethodArg* arg = (TMethodArg*) argList->At(i);
5343 TObjString* nxtpar = (TObjString*) next();
5344 if (i) {
5345 complete += ',';
5346 }
5347 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
5348 TString chpar('\"');
5349 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
5350 // At this point we have to check if string contains \\"
5351 // and apply some more sophisticated parser. Not implemented yet!
5352 complete += chpar;
5353 complete += '\"';
5354 }
5355 else {
5356 complete += nxtpar->String();
5357 }
5358 }
5359 listpar = complete.Data();
5360 }
5361
5362 // And now execute it.
5364 if (error) {
5365 *error = TInterpreter::kNoError;
5366 }
5367 // If the actual class of this object inherits 2nd (or more) from TObject,
5368 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5369 // hence gInterpreter->Execute will improperly correct the offset.
5370 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5372 TClingMethodInfo *minfo = (TClingMethodInfo*)method->fInfo;
5373 func.Init(*minfo);
5374 func.SetArgs(listpar);
5375 // Now calculate the 'this' pointer offset for the method
5376 // when starting from the class described by cl.
5377 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetTargetFunctionDecl());
5378 Longptr_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
5379 void* address = (void*)((Longptr_t)addr + offset);
5380 func.Exec(address);
5381}
5382
5383////////////////////////////////////////////////////////////////////////////////
5384
5385void TCling::ExecuteWithArgsAndReturn(TMethod* method, void* address,
5386 const void* args[] /*=0*/,
5387 int nargs /*=0*/,
5388 void* ret/*= 0*/) const
5389{
5390 if (!method) {
5391 Error("ExecuteWithArgsAndReturn", "No method was defined");
5392 return;
5393 }
5394
5395 TClingMethodInfo* minfo = (TClingMethodInfo*) method->fInfo;
5396 TClingCallFunc func(*minfo);
5397 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5398}
5399
5400////////////////////////////////////////////////////////////////////////////////
5401/// Execute a cling macro.
5402
5404{
5406 fCurExecutingMacros.push_back(filename);
5408 fCurExecutingMacros.pop_back();
5409 return result;
5410}
5411
5412////////////////////////////////////////////////////////////////////////////////
5413/// Return the file name of the current un-included interpreted file.
5414/// See the documentation for GetCurrentMacroName().
5415
5417{
5418 Warning("GetTopLevelMacroName", "Must change return type!");
5419 return fCurExecutingMacros.back();
5420}
5421
5422////////////////////////////////////////////////////////////////////////////////
5423/// Return the file name of the currently interpreted file,
5424/// included or not. Example to illustrate the difference between
5425/// GetCurrentMacroName() and GetTopLevelMacroName():
5426/// ~~~ {.cpp}
5427/// void inclfile() {
5428/// std::cout << "In inclfile.C" << std::endl;
5429/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5430/// TCling::GetCurrentMacroName() << std::endl;
5431/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5432/// TCling::GetTopLevelMacroName() << std::endl;
5433/// }
5434/// ~~~
5435/// ~~~ {.cpp}
5436/// void mymacro() {
5437/// std::cout << "In mymacro.C" << std::endl;
5438/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5439/// TCling::GetCurrentMacroName() << std::endl;
5440/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5441/// TCling::GetTopLevelMacroName() << std::endl;
5442/// std::cout << " Now calling inclfile..." << std::endl;
5443/// gInterpreter->ProcessLine(".x inclfile.C");
5444/// }
5445/// ~~~
5446/// Running mymacro.C will print:
5447///
5448/// ~~~ {.cpp}
5449/// root [0] .x mymacro.C
5450/// ~~~
5451/// In mymacro.C
5452/// ~~~ {.cpp}
5453/// TCling::GetCurrentMacroName() returns ./mymacro.C
5454/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5455/// ~~~
5456/// Now calling inclfile...
5457/// In inclfile.h
5458/// ~~~ {.cpp}
5459/// TCling::GetCurrentMacroName() returns inclfile.C
5460/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5461/// ~~~
5462
5464{
5465#if defined(R__MUST_REVISIT)
5466#if R__MUST_REVISIT(6,0)
5467 Warning("GetCurrentMacroName", "Must change return type!");
5468#endif
5469#endif
5470 return fCurExecutingMacros.back();
5471}
5472
5473////////////////////////////////////////////////////////////////////////////////
5474/// Return the absolute type of typeDesc.
5475/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
5476/// You need to use the result immediately before it is being overwritten.
5477
5478const char* TCling::TypeName(const char* typeDesc)
5479{
5480 TTHREAD_TLS_DECL(std::string,t);
5481
5482 if (!strstr(typeDesc, "(*)(")) {
5483 const char *s = strchr(typeDesc, ' ');
5484 const char *template_start = strchr(typeDesc, '<');
5485 if (!strcmp(typeDesc, "long long")) {
5486 t = typeDesc;
5487 }
5488 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5489 t = typeDesc;
5490 }
5491 // s is the position of the second 'word' (if any)
5492 // except in the case of templates where there will be a space
5493 // just before any closing '>': eg.
5494 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5495 else if (s && (template_start == nullptr || (s < template_start))) {
5496 t = s + 1;
5497 }
5498 else {
5499 t = typeDesc;
5500 }
5501 }
5502 else {
5503 t = typeDesc;
5504 }
5505 auto l = t.length();
5506 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&'))
5507 --l;
5508 t.resize(l);
5509 return t.c_str(); // NOLINT
5510}
5511
5512static bool requiresRootMap(const char* rootmapfile)
5513{
5514 assert(rootmapfile && *rootmapfile);
5515
5516 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5517 libName.consume_back(".rootmap");
5518
5519 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5520}
5521
5522////////////////////////////////////////////////////////////////////////////////
5523/// Read and parse a rootmapfile in its new format, and return 0 in case of
5524/// success, -1 if the file has already been read, and -3 in case its format
5525/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5526/// error.
5527
5528int TCling::ReadRootmapFile(const char *rootmapfile, TUniqueString *uniqueString)
5529{
5530 if (!(rootmapfile && *rootmapfile))
5531 return 0;
5532
5533 if (!requiresRootMap(rootmapfile))
5534 return 0; // success
5535
5536 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5537 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5538
5539 std::string rootmapfileNoBackslash(rootmapfile);
5540#ifdef _MSC_VER
5541 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5542#endif
5543 // Add content of a specific rootmap file
5544 if (fRootmapFiles->FindObject(rootmapfileNoBackslash.c_str()))
5545 return -1;
5546
5547 // Line 1 is `{ decls }`
5548 std::string lineDirective = std::string("\n#line 2 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n";
5549
5550 std::ifstream file(rootmapfileNoBackslash);
5551 std::string line;
5552 line.reserve(200);
5553 std::string lib_name;
5554 line.reserve(100);
5555 bool newFormat = false;
5556 while (getline(file, line, '\n')) {
5557 if (!newFormat && (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5558 file.close();
5559 return -3; // old format
5560 }
5561 newFormat = true;
5562
5563 if (line.compare(0, 9, "{ decls }") == 0) {
5564 // forward declarations
5565
5566 while (getline(file, line, '\n')) {
5567 if (line[0] == '[')
5568 break;
5569 if (!uniqueString) {
5570 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5571 rootmapfileNoBackslash.c_str());
5572 return -4;
5573 }
5574 if (!lineDirective.empty())
5575 uniqueString->Append(lineDirective);
5576 uniqueString->Append(line + '\n');
5577 }
5578 }
5579 const char firstChar = line[0];
5580 if (firstChar == '[') {
5581 // new section (library)
5582 auto brpos = line.find(']');
5583 if (brpos == string::npos)
5584 continue;
5585 lib_name = line.substr(1, brpos - 1);
5586 // Remove spaces at the beginning and at the end of the library name
5587 lib_name.erase(lib_name.find_last_not_of(' ') + 1);
5588 lib_name.erase(0, lib_name.find_first_not_of(' '));
5589 if (gDebug > 3) {
5590 TString lib_nameTstr(lib_name.c_str());
5591 TObjArray *tokens = lib_nameTstr.Tokenize(" ");
5592 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5593 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5594 if (wlib) {
5595 Info("ReadRootmapFile", "%s: New section for %s", rootmapfile, lib_nameTstr.Data());
5596 } else {
5597 Info("ReadRootmapFile", "%s: Section for %s (library does not exist)", rootmapfile, lib_nameTstr.Data());
5598 }
5599 delete[] wlib;
5600 delete tokens;
5601 }
5602 } else {
5603 auto keyLenIt = keyLenMap.find(firstChar);
5604 if (keyLenIt == keyLenMap.end())
5605 continue;
5606 unsigned int keyLen = keyLenIt->second;
5607 // Do not make a copy, just start after the key
5608 const char *keyname = line.c_str() + keyLen;
5609 if (gDebug > 6)
5610 Info("ReadRootmapFile", "%s: class %s in %s", rootmapfile, keyname, lib_name.c_str());
5611 TEnvRec *isThere = fMapfile->Lookup(keyname);
5612 if (isThere) {
5613 if (lib_name != isThere->GetValue()) { // the same key for two different libs
5614 if (firstChar == 'n') {
5615 if (gDebug > 3)
5616 Info("ReadRootmapFile",
5617 "While processing %s, namespace %s was found to be associated to %s although it is already "
5618 "associated to %s",
5619 rootmapfile, keyname, lib_name.c_str(), isThere->GetValue());
5620 } else if (firstChar == 'h') { // it is a header: add the libname to the list of libs to be loaded.
5621 lib_name += " ";
5622 lib_name += isThere->GetValue();
5623 fMapfile->SetValue(keyname, lib_name.c_str());
5624 } else if (!TClassEdit::IsSTLCont(keyname)) {
5625 Warning("ReadRootmapFile",
5626 "While processing %s, %s %s was found to be associated to %s although it is already "
5627 "associated to %s",
5628 rootmapfile, line.substr(0, keyLen - 1).c_str(), keyname, lib_name.c_str(),
5629 isThere->GetValue());
5630 }
5631 } else { // the same key for the same lib
5632 if (gDebug > 3)
5633 Info("ReadRootmapFile", "While processing %s, key %s was found to be already defined for %s",
5634 rootmapfile, keyname, lib_name.c_str());
5635 }
5636 } else {
5637 fMapfile->SetValue(keyname, lib_name.c_str());
5638 }
5639 }
5640 }
5641 file.close();
5642 return 0;
5643}
5644
5645////////////////////////////////////////////////////////////////////////////////
5646/// Create a resource table and read the (possibly) three resource files,
5647/// i.e. `$ROOTSYS/etc/system<name>` (or `ROOTETCDIR/system<name>`), `$HOME/<name>`
5648/// and `$PWD/<name>`. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You
5649/// can read additional user defined resource files by creating additional TEnv
5650/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5651/// the `$HOME/<name>` resource file will be skipped. This might be useful in
5652/// case the home directory resides on an automounted remote file system
5653/// and one wants to avoid the file system from being mounted.
5654
5656{
5657 assert(requiresRootMap(name) && "We have a module!");
5658
5659 if (!requiresRootMap(name))
5660 return;
5661
5663
5665
5666 TString sname = "system";
5667 sname += name;
5668 char *s = gSystem->ConcatFileName(TROOT::GetEtcDir(), sname);
5669
5670 Int_t ret = ReadRootmapFile(s);
5671 if (ret == -3) // old format
5673 delete [] s;
5674 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5676 ret = ReadRootmapFile(s);
5677 if (ret == -3) // old format
5679 delete [] s;
5680 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
5681 ret = ReadRootmapFile(name);
5682 if (ret == -3) // old format
5684 }
5685 } else {
5686 ret = ReadRootmapFile(name);
5687 if (ret == -3) // old format
5689 }
5690 fMapfile->IgnoreDuplicates(ignore);
5691}
5692
5693
5694namespace {
5695 using namespace clang;
5696
5697 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5698 // This class is to be considered an helper for AutoLoading.
5699 // It is a recursive visitor is used to inspect namespaces and specializations
5700 // coming from forward declarations in rootmaps and to set the external visible
5701 // storage flag for them.
5702 public:
5703 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5704 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5705 // We want to enable the external lookup for this namespace
5706 // because it may shadow the lookup of other names contained
5707 // in that namespace
5708
5709 nsDecl->setHasExternalVisibleStorage();
5710 fNSSet.insert(nsDecl);
5711 return true;
5712 }
5713 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl* specDecl) {
5714 // We want to enable the external lookup for this specialization
5715 // because we can provide a definition for it!
5716 if (specDecl->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
5717 //SpecSet.insert(specDecl);
5718 specDecl->setHasExternalLexicalStorage();
5719
5720 // No need to recurse. On the contrary, recursing is actively harmful:
5721 // NOTE: must not recurse to prevent this visitor from triggering loading from
5722 // the external AST source (i.e. autoloading). This would be triggered right here,
5723 // before autoloading is even set up, as rootmap file parsing happens before that.
5724 // Even if autoloading is off and has no effect, triggering loading from external
5725 // AST source resets the flag setHasExternalLexicalStorage(), hiding this specialization
5726 // from subsequent autoloads!
5727 return false;
5728 }
5729 private:
5730 std::unordered_set<const NamespaceDecl*>& fNSSet;
5731 };
5732}
5733
5734////////////////////////////////////////////////////////////////////////////////
5735/// Load map between class and library. If rootmapfile is specified a
5736/// specific rootmap file can be added (typically used by ACLiC).
5737/// In case of error -1 is returned, 0 otherwise.
5738/// The interpreter uses this information to automatically load the shared
5739/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5740
5741Int_t TCling::LoadLibraryMap(const char* rootmapfile)
5742{
5743 if (rootmapfile && *rootmapfile && !requiresRootMap(rootmapfile))
5744 return 0;
5745
5747
5748 // open the [system].rootmap files
5749 if (!fMapfile) {
5750 fMapfile = new TEnv();
5754 InitRootmapFile(".rootmap");
5755 }
5756
5757 // Prepare a list of all forward declarations for cling
5758 // For some experiments it is easily as big as 500k characters. To be on the
5759 // safe side, we go for 1M.
5760 TUniqueString uniqueString(1048576);
5761
5762 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5763 // A rootmap file must end with the string ".rootmap".
5764 TString ldpath = gSystem->GetDynamicPath();
5765 if (ldpath != fRootmapLoadPath) {
5766 fRootmapLoadPath = ldpath;
5767#ifdef WIN32
5768 TObjArray* paths = ldpath.Tokenize(";");
5769#else
5770 TObjArray* paths = ldpath.Tokenize(":");
5771#endif
5772 TString d;
5773 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5774 d = ((TObjString *)paths->At(i))->GetString();
5775 // check if directory already scanned
5776 Int_t skip = 0;
5777 for (Int_t j = 0; j < i; j++) {
5778 TString pd = ((TObjString *)paths->At(j))->GetString();
5779 if (pd == d) {
5780 skip++;
5781 break;
5782 }
5783 }
5784 if (!skip) {
5785 void* dirp = gSystem->OpenDirectory(d);
5786 if (dirp) {
5787 if (gDebug > 3) {
5788 Info("LoadLibraryMap", "%s", d.Data());
5789 }
5790 const char* f1;
5791 while ((f1 = gSystem->GetDirEntry(dirp))) {
5792 TString f = f1;
5793 if (f.EndsWith(".rootmap")) {
5794 TString p;
5795 p = d + "/" + f;
5797 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
5798 if (gDebug > 4) {
5799 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
5800 }
5801 Int_t ret = ReadRootmapFile(p, &uniqueString);
5802
5803 if (ret == 0)
5804 fRootmapFiles->Add(new TNamed(gSystem->BaseName(f), p.Data()));
5805 if (ret == -3) {
5806 // old format
5808 fRootmapFiles->Add(new TNamed(f, p));
5809 }
5810 }
5811 // else {
5812 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
5813 // fRootmapFiles->FindObject(f)->ls();
5814 // }
5815 }
5816 }
5817 if (f.BeginsWith("rootmap")) {
5818 TString p;
5819 p = d + "/" + f;
5820 FileStat_t stat;
5821 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
5822 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
5823 }
5824 }
5825 }
5826 }
5827 gSystem->FreeDirectory(dirp);
5828 }
5829 }
5830 delete paths;
5831 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
5832 return -1;
5833 }
5834 }
5835 if (rootmapfile && *rootmapfile) {
5836 Int_t res = ReadRootmapFile(rootmapfile, &uniqueString);
5837 if (res == 0) {
5838 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
5839 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
5840 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5841 }
5842 else if (res == -3) {
5843 // old format
5845 fMapfile->ReadFile(rootmapfile, kEnvGlobal);
5846 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5847 fMapfile->IgnoreDuplicates(ignore);
5848 }
5849 }
5850 TEnvRec* rec;
5851 TIter next(fMapfile->GetTable());
5852 while ((rec = (TEnvRec*) next())) {
5853 TString cls = rec->GetName();
5854 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5855 // get the first lib from the list of lib and dependent libs
5856 TString libs = rec->GetValue();
5857 if (libs == "") {
5858 continue;
5859 }
5860 TString delim(" ");
5861 TObjArray* tokens = libs.Tokenize(delim);
5862 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5863 // convert "@@" to "::", we used "@@" because TEnv
5864 // considers "::" a terminator
5865 cls.Remove(0, 8);
5866 cls.ReplaceAll("@@", "::");
5867 // convert "-" to " ", since class names may have
5868 // blanks and TEnv considers a blank a terminator
5869 cls.ReplaceAll("-", " ");
5870 if (gDebug > 6) {
5871 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
5872 if (wlib) {
5873 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
5874 }
5875 else {
5876 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
5877 }
5878 delete[] wlib;
5879 }
5880 delete tokens;
5881 }
5882 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
5883 cls.Remove(0, 8);
5884 // convert "-" to " ", since class names may have
5885 // blanks and TEnv considers a blank a terminator
5886 cls.ReplaceAll("-", " ");
5887 fInterpreter->declare(cls.Data());
5888 }
5889 }
5890
5891 // Process the forward declarations collected
5892 cling::Transaction* T = nullptr;
5893 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
5894 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
5895
5896 if (compRes!=cling::Interpreter::kSuccess){
5897 Warning("LoadLibraryMap",
5898 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
5899 }
5900
5901 if (T) {
5902 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
5903 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
5904 if (declIt->m_DGR.isSingleDecl()) {
5905 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
5906 if (clang::isa<TagDecl>(D) || clang::isa<NamespaceDecl>(D)) {
5907 evsAdder.TraverseDecl(D);
5908 }
5909 }
5910 }
5911 }
5912 }
5913
5914 // clear duplicates
5915
5916 return 0;
5917}
5918
5919////////////////////////////////////////////////////////////////////////////////
5920/// Scan again along the dynamic path for library maps. Entries for the loaded
5921/// shared libraries are unloaded first. This can be useful after reseting
5922/// the dynamic path through TSystem::SetDynamicPath()
5923/// In case of error -1 is returned, 0 otherwise.
5924
5926{
5929 return 0;
5930}
5931
5932////////////////////////////////////////////////////////////////////////////////
5933/// Reload the library map entries coming from all the loaded shared libraries,
5934/// after first unloading the current ones.
5935/// In case of error -1 is returned, 0 otherwise.
5936
5938{
5939 const TString sharedLibLStr = GetSharedLibs();
5940 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5941 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
5942 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
5943 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5944 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5945 const Int_t ret = UnloadLibraryMap(sharedLibBaseStr);
5946 if (ret < 0) {
5947 continue;
5948 }
5949 TString rootMapBaseStr = sharedLibBaseStr;
5950 if (sharedLibBaseStr.EndsWith(".dll")) {
5951 rootMapBaseStr.ReplaceAll(".dll", "");
5952 }
5953 else if (sharedLibBaseStr.EndsWith(".DLL")) {
5954 rootMapBaseStr.ReplaceAll(".DLL", "");
5955 }
5956 else if (sharedLibBaseStr.EndsWith(".so")) {
5957 rootMapBaseStr.ReplaceAll(".so", "");
5958 }
5959 else if (sharedLibBaseStr.EndsWith(".sl")) {
5960 rootMapBaseStr.ReplaceAll(".sl", "");
5961 }
5962 else if (sharedLibBaseStr.EndsWith(".dl")) {
5963 rootMapBaseStr.ReplaceAll(".dl", "");
5964 }
5965 else if (sharedLibBaseStr.EndsWith(".a")) {
5966 rootMapBaseStr.ReplaceAll(".a", "");
5967 }
5968 else {
5969 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
5970 delete sharedLibL;
5971 return -1;
5972 }
5973 rootMapBaseStr += ".rootmap";
5974 const char* rootMap = gSystem->Which(gSystem->GetDynamicPath(), rootMapBaseStr);
5975 if (!rootMap) {
5976 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
5977 delete[] rootMap;
5978 delete sharedLibL;
5979 return -1;
5980 }
5981 const Int_t status = LoadLibraryMap(rootMap);
5982 if (status < 0) {
5983 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
5984 delete[] rootMap;
5985 delete sharedLibL;
5986 return -1;
5987 }
5988 delete[] rootMap;
5989 }
5990 delete sharedLibL;
5991 return 0;
5992}
5993
5994////////////////////////////////////////////////////////////////////////////////
5995/// Unload the library map entries coming from all the loaded shared libraries.
5996/// Returns 0 if succesful
5997
5999{
6000 const TString sharedLibLStr = GetSharedLibs();
6001 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
6002 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
6003 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
6004 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
6005 UnloadLibraryMap(sharedLibBaseStr);
6006 }
6007 delete sharedLibL;
6008 return 0;
6009}
6010
6011////////////////////////////////////////////////////////////////////////////////
6012/// Unload library map entries coming from the specified library.
6013/// Returns -1 in case no entries for the specified library were found,
6014/// 0 otherwise.
6015
6017{
6018 if (!fMapfile || !library || !*library) {
6019 return 0;
6020 }
6021 TString libname(library);
6022 Ssiz_t idx = libname.Last('.');
6023 if (idx != kNPOS) {
6024 libname.Remove(idx);
6025 }
6026 size_t len = libname.Length();
6027 TEnvRec *rec;
6028 TIter next(fMapfile->GetTable());
6030 Int_t ret = 0;
6031 while ((rec = (TEnvRec *) next())) {
6032 TString cls = rec->GetName();
6033 if (cls.Length() > 2) {
6034 // get the first lib from the list of lib and dependent libs
6035 TString libs = rec->GetValue();
6036 if (libs == "") {
6037 continue;
6038 }
6039 TString delim(" ");
6040 TObjArray* tokens = libs.Tokenize(delim);
6041 const char* lib = ((TObjString *)tokens->At(0))->GetName();
6042 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
6043 // convert "@@" to "::", we used "@@" because TEnv
6044 // considers "::" a terminator
6045 cls.Remove(0, 8);
6046 cls.ReplaceAll("@@", "::");
6047 // convert "-" to " ", since class names may have
6048 // blanks and TEnv considers a blank a terminator
6049 cls.ReplaceAll("-", " ");
6050 }
6051 if (!strncmp(lib, libname.Data(), len)) {
6052 if (fMapfile->GetTable()->Remove(rec) == nullptr) {
6053 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
6054 ret = -1;
6055 }
6056 }
6057 delete tokens;
6058 }
6059 }
6060 if (ret >= 0) {
6061 TString library_rootmap(library);
6062 if (!library_rootmap.EndsWith(".rootmap"))
6063 library_rootmap.Append(".rootmap");
6064 TNamed* mfile = nullptr;
6065 while ((mfile = (TNamed *)fRootmapFiles->FindObject(library_rootmap))) {
6066 fRootmapFiles->Remove(mfile);
6067 delete mfile;
6068 }
6070 }
6071 return ret;
6072}
6073
6074////////////////////////////////////////////////////////////////////////////////
6075/// Register the AutoLoading information for a class.
6076/// libs is a space separated list of libraries.
6077
6078Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
6079{
6080 if (!cls || !*cls)
6081 return 0;
6082
6083 TString key = TString("Library.") + cls;
6084 // convert "::" to "@@", we used "@@" because TEnv
6085 // considers "::" a terminator
6086 key.ReplaceAll("::", "@@");
6087 // convert "-" to " ", since class names may have
6088 // blanks and TEnv considers a blank a terminator
6089 key.ReplaceAll(" ", "-");
6090
6092 if (!fMapfile) {
6093 fMapfile = new TEnv();
6095
6098
6099 InitRootmapFile(".rootmap");
6100 }
6101 //fMapfile->SetValue(key, libs);
6102 fMapfile->SetValue(cls, libs);
6103 return 1;
6104}
6105
6106////////////////////////////////////////////////////////////////////////////////
6107/// Demangle the name (from the typeinfo) and then request the class
6108/// via the usual name based interface (TClass::GetClass).
6109
6110TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
6111{
6112 int err = 0;
6113 char* demangled_name = TClassEdit::DemangleTypeIdName(typeinfo, err);
6114 if (err) return nullptr;
6115 TClass* theClass = TClass::GetClass(demangled_name, load, kTRUE);
6116 free(demangled_name);
6117 return theClass;
6118}
6119
6120////////////////////////////////////////////////////////////////////////////////
6121/// Load library containing the specified class. Returns 0 in case of error
6122/// and 1 in case if success.
6123
6124Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
6125{
6126 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6127
6128 int err = 0;
6129 char* demangled_name_c = TClassEdit::DemangleTypeIdName(typeinfo, err);
6130 if (err) {
6131 return 0;
6132 }
6133
6134 std::string demangled_name(demangled_name_c);
6135 free(demangled_name_c);
6136
6137 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
6138 // shortened name.
6140 splitname.ShortType(demangled_name, TClassEdit::kDropStlDefault | TClassEdit::kDropStd);
6141
6142 // No need to worry about typedef, they aren't any ... but there are
6143 // inlined namespaces ...
6144
6145 Int_t result = AutoLoad(demangled_name.c_str());
6146 if (result == 0) {
6147 demangled_name = TClassEdit::GetLong64_Name(demangled_name);
6148 result = AutoLoad(demangled_name.c_str(), knowDictNotLoaded);
6149 }
6150
6151 return result;
6152}
6153
6154////////////////////////////////////////////////////////////////////////////////
6155// Get the list of 'published'/'known' library for the class and load them.
6157{
6158 Int_t status = 0;
6159
6160 // lookup class to find list of dependent libraries
6161 TString deplibs = gCling->GetClassSharedLibs(cls);
6162 if (!deplibs.IsNull()) {
6163 TString delim(" ");
6164 TObjArray* tokens = deplibs.Tokenize(delim);
6165 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
6166 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
6167 if (gROOT->LoadClass(cls, deplib) == 0) {
6168 if (gDebug > 0) {
6169 gCling->Info("TCling::AutoLoad",
6170 "loaded dependent library %s for %s", deplib, cls);
6171 }
6172 }
6173 else {
6174 gCling->Error("TCling::AutoLoad",
6175 "failure loading dependent library %s for %s",
6176 deplib, cls);
6177 }
6178 }
6179 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6180 if (lib && lib[0]) {
6181 if (gROOT->LoadClass(cls, lib) == 0) {
6182 if (gDebug > 0) {
6183 gCling->Info("TCling::AutoLoad",
6184 "loaded library %s for %s", lib, cls);
6185 }
6186 status = 1;
6187 }
6188 else {
6189 gCling->Error("TCling::AutoLoad",
6190 "failure loading library %s for %s", lib, cls);
6191 }
6192 }
6193 delete tokens;
6194 }
6195
6196 return status;
6197}
6198
6199////////////////////////////////////////////////////////////////////////////////
6200// Iterate through the data member of the class (either through the TProtoClass
6201// or through Cling) and trigger, recursively, the loading the necessary libraries.
6202// \note `cls` is expected to be already normalized!
6203// \returns 1 on success.
6204Int_t TCling::DeepAutoLoadImpl(const char *cls, std::unordered_set<std::string> &visited,
6205 bool nameIsNormalized)
6206{
6207 // Try to insert; if insertion failed because the entry existed, DeepAutoLoadImpl()
6208 // has previously (within the same call to `AutoLoad()`) tried to load this class
6209 // and we are done, whether success or not, as it won't work better now than before,
6210 // because there is no additional information now compared to before.
6211 if (!visited.insert(std::string(cls)).second)
6212 return 1;
6213
6214 if (ShallowAutoLoadImpl(cls) == 0) {
6215 // If ShallowAutoLoadImpl() has an error, we have an error.
6216 return 0;
6217 }
6218
6219 // Now look through the TProtoClass to load the required library/dictionary
6220 if (TProtoClass *proto = nameIsNormalized ? TClassTable::GetProtoNorm(cls) : TClassTable::GetProto(cls)) {
6221 for (auto element : proto->GetData()) {
6222 if (element->IsBasic())
6223 continue;
6224 const char *subtypename = element->GetTypeName();
6225 if (!TClassTable::GetDictNorm(subtypename)) {
6226 // Failure to load a dictionary is not (quite) a failure load
6227 // the top-level library. If we return false here, then
6228 // we would end up in a situation where the library and thus
6229 // the dictionary is loaded for "cls" but the TClass is
6230 // not created and/or marked as unavailable (in case where
6231 // AutoLoad is called from TClass::GetClass).
6232 DeepAutoLoadImpl(subtypename, visited, true /*normalized*/);
6233 }
6234 }
6235 return 1;
6236 }
6237
6238 // We found no TProtoClass for cls.
6239 auto classinfo = gInterpreter->ClassInfo_Factory(cls);
6240 if (classinfo && gInterpreter->ClassInfo_IsValid(classinfo)
6241 && !(gInterpreter->ClassInfo_Property(classinfo) & kIsEnum))
6242 {
6243 DataMemberInfo_t *memberinfo = gInterpreter->DataMemberInfo_Factory(classinfo, TDictionary::EMemberSelection::kNoUsingDecls);
6244 while (gInterpreter->DataMemberInfo_Next(memberinfo)) {
6245 if (gInterpreter->DataMemberInfo_TypeProperty(memberinfo) & ::kIsFundamental)
6246 continue;
6247 auto membertypename = TClassEdit::GetLong64_Name(gInterpreter->TypeName(gInterpreter->DataMemberInfo_TypeTrueName(memberinfo)));
6248 if (!TClassTable::GetDictNorm(membertypename.c_str())) {
6249 // Failure to load a dictionary is not (quite) a failure load
6250 // the top-level library. See detailed comment in the TProtoClass
6251 // branch (above).
6252 (void)DeepAutoLoadImpl(membertypename.c_str(), visited, true /*normalized*/);
6253 }
6254 }
6255 gInterpreter->DataMemberInfo_Delete(memberinfo);
6256 }
6257 gInterpreter->ClassInfo_Delete(classinfo);
6258 return 1;
6259}
6260
6261////////////////////////////////////////////////////////////////////////////////
6262/// Load library containing the specified class. Returns 0 in case of error
6263/// and 1 in case if success.
6264
6265Int_t TCling::AutoLoad(const char *cls, Bool_t knowDictNotLoaded /* = kFALSE */)
6266{
6267 // Prevent update to IsClassAutoloading between our check and our actions.
6269
6270 // TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
6271 // rootcling (in *_rdict.pcm file generation) it is a no op.
6272 // FIXME: We should avoid calling autoload when we know we are not supposed
6273 // to and transform this check into an assert.
6275 // Never load any library from rootcling/genreflex.
6276 if (gDebug > 2) {
6277 Info("TCling::AutoLoad", "Explicitly disabled (the class name is %s)", cls);
6278 }
6279 return 0;
6280 }
6281
6282 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6283
6285
6286 if (!knowDictNotLoaded && gClassTable->GetDictNorm(cls)) {
6287 // The library is already loaded as the class's dictionary is known.
6288 // Return success.
6289 // Note: the name (cls) is expected to be normalized as it comes either
6290 // from a callbacks (that can/should calculate the normalized name from the
6291 // decl) or from TClass::GetClass (which does also calculate the normalized
6292 // name).
6293 return 1;
6294 }
6295
6296 if (gDebug > 2) {
6297 Info("TCling::AutoLoad",
6298 "Trying to autoload for %s", cls);
6299 }
6300
6301 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
6302 if (gDebug > 2) {
6303 Info("TCling::AutoLoad",
6304 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
6305 }
6306 return 0;
6307 }
6308 // Prevent the recursion when the library dictionary are loaded.
6309 SuspendAutoLoadingRAII autoLoadOff(this);
6310 // Try using externally provided callback first.
6311 if (fAutoLoadCallBack) {
6312 int success = (*(AutoLoadCallBack_t)fAutoLoadCallBack)(cls);
6313 if (success)
6314 return success;
6315 }
6316
6317 // During the 'Deep' part of the search we will call GetClassSharedLibsForModule
6318 // (when module are enabled) which might end up calling AutoParsing but
6319 // that should only be for the cases where the library has no generated pcm
6320 // and in that case a rootmap should be available.
6321 // This avoids a very costly operation (for generally no gain) but reduce the
6322 // quality of the search (i.e. bad in case of library with no pcm and no rootmap
6323 // file).
6324 TInterpreter::SuspendAutoParsing autoParseRaii(this);
6325 std::unordered_set<std::string> visited;
6326 return DeepAutoLoadImpl(cls, visited, false /*normalized*/);
6327}
6328
6329////////////////////////////////////////////////////////////////////////////////
6330/// Parse the payload or header.
6331
6332static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
6333 Bool_t header,
6334 cling::Interpreter *interpreter)
6335{
6336 std::string code = gNonInterpreterClassDef ;
6337 if (!header) {
6338 // This is the complete header file content and not the
6339 // name of a header.
6340 code += what;
6341
6342 } else {
6343 code += ("#include \"");
6344 code += what;
6345 code += "\"\n";
6346 }
6347 code += ("#ifdef __ROOTCLING__\n"
6348 "#undef __ROOTCLING__\n"
6349 + gInterpreterClassDef +
6350 "#endif");
6351
6352 cling::Interpreter::CompilationResult cr;
6353 {
6354 // scope within which diagnostics are de-activated
6355 // For now we disable diagnostics because we saw them already at
6356 // dictionary generation time. That won't be an issue with the PCMs.
6357
6358 Sema &SemaR = interpreter->getSema();
6359 ROOT::Internal::ParsingStateRAII parsingStateRAII(interpreter->getParser(), SemaR);
6360 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
6361
6362 #if defined(R__MUST_REVISIT)
6363 #if R__MUST_REVISIT(6,2)
6364 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
6365 #endif
6366 #endif
6367
6368 cr = interpreter->parseForModule(code);
6369 }
6370 return cr;
6371}
6372
6373////////////////////////////////////////////////////////////////////////////////
6374/// Helper routine for TCling::AutoParse implementing the actual call to the
6375/// parser and looping over template parameters (if
6376/// any) and when they don't have a registered header to autoparse,
6377/// recurse over their template parameters.
6378///
6379/// Returns the number of header parsed.
6380
6381UInt_t TCling::AutoParseImplRecurse(const char *cls, bool topLevel)
6382{
6383 // We assume the lock has already been taken.
6384 // R__LOCKGUARD(gInterpreterMutex);
6385
6386 Int_t nHheadersParsed = 0;
6387 unsigned long offset = 0;
6388 if (strncmp(cls, "const ", 6) == 0) {
6389 offset = 6;
6390 }
6391
6392 // Loop on the possible autoparse keys
6393 bool skipFirstEntry = false;
6394 std::vector<std::string> autoparseKeys;
6395 if (strchr(cls, '<')) {
6396 int nestedLoc = 0;
6397 TClassEdit::GetSplit(cls + offset, autoparseKeys, nestedLoc, TClassEdit::kDropTrailStar);
6398 // Check if we can skip the name of the template in the autoparses
6399 // Take all the scopes one by one. If all of them are in the AST, we do not
6400 // need to autoparse for that particular template.
6401 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
6402 // autoparseKeys[0] is empty when the input is not a template instance.
6403 // The case strchr(cls, '<') != 0 but still not a template instance can
6404 // happens 'just' for string (GetSplit replaces the template by the short name
6405 // and then use that for thew splitting)
6406 TString templateName(autoparseKeys[0]);
6407 auto tokens = templateName.Tokenize("::");
6408 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
6409 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
6410 if (TClassEdit::IsStdClass(cls + offset))
6411 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
6412 auto nTokens = tokens->GetEntriesFast();
6413 for (Int_t tk = 0; tk < nTokens; ++tk) {
6414 auto scopeObj = tokens->UncheckedAt(tk);
6415 auto scopeName = ((TObjString*) scopeObj)->String().Data();
6416 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
6417 // Check if we have multiple nodes in the AST with this name
6418 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
6419 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
6420 if (!previousScopeAsContext) break; // this is not a context
6421 }
6422 delete tokens;
6423 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
6424 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
6425 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
6426 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
6427 skipFirstEntry = templatedDecl->hasDefinition();
6428 }
6429 }
6430 }
6431
6432 }
6433 }
6434 if (topLevel) autoparseKeys.emplace_back(cls);
6435
6436 for (const auto & apKeyStr : autoparseKeys) {
6437 if (skipFirstEntry) {
6438 skipFirstEntry=false;
6439 continue;
6440 }
6441 if (apKeyStr.empty()) continue;
6442 const char *apKey = apKeyStr.c_str();
6443 std::size_t normNameHash(fStringHashFunction(apKey));
6444 // If the class was not looked up
6445 if (gDebug > 1) {
6446 Info("TCling::AutoParse",
6447 "Starting autoparse for %s\n", apKey);
6448 }
6449 if (fLookedUpClasses.insert(normNameHash).second) {
6450 auto const &iter = fClassesHeadersMap.find(normNameHash);
6451 if (iter != fClassesHeadersMap.end()) {
6452 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
6453 fTransactionHeadersMap.insert({T,normNameHash});
6454 auto const &hNamesPtrs = iter->second;
6455 if (gDebug > 1) {
6456 Info("TCling::AutoParse",
6457 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
6458 }
6459 for (auto & hName : hNamesPtrs) {
6460 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
6461 if (0 != fPayloads.count(normNameHash)) {
6462 float initRSSval=0.f, initVSIZEval=0.f;
6463 (void) initRSSval; // Avoid unused var warning
6464 (void) initVSIZEval;
6465 if (gDebug > 0) {
6466 Info("AutoParse",
6467 "Parsing full payload for %s", apKey);
6468 ProcInfo_t info;
6469 gSystem->GetProcInfo(&info);
6470 initRSSval = 1e-3*info.fMemResident;
6471 initVSIZEval = 1e-3*info.fMemVirtual;
6472 }
6473 auto cRes = ExecAutoParse(hName, kFALSE, GetInterpreterImpl());
6474 if (cRes != cling::Interpreter::kSuccess) {
6475 if (hName[0] == '\n')
6476 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
6477 } else {
6478 fParsedPayloadsAddresses.insert(hName);
6479 nHheadersParsed++;
6480 if (gDebug > 0){
6481 ProcInfo_t info;
6482 gSystem->GetProcInfo(&info);
6483 float endRSSval = 1e-3*info.fMemResident;
6484 float endVSIZEval = 1e-3*info.fMemVirtual;
6485 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6486 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6487 }
6488 }
6489 } else if (!IsLoaded(hName)) {
6490 if (gDebug > 0) {
6491 Info("AutoParse",
6492 "Parsing single header %s", hName);
6493 }
6494 auto cRes = ExecAutoParse(hName, kTRUE, GetInterpreterImpl());
6495 if (cRes != cling::Interpreter::kSuccess) {
6496 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
6497 } else {
6498 nHheadersParsed++;
6499 }
6500 }
6501 }
6502 }
6503 else {
6504 // There is no header registered for this class, if this a
6505 // template, it will be instantiated if/when it is requested
6506 // and if we do no load/parse its components we might end up
6507 // not using an eventual specialization.
6508 if (strchr(apKey, '<')) {
6509 nHheadersParsed += AutoParseImplRecurse(apKey, false);
6510 }
6511 }
6512 }
6513 }
6514
6515 return nHheadersParsed;
6516
6517}
6518
6519////////////////////////////////////////////////////////////////////////////////
6520/// Parse the headers relative to the class
6521/// Returns 1 in case of success, 0 in case of failure
6522
6523Int_t TCling::AutoParse(const char *cls)
6524{
6525 if (llvm::StringRef(cls).contains("(lambda)"))
6526 return 0;
6527
6530 return AutoLoad(cls);
6531 } else {
6532 return 0;
6533 }
6534 }
6535
6537
6538 if (gDebug > 1) {
6539 Info("TCling::AutoParse",
6540 "Trying to autoparse for %s", cls);
6541 }
6542
6543 // The catalogue of headers is in the dictionary
6545 && !gClassTable->GetDictNorm(cls)) {
6546 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
6547 ROOT::Internal::ParsingStateRAII parsingStateRAII(fInterpreter->getParser(),
6548 fInterpreter->getSema());
6549 AutoLoad(cls, true /*knowDictNotLoaded*/);
6550 }
6551
6552 // Prevent the recursion when the library dictionary are loaded.
6553 SuspendAutoLoadingRAII autoLoadOff(this);
6554
6555 // No recursive header parsing on demand; we require headers to be standalone.
6556 SuspendAutoParsing autoParseRAII(this);
6557
6558 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
6559
6561
6562 return nHheadersParsed > 0 ? 1 : 0;
6563}
6564
6565// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6566// Try to solve the problem by AutoLoading. Return true when AutoLoading success, return
6567// false if not.
6568bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6569{
6570 StringRef errMsg(errmessage);
6571 if (errMsg.contains("undefined symbol: ")) {
6572 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6573 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6574 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6575 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6576 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6577 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6578 return true;
6579 } else {
6580 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6581 if ( ((TCling*)gCling)->LazyFunctionCreatorAutoload(errmessage))
6582 return true;
6583 }
6584
6585 return false;
6586}
6587
6588////////////////////////////////////////////////////////////////////////////////
6589/// Autoload a library based on a missing symbol.
6590
6591void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {
6592 std::string dlsym_mangled_name = ROOT::TMetaUtils::DemangleNameForDlsym(mangled_name);
6593
6594 // We have already loaded the library.
6595 if (void* Addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name))
6596 return Addr;
6597
6598 const cling::DynamicLibraryManager &DLM = *GetInterpreterImpl()->getDynamicLibraryManager();
6600
6601 auto LibLoader = [](const std::string& LibName) -> bool {
6602 if (gSystem->Load(LibName.c_str(), "", false) < 0) {
6603 ::Error("TCling__LazyFunctionCreatorAutoloadForModule",
6604 "Failed to load library %s", LibName.c_str());
6605 return false;
6606 }
6607 return true; //success.
6608 };
6609
6610 std::string libName = DLM.searchLibrariesForSymbol(mangled_name,
6611 /*searchSystem=*/ true);
6612
6613 assert(!llvm::StringRef(libName).startswith("libNew") &&
6614 "We must not resolve symbols from libNew!");
6615
6616 if (libName.empty())
6617 return nullptr;
6618
6619 if (!LibLoader(libName))
6620 return nullptr;
6621
6622 return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name);
6623}
6624
6625////////////////////////////////////////////////////////////////////////////////
6626
6627Bool_t TCling::IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
6628{
6629 return fNSFromRootmaps.count(nsDecl) != 0;
6630}
6631
6632////////////////////////////////////////////////////////////////////////////////
6633/// Internal function. Actually do the update of the ClassInfo when seeing
6634// new TagDecl or NamespaceDecl.
6635void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6636{
6637
6639 if (cci) {
6640 // If we only had a forward declaration then update the
6641 // TClingClassInfo with the definition if we have it now.
6642 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6643 if (!oldDef || (def && def != oldDef)) {
6644 cl->ResetCaches();
6646 if (def) {
6647 if (cci->GetType()) {
6648 // It's a tag decl, not a namespace decl.
6649 cci->Init(*cci->GetType());
6651 } else {
6652 Error("RefreshClassInfo", "Should not need to update the classInfo a non type decl: %s", oldDef->getNameAsString().c_str());
6653 }
6654 }
6655 }
6656 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6657 cl->ResetCaches();
6658 // yes, this is almost a waste of time, but we do need to lookup
6659 // the 'type' corresponding to the TClass anyway in order to
6660 // preserve the opaque typedefs (Double32_t)
6661 if (!alias && def != nullptr)
6662 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), def);
6663 else
6664 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), cl->GetName());
6665 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6666 // We now need to update the state and bits.
6667 if (cl->fState != TClass::kHasTClassInit) {
6668 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6670 }
6671 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6672 } else {
6673 delete ((TClingClassInfo *)cl->fClassInfo);
6674 cl->fClassInfo = nullptr;
6675 }
6676 }
6677}
6678
6679////////////////////////////////////////////////////////////////////////////////
6680/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6681void TCling::UpdateClassInfoWithDecl(const NamedDecl* ND)
6682{
6683 const TagDecl *td = dyn_cast<TagDecl>(ND);
6684 const NamespaceDecl *ns = dyn_cast<NamespaceDecl>(ND);
6685 const NamedDecl *canon = nullptr;
6686
6687 std::string name;
6688 TagDecl* tdDef = nullptr;
6689 if (td) {
6690 canon = tdDef = td->getDefinition();
6691 // Let's pass the decl to the TClass only if it has a definition.
6692 if (!tdDef) return;
6693
6694 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6695 // Ignore incomplete definition.
6696 // Ignore declaration within a function.
6697 return;
6698 }
6699
6700 auto declName = tdDef->getNameAsString();
6701 // Check if we have registered the unqualified name into the list
6702 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6703 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6704 // the unqualified name is sufficient (and the fully qualified name might be
6705 // 'wrong' if there is difference in spelling in the template paramters (for example)
6706 if (!TClass::HasNoInfoOrEmuOrFwdDeclaredDecl(declName.c_str())){
6707 // 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() );
6708 return;
6709 }
6710
6711 clang::QualType type(tdDef->getTypeForDecl(), 0);
6713 } else if (ns) {
6714 canon = ns->getCanonicalDecl();
6715 name = ND->getQualifiedNameAsString();
6716 } else {
6717 name = ND->getQualifiedNameAsString();
6718 }
6719
6720 // Supposedly we are being called while something is being
6721 // loaded ... let's now tell the autoloader to do the work
6722 // yet another time.
6723 SuspendAutoLoadingRAII autoLoadOff(this);
6724 // FIXME: There can be more than one TClass for a single decl.
6725 // for example vector<double> and vector<Double32_t>
6726 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6727 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6728 RefreshClassInfo(cl, canon, false);
6729 }
6730 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6731 // and update them too:
6732 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6733 // RefreshClassInfo(cl, tdDef, true);
6734}
6735
6736////////////////////////////////////////////////////////////////////////////////
6737/// No op: see TClingCallbacks
6738
6739void TCling::UpdateClassInfo(char* item, Long_t tagnum)
6740{
6741}
6742
6743//______________________________________________________________________________
6744//FIXME: Factor out that function in TClass, because TClass does it already twice
6745void TCling::UpdateClassInfoWork(const char* item)
6746{
6747 // This is a no-op as part of the API.
6748 // TCling uses UpdateClassInfoWithDecl() instead.
6749}
6750
6751////////////////////////////////////////////////////////////////////////////////
6752/// Update all canvases at end the terminal input command.
6753
6755{
6756 TIter next(gROOT->GetListOfCanvases());
6757 TVirtualPad* canvas;
6758 while ((canvas = (TVirtualPad*)next())) {
6759 canvas->Update();
6760 }
6761}
6762
6763////////////////////////////////////////////////////////////////////////////////
6764
6765void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6766 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6767
6768 // If the transaction does not contain anything we can return earlier.
6769 if (!HandleNewTransaction(T)) return;
6770
6771 bool isTUTransaction = false;
6772 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
6773 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
6774 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
6775 // The is the first transaction, we have to expose to meta
6776 // what's already in the AST.
6777 isTUTransaction = true;
6778 }
6779 }
6780
6781 std::set<const void*> TransactionDeclSet;
6782 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
6783 const clang::Decl* WrapperFD = T.getWrapperFD();
6784 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6785 I != E; ++I) {
6786 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
6787 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
6788 continue;
6789
6790 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6791 DE = I->m_DGR.end(); DI != DE; ++DI) {
6792 if (*DI == WrapperFD)
6793 continue;
6794 TransactionDeclSet.insert(*DI);
6795 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
6796 }
6797 }
6798 }
6799
6800 // The above might trigger more decls to be deserialized.
6801 // Thus the iteration over the deserialized decls must be last.
6802 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
6803 E = T.deserialized_decls_end(); I != E; ++I) {
6804 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6805 DE = I->m_DGR.end(); DI != DE; ++DI)
6806 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
6807 //FIXME: HandleNewDecl should take DeclGroupRef
6808 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
6809 modifiedTClasses);
6810 }
6811 }
6812
6813
6814 // When fully building the reflection info in TClass, a deserialization
6815 // could be triggered, which may result in request for building the
6816 // reflection info for the same TClass. This in turn will clear the caches
6817 // for the TClass in-flight and cause null ptr derefs.
6818 // FIXME: This is a quick fix, solving most of the issues. The actual
6819 // question is: Shouldn't TClass provide a lock mechanism on update or lock
6820 // itself until the update is done.
6821 //
6822 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
6823 std::vector<TClass*>::iterator it;
6824 it = set_difference(modifiedTClasses.begin(), modifiedTClasses.end(),
6825 ((TCling*)gCling)->GetModTClasses().begin(),
6826 ((TCling*)gCling)->GetModTClasses().end(),
6827 modifiedTClassesDiff.begin());
6828 modifiedTClassesDiff.resize(it - modifiedTClassesDiff.begin());
6829
6830 // Lock the TClass for updates
6831 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
6832 modifiedTClassesDiff.end());
6833 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
6834 E = modifiedTClassesDiff.end(); I != E; ++I) {
6835 // Make sure the TClass has not been deleted.
6836 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
6837 continue;
6838 }
6839 // Could trigger deserialization of decls.
6840 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
6841 // Unlock the TClass for updates
6842 ((TCling*)gCling)->GetModTClasses().erase(*I);
6843
6844 }
6845}
6846
6847///\brief Invalidate stored TCling state for declarations included in transaction `T'.
6848///
6849void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
6850{
6852
6853 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6854 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6855 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6856 (TListOfEnums *)gROOT->GetListOfEnums());
6857
6858 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
6859 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6860 I != E; ++I) {
6861 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
6862 continue;
6863 if (I->m_Call == cling::Transaction::kCCINone) {
6864 UpdateListsOnUnloaded(*(*iNested));
6865 ++iNested;
6866 continue;
6867 }
6868
6869 for (auto &D : I->m_DGR)
6870 InvalidateCachedDecl(Lists, D);
6871 }
6872}
6873
6874///\brief Invalidate cached TCling information for the given global declaration.
6875///
6876void TCling::InvalidateGlobal(const Decl *D) {
6877 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6878 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6879 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6880 (TListOfEnums *)gROOT->GetListOfEnums());
6881 InvalidateCachedDecl(Lists, D);
6882}
6883
6884///\brief Invalidate cached TCling information for the given declaration, and
6885/// removed it from the appropriate object list.
6886///\param[in] Lists - std::tuple<TListOfDataMembers&, TListOfFunctions&,
6887/// TListOfFunctionTemplates&, TListOfEnums&>
6888/// of pointers to the (global/class) object lists.
6889///\param[in] D - Decl to discard.
6890///
6894 TListOfEnums*> &Lists, const Decl *D) {
6895 if (D->isFromASTFile()) // `D' came from the PCH; ignore
6896 return;
6897
6898 TListOfDataMembers &LODM = *(std::get<0>(Lists));
6899 TListOfFunctions &LOF = *(std::get<1>(Lists));
6900 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
6901 TListOfEnums &LOE = *(std::get<3>(Lists));
6902
6903 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D)) {
6904 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
6905 if (LODM.GetClass())
6906 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
6907 else
6908 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
6909 } else if (isa<FunctionDecl>(D)) {
6911 } else if (isa<FunctionTemplateDecl>(D)) {
6913 } else if (isa<EnumDecl>(D)) {
6914 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
6915 if (!E)
6916 return;
6917
6918 // Try to invalidate enumerators (for unscoped enumerations).
6919 for (TIter I = E->GetConstants(); auto EC = (TEnumConstant *)I(); )
6921 (TEnumConstant *)LODM.FindObject(EC->GetName()));
6922
6924 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
6925 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->isCompleteDefinition())
6926 return;
6927
6928 std::vector<TClass *> Classes;
6929 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
6930 return;
6931 for (auto &C : Classes) {
6932 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
6933 (TListOfFunctions *)C->GetListOfMethods(),
6934 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
6935 (TListOfEnums *)C->GetListOfEnums());
6936 for (auto &I : cast<DeclContext>(D)->decls())
6937 InvalidateCachedDecl(Lists, I);
6938
6939 // For NamespaceDecl (redeclarable), only invalidate this redecl.
6940 if (D->getKind() != Decl::Namespace
6941 || cast<NamespaceDecl>(D)->isOriginalNamespace())
6942 C->ResetClassInfo();
6943 }
6944 }
6945}
6946
6947////////////////////////////////////////////////////////////////////////////////
6948// If an autoparse was done during a transaction and that it is rolled back,
6949// we need to make sure the next request for the same autoparse will be
6950// honored.
6951void TCling::TransactionRollback(const cling::Transaction &T) {
6952 auto const &triter = fTransactionHeadersMap.find(&T);
6953 if (triter != fTransactionHeadersMap.end()) {
6954 std::size_t normNameHash = triter->second;
6955
6956 fLookedUpClasses.erase(normNameHash);
6957
6958 auto const &iter = fClassesHeadersMap.find(normNameHash);
6959 if (iter != fClassesHeadersMap.end()) {
6960 auto const &hNamesPtrs = iter->second;
6961 for (auto &hName : hNamesPtrs) {
6962 if (gDebug > 0) {
6963 Info("TransactionRollback",
6964 "Restoring ability to autoaparse: %s", hName);
6965 }
6966 fParsedPayloadsAddresses.erase(hName);
6967 }
6968 }
6969 }
6970}
6971
6972////////////////////////////////////////////////////////////////////////////////
6973
6974void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
6975// R__LOCKGUARD_CLING(gInterpreterMutex);
6976// UpdateListOfLoadedSharedLibraries();
6977}
6978
6979////////////////////////////////////////////////////////////////////////////////
6980
6981void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
6982 fPrevLoadedDynLibInfo = nullptr;
6983 fSharedLibs = "";
6984}
6985
6986////////////////////////////////////////////////////////////////////////////////
6987/// Return the list of shared libraries loaded into the process.
6988
6990{
6993 return fSharedLibs;
6994}
6995
6996static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH, bool skipCore)
6997{
6998 if (!cls || !*cls)
6999 return {};
7000
7001 using namespace clang;
7002 if (const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
7003 /*type*/ nullptr, /*instantiate*/ false)) {
7004 if (!D->isFromASTFile()) {
7005 if (gDebug > 5)
7006 Warning("GetClassSharedLibsForModule", "Decl found for %s is not part of a module", cls);
7007 return {};
7008 }
7009 class ModuleCollector : public ConstDeclVisitor<ModuleCollector> {
7010 llvm::DenseSet<Module *> &m_TopLevelModules;
7011
7012 public:
7013 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
7014 void Collect(const Decl *D) { Visit(D); }
7015
7016 void VisitDecl(const Decl *D)
7017 {
7018 // FIXME: Such case is described ROOT-7765 where
7019 // ROOT_GENERATE_DICTIONARY does not contain the list of headers.
7020 // They are specified as #includes in the LinkDef file. This leads to
7021 // generation of incomplete modulemap files and this logic fails to
7022 // compute the corresponding module of D.
7023 // FIXME: If we want to support such a case, we should not rely on
7024 // the contents of the modulemap but mangle D and look it up in the
7025 // .so files.
7026 if (!D->hasOwningModule())
7027 return;
7028 if (Module *M = D->getOwningModule()->getTopLevelModule())
7029 m_TopLevelModules.insert(M);
7030 }
7031
7032 void VisitTemplateArgument(const TemplateArgument &TA)
7033 {
7034 switch (TA.getKind()) {
7035 case TemplateArgument::Null:
7036 case TemplateArgument::Integral:
7037 case TemplateArgument::Pack:
7038 case TemplateArgument::NullPtr:
7039 case TemplateArgument::StructuralValue:
7040 case TemplateArgument::Expression:
7041 case TemplateArgument::Template:
7042 case TemplateArgument::TemplateExpansion: return;
7043 case TemplateArgument::Type:
7044 if (const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
7045 return Visit(TagTy->getDecl());
7046 return;
7047 case TemplateArgument::Declaration: return Visit(TA.getAsDecl());
7048 }
7049 llvm_unreachable("Invalid TemplateArgument::Kind!");
7050 }
7051
7052 void VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *CTSD)
7053 {
7054 if (CTSD->getOwningModule())
7055 VisitDecl(CTSD);
7056 else
7057 VisitDecl(CTSD->getSpecializedTemplate());
7058 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
7059 for (const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
7060 VisitTemplateArgument(*Arg);
7061 }
7062 }
7063 };
7064
7065 llvm::DenseSet<Module *> TopLevelModules;
7066 ModuleCollector m(TopLevelModules);
7067 m.Collect(D);
7068 std::string result;
7069 for (auto M : TopLevelModules) {
7070 // ROOT-unaware modules (i.e. not processed by rootcling) do not have a
7071 // link declaration.
7072 if (!M->LinkLibraries.size())
7073 continue;
7074 // We have preloaded the Core module thus libCore.so
7075 if (M->Name == "Core" && skipCore)
7076 continue;
7077 assert(M->LinkLibraries.size() == 1);
7078 if (!result.empty())
7079 result += ' ';
7080 result += M->LinkLibraries[0].Library;
7081 }
7082 return result;
7083 }
7084 return {};
7085}
7086
7087////////////////////////////////////////////////////////////////////////////////
7088/// Get the list of shared libraries containing the code for class cls.
7089/// The first library in the list is the one containing the class, the
7090/// others are the libraries the first one depends on. Returns 0
7091/// in case the library is not found.
7092/// \param cls the name of the class
7093/// \param skipCore if true (default), remove "Core" from the returned list
7094
7095const char* TCling::GetClassSharedLibs(const char* cls, bool skipCore)
7096{
7097 if (fCxxModulesEnabled) {
7098 // Lock the interpreter mutex before interacting with cling.
7099 // TODO: Can we move this further deep? In principle the lock should be in
7100 // GetClassSharedLibsForModule, but it might be needed also for
7101 // getLookupHelper?
7103 llvm::StringRef className = cls;
7104 // If we get a class name containing lambda, we cannot parse it and we
7105 // can exit early.
7106 // FIXME: This works around a bug when we are instantiating a template
7107 // make_unique and the substitution fails. Seen in most of the dataframe
7108 // tests.
7109 if (className.contains("(lambda)"))
7110 return nullptr;
7111 // Limit the recursion which can be induced by GetClassSharedLibsForModule.
7112 SuspendAutoLoadingRAII AutoLoadingDisabled(this);
7113 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
7114 std::string libs = GetClassSharedLibsForModule(cls, LH, skipCore);
7115 if (!libs.empty()) {
7116 fAutoLoadLibStorage.push_back(libs);
7117 return fAutoLoadLibStorage.back().c_str();
7118 }
7119 }
7120
7121 if (!cls || !*cls) {
7122 return nullptr;
7123 }
7124 // lookup class to find list of libraries
7125 if (fMapfile) {
7126 TEnvRec* libs_record = nullptr;
7127 libs_record = fMapfile->Lookup(cls);
7128 if (libs_record) {
7129 const char* libs = libs_record->GetValue();
7130 return (*libs) ? libs : nullptr;
7131 }
7132 else {
7133 // Try the old format...
7134 TString c = TString("Library.") + cls;
7135 // convert "::" to "@@", we used "@@" because TEnv
7136 // considers "::" a terminator
7137 c.ReplaceAll("::", "@@");
7138 // convert "-" to " ", since class names may have
7139 // blanks and TEnv considers a blank a terminator
7140 c.ReplaceAll(" ", "-");
7141 // Use TEnv::Lookup here as the rootmap file must start with Library.
7142 // and do not support using any stars (so we do not need to waste time
7143 // with the search made by TEnv::GetValue).
7144 TEnvRec* libs_record = nullptr;
7145 libs_record = fMapfile->Lookup(c);
7146 if (libs_record) {
7147 const char* libs = libs_record->GetValue();
7148 return (*libs) ? libs : nullptr;
7149 }
7150 }
7151 }
7152 return nullptr;
7153}
7154
7155/// This interface returns a list of dependent libraries in the form:
7156/// lib libA.so libB.so libC.so. The first library is the library we are
7157/// searching dependencies for.
7158/// Note: In order to speed up the search, we display the dependencies of the
7159/// libraries which are not yet loaded. For instance, if libB.so was already
7160/// loaded the list would contain: lib libA.so libC.so.
7161static std::string GetSharedLibImmediateDepsSlow(std::string lib,
7162 cling::Interpreter *interp,
7163 bool skipLoadedLibs = true)
7164{
7165 TString LibFullPath(lib);
7166 if (!llvm::sys::path::is_absolute(lib)) {
7167 if (!gSystem->FindDynamicLibrary(LibFullPath, /*quiet=*/true)) {
7168 Error("TCling__GetSharedLibImmediateDepsSlow", "Cannot find library '%s'", lib.c_str());
7169 return "";
7170 }
7171 } else {
7172 assert(llvm::sys::fs::exists(lib) && "Must exist!");
7173 lib = llvm::sys::path::filename(lib).str();
7174 }
7175
7176 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
7177 if (!ObjF) {
7178 Warning("TCling__GetSharedLibImmediateDepsSlow", "Failed to read object file %s", lib.c_str());
7179 return "";
7180 }
7181
7182 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7183
7184 std::set<string> DedupSet;
7185 std::string Result = lib + ' ';
7186 for (const auto &S : BinObjFile->symbols()) {
7187 uint32_t Flags = llvm::cantFail(S.getFlags());
7188 // Skip defined symbols: we have them.
7189 if (!(Flags & llvm::object::SymbolRef::SF_Undefined))
7190 continue;
7191 // Skip undefined weak symbols: if we don't have them we won't need them.
7192 // `__gmon_start__` being a typical example.
7193 if (Flags & llvm::object::SymbolRef::SF_Weak)
7194 continue;
7195 llvm::Expected<StringRef> SymNameErr = S.getName();
7196 if (!SymNameErr) {
7197 Warning("GetSharedLibDepsForModule", "Failed to read symbol");
7198 continue;
7199 }
7200 llvm::StringRef SymName = SymNameErr.get();
7201 if (SymName.empty())
7202 continue;
7203
7204 if (BinObjFile->isELF()) {
7205 // Skip the symbols which are part of the C/C++ runtime and have a
7206 // fixed library version. See binutils ld VERSION. Those reside in
7207 // 'system' libraries, which we avoid in FindLibraryForSymbol.
7208 if (SymName.contains("@GLIBCXX") || SymName.contains("@CXXABI") ||
7209 SymName.contains("@GLIBC") || SymName.contains("@GCC"))
7210 continue;
7211
7212 // Those are 'weak undefined' symbols produced by gcc. We can
7213 // ignore them.
7214 // FIXME: It is unclear whether we can ignore all weak undefined
7215 // symbols:
7216 // http://lists.llvm.org/pipermail/llvm-dev/2017-October/118177.html
7217 static constexpr llvm::StringRef RegisterClasses("_Jv_RegisterClasses");
7218 static constexpr llvm::StringRef RegisterCloneTable("_ITM_registerTMCloneTable");
7219 static constexpr llvm::StringRef DeregisterCloneTable("_ITM_deregisterTMCloneTable");
7220 if (SymName == RegisterClasses ||
7221 SymName == RegisterCloneTable ||
7222 SymName == DeregisterCloneTable)
7223 continue;
7224 }
7225
7226 // If we can find the address of the symbol, we have loaded it. Skip.
7227 if (skipLoadedLibs) {
7228 std::string SymNameForDlsym = ROOT::TMetaUtils::DemangleNameForDlsym(SymName.str());
7229 if (llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymNameForDlsym))
7230 continue;
7231 }
7232
7234 std::string found = interp->getDynamicLibraryManager()->searchLibrariesForSymbol(SymName, /*searchSystem*/false);
7235 // The expected output is just filename without the full path, which
7236 // is not very accurate, because our Dyld implementation might find
7237 // a match in location a/b/c.so and if we return just c.so ROOT might
7238 // resolve it to y/z/c.so and there we might not be ABI compatible.
7239 // FIXME: Teach the users of GetSharedLibDeps to work with full paths.
7240 if (!found.empty()) {
7241 std::string cand = llvm::sys::path::filename(found).str();
7242 if (!DedupSet.insert(cand).second)
7243 continue;
7244
7245 Result += cand + ' ';
7246 }
7247 }
7248
7249 return Result;
7250}
7251
7252static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
7253{
7254 // Check if we have parsed a rootmap file.
7255 llvm::SmallString<256> rootmapName;
7256 if (!lib.startswith("lib"))
7257 rootmapName.append("lib");
7258
7259 rootmapName.append(llvm::sys::path::filename(lib));
7260 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7261
7262 if (gCling->GetRootMapFiles()->FindObject(rootmapName.c_str()))
7263 return true;
7264
7265 // Perform a last resort by dropping the lib prefix.
7266 llvm::StringRef rootmapNameNoLib = rootmapName.str();
7267 if (rootmapNameNoLib.consume_front("lib"))
7268 return gCling->GetRootMapFiles()->FindObject(rootmapNameNoLib.data());
7269
7270 return false;
7271}
7272
7273static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
7274{
7275 if (gCling->HasPCMForLibrary(lib.data()))
7276 return true;
7277
7278 return hasParsedRootmapForLibrary(lib);
7279}
7280
7281////////////////////////////////////////////////////////////////////////////////
7282/// Get the list a libraries on which the specified lib depends. The
7283/// returned string contains as first element the lib itself.
7284/// Returns 0 in case the lib does not exist or does not have
7285/// any dependencies. If useDyld is true, we iterate through all available
7286/// libraries and try to construct the dependency chain by resolving each
7287/// symbol.
7288
7289const char* TCling::GetSharedLibDeps(const char* lib, bool useDyld/* = false*/)
7290{
7291 if (llvm::sys::path::is_absolute(lib) && !llvm::sys::fs::exists(lib))
7292 return nullptr;
7293
7294 if (!hasParsedRootmapForLibrary(lib)) {
7295 llvm::SmallString<512> rootmapName(lib);
7296 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7297 if (llvm::sys::fs::exists(rootmapName)) {
7298 if (gDebug > 0)
7299 Info("Load", "loading %s", rootmapName.c_str());
7300 gInterpreter->LoadLibraryMap(rootmapName.c_str());
7301 }
7302 }
7303
7304 if (hasPrecomputedLibraryDeps(lib) && useDyld) {
7305 if (gDebug > 0)
7306 Warning("TCling::GetSharedLibDeps", "Precomputed dependencies available but scanning '%s'", lib);
7307 }
7308
7309 if (useDyld) {
7310 std::string libs = GetSharedLibImmediateDepsSlow(lib, GetInterpreterImpl());
7311 if (!libs.empty()) {
7312 fAutoLoadLibStorage.push_back(libs);
7313 return fAutoLoadLibStorage.back().c_str();
7314 }
7315 }
7316
7317 if (!fMapfile || !lib || !lib[0]) {
7318 return nullptr;
7319 }
7320 TString libname(lib);
7321 Ssiz_t idx = libname.Last('.');
7322 if (idx != kNPOS) {
7323 libname.Remove(idx);
7324 }
7325 TEnvRec* rec;
7326 TIter next(fMapfile->GetTable());
7327 size_t len = libname.Length();
7328 while ((rec = (TEnvRec*) next())) {
7329 const char* libs = rec->GetValue();
7330 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7331 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
7332 return libs;
7333 }
7334 }
7335 return nullptr;
7336}
7337
7338////////////////////////////////////////////////////////////////////////////////
7339/// If error messages are disabled, the interpreter should suppress its
7340/// failures and warning messages from stdout.
7341
7343{
7344#if defined(R__MUST_REVISIT)
7345#if R__MUST_REVISIT(6,2)
7346 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
7347#endif
7348#endif
7349 return kTRUE;
7350}
7351
7352////////////////////////////////////////////////////////////////////////////////
7353/// If error messages are disabled, the interpreter should suppress its
7354/// failures and warning messages from stdout. Return the previous state.
7355
7357{
7358#if defined(R__MUST_REVISIT)
7359#if R__MUST_REVISIT(6,2)
7360 Warning("SetErrorMessages", "Interface not available yet.");
7361#endif
7362#endif
7364}
7365
7366////////////////////////////////////////////////////////////////////////////////
7367/// Refresh the list of include paths known to the interpreter and return it
7368/// with -I prepended.
7369
7371{
7373
7374 fIncludePath = "";
7375
7376 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7377 //false - no system header, true - with flags.
7378 fInterpreter->GetIncludePaths(includePaths, false, true);
7379 if (const size_t nPaths = includePaths.size()) {
7380 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
7381
7382 for (size_t i = 0; i < nPaths; i += 2) {
7383 if (i)
7384 fIncludePath.Append(' ');
7385 fIncludePath.Append(includePaths[i].c_str());
7386
7387 if (includePaths[i] != "-I")
7388 fIncludePath.Append(' ');
7389 fIncludePath.Append('"');
7390 fIncludePath.Append(includePaths[i + 1], includePaths[i + 1].length());
7391 fIncludePath.Append('"');
7392 }
7393 }
7394
7395 return fIncludePath;
7396}
7397
7398////////////////////////////////////////////////////////////////////////////////
7399/// Return the directory containing CINT's stl cintdlls.
7400
7401const char* TCling::GetSTLIncludePath() const
7402{
7403 return "";
7404}
7405
7406//______________________________________________________________________________
7407// M I S C
7408//______________________________________________________________________________
7409
7410int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
7411{
7412 // Interface to cling function
7413 return 0;
7414}
7415
7416////////////////////////////////////////////////////////////////////////////////
7417/// Interface to cling function
7418
7419int TCling::DisplayIncludePath(FILE *fout) const
7420{
7421 assert(fout != nullptr && "DisplayIncludePath, 'fout' parameter is null");
7422
7423 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7424 //false - no system header, true - with flags.
7425 fInterpreter->GetIncludePaths(includePaths, false, true);
7426 if (const size_t nPaths = includePaths.size()) {
7427 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
7428
7429 std::string allIncludes("include path:");
7430 for (size_t i = 0; i < nPaths; i += 2) {
7431 allIncludes += ' ';
7432 allIncludes += includePaths[i];
7433
7434 if (includePaths[i] != "-I")
7435 allIncludes += ' ';
7436 allIncludes += includePaths[i + 1];
7437 }
7438
7439 fprintf(fout, "%s\n", allIncludes.c_str());
7440 }
7441
7442 return 0;
7443}
7444
7445////////////////////////////////////////////////////////////////////////////////
7446/// Interface to cling function
7447
7448void* TCling::FindSym(const char* entry) const
7449{
7451 return fInterpreter->getAddressOfGlobal(entry);
7452}
7453
7454////////////////////////////////////////////////////////////////////////////////
7455/// Let the interpreter issue a generic error, and set its error state.
7456
7457void TCling::GenericError(const char* error) const
7458{
7459#if defined(R__MUST_REVISIT)
7460#if R__MUST_REVISIT(6,2)
7461 Warning("GenericError","Interface not available yet.");
7462#endif
7463#endif
7464}
7465
7466////////////////////////////////////////////////////////////////////////////////
7467/// This routines used to return the address of the internal wrapper
7468/// function (of the interpreter) that was used to call *all* the
7469/// interpreted functions that were bytecode compiled (no longer
7470/// interpreted line by line). In Cling, there is no such
7471/// wrapper function.
7472/// In practice this routines was use to decipher whether the
7473/// pointer returns by InterfaceMethod could be used to uniquely
7474/// represent the function. In Cling if the function is in a
7475/// useable state (its compiled version is available), this is
7476/// always the case.
7477/// See TClass::GetMethod.
7478
7480{
7481 return 0;
7482}
7483
7484////////////////////////////////////////////////////////////////////////////////
7485/// Interface to cling function
7486
7488{
7489#if defined(R__MUST_REVISIT)
7490#if R__MUST_REVISIT(6,2)
7491 Warning("GetSecurityError", "Interface not available yet.");
7492#endif
7493#endif
7494 return 0;
7495}
7496
7497////////////////////////////////////////////////////////////////////////////////
7498/// Load a source file or library called path into the interpreter.
7499
7500int TCling::LoadFile(const char* path) const
7501{
7502 // Modifying the interpreter state needs locking.
7504 cling::Interpreter::CompilationResult compRes;
7505 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(".L %s", path), compRes, /*cling::Value*/nullptr);
7506 return compRes == cling::Interpreter::kFailure;
7507}
7508
7509////////////////////////////////////////////////////////////////////////////////
7510/// Load the declarations from text into the interpreter.
7511/// Note that this cannot be (top level) statements; text must contain
7512/// top level declarations.
7513/// Returns true on success, false on failure.
7514
7515Bool_t TCling::LoadText(const char* text) const
7516{
7517 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7518}
7519
7520////////////////////////////////////////////////////////////////////////////////
7521/// Interface to cling function
7522
7523const char* TCling::MapCppName(const char* name) const
7524{
7525 TTHREAD_TLS_DECL(std::string,buffer);
7527 return buffer.c_str(); // NOLINT
7528}
7529
7530////////////////////////////////////////////////////////////////////////////////
7531/// [Place holder for Mutex Lock]
7532/// Provide the interpreter with a way to
7533/// acquire a lock used to protect critical section
7534/// of its code (non-thread safe parts).
7535
7536void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7537{
7538 // nothing to do for now.
7539}
7540
7541////////////////////////////////////////////////////////////////////////////////
7542/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7543/// release a lock used to protect critical section
7544/// of its code (non-thread safe parts).
7545
7546void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7547{
7548 // nothing to do for now.
7549}
7550
7551////////////////////////////////////////////////////////////////////////////////
7552/// Returns if class AutoLoading is currently enabled.
7553
7555{
7556 if (IsFromRootCling())
7557 return false;
7558 if (!fClingCallbacks)
7559 return false;
7561}
7562
7563////////////////////////////////////////////////////////////////////////////////
7564/// Enable/Disable the AutoLoading of libraries.
7565/// Returns the old value, i.e whether it was enabled or not.
7566
7567int TCling::SetClassAutoLoading(int autoload) const
7568{
7569 // If no state change is required, exit early.
7570 // FIXME: In future we probably want to complain if we made a request which
7571 // was with the same state as before in order to catch programming errors.
7572 if ((bool) autoload == IsClassAutoLoadingEnabled())
7573 return autoload;
7574
7575 assert(fClingCallbacks && "We must have callbacks!");
7576 bool oldVal = fClingCallbacks->IsAutoLoadingEnabled();
7578 return oldVal;
7579}
7580
7581////////////////////////////////////////////////////////////////////////////////
7582/// Enable/Disable the Autoparsing of headers.
7583/// Returns the old value, i.e whether it was enabled or not.
7584
7586{
7587 bool oldVal = fHeaderParsingOnDemand;
7588 fHeaderParsingOnDemand = autoparse;
7589 return oldVal;
7590}
7591
7592////////////////////////////////////////////////////////////////////////////////
7593/// Suspend the Autoparsing of headers.
7594/// Returns the old value, i.e whether it was suspended or not.
7595
7600 return old;
7601}
7602
7603////////////////////////////////////////////////////////////////////////////////
7604/// Set a callback to receive error messages.
7605
7607{
7608#if defined(R__MUST_REVISIT)
7609#if R__MUST_REVISIT(6,2)
7610 Warning("SetErrmsgcallback", "Interface not available yet.");
7611#endif
7612#endif
7613}
7614
7616{
7617 if (enable) {
7618 auto consumer = new TClingDelegateDiagnosticPrinter(
7619 &fInterpreter->getDiagnostics().getDiagnosticOptions(),
7620 fInterpreter->getCI()->getLangOpts(),
7621 [] (clang::DiagnosticsEngine::Level Level, const std::string &Info) {
7622 if (Level == clang::DiagnosticsEngine::Warning) {
7623 ::Warning("cling", "%s", Info.c_str());
7624 } else if (Level == clang::DiagnosticsEngine::Error
7625 || Level == clang::DiagnosticsEngine::Fatal) {
7626 ::Error("cling", "%s", Info.c_str());
7627 } else {
7628 ::Info("cling", "%s", Info.c_str());
7629 }
7630 });
7631 fInterpreter->replaceDiagnosticConsumer(consumer, /*Own=*/true);
7632 } else {
7633 fInterpreter->replaceDiagnosticConsumer(nullptr);
7634 }
7635}
7636
7637
7638////////////////////////////////////////////////////////////////////////////////
7639/// Create / close a scope for temporaries. No-op for cling; use
7640/// cling::Value instead.
7641
7642void TCling::SetTempLevel(int val) const
7643{
7644}
7645
7646////////////////////////////////////////////////////////////////////////////////
7647
7648int TCling::UnloadFile(const char* path) const
7649{
7650 // Modifying the interpreter state needs locking.
7652 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7653 std::string canonical = DLM->lookupLibrary(path);
7654 if (canonical.empty()) {
7655 canonical = path;
7656 }
7657 // Unload a shared library or a source file.
7658 cling::Interpreter::CompilationResult compRes;
7659 HandleInterpreterException(GetMetaProcessorImpl(), Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/nullptr);
7660 return compRes == cling::Interpreter::kFailure;
7661}
7662
7663std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7664 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7665}
7666
7667////////////////////////////////////////////////////////////////////////////////
7668/// The call to Cling's tab complition.
7669
7670void TCling::CodeComplete(const std::string& line, size_t& cursor,
7671 std::vector<std::string>& completions)
7672{
7673 fInterpreter->codeComplete(line, cursor, completions);
7674}
7675
7676////////////////////////////////////////////////////////////////////////////////
7677/// Get the interpreter value corresponding to the statement.
7679{
7680 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7681 auto compRes = fInterpreter->evaluate(code, *V);
7682 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7683}
7684
7685////////////////////////////////////////////////////////////////////////////////
7686
7688{
7689 using namespace cling;
7690 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7692}
7693
7694////////////////////////////////////////////////////////////////////////////////
7695/// Register value as a temporary, extending its lifetime to that of the
7696/// interpreter. This is needed for TCling's compatibility interfaces
7697/// returning long - the address of the temporary objects.
7698/// As such, "simple" types don't need to be stored; they are returned by
7699/// value; only pointers / references / objects need to be stored.
7700
7701void TCling::RegisterTemporary(const cling::Value& value)
7702{
7703 if (value.isValid() && value.needsManagedAllocation()) {
7705 fTemporaries->push_back(value);
7706 }
7707}
7708
7709////////////////////////////////////////////////////////////////////////////////
7710/// If the interpreter encounters Name, check whether that is an object ROOT
7711/// could retrieve. To not re-read objects from disk, cache the name/object
7712/// pair for a given LookupCtx.
7713
7714TObject* TCling::GetObjectAddress(const char *Name, void *&LookupCtx)
7715{
7716 // The call to FindSpecialObject might induces any kind of use
7717 // of the interpreter ... (library loading, function calling, etc.)
7718 // ... and we _know_ we are in the middle of parsing, so let's make
7719 // sure to save the state and then restore it.
7720
7721 if (gDirectory) {
7722 auto iSpecObjMap = fSpecialObjectMaps.find(gDirectory);
7723 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7724 auto iSpecObj = iSpecObjMap->second.find(Name);
7725 if (iSpecObj != iSpecObjMap->second.end()) {
7726 LookupCtx = gDirectory;
7727 return iSpecObj->second;
7728 }
7729 }
7730 }
7731
7732 // Save state of the PP
7733 Sema &SemaR = fInterpreter->getSema();
7734 ASTContext& C = SemaR.getASTContext();
7735 Preprocessor &PP = SemaR.getPreprocessor();
7736 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7737 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7738 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7739 // After we have saved the token reset the current one to something which
7740 // is safe (semi colon usually means empty decl)
7741 Token& Tok = const_cast<Token&>(P.getCurToken());
7742 Tok.setKind(tok::semi);
7743
7744 // We can't PushDeclContext, because we go up and the routine that pops
7745 // the DeclContext assumes that we drill down always.
7746 // We have to be on the global context. At that point we are in a
7747 // wrapper function so the parent context must be the global.
7748 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7749 SemaR.TUScope);
7750
7751 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7752 if (specObj) {
7753 if (!LookupCtx) {
7754 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7755 } else {
7756 fSpecialObjectMaps[LookupCtx][Name] = specObj;
7757 }
7758 }
7759 return specObj;
7760}
7761
7762////////////////////////////////////////////////////////////////////////////////
7763/// Inject function as a friend into klass.
7764/// With function being f in void f() {new N::PrivKlass(); } this enables
7765/// I/O of non-public classes.
7766
7767void TCling::AddFriendToClass(clang::FunctionDecl* function,
7768 clang::CXXRecordDecl* klass) const
7769{
7770 using namespace clang;
7771 ASTContext& Ctx = klass->getASTContext();
7772 FriendDecl::FriendUnion friendUnion(function);
7773 // one dummy object for the source location
7774 SourceLocation sl;
7775 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
7776 klass->pushFriendDecl(friendDecl);
7777}
7778
7779//______________________________________________________________________________
7780//
7781// DeclId getter.
7782//
7783
7784////////////////////////////////////////////////////////////////////////////////
7785/// Return a unique identifier of the declaration represented by the
7786/// CallFunc
7787
7789{
7790 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
7791 return nullptr;
7792}
7793
7794////////////////////////////////////////////////////////////////////////////////
7795/// Return a (almost) unique identifier of the declaration represented by the
7796/// ClassInfo. In ROOT, this identifier can point to more than one TClass
7797/// when the underlying class is a template instance involving one of the
7798/// opaque typedef.
7799
7801{
7802 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
7803 return nullptr;
7804}
7805
7806////////////////////////////////////////////////////////////////////////////////
7807/// Return a unique identifier of the declaration represented by the
7808/// MethodInfo
7809
7811{
7812 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
7813 return nullptr;
7814}
7815
7816////////////////////////////////////////////////////////////////////////////////
7817/// Return a unique identifier of the declaration represented by the
7818/// MethodInfo
7819
7821{
7822 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
7823 return nullptr;
7824}
7825
7826////////////////////////////////////////////////////////////////////////////////
7827/// Return a unique identifier of the declaration represented by the
7828/// TypedefInfo
7829
7831{
7832 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
7833 return nullptr;
7834}
7835
7836//______________________________________________________________________________
7837//
7838// CallFunc interface
7839//
7840
7841////////////////////////////////////////////////////////////////////////////////
7842
7843void TCling::CallFunc_Delete(CallFunc_t* func) const
7844{
7845 delete (TClingCallFunc*) func;
7846}
7847
7848////////////////////////////////////////////////////////////////////////////////
7849
7850void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
7851{
7852 TClingCallFunc* f = (TClingCallFunc*) func;
7853 f->Exec(address);
7854}
7855
7856////////////////////////////////////////////////////////////////////////////////
7857
7858void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
7859{
7860 TClingCallFunc* f = (TClingCallFunc*) func;
7861 f->Exec(address, &val);
7862}
7863
7864////////////////////////////////////////////////////////////////////////////////
7865
7866void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
7867{
7868 TClingCallFunc* f = (TClingCallFunc*) func;
7869 f->ExecWithReturn(address, ret);
7870}
7871
7872////////////////////////////////////////////////////////////////////////////////
7873
7874void TCling::CallFunc_ExecWithArgsAndReturn(CallFunc_t* func, void* address,
7875 const void* args[] /*=0*/,
7876 int nargs /*=0*/,
7877 void* ret/*=0*/) const
7878{
7879 TClingCallFunc* f = (TClingCallFunc*) func;
7880 f->ExecWithArgsAndReturn(address, args, nargs, ret);
7881}
7882
7883////////////////////////////////////////////////////////////////////////////////
7884
7885Longptr_t TCling::CallFunc_ExecInt(CallFunc_t* func, void* address) const
7886{
7887 TClingCallFunc* f = (TClingCallFunc*) func;
7888 return f->ExecInt(address);
7889}
7890
7891////////////////////////////////////////////////////////////////////////////////
7892
7893Long64_t TCling::CallFunc_ExecInt64(CallFunc_t* func, void* address) const
7894{
7895 TClingCallFunc* f = (TClingCallFunc*) func;
7896 return f->ExecInt64(address);
7897}
7898
7899////////////////////////////////////////////////////////////////////////////////
7900
7901Double_t TCling::CallFunc_ExecDouble(CallFunc_t* func, void* address) const
7902{
7903 TClingCallFunc* f = (TClingCallFunc*) func;
7904 return f->ExecDouble(address);
7905}
7906
7907////////////////////////////////////////////////////////////////////////////////
7908
7909CallFunc_t* TCling::CallFunc_Factory() const
7910{
7912 return (CallFunc_t*) new TClingCallFunc(GetInterpreterImpl());
7913}
7914
7915////////////////////////////////////////////////////////////////////////////////
7916
7917CallFunc_t* TCling::CallFunc_FactoryCopy(CallFunc_t* func) const
7918{
7919 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
7920}
7921
7922////////////////////////////////////////////////////////////////////////////////
7923
7924MethodInfo_t* TCling::CallFunc_FactoryMethod(CallFunc_t* func) const
7925{
7926 TClingCallFunc* f = (TClingCallFunc*) func;
7927 return (MethodInfo_t*) f->FactoryMethod();
7928}
7929
7930////////////////////////////////////////////////////////////////////////////////
7931
7932void TCling::CallFunc_IgnoreExtraArgs(CallFunc_t* func, bool ignore) const
7933{
7934 TClingCallFunc* f = (TClingCallFunc*) func;
7935 f->IgnoreExtraArgs(ignore);
7936}
7937
7938////////////////////////////////////////////////////////////////////////////////
7939
7940void TCling::CallFunc_Init(CallFunc_t* func) const
7941{
7943 TClingCallFunc* f = (TClingCallFunc*) func;
7944 f->Init();
7945}
7946
7947////////////////////////////////////////////////////////////////////////////////
7948
7949bool TCling::CallFunc_IsValid(CallFunc_t* func) const
7950{
7951 TClingCallFunc* f = (TClingCallFunc*) func;
7952 return f->IsValid();
7953}
7954
7955////////////////////////////////////////////////////////////////////////////////
7956
7958TCling::CallFunc_IFacePtr(CallFunc_t * func) const
7959{
7960 TClingCallFunc* f = (TClingCallFunc*) func;
7961 return f->IFacePtr();
7962}
7963
7964////////////////////////////////////////////////////////////////////////////////
7965
7966void TCling::CallFunc_ResetArg(CallFunc_t* func) const
7967{
7968 TClingCallFunc* f = (TClingCallFunc*) func;
7969 f->ResetArg();
7970}
7971
7972////////////////////////////////////////////////////////////////////////////////
7973
7974void TCling::CallFunc_SetArg(CallFunc_t* func, Long_t param) const
7975{
7976 TClingCallFunc* f = (TClingCallFunc*) func;
7977 f->SetArg(param);
7978}
7979
7980////////////////////////////////////////////////////////////////////////////////
7981
7982void TCling::CallFunc_SetArg(CallFunc_t* func, ULong_t param) const
7983{
7984 TClingCallFunc* f = (TClingCallFunc*) func;
7985 f->SetArg(param);
7986}
7987
7988////////////////////////////////////////////////////////////////////////////////
7989
7990void TCling::CallFunc_SetArg(CallFunc_t* func, Float_t param) const
7991{
7992 TClingCallFunc* f = (TClingCallFunc*) func;
7993 f->SetArg(param);
7994}
7995
7996////////////////////////////////////////////////////////////////////////////////
7997
7998void TCling::CallFunc_SetArg(CallFunc_t* func, Double_t param) const
7999{
8000 TClingCallFunc* f = (TClingCallFunc*) func;
8001 f->SetArg(param);
8002}
8003
8004////////////////////////////////////////////////////////////////////////////////
8005
8006void TCling::CallFunc_SetArg(CallFunc_t* func, Long64_t param) const
8007{
8008 TClingCallFunc* f = (TClingCallFunc*) func;
8009 f->SetArg(param);
8010}
8011
8012////////////////////////////////////////////////////////////////////////////////
8013
8014void TCling::CallFunc_SetArg(CallFunc_t* func, ULong64_t param) const
8015{
8016 TClingCallFunc* f = (TClingCallFunc*) func;
8017 f->SetArg(param);
8018}
8019
8020////////////////////////////////////////////////////////////////////////////////
8021
8022void TCling::CallFunc_SetArgArray(CallFunc_t* func, Longptr_t* paramArr, Int_t nparam) const
8023{
8024 TClingCallFunc* f = (TClingCallFunc*) func;
8025 f->SetArgArray(paramArr, nparam);
8026}
8027
8028////////////////////////////////////////////////////////////////////////////////
8029
8030void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
8031{
8032 TClingCallFunc* f = (TClingCallFunc*) func;
8033 f->SetArgs(param);
8034}
8035
8036////////////////////////////////////////////////////////////////////////////////
8037
8038void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Longptr_t* offset) const
8039{
8040 TClingCallFunc* f = (TClingCallFunc*) func;
8041 TClingClassInfo* ci = (TClingClassInfo*) info;
8042 f->SetFunc(ci, method, params, offset);
8043}
8044
8045////////////////////////////////////////////////////////////////////////////////
8046
8047void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Longptr_t* offset) const
8048{
8049 TClingCallFunc* f = (TClingCallFunc*) func;
8050 TClingClassInfo* ci = (TClingClassInfo*) info;
8051 f->SetFunc(ci, method, params, objectIsConst, offset);
8052}
8053////////////////////////////////////////////////////////////////////////////////
8054
8055void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
8056{
8057 TClingCallFunc* f = (TClingCallFunc*) func;
8058 TClingMethodInfo* minfo = (TClingMethodInfo*) info;
8059 f->SetFunc(minfo);
8060}
8061
8062////////////////////////////////////////////////////////////////////////////////
8063/// Interface to cling function
8064
8065void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8066{
8067 TClingCallFunc* f = (TClingCallFunc*) func;
8068 TClingClassInfo* ci = (TClingClassInfo*) info;
8069 f->SetFuncProto(ci, method, proto, offset, mode);
8070}
8071
8072////////////////////////////////////////////////////////////////////////////////
8073/// Interface to cling function
8074
8075void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8076{
8077 TClingCallFunc* f = (TClingCallFunc*) func;
8078 TClingClassInfo* ci = (TClingClassInfo*) info;
8079 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
8080}
8081
8082////////////////////////////////////////////////////////////////////////////////
8083/// Interface to cling function
8084
8085void 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
8086{
8087 TClingCallFunc* f = (TClingCallFunc*) func;
8088 TClingClassInfo* ci = (TClingClassInfo*) info;
8089 llvm::SmallVector<clang::QualType, 4> funcProto;
8090 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8091 iter != end; ++iter) {
8092 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8093 }
8094 f->SetFuncProto(ci, method, funcProto, offset, mode);
8095}
8096
8097////////////////////////////////////////////////////////////////////////////////
8098/// Interface to cling function
8099
8100void 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
8101{
8102 TClingCallFunc* f = (TClingCallFunc*) func;
8103 TClingClassInfo* ci = (TClingClassInfo*) info;
8104 llvm::SmallVector<clang::QualType, 4> funcProto;
8105 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8106 iter != end; ++iter) {
8107 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8108 }
8109 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
8110}
8111
8112std::string TCling::CallFunc_GetWrapperCode(CallFunc_t *func) const
8113{
8114 TClingCallFunc *f = (TClingCallFunc *)func;
8115 std::string wrapper_name;
8116 std::string wrapper;
8117 f->get_wrapper_code(wrapper_name, wrapper);
8118 return wrapper;
8119}
8120
8121//______________________________________________________________________________
8122//
8123// ClassInfo interface
8124//
8125
8126////////////////////////////////////////////////////////////////////////////////
8127/// Return true if the entity pointed to by 'declid' is declared in
8128/// the context described by 'info'. If info is null, look into the
8129/// global scope (translation unit scope).
8130
8131Bool_t TCling::ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const
8132{
8133 if (!declid)
8134 return kFALSE;
8135
8136 const clang::DeclContext *ctxt = nullptr;
8137 if (info) {
8138 ctxt = clang::Decl::castToDeclContext(((TClingClassInfo*)info)->GetDecl());
8139 } else {
8140 ctxt = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
8141 }
8142 if (!ctxt)
8143 return kFALSE;
8144
8145 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
8146 if (!decl)
8147 return kFALSE;
8148
8149 const clang::DeclContext *declDC = decl->getDeclContext();
8150 // ClassInfo_t-s are always "spellable" scopes, never unnamed or inline ones.
8151 while (true) {
8152 if (declDC->isTransparentContext()) {
8153 declDC = declDC->getParent();
8154 continue;
8155 }
8156 if (const auto *declRD = llvm::dyn_cast<clang::RecordDecl>(declDC)) {
8157 if (declRD->isAnonymousStructOrUnion()) {
8158 declDC = declRD->getParent();
8159 continue;
8160 }
8161 }
8162 if (const auto *declNS = llvm::dyn_cast<clang::NamespaceDecl>(declDC)) {
8163 if (declNS->isAnonymousNamespace() || declNS->isInlineNamespace()) {
8164 declDC = declNS->getParent();
8165 continue;
8166 }
8167 }
8168 break;
8169 }
8170
8171 return declDC->Equals(ctxt);
8172}
8173
8174////////////////////////////////////////////////////////////////////////////////
8175
8177{
8178 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8179 return TClinginfo->ClassProperty();
8180}
8181
8182////////////////////////////////////////////////////////////////////////////////
8183
8184void TCling::ClassInfo_Delete(ClassInfo_t* cinfo) const
8185{
8186 delete (TClingClassInfo*) cinfo;
8187}
8188
8189////////////////////////////////////////////////////////////////////////////////
8190
8191void TCling::ClassInfo_Delete(ClassInfo_t* cinfo, void* arena) const
8192{
8193 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8194 TClinginfo->Delete(arena,*fNormalizedCtxt);
8195}
8196
8197////////////////////////////////////////////////////////////////////////////////
8198
8199void TCling::ClassInfo_DeleteArray(ClassInfo_t* cinfo, void* arena, bool dtorOnly) const
8200{
8201 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8202 TClinginfo->DeleteArray(arena, dtorOnly,*fNormalizedCtxt);
8203}
8204
8205////////////////////////////////////////////////////////////////////////////////
8206
8207void TCling::ClassInfo_Destruct(ClassInfo_t* cinfo, void* arena) const
8208{
8209 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8210 TClinginfo->Destruct(arena,*fNormalizedCtxt);
8211}
8212
8213////////////////////////////////////////////////////////////////////////////////
8214
8215ClassInfo_t* TCling::ClassInfo_Factory(Bool_t all) const
8216{
8218 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), all);
8219}
8220
8221////////////////////////////////////////////////////////////////////////////////
8222
8223ClassInfo_t* TCling::ClassInfo_Factory(ClassInfo_t* cinfo) const
8224{
8225 return (ClassInfo_t*) new TClingClassInfo(*(TClingClassInfo*)cinfo);
8226}
8227
8228////////////////////////////////////////////////////////////////////////////////
8229
8230ClassInfo_t* TCling::ClassInfo_Factory(const char* name) const
8231{
8233 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), name);
8234}
8235
8236ClassInfo_t* TCling::ClassInfo_Factory(DeclId_t declid) const
8237{
8239 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), (const clang::Decl*)declid);
8240}
8241
8242
8243////////////////////////////////////////////////////////////////////////////////
8244
8245int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
8246{
8247 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8248 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
8249}
8250
8251////////////////////////////////////////////////////////////////////////////////
8252
8253bool TCling::ClassInfo_HasDefaultConstructor(ClassInfo_t* cinfo, Bool_t testio) const
8254{
8255 TClingClassInfo *TClinginfo = (TClingClassInfo *) cinfo;
8257}
8258
8259////////////////////////////////////////////////////////////////////////////////
8260
8261bool TCling::ClassInfo_HasMethod(ClassInfo_t* cinfo, const char* name) const
8262{
8263 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8264 return TClinginfo->HasMethod(name);
8265}
8266
8267////////////////////////////////////////////////////////////////////////////////
8268
8269void TCling::ClassInfo_Init(ClassInfo_t* cinfo, const char* name) const
8270{
8272 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8273 TClinginfo->Init(name);
8274}
8275
8276////////////////////////////////////////////////////////////////////////////////
8277
8278void TCling::ClassInfo_Init(ClassInfo_t* cinfo, int tagnum) const
8279{
8281 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8282 TClinginfo->Init(tagnum);
8283}
8284
8285////////////////////////////////////////////////////////////////////////////////
8286
8287bool TCling::ClassInfo_IsBase(ClassInfo_t* cinfo, const char* name) const
8288{
8289 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8290 return TClinginfo->IsBase(name);
8291}
8292
8293////////////////////////////////////////////////////////////////////////////////
8294
8295bool TCling::ClassInfo_IsEnum(const char* name) const
8296{
8298}
8299
8300////////////////////////////////////////////////////////////////////////////////
8301
8303{
8304 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8305 return TClinginfo->IsScopedEnum();
8306}
8307
8308
8309////////////////////////////////////////////////////////////////////////////////
8310
8312{
8313 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8314 return TClinginfo->GetUnderlyingType();
8315}
8316
8317
8318////////////////////////////////////////////////////////////////////////////////
8319
8320bool TCling::ClassInfo_IsLoaded(ClassInfo_t* cinfo) const
8321{
8322 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8323 return TClinginfo->IsLoaded();
8324}
8325
8326////////////////////////////////////////////////////////////////////////////////
8327
8328bool TCling::ClassInfo_IsValid(ClassInfo_t* cinfo) const
8329{
8330 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8331 return TClinginfo->IsValid();
8332}
8333
8334////////////////////////////////////////////////////////////////////////////////
8335
8336bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8337{
8338 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8339 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
8340}
8341
8342////////////////////////////////////////////////////////////////////////////////
8343
8344bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8345{
8346 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8347 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8348}
8349
8350////////////////////////////////////////////////////////////////////////////////
8351
8352int TCling::ClassInfo_Next(ClassInfo_t* cinfo) const
8353{
8354 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8355 return TClinginfo->Next();
8356}
8357
8358////////////////////////////////////////////////////////////////////////////////
8359
8360void* TCling::ClassInfo_New(ClassInfo_t* cinfo) const
8361{
8362 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8363 return TClinginfo->New(*fNormalizedCtxt);
8364}
8365
8366////////////////////////////////////////////////////////////////////////////////
8367
8368void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n) const
8369{
8370 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8371 return TClinginfo->New(n,*fNormalizedCtxt);
8372}
8373
8374////////////////////////////////////////////////////////////////////////////////
8375
8376void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n, void* arena) const
8377{
8378 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8379 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8380}
8381
8382////////////////////////////////////////////////////////////////////////////////
8383
8384void* TCling::ClassInfo_New(ClassInfo_t* cinfo, void* arena) const
8385{
8386 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8387 return TClinginfo->New(arena,*fNormalizedCtxt);
8388}
8389
8390////////////////////////////////////////////////////////////////////////////////
8391
8392Long_t TCling::ClassInfo_Property(ClassInfo_t* cinfo) const
8393{
8394 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8395 return TClinginfo->Property();
8396}
8397
8398////////////////////////////////////////////////////////////////////////////////
8399
8400int TCling::ClassInfo_Size(ClassInfo_t* cinfo) const
8401{
8402 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8403 return TClinginfo->Size();
8404}
8405
8406////////////////////////////////////////////////////////////////////////////////
8407
8408Longptr_t TCling::ClassInfo_Tagnum(ClassInfo_t* cinfo) const
8409{
8410 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8411 return TClinginfo->Tagnum();
8412}
8413
8414////////////////////////////////////////////////////////////////////////////////
8415
8416const char* TCling::ClassInfo_FileName(ClassInfo_t* cinfo) const
8417{
8418 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8419 return TClinginfo->FileName();
8420}
8421
8422////////////////////////////////////////////////////////////////////////////////
8423
8424const char* TCling::ClassInfo_FullName(ClassInfo_t* cinfo) const
8425{
8426 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8427 TTHREAD_TLS_DECL(std::string,output);
8428 TClinginfo->FullName(output,*fNormalizedCtxt);
8429 return output.c_str(); // NOLINT
8430}
8431
8432////////////////////////////////////////////////////////////////////////////////
8433
8434const char* TCling::ClassInfo_Name(ClassInfo_t* cinfo) const
8435{
8436 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8437 return TClinginfo->Name();
8438}
8439
8440////////////////////////////////////////////////////////////////////////////////
8441
8442const char* TCling::ClassInfo_Title(ClassInfo_t* cinfo) const
8443{
8444 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8445 return TClinginfo->Title();
8446}
8447
8448////////////////////////////////////////////////////////////////////////////////
8449
8450const char* TCling::ClassInfo_TmpltName(ClassInfo_t* cinfo) const
8451{
8452 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8453 return TClinginfo->TmpltName();
8454}
8455
8456
8457
8458//______________________________________________________________________________
8459//
8460// BaseClassInfo interface
8461//
8462
8463////////////////////////////////////////////////////////////////////////////////
8464
8465void TCling::BaseClassInfo_Delete(BaseClassInfo_t* bcinfo) const
8466{
8467 delete(TClingBaseClassInfo*) bcinfo;
8468}
8469
8470////////////////////////////////////////////////////////////////////////////////
8471
8472BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo) const
8473{
8475 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8476 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo);
8477}
8478
8479////////////////////////////////////////////////////////////////////////////////
8480
8481BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* derived,
8482 ClassInfo_t* base) const
8483{
8485 TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
8486 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) base;
8487 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo, TClinginfoBase);
8488}
8489
8490////////////////////////////////////////////////////////////////////////////////
8491
8492int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo) const
8493{
8494 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8495 return TClinginfo->Next();
8496}
8497
8498////////////////////////////////////////////////////////////////////////////////
8499
8500int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo, int onlyDirect) const
8501{
8502 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8503 return TClinginfo->Next(onlyDirect);
8504}
8505
8506////////////////////////////////////////////////////////////////////////////////
8507
8508Longptr_t TCling::BaseClassInfo_Offset(BaseClassInfo_t* toBaseClassInfo, void * address, bool isDerivedObject) const
8509{
8510 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) toBaseClassInfo;
8511 return TClinginfo->Offset(address, isDerivedObject);
8512}
8513
8514////////////////////////////////////////////////////////////////////////////////
8515
8516Longptr_t TCling::ClassInfo_GetBaseOffset(ClassInfo_t* fromDerived, ClassInfo_t* toBase, void * address, bool isDerivedObject) const
8517{
8518 TClingClassInfo* TClinginfo = (TClingClassInfo*) fromDerived;
8519 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) toBase;
8520 // Offset to the class itself.
8521 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8522 return 0;
8523 }
8524 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8525}
8526
8527////////////////////////////////////////////////////////////////////////////////
8528
8529Long_t TCling::BaseClassInfo_Property(BaseClassInfo_t* bcinfo) const
8530{
8531 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8532 return TClinginfo->Property();
8533}
8534
8535////////////////////////////////////////////////////////////////////////////////
8536
8537ClassInfo_t *TCling::BaseClassInfo_ClassInfo(BaseClassInfo_t *bcinfo) const
8538{
8539 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8540 return (ClassInfo_t *)TClinginfo->GetBase();
8541}
8542
8543////////////////////////////////////////////////////////////////////////////////
8544
8545Longptr_t TCling::BaseClassInfo_Tagnum(BaseClassInfo_t* bcinfo) const
8546{
8547 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8548 return TClinginfo->Tagnum();
8549}
8550
8551////////////////////////////////////////////////////////////////////////////////
8552
8553const char* TCling::BaseClassInfo_FullName(BaseClassInfo_t* bcinfo) const
8554{
8555 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8556 TTHREAD_TLS_DECL(std::string,output);
8557 TClinginfo->FullName(output,*fNormalizedCtxt);
8558 return output.c_str(); // NOLINT
8559}
8560
8561////////////////////////////////////////////////////////////////////////////////
8562
8563const char* TCling::BaseClassInfo_Name(BaseClassInfo_t* bcinfo) const
8564{
8565 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8566 return TClinginfo->Name();
8567}
8568
8569////////////////////////////////////////////////////////////////////////////////
8570
8571const char* TCling::BaseClassInfo_TmpltName(BaseClassInfo_t* bcinfo) const
8572{
8573 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8574 return TClinginfo->TmpltName();
8575}
8576
8577//______________________________________________________________________________
8578//
8579// DataMemberInfo interface
8580//
8581
8582////////////////////////////////////////////////////////////////////////////////
8583
8584int TCling::DataMemberInfo_ArrayDim(DataMemberInfo_t* dminfo) const
8585{
8586 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8587 return TClinginfo->ArrayDim();
8588}
8589
8590////////////////////////////////////////////////////////////////////////////////
8591
8592void TCling::DataMemberInfo_Delete(DataMemberInfo_t* dminfo) const
8593{
8594 delete(TClingDataMemberInfo*) dminfo;
8595}
8596
8597////////////////////////////////////////////////////////////////////////////////
8598
8599DataMemberInfo_t* TCling::DataMemberInfo_Factory(ClassInfo_t* clinfo, TDictionary::EMemberSelection selection) const
8600{
8602 TClingClassInfo* TClingclass_info = (TClingClassInfo*) clinfo;
8603 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), TClingclass_info, selection);
8604}
8605
8606////////////////////////////////////////////////////////////////////////////////
8607
8608DataMemberInfo_t* TCling::DataMemberInfo_Factory(DeclId_t declid, ClassInfo_t* clinfo) const
8609{
8611 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8612 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8613 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), vd, (TClingClassInfo*)clinfo);
8614}
8615
8616////////////////////////////////////////////////////////////////////////////////
8617
8618DataMemberInfo_t* TCling::DataMemberInfo_FactoryCopy(DataMemberInfo_t* dminfo) const
8619{
8620 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8621 return (DataMemberInfo_t*) new TClingDataMemberInfo(*TClinginfo);
8622}
8623
8624////////////////////////////////////////////////////////////////////////////////
8625
8626bool TCling::DataMemberInfo_IsValid(DataMemberInfo_t* dminfo) const
8627{
8628 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8629 return TClinginfo->IsValid();
8630}
8631
8632////////////////////////////////////////////////////////////////////////////////
8633
8634int TCling::DataMemberInfo_MaxIndex(DataMemberInfo_t* dminfo, Int_t dim) const
8635{
8636 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8637 return TClinginfo->MaxIndex(dim);
8638}
8639
8640////////////////////////////////////////////////////////////////////////////////
8641
8642int TCling::DataMemberInfo_Next(DataMemberInfo_t* dminfo) const
8643{
8644 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8645 return TClinginfo->Next();
8646}
8647
8648////////////////////////////////////////////////////////////////////////////////
8649
8650Longptr_t TCling::DataMemberInfo_Offset(DataMemberInfo_t* dminfo) const
8651{
8652 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8653 return TClinginfo->Offset();
8654}
8655
8656////////////////////////////////////////////////////////////////////////////////
8657
8658Long_t TCling::DataMemberInfo_Property(DataMemberInfo_t* dminfo) const
8659{
8660 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8661 return TClinginfo->Property();
8662}
8663
8664////////////////////////////////////////////////////////////////////////////////
8665
8666Long_t TCling::DataMemberInfo_TypeProperty(DataMemberInfo_t* dminfo) const
8667{
8668 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8669 return TClinginfo->TypeProperty();
8670}
8671
8672////////////////////////////////////////////////////////////////////////////////
8673
8674int TCling::DataMemberInfo_TypeSize(DataMemberInfo_t* dminfo) const
8675{
8676 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8677 return TClinginfo->TypeSize();
8678}
8679
8680////////////////////////////////////////////////////////////////////////////////
8681
8682const char* TCling::DataMemberInfo_TypeName(DataMemberInfo_t* dminfo) const
8683{
8684 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8685 return TClinginfo->TypeName();
8686}
8687
8688////////////////////////////////////////////////////////////////////////////////
8689
8690const char* TCling::DataMemberInfo_TypeTrueName(DataMemberInfo_t* dminfo) const
8691{
8692 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8693 return TClinginfo->TypeTrueName(*fNormalizedCtxt);
8694}
8695
8696////////////////////////////////////////////////////////////////////////////////
8697
8698const char* TCling::DataMemberInfo_Name(DataMemberInfo_t* dminfo) const
8699{
8700 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8701 return TClinginfo->Name();
8702}
8703
8704////////////////////////////////////////////////////////////////////////////////
8705
8706const char* TCling::DataMemberInfo_Title(DataMemberInfo_t* dminfo) const
8707{
8708 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8709 return TClinginfo->Title();
8710}
8711
8712////////////////////////////////////////////////////////////////////////////////
8713
8714const char* TCling::DataMemberInfo_ValidArrayIndex(DataMemberInfo_t* dminfo) const
8715{
8716 TTHREAD_TLS_DECL(std::string,result);
8717
8718 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8719 result = TClinginfo->ValidArrayIndex().str();
8720 return result.c_str(); // NOLINT
8721}
8722
8723////////////////////////////////////////////////////////////////////////////////
8724
8725void TCling::SetDeclAttr(DeclId_t declId, const char* attribute)
8726{
8727 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8728 ASTContext &C = decl->getASTContext();
8729 decl->addAttr(AnnotateAttr::CreateImplicit(C, attribute, nullptr, 0));
8730}
8731
8732//______________________________________________________________________________
8733//
8734// Function Template interface
8735//
8736
8737////////////////////////////////////////////////////////////////////////////////
8738
8739static void ConstructorName(std::string &name, const clang::Decl *decl,
8740 cling::Interpreter &interp,
8741 const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
8742{
8743 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8744 if (!td) return;
8745
8746 clang::QualType qualType(td->getTypeForDecl(),0);
8747 ROOT::TMetaUtils::GetNormalizedName(name, qualType, interp, normCtxt);
8748 unsigned int level = 0;
8749 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8750 if (name[cursor] == '>') ++level;
8751 else if (name[cursor] == '<' && level) --level;
8752 else if (level == 0 && name[cursor] == ':') {
8753 name.erase(0,cursor+1);
8754 break;
8755 }
8756 }
8757}
8758
8759////////////////////////////////////////////////////////////////////////////////
8760
8761void TCling::GetFunctionName(const clang::Decl *decl, std::string &output) const
8762{
8763 output.clear();
8764
8765 const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(decl);
8766 if (const auto *USD = llvm::dyn_cast<clang::UsingShadowDecl>(decl)) {
8767 FD = llvm::dyn_cast<clang::FunctionDecl>(USD->getTargetDecl());
8768 }
8769 if (!FD) {
8770 Error("GetFunctionName", "NULL Decl!");
8771 return;
8772 }
8773
8774 // For using-decls, show "Derived", not "Base", i.e. use the
8775 // name of the decl context of the UsingShadowDecl (aka `decl`)
8776 // not the name of FD's decl context.
8777 if (llvm::isa<clang::CXXConstructorDecl>(FD))
8778 {
8780
8781 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
8782 {
8784 output.insert(output.begin(), '~');
8785 } else {
8786 llvm::raw_string_ostream stream(output);
8787 auto printPolicy = decl->getASTContext().getPrintingPolicy();
8788 // Don't trigger fopen of the source file to count lines:
8789 printPolicy.AnonymousTagLocations = false;
8790 FD->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
8791 }
8792}
8793
8794////////////////////////////////////////////////////////////////////////////////
8795/// Return a unique identifier of the declaration represented by the
8796/// FuncTempInfo
8797
8799{
8800 return (DeclId_t)info;
8801}
8802
8803////////////////////////////////////////////////////////////////////////////////
8804/// Delete the FuncTempInfo_t
8805
8806void TCling::FuncTempInfo_Delete(FuncTempInfo_t * /* ft_info */) const
8807{
8808 // Currently the address of ft_info is actually the decl itself,
8809 // so we have nothing to do.
8810}
8811
8812////////////////////////////////////////////////////////////////////////////////
8813/// Construct a FuncTempInfo_t
8814
8815FuncTempInfo_t *TCling::FuncTempInfo_Factory(DeclId_t declid) const
8816{
8817 // Currently the address of ft_info is actually the decl itself,
8818 // so we have nothing to do.
8819
8820 return (FuncTempInfo_t*)const_cast<void*>(declid);
8821}
8822
8823////////////////////////////////////////////////////////////////////////////////
8824/// Construct a FuncTempInfo_t
8825
8826FuncTempInfo_t *TCling::FuncTempInfo_FactoryCopy(FuncTempInfo_t *ft_info) const
8827{
8828 // Currently the address of ft_info is actually the decl itself,
8829 // so we have nothing to do.
8830
8831 return (FuncTempInfo_t*)ft_info;
8832}
8833
8834////////////////////////////////////////////////////////////////////////////////
8835/// Check validity of a FuncTempInfo_t
8836
8837Bool_t TCling::FuncTempInfo_IsValid(FuncTempInfo_t *t_info) const
8838{
8839 // Currently the address of ft_info is actually the decl itself,
8840 // so we have nothing to do.
8841
8842 return t_info != nullptr;
8843}
8844
8845////////////////////////////////////////////////////////////////////////////////
8846/// Return the maximum number of template arguments of the
8847/// function template described by ft_info.
8848
8849UInt_t TCling::FuncTempInfo_TemplateNargs(FuncTempInfo_t *ft_info) const
8850{
8851 if (!ft_info) return 0;
8852 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8853 return ft->getTemplateParameters()->size();
8854}
8855
8856////////////////////////////////////////////////////////////////////////////////
8857/// Return the number of required template arguments of the
8858/// function template described by ft_info.
8859
8861{
8862 if (!ft_info) return 0;
8863 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8864 return ft->getTemplateParameters()->getMinRequiredArguments();
8865}
8866
8867////////////////////////////////////////////////////////////////////////////////
8868/// Return the property of the function template.
8869
8870Long_t TCling::FuncTempInfo_Property(FuncTempInfo_t *ft_info) const
8871{
8872 if (!ft_info) return 0;
8873
8874 long property = 0L;
8875 property |= kIsCompiled;
8876
8877 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8878
8879 switch (ft->getAccess()) {
8880 case clang::AS_public:
8881 property |= kIsPublic;
8882 break;
8883 case clang::AS_protected:
8884 property |= kIsProtected;
8885 break;
8886 case clang::AS_private:
8887 property |= kIsPrivate;
8888 break;
8889 case clang::AS_none:
8890 if (ft->getDeclContext()->isNamespace())
8892 break;
8893 default:
8894 // IMPOSSIBLE
8895 assert(false && "Unexpected value for the access property value in Clang");
8896 break;
8897 }
8898
8899 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8900 if (const clang::CXXMethodDecl *md =
8901 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
8902 if (md->getMethodQualifiers().hasConst()) {
8903 property |= kIsConstant | kIsConstMethod;
8904 }
8905 if (md->isVirtual()) {
8906 property |= kIsVirtual;
8907 }
8908 if (md->isPureVirtual()) {
8909 property |= kIsPureVirtual;
8910 }
8911 if (const clang::CXXConstructorDecl *cd =
8912 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
8913 if (cd->isExplicit()) {
8914 property |= kIsExplicit;
8915 }
8916 }
8917 else if (const clang::CXXConversionDecl *cd =
8918 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
8919 if (cd->isExplicit()) {
8920 property |= kIsExplicit;
8921 }
8922 }
8923 }
8924 return property;
8925}
8926
8927////////////////////////////////////////////////////////////////////////////////
8928/// Return the property not already defined in Property
8929/// See TDictionary's EFunctionProperty
8930
8931Long_t TCling::FuncTempInfo_ExtraProperty(FuncTempInfo_t* ft_info) const
8932{
8933 if (!ft_info) return 0;
8934
8935 long property = 0L;
8936 property |= kIsCompiled;
8937
8938 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8939 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8940
8941 if (fd->isOverloadedOperator())
8943 if (llvm::isa<clang::CXXConversionDecl>(fd))
8945 if (llvm::isa<clang::CXXConstructorDecl>(fd))
8947 if (llvm::isa<clang::CXXDestructorDecl>(fd))
8949 if (fd->isInlined())
8951 return property;
8952}
8953
8954////////////////////////////////////////////////////////////////////////////////
8955/// Return the name of this function template.
8956
8957void TCling::FuncTempInfo_Name(FuncTempInfo_t *ft_info, TString &output) const
8958{
8959 output.Clear();
8960 if (!ft_info) return;
8961 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8962 std::string buf;
8963 GetFunctionName(ft->getTemplatedDecl(), buf);
8964 output = buf;
8965}
8966
8967////////////////////////////////////////////////////////////////////////////////
8968/// Return the comments associates with this function template.
8969
8970void TCling::FuncTempInfo_Title(FuncTempInfo_t *ft_info, TString &output) const
8971{
8972 output.Clear();
8973 if (!ft_info) return;
8974 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8975
8976 // Iterate over the redeclarations, we can have multiple definitions in the
8977 // redecl chain (came from merging of pcms).
8978 if (const RedeclarableTemplateDecl *AnnotFD
8979 = ROOT::TMetaUtils::GetAnnotatedRedeclarable((const RedeclarableTemplateDecl*)ft)) {
8980 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
8981 output = A->getAnnotation().str();
8982 return;
8983 }
8984 }
8985 if (!ft->isFromASTFile()) {
8986 // Try to get the comment from the header file if present
8987 // but not for decls from AST file, where rootcling would have
8988 // created an annotation
8990 }
8991}
8992
8993
8994//______________________________________________________________________________
8995//
8996// MethodInfo interface
8997//
8998
8999////////////////////////////////////////////////////////////////////////////////
9000/// Interface to cling function
9001
9002void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
9003{
9004 delete(TClingMethodInfo*) minfo;
9005}
9006
9007////////////////////////////////////////////////////////////////////////////////
9008
9009void TCling::MethodInfo_CreateSignature(MethodInfo_t* minfo, TString& signature) const
9010{
9011 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9012 // The next call locks the interpreter mutex.
9013 info->CreateSignature(signature);
9014}
9015
9016////////////////////////////////////////////////////////////////////////////////
9017
9018MethodInfo_t* TCling::MethodInfo_Factory() const
9019{
9021 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl());
9022}
9023
9024////////////////////////////////////////////////////////////////////////////////
9025
9026MethodInfo_t* TCling::MethodInfo_Factory(ClassInfo_t* clinfo) const
9027{
9029 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
9030}
9031
9032////////////////////////////////////////////////////////////////////////////////
9033
9034MethodInfo_t* TCling::MethodInfo_Factory(DeclId_t declid) const
9035{
9036 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
9038 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), decl);
9039}
9040
9041////////////////////////////////////////////////////////////////////////////////
9042
9043MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
9044{
9045 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
9046}
9047
9048////////////////////////////////////////////////////////////////////////////////
9049
9050void* TCling::MethodInfo_InterfaceMethod(MethodInfo_t* minfo) const
9051{
9052 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9053 // The next call locks the interpreter mutex.
9054 return info->InterfaceMethod();
9055}
9056
9057////////////////////////////////////////////////////////////////////////////////
9058
9059bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
9060{
9061 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9062 return info->IsValid();
9063}
9064
9065////////////////////////////////////////////////////////////////////////////////
9066
9067int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
9068{
9069 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9070 return info->NArg();
9071}
9072
9073////////////////////////////////////////////////////////////////////////////////
9074
9075int TCling::MethodInfo_NDefaultArg(MethodInfo_t* minfo) const
9076{
9077 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9078 return info->NDefaultArg();
9079}
9080
9081////////////////////////////////////////////////////////////////////////////////
9082
9083int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
9084{
9085 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9086 return info->Next();
9087}
9088
9089////////////////////////////////////////////////////////////////////////////////
9090
9091Long_t TCling::MethodInfo_Property(MethodInfo_t* minfo) const
9092{
9093 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9094 // The next call locks the interpreter mutex.
9095 return info->Property();
9096}
9097
9098////////////////////////////////////////////////////////////////////////////////
9099
9101{
9102 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9103 // The next call locks the interpreter mutex.
9104 return info->ExtraProperty();
9105}
9106
9107////////////////////////////////////////////////////////////////////////////////
9108
9109TypeInfo_t* TCling::MethodInfo_Type(MethodInfo_t* minfo) const
9110{
9111 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9112 // The next call locks the interpreter mutex.
9113 return (TypeInfo_t*)info->Type();
9114}
9115
9116////////////////////////////////////////////////////////////////////////////////
9117
9118const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
9119{
9120 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9121 TTHREAD_TLS_DECL(TString, mangled_name);
9122 // The next call locks the interpreter mutex.
9123 mangled_name = info->GetMangledName();
9124 return mangled_name;
9125}
9126
9127////////////////////////////////////////////////////////////////////////////////
9128
9129const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
9130{
9131 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9132 // The next call locks the interpreter mutex.
9133 return info->GetPrototype();
9134}
9135
9136////////////////////////////////////////////////////////////////////////////////
9137
9138const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
9139{
9140 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9141 // The next call locks the interpreter mutex.
9142 return info->Name();
9143}
9144
9145////////////////////////////////////////////////////////////////////////////////
9146
9147const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
9148{
9149 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9150 // The next call locks the interpreter mutex.
9151 return info->TypeName();
9152}
9153
9154////////////////////////////////////////////////////////////////////////////////
9155
9156std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
9157{
9158 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9159 // The next part locks the interpreter mutex.
9160 if (info && info->IsValid())
9161 return info->Type()->NormalizedName(*fNormalizedCtxt);
9162 else
9163 return "";
9164}
9165
9166////////////////////////////////////////////////////////////////////////////////
9167
9168const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
9169{
9170 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9171 // The next call locks the interpreter mutex.
9172 return info->Title();
9173}
9174
9175////////////////////////////////////////////////////////////////////////////////
9176
9178{
9179 if (func) {
9180 return MethodInfo_MethodCallReturnType(func->fInfo);
9181 } else {
9182 return EReturnType::kOther;
9183 }
9184}
9185
9186////////////////////////////////////////////////////////////////////////////////
9187
9189{
9190 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9191 if (info && info->IsValid()) {
9192 TClingTypeInfo *typeinfo = info->Type();
9193 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
9194 if (QT->isEnumeralType()) {
9195 return EReturnType::kLong;
9196 } else if (QT->isPointerType()) {
9197 // Look for char*
9198 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
9199 if ( QT->isCharType() ) {
9200 return EReturnType::kString;
9201 } else {
9202 return EReturnType::kOther;
9203 }
9204 } else if ( QT->isFloatingType() ) {
9205 int sz = typeinfo->Size();
9206 if (sz == 4 || sz == 8) {
9207 // Support only float and double.
9208 return EReturnType::kDouble;
9209 } else {
9210 return EReturnType::kOther;
9211 }
9212 } else if ( QT->isIntegerType() ) {
9213 int sz = typeinfo->Size();
9214 if (sz <= 8) {
9215 // Support only up to long long ... but
9216 // FIXME the TMethodCall::Execute only
9217 // return long (4 bytes) ...
9218 // The v5 implementation of TMethodCall::ReturnType
9219 // was not making the distinction so we let it go
9220 // as is for now, but we really need to upgrade
9221 // TMethodCall::Execute ...
9222 return EReturnType::kLong;
9223 } else {
9224 return EReturnType::kOther;
9225 }
9226 } else {
9227 return EReturnType::kOther;
9228 }
9229 } else {
9230 return EReturnType::kOther;
9231 }
9232}
9233
9234//______________________________________________________________________________
9235//
9236// MethodArgInfo interface
9237//
9238
9239////////////////////////////////////////////////////////////////////////////////
9240
9241void TCling::MethodArgInfo_Delete(MethodArgInfo_t* marginfo) const
9242{
9243 delete(TClingMethodArgInfo*) marginfo;
9244}
9245
9246////////////////////////////////////////////////////////////////////////////////
9247
9248MethodArgInfo_t* TCling::MethodArgInfo_Factory() const
9249{
9251 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl());
9252}
9253
9254////////////////////////////////////////////////////////////////////////////////
9255
9256MethodArgInfo_t* TCling::MethodArgInfo_Factory(MethodInfo_t *minfo) const
9257{
9259 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl(), (TClingMethodInfo*)minfo);
9260}
9261
9262////////////////////////////////////////////////////////////////////////////////
9263
9264MethodArgInfo_t* TCling::MethodArgInfo_FactoryCopy(MethodArgInfo_t* marginfo) const
9265{
9266 return (MethodArgInfo_t*)
9268}
9269
9270////////////////////////////////////////////////////////////////////////////////
9271
9272bool TCling::MethodArgInfo_IsValid(MethodArgInfo_t* marginfo) const
9273{
9274 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9275 return info->IsValid();
9276}
9277
9278////////////////////////////////////////////////////////////////////////////////
9279
9280int TCling::MethodArgInfo_Next(MethodArgInfo_t* marginfo) const
9281{
9282 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9283 return info->Next();
9284}
9285
9286////////////////////////////////////////////////////////////////////////////////
9287
9288Long_t TCling::MethodArgInfo_Property(MethodArgInfo_t* marginfo) const
9289{
9290 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9291 return info->Property();
9292}
9293
9294////////////////////////////////////////////////////////////////////////////////
9295
9296const char* TCling::MethodArgInfo_DefaultValue(MethodArgInfo_t* marginfo) const
9297{
9298 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9299 return info->DefaultValue();
9300}
9301
9302////////////////////////////////////////////////////////////////////////////////
9303
9304const char* TCling::MethodArgInfo_Name(MethodArgInfo_t* marginfo) const
9305{
9306 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9307 return info->Name();
9308}
9309
9310////////////////////////////////////////////////////////////////////////////////
9311
9312const char* TCling::MethodArgInfo_TypeName(MethodArgInfo_t* marginfo) const
9313{
9314 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9315 return info->TypeName();
9316}
9317
9318////////////////////////////////////////////////////////////////////////////////
9319
9320std::string TCling::MethodArgInfo_TypeNormalizedName(MethodArgInfo_t* marginfo) const
9321{
9322 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9323 return info->Type()->NormalizedName(*fNormalizedCtxt);
9324}
9325
9326////////////////////////////////////////////////////////////////////////////////
9327
9328TypeInfo_t* TCling::MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
9329{
9330 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9331 return (TypeInfo_t*) info->Type();
9332}
9333
9334//______________________________________________________________________________
9335//
9336// TypeInfo interface
9337//
9338
9339////////////////////////////////////////////////////////////////////////////////
9340
9341void TCling::TypeInfo_Delete(TypeInfo_t* tinfo) const
9342{
9343 delete (TClingTypeInfo*) tinfo;
9344}
9345
9346////////////////////////////////////////////////////////////////////////////////
9347
9348TypeInfo_t* TCling::TypeInfo_Factory() const
9349{
9351 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl());
9352}
9353
9354////////////////////////////////////////////////////////////////////////////////
9355
9356TypeInfo_t* TCling::TypeInfo_Factory(const char *name) const
9357{
9359 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl(), name);
9360}
9361
9362////////////////////////////////////////////////////////////////////////////////
9363
9364TypeInfo_t* TCling::TypeInfo_FactoryCopy(TypeInfo_t* tinfo) const
9365{
9366 return (TypeInfo_t*) new TClingTypeInfo(*(TClingTypeInfo*)tinfo);
9367}
9368
9369////////////////////////////////////////////////////////////////////////////////
9370
9371void TCling::TypeInfo_Init(TypeInfo_t* tinfo, const char* name) const
9372{
9374 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9375 TClinginfo->Init(name);
9376}
9377
9378////////////////////////////////////////////////////////////////////////////////
9379
9380bool TCling::TypeInfo_IsValid(TypeInfo_t* tinfo) const
9381{
9382 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9383 return TClinginfo->IsValid();
9384}
9385
9386////////////////////////////////////////////////////////////////////////////////
9387
9388const char* TCling::TypeInfo_Name(TypeInfo_t* tinfo) const
9389{
9390 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9391 return TClinginfo->Name();
9392}
9393
9394////////////////////////////////////////////////////////////////////////////////
9395
9396Long_t TCling::TypeInfo_Property(TypeInfo_t* tinfo) const
9397{
9398 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9399 return TClinginfo->Property();
9400}
9401
9402////////////////////////////////////////////////////////////////////////////////
9403
9404int TCling::TypeInfo_RefType(TypeInfo_t* tinfo) const
9405{
9406 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9407 return TClinginfo->RefType();
9408}
9409
9410////////////////////////////////////////////////////////////////////////////////
9411
9412int TCling::TypeInfo_Size(TypeInfo_t* tinfo) const
9413{
9414 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9415 return TClinginfo->Size();
9416}
9417
9418////////////////////////////////////////////////////////////////////////////////
9419
9420const char* TCling::TypeInfo_TrueName(TypeInfo_t* tinfo) const
9421{
9422 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9423 return TClinginfo->TrueName(*fNormalizedCtxt);
9424}
9425
9426////////////////////////////////////////////////////////////////////////////////
9427
9428void* TCling::TypeInfo_QualTypePtr(TypeInfo_t* tinfo) const
9429{
9430 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9431 return TClinginfo->QualTypePtr();
9432}
9433
9434
9435//______________________________________________________________________________
9436//
9437// TypedefInfo interface
9438//
9439
9440////////////////////////////////////////////////////////////////////////////////
9441
9442void TCling::TypedefInfo_Delete(TypedefInfo_t* tinfo) const
9443{
9444 delete(TClingTypedefInfo*) tinfo;
9445}
9446
9447////////////////////////////////////////////////////////////////////////////////
9448
9449TypedefInfo_t* TCling::TypedefInfo_Factory() const
9450{
9452 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl());
9453}
9454
9455////////////////////////////////////////////////////////////////////////////////
9456
9457TypedefInfo_t* TCling::TypedefInfo_Factory(const char *name) const
9458{
9460 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl(), name);
9461}
9462
9463////////////////////////////////////////////////////////////////////////////////
9464
9465TypedefInfo_t* TCling::TypedefInfo_FactoryCopy(TypedefInfo_t* tinfo) const
9466{
9467 return (TypedefInfo_t*) new TClingTypedefInfo(*(TClingTypedefInfo*)tinfo);
9468}
9469
9470////////////////////////////////////////////////////////////////////////////////
9471
9472void TCling::TypedefInfo_Init(TypedefInfo_t* tinfo,
9473 const char* name) const
9474{
9476 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9477 TClinginfo->Init(name);
9478}
9479
9480////////////////////////////////////////////////////////////////////////////////
9481
9482bool TCling::TypedefInfo_IsValid(TypedefInfo_t* tinfo) const
9483{
9484 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9485 return TClinginfo->IsValid();
9486}
9487
9488////////////////////////////////////////////////////////////////////////////////
9489
9490Int_t TCling::TypedefInfo_Next(TypedefInfo_t* tinfo) const
9491{
9492 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9493 return TClinginfo->Next();
9494}
9495
9496////////////////////////////////////////////////////////////////////////////////
9497
9498Long_t TCling::TypedefInfo_Property(TypedefInfo_t* tinfo) const
9499{
9500 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9501 return TClinginfo->Property();
9502}
9503
9504////////////////////////////////////////////////////////////////////////////////
9505
9506int TCling::TypedefInfo_Size(TypedefInfo_t* tinfo) const
9507{
9508 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9509 return TClinginfo->Size();
9510}
9511
9512////////////////////////////////////////////////////////////////////////////////
9513
9514const char* TCling::TypedefInfo_TrueName(TypedefInfo_t* tinfo) const
9515{
9516 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9517 return TClinginfo->TrueName(*fNormalizedCtxt);
9518}
9519
9520////////////////////////////////////////////////////////////////////////////////
9521
9522const char* TCling::TypedefInfo_Name(TypedefInfo_t* tinfo) const
9523{
9524 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9525 return TClinginfo->Name();
9526}
9527
9528////////////////////////////////////////////////////////////////////////////////
9529
9530const char* TCling::TypedefInfo_Title(TypedefInfo_t* tinfo) const
9531{
9532 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9533 return TClinginfo->Title();
9534}
9535
9536////////////////////////////////////////////////////////////////////////////////
9537
9538bool TCling::IsSameType(const void * QualTypePtr1, const void * QualTypePtr2) const
9539{
9540 clang::QualType QT1 = clang::QualType::getFromOpaquePtr(QualTypePtr1);
9541 clang::QualType QT2 = clang::QualType::getFromOpaquePtr(QualTypePtr2);
9542 return fInterpreter->getCI()->getASTContext().hasSameType(QT1, QT2);
9543}
9544
9545////////////////////////////////////////////////////////////////////////////////
9546
9547bool TCling::IsIntegerType(const void * QualTypePtr) const
9548{
9549 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9550 return QT->hasIntegerRepresentation();
9551}
9552
9553////////////////////////////////////////////////////////////////////////////////
9554
9555bool TCling::IsSignedIntegerType(const void * QualTypePtr) const
9556{
9557 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9558 return QT->hasSignedIntegerRepresentation();
9559}
9560
9561////////////////////////////////////////////////////////////////////////////////
9562
9563bool TCling::IsUnsignedIntegerType(const void * QualTypePtr) const
9564{
9565 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9566 return QT->hasUnsignedIntegerRepresentation();
9567}
9568
9569////////////////////////////////////////////////////////////////////////////////
9570
9571bool TCling::IsFloatingType(const void * QualTypePtr) const
9572{
9573 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9574 return QT->hasFloatingRepresentation();
9575}
9576
9577////////////////////////////////////////////////////////////////////////////////
9578
9579bool TCling::IsPointerType(const void * QualTypePtr) const
9580{
9581 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9582 return QT->hasPointerRepresentation();
9583}
9584
9585////////////////////////////////////////////////////////////////////////////////
9586
9587bool TCling::IsVoidPointerType(const void * QualTypePtr) const
9588{
9589 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9590 return QT->isVoidPointerType();
9591}
9592
9593////////////////////////////////////////////////////////////////////////////////
9594
9596{
9597 clang::FunctionDecl *FD = (clang::FunctionDecl *) fdeclid;
9598 return llvm::isa_and_nonnull<clang::CXXMethodDecl>(FD);
9599}
9600
9601////////////////////////////////////////////////////////////////////////////////
9602
9604{
9605 if (!fInitialMutex) {
9607 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
9608 }
9610 }
9611 // We will "forget" this lock once we backed out of all interpreter frames.
9612 // Here we are entering one, so ++.
9614}
9615
9616////////////////////////////////////////////////////////////////////////////////
9617
9619{
9620 if (!fInitialMutex)
9621 return;
9622 if (fInitialMutex.fRecurseCount == 0) {
9623 Error("ForgetMutexState", "mutex state's recurse count already 0!");
9624 }
9625 else if (--fInitialMutex.fRecurseCount == 0) {
9626 // We have returned from all interpreter frames. Reset the initial lock state.
9627 fInitialMutex.fState.reset();
9628 }
9629}
9630
9631////////////////////////////////////////////////////////////////////////////////
9632/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
9633
9635{
9636 if (gInterpreterMutex) {
9637 if (delta) {
9638 auto typedDelta = static_cast<MutexStateAndRecurseCountDelta *>(delta);
9639 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP{typedDelta};
9640 gCoreMutex->Apply(std::move(typedDelta->fDelta));
9641 // Now that we have the lock, update the global
9642 R__ASSERT(fInitialMutex.fRecurseCount == 0 && "Inconsistent state of fInitialMutex! Another thread within Interpreter critical section.");
9643 std::swap(fInitialMutex, typedDelta->fInitialState);
9644 } else {
9645 // This case happens when EnableThreadSafety is first called from
9646 // the interpreter function we just handled.
9647 // Since thread safety was not enabled at the time we rewound, there was
9648 // no lock taken and even-though we should be locking the rest of this
9649 // interpreter handling/modifying code (since there might be threads in
9650 // flight), we can't because there would not be any lock guard to release the
9651 // locks
9653 Error("ApplyToInterpreterMutex",
9654 "After returning from user code that turned on thread safety support, we notice that fInitialMutex is already used ... "
9655 "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.");
9656 }
9657 }
9658}
9659
9660////////////////////////////////////////////////////////////////////////////////
9661/// Reset the interpreter lock to the state it had before interpreter-related
9662/// calls happened.
9663
9665{
9666 if (fInitialMutex) {
9667 // Need to start a new recurse count.
9668 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP(new MutexStateAndRecurseCountDelta());
9669 std::swap(uniqueP->fInitialState, fInitialMutex);
9670 uniqueP->fDelta = gCoreMutex->Rewind(*uniqueP->fInitialState.fState);
9671 return uniqueP.release();
9672 }
9674 return nullptr;
9675}
#define R__EXTERN
Definition DllImport.h:26
The file contains utilities which are foundational and could be used across the core component of ROO...
#define d(i)
Definition RSha256.hxx:102
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define 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:75
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:94
constexpr Ssiz_t kNPOS
Definition RtypesCore.h:117
long long Long64_t
Definition RtypesCore.h:69
unsigned long long ULong64_t
Definition RtypesCore.h:70
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
TClass *(* DictFuncPtr_t)()
Definition Rtypes.h:85
R__EXTERN TApplication * gApplication
R__EXTERN TClassTable * gClassTable
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:341
void TCling__TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:579
static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
Definition TCling.cxx:1299
static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
Definition TCling.cxx:7252
void TCling__InvalidateGlobal(const clang::Decl *D)
Definition TCling.cxx:574
bool TClingLookupHelper__AutoParse(const char *cname)
Allow calling autoparsing from TMetaUtils.
Definition TCling.cxx:894
R__EXTERN int optind
Definition TCling.cxx:317
void * TCling__LockCompilationDuringUserCodeExecution()
Lock the interpreter.
Definition TCling.cxx:368
void TCling__UpdateListsOnUnloaded(const cling::Transaction &T)
Definition TCling.cxx:569
void TCling__GetNormalizedContext(const ROOT::TMetaUtils::TNormalizedCtxt *&normCtxt)
Definition TCling.cxx:557
int TCling__LoadLibrary(const char *library)
Load a library.
Definition TCling.cxx:333
void TCling__DEBUG__dump(clang::DeclContext *DC)
Definition TCling.cxx:224
ETupleOrdering
Check in what order the member of a tuple are layout.
Definition TCling.cxx:3905
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:351
static const std::unordered_set< std::string > gIgnoredPCMNames
List of dicts that have the PCM information already in the PCH.
Definition TCling.cxx:1939
static Bool_t s_IsLibraryLoaded(const char *libname, cling::Interpreter *fInterpreter)
Definition TCling.cxx:3129
const char * TCling__GetClassSharedLibs(const char *className, bool skipCore)
Definition TCling.cxx:633
static GlobalModuleIndex * loadGlobalModuleIndex(cling::Interpreter &interp)
Definition TCling.cxx:1080
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:903
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:1065
void TCling__UnlockCompilationDuringUserCodeExecution(void *)
Unlock the interpreter.
Definition TCling.cxx:379
static std::string AlternateTuple(const char *classname, const cling::LookupHelper &lh, Bool_t silent)
Definition TCling.cxx:3947
static bool R__InitStreamerInfoFactory()
Helper to initialize TVirtualStreamerInfo's factor early.
Definition TCling.cxx:1664
int TCling__AutoParseCallback(const char *className)
Definition TCling.cxx:628
clang::RecordDecl * TCling__DEBUG__DCtoRecordDecl(clang::DeclContext *DC)
Definition TCling.cxx:221
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:699
static bool HaveFullGlobalModuleIndex
Definition TCling.cxx:1079
bool TCling__TEST_isInvalidDecl(clang::Decl *D)
Definition TCling.cxx:251
void TCling__LibraryUnloadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:593
void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter *)
Definition TCling.cxx:564
const Decl * TCling__GetObjectDecl(TObject *obj)
Definition TCling.cxx:604
static ETupleOrdering IsTupleAscending()
Definition TCling.cxx:3923
void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Definition TCling.cxx:588
static void TCling__UpdateClassInfo(const NamedDecl *TD)
Update TClingClassInfo for a class (e.g. upon seeing a definition).
Definition TCling.cxx:389
clang::DeclContext * TCling__DEBUG__getDeclContext(clang::Decl *D)
Definition TCling.cxx:215
int TCling__CompileMacro(const char *fileName, const char *options)
Definition TCling.cxx:644
#define R__DLLEXPORT
Definition TCling.cxx:151
void * TCling__ResetInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:360
void TCling__DEBUG__decl_dump(void *D)
Definition TCling.cxx:233
int TCling__AutoLoadCallback(const char *className)
Definition TCling.cxx:623
static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
Definition TCling.cxx:1030
static void RegisterCxxModules(cling::Interpreter &clingInterp)
Definition TCling.cxx:1183
static void ConstructorName(std::string &name, const clang::Decl *decl, cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition TCling.cxx:8739
void TCling__PrintStackTrace()
Print a StackTrace!
Definition TCling.cxx:326
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:2423
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:7161
void TCling__DEBUG__printName(clang::Decl *D)
Definition TCling.cxx:236
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:680
static void PrintDlError(const char *dyLibName, const char *modulename)
Definition TCling.cxx:1964
TInterpreter * CreateInterpreter(void *interpLibHandle, const char *argv[])
Definition TCling.cxx:608
static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH, bool skipCore)
Definition TCling.cxx:6996
const char * fantomline
Definition TCling.cxx:841
void TCling__LibraryLoadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:583
static cling::Interpreter::CompilationResult ExecAutoParse(const char *what, Bool_t header, cling::Interpreter *interpreter)
Parse the payload or header.
Definition TCling.cxx:6332
static bool requiresRootMap(const char *rootmapfile)
Definition TCling.cxx:5512
clang::NamespaceDecl * TCling__DEBUG__DCtoNamespace(clang::DeclContext *DC)
Definition TCling.cxx:218
TObject * TCling__GetObjectAddress(const char *Name, void *&LookupCtx)
Definition TCling.cxx:600
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:1052
int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:639
void DestroyInterpreter(TInterpreter *interp)
Definition TCling.cxx:616
static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
Definition TCling.cxx:7273
void TCling__SplitAclicMode(const char *fileName, string &mode, string &args, string &io, string &fname)
Definition TCling.cxx:651
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)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:218
constexpr Int_t kWarning
Definition TError.h:46
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx: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:406
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2489
@ kReadPermission
Definition TSystem.h:45
Bool_t R_ISREG(Int_t mode)
Definition TSystem.h:116
R__EXTERN TSystem * gSystem
Definition TSystem.h:561
R__EXTERN TVirtualMutex * gGlobalMutex
#define R__LOCKGUARD(mutex)
#define R__WRITE_LOCKGUARD(mutex)
#define R__READ_LOCKGUARD(mutex)
const char * proto
Definition civetweb.c:17535
#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:3508
EState GetState() const
Definition TClass.h:488
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition TClass.cxx:2955
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:576
Version_t fClassVersion
Definition TClass.h:221
TList * GetListOfFunctionTemplates(Bool_t load=kTRUE)
Return TListOfFunctionTemplates for a class.
Definition TClass.cxx:3867
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:4984
static void RemoveClassDeclId(TDictionary::DeclId_t id)
Definition TClass.cxx:603
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:2274
std::atomic< TListOfEnums * > fEnums
Definition TClass.h:205
static Bool_t HasNoInfoOrEmuOrFwdDeclaredDecl(const char *)
Definition TClass.cxx:3467
virtual void PostLoadCheck()
Do the initialization that can only be done after the CINT dictionary has been fully populated and ca...
Definition TClass.cxx:6028
static TClass * LoadClass(const char *requestedname, Bool_t silent)
Helper function used by TClass::GetClass().
Definition TClass.cxx:5818
Int_t Size() const
Return size of object of this class.
Definition TClass.cxx:5773
@ 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:5981
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:2966
void ResetCaches()
To clean out all caches.
Definition TClass.cxx:4284
Long_t Property() const override
Returns the properties of the TClass as a bit field stored as a Long_t value.
Definition TClass.cxx:6155
static Int_t ReadRules()
Read the class.rules files from the default location:.
Definition TClass.cxx:1889
@ 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:3532
@ 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:3037
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:1006
bool Append(const std::string &str)
Append string to the storage if not added already.
Definition TCling.cxx:1014
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:6204
const char * MethodArgInfo_DefaultValue(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9296
bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const final
Definition TCling.cxx:8302
const char * TypeInfo_Name(TypeInfo_t *) const final
Definition TCling.cxx:9388
void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const final
Definition TCling.cxx:9050
void LoadEnums(TListOfEnums &cl) const final
Create list of pointers to enums for TClass cl.
Definition TCling.cxx:4395
void UpdateListOfGlobals() final
No op: see TClingCallbacks (used to update the list of globals)
Definition TCling.cxx:3885
bool TypedefInfo_IsValid(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9482
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE) final
Load library containing the specified class.
Definition TCling.cxx:6265
void CallFunc_Init(CallFunc_t *func) const final
Definition TCling.cxx:7940
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:3648
bool LibraryLoadingFailed(const std::string &, const std::string &, bool, bool)
Definition TCling.cxx:6568
void GenericError(const char *error) const final
Let the interpreter issue a generic error, and set its error state.
Definition TCling.cxx:7457
std::vector< void * > fRegisterModuleDyLibs
Definition TCling.h:138
void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const final
Definition TCling.cxx:7866
TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const final
Definition TCling.cxx:9109
std::vector< std::string > fAutoLoadLibStorage
Definition TCling.h:118
void CallFunc_Delete(CallFunc_t *func) const final
Definition TCling.cxx:7843
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:7500
void ResetAll() final
Reset the Cling state to its initial state.
Definition TCling.cxx:3724
void SetDeclAttr(DeclId_t, const char *) final
Definition TCling.cxx:8725
void HandleNewDecl(const void *DV, bool isDeserialized, std::set< TClass * > &modifiedClasses)
Definition TCling.cxx:496
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:6891
Long_t MethodInfo_Property(MethodInfo_t *minfo) const final
Definition TCling.cxx:9091
virtual void LoadFunctionTemplates(TClass *cl) const final
Create list of pointers to function templates for TClass cl.
Definition TCling.cxx:4442
bool ClassInfo_IsValidMethod(ClassInfo_t *info, const char *method, const char *proto, Longptr_t *offset, ROOT::EFunctionMatchMode=ROOT::kConversionMatch) const final
Definition TCling.cxx:8336
Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8658
int SetClassAutoparsing(int) final
Enable/Disable the Autoparsing of headers.
Definition TCling.cxx:7585
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:4489
void RewindDictionary() final
Rewind Cling dictionary to the point where it was before executing the current macro.
Definition TCling.cxx:3769
bool ClassInfo_IsValid(ClassInfo_t *info) const final
Definition TCling.cxx:8328
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition TCling.cxx:6765
int TypeInfo_RefType(TypeInfo_t *) const final
Definition TCling.cxx:9404
void CreateListOfBaseClasses(TClass *cl) const final
Create list of pointers to base class(es) for TClass cl.
Definition TCling.cxx:4371
ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const final
Definition TCling.cxx:8215
const char * MethodInfo_Name(MethodInfo_t *minfo) const final
Definition TCling.cxx:9138
BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const final
Definition TCling.cxx:8472
Bool_t LoadText(const char *text) const final
Load the declarations from text into the interpreter.
Definition TCling.cxx:7515
const char * GetSharedLibDeps(const char *lib, bool tryDyld=false) final
Get the list a libraries on which the specified lib depends.
Definition TCling.cxx:7289
EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const final
Definition TCling.cxx:9188
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition TCling.cxx:7714
Longptr_t ProcessLineAsynch(const char *line, EErrorCode *error=nullptr)
Let cling process a command line asynch.
Definition TCling.cxx:3560
bool MethodInfo_IsValid(MethodInfo_t *minfo) const final
Definition TCling.cxx:9059
FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8815
TypeInfo_t * TypeInfo_Factory() const final
Definition TCling.cxx:9348
bool IsClassAutoLoadingEnabled() const
Returns if class AutoLoading is currently enabled.
Definition TCling.cxx:7554
void InvalidateGlobal(const clang::Decl *D)
Invalidate cached TCling information for the given global declaration.
Definition TCling.cxx:6876
int Evaluate(const char *, TInterpreterValue &) final
Get the interpreter value corresponding to the statement.
Definition TCling.cxx:7678
std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const final
Definition TCling.cxx:7663
void UpdateListOfLoadedSharedLibraries()
Definition TCling.cxx:3348
const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9530
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:8065
void InitRootmapFile(const char *name)
Create a resource table and read the (possibly) three resource files, i.e.
Definition TCling.cxx:5655
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:6523
bool FunctionDeclId_IsMethod(DeclId_t fdeclid) const
Definition TCling.cxx:9595
void LoadPCM(std::string pcmFileNameFullPath)
Tries to load a rdict PCM, issues diagnostics if it fails.
Definition TCling.cxx:1811
void UpdateListOfMethods(TClass *cl) const final
Update the list of pointers to method for TClass cl This is now a nop.
Definition TCling.cxx:4507
virtual ~TCling()
Destroy the interpreter interface.
Definition TCling.cxx:1618
void AddFriendToClass(clang::FunctionDecl *, clang::CXXRecordDecl *) const
Inject function as a friend into klass.
Definition TCling.cxx:7767
void PrintIntro() final
No-op; see TRint instead.
Definition TCling.cxx:2648
Bool_t fCxxModulesEnabled
Definition TCling.h:128
int BaseClassInfo_Next(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8492
void RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
Internal function. Actually do the update of the ClassInfo when seeing.
Definition TCling.cxx:6635
CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const final
Definition TCling.cxx:7917
Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7901
void CallFunc_ResetArg(CallFunc_t *func) const final
Definition TCling.cxx:7966
const char * GetCurrentMacroName() const final
Return the file name of the currently interpreted file, included or not.
Definition TCling.cxx:5463
Bool_t IsLoaded(const char *filename) const final
Return true if the file has already been loaded by cint.
Definition TCling.cxx:3172
void SaveGlobalsContext() final
Save the current Cling state of global objects.
Definition TCling.cxx:3872
void CallFunc_IgnoreExtraArgs(CallFunc_t *func, bool ignore) const final
Definition TCling.cxx:7932
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:9634
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition TCling.cxx:6591
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:4723
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:8131
Bool_t IsLibraryLoaded(const char *libname) const final
Definition TCling.cxx:3138
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:7479
int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8584
TypeInfo_t * MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9328
DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8618
Bool_t HandleNewTransaction(const cling::Transaction &T)
Helper function to increase the internal Cling count of transactions that change the AST.
Definition TCling.cxx:3665
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:5528
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition TCling.h:153
int ClassInfo_Next(ClassInfo_t *info) const final
Definition TCling.cxx:8352
void SetErrmsgcallback(void *p) const final
Set a callback to receive error messages.
Definition TCling.cxx:7606
bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9272
int TypeInfo_Size(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9412
Int_t DeleteGlobal(void *obj) final
Delete obj from Cling symbol table so it cannot be accessed anymore.
Definition TCling.cxx:3783
int GetSecurityError() const final
Interface to cling function.
Definition TCling.cxx:7487
void SetTempLevel(int val) const final
Create / close a scope for temporaries.
Definition TCling.cxx:7642
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:8849
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:5155
TypedefInfo_t * TypedefInfo_Factory() const final
Definition TCling.cxx:9449
TObjArray * fRootmapFiles
Definition TCling.h:126
bool IsVoidPointerType(const void *QualTypePtr) const
Definition TCling.cxx:9587
Longptr_t ProcessLine(const char *line, EErrorCode *error=nullptr) final
Definition TCling.cxx:2453
int ClassInfo_Size(ClassInfo_t *info) const final
Definition TCling.cxx:8400
const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9312
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:5403
std::vector< std::pair< TClass *, DictFuncPtr_t > > fClassesToUpdate
Definition TCling.h:146
int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8642
const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9522
void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8465
Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const final
Definition TCling.cxx:9100
void LoadMacro(const char *filename, EErrorCode *error=nullptr) final
Load a macro file in cling's memory.
Definition TCling.cxx:3552
FuncTempInfo_t * FuncTempInfo_FactoryCopy(FuncTempInfo_t *) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8826
int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const final
Definition TCling.cxx:8634
Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const final
Check validity of a FuncTempInfo_t.
Definition TCling.cxx:8837
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:2662
bool ClassInfo_IsBase(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8287
void RecursiveRemove(TObject *obj) final
Delete object from cling symbol table so it can not be used anymore.
Definition TCling.cxx:3683
const char * DataMemberInfo_TypeName(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8682
DeclId_t GetDataMemberAtAddr(const void *addr) const final
Return pointer to cling DeclId for a data member with a given name.
Definition TCling.cxx:4950
void CallFunc_SetArgArray(CallFunc_t *func, Longptr_t *paramArr, Int_t nparam) const final
Definition TCling.cxx:8022
std::string CallFunc_GetWrapperCode(CallFunc_t *func) const final
Definition TCling.cxx:8112
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:9664
const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9304
Bool_t HasPCMForLibrary(const char *libname) const final
Return true if ROOT has cxxmodules pcm for a given library name.
Definition TCling.cxx:3147
void TypedefInfo_Init(TypedefInfo_t *tinfo, const char *name) const final
Definition TCling.cxx:9472
const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8706
Longptr_t CallFunc_ExecInt(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7885
void ClearStack() final
Delete existing temporary values.
Definition TCling.cxx:3085
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:7536
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:7356
MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const final
Definition TCling.cxx:7924
bool IsUnsignedIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9563
TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9465
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:5048
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:2393
std::string MethodArgInfo_TypeNormalizedName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9320
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:4832
Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9288
int TypedefInfo_Size(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9506
void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:7874
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:5200
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:6745
Int_t Load(const char *filenam, Bool_t system=kFALSE) final
Load a library file in cling's memory.
Definition TCling.cxx:3515
int TypedefInfo_Next(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9490
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:5007
void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const final
Definition TCling.cxx:9371
Bool_t SetSuspendAutoParsing(Bool_t value) final
Suspend the Autoparsing of headers.
Definition TCling.cxx:7596
int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8674
static void * fgSetOfSpecials
Definition TCling.h:105
const char * ClassInfo_Title(ClassInfo_t *info) const final
Definition TCling.cxx:8442
const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8698
const char * TypeName(const char *typeDesc) final
Return the absolute type of typeDesc.
Definition TCling.cxx:5478
ROOT::TMetaUtils::TNormalizedCtxt * fNormalizedCtxt
Definition TCling.h:134
bool IsSignedIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9555
void ForgetMutexState() final
Definition TCling.cxx:9618
int MethodInfo_Next(MethodInfo_t *minfo) const final
Definition TCling.cxx:9083
Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const final
Definition TCling.cxx:8176
void MethodInfo_Delete(MethodInfo_t *minfo) const final
Interface to cling function.
Definition TCling.cxx:9002
bool fIsShuttingDown
Definition TCling.h:187
void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9241
DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo, TDictionary::EMemberSelection selection) const final
Definition TCling.cxx:8599
void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const final
Definition TCling.cxx:8207
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:6110
Int_t UnloadAllSharedLibraryMaps() final
Unload the library map entries coming from all the loaded shared libraries.
Definition TCling.cxx:5998
void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const final
Definition TCling.cxx:8269
std::set< TClass * > & GetModTClasses()
Definition TCling.h:579
ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const final
Definition TCling.cxx:8537
TClingCallbacks * fClingCallbacks
Definition TCling.h:139
Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7893
Long_t ClassInfo_Property(ClassInfo_t *info) const final
Definition TCling.cxx:8392
Longptr_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8516
void UpdateEnumConstants(TEnum *enumObj, TClass *cl) const final
Definition TCling.cxx:421
void ExecuteWithArgsAndReturn(TMethod *method, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:5385
Bool_t IsErrorMessagesEnabled() const final
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition TCling.cxx:7342
TString fIncludePath
Definition TCling.h:115
int DisplayIncludePath(FILE *fout) const final
Interface to cling function.
Definition TCling.cxx:7419
void TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:6951
Long_t FuncTempInfo_Property(FuncTempInfo_t *) const final
Return the property of the function template.
Definition TCling.cxx:8870
TEnum * CreateEnum(void *VD, TClass *cl) const final
Definition TCling.cxx:469
const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9420
Int_t UnloadLibraryMap(const char *library) final
Unload library map entries coming from the specified library.
Definition TCling.cxx:6016
void RegisterTemporary(const TInterpreterValue &value)
Definition TCling.cxx:7687
MutexStateAndRecurseCount fInitialMutex
Definition TCling.h:174
const char * GetSharedLibs() final
Return the list of shared libraries loaded into the process.
Definition TCling.cxx:6989
int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9280
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx) final
Definition TCling.cxx:9603
Long_t TypeInfo_Property(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9396
const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const final
Definition TCling.cxx:9129
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:8860
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:2010
static Int_t ShallowAutoLoadImpl(const char *cls)
Definition TCling.cxx:6156
void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const final
Definition TCling.cxx:9009
Bool_t CheckClassTemplate(const char *name) final
Return true if there is a class template by the given name ...
Definition TCling.cxx:4349
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6974
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:2384
TObjArray * GetRootMapFiles() const final
Definition TCling.h:223
bool DataMemberInfo_IsValid(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8626
bool ClassInfo_IsEnum(const char *name) const final
Definition TCling.cxx:8295
int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9075
void CreateListOfMethods(TClass *cl) const final
Create list of pointers to methods for TClass cl.
Definition TCling.cxx:4498
Int_t RescanLibraryMap() final
Scan again along the dynamic path for library maps.
Definition TCling.cxx:5925
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:7615
const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9118
Bool_t fHeaderParsingOnDemand
Definition TCling.h:181
bool IsIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9547
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:5110
void * ClassInfo_New(ClassInfo_t *info) const final
Definition TCling.cxx:8360
int DisplayClass(FILE *fout, const char *name, int base, int start) const final
Definition TCling.cxx:7410
virtual void GetFunctionName(const clang::Decl *decl, std::string &name) const
Definition TCling.cxx:8761
void CreateListOfMethodArgs(TFunction *m) const final
Create list of pointers to method arguments for TMethod m.
Definition TCling.cxx:4523
virtual const char * GetSTLIncludePath() const final
Return the directory containing CINT's stl cintdlls.
Definition TCling.cxx:7401
MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9264
Longptr_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8508
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:4177
void * FindSym(const char *entry) const final
Interface to cling function.
Definition TCling.cxx:7448
void RegisterLoadedSharedLibrary(const char *name)
Register a new shared library name with the interpreter; add it to fSharedLibs.
Definition TCling.cxx:3415
void TypeInfo_Delete(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9341
int MethodInfo_NArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9067
DeclId_t GetDataMemberWithValue(const void *ptrvalue) const final
NOT IMPLEMENTED.
Definition TCling.cxx:4941
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition TCling.h:125
EReturnType MethodCallReturnType(TFunction *func) const final
Definition TCling.cxx:9177
void ProcessClassesToUpdate()
Definition TCling.cxx:1980
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:5133
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:4962
const char * MethodInfo_Title(MethodInfo_t *minfo) const final
Definition TCling.cxx:9168
TString fRootmapLoadPath
Definition TCling.h:116
const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8571
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:3098
const char * BaseClassInfo_FullName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8553
void CallFunc_SetArgs(CallFunc_t *func, const char *param) const final
Definition TCling.cxx:8030
int UnloadFile(const char *path) const final
Definition TCling.cxx:7648
void SetClassInfo(TClass *cl, Bool_t reload=kFALSE, Bool_t silent=kFALSE) final
Set pointer to the TClingClassInfo in TClass.
Definition TCling.cxx:4041
void CallFunc_Exec(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7850
bool IsPointerType(const void *QualTypePtr) const
Definition TCling.cxx:9579
bool IsFloatingType(const void *QualTypePtr) const
Definition TCling.cxx:9571
Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const final
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition TCling.cxx:8931
bool CallFunc_IsValid(CallFunc_t *func) const final
Definition TCling.cxx:7949
const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8563
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition TCling.h:135
const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8714
Int_t GetMore() const final
Return whether we are waiting for more input either because the collected input contains unbalanced b...
Definition TCling.cxx:4544
Bool_t fIsAutoParsingSuspended
Definition TCling.h:182
std::string ToString(const char *type, void *obj) final
Definition TCling.cxx:1023
DeclId_t GetDeclId(const llvm::GlobalValue *gv) const
Return pointer to cling DeclId for a global value.
Definition TCling.cxx:4872
void Execute(const char *function, const char *params, int *error=nullptr) final
Execute a global function with arguments params.
Definition TCling.cxx:5233
bool ClassInfo_IsLoaded(ClassInfo_t *info) const final
Definition TCling.cxx:8320
Longptr_t ClassInfo_Tagnum(ClassInfo_t *info) const final
Definition TCling.cxx:8408
Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8529
void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Longptr_t *Offset) const final
Definition TCling.cxx:8038
std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const final
Get the scopes representing using declarations of namespace.
Definition TCling.cxx:4478
const char * ClassInfo_FileName(ClassInfo_t *info) const final
Definition TCling.cxx:8416
void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const final
Return the comments associates with this function template.
Definition TCling.cxx:8970
const char * ClassInfo_TmpltName(ClassInfo_t *info) const final
Definition TCling.cxx:8450
void SaveContext() final
Save the current Cling state.
Definition TCling.cxx:3859
void LoadPCMImpl(TFile &pcmFile)
Tries to load a PCM from TFile; returns true on success.
Definition TCling.cxx:1696
Bool_t IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:6627
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:3740
void CodeComplete(const std::string &, size_t &, std::vector< std::string > &) final
The call to Cling's tab complition.
Definition TCling.cxx:7670
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:3754
const char * MapCppName(const char *) const final
Interface to cling function.
Definition TCling.cxx:7523
Longptr_t Calc(const char *line, EErrorCode *error=nullptr) final
Directly execute an executable statement (e.g.
Definition TCling.cxx:3585
Int_t ReloadAllSharedLibraryMaps() final
Reload the library map entries coming from all the loaded shared libraries, after first unloading the...
Definition TCling.cxx:5937
void UpdateListOfGlobalFunctions() final
No op: see TClingCallbacks (used to update the list of global functions)
Definition TCling.cxx:3892
void DataMemberInfo_Delete(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8592
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:5416
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:4516
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:2684
Int_t SetClassSharedLibs(const char *cls, const char *libs) final
Register the AutoLoading information for a class.
Definition TCling.cxx:6078
MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const final
Definition TCling.cxx:9043
std::set< const char * > fParsedPayloadsAddresses
Definition TCling.h:123
CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const final
Definition TCling.cxx:7958
MethodArgInfo_t * MethodArgInfo_Factory() const final
Definition TCling.cxx:9248
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition TCling.cxx:6739
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:5029
void ClassInfo_Delete(ClassInfo_t *info) const final
Definition TCling.cxx:8184
std::unique_ptr< cling::Interpreter > fInterpreter
Definition TCling.h:130
EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const final
Definition TCling.cxx:8311
void FuncTempInfo_Delete(FuncTempInfo_t *) const final
Delete the FuncTempInfo_t.
Definition TCling.cxx:8806
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:5177
Int_t DeleteVariable(const char *name) final
Undeclare obj called name.
Definition TCling.cxx:3798
const char * GetClassSharedLibs(const char *cls, bool skipCore=true) final
Get the list of shared libraries containing the code for class cls.
Definition TCling.cxx:7095
Longptr_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8650
CallFunc_t * CallFunc_Factory() const final
Definition TCling.cxx:7909
MethodInfo_t * MethodInfo_Factory() const final
Definition TCling.cxx:9018
Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8666
void ClearFileBusy() final
Reset the interpreter internal state in case a previous action was not correctly terminated.
Definition TCling.cxx:3077
cling::MetaProcessor * GetMetaProcessorImpl() const
Definition TCling.h:645
bool DiagnoseIfInterpreterException(const std::exception &e) const final
Definition TCling.cxx:2442
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:7546
std::set< size_t > fLookedUpClasses
Definition TCling.h:121
virtual void AddAvailableIndentifiers(TSeqCollection &Idents) final
Definition TCling.cxx:2358
void TypedefInfo_Delete(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9442
void Reset() final
Pressing Ctrl+C should forward here.
Definition TCling.cxx:3708
const char * TypedefInfo_TrueName(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9514
int SetClassAutoLoading(int) const final
Enable/Disable the AutoLoading of libraries.
Definition TCling.cxx:7567
const char * ClassInfo_FullName(ClassInfo_t *info) const final
Definition TCling.cxx:8424
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:6381
const char * MethodInfo_TypeName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9147
void CallFunc_SetArg(CallFunc_t *func, Long_t param) const final
Definition TCling.cxx:7974
const char * GetIncludePath() final
Refresh the list of include paths known to the interpreter and return it with -I prepended.
Definition TCling.cxx:7370
void UpdateListsOnUnloaded(const cling::Transaction &T)
Invalidate stored TCling state for declarations included in transaction ‘T’.
Definition TCling.cxx:6849
void UpdateClassInfoWithDecl(const clang::NamedDecl *ND)
Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
Definition TCling.cxx:6681
bool IsSameType(const void *QualTypePtr1, const void *QualTypePtr2) const
Definition TCling.cxx:9538
virtual void Initialize() final
Initialize the interpreter, once TROOT::fInterpreter is set.
Definition TCling.cxx:1636
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:8245
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:4771
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:8957
std::unique_ptr< cling::MetaProcessor > fMetaProcessor
Definition TCling.h:131
bool TypeInfo_IsValid(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9380
bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const final
Definition TCling.cxx:1906
std::string MethodInfo_TypeNormalizedName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9156
const char * ClassInfo_Name(ClassInfo_t *info) const final
Definition TCling.cxx:8434
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE) final
Generate a TClass for the given class.
Definition TCling.cxx:4554
ULong64_t fTransactionCount
Definition TCling.h:148
bool ClassInfo_HasDefaultConstructor(ClassInfo_t *info, Bool_t testio=kFALSE) const final
Definition TCling.cxx:8253
void EndOfLineAction() final
It calls a "fantom" method to synchronize user keyboard input and ROOT prompt line.
Definition TCling.cxx:3121
TypeInfo_t * TypeInfo_FactoryCopy(TypeInfo_t *) const final
Definition TCling.cxx:9364
void * TypeInfo_QualTypePtr(TypeInfo_t *tinfo) const
Definition TCling.cxx:9428
bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8261
void ClassInfo_DeleteArray(ClassInfo_t *info, void *arena, bool dtorOnly) const final
Definition TCling.cxx:8199
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:8690
virtual void ShutDown() final
Definition TCling.cxx:1655
void UpdateListOfTypes() final
No op: see TClingCallbacks (used to update the list of types)
Definition TCling.cxx:3899
Long_t TypedefInfo_Property(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9498
void RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Register Rdict data for future loading by LoadPCM;.
Definition TCling.cxx:1678
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:3569
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:4989
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition TCling.cxx:6754
Int_t LoadLibraryMap(const char *rootmapfile=nullptr) final
Load map between class and library.
Definition TCling.cxx:5741
Longptr_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8545
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6981
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 an on-disk file, usually with extension .root, that stores objects in a file-system-li...
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 Bool_t Declare(const char *code)=0
virtual const char * GetClassSharedLibs(const char *cls, bool skipCore=true)=0
std::vector< std::pair< std::string, int > > FwdDeclArgsToKeepCollection_t
TDictionary::DeclId_t DeclId_t
virtual TObjArray * GetRootMapFiles() const =0
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition TKey.h:28
A collection of TDataMember objects designed for fast access given a DeclId_t and for keep track of T...
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:355
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:979
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:408
static TClass * Class()
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:993
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1021
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:488
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:967
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:3045
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition TROOT.cxx:2762
static const std::vector< std::string > & AddExtraInterpreterArgs(const std::vector< std::string > &args)
Provide command line arguments to the interpreter construction.
Definition TROOT.cxx:2955
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition TROOT.cxx:3055
static const char **& GetExtraInterpreterArgs()
INTERNAL function! Used by rootcling to inject interpreter arguments through a C-interface layer.
Definition TROOT.cxx:2965
static const TString & GetSharedLibDir()
Get the shared libraries directory in the installation. Static utility function.
Definition TROOT.cxx:3034
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:417
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2244
const char * Data() const
Definition TString.h:376
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:931
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition TString.cxx:2264
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:623
TString & Prepend(const char *cs)
Definition TString.h:673
Bool_t IsNull() const
Definition TString.h:414
TString & Remove(Ssiz_t pos)
Definition TString.h:685
TString & Append(const char *cs)
Definition TString.h:572
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:2378
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:632
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:1274
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition TSystem.cxx:845
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition TSystem.cxx:836
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1665
virtual const char * GetIncludePath()
Get the list of include path.
Definition TSystem.cxx:3973
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition TSystem.cxx:4258
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition TSystem.cxx:1071
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1538
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition TSystem.cxx:1857
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:1398
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition TSystem.cxx:1081
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:1296
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition TSystem.cxx:853
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition TSystem.cxx:2489
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:934
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition TSystem.cxx:1795
virtual const char * FindDynamicLibrary(TString &lib, Bool_t quiet=kFALSE)
Find a dynamic library using the system search paths.
Definition TSystem.cxx:2034
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition TSystem.cxx:437
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:2836
virtual const char * WorkingDirectory()
Return working directory.
Definition TSystem.cxx:871
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1548
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition TSystem.cxx:1649
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition TSystem.cxx:887
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1032
virtual void StackTrace()
Print a stack trace.
Definition TSystem.cxx:734
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
Definition TSystem.cxx:2020
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 valid name of the C++ symbol/type (pass as 'input') that can be u...
std::pair< bool, int > GetTrivialIntegralReturnValue(const clang::FunctionDecl *funcCV, const cling::Interpreter &interp)
If the function contains 'just': return SomeValue; this routine will extract this value and return it...
std::string GetRealPath(const std::string &path)
void GetQualifiedName(std::string &qual_name, const clang::QualType &type, const clang::NamedDecl &forcontext)
Main implementation relying on GetFullyQualifiedTypeName All other GetQualifiedName functions leverag...
llvm::StringRef GetComment(const clang::Decl &decl, clang::SourceLocation *loc=nullptr)
Returns the comment (// striped away), annotating declaration in a meaningful for ROOT IO way.
void SetPathsForRelocatability(std::vector< std::string > &clingArgs)
Organise the parameters for cling in order to guarantee relocatability It treats the gcc toolchain an...
const clang::Type * GetUnderlyingType(clang::QualType type)
Return the base/underlying type of a chain of array or pointers type.
ROOT::ESTLType IsSTLCont(const clang::RecordDecl &cl)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container abs(result):...
bool ExtractAttrPropertyFromName(const clang::Decl &decl, const std::string &propName, std::string &propValue)
This routine counts on the "propName<separator>propValue" format.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
R__EXTERN TVirtualRWMutex * gCoreMutex
EFunctionMatchMode
@ kExactMatch
bool IsStdPairBase(std::string_view name)
Definition TClassEdit.h:188
bool IsStdArray(std::string_view name)
Definition TClassEdit.h:183
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
bool IsStdPair(std::string_view name)
Definition TClassEdit.h:184
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:208
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:182
@ kDropStlDefault
Definition TClassEdit.h:82
EComplexType GetComplexType(const char *)
static const char * what
Definition stlLoader.cc:5
Int_t fMode
Definition TSystem.h:125
Long_t fMemVirtual
Definition TSystem.h:200
Long_t fMemResident
Definition TSystem.h:199
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()