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)
634{
635 return ((TCling*)gCling)->GetClassSharedLibs(className);
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 fileContent += "#pragma link C++ class ";
789 if (iSTLType != sSTLTypes.end()) {
790 // STL class; we cannot (and don't need to) store iterators;
791 // their shadow and the compiler's version don't agree. So
792 // don't ask for the '+'
793 fileContent += *it + "::*;\n" ;
794 }
795 else {
796 // Not an STL class; we need to allow the I/O of contained
797 // classes (now that we have a dictionary for them).
798 fileContent += *it + "::*+;\n" ;
799 }
800 }
801 fileContent += "#endif\n";
802 //end(1)
803 //(2) prepare the file
804 FILE* filePointer;
805 filePointer = fopen(fileName, "w");
806 if (filePointer == nullptr) {
807 //can't open a file
808 return 1;
809 }
810 //end(2)
811 //write data into the file
812 fprintf(filePointer, "%s", fileContent.c_str());
813 fclose(filePointer);
814 }
815 //(3) checking if we can compile a macro, if not then cleaning
816 Int_t oldErrorIgnoreLevel = gErrorIgnoreLevel;
817 gErrorIgnoreLevel = kWarning; // no "Info: creating library..."
818 Int_t ret = gSystem->CompileMacro(fileName, "k");
819 gErrorIgnoreLevel = oldErrorIgnoreLevel;
820 if (ret == 0) { //can't compile a macro
821 return 2;
822 }
823 //end(3)
824 return 0;
825}
826
827int TCling_GenerateDictionary(const std::string& className,
828 const std::vector<std::string> &headers,
829 const std::vector<std::string> &fwdDecls,
830 const std::vector<std::string> &unknown)
831{
832 //This function automatically creates the "LinkDef.h" file for templated
833 //classes then executes CompileMacro on it.
834 //The name of the file depends on the class name, and it's not generated again
835 //if the file exist.
836 std::vector<std::string> classes;
837 classes.push_back(className);
838 return TCling_GenerateDictionary(classes, headers, fwdDecls, unknown);
839}
840
841//______________________________________________________________________________
842//
843//
844//
845
846// It is a "fantom" method to synchronize user keyboard input
847// and ROOT prompt line (for WIN32)
848const char* fantomline = "TRint::EndOfLineAction();";
849
850//______________________________________________________________________________
851//
852//
853//
854
855void* TCling::fgSetOfSpecials = nullptr;
856
857//______________________________________________________________________________
858//
859// llvm error handler through exceptions; see also cling/UserInterface
860//
861namespace {
862 // Handle fatal llvm errors by throwing an exception.
863 // Yes, throwing exceptions in error handlers is bad.
864 // Doing nothing is pretty terrible, too.
865 void exceptionErrorHandler(void * /*user_data*/,
866 const char *reason,
867 bool /*gen_crash_diag*/) {
868 throw std::runtime_error(std::string(">>> Interpreter compilation error:\n") + reason);
869 }
870}
871
872//______________________________________________________________________________
873//
874//
875//
876
877////////////////////////////////////////////////////////////////////////////////
878
879namespace{
880 // An instance of this class causes the diagnostics of clang to be suppressed
881 // during its lifetime
882 class clangDiagSuppr {
883 public:
884 clangDiagSuppr(clang::DiagnosticsEngine& diag): fDiagEngine(diag){
885 fOldDiagValue = fDiagEngine.getIgnoreAllWarnings();
886 fDiagEngine.setIgnoreAllWarnings(true);
887 }
888
889 ~clangDiagSuppr() {
890 fDiagEngine.setIgnoreAllWarnings(fOldDiagValue);
891 }
892 private:
893 clang::DiagnosticsEngine& fDiagEngine;
894 bool fOldDiagValue;
895 };
896
897}
898
899////////////////////////////////////////////////////////////////////////////////
900/// Allow calling autoparsing from TMetaUtils
902{
903 return gCling->AutoParse(cname);
904}
905
906////////////////////////////////////////////////////////////////////////////////
907/// Try hard to avoid looking up in the Cling database as this could enduce
908/// an unwanted autoparsing.
909
910bool TClingLookupHelper__ExistingTypeCheck(const std::string &tname,
911 std::string &result)
912{
913 result.clear();
914
915 unsigned long offset = 0;
916 if (strncmp(tname.c_str(), "const ", 6) == 0) {
917 offset = 6;
918 }
919 unsigned long end = tname.length();
920 while( end && (tname[end-1]=='&' || tname[end-1]=='*' || tname[end-1]==']') ) {
921 if ( tname[end-1]==']' ) {
922 --end;
923 while ( end && tname[end-1]!='[' ) --end;
924 }
925 --end;
926 }
927 std::string innerbuf;
928 const char *inner;
929 if (end != tname.length()) {
930 innerbuf = tname.substr(offset,end-offset);
931 inner = innerbuf.c_str();
932 } else {
933 inner = tname.c_str()+offset;
934 }
935
936 //if (strchr(tname.c_str(),'[')!=0) fprintf(stderr,"DEBUG: checking on %s vs %s %lu %lu\n",tname.c_str(),inner,offset,end);
937 if (gROOT->GetListOfClasses()->FindObject(inner)
938 || TClassTable::Check(inner,result) ) {
939 // This is a known class.
940 return true;
941 }
942
943 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
944 TDataType *type = (TDataType *)typeTable->THashTable::FindObject( inner );
945 if (type) {
946 // This is a raw type and an already loaded typedef.
947 const char *newname = type->GetFullTypeName();
948 if (type->GetType() == kLong64_t) {
949 newname = "Long64_t";
950 } else if (type->GetType() == kULong64_t) {
951 newname = "ULong64_t";
952 }
953 if (strcmp(inner,newname) == 0) {
954 return true;
955 }
956 if (offset) result = "const ";
957 result += newname;
958 if ( end != tname.length() ) {
959 result += tname.substr(end,tname.length()-end);
960 }
961 if (result == tname) result.clear();
962 return true;
963 }
964
965 // Check if the name is an enumerator
966 const auto lastPos = TClassEdit::GetUnqualifiedName(inner);
967 if (lastPos != inner) // Main switch: case 1 - scoped enum, case 2 global enum
968 {
969 // We have a scope
970 // All of this C gymnastic is to avoid allocations on the heap
971 const auto enName = lastPos;
972 const auto scopeNameSize = ((Long64_t)lastPos - (Long64_t)inner) / sizeof(decltype(*lastPos)) - 2;
973 char *scopeName = new char[scopeNameSize + 1];
974 strncpy(scopeName, inner, scopeNameSize);
975 scopeName[scopeNameSize] = '\0';
976 // Check if the scope is in the list of classes
977 if (auto scope = static_cast<TClass *>(gROOT->GetListOfClasses()->FindObject(scopeName))) {
978 auto enumTable = dynamic_cast<const THashList *>(scope->GetListOfEnums(false));
979 if (enumTable && enumTable->THashList::FindObject(enName)) { delete [] scopeName; return true; }
980 }
981 // It may still be in one of the loaded protoclasses
982 else if (auto scope = static_cast<TProtoClass *>(gClassTable->GetProtoNorm(scopeName))) {
983 auto listOfEnums = scope->GetListOfEnums();
984 if (listOfEnums) { // it could be null: no enumerators in the protoclass
985 auto enumTable = dynamic_cast<const THashList *>(listOfEnums);
986 if (enumTable && enumTable->THashList::FindObject(enName)) { delete [] scopeName; return true; }
987 }
988 }
989 delete [] scopeName;
990 } else
991 {
992 // We don't have any scope: this could only be a global enum
993 auto enumTable = dynamic_cast<const THashList *>(gROOT->GetListOfEnums());
994 if (enumTable && enumTable->THashList::FindObject(inner)) return true;
995 }
996
997 if (gCling->GetClassSharedLibs(inner))
998 {
999 // This is a class name.
1000 return true;
1001 }
1002
1003 return false;
1004}
1005
1006////////////////////////////////////////////////////////////////////////////////
1007
1009{
1010 fContent.reserve(size);
1011}
1012
1013////////////////////////////////////////////////////////////////////////////////
1014
1016{
1017 return fContent.c_str();
1018}
1019
1020////////////////////////////////////////////////////////////////////////////////
1021/// Append string to the storage if not added already.
1022
1023inline bool TCling::TUniqueString::Append(const std::string& str)
1024{
1025 bool notPresent = fLinesHashSet.emplace(fHashFunc(str)).second;
1026 if (notPresent){
1027 fContent+=str;
1028 }
1029 return notPresent;
1030}
1031
1032std::string TCling::ToString(const char* type, void* obj)
1033{
1034 return fInterpreter->toString(type, obj);
1035}
1036
1037////////////////////////////////////////////////////////////////////////////////
1038///\returns true if the module was loaded.
1039static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
1040{
1041 // When starting up ROOT, cling would load all modulemap files on the include
1042 // paths. However, in a ROOT session, it is very common to run aclic which
1043 // will invoke rootcling and possibly produce a modulemap and a module in
1044 // the current folder.
1045 //
1046 // Before failing, try loading the modulemap in the current folder and try
1047 // loading the requested module from it.
1048 std::string currentDir = gSystem->WorkingDirectory();
1049 assert(!currentDir.empty());
1051 if (gDebug > 2)
1052 ::Info("TCling::__LoadModule", "Preloading module %s. \n",
1053 ModuleName.c_str());
1054
1055 return interp.loadModule(ModuleName, /*Complain=*/true);
1056}
1057
1058////////////////////////////////////////////////////////////////////////////////
1059/// Loads the C++ modules that we require to run any ROOT program. This is just
1060/// supposed to make a C++ module from a modulemap available to the interpreter.
1061static void LoadModules(const std::vector<std::string> &modules, cling::Interpreter &interp)
1062{
1063 for (const auto &modName : modules)
1064 LoadModule(modName, interp);
1065}
1066
1067static bool IsFromRootCling() {
1068 // rootcling also uses TCling for generating the dictionary ROOT files.
1069 const static bool foundSymbol = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
1070 return foundSymbol;
1071}
1072
1073/// Checks if there is an ASTFile on disk for the given module \c M.
1074static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName = nullptr)
1075{
1076 const HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
1077
1078 std::string ModuleFileName;
1079 if (!HSOpts.PrebuiltModulePaths.empty())
1080 // Load the module from *only* in the prebuilt module path.
1081 ModuleFileName = PP.getHeaderSearchInfo().getPrebuiltModuleFileName(M->Name);
1082 if (FullFileName)
1083 *FullFileName = ModuleFileName;
1084
1085 return !ModuleFileName.empty();
1086}
1087
1088static bool HaveFullGlobalModuleIndex = false;
1089static GlobalModuleIndex *loadGlobalModuleIndex(cling::Interpreter &interp)
1090{
1091 CompilerInstance &CI = *interp.getCI();
1092 Preprocessor &PP = CI.getPreprocessor();
1093 auto ModuleManager = CI.getASTReader();
1094 assert(ModuleManager);
1095 // StringRef ModuleIndexPath = HSI.getModuleCachePath();
1096 // HeaderSearch& HSI = PP.getHeaderSearchInfo();
1097 // HSI.setModuleCachePath(TROOT::GetSharedLibDir().Data());
1098 std::string ModuleIndexPath = TROOT::GetSharedLibDir().Data();
1099 if (ModuleIndexPath.empty())
1100 return nullptr;
1101 // Get an existing global index. This loads it if not already loaded.
1102 ModuleManager->resetForReload();
1103 ModuleManager->loadGlobalIndex();
1104 GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex();
1105
1106 // For finding modules needing to be imported for fixit messages,
1107 // we need to make the global index cover all modules, so we do that here.
1108 if (!GlobalIndex && !HaveFullGlobalModuleIndex) {
1109 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1110 bool RecreateIndex = false;
1111 for (ModuleMap::module_iterator I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1112 Module *TheModule = I->second;
1113 // We want the index only of the prebuilt modules.
1114 if (!HasASTFileOnDisk(TheModule, PP))
1115 continue;
1116 LoadModule(TheModule->Name, interp);
1117 RecreateIndex = true;
1118 }
1119 if (RecreateIndex) {
1120 cling::Interpreter::PushTransactionRAII deserRAII(&interp);
1121 clang::GlobalModuleIndex::UserDefinedInterestingIDs IDs;
1122
1123 struct DefinitionFinder : public RecursiveASTVisitor<DefinitionFinder> {
1124 DefinitionFinder(clang::GlobalModuleIndex::UserDefinedInterestingIDs& IDs,
1125 clang::TranslationUnitDecl* TU) : DefinitionIDs(IDs) {
1126 TraverseDecl(TU);
1127 }
1128 bool VisitNamedDecl(NamedDecl *ND) {
1129 if (!ND->isFromASTFile())
1130 return true;
1131 if (!ND->getIdentifier())
1132 return true;
1133
1134 if (ND->getAccess() == AS_protected || ND->getAccess() == AS_private)
1135 return true;
1136
1137 if (TagDecl *TD = llvm::dyn_cast<TagDecl>(ND)) {
1138 if (TD->isCompleteDefinition())
1139 Register(TD);
1140 } else if (NamespaceDecl *NSD = llvm::dyn_cast<NamespaceDecl>(ND)) {
1141 Register(NSD, /*AddSingleEntry=*/ false);
1142 }
1143 else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(ND))
1144 Register(TND);
1145 // FIXME: Add the rest...
1146 return true; // continue decending
1147 }
1148 private:
1149 clang::GlobalModuleIndex::UserDefinedInterestingIDs &DefinitionIDs;
1150 void Register(const NamedDecl* ND, bool AddSingleEntry = true) {
1151 assert(ND->isFromASTFile());
1152 // FIXME: All decls should have an owning module once rootcling
1153 // updates its generated decls from within the LookupHelper & co.
1154 if (!ND->hasOwningModule()) {
1155#ifndef NDEBUG
1156 SourceManager &SM = ND->getASTContext().getSourceManager();
1157 SourceLocation Loc = ND->getLocation();
1158 const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Loc));
1159 (void)FE;
1160 assert(FE->getName().contains("input_line_"));
1161#endif
1162 return;
1163 }
1164
1165 Module *OwningModule = ND->getOwningModule()->getTopLevelModule();
1166 assert(OwningModule);
1167 assert(!ND->getName().empty() && "Empty name");
1168 if (AddSingleEntry && DefinitionIDs.count(ND->getName()))
1169 return;
1170 // FIXME: The FileEntry in not stable to serialize.
1171 // FIXME: We might end up with many times with the same module.
1172 // FIXME: We might end up two modules containing a definition.
1173 // FIXME: What do we do if no definition is found.
1174 DefinitionIDs[ND->getName()].push_back(OwningModule->getASTFile());
1175 }
1176 };
1177 DefinitionFinder defFinder(IDs, CI.getASTContext().getTranslationUnitDecl());
1178
1179 llvm::cantFail(GlobalModuleIndex::writeIndex(CI.getFileManager(),
1180 CI.getPCHContainerReader(),
1181 ModuleIndexPath,
1182 &IDs));
1183 ModuleManager->resetForReload();
1184 ModuleManager->loadGlobalIndex();
1185 GlobalIndex = ModuleManager->getGlobalIndex();
1186 }
1188 }
1189 return GlobalIndex;
1190}
1191
1192static void RegisterCxxModules(cling::Interpreter &clingInterp)
1193{
1194 if (!clingInterp.getCI()->getLangOpts().Modules)
1195 return;
1196
1197 // Loading of a module might deserialize.
1198 cling::Interpreter::PushTransactionRAII deserRAII(&clingInterp);
1199
1200 // Setup core C++ modules if we have any to setup.
1201
1202 // Load libc and stl first.
1203 // Load vcruntime module for windows
1204#ifdef R__WIN32
1205 LoadModule("vcruntime", clingInterp);
1206 LoadModule("services", clingInterp);
1207#endif
1208
1209#ifdef R__MACOSX
1210 LoadModule("Darwin", clingInterp);
1211#else
1212 LoadModule("libc", clingInterp);
1213#endif
1214 LoadModule("std", clingInterp);
1215
1216 LoadModule("_Builtin_intrinsics", clingInterp);
1217
1218 // Load core modules
1219 // This should be vector in order to be able to pass it to LoadModules
1220 std::vector<std::string> CoreModules = {"ROOT_Foundation_C",
1221 "ROOT_Config",
1222 "ROOT_Rtypes",
1223 "ROOT_Foundation_Stage1_NoRTTI",
1224 "Core",
1225 "Rint",
1226 "RIO"};
1227
1228 LoadModules(CoreModules, clingInterp);
1229
1230 // Take this branch only from ROOT because we don't need to preload modules in rootcling
1231 if (!IsFromRootCling()) {
1232 std::vector<std::string> CommonModules = {"MathCore"};
1233 LoadModules(CommonModules, clingInterp);
1234
1235 // These modules should not be preloaded but they fix issues.
1236 // FIXME: Hist is not a core module but is very entangled to MathCore and
1237 // causes issues.
1238 std::vector<std::string> FIXMEModules = {"Hist"};
1239 clang::CompilerInstance &CI = *clingInterp.getCI();
1240 clang::Preprocessor &PP = CI.getPreprocessor();
1241 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1242 if (MMap.findModule("RInterface"))
1243 FIXMEModules.push_back("RInterface");
1244
1245 LoadModules(FIXMEModules, clingInterp);
1246
1247 GlobalModuleIndex *GlobalIndex = nullptr;
1248 loadGlobalModuleIndex(clingInterp);
1249 // FIXME: The ASTReader still calls loadGlobalIndex and loads the file
1250 // We should investigate how to suppress it completely.
1251 GlobalIndex = CI.getASTReader()->getGlobalIndex();
1252
1253 llvm::StringSet<> KnownModuleFileNames;
1254 if (GlobalIndex)
1255 GlobalIndex->getKnownModuleFileNames(KnownModuleFileNames);
1256
1257 std::vector<std::string> PendingModules;
1258 PendingModules.reserve(256);
1259 for (auto I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1260 clang::Module *M = I->second;
1261 assert(M);
1262
1263 // We want to load only already created modules.
1264 std::string FullASTFilePath;
1265 if (!HasASTFileOnDisk(M, PP, &FullASTFilePath))
1266 continue;
1267
1268 if (GlobalIndex && KnownModuleFileNames.count(FullASTFilePath))
1269 continue;
1270
1271 if (M->IsUnimportable)
1272 continue;
1273
1274 if (GlobalIndex)
1275 LoadModule(M->Name, clingInterp);
1276 else {
1277 // FIXME: We may be able to remove those checks as cling::loadModule
1278 // checks if a module was alredy loaded.
1279 if (std::find(CoreModules.begin(), CoreModules.end(), M->Name) != CoreModules.end())
1280 continue; // This is a core module which was already loaded.
1281
1282 // Load system modules now and delay the other modules after we have
1283 // loaded all system ones.
1284 if (M->IsSystem)
1285 LoadModule(M->Name, clingInterp);
1286 else
1287 PendingModules.push_back(M->Name);
1288 }
1289 }
1290 LoadModules(PendingModules, clingInterp);
1291 }
1292
1293 // Check that the gROOT macro was exported by any core module.
1294 assert(clingInterp.getMacro("gROOT") && "Couldn't load gROOT macro?");
1295
1296 // `ERROR` and `PI` are from loading R related modules, which conflict with
1297 // user's code.
1298 clingInterp.declare(R"CODE(
1299#ifdef PI
1300# undef PI
1301#endif
1302#ifdef ERROR
1303# undef ERROR
1304#endif
1305 )CODE");
1306}
1307
1308static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
1309{
1310 std::string PreIncludes;
1311 bool hasCxxModules = clingInterp.getCI()->getLangOpts().Modules;
1312
1313 // For the list to also include string, we have to include it now.
1314 // rootcling does parts already if needed, e.g. genreflex does not want using
1315 // namespace std.
1316 if (IsFromRootCling()) {
1317 PreIncludes += "#include \"RtypesCore.h\"\n";
1318 } else {
1319 if (!hasCxxModules)
1320 PreIncludes += "#include \"Rtypes.h\"\n";
1321
1322 PreIncludes += gClassDefInterpMacro + "\n"
1323 + gInterpreterClassDef + "\n"
1324 "#undef ClassImp\n"
1325 "#define ClassImp(X);\n";
1326 }
1327 if (!hasCxxModules)
1328 PreIncludes += "#include <string>\n";
1329
1330 // We must include it even when we have modules because it is marked as
1331 // textual in the modulemap due to the nature of the assert header.
1332#ifndef R__WIN32
1333 PreIncludes += "#include <cassert>\n";
1334#endif
1335 PreIncludes += "using namespace std;\n";
1336 clingInterp.declare(PreIncludes);
1337}
1338
1339////////////////////////////////////////////////////////////////////////////////
1340/// Initialize the cling interpreter interface.
1341/// \param name name for TInterpreter
1342/// \param title title for TInterpreter
1343/// \param argv - array of arguments passed to the cling::Interpreter constructor
1344/// e.g. `-DFOO=bar`. The last element of the array must be `nullptr`.
1345
1346TCling::TCling(const char *name, const char *title, const char* const argv[], void *interpLibHandle)
1347: TInterpreter(name, title), fGlobalsListSerial(-1), fMapfile(nullptr),
1348 fRootmapFiles(nullptr), fLockProcessLine(true), fNormalizedCtxt(nullptr),
1349 fPrevLoadedDynLibInfo(nullptr), fClingCallbacks(nullptr), fAutoLoadCallBack(nullptr),
1351{
1352 fPrompt[0] = 0;
1353 const bool fromRootCling = IsFromRootCling();
1354
1355 fCxxModulesEnabled = false;
1356#ifdef R__USE_CXXMODULES
1357 fCxxModulesEnabled = true;
1358#endif
1359
1360 llvm::install_fatal_error_handler(&exceptionErrorHandler);
1361
1362 fTemporaries = new std::vector<cling::Value>();
1363
1364 std::vector<std::string> clingArgsStorage;
1365 clingArgsStorage.push_back("cling4root");
1366 for (const char* const* arg = argv; *arg; ++arg)
1367 clingArgsStorage.push_back(*arg);
1368
1369 // rootcling sets its arguments through TROOT::GetExtraInterpreterArgs().
1370 if (!fromRootCling) {
1372
1373 // Add -I early so ASTReader can find the headers.
1374 std::string interpInclude(TROOT::GetEtcDir().Data());
1375 clingArgsStorage.push_back("-I" + interpInclude);
1376
1377 // Add include path to etc/cling.
1378 clingArgsStorage.push_back("-I" + interpInclude + "/cling");
1379
1380 // Add include path to etc/cling.
1381 clingArgsStorage.push_back("-I" + interpInclude + "/cling/plugins/include");
1382
1383 // Add the root include directory and etc/ to list searched by default.
1384 clingArgsStorage.push_back(std::string(("-I" + TROOT::GetIncludeDir()).Data()));
1385
1386 // Add the current path to the include path
1387 // TCling::AddIncludePath(".");
1388
1389 // Attach the PCH (unless we have C++ modules enabled which provide the
1390 // same functionality).
1391 if (!fCxxModulesEnabled) {
1392 std::string pchFilename = interpInclude + "/allDict.cxx.pch";
1393 if (gSystem->Getenv("ROOT_PCH")) {
1394 pchFilename = gSystem->Getenv("ROOT_PCH");
1395 }
1396
1397 clingArgsStorage.push_back("-include-pch");
1398 clingArgsStorage.push_back(pchFilename);
1399 }
1400
1401 clingArgsStorage.push_back("-Wno-undefined-inline");
1402 clingArgsStorage.push_back("-fsigned-char");
1403 // The -O1 optimization flag has nasty side effects on Windows (32 and 64 bit)
1404 // See the GitHub issues #9809 and #9944
1405 // TODO: to be reviewed after the upgrade of LLVM & Clang
1406#ifndef _MSC_VER
1407 clingArgsStorage.push_back("-O1");
1408 // Disable optimized register allocation which is turned on automatically
1409 // by -O1, but seems to require -O2 to not explode in run time.
1410 clingArgsStorage.push_back("-mllvm");
1411 clingArgsStorage.push_back("-optimize-regalloc=0");
1412#endif
1413 }
1414
1415 // Process externally passed arguments if present.
1416 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv("EXTRA_CLING_ARGS");
1417 if (EnvOpt.has_value()) {
1418 StringRef Env(*EnvOpt);
1419 while (!Env.empty()) {
1420 StringRef Arg;
1421 std::tie(Arg, Env) = Env.split(' ');
1422 clingArgsStorage.push_back(Arg.str());
1423 }
1424 }
1425
1426 auto GetEnvVarPath = [](const std::string &EnvVar, std::vector<std::string> &Paths) {
1427 std::optional<std::string> EnvOpt = llvm::sys::Process::GetEnv(EnvVar);
1428 if (EnvOpt.has_value()) {
1429 StringRef Env(*EnvOpt);
1430 while (!Env.empty()) {
1431 StringRef Arg;
1432 std::tie(Arg, Env) = Env.split(ROOT::FoundationUtils::GetEnvPathSeparator());
1433 if (std::find(Paths.begin(), Paths.end(), Arg.str()) == Paths.end())
1434 Paths.push_back(Arg.str());
1435 }
1436 }
1437 };
1438
1439 if (fCxxModulesEnabled) {
1440 std::vector<std::string> Paths;
1441 // ROOT usually knows better where its libraries are. This way we can
1442 // discover modules without having to should thisroot.sh and should fix
1443 // gnuinstall.
1444 Paths.push_back(TROOT::GetSharedLibDir().Data());
1445 GetEnvVarPath("CLING_PREBUILT_MODULE_PATH", Paths);
1446 std::string EnvVarPath;
1447 for (const std::string& P : Paths)
1449 // FIXME: We should make cling -fprebuilt-module-path work.
1450 gSystem->Setenv("CLING_PREBUILT_MODULE_PATH", EnvVarPath.c_str());
1451 }
1452
1453 // FIXME: This only will enable frontend timing reports.
1454 EnvOpt = llvm::sys::Process::GetEnv("ROOT_CLING_TIMING");
1455 if (EnvOpt.has_value())
1456 clingArgsStorage.push_back("-ftime-report");
1457
1458 // Add the overlay file. Note that we cannot factor it out for both root
1459 // and rootcling because rootcling activates modules only if -cxxmodule
1460 // flag is passed.
1461 if (fCxxModulesEnabled && !fromRootCling) {
1462 // For now we prefer rootcling to enumerate explicitly its modulemaps.
1463 std::vector<std::string> ModuleMaps;
1464 std::string ModuleMapSuffix = ROOT::FoundationUtils::GetPathSeparator() + "ROOT.modulemap";
1465 ModuleMaps.push_back(TROOT::GetIncludeDir().Data() + ModuleMapSuffix);
1466 GetEnvVarPath("CLING_MODULEMAP_FILES", ModuleMaps);
1467
1468 std::string cwd = gSystem->WorkingDirectory();
1469 // Give highest precedence of the modulemap in the cwd if any.
1470 if (llvm::sys::fs::exists(cwd + ModuleMapSuffix))
1471 ModuleMaps.push_back(cwd + ModuleMapSuffix);
1472
1473 for (const std::string& M : ModuleMaps)
1474 clingArgsStorage.push_back("-fmodule-map-file=" + M);
1475
1476 std::string ModulesCachePath;
1477 EnvOpt = llvm::sys::Process::GetEnv("CLING_MODULES_CACHE_PATH");
1478 if (EnvOpt.has_value()){
1479 StringRef Env(*EnvOpt);
1480 assert(llvm::sys::fs::exists(Env) && "Path does not exist!");
1481 ModulesCachePath = Env.str();
1482 } else {
1483 ModulesCachePath = TROOT::GetSharedLibDir();
1484 }
1485
1486 clingArgsStorage.push_back("-fmodules-cache-path=" + ModulesCachePath);
1487 }
1488
1489 std::vector<const char*> interpArgs;
1490 for (std::vector<std::string>::const_iterator iArg = clingArgsStorage.begin(),
1491 eArg = clingArgsStorage.end(); iArg != eArg; ++iArg)
1492 interpArgs.push_back(iArg->c_str());
1493
1494 // Activate C++ modules support. If we are running within rootcling, it's up
1495 // to rootcling to set this flag depending on whether it wants to produce
1496 // C++ modules.
1497 TString vfsArg;
1498 if (fCxxModulesEnabled) {
1499 if (!fromRootCling) {
1500 // We only set this flag, rest is done by the CIFactory.
1501 interpArgs.push_back("-fmodules");
1502 interpArgs.push_back("-fno-implicit-module-maps");
1503 // We should never build modules during runtime, so let's enable the
1504 // module build remarks from clang to make it easier to spot when we do
1505 // this by accident.
1506 interpArgs.push_back("-Rmodule-build");
1507 }
1508 // ROOT implements its AutoLoading upon module's link directives. We
1509 // generate module A { header "A.h" link "A.so" export * } where ROOT's
1510 // facilities use the link directive to dynamically load the relevant
1511 // library. So, we need to suppress clang's default autolink behavior.
1512 interpArgs.push_back("-fno-autolink");
1513 }
1514
1515#ifdef R__FAST_MATH
1516 // Same setting as in rootcling_impl.cxx.
1517 interpArgs.push_back("-ffast-math");
1518#endif
1519
1520 TString llvmResourceDir = TROOT::GetEtcDir() + "/cling";
1521 // Add statically injected extra arguments, usually coming from rootcling.
1522 for (const char** extraArgs = TROOT::GetExtraInterpreterArgs();
1523 extraArgs && *extraArgs; ++extraArgs) {
1524 if (!strcmp(*extraArgs, "-resource-dir")) {
1525 // Take the next arg as the llvm resource directory.
1526 llvmResourceDir = *(++extraArgs);
1527 } else {
1528 interpArgs.push_back(*extraArgs);
1529 }
1530 }
1531
1532 std::vector<std::string> _empty;
1533 auto args = TROOT::AddExtraInterpreterArgs(_empty);
1534 for (const auto &arg: args)
1535 interpArgs.emplace_back(arg.c_str());
1536
1537 // Add the Rdict module file extension.
1538 cling::Interpreter::ModuleFileExtensions extensions;
1539 EnvOpt = llvm::sys::Process::GetEnv("ROOTDEBUG_RDICT");
1540 if (!EnvOpt.has_value())
1541 extensions.push_back(std::make_shared<TClingRdictModuleFileExtension>());
1542
1543 fInterpreter = std::make_unique<cling::Interpreter>(interpArgs.size(),
1544 &(interpArgs[0]),
1545 llvmResourceDir, extensions,
1546 interpLibHandle);
1547
1548 // Don't check whether modules' files exist.
1549 fInterpreter->getCI()->getPreprocessorOpts().DisablePCHOrModuleValidation =
1550 DisableValidationForModuleKind::All;
1551
1552 // Until we can disable AutoLoading during Sema::CorrectTypo() we have
1553 // to disable spell checking.
1554 fInterpreter->getCI()->getLangOpts().SpellChecking = false;
1555
1556 // Sync modules on/off between clang and us: clang turns it on for C++ >= 20.
1557 auto isModulesArg = [](const char* arg) { return !strcmp(arg, "-fmodules"); };
1558 bool hasModulesArg = std::find_if(interpArgs.begin(), interpArgs.end(), isModulesArg) != interpArgs.end();
1559 fInterpreter->getCI()->getLangOpts().Modules = hasModulesArg;
1560
1561 // We need stream that doesn't close its file descriptor, thus we are not
1562 // using llvm::outs. Keeping file descriptor open we will be able to use
1563 // the results in pipes (Savannah #99234).
1564 static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO, /*ShouldClose*/false);
1565 fMetaProcessor = std::make_unique<cling::MetaProcessor>(*fInterpreter, fMPOuts);
1566
1569
1570 // We are now ready (enough is loaded) to init the list of opaque typedefs.
1577
1578 // Disallow auto-parsing in rootcling
1579 fIsAutoParsingSuspended = fromRootCling;
1580
1581 ResetAll();
1582
1583 // Enable dynamic lookup
1584 if (!fromRootCling) {
1585 fInterpreter->enableDynamicLookup();
1586 }
1587
1588 // Enable ClinG's DefinitionShadower for ROOT.
1589 fInterpreter->getRuntimeOptions().AllowRedefinition = 1;
1590 auto &Policy = const_cast<clang::PrintingPolicy &>(fInterpreter->getCI()->getASTContext().getPrintingPolicy());
1591 // Print 'a<b<c> >' rather than 'a<b<c>>'.
1592 // FIXME: We should probably switch to the default printing policy setting
1593 // after adjusting tons of reference files.
1594 Policy.SplitTemplateClosers = true;
1595 // Keep default templare arguments, required for dictionary generation.
1596 Policy.SuppressDefaultTemplateArgs = false;
1597
1598
1599 // Attach cling callbacks last; they might need TROOT::fInterpreter
1600 // and should thus not be triggered during the equivalent of
1601 // TROOT::fInterpreter = new TCling;
1602 std::unique_ptr<TClingCallbacks>
1603 clingCallbacks(new TClingCallbacks(GetInterpreterImpl(), /*hasCodeGen*/ !fromRootCling));
1604 fClingCallbacks = clingCallbacks.get();
1606 fInterpreter->setCallbacks(std::move(clingCallbacks));
1607
1608 if (!fromRootCling) {
1609 cling::DynamicLibraryManager& DLM = *fInterpreter->getDynamicLibraryManager();
1610 // Make sure cling looks into ROOT's libdir, even if not part of LD_LIBRARY_PATH
1611 // e.g. because of an RPATH build.
1612 DLM.addSearchPath(TROOT::GetSharedLibDir().Data(), /*isUser=*/true,
1613 /*prepend=*/true);
1614 auto ShouldPermanentlyIgnore = [](llvm::StringRef FileName) -> bool{
1615 llvm::StringRef stem = llvm::sys::path::stem(FileName);
1616 return stem.startswith("libNew") || stem.startswith("libcppyy_backend");
1617 };
1618 // Initialize the dyld for AutoloadLibraryGenerator.
1619 DLM.initializeDyld(ShouldPermanentlyIgnore);
1620 }
1621}
1622
1623
1624////////////////////////////////////////////////////////////////////////////////
1625/// Destroy the interpreter interface.
1626
1628{
1629 // ROOT's atexit functions require the interepreter to be available.
1630 // Run them before shutting down.
1631 if (!IsFromRootCling())
1632 GetInterpreterImpl()->runAtExitFuncs();
1633 fIsShuttingDown = true;
1634 delete fMapfile;
1635 delete fRootmapFiles;
1636 delete fTemporaries;
1637 delete fNormalizedCtxt;
1638 delete fLookupHelper;
1639 gCling = nullptr;
1640}
1641
1642////////////////////////////////////////////////////////////////////////////////
1643/// Initialize the interpreter, once TROOT::fInterpreter is set.
1644
1646{
1648
1649 // We are set up. Enable ROOT's AutoLoading.
1650 if (IsFromRootCling())
1651 return;
1652
1653 // Read the rules before enabling the auto loading to not inadvertently
1654 // load the libraries for the classes concerned even-though the user is
1655 // *not* using them.
1656 // Note this call must happen before the first call to LoadLibraryMap.
1657 assert(GetRootMapFiles() == nullptr && "Must be called before LoadLibraryMap!");
1658 TClass::ReadRules(); // Read the default customization rules ...
1659
1661 SetClassAutoLoading(true);
1662}
1663
1665{
1666 fIsShuttingDown = true;
1667 ResetGlobals();
1668}
1669
1670////////////////////////////////////////////////////////////////////////////////
1671/// Helper to initialize TVirtualStreamerInfo's factor early.
1672/// Use static initialization to insure only one TStreamerInfo is created.
1674{
1675 // Use lambda since SetFactory return void.
1676 auto setFactory = []() {
1678 return kTRUE;
1679 };
1680 static bool doneFactory = setFactory();
1681 return doneFactory; // avoid unused variable warning.
1682}
1683
1684////////////////////////////////////////////////////////////////////////////////
1685/// Register Rdict data for future loading by LoadPCM;
1686
1687void TCling::RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
1688{
1689 if (IsFromRootCling())
1690 return;
1691
1692 if (llvm::sys::fs::exists(pcmFileNameFullPath)) {
1693 ::Error("TCling::RegisterRdictForLoadPCM", "Rdict '%s' is both in Module extension and in File system.", pcmFileNameFullPath.c_str());
1694 return;
1695 }
1696
1697 // The pcmFileNameFullPath must be resolved already because we cannot resolve
1698 // a link to a non-existent file.
1699 fPendingRdicts[pcmFileNameFullPath] = *pcmContent;
1700}
1701
1702////////////////////////////////////////////////////////////////////////////////
1703/// Tries to load a PCM from TFile; returns true on success.
1704
1706{
1707 auto listOfKeys = pcmFile.GetListOfKeys();
1708
1709 // This is an empty pcm
1710 if (listOfKeys && ((listOfKeys->GetSize() == 0) || // Nothing here, or
1711 ((listOfKeys->GetSize() == 1) && // only one, and
1712 !strcmp(((TKey *)listOfKeys->At(0))->GetName(), "EMPTY") // name is EMPTY
1713 ))) {
1714 return;
1715 }
1716
1717 TObjArray *protoClasses;
1718 if (gDebug > 1)
1719 ::Info("TCling::LoadPCMImpl", "reading protoclasses for %s \n", pcmFile.GetName());
1720
1721 TObjArray *enums;
1722 pcmFile.GetObject("__Enums", enums);
1723 if (enums) {
1724 // Cache the pointers
1725 auto listOfGlobals = gROOT->GetListOfGlobals();
1726 auto listOfEnums = dynamic_cast<THashList *>(gROOT->GetListOfEnums());
1727 // Loop on enums and then on enum constants
1728 for (auto selEnum : *enums) {
1729 const char *enumScope = selEnum->GetTitle();
1730 const char *enumName = selEnum->GetName();
1731 if (strcmp(enumScope, "") == 0) {
1732 // This is a global enum and is added to the
1733 // list of enums and its constants to the list of globals
1734 if (!listOfEnums->THashList::FindObject(enumName)) {
1735 ((TEnum *)selEnum)->SetClass(nullptr);
1736 listOfEnums->Add(selEnum);
1737 }
1738 for (auto enumConstant : *static_cast<TEnum *>(selEnum)->GetConstants()) {
1739 if (!listOfGlobals->FindObject(enumConstant)) {
1740 listOfGlobals->Add(enumConstant);
1741 }
1742 }
1743 } else {
1744 // This enum is in a namespace. A TClass entry is bootstrapped if
1745 // none exists yet and the enum is added to it
1746 TClass *nsTClassEntry = TClass::GetClass(enumScope);
1747 if (!nsTClassEntry) {
1748 nsTClassEntry = new TClass(enumScope, 0, TClass::kNamespaceForMeta, true);
1749 }
1750 auto listOfEnums = nsTClassEntry->fEnums.load();
1751 if (!listOfEnums) {
1752 if ((kIsClass | kIsStruct | kIsUnion) & nsTClassEntry->Property()) {
1753 // For this case, the list will be immutable once constructed
1754 // (i.e. in this case, by the end of this routine).
1755 listOfEnums = nsTClassEntry->fEnums = new TListOfEnums(nsTClassEntry);
1756 } else {
1757 // namespaces can have enums added to them
1758 listOfEnums = nsTClassEntry->fEnums = new TListOfEnumsWithLock(nsTClassEntry);
1759 }
1760 }
1761 if (listOfEnums && !listOfEnums->THashList::FindObject(enumName)) {
1762 ((TEnum *)selEnum)->SetClass(nsTClassEntry);
1763 listOfEnums->Add(selEnum);
1764 }
1765 }
1766 }
1767 enums->Clear();
1768 delete enums;
1769 }
1770
1771 pcmFile.GetObject("__ProtoClasses", protoClasses);
1772
1773 if (protoClasses) {
1774 for (auto obj : *protoClasses) {
1775 TProtoClass *proto = (TProtoClass *)obj;
1777 }
1778 // Now that all TClass-es know how to set them up we can update
1779 // existing TClasses, which might cause the creation of e.g. TBaseClass
1780 // objects which in turn requires the creation of TClasses, that could
1781 // come from the PCH, but maybe later in the loop. Instead of resolving
1782 // a dependency graph the addition to the TClassTable above allows us
1783 // to create these dependent TClasses as needed below.
1784 for (auto proto : *protoClasses) {
1785 if (TClass *existingCl = (TClass *)gROOT->GetListOfClasses()->FindObject(proto->GetName())) {
1786 // We have an existing TClass object. It might be emulated
1787 // or interpreted; we now have more information available.
1788 // Make that available.
1789 if (existingCl->GetState() != TClass::kHasTClassInit) {
1790 DictFuncPtr_t dict = gClassTable->GetDict(proto->GetName());
1791 if (!dict) {
1792 ::Error("TCling::LoadPCM", "Inconsistent TClassTable for %s", proto->GetName());
1793 } else {
1794 // This will replace the existing TClass.
1795 TClass *ncl = (*dict)();
1796 if (ncl)
1797 ncl->PostLoadCheck();
1798 }
1799 }
1800 }
1801 }
1802
1803 protoClasses->Clear(); // Ownership was transfered to TClassTable.
1804 delete protoClasses;
1805 }
1806
1807 TObjArray *dataTypes;
1808 pcmFile.GetObject("__Typedefs", dataTypes);
1809 if (dataTypes) {
1810 for (auto typedf : *dataTypes)
1811 gROOT->GetListOfTypes()->Add(typedf);
1812 dataTypes->Clear(); // Ownership was transfered to TListOfTypes.
1813 delete dataTypes;
1814 }
1815}
1816
1817////////////////////////////////////////////////////////////////////////////////
1818/// Tries to load a rdict PCM, issues diagnostics if it fails.
1819
1820void TCling::LoadPCM(std::string pcmFileNameFullPath)
1821{
1822 SuspendAutoLoadingRAII autoloadOff(this);
1823 SuspendAutoParsing autoparseOff(this);
1824 assert(!pcmFileNameFullPath.empty());
1825 assert(llvm::sys::path::is_absolute(pcmFileNameFullPath));
1826
1827 // Easier to work with the ROOT interfaces.
1828 TString pcmFileName = pcmFileNameFullPath;
1829
1830 // Prevent the ROOT-PCMs hitting this during auto-load during
1831 // JITting - which will cause recursive compilation.
1832 // Avoid to call the plugin manager at all.
1834
1836 llvm::SaveAndRestore<Int_t> SaveGDebug(gDebug);
1837 if (gDebug > 5) {
1838 gDebug -= 5;
1839 ::Info("TCling::LoadPCM", "Loading ROOT PCM %s", pcmFileName.Data());
1840 } else {
1841 gDebug = 0;
1842 }
1843
1844 if (llvm::sys::fs::is_symlink_file(pcmFileNameFullPath))
1845 pcmFileNameFullPath = ROOT::TMetaUtils::GetRealPath(pcmFileNameFullPath);
1846
1847 auto pendingRdict = fPendingRdicts.find(pcmFileNameFullPath);
1848 if (pendingRdict != fPendingRdicts.end()) {
1849 llvm::StringRef pcmContent = pendingRdict->second;
1850 TMemFile::ZeroCopyView_t range{pcmContent.data(), pcmContent.size()};
1851 std::string RDictFileOpts = pcmFileNameFullPath + "?filetype=pcm";
1852 TMemFile pcmMemFile(RDictFileOpts.c_str(), range);
1853
1854 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
1855 LoadPCMImpl(pcmMemFile);
1856 // Currently the module file are never unloaded (even if the library is
1857 // unloaded) and, of course, never reloaded.
1858 // Consequently, we must NOT remove the `pendingRdict` from the list
1859 // of pending dictionary, otherwise if a library is unloaded and then
1860 // reload we will be unable to update properly the TClass object
1861 // (because we wont be able to load the rootpcm file by executing the
1862 // above lines)
1863
1864 return;
1865 }
1866
1867 if (!llvm::sys::fs::exists(pcmFileNameFullPath)) {
1868 ::Error("TCling::LoadPCM", "ROOT PCM %s file does not exist",
1869 pcmFileNameFullPath.data());
1870 if (!fPendingRdicts.empty())
1871 for (const auto &rdict : fPendingRdicts)
1872 ::Info("TCling::LoadPCM", "In-memory ROOT PCM candidate %s\n",
1873 rdict.first.c_str());
1874 return;
1875 }
1876
1877 if (!gROOT->IsRootFile(pcmFileName)) {
1878 Fatal("LoadPCM", "The file %s is not a ROOT as was expected\n", pcmFileName.Data());
1879 return;
1880 }
1881 TFile pcmFile(pcmFileName + "?filetype=pcm", "READ");
1882 LoadPCMImpl(pcmFile);
1883}
1884
1885//______________________________________________________________________________
1886
1887namespace {
1888 using namespace clang;
1889
1890 class ExtLexicalStorageAdder: public RecursiveASTVisitor<ExtLexicalStorageAdder>{
1891 // This class is to be considered an helper for autoparsing.
1892 // It visits the AST and marks all classes (in all of their redeclarations)
1893 // with the setHasExternalLexicalStorage method.
1894 public:
1895 bool VisitRecordDecl(clang::RecordDecl* rcd){
1896 if (gDebug > 2)
1897 Info("ExtLexicalStorageAdder",
1898 "Adding external lexical storage to class %s",
1899 rcd->getNameAsString().c_str());
1900 auto reDeclPtr = rcd->getMostRecentDecl();
1901 do {
1902 reDeclPtr->setHasExternalLexicalStorage();
1903 } while ((reDeclPtr = reDeclPtr->getPreviousDecl()));
1904
1905 return false;
1906 }
1907 };
1908
1909
1910}
1911
1912////////////////////////////////////////////////////////////////////////////////
1913///\returns true if the module map was loaded, false on error or if the map was
1914/// already loaded.
1915bool TCling::RegisterPrebuiltModulePath(const std::string &FullPath,
1916 const std::string &ModuleMapName /*= "module.modulemap"*/) const
1917{
1918 assert(llvm::sys::path::is_absolute(FullPath));
1919 Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
1920 FileManager &FM = PP.getFileManager();
1921 // FIXME: In a ROOT session we can add an include path (through .I /inc/path)
1922 // We should look for modulemap files there too.
1923 if (auto DE = FM.getOptionalDirectoryRef(FullPath)) {
1924 HeaderSearch &HS = PP.getHeaderSearchInfo();
1925 HeaderSearchOptions &HSOpts = HS.getHeaderSearchOpts();
1926 const auto &ModPaths = HSOpts.PrebuiltModulePaths;
1927 bool pathExists = std::find(ModPaths.begin(), ModPaths.end(), FullPath) != ModPaths.end();
1928 if (!pathExists)
1929 HSOpts.AddPrebuiltModulePath(FullPath);
1930 // We cannot use HS.lookupModuleMapFile(DE, /*IsFramework*/ false);
1931 // because its internal call to getFile has CacheFailure set to true.
1932 // In our case, modulemaps can appear any time due to ACLiC.
1933 // Code copied from HS.lookupModuleMapFile.
1934 llvm::SmallString<256> ModuleMapFileName(DE->getName());
1935 llvm::sys::path::append(ModuleMapFileName, ModuleMapName);
1936 if (auto FE = FM.getOptionalFileRef(ModuleMapFileName, /*openFile*/ false,
1937 /*CacheFailure*/ false)) {
1938 if (!HS.loadModuleMapFile(*FE, /*IsSystem*/ false))
1939 return true;
1940 Error("RegisterPrebuiltModulePath", "Could not load modulemap in %s", ModuleMapFileName.c_str());
1941 }
1942 }
1943 return false;
1944}
1945
1946////////////////////////////////////////////////////////////////////////////////
1947/// List of dicts that have the PCM information already in the PCH.
1948static const std::unordered_set<std::string> gIgnoredPCMNames = {"libCore",
1949 "libRint",
1950 "libThread",
1951 "libRIO",
1952 "libImt",
1953 "libMultiProc",
1954 "libcomplexDict",
1955 "libdequeDict",
1956 "liblistDict",
1957 "libforward_listDict",
1958 "libvectorDict",
1959 "libmapDict",
1960 "libmultimap2Dict",
1961 "libmap2Dict",
1962 "libmultimapDict",
1963 "libsetDict",
1964 "libmultisetDict",
1965 "libunordered_setDict",
1966 "libunordered_multisetDict",
1967 "libunordered_mapDict",
1968 "libunordered_multimapDict",
1969 "libvalarrayDict",
1970 "G__GenVector32",
1971 "G__Smatrix32"};
1972
1973static void PrintDlError(const char *dyLibName, const char *modulename)
1974{
1975#ifdef R__WIN32
1976 char dyLibError[1000];
1977 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1978 dyLibError, sizeof(dyLibError), NULL);
1979#else
1980 const char *dyLibError = dlerror();
1981#endif
1982 ::Error("TCling::RegisterModule", "Cannot open shared library %s for dictionary %s:\n %s", dyLibName, modulename,
1983 (dyLibError) ? dyLibError : "");
1984}
1985
1986////////////////////////////////////////////////////////////////////////////////
1987// Update all the TClass registered in fClassesToUpdate
1988
1990{
1991 while (!fClassesToUpdate.empty()) {
1992 TClass *oldcl = fClassesToUpdate.back().first;
1993 // If somehow the TClass has already been loaded (maybe it was registered several time),
1994 // we skip it. Otherwise, the existing TClass is in mode kInterpreted, kEmulated or
1995 // maybe even kForwardDeclared and needs to replaced.
1996 if (oldcl->GetState() != TClass::kHasTClassInit) {
1997 // if (gDebug > 2) Info("RegisterModule", "Forcing TClass init for %s", oldcl->GetName());
1998 DictFuncPtr_t dict = fClassesToUpdate.back().second;
1999 fClassesToUpdate.pop_back();
2000 // Calling func could manipulate the list so, let maintain the list
2001 // then call the dictionary function.
2002 TClass *ncl = dict();
2003 if (ncl) ncl->PostLoadCheck();
2004 } else {
2005 fClassesToUpdate.pop_back();
2006 }
2007 }
2008}
2009////////////////////////////////////////////////////////////////////////////////
2010/// Inject the module named "modulename" into cling; load all headers.
2011/// headers is a 0-terminated array of header files to `#include` after
2012/// loading the module. The module is searched for in all $LD_LIBRARY_PATH
2013/// entries (or %PATH% on Windows).
2014/// This function gets called by the static initialization of dictionary
2015/// libraries.
2016/// The payload code is injected "as is" in the interpreter.
2017/// The value of 'triggerFunc' is used to find the shared library location.
2018
2019void TCling::RegisterModule(const char* modulename,
2020 const char** headers,
2021 const char** includePaths,
2022 const char* payloadCode,
2023 const char* fwdDeclsCode,
2024 void (*triggerFunc)(),
2025 const FwdDeclArgsToKeepCollection_t& fwdDeclsArgToSkip,
2026 const char** classesHeaders,
2027 Bool_t lateRegistration /*=false*/,
2028 Bool_t hasCxxModule /*=false*/)
2029{
2030 const bool fromRootCling = IsFromRootCling();
2031 // We need the dictionary initialization but we don't want to inject the
2032 // declarations into the interpreter, except for those we really need for
2033 // I/O; see rootcling.cxx after the call to TCling__GetInterpreter().
2034 if (fromRootCling) return;
2035
2036 // When we cannot provide a module for the library we should enable header
2037 // parsing. This 'mixed' mode ensures gradual migration to modules.
2038 llvm::SaveAndRestore<bool> SaveHeaderParsing(fHeaderParsingOnDemand);
2039 fHeaderParsingOnDemand = !hasCxxModule;
2040
2041 // Treat Aclic Libs in a special way. Do not delay the parsing.
2042 bool hasHeaderParsingOnDemand = fHeaderParsingOnDemand;
2043 bool isACLiC = strstr(modulename, "_ACLiC_dict") != nullptr;
2044 if (hasHeaderParsingOnDemand && isACLiC) {
2045 if (gDebug>1)
2046 Info("TCling::RegisterModule",
2047 "Header parsing on demand is active but this is an Aclic library. Disabling it for this library.");
2048 hasHeaderParsingOnDemand = false;
2049 }
2050
2051
2052 // Make sure we relookup symbols that were search for before we loaded
2053 // their autoparse information. We could be more subtil and remove only
2054 // the failed one or only the one in this module, but for now this is
2055 // better than nothing.
2056 fLookedUpClasses.clear();
2057
2058 // Make sure we do not set off AutoLoading or autoparsing during the
2059 // module registration!
2060 SuspendAutoLoadingRAII autoLoadOff(this);
2061
2062 for (const char** inclPath = includePaths; *inclPath; ++inclPath) {
2063 TCling::AddIncludePath(*inclPath);
2064 }
2065 cling::Transaction* T = nullptr;
2066 // Put the template decls and the number of arguments to skip in the TNormalizedCtxt
2067 for (auto& fwdDeclArgToSkipPair : fwdDeclsArgToSkip){
2068 const std::string& fwdDecl = fwdDeclArgToSkipPair.first;
2069 const int nArgsToSkip = fwdDeclArgToSkipPair.second;
2070 auto compRes = fInterpreter->declare(fwdDecl.c_str(), &T);
2071 assert(cling::Interpreter::kSuccess == compRes &&
2072 "A fwd declaration could not be compiled");
2073 if (compRes!=cling::Interpreter::kSuccess){
2074 Warning("TCling::RegisterModule",
2075 "Problems in declaring string '%s' were encountered.",
2076 fwdDecl.c_str()) ;
2077 continue;
2078 }
2079
2080 // Drill through namespaces recursively until the template is found
2081 if(ClassTemplateDecl* TD = FindTemplateInNamespace(T->getFirstDecl().getSingleDecl())){
2082 fNormalizedCtxt->AddTemplAndNargsToKeep(TD->getCanonicalDecl(), nArgsToSkip);
2083 }
2084
2085 }
2086
2087 // FIXME: Remove #define __ROOTCLING__ once PCMs are there.
2088 // This is used to give Sema the same view on ACLiC'ed files (which
2089 // are then #included through the dictionary) as rootcling had.
2090 TString code = gNonInterpreterClassDef;
2091 if (payloadCode)
2092 code += payloadCode;
2093
2094 std::string dyLibName = cling::DynamicLibraryManager::getSymbolLocation(triggerFunc);
2095 assert(!llvm::sys::fs::is_symlink_file(dyLibName));
2096
2097 if (dyLibName.empty()) {
2098 ::Error("TCling::RegisterModule", "Dictionary trigger function for %s not found", modulename);
2099 return;
2100 }
2101
2102 // The triggerFunc may not be in a shared object but in an executable.
2103 bool isSharedLib = cling::DynamicLibraryManager::isSharedLibrary(dyLibName);
2104
2105 bool wasDlopened = false;
2106
2107 // If this call happens after dlopen has finished (i.e. late registration)
2108 // there is no need to dlopen the library recursively. See ROOT-8437 where
2109 // the dyLibName would correspond to the binary.
2110 if (!lateRegistration) {
2111
2112 if (isSharedLib) {
2113 // We need to open the dictionary shared library, to resolve symbols
2114 // requested by the JIT from it: as the library is currently being dlopen'ed,
2115 // its symbols are not yet reachable from the process.
2116 // Recursive dlopen seems to work just fine.
2117 void* dyLibHandle = dlopen(dyLibName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
2118 if (dyLibHandle) {
2119 fRegisterModuleDyLibs.push_back(dyLibHandle);
2120 wasDlopened = true;
2121 } else {
2122 PrintDlError(dyLibName.c_str(), modulename);
2123 }
2124 }
2125 } // if (!lateRegistration)
2126
2127 if (hasHeaderParsingOnDemand && fwdDeclsCode){
2128 // We now parse the forward declarations. All the classes are then modified
2129 // in order for them to have an external lexical storage.
2130 std::string fwdDeclsCodeLessEnums;
2131 {
2132 // Search for enum forward decls and only declare them if no
2133 // declaration exists yet.
2134 std::string fwdDeclsLine;
2135 std::istringstream fwdDeclsCodeStr(fwdDeclsCode);
2136 std::vector<std::string> scopes;
2137 while (std::getline(fwdDeclsCodeStr, fwdDeclsLine)) {
2138 const auto enumPos = fwdDeclsLine.find("enum __attribute__((annotate(\"");
2139 // We check if the line contains a fwd declaration of an enum
2140 if (enumPos != std::string::npos) {
2141 // We clear the scopes which we may have carried from a previous iteration
2142 scopes.clear();
2143 // We check if the enum is not in a scope. If yes, save its name
2144 // and the names of the enclosing scopes.
2145 if (enumPos != 0) {
2146 // it's enclosed in namespaces. We need to understand what they are
2147 auto nsPos = fwdDeclsLine.find("namespace");
2148 R__ASSERT(nsPos < enumPos && "Inconsistent enum and enclosing scope parsing!");
2149 while (nsPos < enumPos && nsPos != std::string::npos) {
2150 // we have a namespace, let's put it in the collection of scopes
2151 const auto nsNameStart = nsPos + 10;
2152 const auto nsNameEnd = fwdDeclsLine.find('{', nsNameStart);
2153 const auto nsName = fwdDeclsLine.substr(nsNameStart, nsNameEnd - nsNameStart);
2154 scopes.push_back(nsName);
2155 nsPos = fwdDeclsLine.find("namespace", nsNameEnd);
2156 }
2157 }
2158 clang::DeclContext* DC = nullptr;
2159 for (auto &&aScope: scopes) {
2160 DC = cling::utils::Lookup::Namespace(&fInterpreter->getSema(), aScope.c_str(), DC);
2161 if (!DC) {
2162 // No decl context means we have to fwd declare the enum.
2163 break;
2164 }
2165 }
2166 if (scopes.empty() || DC) {
2167 // We know the scope; let's look for the enum. For that, look
2168 // for the *last* closing parentheses of an attribute because
2169 // there can be multiple.
2170 size_t posEnumName = fwdDeclsLine.rfind("\"))) ");
2171 R__ASSERT(posEnumName != std::string::npos && "Inconsistent enum fwd decl!");
2172 posEnumName += 5; // skip "\"))) "
2173 while (isspace(fwdDeclsLine[posEnumName]))
2174 ++posEnumName;
2175 size_t posEnumNameEnd = fwdDeclsLine.find(" : ", posEnumName);
2176 R__ASSERT(posEnumNameEnd != std::string::npos && "Inconsistent enum fwd decl (end)!");
2177 while (isspace(fwdDeclsLine[posEnumNameEnd]))
2178 --posEnumNameEnd;
2179 // posEnumNameEnd now points to the last character of the name.
2180
2181 std::string enumName = fwdDeclsLine.substr(posEnumName,
2182 posEnumNameEnd - posEnumName + 1);
2183
2184 if (clang::NamedDecl* enumDecl
2185 = cling::utils::Lookup::Named(&fInterpreter->getSema(),
2186 enumName.c_str(), DC)) {
2187 // We have an existing enum decl (forward or definition);
2188 // skip this.
2189 R__ASSERT(llvm::dyn_cast<clang::EnumDecl>(enumDecl) && "not an enum decl!");
2190 (void)enumDecl;
2191 continue;
2192 }
2193 }
2194 }
2195
2196 fwdDeclsCodeLessEnums += fwdDeclsLine + "\n";
2197 }
2198 }
2199
2200 if (!fwdDeclsCodeLessEnums.empty()){ // Avoid the overhead if nothing is to be declared
2201 auto compRes = fInterpreter->declare(fwdDeclsCodeLessEnums, &T);
2202 assert(cling::Interpreter::kSuccess == compRes &&
2203 "The forward declarations could not be compiled");
2204 if (compRes!=cling::Interpreter::kSuccess){
2205 Warning("TCling::RegisterModule",
2206 "Problems in compiling forward declarations for module %s: '%s'",
2207 modulename, fwdDeclsCodeLessEnums.c_str()) ;
2208 }
2209 else if (T){
2210 // Loop over all decls in the transaction and go through them all
2211 // to mark them properly.
2212 // In order to do that, we first iterate over all the DelayedCallInfos
2213 // within the transaction. Then we loop over all Decls in the DeclGroupRef
2214 // contained in the DelayedCallInfos. For each decl, we traverse.
2215 ExtLexicalStorageAdder elsa;
2216 for (auto dciIt = T->decls_begin();dciIt!=T->decls_end();dciIt++){
2217 cling::Transaction::DelayCallInfo& dci = *dciIt;
2218 for(auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) {
2219 clang::Decl* declPtr = *dit;
2220 elsa.TraverseDecl(declPtr);
2221 }
2222 }
2223 }
2224 }
2225
2226 // Now we register all the headers necessary for the class
2227 // Typical format of the array:
2228 // {"A", "classes.h", "@",
2229 // "vector<A>", "vector", "@",
2230 // "myClass", payloadCode, "@",
2231 // nullptr};
2232
2233 std::string temp;
2234 for (const char** classesHeader = classesHeaders; *classesHeader; ++classesHeader) {
2235 temp=*classesHeader;
2236
2237 size_t theTemplateHash = 0;
2238 bool addTemplate = false;
2239 size_t posTemplate = temp.find('<');
2240 if (posTemplate != std::string::npos) {
2241 // Add an entry for the template itself.
2242 std::string templateName = temp.substr(0, posTemplate);
2243 theTemplateHash = fStringHashFunction(templateName);
2244 addTemplate = true;
2245 }
2246 size_t theHash = fStringHashFunction(temp);
2247 classesHeader++;
2248 for (const char** classesHeader_inner = classesHeader; 0!=strcmp(*classesHeader_inner,"@"); ++classesHeader_inner,++classesHeader){
2249 // This is done in order to distinguish headers from files and from the payloadCode
2250 if (payloadCode == *classesHeader_inner ){
2251 fPayloads.insert(theHash);
2252 if (addTemplate) fPayloads.insert(theTemplateHash);
2253 }
2254 if (gDebug > 2)
2255 Info("TCling::RegisterModule",
2256 "Adding a header for %s", temp.c_str());
2257 fClassesHeadersMap[theHash].push_back(*classesHeader_inner);
2258 if (addTemplate) {
2259 if (fClassesHeadersMap.find(theTemplateHash) == fClassesHeadersMap.end()) {
2260 fClassesHeadersMap[theTemplateHash].push_back(*classesHeader_inner);
2261 }
2262 addTemplate = false;
2263 }
2264 }
2265 }
2266 }
2267
2268 clang::Sema &TheSema = fInterpreter->getSema();
2269
2270 bool ModuleWasSuccessfullyLoaded = false;
2271 if (hasCxxModule) {
2272 std::string ModuleName = modulename;
2273 if (llvm::StringRef(modulename).startswith("lib"))
2274 ModuleName = llvm::StringRef(modulename).substr(3).str();
2275
2276 // In case we are directly loading the library via gSystem->Load() without
2277 // specifying the relevant include paths we should try loading the
2278 // modulemap next to the library location.
2279 clang::Preprocessor &PP = TheSema.getPreprocessor();
2280 std::string ModuleMapName;
2281 if (isACLiC)
2282 ModuleMapName = ModuleName + ".modulemap";
2283 else
2284 ModuleMapName = "module.modulemap";
2285 RegisterPrebuiltModulePath(llvm::sys::path::parent_path(dyLibName).str(),
2286 ModuleMapName);
2287
2288 // FIXME: We should only complain for modules which we know to exist. For example, we should not complain about
2289 // modules such as GenVector32 because it needs to fall back to GenVector.
2290 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2291 ModuleWasSuccessfullyLoaded = LoadModule(ModuleName, *fInterpreter);
2292 if (!ModuleWasSuccessfullyLoaded) {
2293 // Only report if we found the module in the modulemap.
2294 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
2295 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
2296 if (moduleMap.findModule(ModuleName))
2297 Info("TCling::RegisterModule", "Module %s in modulemap failed to load.", ModuleName.c_str());
2298 }
2299 }
2300
2301 if (gIgnoredPCMNames.find(modulename) == gIgnoredPCMNames.end()) {
2302 llvm::SmallString<256> pcmFileNameFullPath(dyLibName);
2303 // The path dyLibName might not be absolute. This can happen if dyLibName
2304 // is linked to an executable in the same folder.
2305 llvm::sys::fs::make_absolute(pcmFileNameFullPath);
2306 llvm::sys::path::remove_filename(pcmFileNameFullPath);
2307 llvm::sys::path::append(pcmFileNameFullPath,
2309 LoadPCM(pcmFileNameFullPath.str().str());
2310 }
2311
2312 { // scope within which diagnostics are de-activated
2313 // For now we disable diagnostics because we saw them already at
2314 // dictionary generation time. That won't be an issue with the PCMs.
2315
2316 clangDiagSuppr diagSuppr(TheSema.getDiagnostics());
2317
2318#if defined(R__MUST_REVISIT)
2319#if R__MUST_REVISIT(6,2)
2320 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
2321#endif
2322#endif
2323
2324 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand){
2325 SuspendAutoParsing autoParseRaii(this);
2326
2327 const cling::Transaction* watermark = fInterpreter->getLastTransaction();
2328 cling::Interpreter::CompilationResult compRes = fInterpreter->parseForModule(code.Data());
2329 if (isACLiC) {
2330 // Register an unload point.
2331 fMetaProcessor->registerUnloadPoint(watermark, headers[0]);
2332 }
2333
2334 assert(cling::Interpreter::kSuccess == compRes &&
2335 "Payload code of a dictionary could not be parsed correctly.");
2336 if (compRes!=cling::Interpreter::kSuccess) {
2337 Warning("TCling::RegisterModule",
2338 "Problems declaring payload for module %s.", modulename) ;
2339 }
2340 }
2341 }
2342
2343 // Now that all the header have been registered/compiled, let's
2344 // make sure to 'reset' the TClass that have a class init in this module
2345 // but already had their type information available (using information/header
2346 // loaded from other modules or from class rules or from opening a TFile
2347 // or from loading header in a way that did not provoke the loading of
2348 // the library we just loaded).
2350
2351 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand) {
2352 // __ROOTCLING__ might be pulled in through PCH
2353 fInterpreter->declare("#ifdef __ROOTCLING__\n"
2354 "#undef __ROOTCLING__\n"
2355 + gInterpreterClassDef +
2356 "#endif");
2357 }
2358
2359 if (wasDlopened) {
2360 assert(isSharedLib);
2361 void* dyLibHandle = fRegisterModuleDyLibs.back();
2362 fRegisterModuleDyLibs.pop_back();
2363 dlclose(dyLibHandle);
2364 }
2365}
2366
2368 clang::CompilerInstance& CI = *GetInterpreterImpl()->getCI();
2369 ASTContext &C = CI.getASTContext();
2370
2371 // Do not do anything if we have no global module index.
2372 // FIXME: This is mostly to real with false positives in the TTabCom
2373 // interface for non-modules.
2374 if (!fCxxModulesEnabled)
2375 return;
2376
2377 if (IdentifierInfoLookup *External = C.Idents.getExternalIdentifierLookup()) {
2378 std::unique_ptr<IdentifierIterator> Iter(External->getIdentifiers());
2379 for (llvm::StringRef Ident = Iter->Next(); !Ident.empty(); Ident = Iter->Next()) {
2380 std::string I = Ident.str();
2381 if (!Idents.Contains(I.data()))
2382 Idents.Add(new TObjString(I.c_str()));
2383 }
2384 }
2385}
2386
2387
2388////////////////////////////////////////////////////////////////////////////////
2389/// Register classes that already existed prior to their dictionary loading
2390/// and that already had a ClassInfo (and thus would not be refresh via
2391/// UpdateClassInfo.
2392
2394{
2395 fClassesToUpdate.push_back(std::make_pair(oldcl,dict));
2396}
2397
2398////////////////////////////////////////////////////////////////////////////////
2399/// If the dictionary is loaded, we can remove the class from the list
2400/// (otherwise the class might be loaded twice).
2401
2403{
2404 typedef std::vector<std::pair<TClass*,DictFuncPtr_t> >::iterator iterator;
2405 iterator stop = fClassesToUpdate.end();
2406 for(iterator i = fClassesToUpdate.begin();
2407 i != stop;
2408 ++i)
2409 {
2410 if ( i->first == oldcl ) {
2411 fClassesToUpdate.erase(i);
2412 return;
2413 }
2414 }
2415}
2416
2417
2418////////////////////////////////////////////////////////////////////////////////
2419/// Let cling process a command line.
2420///
2421/// If the command is executed and the error is 0, then the return value
2422/// is the int value corresponding to the result of the executed command
2423/// (float and double return values will be truncated).
2424///
2425
2426// Method for handling the interpreter exceptions.
2427// the MetaProcessor is passing in as argument to teh function, because
2428// cling::Interpreter::CompilationResult is a nested class and it cannot be
2429// forward declared, thus this method cannot be a static member function
2430// of TCling.
2431
2432static int HandleInterpreterException(cling::MetaProcessor* metaProcessor,
2433 const char* input_line,
2434 cling::Interpreter::CompilationResult& compRes,
2435 cling::Value* result)
2436{
2437 try {
2438 return metaProcessor->process(input_line, compRes, result);
2439 }
2440 catch (cling::InterpreterException& ex)
2441 {
2442 Error("HandleInterpreterException", "%s\n%s", ex.what(), "Execution of your code was aborted.");
2443 ex.diagnose();
2444 compRes = cling::Interpreter::kFailure;
2445 }
2446 return 0;
2447}
2448
2449////////////////////////////////////////////////////////////////////////////////
2450
2451bool TCling::DiagnoseIfInterpreterException(const std::exception &e) const
2452{
2453 if (auto ie = dynamic_cast<const cling::InterpreterException*>(&e)) {
2454 ie->diagnose();
2455 return true;
2456 }
2457 return false;
2458}
2459
2460////////////////////////////////////////////////////////////////////////////////
2461
2463{
2464 // Copy the passed line, it comes from a static buffer in TApplication
2465 // which can be reentered through the Cling evaluation routines,
2466 // which would overwrite the static buffer and we would forget what we
2467 // were doing.
2468 //
2469 TString sLine(line);
2470 if (strstr(line,fantomline)) {
2471 // End-Of-Line action
2472 // See the comment (copied from above):
2473 // It is a "fantom" method to synchronize user keyboard input
2474 // and ROOT prompt line (for WIN32)
2475 // and is implemented by
2476 if (gApplication) {
2477 if (gApplication->IsCmdThread()) {
2479 gROOT->SetLineIsProcessing();
2480
2482
2483 gROOT->SetLineHasBeenProcessed();
2484 }
2485 }
2486 return 0;
2487 }
2488
2490 gGlobalMutex->Lock();
2491 if (!gInterpreterMutex)
2494 }
2496 gROOT->SetLineIsProcessing();
2497
2498 struct InterpreterFlagsRAII {
2499 cling::Interpreter* fInterpreter;
2500 bool fWasDynamicLookupEnabled;
2501
2502 InterpreterFlagsRAII(cling::Interpreter* interp):
2503 fInterpreter(interp),
2504 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2505 {
2506 fInterpreter->enableDynamicLookup(true);
2507 }
2508 ~InterpreterFlagsRAII() {
2509 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2510 gROOT->SetLineHasBeenProcessed();
2511 }
2512 } interpreterFlagsRAII(GetInterpreterImpl());
2513
2514 // A non-zero returned value means the given line was
2515 // not a complete statement.
2516 int indent = 0;
2517 // This will hold the resulting value of the evaluation the given line.
2518 cling::Value result;
2519 cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess;
2520 if (!strncmp(sLine.Data(), ".L", 2) || !strncmp(sLine.Data(), ".x", 2) ||
2521 !strncmp(sLine.Data(), ".X", 2)) {
2522 // If there was a trailing "+", then CINT compiled the code above,
2523 // and we will need to strip the "+" before passing the line to cling.
2524 TString mod_line(sLine);
2525 TString aclicMode;
2526 TString arguments;
2527 TString io;
2528 TString fname = gSystem->SplitAclicMode(sLine.Data() + 3,
2529 aclicMode, arguments, io);
2530 if (aclicMode.Length()) {
2531 // Remove the leading '+'
2532 R__ASSERT(aclicMode[0]=='+' && "ACLiC mode must start with a +");
2533 aclicMode[0]='k'; // We always want to keep the .so around.
2534 if (aclicMode[1]=='+') {
2535 // We have a 2nd +
2536 aclicMode[1]='f'; // We want to force the recompilation.
2537 }
2538 if (!gSystem->CompileMacro(fname,aclicMode)) {
2539 // ACLiC failed.
2540 compRes = cling::Interpreter::kFailure;
2541 } else {
2542 if (strncmp(sLine.Data(), ".L", 2) != 0) {
2543 // if execution was requested.
2544
2545 if (arguments.Length() == 0) {
2546 arguments = "()";
2547 }
2548 // We need to remove the extension.
2549 Ssiz_t ext = fname.Last('.');
2550 if (ext != kNPOS) {
2551 fname.Remove(ext);
2552 }
2553 const char *function = gSystem->BaseName(fname);
2554 mod_line = function + arguments + io;
2556 }
2557 }
2558 } else if (cling::DynamicLibraryManager::isSharedLibrary(fname.Data()) &&
2559 strncmp(sLine.Data(), ".L", 2) != 0) { // .x *.so or *.dll
2560 if (gSystem->Load(fname) < 0) {
2561 // Loading failed.
2562 compRes = cling::Interpreter::kFailure;
2563 } else {
2564 if (arguments.Length() == 0) {
2565 arguments = "()";
2566 }
2567 // We need to remove the extension. (*.so or *.dll)
2568 Ssiz_t ext = fname.Last('.');
2569 if (ext != kNPOS) {
2570 fname.Remove(ext);
2571 }
2572 // Now we try to find the 'main' function to run within this shared library
2573 // We distinguish two cases: a library.so with a function library(args),
2574 // or a precompiled ACLiC macro (macro_C.so) with a function macro(args).
2575 // Only in the second case, we need to strip the suffix _C or _cpp from fname.
2576 if (!gInterpreter->GetFunction(nullptr, gSystem->BaseName(fname))) { // AcLiC macro
2577 // We need to remove the automatically appended _ extension when compiling (macro_C from macro.C)
2578 ext = fname.Last('_');
2579 if (ext != kNPOS) {
2580 fname.Remove(ext);
2581 }
2582 }
2583 const char *function = gSystem->BaseName(fname);
2584 mod_line = function + arguments + io;
2586 }
2587 } else {
2588 // neither ACLiC nor run shared-library (.x)
2589 size_t unnamedMacroOpenCurly;
2590 {
2591 std::string code;
2592 std::string codeline;
2593 // Windows requires std::ifstream::binary to properly handle
2594 // CRLF and LF line endings
2595 std::ifstream in(fname, std::ifstream::binary);
2596 while (in) {
2597 std::getline(in, codeline);
2598 code += codeline + "\n";
2599 }
2600 unnamedMacroOpenCurly
2601 = cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
2602 }
2603
2604 fCurExecutingMacros.push_back(fname);
2605 if (unnamedMacroOpenCurly != std::string::npos) {
2606 compRes = fMetaProcessor->readInputFromFile(fname.Data(), &result,
2607 unnamedMacroOpenCurly);
2608 } else {
2609 // No DynLookup for .x, .L of named macros.
2610 fInterpreter->enableDynamicLookup(false);
2612 }
2613 fCurExecutingMacros.pop_back();
2614 }
2615 } // .L / .X / .x
2616 else {
2617 if (0!=strncmp(sLine.Data(), ".autodict ",10) && sLine != ".autodict") {
2618 // explicitly ignore .autodict without having to support it
2619 // in cling.
2620
2621 // Turn off autoparsing if this is an include directive
2622 bool isInclusionDirective = sLine.Contains("\n#include") || sLine.BeginsWith("#include");
2623 if (isInclusionDirective) {
2624 SuspendAutoParsing autoParseRaii(this);
2626 } else {
2628 }
2629 }
2630 }
2631 if (result.isValid())
2633 if (indent) {
2634 if (error)
2635 *error = kProcessing;
2636 return 0;
2637 }
2638 if (error) {
2639 switch (compRes) {
2640 case cling::Interpreter::kSuccess: *error = kNoError; break;
2641 case cling::Interpreter::kFailure: *error = kRecoverable; break;
2642 case cling::Interpreter::kMoreInputExpected: *error = kProcessing; break;
2643 }
2644 }
2645 if (compRes == cling::Interpreter::kSuccess
2646 && result.isValid()
2647 && !result.isVoid())
2648 {
2649 return result.castAs<Longptr_t>();
2650 }
2651 return 0;
2652}
2653
2654////////////////////////////////////////////////////////////////////////////////
2655/// No-op; see TRint instead.
2656
2658{
2659}
2660
2661////////////////////////////////////////////////////////////////////////////////
2662/// \brief Add a directory to the list of directories in which the
2663/// interpreter looks for include files.
2664/// \param[in] path The path to the directory.
2665/// \note Only one path item can be specified at a time, i.e. "path1:path2" is
2666/// \b NOT supported.
2667/// \warning Only the path to the directory should be specified, without
2668/// prepending the \c -I prefix, i.e.
2669/// <tt>gCling->AddIncludePath("/path/to/my/includes")</tt>. If the
2670/// \c -I prefix is used it will be ignored.
2671void TCling::AddIncludePath(const char *path)
2672{
2674 // Favorite source of annoyance: gSystem->AddIncludePath() needs "-I",
2675 // gCling->AddIncludePath() does not! Work around that inconsistency:
2676 if (path[0] == '-' && path[1] == 'I')
2677 path += 2;
2678 TString sPath(path);
2679 gSystem->ExpandPathName(sPath);
2680#ifdef _MSC_VER
2681 if (sPath.BeginsWith("/")) {
2682 char drive[3];
2683 snprintf(drive, 3, "%c:", _getdrive() + 'A' - 1);
2684 sPath.Prepend(drive);
2685 }
2686#endif
2687 fInterpreter->AddIncludePath(sPath.Data());
2688}
2689
2690////////////////////////////////////////////////////////////////////////////////
2691/// Visit all members over members, recursing over base classes.
2692
2693void TCling::InspectMembers(TMemberInspector& insp, const void* obj,
2694 const TClass* cl, Bool_t isTransient)
2695{
2699 }
2700
2701 if (!cl || cl->GetCollectionProxy()) {
2702 // We do not need to investigate the content of the STL
2703 // collection, they are opaque to us (and details are
2704 // uninteresting).
2705 return;
2706 }
2707
2708 static const TClassRef clRefString("std::string");
2709 if (clRefString == cl) {
2710 // We stream std::string without going through members..
2711 return;
2712 }
2713
2714 if (TClassEdit::IsStdArray(cl->GetName())) {
2715 // We treat std arrays as C arrays
2716 return;
2717 }
2718
2719 if (TClassEdit::IsUniquePtr(cl->GetName())) {
2720 // Ignore error caused by the inside of std::unique_ptr
2721 // This is needed solely because of rootclingIO's IsUnsupportedUniquePointer
2722 // which checks the number of elements in the GetListOfRealData.
2723 // If this usage is removed, this can be replaced with a return statement.
2724 // See https://github.com/root-project/root/issues/13574
2725 isTransient = true;
2726 }
2727
2728 const char* cobj = (const char*) obj; // for ptr arithmetics
2729
2730 // Treat the case of std::complex in a special manner. We want to enforce
2731 // the layout of a stl implementation independent class, which is the
2732 // complex as implemented in ROOT5.
2733
2734 // A simple lambda to simplify the code
2735 auto inspInspect = [&] (ptrdiff_t offset){
2736 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_real", cobj, isTransient);
2737 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_imag", cobj + offset, isTransient);
2738 };
2739
2740 auto complexType = TClassEdit::GetComplexType(cl->GetName());
2741 switch(complexType) {
2743 {
2744 break;
2745 }
2747 {
2748 inspInspect(sizeof(float));
2749 return;
2750 }
2752 {
2753 inspInspect(sizeof(double));
2754 return;
2755 }
2757 {
2758 inspInspect(sizeof(int));
2759 return;
2760 }
2762 {
2763 inspInspect(sizeof(long));
2764 return;
2765 }
2766 }
2767
2768 static clang::PrintingPolicy
2769 printPol(fInterpreter->getCI()->getLangOpts());
2770 if (printPol.Indentation) {
2771 // not yet initialized
2772 printPol.Indentation = 0;
2773 printPol.SuppressInitializers = true;
2774 }
2775
2776 const char* clname = cl->GetName();
2777 // Printf("Inspecting class %s\n", clname);
2778
2779 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2780 const clang::Decl *scopeDecl = nullptr;
2781 const clang::Type *recordType = nullptr;
2782
2783 if (cl->GetClassInfo()) {
2784 TClingClassInfo * clingCI = (TClingClassInfo *)cl->GetClassInfo();
2785 scopeDecl = clingCI->GetDecl();
2786 recordType = clingCI->GetType();
2787 } else {
2788 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2789 // Diags will complain about private classes:
2790 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2791 &recordType);
2792 }
2793 if (!scopeDecl) {
2794 Error("InspectMembers", "Cannot find Decl for class %s", clname);
2795 return;
2796 }
2797 const clang::CXXRecordDecl* recordDecl
2798 = llvm::dyn_cast<const clang::CXXRecordDecl>(scopeDecl);
2799 if (!recordDecl) {
2800 Error("InspectMembers", "Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2801 return;
2802 }
2803
2804 {
2805 // Force possible deserializations first. We need to have no pending
2806 // Transaction when passing control flow to the inspector below (ROOT-7779).
2807 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2808
2809 astContext.getASTRecordLayout(recordDecl);
2810
2811 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2812 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2813 }
2814
2815 const clang::ASTRecordLayout& recLayout
2816 = astContext.getASTRecordLayout(recordDecl);
2817
2818 // TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
2819 // if (proxy && ( proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated ) ) {
2820 // Error("InspectMembers","The TClass for %s has an emulated proxy but we are looking at a compiled version of the collection!\n",
2821 // cl->GetName());
2822 // }
2823 if (cl->Size() != recLayout.getSize().getQuantity()) {
2824 Error("InspectMembers","TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2825 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2826 }
2827
2828 unsigned iNField = 0;
2829 // iterate over fields
2830 // FieldDecls are non-static, else it would be a VarDecl.
2831 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2832 eField = recordDecl->field_end(); iField != eField;
2833 ++iField, ++iNField) {
2834
2835
2836 clang::QualType memberQT = iField->getType();
2837 if (recordType) {
2838 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2839 memberQT = ROOT::TMetaUtils::ReSubstTemplateArg(memberQT, recordType);
2840 }
2841 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2842 if (memberQT.isNull()) {
2843 std::string memberName;
2844 llvm::raw_string_ostream stream(memberName);
2845 // Don't trigger fopen of the source file to count lines:
2846 printPol.AnonymousTagLocations = false;
2847 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2848 stream.flush();
2849 Error("InspectMembers",
2850 "Cannot retrieve QualType for member %s while inspecting class %s",
2851 memberName.c_str(), clname);
2852 continue; // skip member
2853 }
2854 const clang::Type* memType = memberQT.getTypePtr();
2855 if (!memType) {
2856 std::string memberName;
2857 llvm::raw_string_ostream stream(memberName);
2858 // Don't trigger fopen of the source file to count lines:
2859 printPol.AnonymousTagLocations = false;
2860 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2861 stream.flush();
2862 Error("InspectMembers",
2863 "Cannot retrieve Type for member %s while inspecting class %s",
2864 memberName.c_str(), clname);
2865 continue; // skip member
2866 }
2867
2868 const clang::Type* memNonPtrType = memType;
2869 Bool_t ispointer = false;
2870 if (memNonPtrType->isPointerType()) {
2871 ispointer = true;
2872 clang::QualType ptrQT
2873 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2874 if (recordType) {
2875 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2876 ptrQT = ROOT::TMetaUtils::ReSubstTemplateArg(ptrQT, recordType);
2877 }
2878 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2879 if (ptrQT.isNull()) {
2880 std::string memberName;
2881 llvm::raw_string_ostream stream(memberName);
2882 // Don't trigger fopen of the source file to count lines:
2883 printPol.AnonymousTagLocations = false;
2884 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2885 stream.flush();
2886 Error("InspectMembers",
2887 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2888 memberName.c_str(), clname);
2889 continue; // skip member
2890 }
2891 memNonPtrType = ptrQT.getTypePtr();
2892 }
2893
2894 // assemble array size(s): "[12][4][]"
2895 llvm::SmallString<8> arraySize;
2896 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2897 unsigned arrLevel = 0;
2898 bool haveErrorDueToArray = false;
2899 while (arrType) {
2900 ++arrLevel;
2901 arraySize += '[';
2902 const clang::ConstantArrayType* constArrType =
2903 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2904 if (constArrType) {
2905 constArrType->getSize().toStringUnsigned(arraySize);
2906 }
2907 arraySize += ']';
2908 clang::QualType subArrQT = arrType->getElementType();
2909 if (subArrQT.isNull()) {
2910 std::string memberName;
2911 llvm::raw_string_ostream stream(memberName);
2912 // Don't trigger fopen of the source file to count lines:
2913 printPol.AnonymousTagLocations = false;
2914 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2915 stream.flush();
2916 Error("InspectMembers",
2917 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
2918 arrLevel, subArrQT.getAsString(printPol).c_str(),
2919 memberName.c_str(), clname);
2920 haveErrorDueToArray = true;
2921 break;
2922 }
2923 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
2924 }
2925 if (haveErrorDueToArray) {
2926 continue; // skip member
2927 }
2928
2929 // construct member name
2930 std::string fieldName;
2931 if (memType->isPointerType()) {
2932 fieldName = "*";
2933 }
2934
2935 // Check if this field has a custom ioname, if not, just use the one of the decl
2936 std::string ioname(iField->getName());
2937 ROOT::TMetaUtils::ExtractAttrPropertyFromName(**iField,"ioname",ioname);
2938 fieldName += ioname;
2939 fieldName += arraySize;
2940
2941 // get member offset
2942 // NOTE currently we do not support bitfield and do not support
2943 // member that are not aligned on 'bit' boundaries.
2944 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
2945 ptrdiff_t fieldOffset = offset.getQuantity();
2946
2947 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fBits[2]", fBits);
2948 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fName", &fName);
2949 // R__insp.InspectMember(fName, "fName.");
2950 // R__insp.Inspect(R__cl, R__insp.GetParent(), "*fClass", &fClass);
2951
2952 // If the class has a custom streamer and the type of the filed is a
2953 // private enum, struct or class, skip it.
2954 if (!insp.IsTreatingNonAccessibleTypes()){
2955 auto iFiledQtype = iField->getType();
2956 if (auto tagDecl = iFiledQtype->getAsTagDecl()){
2957 auto declAccess = tagDecl->getAccess();
2958 if (declAccess == AS_private || declAccess == AS_protected) {
2959 continue;
2960 }
2961 }
2962 }
2963
2964 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
2965
2966 if (!ispointer) {
2967 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
2968 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
2969 // nested objects get an extra call to InspectMember
2970 // R__insp.InspectMember("FileStat_t", (void*)&fFileStat, "fFileStat.", false);
2971 std::string sFieldRecName;
2972 if (!ROOT::TMetaUtils::ExtractAttrPropertyFromName(*fieldRecDecl,"iotype",sFieldRecName)){
2974 clang::QualType(memNonPtrType,0),
2975 *fInterpreter,
2977 }
2978
2979 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
2980 // if we can not find the member (which should not really happen),
2981 // let's consider it transient.
2982 Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();
2983
2984 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
2985 (fieldName + '.').c_str(), transient);
2986
2987 }
2988 }
2989 } // loop over fields
2990
2991 // inspect bases
2992 // TNamed::ShowMembers(R__insp);
2993 unsigned iNBase = 0;
2994 for (clang::CXXRecordDecl::base_class_const_iterator iBase
2995 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
2996 iBase != eBase; ++iBase, ++iNBase) {
2997 clang::QualType baseQT = iBase->getType();
2998 if (baseQT.isNull()) {
2999 Error("InspectMembers",
3000 "Cannot find QualType for base number %d while inspecting class %s",
3001 iNBase, clname);
3002 continue;
3003 }
3004 const clang::CXXRecordDecl* baseDecl
3005 = baseQT->getAsCXXRecordDecl();
3006 if (!baseDecl) {
3007 Error("InspectMembers",
3008 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
3009 iNBase, clname);
3010 continue;
3011 }
3012 TClass* baseCl=nullptr;
3013 std::string sBaseName;
3014 // Try with the DeclId
3015 std::vector<TClass*> foundClasses;
3016 TClass::GetClass(static_cast<DeclId_t>(baseDecl), foundClasses);
3017 if (foundClasses.size()==1){
3018 baseCl=foundClasses[0];
3019 } else {
3020 // Try with the normalised Name, as a fallback
3021 if (!baseCl){
3023 baseQT,
3024 *fInterpreter,
3026 baseCl = TClass::GetClass(sBaseName.c_str());
3027 }
3028 }
3029
3030 if (!baseCl){
3031 std::string qualNameForDiag;
3032 ROOT::TMetaUtils::GetQualifiedName(qualNameForDiag, *baseDecl);
3033 Error("InspectMembers",
3034 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
3035 continue;
3036 }
3037
3038 int64_t baseOffset;
3039 if (iBase->isVirtual()) {
3041 if (!isTransient) {
3042 Error("InspectMembers",
3043 "Base %s of class %s is virtual but no object provided",
3044 sBaseName.c_str(), clname);
3045 }
3047 } else {
3048 // We have an object to determine the vbase offset.
3050 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
3051 if (ci && baseCi) {
3052 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
3053 true /*isDerivedObj*/);
3054 if (baseOffset == -1) {
3055 Error("InspectMembers",
3056 "Error calculating offset of virtual base %s of class %s",
3057 sBaseName.c_str(), clname);
3058 }
3059 } else {
3060 Error("InspectMembers",
3061 "Cannot calculate offset of virtual base %s of class %s",
3062 sBaseName.c_str(), clname);
3063 continue;
3064 }
3065 }
3066 } else {
3067 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
3068 }
3069 // TOFIX: baseCl can be null here!
3070 if (baseCl->IsLoaded()) {
3071 // For loaded class, CallShowMember will (especially for TObject)
3072 // call the virtual ShowMember rather than the class specific version
3073 // resulting in an infinite recursion.
3074 InspectMembers(insp, cobj + baseOffset, baseCl, isTransient);
3075 } else {
3076 baseCl->CallShowMembers(cobj + baseOffset,
3077 insp, isTransient);
3078 }
3079 } // loop over bases
3080}
3081
3082////////////////////////////////////////////////////////////////////////////////
3083/// Reset the interpreter internal state in case a previous action was not correctly
3084/// terminated.
3085
3087{
3088 // No-op there is not equivalent state (to be cleared) in Cling.
3089}
3090
3091////////////////////////////////////////////////////////////////////////////////
3092/// Delete existing temporary values.
3093
3095{
3096 // No-op for cling due to cling::Value.
3097}
3098
3099////////////////////////////////////////////////////////////////////////////////
3100/// Declare code to the interpreter, without any of the interpreter actions
3101/// that could trigger a re-interpretation of the code. I.e. make cling
3102/// behave like a compiler: no dynamic lookup, no input wrapping for
3103/// subsequent execution, no automatic provision of declarations but just a
3104/// plain `#include`.
3105/// Returns true on success, false on failure.
3106
3107bool TCling::Declare(const char* code)
3108{
3110
3111 SuspendAutoLoadingRAII autoLoadOff(this);
3112 SuspendAutoParsing autoParseRaii(this);
3113
3114 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
3115 fInterpreter->enableDynamicLookup(false);
3116 bool oldRawInput = fInterpreter->isRawInputEnabled();
3117 fInterpreter->enableRawInput(true);
3118
3119 Bool_t ret = LoadText(code);
3120
3121 fInterpreter->enableRawInput(oldRawInput);
3122 fInterpreter->enableDynamicLookup(oldDynLookup);
3123 return ret;
3124}
3125
3126////////////////////////////////////////////////////////////////////////////////
3127/// It calls a "fantom" method to synchronize user keyboard input
3128/// and ROOT prompt line.
3129
3131{
3133}
3134
3135// This static function is a hop of TCling::IsLibraryLoaded, which is taking a lock and calling
3136// into this function. This is because we wanted to avoid a duplication in TCling::IsLoaded, which
3137// was already taking a lock.
3138static Bool_t s_IsLibraryLoaded(const char* libname, cling::Interpreter* fInterpreter)
3139{
3140 // Check shared library.
3141 TString tLibName(libname);
3142 if (gSystem->FindDynamicLibrary(tLibName, kTRUE))
3143 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
3144 return false;
3145}
3146
3147Bool_t TCling::IsLibraryLoaded(const char* libname) const
3148{
3150 return s_IsLibraryLoaded(libname, GetInterpreterImpl());
3151}
3152
3153////////////////////////////////////////////////////////////////////////////////
3154/// Return true if ROOT has cxxmodules pcm for a given library name.
3155// FIXME: We need to be able to support lazy loading of pcm generated by ACLiC.
3156Bool_t TCling::HasPCMForLibrary(const char *libname) const
3157{
3158 llvm::StringRef ModuleName(libname);
3159 ModuleName = llvm::sys::path::stem(ModuleName);
3160 ModuleName.consume_front("lib");
3161
3162 // FIXME: In case when the modulemap is not yet loaded we will return the
3163 // wrong result. Consider a call to HasPCMForLibrary(../test/libEvent.so)
3164 // We will only load the modulemap for libEvent.so after we dlopen libEvent
3165 // which may happen after calling this interface. Maybe we should also check
3166 // if there is a Event.pcm file and a module.modulemap, load it and return
3167 // true.
3168 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
3169 clang::Module *M = moduleMap.findModule(ModuleName);
3170 return M && !M->IsUnimportable && M->getASTFile();
3171}
3172
3173////////////////////////////////////////////////////////////////////////////////
3174/// Return true if the file has already been loaded by cint.
3175/// We will try in this order:
3176/// actual filename
3177/// filename as a path relative to
3178/// the include path
3179/// the shared library path
3180
3182{
3184
3185 //FIXME: if we use llvm::sys::fs::make_absolute all this can go away. See
3186 // cling::DynamicLibraryManager.
3187
3188 std::string file_name = filename;
3189 size_t at = std::string::npos;
3190 while ((at = file_name.find("/./")) != std::string::npos)
3191 file_name.replace(at, 3, "/");
3192
3193 std::string filesStr = "";
3194 llvm::raw_string_ostream filesOS(filesStr);
3195 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3196 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
3197 filesOS.flush();
3198
3199 llvm::SmallVector<llvm::StringRef, 100> files;
3200 llvm::StringRef(filesStr).split(files, "\n");
3201
3202 std::set<std::string> fileMap;
3203 llvm::StringRef file_name_ref(file_name);
3204 // Fill fileMap; return early on exact match.
3205 for (llvm::SmallVector<llvm::StringRef, 100>::const_iterator
3206 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
3207 if ((*iF) == file_name_ref) return kTRUE; // exact match
3208 fileMap.insert(iF->str());
3209 }
3210
3211 if (fileMap.empty()) return kFALSE;
3212
3213 // Check MacroPath.
3214 TString sFilename(file_name.c_str());
3216 && fileMap.count(sFilename.Data())) {
3217 return kTRUE;
3218 }
3219
3220 // Check IncludePath.
3221 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
3222 incPath.Append(":").Prepend(" "); // to match " -I" (note leading ' ')
3223 incPath.ReplaceAll(" -I", ":"); // of form :dir1 :dir2:dir3
3224 while (incPath.Index(" :") != -1) {
3225 incPath.ReplaceAll(" :", ":");
3226 }
3227 incPath.Prepend(".:");
3228 sFilename = file_name.c_str();
3229 if (gSystem->FindFile(incPath, sFilename, kReadPermission)
3230 && fileMap.count(sFilename.Data())) {
3231 return kTRUE;
3232 }
3233
3234 // Check shared library.
3235 if (s_IsLibraryLoaded(file_name.c_str(), GetInterpreterImpl()))
3236 return kTRUE;
3237
3238 //FIXME: We must use the cling::Interpreter::lookupFileOrLibrary iface.
3239 clang::ConstSearchDirIterator *CurDir = nullptr;
3240 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
3241 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
3242 auto FE = HS.LookupFile(file_name.c_str(),
3243 clang::SourceLocation(),
3244 /*isAngled*/ false,
3245 /*FromDir*/ nullptr, CurDir,
3246 clang::ArrayRef<std::pair<const clang::FileEntry *,
3247 const clang::DirectoryEntry *>>(),
3248 /*SearchPath*/ nullptr,
3249 /*RelativePath*/ nullptr,
3250 /*RequestingModule*/ nullptr,
3251 /*SuggestedModule*/ nullptr,
3252 /*IsMapped*/ nullptr,
3253 /*IsFrameworkFound*/ nullptr,
3254 /*SkipCache*/ false,
3255 /*BuildSystemModule*/ false,
3256 /*OpenFile*/ false,
3257 /*CacheFail*/ false);
3258 if (FE) {
3259 // check in the source manager if the file is actually loaded
3260 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3261 // this works only with header (and source) files...
3262 clang::FileID FID = SM.translateFile(*FE);
3263 if (!FID.isInvalid() && FID.getHashValue() == 0)
3264 return kFALSE;
3265 else {
3266 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
3267 if (SLocE.isFile() && !SLocE.getFile().getContentCache().getBufferIfLoaded())
3268 return kFALSE;
3269 if (!FID.isInvalid())
3270 return kTRUE;
3271 }
3272 // ...then check shared library again, but with full path now
3273 sFilename = FE->getName().str();
3274 if (gSystem->FindDynamicLibrary(sFilename, kTRUE)
3275 && fileMap.count(sFilename.Data())) {
3276 return kTRUE;
3277 }
3278 }
3279 return kFALSE;
3280}
3281
3282
3283#if defined(R__MACOSX)
3284
3285////////////////////////////////////////////////////////////////////////////////
3286/// Check if lib is in the dynamic linker cache, returns true if it is, and if so,
3287/// modifies the library file name parameter `lib` from `/usr/lib/libFOO.dylib`
3288/// to `-lFOO` such that it can be passed to the linker.
3289/// This is a unique feature of macOS 11.
3290
3291static bool R__UpdateLibFileForLinking(TString &lib)
3292{
3293 const char *mapfile = nullptr;
3294#if __x86_64__
3295 mapfile = "/System/Library/dyld/dyld_shared_cache_x86_64.map";
3296#elif __arm64__
3297 mapfile = "/System/Library/dyld/dyld_shared_cache_arm64e.map";
3298#else
3299 #error unsupported architecture
3300#endif
3301 if (std::ifstream cacheMap{mapfile}) {
3302 std::string line;
3303 while (getline(cacheMap, line)) {
3304 if (line.find(lib) != std::string::npos) {
3305 lib.ReplaceAll("/usr/lib/lib","-l");
3306 lib.ReplaceAll(".dylib","");
3307 return true;
3308 }
3309 }
3310 return false;
3311 }
3312 return false;
3313}
3314#endif // R__MACOSX
3315
3316#if defined (R__LINUX) || defined (R__FBSD)
3317
3318////////////////////////////////////////////////////////////////////////////////
3319/// Callback for dl_iterate_phdr(), see `man dl_iterate_phdr`.
3320/// Collects opened libraries.
3321
3322static int callback_for_dl_iterate_phdr(struct dl_phdr_info *info, size_t size, void *data)
3323{
3324 // This function is called through UpdateListOfLoadedSharedLibraries() which is locked.
3325 static std::unordered_set<decltype(info->dlpi_addr)> sKnownLoadedLibBaseAddrs;
3326
3327 auto newLibs = static_cast<std::vector<std::string>*>(data);
3328 if (!sKnownLoadedLibBaseAddrs.count(info->dlpi_addr)) {
3329 // Skip \0, "", and kernel pseudo-libs linux-vdso.so.1 or linux-gate.so.1
3330 if (info->dlpi_name && info->dlpi_name[0]
3331#if defined(R__FBSD)
3332 //skip the executable (with null addr)
3333 && info->dlpi_addr
3334 //has no path
3335 && strncmp(info->dlpi_name, "[vdso]", 6)
3336 //the linker does not like to be mmapped
3337 //causes a crash in cling::DynamicLibraryManager::loadLibrary())
3338 //with error message "mmap of entire address space failed: Cannot allocate memory"
3339 && strncmp(info->dlpi_name, "/libexec/ld-elf.so.1", 20)
3340#endif
3341 && strncmp(info->dlpi_name, "linux-vdso.so", 13)
3342 && strncmp(info->dlpi_name, "linux-vdso32.so", 15)
3343 && strncmp(info->dlpi_name, "linux-vdso64.so", 15)
3344 && strncmp(info->dlpi_name, "linux-gate.so", 13))
3345 newLibs->emplace_back(info->dlpi_name);
3346 sKnownLoadedLibBaseAddrs.insert(info->dlpi_addr);
3347 }
3348 // No matter what the doc says, return != 0 means "stop the iteration".
3349 return 0;
3350}
3351
3352#endif // R__LINUX || R__FBSD
3353
3354
3355////////////////////////////////////////////////////////////////////////////////
3356
3358{
3359#if defined(R__WIN32) || defined(__CYGWIN__)
3360 HMODULE hModules[1024];
3361 void *hProcess;
3362 unsigned long cbModules;
3363 unsigned int i;
3364 hProcess = (void *)::GetCurrentProcess();
3365 ::EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbModules);
3366 // start at 1 to skip the executable itself
3367 for (i = 1; i < (cbModules / sizeof(void *)); i++) {
3368 static const int bufsize = 260;
3369 wchar_t winname[bufsize];
3370 char posixname[bufsize];
3371 ::GetModuleFileNameExW(hProcess, hModules[i], winname, bufsize);
3372#if defined(__CYGWIN__)
3373 cygwin_conv_path(CCP_WIN_W_TO_POSIX, winname, posixname, bufsize);
3374#else
3375 std::wstring wpath = winname;
3376 std::replace(wpath.begin(), wpath.end(), '\\', '/');
3377 string path(wpath.begin(), wpath.end());
3378 strncpy(posixname, path.c_str(), bufsize);
3379#endif
3380 if (!fSharedLibs.Contains(posixname)) {
3381 RegisterLoadedSharedLibrary(posixname);
3382 }
3383 }
3384#elif defined(R__MACOSX)
3385 // fPrevLoadedDynLibInfo stores the *next* image index to look at
3386 uint32_t imageIndex = (uint32_t) (size_t) fPrevLoadedDynLibInfo;
3387
3388 while (const mach_header* mh = _dyld_get_image_header(imageIndex)) {
3389 // Skip non-dylibs
3390 if (mh->filetype == MH_DYLIB) {
3391 if (const char* imageName = _dyld_get_image_name(imageIndex)) {
3392 RegisterLoadedSharedLibrary(imageName);
3393 }
3394 }
3395
3396 ++imageIndex;
3397 }
3398 fPrevLoadedDynLibInfo = (void*)(size_t)imageIndex;
3399#elif defined(R__LINUX) || defined(R__FBSD)
3400 // fPrevLoadedDynLibInfo is unused on Linux.
3401 (void) fPrevLoadedDynLibInfo;
3402
3403 std::vector<std::string> newLibs;
3404 dl_iterate_phdr(callback_for_dl_iterate_phdr, &newLibs);
3405 for (auto &&lib: newLibs)
3406 RegisterLoadedSharedLibrary(lib.c_str());
3407#else
3408 Error("TCling::UpdateListOfLoadedSharedLibraries",
3409 "Platform not supported!");
3410#endif
3411}
3412
3413namespace {
3414template <int N>
3415static bool StartsWithStrLit(const char *haystack, const char (&needle)[N]) {
3416 return !strncmp(haystack, needle, N - 1);
3417}
3418}
3419
3420////////////////////////////////////////////////////////////////////////////////
3421/// Register a new shared library name with the interpreter; add it to
3422/// fSharedLibs.
3423
3425{
3426 // Ignore NULL filenames, aka "the process".
3427 if (!filename) return;
3428
3429 // Tell the interpreter that this library is available; all libraries can be
3430 // used to resolve symbols.
3431 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3432 if (!DLM->isLibraryLoaded(filename)) {
3433 DLM->loadLibrary(filename, true /*permanent*/, true /*resolved*/);
3434 }
3435
3436#if defined(R__MACOSX)
3437 // Check that this is not a system library that does not exist on disk.
3438 auto lenFilename = strlen(filename);
3439 auto isInMacOSSystemDir = [](const char *fn) {
3440 return StartsWithStrLit(fn, "/usr/lib/") || StartsWithStrLit(fn, "/System/Library/");
3441 };
3442 if (!strcmp(filename, "cl_kernels") // yepp, no directory
3443
3444 // These we should not link with (e.g. because they forward to .tbd):
3445 || StartsWithStrLit(filename, "/usr/lib/system/")
3446 || StartsWithStrLit(filename, "/usr/lib/libc++")
3447 || StartsWithStrLit(filename, "/System/Library/Frameworks/")
3448 || StartsWithStrLit(filename, "/System/Library/PrivateFrameworks/")
3449 || StartsWithStrLit(filename, "/System/Library/CoreServices/")
3450 || StartsWithStrLit(filename, "/usr/lib/libSystem")
3451 || StartsWithStrLit(filename, "/usr/lib/libstdc++")
3452 || StartsWithStrLit(filename, "/usr/lib/libicucore")
3453 || StartsWithStrLit(filename, "/usr/lib/libbsm")
3454 || StartsWithStrLit(filename, "/usr/lib/libobjc")
3455 || StartsWithStrLit(filename, "/usr/lib/libresolv")
3456 || StartsWithStrLit(filename, "/usr/lib/libauto")
3457 || StartsWithStrLit(filename, "/usr/lib/libcups")
3458 || StartsWithStrLit(filename, "/usr/lib/libDiagnosticMessagesClient")
3459 || StartsWithStrLit(filename, "/usr/lib/liblangid")
3460 || StartsWithStrLit(filename, "/usr/lib/libCRFSuite")
3461 || StartsWithStrLit(filename, "/usr/lib/libpam")
3462 || StartsWithStrLit(filename, "/usr/lib/libOpenScriptingUtil")
3463 || StartsWithStrLit(filename, "/usr/lib/libextension")
3464 || StartsWithStrLit(filename, "/usr/lib/libAudioToolboxUtility")
3465 || StartsWithStrLit(filename, "/usr/lib/liboah")
3466 || StartsWithStrLit(filename, "/usr/lib/libRosetta")
3467 || StartsWithStrLit(filename, "/usr/lib/libCoreEntitlements")
3468 || StartsWithStrLit(filename, "/usr/lib/libssl.")
3469 || StartsWithStrLit(filename, "/usr/lib/libcrypto.")
3470
3471 // The system lib is likely in macOS's blob.
3472 || (isInMacOSSystemDir(filename) && gSystem->AccessPathName(filename))
3473
3474 // "Link against the umbrella framework 'System.framework' instead"
3475 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_kernel")
3476 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_platform")
3477 || StartsWithStrLit(filename, "/usr/lib/system/libsystem_pthread")
3478
3479 // "cannot link directly with dylib/framework, your binary is not an allowed client of
3480 // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
3481 // SDKs/MacOSX.sdk/usr/lib/libAudioToolboxUtility.tbd for architecture x86_64
3482 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4, ".tbd")))
3483 return;
3484 TString sFileName(filename);
3485 R__UpdateLibFileForLinking(sFileName);
3486 filename = sFileName.Data();
3487#elif defined(__CYGWIN__)
3488 // Check that this is not a system library
3489 static const int bufsize = 260;
3490 char posixwindir[bufsize];
3491 char *windir = getenv("WINDIR");
3492 if (windir)
3493 cygwin_conv_path(CCP_WIN_A_TO_POSIX, windir, posixwindir, bufsize);
3494 else
3495 snprintf(posixwindir, sizeof(posixwindir), "/Windows/");
3496 if (strstr(filename, posixwindir) ||
3497 strstr(filename, "/usr/bin/cyg"))
3498 return;
3499#elif defined(R__WIN32)
3500 if (strstr(filename, "/Windows/"))
3501 return;
3502#elif defined (R__LINUX)
3503 if (strstr(filename, "/ld-linux")
3504 || strstr(filename, "linux-gnu/")
3505 || strstr(filename, "/libstdc++.")
3506 || strstr(filename, "/libgcc")
3507 || strstr(filename, "/libc.")
3508 || strstr(filename, "/libdl.")
3509 || strstr(filename, "/libm."))
3510 return;
3511#endif
3512 // Update string of available libraries.
3513 if (!fSharedLibs.IsNull()) {
3514 fSharedLibs.Append(" ");
3515 }
3517}
3518
3519////////////////////////////////////////////////////////////////////////////////
3520/// Load a library file in cling's memory.
3521/// if 'system' is true, the library is never unloaded.
3522/// Return 0 on success, -1 on failure.
3523
3524Int_t TCling::Load(const char* filename, Bool_t system)
3525{
3526 assert(!IsFromRootCling() && "Trying to load library from rootcling!");
3527
3528 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3530 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3531 std::string canonLib = DLM->lookupLibrary(filename);
3532 cling::DynamicLibraryManager::LoadLibResult res
3533 = cling::DynamicLibraryManager::kLoadLibNotFound;
3534 if (!canonLib.empty()) {
3535 if (system)
3536 res = DLM->loadLibrary(filename, system, true);
3537 else {
3538 // For the non system libs, we'd like to be able to unload them.
3539 // FIXME: Here we lose the information about kLoadLibAlreadyLoaded case.
3540 cling::Interpreter::CompilationResult compRes;
3541 HandleInterpreterException(GetMetaProcessorImpl(), Form(".L %s", canonLib.c_str()), compRes, /*cling::Value*/nullptr);
3542 if (compRes == cling::Interpreter::kSuccess)
3543 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3544 }
3545 }
3546
3547 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3549 }
3550 switch (res) {
3551 case cling::DynamicLibraryManager::kLoadLibSuccess: return 0;
3552 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return 1;
3553 default: break;
3554 };
3555 return -1;
3556}
3557
3558////////////////////////////////////////////////////////////////////////////////
3559/// Load a macro file in cling's memory.
3560
3561void TCling::LoadMacro(const char* filename, EErrorCode* error)
3562{
3563 ProcessLine(Form(".L %s", filename), error);
3564}
3565
3566////////////////////////////////////////////////////////////////////////////////
3567/// Let cling process a command line asynch.
3568
3570{
3571 return ProcessLine(line, error);
3572}
3573
3574////////////////////////////////////////////////////////////////////////////////
3575/// Let cling process a command line synchronously, i.e we are waiting
3576/// it will be finished.
3577
3579{
3581 if (gApplication) {
3582 if (gApplication->IsCmdThread()) {
3583 return ProcessLine(line, error);
3584 }
3585 return 0;
3586 }
3587 return ProcessLine(line, error);
3588}
3589
3590////////////////////////////////////////////////////////////////////////////////
3591/// Directly execute an executable statement (e.g. "func()", "3+5", etc.
3592/// however not declarations, like "Int_t x;").
3593
3595{
3596#ifdef R__WIN32
3597 // Test on ApplicationImp not being 0 is needed because only at end of
3598 // TApplication ctor the IsLineProcessing flag is set to 0, so before
3599 // we can not use it.
3601 while (gROOT->IsLineProcessing() && !gApplication) {
3602 Warning("Calc", "waiting for cling thread to free");
3603 gSystem->Sleep(500);
3604 }
3605 gROOT->SetLineIsProcessing();
3606 }
3607#endif // R__WIN32
3609 if (error) {
3610 *error = TInterpreter::kNoError;
3611 }
3612 cling::Value valRef;
3613 cling::Interpreter::CompilationResult cr = cling::Interpreter::kFailure;
3614 try {
3615 cr = fInterpreter->evaluate(line, valRef);
3616 }
3617 catch (cling::InterpreterException& ex)
3618 {
3619 Error("Calc", "%s.\n%s", ex.what(), "Evaluation of your expression was aborted.");
3620 ex.diagnose();
3621 cr = cling::Interpreter::kFailure;
3622 }
3623
3624 if (cr != cling::Interpreter::kSuccess) {
3625 // Failure in compilation.
3626 if (error) {
3627 // Note: Yes these codes are weird.
3629 }
3630 return 0L;
3631 }
3632 if (!valRef.isValid()) {
3633 // Failure at runtime.
3634 if (error) {
3635 // Note: Yes these codes are weird.
3636 *error = TInterpreter::kDangerous;
3637 }
3638 return 0L;
3639 }
3640
3641 if (valRef.isVoid()) {
3642 return 0;
3643 }
3644
3645 RegisterTemporary(valRef);
3646#ifdef R__WIN32
3648 gROOT->SetLineHasBeenProcessed();
3649 }
3650#endif // R__WIN32
3651 return valRef.castAs<Longptr_t>();
3652}
3653
3654////////////////////////////////////////////////////////////////////////////////
3655/// Set a getline function to call when input is needed.
3656
3657void TCling::SetGetline(const char * (*getlineFunc)(const char* prompt),
3658 void (*histaddFunc)(const char* line))
3659{
3660 // If cling offers a replacement for G__pause(), it would need to
3661 // also offer a way to customize at least the history recording.
3662
3663#if defined(R__MUST_REVISIT)
3664#if R__MUST_REVISIT(6,2)
3665 Warning("SetGetline","Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3666#endif
3667#endif
3668}
3669
3670////////////////////////////////////////////////////////////////////////////////
3671/// Helper function to increase the internal Cling count of transactions
3672/// that change the AST.
3673
3674Bool_t TCling::HandleNewTransaction(const cling::Transaction &T)
3675{
3677
3678 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3679 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3680 || T.macros_begin() != T.macros_end()
3681 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3683 return true;
3684 }
3685 return false;
3686}
3687
3688////////////////////////////////////////////////////////////////////////////////
3689/// Delete object from cling symbol table so it can not be used anymore.
3690/// cling objects are always on the heap.
3691
3693{
3694 // NOTE: When replacing the mutex by a ReadWrite mutex, we **must**
3695 // put in place the Read/Write part here. Keeping the write lock
3696 // here is 'catasptrophic' for scaling as it means that ALL calls
3697 // to RecursiveRemove will take the write lock and performance
3698 // of many threads trying to access the write lock at the same
3699 // time is relatively bad.
3701 // Note that fgSetOfSpecials is supposed to be updated by TClingCallbacks::tryFindROOTSpecialInternal
3702 // (but isn't at the moment).
3703 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3704 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3705 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3707 DeleteGlobal(obj);
3708 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3709 }
3710 }
3711}
3712
3713////////////////////////////////////////////////////////////////////////////////
3714/// Pressing Ctrl+C should forward here. In the case where we have had
3715/// continuation requested we must reset it.
3716
3718{
3719 fMetaProcessor->cancelContinuation();
3720 // Reset the Cling state to the state saved by the last call to
3721 // TCling::SaveContext().
3722#if defined(R__MUST_REVISIT)
3723#if R__MUST_REVISIT(6,2)
3725 Warning("Reset","Cling should support the equivalent of scratch_upto(&fDictPos)");
3726#endif
3727#endif
3728}
3729
3730////////////////////////////////////////////////////////////////////////////////
3731/// Reset the Cling state to its initial state.
3732
3734{
3735#if defined(R__MUST_REVISIT)
3736#if R__MUST_REVISIT(6,2)
3738 Warning("ResetAll","Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3739#endif
3740#endif
3741}
3742
3743////////////////////////////////////////////////////////////////////////////////
3744/// Reset in Cling the list of global variables to the state saved by the last
3745/// call to TCling::SaveGlobalsContext().
3746///
3747/// Note: Right now, all we do is run the global destructors.
3748
3750{
3752 // TODO:
3753 // Here we should iterate over the transactions (N-3) and revert.
3754 // N-3 because the first three internal to cling.
3755
3756 fInterpreter->runAndRemoveStaticDestructors();
3757}
3758
3759////////////////////////////////////////////////////////////////////////////////
3760/// Reset the Cling 'user' global objects/variables state to the state saved by the last
3761/// call to TCling::SaveGlobalsContext().
3762
3764{
3765#if defined(R__MUST_REVISIT)
3766#if R__MUST_REVISIT(6,2)
3768 Warning("ResetGlobalVar","Cling should support the equivalent of resetglobalvar(obj)");
3769#endif
3770#endif
3771}
3772
3773////////////////////////////////////////////////////////////////////////////////
3774/// Rewind Cling dictionary to the point where it was before executing
3775/// the current macro. This function is typically called after SEGV or
3776/// ctlr-C after doing a longjmp back to the prompt.
3777
3779{
3780#if defined(R__MUST_REVISIT)
3781#if R__MUST_REVISIT(6,2)
3783 Warning("RewindDictionary","Cling should provide a way to revert transaction similar to rewinddictionary()");
3784#endif
3785#endif
3786}
3787
3788////////////////////////////////////////////////////////////////////////////////
3789/// Delete obj from Cling symbol table so it cannot be accessed anymore.
3790/// Returns 1 in case of success and 0 in case object was not in table.
3791
3793{
3794#if defined(R__MUST_REVISIT)
3795#if R__MUST_REVISIT(6,2)
3797 Warning("DeleteGlobal","Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3798#endif
3799#endif
3800 return 0;
3801}
3802
3803////////////////////////////////////////////////////////////////////////////////
3804/// Undeclare obj called name.
3805/// Returns 1 in case of success, 0 for failure.
3806
3808{
3809#if defined(R__MUST_REVISIT)
3810#if R__MUST_REVISIT(6,2)
3811 Warning("DeleteVariable","should do more that just reseting the value to zero");
3812#endif
3813#endif
3814
3816 llvm::StringRef srName(name);
3817 const char* unscopedName = name;
3818 llvm::StringRef::size_type posScope = srName.rfind("::");
3819 const clang::DeclContext* declCtx = nullptr;
3820 if (posScope != llvm::StringRef::npos) {
3821 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3822 const clang::Decl* scopeDecl
3823 = lh.findScope(srName.substr(0, posScope),
3824 cling::LookupHelper::WithDiagnostics);
3825 if (!scopeDecl) {
3826 Error("DeleteVariable", "Cannot find enclosing scope for variable %s",
3827 name);
3828 return 0;
3829 }
3830 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3831 if (!declCtx) {
3832 Error("DeleteVariable",
3833 "Enclosing scope for variable %s is not a declaration context",
3834 name);
3835 return 0;
3836 }
3837 unscopedName += posScope + 2;
3838 }
3839 // Could trigger deserialization of decls.
3840 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
3841 clang::NamedDecl* nVarDecl
3842 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3843 if (!nVarDecl) {
3844 Error("DeleteVariable", "Unknown variable %s", name);
3845 return 0;
3846 }
3847 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3848 if (!varDecl) {
3849 Error("DeleteVariable", "Entity %s is not a variable", name);
3850 return 0;
3851 }
3852
3853 clang::QualType qType = varDecl->getType();
3854 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3855 // Cannot set a reference's address to nullptr; the JIT can place it
3856 // into read-only memory (ROOT-7100).
3857 if (type->isPointerType()) {
3858 int** ppInt = (int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
3859 // set pointer to invalid.
3860 if (ppInt) *ppInt = nullptr;
3861 }
3862 return 1;
3863}
3864
3865////////////////////////////////////////////////////////////////////////////////
3866/// Save the current Cling state.
3867
3869{
3870#if defined(R__MUST_REVISIT)
3871#if R__MUST_REVISIT(6,2)
3873 Warning("SaveContext","Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
3874#endif
3875#endif
3876}
3877
3878////////////////////////////////////////////////////////////////////////////////
3879/// Save the current Cling state of global objects.
3880
3882{
3883#if defined(R__MUST_REVISIT)
3884#if R__MUST_REVISIT(6,2)
3886 Warning("SaveGlobalsContext","Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
3887#endif
3888#endif
3889}
3890
3891////////////////////////////////////////////////////////////////////////////////
3892/// No op: see TClingCallbacks (used to update the list of globals)
3893
3895{
3896}
3897
3898////////////////////////////////////////////////////////////////////////////////
3899/// No op: see TClingCallbacks (used to update the list of global functions)
3900
3902{
3903}
3904
3905////////////////////////////////////////////////////////////////////////////////
3906/// No op: see TClingCallbacks (used to update the list of types)
3907
3909{
3910}
3911
3912////////////////////////////////////////////////////////////////////////////////
3913/// Check in what order the member of a tuple are layout.
3914enum class ETupleOrdering {
3915 kAscending,
3918};
3919
3921{
3924};
3925
3927{
3930};
3931
3933{
3934 std::tuple<int,double> value;
3937
3938 size_t offset0 = ((char*)&(std::get<0>(value))) - ((char*)&value);
3939 size_t offset1 = ((char*)&(std::get<1>(value))) - ((char*)&value);
3940
3941 size_t ascOffset0 = ((char*)&(asc._0)) - ((char*)&asc);
3942 size_t ascOffset1 = ((char*)&(asc._1)) - ((char*)&asc);
3943
3944 size_t desOffset0 = ((char*)&(des._0)) - ((char*)&des);
3945 size_t desOffset1 = ((char*)&(des._1)) - ((char*)&des);
3946
3947 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
3949 } else if (offset0 == desOffset0 && offset1 == desOffset1) {
3951 } else {
3953 }
3954}
3955
3956static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh, Bool_t silent)
3957{
3958 TClassEdit::TSplitType tupleContent(classname);
3959 std::string alternateName = "TEmulatedTuple";
3960 alternateName.append( classname + 5 );
3961
3962 std::string fullname = "ROOT::Internal::" + alternateName;
3963 if (lh.findScope(fullname, cling::LookupHelper::NoDiagnostics,
3964 /*resultType*/nullptr, /* intantiateTemplate= */ false))
3965 return fullname;
3966
3967 {
3968 // Check if we can produce the tuple
3969 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
3970 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
3971 auto deleter = [](TypeInfo_t *type) {
3972 gInterpreter->TypeInfo_Delete(type);
3973 };
3974 std::unique_ptr<TypeInfo_t, decltype(deleter)> type{ gInterpreter->TypeInfo_Factory(), deleter };
3975 while (iter != theEnd) {
3976 gInterpreter->TypeInfo_Init(type.get(), iter->c_str());
3977 if (gInterpreter->TypeInfo_Property(type.get()) & kIsNotReacheable) {
3978 if (!silent)
3979 Error("Load","Could not declare alternate type for %s since %s (or one of its context) is private or protected",
3980 classname, iter->c_str());
3981 return "";
3982 }
3983 ++iter;
3984 }
3985 }
3986
3987 std::string guard_name;
3988 ROOT::TMetaUtils::GetCppName(guard_name,alternateName.c_str());
3989 std::ostringstream guard;
3990 guard << "ROOT_INTERNAL_TEmulated_";
3991 guard << guard_name;
3992
3993 std::ostringstream alternateTuple;
3994 alternateTuple << "#ifndef " << guard.str() << "\n";
3995 alternateTuple << "#define " << guard.str() << "\n";
3996 alternateTuple << "namespace ROOT { namespace Internal {\n";
3997 alternateTuple << "template <class... Types> struct TEmulatedTuple;\n";
3998 alternateTuple << "template <> struct " << alternateName << " {\n";
3999
4000 // This could also be a compile time choice ...
4001 switch(IsTupleAscending()) {
4003 unsigned int nMember = 0;
4004 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple).
4005 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
4006 while (iter != theEnd) {
4007 alternateTuple << " " << *iter << " _" << nMember << ";\n";
4008 ++iter;
4009 ++nMember;
4010 }
4011 break;
4012 }
4014 unsigned int nMember = tupleContent.fElements.size() - 3;
4015 auto iter = tupleContent.fElements.rbegin() + 1; // skip the 'stars'.
4016 auto theEnd = tupleContent.fElements.rend() - 1; // Skip the template name (tuple).
4017 while (iter != theEnd) {
4018 alternateTuple << " " << *iter << " _" << nMember << ";\n";
4019 ++iter;
4020 --nMember;
4021 }
4022 break;
4023 }
4025 Fatal("TCling::SetClassInfo::AlternateTuple",
4026 "Layout of std::tuple on this platform is unexpected.");
4027 break;
4028 }
4029 }
4030
4031 alternateTuple << "};\n";
4032 alternateTuple << "}}\n";
4033 alternateTuple << "#endif\n";
4034 if (!gCling->Declare(alternateTuple.str().c_str()))
4035 {
4036 // Declare is not silent (yet?), so add an explicit error message
4037 // to indicate the consequence of the syntax errors.
4038 Error("Load","Could not declare %s",alternateName.c_str());
4039 return "";
4040 }
4041 alternateName = "ROOT::Internal::" + alternateName;
4042 return alternateName;
4043}
4044
4045////////////////////////////////////////////////////////////////////////////////
4046/// Set pointer to the TClingClassInfo in TClass.
4047/// If 'reload' is true, (attempt to) generate a new ClassInfo even if we
4048/// already have one.
4049
4050void TCling::SetClassInfo(TClass* cl, Bool_t reload, Bool_t silent)
4051{
4052 // We are shutting down, there is no point in reloading, it only triggers
4053 // redundant deserializations.
4054 if (fIsShuttingDown) {
4055 // Remove the decl_id from the DeclIdToTClass map
4056 if (cl->fClassInfo) {
4058 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4059 // Test again as another thread may have set fClassInfo to nullptr.
4060 if (TClinginfo) {
4061 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4062 }
4063 delete TClinginfo;
4064 cl->fClassInfo = nullptr;
4065 }
4066 return;
4067 }
4068
4070 if (cl->fClassInfo && !reload) {
4071 return;
4072 }
4073 //Remove the decl_id from the DeclIdToTClass map
4074 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
4075 if (TClinginfo) {
4076 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
4077 }
4078 delete TClinginfo;
4079 cl->fClassInfo = nullptr;
4080 std::string name(cl->GetName());
4081
4082 auto SetWithoutClassInfoState = [](TClass *cl)
4083 {
4084 if (cl->fState != TClass::kHasTClassInit) {
4085 if (cl->fStreamerInfo->GetEntries() != 0) {
4087 } else {
4089 }
4090 }
4091 };
4092 // Handle the special case of 'tuple' where we ignore the real implementation
4093 // details and just overlay a 'simpler'/'simplistic' version that is easy
4094 // for the I/O to understand and handle.
4095 if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
4096 if (!reload)
4097 name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper(), silent);
4098 if (reload || name.empty()) {
4099 // We could not generate the alternate
4100 SetWithoutClassInfoState(cl);
4101 return;
4102 }
4103 }
4104
4105 bool instantiateTemplate = !cl->TestBit(TClass::kUnloading);
4106 // FIXME: Rather than adding an option to the TClingClassInfo, we should consider combining code
4107 // that is currently in the caller (like SetUnloaded) that disable AutoLoading and AutoParsing and
4108 // code is in the callee (disabling template instantiation) and end up with a more explicit class:
4109 // TClingClassInfoReadOnly.
4110 TClingClassInfo* info = new TClingClassInfo(GetInterpreterImpl(), name.c_str(), instantiateTemplate);
4111 if (!info->IsValid()) {
4112 SetWithoutClassInfoState(cl);
4113 delete info;
4114 return;
4115 }
4116 cl->fClassInfo = (ClassInfo_t*)info; // Note: We are transferring ownership here.
4117 // In case a class contains an external enum, the enum will be seen as a
4118 // class. We must detect this special case and make the class a Zombie.
4119 // Here we assume that a class has at least one method.
4120 // We can NOT call TClass::Property from here, because this method
4121 // assumes that the TClass is well formed to do a lot of information
4122 // caching. The method SetClassInfo (i.e. here) is usually called during
4123 // the building phase of the TClass, hence it is NOT well formed yet.
4124 Bool_t zombieCandidate = kFALSE;
4125 if (
4126 info->IsValid() &&
4127 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
4128 ) {
4129 zombieCandidate = kTRUE;
4130 }
4131 if (!info->IsLoaded()) {
4132 if (info->Property() & (kIsNamespace)) {
4133 // Namespaces can have info but no corresponding CINT dictionary
4134 // because they are auto-created if one of their contained
4135 // classes has a dictionary.
4136 zombieCandidate = kTRUE;
4137 }
4138 // this happens when no dictionary is available
4139 delete info;
4140 cl->fClassInfo = nullptr;
4141 }
4142 if (zombieCandidate && !cl->GetCollectionType()) {
4143 cl->MakeZombie();
4144 }
4145 // If we reach here, the info was valid (See early returns).
4146 if (cl->fState != TClass::kHasTClassInit) {
4147 if (cl->fClassInfo) {
4149 } else {
4150// if (TClassEdit::IsSTLCont(cl->GetName()) {
4151// There will be an emulated collection proxy, is that the same?
4152// cl->fState = TClass::kEmulated;
4153// } else {
4154 if (cl->fStreamerInfo->GetEntries() != 0) {
4156 } else {
4158 }
4159// }
4160 }
4161 }
4162 if (cl->fClassInfo) {
4163 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
4164 }
4165}
4166
4167////////////////////////////////////////////////////////////////////////////////
4168/// Checks if an entity with the specified name is defined in Cling.
4169/// Returns kUnknown if the entity is not defined.
4170/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
4171/// Returns kKnown if the entity is defined.
4172///
4173/// By default, structs, namespaces, classes, enums and unions are looked for.
4174/// If the flag isClassOrNamespaceOnly is true, classes, structs and
4175/// namespaces only are considered. I.e. if the name is an enum or a union,
4176/// the returned value is false.
4177///
4178/// In the case where the class is not loaded and belongs to a namespace
4179/// or is nested, looking for the full class name is outputting a lots of
4180/// (expected) error messages. Currently the only way to avoid this is to
4181/// specifically check that each level of nesting is already loaded.
4182/// In case of templates the idea is that everything between the outer
4183/// '<' and '>' has to be skipped, e.g.: `aap<pippo<noot>::klaas>::a_class`
4184
4186TCling::CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly /* = kFALSE*/)
4187{
4189 static const char *anonEnum = "anonymous enum ";
4190 static const int cmplen = strlen(anonEnum);
4191
4192 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
4193 return kUnknown;
4194 }
4195
4196 // Do not turn on the AutoLoading if it is globally off.
4197 autoload = autoload && IsClassAutoLoadingEnabled();
4198
4199 // Avoid the double search below in case the name is a fundamental type
4200 // or typedef to a fundamental type.
4201 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
4202 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
4203
4204 if (fundType && fundType->GetType() < TVirtualStreamerInfo::kObject
4205 && fundType->GetType() > 0) {
4206 // Fundamental type, no a class.
4207 return kUnknown;
4208 }
4209
4210 // Migrated from within TClass::GetClass
4211 // If we want to know if a class or a namespace with this name exists in the
4212 // interpreter and this is an enum in the type system, before or after loading
4213 // according to the autoload function argument, return kUnknown.
4214 if (isClassOrNamespaceOnly && TEnum::GetEnum(name, autoload ? TEnum::kAutoload : TEnum::kNone))
4215 return kUnknown;
4216
4217 const char *classname = name;
4218
4219 // RAII to suspend and restore auto-loading and auto-parsing based on some external conditions.
4220 class MaybeSuspendAutoLoadParse {
4221 int fStoreAutoLoad = 0;
4222 int fStoreAutoParse = 0;
4223 bool fSuspendedAutoParse = false;
4224 public:
4225 MaybeSuspendAutoLoadParse(int autoload) {
4226 fStoreAutoLoad = ((TCling*)gCling)->SetClassAutoLoading(autoload);
4227 }
4228
4229 void SuspendAutoParsing() {
4230 fSuspendedAutoParse = true;
4231 fStoreAutoParse = ((TCling*)gCling)->SetSuspendAutoParsing(true);
4232 }
4233
4234 ~MaybeSuspendAutoLoadParse() {
4235 if (fSuspendedAutoParse)
4236 ((TCling*)gCling)->SetSuspendAutoParsing(fStoreAutoParse);
4237 ((TCling*)gCling)->SetClassAutoLoading(fStoreAutoLoad);
4238 }
4239 };
4240
4241 MaybeSuspendAutoLoadParse autoLoadParseRAII( autoload );
4242 if (TClassEdit::IsStdPair(classname) || TClassEdit::IsStdPairBase(classname))
4243 autoLoadParseRAII.SuspendAutoParsing();
4244
4245 // First we want to check whether the decl exist, but _without_
4246 // generating any template instantiation. However, the lookup
4247 // still will create a forward declaration of the class template instance
4248 // if it exist. In this case, the return value of findScope will still
4249 // be zero but the type will be initialized.
4250 // Note in the corresponding code in ROOT 5, CINT was not instantiating
4251 // this forward declaration.
4252 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4253 const clang::Type *type = nullptr;
4254 const clang::Decl *decl
4255 = lh.findScope(classname,
4256 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4257 : cling::LookupHelper::NoDiagnostics,
4258 &type, /* intantiateTemplate= */ false );
4259 if (!decl) {
4260 std::string buf = TClassEdit::InsertStd(classname);
4261 decl = lh.findScope(buf,
4262 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4263 : cling::LookupHelper::NoDiagnostics,
4264 &type,false);
4265 }
4266
4267 if (type) {
4268 // If decl==0 and the type is valid, then we have a forward declaration.
4269 if (!decl) {
4270 // If we have a forward declaration for a class template instantiation,
4271 // we want to ignore it if it was produced/induced by the call to
4272 // findScope, however we can not distinguish those from the
4273 // instantiation induce by 'soft' use (and thus also induce by the
4274 // same underlying code paths)
4275 // ['soft' use = use not requiring a complete definition]
4276 // So to reduce the amount of disruption to the existing code we
4277 // would just ignore those for STL collection, for which we really
4278 // need to have the compiled collection proxy (and thus the TClass
4279 // bootstrap).
4280 clang::ClassTemplateSpecializationDecl *tmpltDecl =
4281 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
4282 (type->getAsCXXRecordDecl());
4283 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
4284 // Since the point of instantiation is invalid, we 'guess' that
4285 // the 'instantiation' of the forwarded type appended in
4286 // findscope.
4287 if (ROOT::TMetaUtils::IsSTLCont(*tmpltDecl)) {
4288 // For STL Collection we return kUnknown.
4289 return kUnknown;
4290 }
4291 }
4292 }
4294 if (!tci.IsValid()) {
4295 return kUnknown;
4296 }
4297 auto propertiesMask = isClassOrNamespaceOnly ? kIsClass | kIsStruct | kIsNamespace :
4299
4300 if (tci.Property() & propertiesMask) {
4301 bool hasClassDefInline = false;
4302 if (isClassOrNamespaceOnly) {
4303 // We do not need to check for ClassDefInline when this is called from
4304 // TClass::Init, we only do it for the call from TClass::GetClass.
4305 auto hasDictionary = tci.GetMethod("Dictionary", "", false, nullptr, ROOT::kExactMatch);
4306 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, nullptr, ROOT::kExactMatch);
4307
4308 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
4309 int lineNumber = 0;
4310 bool success = false;
4311 std::tie(success, lineNumber) =
4312 ROOT::TMetaUtils::GetTrivialIntegralReturnValue(implLineFunc.GetAsFunctionDecl(), *fInterpreter);
4313 hasClassDefInline = success && (lineNumber == -1);
4314 }
4315 }
4316
4317 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
4318 // , hasClassDefInline);
4319
4320 // We are now sure that the entry is not in fact an autoload entry.
4321 if (hasClassDefInline)
4322 return kWithClassDefInline;
4323 else
4324 return kKnown;
4325 } else {
4326 // We are now sure that the entry is not in fact an autoload entry.
4327 return kUnknown;
4328 }
4329 }
4330
4331 if (decl)
4332 return kKnown;
4333 else
4334 return kUnknown;
4335
4336 // Setting up iterator part of TClingTypedefInfo is too slow.
4337 // Copy the lookup code instead:
4338 /*
4339 TClingTypedefInfo t(fInterpreter, name);
4340 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
4341 delete[] classname;
4342 return kTRUE;
4343 }
4344 */
4345
4346// const clang::Decl *decl = lh.findScope(name);
4347// if (!decl) {
4348// std::string buf = TClassEdit::InsertStd(name);
4349// decl = lh.findScope(buf);
4350// }
4351
4352// return (decl);
4353}
4354
4355////////////////////////////////////////////////////////////////////////////////
4356/// Return true if there is a class template by the given name ...
4357
4359{
4360 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4361 // Interpreter transaction ahead, needs locking
4363 const clang::Decl *decl
4364 = lh.findClassTemplate(name,
4365 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4366 : cling::LookupHelper::NoDiagnostics);
4367 if (!decl) {
4368 std::string strname = "std::";
4369 strname += name;
4370 decl = lh.findClassTemplate(strname,
4371 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4372 : cling::LookupHelper::NoDiagnostics);
4373 }
4374 return nullptr != decl;
4375}
4376
4377////////////////////////////////////////////////////////////////////////////////
4378/// Create list of pointers to base class(es) for TClass cl.
4379
4381{
4383 if (cl->fBase) {
4384 return;
4385 }
4387 if (!tci) return;
4389 TList *listOfBase = new TList;
4390 while (t.Next()) {
4391 // if name cannot be obtained no use to put in list
4392 if (t.IsValid() && t.Name()) {
4394 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
4395 }
4396 }
4397 // Now that is complete, publish it.
4398 cl->fBase = listOfBase;
4399}
4400
4401////////////////////////////////////////////////////////////////////////////////
4402/// Create list of pointers to enums for TClass cl.
4403
4404void TCling::LoadEnums(TListOfEnums& enumList) const
4405{
4407
4408 const Decl * D;
4409 TClass* cl = enumList.GetClass();
4410 if (cl) {
4411 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4412 }
4413 else {
4414 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4415 }
4416 // Iterate on the decl of the class and get the enums.
4417 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4418 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4419 // Collect all contexts of the namespace.
4420 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4421 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4422 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(), declEnd = allDeclContexts.end();
4423 declIter != declEnd; ++declIter) {
4424 // Iterate on all decls for each context.
4425 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4426 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4427 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4428 // Get name of the enum type.
4429 std::string buf;
4430 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4431 llvm::raw_string_ostream stream(buf);
4432 // Don't trigger fopen of the source file to count lines:
4433 Policy.AnonymousTagLocations = false;
4434 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
4435 stream.flush();
4436 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
4437 if (!buf.empty()) {
4438 const char* name = buf.c_str();
4439 // Add the enum to the list of loaded enums.
4440 enumList.Get(ED, name);
4441 }
4442 }
4443 }
4444 }
4445 }
4446}
4447
4448////////////////////////////////////////////////////////////////////////////////
4449/// Create list of pointers to function templates for TClass cl.
4450
4452{
4454
4455 const Decl * D;
4456 TListOfFunctionTemplates* funcTempList;
4457 if (cl) {
4458 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4459 funcTempList = (TListOfFunctionTemplates*)cl->GetListOfFunctionTemplates(false);
4460 }
4461 else {
4462 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4463 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4464 }
4465 // Iterate on the decl of the class and get the enums.
4466 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4467 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4468 // Collect all contexts of the namespace.
4469 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4470 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4471 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(),
4472 declEnd = allDeclContexts.end(); declIter != declEnd; ++declIter) {
4473 // Iterate on all decls for each context.
4474 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4475 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4476 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4477 funcTempList->Get(FTD);
4478 }
4479 }
4480 }
4481 }
4482}
4483
4484////////////////////////////////////////////////////////////////////////////////
4485/// Get the scopes representing using declarations of namespace
4486
4487std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4488{
4490 return ci->GetUsingNamespaces();
4491}
4492
4493////////////////////////////////////////////////////////////////////////////////
4494/// Create list of pointers to data members for TClass cl.
4495/// This is now a nop. The creation and updating is handled in
4496/// TListOfDataMembers.
4497
4499{
4500}
4501
4502////////////////////////////////////////////////////////////////////////////////
4503/// Create list of pointers to methods 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 method for TClass cl
4513/// This is now a nop. The creation and updating is handled in
4514/// TListOfFunctions.
4515
4517{
4518}
4519
4520////////////////////////////////////////////////////////////////////////////////
4521/// Update the list of pointers to data members for TClass cl
4522/// This is now a nop. The creation and updating is handled in
4523/// TListOfDataMembers.
4524
4526{
4527}
4528
4529////////////////////////////////////////////////////////////////////////////////
4530/// Create list of pointers to method arguments for TMethod m.
4531
4533{
4535 if (m->fMethodArgs) {
4536 return;
4537 }
4538 TList *arglist = new TList;
4540 while (t.Next()) {
4541 if (t.IsValid()) {
4543 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4544 }
4545 }
4546 m->fMethodArgs = arglist;
4547}
4548
4549////////////////////////////////////////////////////////////////////////////////
4550/// Return whether we are waiting for more input either because the collected
4551/// input contains unbalanced braces or last seen token was a `\` (backslash-newline)
4552
4554{
4555 return fMetaProcessor->awaitingMoreInput();
4556}
4557
4558////////////////////////////////////////////////////////////////////////////////
4559/// Generate a TClass for the given class.
4560/// Since the caller has already check the ClassInfo, let it give use the
4561/// result (via the value of emulation) rather than recalculate it.
4562
4563TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4564{
4565// For now the following line would lead to the (unwanted) instantiation
4566// of class template. This could/would need to be resurrected only if
4567// we re-introduce so sort of automatic instantiation. However this would
4568// have to include carefull look at the template parameter to avoid
4569// creating instance we can not really use (if the parameter are only forward
4570// declaration or do not have all the necessary interfaces).
4571
4572 // TClingClassInfo tci(fInterpreter, classname);
4573 // if (1 || !tci.IsValid()) {
4574
4575 Version_t version = 1;
4576 if (TClassEdit::IsSTLCont(classname)) {
4577 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4578 }
4580 TClass *cl = new TClass(classname, version, silent);
4581 if (!emulation) {
4582 // Set the class version if the class is versioned.
4583 // Note that we cannot just call CLASS::Class_Version() as we might not have
4584 // an execution engine (when invoked from rootcling).
4585
4586 // Do not call cl->GetClassVersion(), it has side effects!
4587 Version_t oldvers = cl->fClassVersion;
4588 if (oldvers == version && cl->GetClassInfo()) {
4589 // We have a version and it might need an update.
4591 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4592 // Namespaces don't have class versions.
4593 return cl;
4594 }
4595 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", nullptr /*poffset*/,
4598 if (!mi.IsValid()) {
4599 if (cl->TestBit(TClass::kIsTObject)) {
4600 Error("GenerateTClass",
4601 "Cannot find %s::Class_Version()! Class version might be wrong.",
4602 cl->GetName());
4603 }
4604 return cl;
4605 }
4606 Version_t newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4607 *fInterpreter);
4608 if (newvers == -1) {
4609 // Didn't manage to determine the class version from the AST.
4610 // Use runtime instead.
4611 if ((mi.Property() & kIsStatic)
4612 && !fInterpreter->isInSyntaxOnlyMode()) {
4613 // This better be a static function.
4615 callfunc.SetFunc(&mi);
4616 newvers = callfunc.ExecInt(nullptr);
4617 } else {
4618 Error("GenerateTClass",
4619 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4620 cl->GetName());
4621 }
4622 }
4623 if (newvers != oldvers) {
4624 cl->fClassVersion = newvers;
4625 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4626 }
4627 }
4628 }
4629
4630 return cl;
4631
4632// } else {
4633// return GenerateTClass(&tci,silent);
4634// }
4635}
4636
4637#if 0
4638////////////////////////////////////////////////////////////////////////////////
4639
4640static void GenerateTClass_GatherInnerIncludes(cling::Interpreter *interp, TString &includes,TClingClassInfo *info)
4641{
4642 includes += info->FileName();
4643
4644 const clang::ClassTemplateSpecializationDecl *templateCl
4645 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4646 if (templateCl) {
4647 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4648 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4649 if (arg.getKind() == clang::TemplateArgument::Type) {
4650 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4651
4652 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4653 // We really need a header file.
4654 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4655 if (argdecl) {
4656 includes += ";";
4657 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4658 GenerateTClass_GatherInnerIncludes(interp, includes, &subinfo);
4659 } else {
4660 std::string Result;
4661 llvm::raw_string_ostream OS(Result);
4662 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4663 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4664 }
4665 }
4666 }
4667 }
4668 }
4669}
4670#endif
4671
4672////////////////////////////////////////////////////////////////////////////////
4673/// Generate a TClass for the given class.
4674
4675TClass *TCling::GenerateTClass(ClassInfo_t *classinfo, Bool_t silent /* = kFALSE */)
4676{
4677 TClingClassInfo *info = (TClingClassInfo*)classinfo;
4678 if (!info || !info->IsValid()) {
4679 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4680 return nullptr;
4681 }
4682 // We are in the case where we have AST nodes for this class.
4683 TClass *cl = nullptr;
4684 std::string classname;
4685 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4686 if (TClassEdit::IsSTLCont(classname)) {
4687#if 0
4688 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4689 // We need to build up the list of required headers, by
4690 // looking at each template arguments.
4691 TString includes;
4692 GenerateTClass_GatherInnerIncludes(fInterpreter,includes,info);
4693
4694 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4695 // 0 means success.
4696 cl = TClass::LoadClass(classnam.c_str(), silent);
4697 if (cl == 0) {
4698 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4699 }
4700 }
4701#endif
4702 if (cl == nullptr) {
4703 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4704 cl = new TClass(classinfo, version, nullptr, nullptr, -1, -1, silent);
4705 }
4706 } else {
4707 // For regular class, just create a TClass on the fly ...
4708 // Not quite useful yet, but that what CINT used to do anyway.
4709 cl = new TClass(classinfo, 1, nullptr, nullptr, -1, -1, silent);
4710 }
4711 // Add the new TClass to the map of declid and TClass*.
4712 if (cl) {
4714 }
4715 return cl;
4716}
4717
4718////////////////////////////////////////////////////////////////////////////////
4719/// Generate the dictionary for the C++ classes listed in the first
4720/// argument (in a semi-colon separated list).
4721/// 'includes' contains a semi-colon separated list of file to
4722/// `#include` in the dictionary.
4723/// For example:
4724/// ~~~ {.cpp}
4725/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4726/// ~~~
4727/// or
4728/// ~~~ {.cpp}
4729/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4730/// ~~~
4731
4732Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4733{
4734 if (classes == nullptr || classes[0] == 0) {
4735 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4736 return 0;
4737 }
4738 // Split the input list
4739 std::vector<std::string> listClasses;
4740 for (
4741 const char* current = classes, *prev = classes;
4742 *current != 0;
4743 ++current
4744 ) {
4745 if (*current == ';') {
4746 listClasses.push_back(std::string(prev, current - prev));
4747 prev = current + 1;
4748 }
4749 else if (*(current + 1) == 0) {
4750 listClasses.push_back(std::string(prev, current + 1 - prev));
4751 prev = current + 1;
4752 }
4753 }
4754 std::vector<std::string> listIncludes;
4755 if (!includes)
4756 includes = "";
4757 for (
4758 const char* current = includes, *prev = includes;
4759 *current != 0;
4760 ++current
4761 ) {
4762 if (*current == ';') {
4763 listIncludes.push_back(std::string(prev, current - prev));
4764 prev = current + 1;
4765 }
4766 else if (*(current + 1) == 0) {
4767 listIncludes.push_back(std::string(prev, current + 1 - prev));
4768 prev = current + 1;
4769 }
4770 }
4771 // Generate the temporary dictionary file
4772 return !TCling_GenerateDictionary(listClasses, listIncludes,
4773 std::vector<std::string>(), std::vector<std::string>());
4774}
4775
4776////////////////////////////////////////////////////////////////////////////////
4777/// Return pointer to cling Decl of global/static variable that is located
4778/// at the address given by addr.
4779
4780TInterpreter::DeclId_t TCling::GetDataMember(ClassInfo_t *opaque_cl, const char *name) const
4781{
4783 DeclId_t d;
4784 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4785
4786 // Could trigger deserialization of decls.
4787 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4788
4789 if (cl) {
4790 d = cl->GetDataMember(name);
4791 // We check if the decl of the data member has an annotation which indicates
4792 // an ioname.
4793 // In case this is true, if the name requested is not the ioname, we
4794 // return 0, as if the member did not exist. In some sense we override
4795 // the information in the TClassInfo instance, isolating the typesystem in
4796 // TClass from the one in the AST.
4797 if (const ValueDecl* decl = (const ValueDecl*) d){
4798 std::string ioName;
4799 bool hasIoName = ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"ioname",ioName);
4800 if (hasIoName && ioName != name) return nullptr;
4801 }
4802 return d;
4803 }
4804 // We are looking up for something on the TU scope.
4805 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
4806 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
4807 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
4808 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
4809 // are only fulfilling ROOT's understanding for a Data Member.
4810 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
4811 // similar as below.
4812 using namespace clang;
4813 Sema& SemaR = fInterpreter->getSema();
4814 DeclarationName DName = &SemaR.Context.Idents.get(name);
4815
4816 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
4817 Sema::ForExternalRedeclaration);
4818
4819 cling::utils::Lookup::Named(&SemaR, R);
4820
4821 LookupResult::Filter F = R.makeFilter();
4822 // Filter the data-member looking decls.
4823 while (F.hasNext()) {
4824 NamedDecl *D = F.next();
4825 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) ||
4826 isa<IndirectFieldDecl>(D))
4827 continue;
4828 F.erase();
4829 }
4830 F.done();
4831
4832 if (R.isSingleResult())
4833 return R.getFoundDecl();
4834 return nullptr;
4835}
4836
4837////////////////////////////////////////////////////////////////////////////////
4838/// Return pointer to cling Decl of global/static variable that is located
4839/// at the address given by addr.
4840
4842{
4844
4845 const clang::Decl* possibleEnum = nullptr;
4846 // FInd the context of the decl.
4847 if (cl) {
4849 if (cci) {
4850 const clang::DeclContext* dc = nullptr;
4851 if (const clang::Decl* D = cci->GetDecl()) {
4852 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
4853 dc = dyn_cast<clang::RecordDecl>(D);
4854 }
4855 }
4856 if (dc) {
4857 // If it is a data member enum.
4858 // Could trigger deserialization of decls.
4859 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4860 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
4861 } else {
4862 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
4863 }
4864 }
4865 } else {
4866 // If it is a global enum.
4867 // Could trigger deserialization of decls.
4868 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4869 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
4870 }
4871 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
4872 && isa<clang::EnumDecl>(possibleEnum)) {
4873 return possibleEnum;
4874 }
4875 return nullptr;
4876}
4877
4878////////////////////////////////////////////////////////////////////////////////
4879/// Return pointer to cling DeclId for a global value
4880
4881TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
4882{
4883 if (!gv) return nullptr;
4884
4885 llvm::StringRef mangled_name = gv->getName();
4886
4887 int err = 0;
4888 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.str().c_str(), err);
4889 if (err) {
4890 if (err == -2) {
4891 // It might simply be an unmangled global name.
4892 DeclId_t d;
4894 d = gcl.GetDataMember(mangled_name.str().c_str());
4895 return d;
4896 }
4897 return nullptr;
4898 }
4899
4900 std::string scopename(demangled_name_c);
4901 free(demangled_name_c);
4902
4903 //
4904 // Separate out the class or namespace part of the
4905 // function name.
4906 //
4907 std::string dataname;
4908
4909 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
4910 scopename.erase(0, sizeof("typeinfo for ")-1);
4911 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
4912 scopename.erase(0, sizeof("vtable for ")-1);
4913 } else {
4914 // See if it is a function
4915 std::string::size_type pos = scopename.rfind('(');
4916 if (pos != std::string::npos) {
4917 return nullptr;
4918 }
4919 // Separate the scope and member name
4920 pos = scopename.rfind(':');
4921 if (pos != std::string::npos) {
4922 if ((pos != 0) && (scopename[pos-1] == ':')) {
4923 dataname = scopename.substr(pos+1);
4924 scopename.erase(pos-1);
4925 }
4926 } else {
4927 scopename.clear();
4928 dataname = scopename;
4929 }
4930 }
4931 //fprintf(stderr, "name: '%s'\n", name.c_str());
4932 // Now we have the class or namespace name, so do the lookup.
4933
4934
4935 DeclId_t d;
4936 if (scopename.size()) {
4937 TClingClassInfo cl(GetInterpreterImpl(), scopename.c_str());
4938 d = cl.GetDataMember(dataname.c_str());
4939 }
4940 else {
4942 d = gcl.GetDataMember(dataname.c_str());
4943 }
4944 return d;
4945}
4946
4947////////////////////////////////////////////////////////////////////////////////
4948/// NOT IMPLEMENTED.
4949
4951{
4952 Error("GetDataMemberWithValue()", "not implemented");
4953 return nullptr;
4954}
4955
4956////////////////////////////////////////////////////////////////////////////////
4957/// Return pointer to cling DeclId for a data member with a given name.
4958
4960{
4961 // NOT IMPLEMENTED.
4962 Error("GetDataMemberAtAddr()", "not implemented");
4963 return nullptr;
4964}
4965
4966////////////////////////////////////////////////////////////////////////////////
4967/// Return the cling mangled name for a method of a class with parameters
4968/// params (params is a string of actual arguments, not formal ones). If the
4969/// class is 0 the global function list will be searched.
4970
4971TString TCling::GetMangledName(TClass* cl, const char* method,
4972 const char* params, Bool_t objectIsConst /* = kFALSE */)
4973{
4976 if (cl) {
4978 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4979 &offset);
4980 }
4981 else {
4984 func.SetFunc(&gcl, method, params, &offset);
4985 }
4987 if (!mi) return "";
4988 TString mangled_name( mi->GetMangledName() );
4989 delete mi;
4990 return mangled_name;
4991}
4992
4993////////////////////////////////////////////////////////////////////////////////
4994/// Return the cling mangled name for a method of a class with a certain
4995/// prototype, i.e. "char*,int,float". If the class is 0 the global function
4996/// list will be searched.
4997
4999 const char* proto, Bool_t objectIsConst /* = kFALSE */,
5000 EFunctionMatchMode mode /* = kConversionMatch */)
5001{
5003 if (cl) {
5004 return ((TClingClassInfo*)cl->GetClassInfo())->
5005 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
5006 }
5008 return gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetMangledName();
5009}
5010
5011////////////////////////////////////////////////////////////////////////////////
5012/// Return pointer to cling interface function for a method of a class with
5013/// parameters params (params is a string of actual arguments, not formal
5014/// ones). If the class is 0 the global function list will be searched.
5015
5016void* TCling::GetInterfaceMethod(TClass* cl, const char* method,
5017 const char* params, Bool_t objectIsConst /* = kFALSE */)
5018{
5021 if (cl) {
5023 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
5024 &offset);
5025 }
5026 else {
5029 func.SetFunc(&gcl, method, params, &offset);
5030 }
5031 return (void*) func.InterfaceMethod();
5032}
5033
5034////////////////////////////////////////////////////////////////////////////////
5035/// Return pointer to cling interface function for a method of a class with
5036/// a certain name.
5037
5038TInterpreter::DeclId_t TCling::GetFunction(ClassInfo_t *opaque_cl, const char* method)
5039{
5041 DeclId_t f;
5042 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5043 if (cl) {
5044 f = cl->GetMethod(method).GetDeclId();
5045 }
5046 else {
5048 f = gcl.GetMethod(method).GetDeclId();
5049 }
5050 return f;
5051
5052}
5053
5054////////////////////////////////////////////////////////////////////////////////
5055/// Insert overloads of name in cl to res.
5056
5057void TCling::GetFunctionOverloads(ClassInfo_t *cl, const char *funcname,
5058 std::vector<DeclId_t>& res) const
5059{
5060 clang::Sema& S = fInterpreter->getSema();
5061 clang::ASTContext& Ctx = S.Context;
5062 const clang::Decl* CtxDecl
5063 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
5064 Ctx.getTranslationUnitDecl();
5065 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
5066 const clang::DeclContext* DeclCtx = RecDecl;
5067
5068 if (!DeclCtx)
5069 DeclCtx = dyn_cast<clang::NamespaceDecl>(CtxDecl);
5070 if (!DeclCtx) return;
5071
5072 clang::DeclarationName DName;
5073 // The DeclarationName is funcname, unless it's a ctor or dtor.
5074 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
5075
5076 if (RecDecl) {
5077 if (RecDecl->getNameAsString() == funcname) {
5078 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5079 DName = Ctx.DeclarationNames.getCXXConstructorName(Ctx.getCanonicalType(QT));
5080 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
5081 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
5082 DName = Ctx.DeclarationNames.getCXXDestructorName(Ctx.getCanonicalType(QT));
5083 } else {
5084 DName = &Ctx.Idents.get(funcname);
5085 }
5086 } else {
5087 DName = &Ctx.Idents.get(funcname);
5088 }
5089
5090 // NotForRedeclaration: we want to find names in inline namespaces etc.
5091 clang::LookupResult R(S, DName, clang::SourceLocation(),
5092 Sema::LookupOrdinaryName, clang::Sema::NotForRedeclaration);
5093 R.suppressDiagnostics(); // else lookup with NotForRedeclaration will check access etc
5094 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
5095 if (R.empty()) return;
5096 R.resolveKind();
5097 res.reserve(res.size() + (R.end() - R.begin()));
5098 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
5099 IR != ER; ++IR) {
5100 if (const clang::FunctionDecl* FD
5101 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
5102 if (!FD->getDescribedFunctionTemplate()) {
5103 res.push_back(FD);
5104 }
5105 } else if (const auto *USD = llvm::dyn_cast<const clang::UsingShadowDecl>(*IR)) {
5106 // FIXME: multi-level using
5107 if (llvm::isa<clang::FunctionDecl>(USD->getTargetDecl())) {
5108 res.push_back(USD);
5109 }
5110 }
5111 }
5112}
5113
5114////////////////////////////////////////////////////////////////////////////////
5115/// Return pointer to cling interface function for a method of a class with
5116/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5117/// function list will be searched.
5118
5120 const char* proto,
5121 Bool_t objectIsConst /* = kFALSE */,
5122 EFunctionMatchMode mode /* = kConversionMatch */)
5123{
5125 void* f;
5126 if (cl) {
5127 f = ((TClingClassInfo*)cl->GetClassInfo())->
5128 GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5129 }
5130 else {
5132 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).InterfaceMethod();
5133 }
5134 return f;
5135}
5136
5137////////////////////////////////////////////////////////////////////////////////
5138/// Return pointer to cling DeclId for a method of a class with
5139/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5140/// function list will be searched.
5141
5142TInterpreter::DeclId_t TCling::GetFunctionWithValues(ClassInfo_t *opaque_cl, const char* method,
5143 const char* params,
5144 Bool_t objectIsConst /* = kFALSE */)
5145{
5147 DeclId_t f;
5148 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5149 if (cl) {
5150 f = cl->GetMethodWithArgs(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5151 }
5152 else {
5154 f = gcl.GetMethod(method, params, objectIsConst, nullptr /*poffset*/).GetDeclId();
5155 }
5156 return f;
5157}
5158
5159////////////////////////////////////////////////////////////////////////////////
5160/// Return pointer to cling interface function for a method of a class with
5161/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
5162/// function list will be searched.
5163
5164TInterpreter::DeclId_t TCling::GetFunctionWithPrototype(ClassInfo_t *opaque_cl, const char* method,
5165 const char* proto,
5166 Bool_t objectIsConst /* = kFALSE */,
5167 EFunctionMatchMode mode /* = kConversionMatch */)
5168{
5170 DeclId_t f;
5171 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5172 if (cl) {
5173 f = cl->GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5174 }
5175 else {
5177 f = gcl.GetMethod(method, proto, objectIsConst, nullptr /*poffset*/, mode).GetDeclId();
5178 }
5179 return f;
5180}
5181
5182////////////////////////////////////////////////////////////////////////////////
5183/// Return pointer to cling interface function for a method of a class with
5184/// a certain name.
5185
5186TInterpreter::DeclId_t TCling::GetFunctionTemplate(ClassInfo_t *opaque_cl, const char* name)
5187{
5189 DeclId_t f;
5190 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
5191 if (cl) {
5192 f = cl->GetFunctionTemplate(name);
5193 }
5194 else {
5196 f = gcl.GetFunctionTemplate(name);
5197 }
5198 return f;
5199
5200}
5201
5202////////////////////////////////////////////////////////////////////////////////
5203/// The 'name' is known to the interpreter, this function returns
5204/// the internal version of this name (usually just resolving typedefs)
5205/// This is used in particular to synchronize between the name used
5206/// by rootcling and by the run-time environment (TClass)
5207/// Return 0 if the name is not known.
5208
5209void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
5210{
5211 output.clear();
5212
5214
5216 if (!cl.IsValid()) {
5217 return ;
5218 }
5219 if (full) {
5221 return;
5222 }
5223 // Well well well, for backward compatibility we need to act a bit too
5224 // much like CINT.
5227
5228 return;
5229}
5230
5231////////////////////////////////////////////////////////////////////////////////
5232/// Execute a global function with arguments params.
5233///
5234/// FIXME: The cint-based version of this code does not check if the
5235/// SetFunc() call works, and does not do any real checking
5236/// for errors from the Exec() call. It did fetch the most
5237/// recent cint security error and return that in error, but
5238/// this does not really translate well to cling/clang. We
5239/// should enhance these interfaces so that we can report
5240/// compilation and runtime errors properly.
5241
5242void TCling::Execute(const char* function, const char* params, int* error)
5243{
5245 if (error) {
5246 *error = TInterpreter::kNoError;
5247 }
5249 Longptr_t offset = 0L;
5251 func.SetFunc(&cl, function, params, &offset);
5252 func.Exec(nullptr);
5253}
5254
5255////////////////////////////////////////////////////////////////////////////////
5256/// Execute a method from class cl with arguments params.
5257///
5258/// FIXME: The cint-based version of this code does not check if the
5259/// SetFunc() call works, and does not do any real checking
5260/// for errors from the Exec() call. It did fetch the most
5261/// recent cint security error and return that in error, but
5262/// this does not really translate well to cling/clang. We
5263/// should enhance these interfaces so that we can report
5264/// compilation and runtime errors properly.
5265
5266void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5267 const char* params, Bool_t objectIsConst, int* error)
5268{
5270 if (error) {
5271 *error = TInterpreter::kNoError;
5272 }
5273 // If the actual class of this object inherits 2nd (or more) from TObject,
5274 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5275 // hence gInterpreter->Execute will improperly correct the offset.
5276 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5277 Longptr_t offset = 0L;
5279 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst, &offset);
5280 void* address = (void*)((Longptr_t)addr + offset);
5281 func.Exec(address);
5282}
5283
5284////////////////////////////////////////////////////////////////////////////////
5285
5286void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5287 const char* params, int* error)
5288{
5289 Execute(obj,cl,method,params,false,error);
5290}
5291
5292////////////////////////////////////////////////////////////////////////////////
5293/// Execute a method from class cl with the arguments in array params
5294/// (params[0] ... params[n] = array of TObjString parameters).
5295/// Convert the TObjArray array of TObjString parameters to a character
5296/// string of comma separated parameters.
5297/// The parameters of type 'char' are enclosed in double quotes and all
5298/// internal quotes are escaped.
5299
5300void TCling::Execute(TObject* obj, TClass* cl, TMethod* method,
5301 TObjArray* params, int* error)
5302{
5303 if (!method) {
5304 Error("Execute", "No method was defined");
5305 return;
5306 }
5307 TList* argList = method->GetListOfMethodArgs();
5308 // Check number of actual parameters against of expected formal ones
5309
5310 Int_t nparms = argList->LastIndex() + 1;
5311 Int_t argc = params ? params->GetEntries() : 0;
5312
5313 if (argc > nparms) {
5314 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
5315 return;
5316 }
5317 if (nparms != argc) {
5318 // Let's see if the 'missing' argument are all defaulted.
5319 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
5320 assert(nparms > 0);
5321
5322 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
5323 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5324 // There is a default value for the first missing
5325 // argument, so we are fine.
5326 } else {
5327 Int_t firstDefault = -1;
5328 for (Int_t i = 0; i < nparms; i ++) {
5329 arg = (TMethodArg *) argList->At( i );
5330 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5331 firstDefault = i;
5332 break;
5333 }
5334 }
5335 if (firstDefault >= 0) {
5336 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);
5337 } else {
5338 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
5339 }
5340 return;
5341 }
5342 }
5343
5344 const char* listpar = "";
5345 TString complete(10);
5346 if (params) {
5347 // Create a character string of parameters from TObjArray
5348 TIter next(params);
5349 for (Int_t i = 0; i < argc; i ++) {
5350 TMethodArg* arg = (TMethodArg*) argList->At(i);
5352 TObjString* nxtpar = (TObjString*) next();
5353 if (i) {
5354 complete += ',';
5355 }
5356 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
5357 TString chpar('\"');
5358 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
5359 // At this point we have to check if string contains \\"
5360 // and apply some more sophisticated parser. Not implemented yet!
5361 complete += chpar;
5362 complete += '\"';
5363 }
5364 else {
5365 complete += nxtpar->String();
5366 }
5367 }
5368 listpar = complete.Data();
5369 }
5370
5371 // And now execute it.
5373 if (error) {
5374 *error = TInterpreter::kNoError;
5375 }
5376 // If the actual class of this object inherits 2nd (or more) from TObject,
5377 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5378 // hence gInterpreter->Execute will improperly correct the offset.
5379 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5381 TClingMethodInfo *minfo = (TClingMethodInfo*)method->fInfo;
5382 func.Init(*minfo);
5383 func.SetArgs(listpar);
5384 // Now calculate the 'this' pointer offset for the method
5385 // when starting from the class described by cl.
5386 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetTargetFunctionDecl());
5387 Longptr_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
5388 void* address = (void*)((Longptr_t)addr + offset);
5389 func.Exec(address);
5390}
5391
5392////////////////////////////////////////////////////////////////////////////////
5393
5394void TCling::ExecuteWithArgsAndReturn(TMethod* method, void* address,
5395 const void* args[] /*=0*/,
5396 int nargs /*=0*/,
5397 void* ret/*= 0*/) const
5398{
5399 if (!method) {
5400 Error("ExecuteWithArgsAndReturn", "No method was defined");
5401 return;
5402 }
5403
5404 TClingMethodInfo* minfo = (TClingMethodInfo*) method->fInfo;
5405 TClingCallFunc func(*minfo);
5406 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5407}
5408
5409////////////////////////////////////////////////////////////////////////////////
5410/// Execute a cling macro.
5411
5413{
5415 fCurExecutingMacros.push_back(filename);
5417 fCurExecutingMacros.pop_back();
5418 return result;
5419}
5420
5421////////////////////////////////////////////////////////////////////////////////
5422/// Return the file name of the current un-included interpreted file.
5423/// See the documentation for GetCurrentMacroName().
5424
5426{
5427 Warning("GetTopLevelMacroName", "Must change return type!");
5428 return fCurExecutingMacros.back();
5429}
5430
5431////////////////////////////////////////////////////////////////////////////////
5432/// Return the file name of the currently interpreted file,
5433/// included or not. Example to illustrate the difference between
5434/// GetCurrentMacroName() and GetTopLevelMacroName():
5435/// ~~~ {.cpp}
5436/// void inclfile() {
5437/// std::cout << "In inclfile.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/// }
5443/// ~~~
5444/// ~~~ {.cpp}
5445/// void mymacro() {
5446/// std::cout << "In mymacro.C" << std::endl;
5447/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5448/// TCling::GetCurrentMacroName() << std::endl;
5449/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5450/// TCling::GetTopLevelMacroName() << std::endl;
5451/// std::cout << " Now calling inclfile..." << std::endl;
5452/// gInterpreter->ProcessLine(".x inclfile.C");;
5453/// }
5454/// ~~~
5455/// Running mymacro.C will print:
5456///
5457/// ~~~ {.cpp}
5458/// root [0] .x mymacro.C
5459/// ~~~
5460/// In mymacro.C
5461/// ~~~ {.cpp}
5462/// TCling::GetCurrentMacroName() returns ./mymacro.C
5463/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5464/// ~~~
5465/// Now calling inclfile...
5466/// In inclfile.h
5467/// ~~~ {.cpp}
5468/// TCling::GetCurrentMacroName() returns inclfile.C
5469/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5470/// ~~~
5471
5473{
5474#if defined(R__MUST_REVISIT)
5475#if R__MUST_REVISIT(6,0)
5476 Warning("GetCurrentMacroName", "Must change return type!");
5477#endif
5478#endif
5479 return fCurExecutingMacros.back();
5480}
5481
5482////////////////////////////////////////////////////////////////////////////////
5483/// Return the absolute type of typeDesc.
5484/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
5485/// You need to use the result immediately before it is being overwritten.
5486
5487const char* TCling::TypeName(const char* typeDesc)
5488{
5489 TTHREAD_TLS_DECL(std::string,t);
5490
5491 if (!strstr(typeDesc, "(*)(")) {
5492 const char *s = strchr(typeDesc, ' ');
5493 const char *template_start = strchr(typeDesc, '<');
5494 if (!strcmp(typeDesc, "long long")) {
5495 t = typeDesc;
5496 }
5497 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5498 t = typeDesc;
5499 }
5500 // s is the position of the second 'word' (if any)
5501 // except in the case of templates where there will be a space
5502 // just before any closing '>': eg.
5503 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5504 else if (s && (template_start == nullptr || (s < template_start))) {
5505 t = s + 1;
5506 }
5507 else {
5508 t = typeDesc;
5509 }
5510 }
5511 else {
5512 t = typeDesc;
5513 }
5514 auto l = t.length();
5515 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&'))
5516 --l;
5517 t.resize(l);
5518 return t.c_str(); // NOLINT
5519}
5520
5521static bool requiresRootMap(const char* rootmapfile)
5522{
5523 assert(rootmapfile && *rootmapfile);
5524
5525 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5526 libName.consume_back(".rootmap");
5527
5528 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5529}
5530
5531////////////////////////////////////////////////////////////////////////////////
5532/// Read and parse a rootmapfile in its new format, and return 0 in case of
5533/// success, -1 if the file has already been read, and -3 in case its format
5534/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5535/// error.
5536
5537int TCling::ReadRootmapFile(const char *rootmapfile, TUniqueString *uniqueString)
5538{
5539 if (!(rootmapfile && *rootmapfile))
5540 return 0;
5541
5542 if (!requiresRootMap(rootmapfile))
5543 return 0; // success
5544
5545 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5546 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5547
5548 std::string rootmapfileNoBackslash(rootmapfile);
5549#ifdef _MSC_VER
5550 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5551#endif
5552 // Add content of a specific rootmap file
5553 if (fRootmapFiles->FindObject(rootmapfileNoBackslash.c_str()))
5554 return -1;
5555
5556 // Line 1 is `{ decls }`
5557 std::string lineDirective = std::string("\n#line 2 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n";
5558
5559 std::ifstream file(rootmapfileNoBackslash);
5560 std::string line;
5561 line.reserve(200);
5562 std::string lib_name;
5563 line.reserve(100);
5564 bool newFormat = false;
5565 while (getline(file, line, '\n')) {
5566 if (!newFormat && (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5567 file.close();
5568 return -3; // old format
5569 }
5570 newFormat = true;
5571
5572 if (line.compare(0, 9, "{ decls }") == 0) {
5573 // forward declarations
5574
5575 while (getline(file, line, '\n')) {
5576 if (line[0] == '[')
5577 break;
5578 if (!uniqueString) {
5579 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5580 rootmapfileNoBackslash.c_str());
5581 return -4;
5582 }
5583 if (!lineDirective.empty())
5584 uniqueString->Append(lineDirective);
5585 uniqueString->Append(line + '\n');
5586 }
5587 }
5588 const char firstChar = line[0];
5589 if (firstChar == '[') {
5590 // new section (library)
5591 auto brpos = line.find(']');
5592 if (brpos == string::npos)
5593 continue;
5594 lib_name = line.substr(1, brpos - 1);
5595 // Remove spaces at the beginning and at the end of the library name
5596 lib_name.erase(lib_name.find_last_not_of(' ') + 1);
5597 lib_name.erase(0, lib_name.find_first_not_of(' '));
5598 if (gDebug > 3) {
5599 TString lib_nameTstr(lib_name.c_str());
5600 TObjArray *tokens = lib_nameTstr.Tokenize(" ");
5601 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5602 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5603 if (wlib) {
5604 Info("ReadRootmapFile", "%s: New section for %s", rootmapfile, lib_nameTstr.Data());
5605 } else {
5606 Info("ReadRootmapFile", "%s: Section for %s (library does not exist)", rootmapfile, lib_nameTstr.Data());
5607 }
5608 delete[] wlib;
5609 delete tokens;
5610 }
5611 } else {
5612 auto keyLenIt = keyLenMap.find(firstChar);
5613 if (keyLenIt == keyLenMap.end())
5614 continue;
5615 unsigned int keyLen = keyLenIt->second;
5616 // Do not make a copy, just start after the key
5617 const char *keyname = line.c_str() + keyLen;
5618 if (gDebug > 6)
5619 Info("ReadRootmapFile", "%s: class %s in %s", rootmapfile, keyname, lib_name.c_str());
5620 TEnvRec *isThere = fMapfile->Lookup(keyname);
5621 if (isThere) {
5622 if (lib_name != isThere->GetValue()) { // the same key for two different libs
5623 if (firstChar == 'n') {
5624 if (gDebug > 3)
5625 Info("ReadRootmapFile",
5626 "While processing %s, namespace %s was found to be associated to %s although it is already "
5627 "associated to %s",
5628 rootmapfile, keyname, lib_name.c_str(), isThere->GetValue());
5629 } else if (firstChar == 'h') { // it is a header: add the libname to the list of libs to be loaded.
5630 lib_name += " ";
5631 lib_name += isThere->GetValue();
5632 fMapfile->SetValue(keyname, lib_name.c_str());
5633 } else if (!TClassEdit::IsSTLCont(keyname)) {
5634 Warning("ReadRootmapFile",
5635 "While processing %s, %s %s was found to be associated to %s although it is already "
5636 "associated to %s",
5637 rootmapfile, line.substr(0, keyLen - 1).c_str(), keyname, lib_name.c_str(),
5638 isThere->GetValue());
5639 }
5640 } else { // the same key for the same lib
5641 if (gDebug > 3)
5642 Info("ReadRootmapFile", "While processing %s, key %s was found to be already defined for %s",
5643 rootmapfile, keyname, lib_name.c_str());
5644 }
5645 } else {
5646 fMapfile->SetValue(keyname, lib_name.c_str());
5647 }
5648 }
5649 }
5650 file.close();
5651 return 0;
5652}
5653
5654////////////////////////////////////////////////////////////////////////////////
5655/// Create a resource table and read the (possibly) three resource files,
5656/// i.e. `$ROOTSYS/etc/system<name>` (or `ROOTETCDIR/system<name>`), `$HOME/<name>`
5657/// and `$PWD/<name>`. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You
5658/// can read additional user defined resource files by creating additional TEnv
5659/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5660/// the `$HOME/<name>` resource file will be skipped. This might be useful in
5661/// case the home directory resides on an automounted remote file system
5662/// and one wants to avoid the file system from being mounted.
5663
5665{
5666 assert(requiresRootMap(name) && "We have a module!");
5667
5668 if (!requiresRootMap(name))
5669 return;
5670
5672
5674
5675 TString sname = "system";
5676 sname += name;
5677 char *s = gSystem->ConcatFileName(TROOT::GetEtcDir(), sname);
5678
5679 Int_t ret = ReadRootmapFile(s);
5680 if (ret == -3) // old format
5682 delete [] s;
5683 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5685 ret = ReadRootmapFile(s);
5686 if (ret == -3) // old format
5688 delete [] s;
5689 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
5690 ret = ReadRootmapFile(name);
5691 if (ret == -3) // old format
5693 }
5694 } else {
5695 ret = ReadRootmapFile(name);
5696 if (ret == -3) // old format
5698 }
5699 fMapfile->IgnoreDuplicates(ignore);
5700}
5701
5702
5703namespace {
5704 using namespace clang;
5705
5706 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5707 // This class is to be considered an helper for AutoLoading.
5708 // It is a recursive visitor is used to inspect namespaces and specializations
5709 // coming from forward declarations in rootmaps and to set the external visible
5710 // storage flag for them.
5711 public:
5712 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5713 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5714 // We want to enable the external lookup for this namespace
5715 // because it may shadow the lookup of other names contained
5716 // in that namespace
5717
5718 nsDecl->setHasExternalVisibleStorage();
5719 fNSSet.insert(nsDecl);
5720 return true;
5721 }
5722 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl* specDecl) {
5723 // We want to enable the external lookup for this specialization
5724 // because we can provide a definition for it!
5725 if (specDecl->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
5726 //SpecSet.insert(specDecl);
5727 specDecl->setHasExternalLexicalStorage();
5728
5729 // No need to recurse. On the contrary, recursing is actively harmful:
5730 // NOTE: must not recurse to prevent this visitor from triggering loading from
5731 // the external AST source (i.e. autoloading). This would be triggered right here,
5732 // before autoloading is even set up, as rootmap file parsing happens before that.
5733 // Even if autoloading is off and has no effect, triggering loading from external
5734 // AST source resets the flag setHasExternalLexicalStorage(), hiding this specialization
5735 // from subsequent autoloads!
5736 return false;
5737 }
5738 private:
5739 std::unordered_set<const NamespaceDecl*>& fNSSet;
5740 };
5741}
5742
5743////////////////////////////////////////////////////////////////////////////////
5744/// Load map between class and library. If rootmapfile is specified a
5745/// specific rootmap file can be added (typically used by ACLiC).
5746/// In case of error -1 is returned, 0 otherwise.
5747/// The interpreter uses this information to automatically load the shared
5748/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5749
5750Int_t TCling::LoadLibraryMap(const char* rootmapfile)
5751{
5752 if (rootmapfile && *rootmapfile && !requiresRootMap(rootmapfile))
5753 return 0;
5754
5756
5757 // open the [system].rootmap files
5758 if (!fMapfile) {
5759 fMapfile = new TEnv();
5763 InitRootmapFile(".rootmap");
5764 }
5765
5766 // Prepare a list of all forward declarations for cling
5767 // For some experiments it is easily as big as 500k characters. To be on the
5768 // safe side, we go for 1M.
5769 TUniqueString uniqueString(1048576);
5770
5771 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5772 // A rootmap file must end with the string ".rootmap".
5773 TString ldpath = gSystem->GetDynamicPath();
5774 if (ldpath != fRootmapLoadPath) {
5775 fRootmapLoadPath = ldpath;
5776#ifdef WIN32
5777 TObjArray* paths = ldpath.Tokenize(";");
5778#else
5779 TObjArray* paths = ldpath.Tokenize(":");
5780#endif
5781 TString d;
5782 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5783 d = ((TObjString *)paths->At(i))->GetString();
5784 // check if directory already scanned
5785 Int_t skip = 0;
5786 for (Int_t j = 0; j < i; j++) {
5787 TString pd = ((TObjString *)paths->At(j))->GetString();
5788 if (pd == d) {
5789 skip++;
5790 break;
5791 }
5792 }
5793 if (!skip) {
5794 void* dirp = gSystem->OpenDirectory(d);
5795 if (dirp) {
5796 if (gDebug > 3) {
5797 Info("LoadLibraryMap", "%s", d.Data());
5798 }
5799 const char* f1;
5800 while ((f1 = gSystem->GetDirEntry(dirp))) {
5801 TString f = f1;
5802 if (f.EndsWith(".rootmap")) {
5803 TString p;
5804 p = d + "/" + f;
5806 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
5807 if (gDebug > 4) {
5808 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
5809 }
5810 Int_t ret = ReadRootmapFile(p, &uniqueString);
5811
5812 if (ret == 0)
5813 fRootmapFiles->Add(new TNamed(gSystem->BaseName(f), p.Data()));
5814 if (ret == -3) {
5815 // old format
5817 fRootmapFiles->Add(new TNamed(f, p));
5818 }
5819 }
5820 // else {
5821 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
5822 // fRootmapFiles->FindObject(f)->ls();
5823 // }
5824 }
5825 }
5826 if (f.BeginsWith("rootmap")) {
5827 TString p;
5828 p = d + "/" + f;
5829 FileStat_t stat;
5830 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
5831 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
5832 }
5833 }
5834 }
5835 }
5836 gSystem->FreeDirectory(dirp);
5837 }
5838 }
5839 delete paths;
5840 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
5841 return -1;
5842 }
5843 }
5844 if (rootmapfile && *rootmapfile) {
5845 Int_t res = ReadRootmapFile(rootmapfile, &uniqueString);
5846 if (res == 0) {
5847 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
5848 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
5849 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5850 }
5851 else if (res == -3) {
5852 // old format
5854 fMapfile->ReadFile(rootmapfile, kEnvGlobal);
5855 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5856 fMapfile->IgnoreDuplicates(ignore);
5857 }
5858 }
5859 TEnvRec* rec;
5860 TIter next(fMapfile->GetTable());
5861 while ((rec = (TEnvRec*) next())) {
5862 TString cls = rec->GetName();
5863 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5864 // get the first lib from the list of lib and dependent libs
5865 TString libs = rec->GetValue();
5866 if (libs == "") {
5867 continue;
5868 }
5869 TString delim(" ");
5870 TObjArray* tokens = libs.Tokenize(delim);
5871 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5872 // convert "@@" to "::", we used "@@" because TEnv
5873 // considers "::" a terminator
5874 cls.Remove(0, 8);
5875 cls.ReplaceAll("@@", "::");
5876 // convert "-" to " ", since class names may have
5877 // blanks and TEnv considers a blank a terminator
5878 cls.ReplaceAll("-", " ");
5879 if (gDebug > 6) {
5880 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
5881 if (wlib) {
5882 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
5883 }
5884 else {
5885 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
5886 }
5887 delete[] wlib;
5888 }
5889 delete tokens;
5890 }
5891 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
5892 cls.Remove(0, 8);
5893 // convert "-" to " ", since class names may have
5894 // blanks and TEnv considers a blank a terminator
5895 cls.ReplaceAll("-", " ");
5896 fInterpreter->declare(cls.Data());
5897 }
5898 }
5899
5900 // Process the forward declarations collected
5901 cling::Transaction* T = nullptr;
5902 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
5903 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
5904
5905 if (compRes!=cling::Interpreter::kSuccess){
5906 Warning("LoadLibraryMap",
5907 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
5908 }
5909
5910 if (T) {
5911 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
5912 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
5913 if (declIt->m_DGR.isSingleDecl()) {
5914 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
5915 if (clang::isa<TagDecl>(D) || clang::isa<NamespaceDecl>(D)) {
5916 evsAdder.TraverseDecl(D);
5917 }
5918 }
5919 }
5920 }
5921 }
5922
5923 // clear duplicates
5924
5925 return 0;
5926}
5927
5928////////////////////////////////////////////////////////////////////////////////
5929/// Scan again along the dynamic path for library maps. Entries for the loaded
5930/// shared libraries are unloaded first. This can be useful after reseting
5931/// the dynamic path through TSystem::SetDynamicPath()
5932/// In case of error -1 is returned, 0 otherwise.
5933
5935{
5938 return 0;
5939}
5940
5941////////////////////////////////////////////////////////////////////////////////
5942/// Reload the library map entries coming from all the loaded shared libraries,
5943/// after first unloading the current ones.
5944/// In case of error -1 is returned, 0 otherwise.
5945
5947{
5948 const TString sharedLibLStr = GetSharedLibs();
5949 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5950 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
5951 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
5952 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5953 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5954 const Int_t ret = UnloadLibraryMap(sharedLibBaseStr);
5955 if (ret < 0) {
5956 continue;
5957 }
5958 TString rootMapBaseStr = sharedLibBaseStr;
5959 if (sharedLibBaseStr.EndsWith(".dll")) {
5960 rootMapBaseStr.ReplaceAll(".dll", "");
5961 }
5962 else if (sharedLibBaseStr.EndsWith(".DLL")) {
5963 rootMapBaseStr.ReplaceAll(".DLL", "");
5964 }
5965 else if (sharedLibBaseStr.EndsWith(".so")) {
5966 rootMapBaseStr.ReplaceAll(".so", "");
5967 }
5968 else if (sharedLibBaseStr.EndsWith(".sl")) {
5969 rootMapBaseStr.ReplaceAll(".sl", "");
5970 }
5971 else if (sharedLibBaseStr.EndsWith(".dl")) {
5972 rootMapBaseStr.ReplaceAll(".dl", "");
5973 }
5974 else if (sharedLibBaseStr.EndsWith(".a")) {
5975 rootMapBaseStr.ReplaceAll(".a", "");
5976 }
5977 else {
5978 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
5979 delete sharedLibL;
5980 return -1;
5981 }
5982 rootMapBaseStr += ".rootmap";
5983 const char* rootMap = gSystem->Which(gSystem->GetDynamicPath(), rootMapBaseStr);
5984 if (!rootMap) {
5985 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
5986 delete[] rootMap;
5987 delete sharedLibL;
5988 return -1;
5989 }
5990 const Int_t status = LoadLibraryMap(rootMap);
5991 if (status < 0) {
5992 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
5993 delete[] rootMap;
5994 delete sharedLibL;
5995 return -1;
5996 }
5997 delete[] rootMap;
5998 }
5999 delete sharedLibL;
6000 return 0;
6001}
6002
6003////////////////////////////////////////////////////////////////////////////////
6004/// Unload the library map entries coming from all the loaded shared libraries.
6005/// Returns 0 if succesful
6006
6008{
6009 const TString sharedLibLStr = GetSharedLibs();
6010 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
6011 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
6012 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
6013 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
6014 UnloadLibraryMap(sharedLibBaseStr);
6015 }
6016 delete sharedLibL;
6017 return 0;
6018}
6019
6020////////////////////////////////////////////////////////////////////////////////
6021/// Unload library map entries coming from the specified library.
6022/// Returns -1 in case no entries for the specified library were found,
6023/// 0 otherwise.
6024
6026{
6027 if (!fMapfile || !library || !*library) {
6028 return 0;
6029 }
6030 TString libname(library);
6031 Ssiz_t idx = libname.Last('.');
6032 if (idx != kNPOS) {
6033 libname.Remove(idx);
6034 }
6035 size_t len = libname.Length();
6036 TEnvRec *rec;
6037 TIter next(fMapfile->GetTable());
6039 Int_t ret = 0;
6040 while ((rec = (TEnvRec *) next())) {
6041 TString cls = rec->GetName();
6042 if (cls.Length() > 2) {
6043 // get the first lib from the list of lib and dependent libs
6044 TString libs = rec->GetValue();
6045 if (libs == "") {
6046 continue;
6047 }
6048 TString delim(" ");
6049 TObjArray* tokens = libs.Tokenize(delim);
6050 const char* lib = ((TObjString *)tokens->At(0))->GetName();
6051 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
6052 // convert "@@" to "::", we used "@@" because TEnv
6053 // considers "::" a terminator
6054 cls.Remove(0, 8);
6055 cls.ReplaceAll("@@", "::");
6056 // convert "-" to " ", since class names may have
6057 // blanks and TEnv considers a blank a terminator
6058 cls.ReplaceAll("-", " ");
6059 }
6060 if (!strncmp(lib, libname.Data(), len)) {
6061 if (fMapfile->GetTable()->Remove(rec) == nullptr) {
6062 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
6063 ret = -1;
6064 }
6065 }
6066 delete tokens;
6067 }
6068 }
6069 if (ret >= 0) {
6070 TString library_rootmap(library);
6071 if (!library_rootmap.EndsWith(".rootmap"))
6072 library_rootmap.Append(".rootmap");
6073 TNamed* mfile = nullptr;
6074 while ((mfile = (TNamed *)fRootmapFiles->FindObject(library_rootmap))) {
6075 fRootmapFiles->Remove(mfile);
6076 delete mfile;
6077 }
6079 }
6080 return ret;
6081}
6082
6083////////////////////////////////////////////////////////////////////////////////
6084/// Register the AutoLoading information for a class.
6085/// libs is a space separated list of libraries.
6086
6087Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
6088{
6089 if (!cls || !*cls)
6090 return 0;
6091
6092 TString key = TString("Library.") + cls;
6093 // convert "::" to "@@", we used "@@" because TEnv
6094 // considers "::" a terminator
6095 key.ReplaceAll("::", "@@");
6096 // convert "-" to " ", since class names may have
6097 // blanks and TEnv considers a blank a terminator
6098 key.ReplaceAll(" ", "-");
6099
6101 if (!fMapfile) {
6102 fMapfile = new TEnv();
6104
6107
6108 InitRootmapFile(".rootmap");
6109 }
6110 //fMapfile->SetValue(key, libs);
6111 fMapfile->SetValue(cls, libs);
6112 return 1;
6113}
6114
6115////////////////////////////////////////////////////////////////////////////////
6116/// Demangle the name (from the typeinfo) and then request the class
6117/// via the usual name based interface (TClass::GetClass).
6118
6119TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
6120{
6121 int err = 0;
6122 char* demangled_name = TClassEdit::DemangleTypeIdName(typeinfo, err);
6123 if (err) return nullptr;
6124 TClass* theClass = TClass::GetClass(demangled_name, load, kTRUE);
6125 free(demangled_name);
6126 return theClass;
6127}
6128
6129////////////////////////////////////////////////////////////////////////////////
6130/// Load library containing the specified class. Returns 0 in case of error
6131/// and 1 in case if success.
6132
6133Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
6134{
6135 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6136
6137 int err = 0;
6138 char* demangled_name_c = TClassEdit::DemangleTypeIdName(typeinfo, err);
6139 if (err) {
6140 return 0;
6141 }
6142
6143 std::string demangled_name(demangled_name_c);
6144 free(demangled_name_c);
6145
6146 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
6147 // shortened name.
6149 splitname.ShortType(demangled_name, TClassEdit::kDropStlDefault | TClassEdit::kDropStd);
6150
6151 // No need to worry about typedef, they aren't any ... but there are
6152 // inlined namespaces ...
6153
6154 Int_t result = AutoLoad(demangled_name.c_str());
6155 if (result == 0) {
6156 demangled_name = TClassEdit::GetLong64_Name(demangled_name);
6157 result = AutoLoad(demangled_name.c_str(), knowDictNotLoaded);
6158 }
6159
6160 return result;
6161}
6162
6163////////////////////////////////////////////////////////////////////////////////
6164// Get the list of 'published'/'known' library for the class and load them.
6166{
6167 Int_t status = 0;
6168
6169 // lookup class to find list of dependent libraries
6170 TString deplibs = gCling->GetClassSharedLibs(cls);
6171 if (!deplibs.IsNull()) {
6172 TString delim(" ");
6173 TObjArray* tokens = deplibs.Tokenize(delim);
6174 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
6175 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
6176 if (gROOT->LoadClass(cls, deplib) == 0) {
6177 if (gDebug > 0) {
6178 gCling->Info("TCling::AutoLoad",
6179 "loaded dependent library %s for %s", deplib, cls);
6180 }
6181 }
6182 else {
6183 gCling->Error("TCling::AutoLoad",
6184 "failure loading dependent library %s for %s",
6185 deplib, cls);
6186 }
6187 }
6188 const char* lib = ((TObjString*)tokens->At(0))->GetName();
6189 if (lib && lib[0]) {
6190 if (gROOT->LoadClass(cls, lib) == 0) {
6191 if (gDebug > 0) {
6192 gCling->Info("TCling::AutoLoad",
6193 "loaded library %s for %s", lib, cls);
6194 }
6195 status = 1;
6196 }
6197 else {
6198 gCling->Error("TCling::AutoLoad",
6199 "failure loading library %s for %s", lib, cls);
6200 }
6201 }
6202 delete tokens;
6203 }
6204
6205 return status;
6206}
6207
6208////////////////////////////////////////////////////////////////////////////////
6209// Iterate through the data member of the class (either through the TProtoClass
6210// or through Cling) and trigger, recursively, the loading the necessary libraries.
6211// \note `cls` is expected to be already normalized!
6212// \returns 1 on success.
6213Int_t TCling::DeepAutoLoadImpl(const char *cls, std::unordered_set<std::string> &visited,
6214 bool nameIsNormalized)
6215{
6216 // Try to insert; if insertion failed because the entry existed, DeepAutoLoadImpl()
6217 // has previously (within the same call to `AutoLoad()`) tried to load this class
6218 // and we are done, whether success or not, as it won't work better now than before,
6219 // because there is no additional information now compared to before.
6220 if (!visited.insert(std::string(cls)).second)
6221 return 1;
6222
6223 if (ShallowAutoLoadImpl(cls) == 0) {
6224 // If ShallowAutoLoadImpl() has an error, we have an error.
6225 return 0;
6226 }
6227
6228 // Now look through the TProtoClass to load the required library/dictionary
6229 if (TProtoClass *proto = nameIsNormalized ? TClassTable::GetProtoNorm(cls) : TClassTable::GetProto(cls)) {
6230 for (auto element : proto->GetData()) {
6231 if (element->IsBasic())
6232 continue;
6233 const char *subtypename = element->GetTypeName();
6234 if (!TClassTable::GetDictNorm(subtypename)) {
6235 // Failure to load a dictionary is not (quite) a failure load
6236 // the top-level library. If we return false here, then
6237 // we would end up in a situation where the library and thus
6238 // the dictionary is loaded for "cls" but the TClass is
6239 // not created and/or marked as unavailable (in case where
6240 // AutoLoad is called from TClass::GetClass).
6241 DeepAutoLoadImpl(subtypename, visited, true /*normalized*/);
6242 }
6243 }
6244 return 1;
6245 }
6246
6247 // We found no TProtoClass for cls.
6248 auto classinfo = gInterpreter->ClassInfo_Factory(cls);
6249 if (classinfo && gInterpreter->ClassInfo_IsValid(classinfo)
6250 && !(gInterpreter->ClassInfo_Property(classinfo) & kIsEnum))
6251 {
6252 DataMemberInfo_t *memberinfo = gInterpreter->DataMemberInfo_Factory(classinfo, TDictionary::EMemberSelection::kNoUsingDecls);
6253 while (gInterpreter->DataMemberInfo_Next(memberinfo)) {
6254 if (gInterpreter->DataMemberInfo_TypeProperty(memberinfo) & ::kIsFundamental)
6255 continue;
6256 auto membertypename = TClassEdit::GetLong64_Name(gInterpreter->TypeName(gInterpreter->DataMemberInfo_TypeTrueName(memberinfo)));
6257 if (!TClassTable::GetDictNorm(membertypename.c_str())) {
6258 // Failure to load a dictionary is not (quite) a failure load
6259 // the top-level library. See detailed comment in the TProtoClass
6260 // branch (above).
6261 (void)DeepAutoLoadImpl(membertypename.c_str(), visited, true /*normalized*/);
6262 }
6263 }
6264 gInterpreter->DataMemberInfo_Delete(memberinfo);
6265 }
6266 gInterpreter->ClassInfo_Delete(classinfo);
6267 return 1;
6268}
6269
6270////////////////////////////////////////////////////////////////////////////////
6271/// Load library containing the specified class. Returns 0 in case of error
6272/// and 1 in case if success.
6273
6274Int_t TCling::AutoLoad(const char *cls, Bool_t knowDictNotLoaded /* = kFALSE */)
6275{
6276 // Prevent update to IsClassAutoloading between our check and our actions.
6278
6279 // TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
6280 // rootcling (in *_rdict.pcm file generation) it is a no op.
6281 // FIXME: We should avoid calling autoload when we know we are not supposed
6282 // to and transform this check into an assert.
6284 // Never load any library from rootcling/genreflex.
6285 if (gDebug > 2) {
6286 Info("TCling::AutoLoad", "Explicitly disabled (the class name is %s)", cls);
6287 }
6288 return 0;
6289 }
6290
6291 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6292
6294
6295 if (!knowDictNotLoaded && gClassTable->GetDictNorm(cls)) {
6296 // The library is already loaded as the class's dictionary is known.
6297 // Return success.
6298 // Note: the name (cls) is expected to be normalized as it comes either
6299 // from a callbacks (that can/should calculate the normalized name from the
6300 // decl) or from TClass::GetClass (which does also calculate the normalized
6301 // name).
6302 return 1;
6303 }
6304
6305 if (gDebug > 2) {
6306 Info("TCling::AutoLoad",
6307 "Trying to autoload for %s", cls);
6308 }
6309
6310 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
6311 if (gDebug > 2) {
6312 Info("TCling::AutoLoad",
6313 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
6314 }
6315 return 0;
6316 }
6317 // Prevent the recursion when the library dictionary are loaded.
6318 SuspendAutoLoadingRAII autoLoadOff(this);
6319 // Try using externally provided callback first.
6320 if (fAutoLoadCallBack) {
6321 int success = (*(AutoLoadCallBack_t)fAutoLoadCallBack)(cls);
6322 if (success)
6323 return success;
6324 }
6325
6326 // During the 'Deep' part of the search we will call GetClassSharedLibsForModule
6327 // (when module are enabled) which might end up calling AutoParsing but
6328 // that should only be for the cases where the library has no generated pcm
6329 // and in that case a rootmap should be available.
6330 // This avoids a very costly operation (for generally no gain) but reduce the
6331 // quality of the search (i.e. bad in case of library with no pcm and no rootmap
6332 // file).
6333 TInterpreter::SuspendAutoParsing autoParseRaii(this);
6334 std::unordered_set<std::string> visited;
6335 return DeepAutoLoadImpl(cls, visited, false /*normalized*/);
6336}
6337
6338////////////////////////////////////////////////////////////////////////////////
6339/// Parse the payload or header.
6340
6341static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
6342 Bool_t header,
6343 cling::Interpreter *interpreter)
6344{
6345 std::string code = gNonInterpreterClassDef ;
6346 if (!header) {
6347 // This is the complete header file content and not the
6348 // name of a header.
6349 code += what;
6350
6351 } else {
6352 code += ("#include \"");
6353 code += what;
6354 code += "\"\n";
6355 }
6356 code += ("#ifdef __ROOTCLING__\n"
6357 "#undef __ROOTCLING__\n"
6358 + gInterpreterClassDef +
6359 "#endif");
6360
6361 cling::Interpreter::CompilationResult cr;
6362 {
6363 // scope within which diagnostics are de-activated
6364 // For now we disable diagnostics because we saw them already at
6365 // dictionary generation time. That won't be an issue with the PCMs.
6366
6367 Sema &SemaR = interpreter->getSema();
6368 ROOT::Internal::ParsingStateRAII parsingStateRAII(interpreter->getParser(), SemaR);
6369 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
6370
6371 #if defined(R__MUST_REVISIT)
6372 #if R__MUST_REVISIT(6,2)
6373 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
6374 #endif
6375 #endif
6376
6377 cr = interpreter->parseForModule(code);
6378 }
6379 return cr;
6380}
6381
6382////////////////////////////////////////////////////////////////////////////////
6383/// Helper routine for TCling::AutoParse implementing the actual call to the
6384/// parser and looping over template parameters (if
6385/// any) and when they don't have a registered header to autoparse,
6386/// recurse over their template parameters.
6387///
6388/// Returns the number of header parsed.
6389
6390UInt_t TCling::AutoParseImplRecurse(const char *cls, bool topLevel)
6391{
6392 // We assume the lock has already been taken.
6393 // R__LOCKGUARD(gInterpreterMutex);
6394
6395 Int_t nHheadersParsed = 0;
6396 unsigned long offset = 0;
6397 if (strncmp(cls, "const ", 6) == 0) {
6398 offset = 6;
6399 }
6400
6401 // Loop on the possible autoparse keys
6402 bool skipFirstEntry = false;
6403 std::vector<std::string> autoparseKeys;
6404 if (strchr(cls, '<')) {
6405 int nestedLoc = 0;
6406 TClassEdit::GetSplit(cls + offset, autoparseKeys, nestedLoc, TClassEdit::kDropTrailStar);
6407 // Check if we can skip the name of the template in the autoparses
6408 // Take all the scopes one by one. If all of them are in the AST, we do not
6409 // need to autoparse for that particular template.
6410 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
6411 // autoparseKeys[0] is empty when the input is not a template instance.
6412 // The case strchr(cls, '<') != 0 but still not a template instance can
6413 // happens 'just' for string (GetSplit replaces the template by the short name
6414 // and then use that for thew splitting)
6415 TString templateName(autoparseKeys[0]);
6416 auto tokens = templateName.Tokenize("::");
6417 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
6418 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
6419 if (TClassEdit::IsStdClass(cls + offset))
6420 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
6421 auto nTokens = tokens->GetEntriesFast();
6422 for (Int_t tk = 0; tk < nTokens; ++tk) {
6423 auto scopeObj = tokens->UncheckedAt(tk);
6424 auto scopeName = ((TObjString*) scopeObj)->String().Data();
6425 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
6426 // Check if we have multiple nodes in the AST with this name
6427 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
6428 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
6429 if (!previousScopeAsContext) break; // this is not a context
6430 }
6431 delete tokens;
6432 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
6433 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
6434 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
6435 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
6436 skipFirstEntry = templatedDecl->hasDefinition();
6437 }
6438 }
6439 }
6440
6441 }
6442 }
6443 if (topLevel) autoparseKeys.emplace_back(cls);
6444
6445 for (const auto & apKeyStr : autoparseKeys) {
6446 if (skipFirstEntry) {
6447 skipFirstEntry=false;
6448 continue;
6449 }
6450 if (apKeyStr.empty()) continue;
6451 const char *apKey = apKeyStr.c_str();
6452 std::size_t normNameHash(fStringHashFunction(apKey));
6453 // If the class was not looked up
6454 if (gDebug > 1) {
6455 Info("TCling::AutoParse",
6456 "Starting autoparse for %s\n", apKey);
6457 }
6458 if (fLookedUpClasses.insert(normNameHash).second) {
6459 auto const &iter = fClassesHeadersMap.find(normNameHash);
6460 if (iter != fClassesHeadersMap.end()) {
6461 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
6462 fTransactionHeadersMap.insert({T,normNameHash});
6463 auto const &hNamesPtrs = iter->second;
6464 if (gDebug > 1) {
6465 Info("TCling::AutoParse",
6466 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
6467 }
6468 for (auto & hName : hNamesPtrs) {
6469 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
6470 if (0 != fPayloads.count(normNameHash)) {
6471 float initRSSval=0.f, initVSIZEval=0.f;
6472 (void) initRSSval; // Avoid unused var warning
6473 (void) initVSIZEval;
6474 if (gDebug > 0) {
6475 Info("AutoParse",
6476 "Parsing full payload for %s", apKey);
6477 ProcInfo_t info;
6478 gSystem->GetProcInfo(&info);
6479 initRSSval = 1e-3*info.fMemResident;
6480 initVSIZEval = 1e-3*info.fMemVirtual;
6481 }
6482 auto cRes = ExecAutoParse(hName, kFALSE, GetInterpreterImpl());
6483 if (cRes != cling::Interpreter::kSuccess) {
6484 if (hName[0] == '\n')
6485 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
6486 } else {
6487 fParsedPayloadsAddresses.insert(hName);
6488 nHheadersParsed++;
6489 if (gDebug > 0){
6490 ProcInfo_t info;
6491 gSystem->GetProcInfo(&info);
6492 float endRSSval = 1e-3*info.fMemResident;
6493 float endVSIZEval = 1e-3*info.fMemVirtual;
6494 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6495 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6496 }
6497 }
6498 } else if (!IsLoaded(hName)) {
6499 if (gDebug > 0) {
6500 Info("AutoParse",
6501 "Parsing single header %s", hName);
6502 }
6503 auto cRes = ExecAutoParse(hName, kTRUE, GetInterpreterImpl());
6504 if (cRes != cling::Interpreter::kSuccess) {
6505 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
6506 } else {
6507 nHheadersParsed++;
6508 }
6509 }
6510 }
6511 }
6512 else {
6513 // There is no header registered for this class, if this a
6514 // template, it will be instantiated if/when it is requested
6515 // and if we do no load/parse its components we might end up
6516 // not using an eventual specialization.
6517 if (strchr(apKey, '<')) {
6518 nHheadersParsed += AutoParseImplRecurse(apKey, false);
6519 }
6520 }
6521 }
6522 }
6523
6524 return nHheadersParsed;
6525
6526}
6527
6528////////////////////////////////////////////////////////////////////////////////
6529/// Parse the headers relative to the class
6530/// Returns 1 in case of success, 0 in case of failure
6531
6532Int_t TCling::AutoParse(const char *cls)
6533{
6534 if (llvm::StringRef(cls).contains("(lambda)"))
6535 return 0;
6536
6539 return AutoLoad(cls);
6540 } else {
6541 return 0;
6542 }
6543 }
6544
6546
6547 if (gDebug > 1) {
6548 Info("TCling::AutoParse",
6549 "Trying to autoparse for %s", cls);
6550 }
6551
6552 // The catalogue of headers is in the dictionary
6554 && !gClassTable->GetDictNorm(cls)) {
6555 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
6556 ROOT::Internal::ParsingStateRAII parsingStateRAII(fInterpreter->getParser(),
6557 fInterpreter->getSema());
6558 AutoLoad(cls, true /*knowDictNotLoaded*/);
6559 }
6560
6561 // Prevent the recursion when the library dictionary are loaded.
6562 SuspendAutoLoadingRAII autoLoadOff(this);
6563
6564 // No recursive header parsing on demand; we require headers to be standalone.
6565 SuspendAutoParsing autoParseRAII(this);
6566
6567 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
6568
6570
6571 return nHheadersParsed > 0 ? 1 : 0;
6572}
6573
6574// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6575// Try to solve the problem by AutoLoading. Return true when AutoLoading success, return
6576// false if not.
6577bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6578{
6579 StringRef errMsg(errmessage);
6580 if (errMsg.contains("undefined symbol: ")) {
6581 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6582 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6583 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6584 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6585 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6586 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6587 return true;
6588 } else {
6589 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6590 if ( ((TCling*)gCling)->LazyFunctionCreatorAutoload(errmessage))
6591 return true;
6592 }
6593
6594 return false;
6595}
6596
6597////////////////////////////////////////////////////////////////////////////////
6598/// Autoload a library based on a missing symbol.
6599
6600void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {
6601 std::string dlsym_mangled_name = ROOT::TMetaUtils::DemangleNameForDlsym(mangled_name);
6602
6603 // We have already loaded the library.
6604 if (void* Addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name))
6605 return Addr;
6606
6607 const cling::DynamicLibraryManager &DLM = *GetInterpreterImpl()->getDynamicLibraryManager();
6609
6610 auto LibLoader = [](const std::string& LibName) -> bool {
6611 if (gSystem->Load(LibName.c_str(), "", false) < 0) {
6612 ::Error("TCling__LazyFunctionCreatorAutoloadForModule",
6613 "Failed to load library %s", LibName.c_str());
6614 return false;
6615 }
6616 return true; //success.
6617 };
6618
6619 std::string libName = DLM.searchLibrariesForSymbol(mangled_name,
6620 /*searchSystem=*/ true);
6621
6622 assert(!llvm::StringRef(libName).startswith("libNew") &&
6623 "We must not resolve symbols from libNew!");
6624
6625 if (libName.empty())
6626 return nullptr;
6627
6628 if (!LibLoader(libName))
6629 return nullptr;
6630
6631 return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(dlsym_mangled_name);
6632}
6633
6634////////////////////////////////////////////////////////////////////////////////
6635
6636Bool_t TCling::IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
6637{
6638 return fNSFromRootmaps.count(nsDecl) != 0;
6639}
6640
6641////////////////////////////////////////////////////////////////////////////////
6642/// Internal function. Actually do the update of the ClassInfo when seeing
6643// new TagDecl or NamespaceDecl.
6644void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6645{
6646
6648 if (cci) {
6649 // If we only had a forward declaration then update the
6650 // TClingClassInfo with the definition if we have it now.
6651 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6652 if (!oldDef || (def && def != oldDef)) {
6653 cl->ResetCaches();
6655 if (def) {
6656 // It's a tag decl, not a namespace decl.
6657 cci->Init(*cci->GetType());
6659 }
6660 }
6661 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6662 cl->ResetCaches();
6663 // yes, this is almost a waste of time, but we do need to lookup
6664 // the 'type' corresponding to the TClass anyway in order to
6665 // preserve the opaque typedefs (Double32_t)
6666 if (!alias && def != nullptr)
6667 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), def);
6668 else
6669 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), cl->GetName());
6670 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6671 // We now need to update the state and bits.
6672 if (cl->fState != TClass::kHasTClassInit) {
6673 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6675 }
6676 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6677 } else {
6678 delete ((TClingClassInfo *)cl->fClassInfo);
6679 cl->fClassInfo = nullptr;
6680 }
6681 }
6682}
6683
6684////////////////////////////////////////////////////////////////////////////////
6685/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6686void TCling::UpdateClassInfoWithDecl(const NamedDecl* ND)
6687{
6688 const TagDecl *td = dyn_cast<TagDecl>(ND);
6689 const NamespaceDecl *ns = dyn_cast<NamespaceDecl>(ND);
6690 const NamedDecl *canon = nullptr;
6691
6692 std::string name;
6693 TagDecl* tdDef = nullptr;
6694 if (td) {
6695 canon = tdDef = td->getDefinition();
6696 // Let's pass the decl to the TClass only if it has a definition.
6697 if (!tdDef) return;
6698
6699 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6700 // Ignore incomplete definition.
6701 // Ignore declaration within a function.
6702 return;
6703 }
6704
6705 auto declName = tdDef->getNameAsString();
6706 // Check if we have registered the unqualified name into the list
6707 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6708 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6709 // the unqualified name is sufficient (and the fully qualified name might be
6710 // 'wrong' if there is difference in spelling in the template paramters (for example)
6711 if (!TClass::HasNoInfoOrEmuOrFwdDeclaredDecl(declName.c_str())){
6712 // 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() );
6713 return;
6714 }
6715
6716 clang::QualType type(tdDef->getTypeForDecl(), 0);
6718 } else if (ns) {
6719 canon = ns->getCanonicalDecl();
6720 name = ND->getQualifiedNameAsString();
6721 } else {
6722 name = ND->getQualifiedNameAsString();
6723 }
6724
6725 // Supposedly we are being called while something is being
6726 // loaded ... let's now tell the autoloader to do the work
6727 // yet another time.
6728 SuspendAutoLoadingRAII autoLoadOff(this);
6729 // FIXME: There can be more than one TClass for a single decl.
6730 // for example vector<double> and vector<Double32_t>
6731 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6732 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6733 RefreshClassInfo(cl, canon, false);
6734 }
6735 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6736 // and update them too:
6737 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6738 // RefreshClassInfo(cl, tdDef, true);
6739}
6740
6741////////////////////////////////////////////////////////////////////////////////
6742/// No op: see TClingCallbacks
6743
6744void TCling::UpdateClassInfo(char* item, Long_t tagnum)
6745{
6746}
6747
6748//______________________________________________________________________________
6749//FIXME: Factor out that function in TClass, because TClass does it already twice
6750void TCling::UpdateClassInfoWork(const char* item)
6751{
6752 // This is a no-op as part of the API.
6753 // TCling uses UpdateClassInfoWithDecl() instead.
6754}
6755
6756////////////////////////////////////////////////////////////////////////////////
6757/// Update all canvases at end the terminal input command.
6758
6760{
6761 TIter next(gROOT->GetListOfCanvases());
6762 TVirtualPad* canvas;
6763 while ((canvas = (TVirtualPad*)next())) {
6764 canvas->Update();
6765 }
6766}
6767
6768////////////////////////////////////////////////////////////////////////////////
6769
6770void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6771 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6772
6773 // If the transaction does not contain anything we can return earlier.
6774 if (!HandleNewTransaction(T)) return;
6775
6776 bool isTUTransaction = false;
6777 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
6778 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
6779 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
6780 // The is the first transaction, we have to expose to meta
6781 // what's already in the AST.
6782 isTUTransaction = true;
6783 }
6784 }
6785
6786 std::set<const void*> TransactionDeclSet;
6787 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
6788 const clang::Decl* WrapperFD = T.getWrapperFD();
6789 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6790 I != E; ++I) {
6791 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
6792 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
6793 continue;
6794
6795 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6796 DE = I->m_DGR.end(); DI != DE; ++DI) {
6797 if (*DI == WrapperFD)
6798 continue;
6799 TransactionDeclSet.insert(*DI);
6800 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
6801 }
6802 }
6803 }
6804
6805 // The above might trigger more decls to be deserialized.
6806 // Thus the iteration over the deserialized decls must be last.
6807 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
6808 E = T.deserialized_decls_end(); I != E; ++I) {
6809 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6810 DE = I->m_DGR.end(); DI != DE; ++DI)
6811 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
6812 //FIXME: HandleNewDecl should take DeclGroupRef
6813 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
6814 modifiedTClasses);
6815 }
6816 }
6817
6818
6819 // When fully building the reflection info in TClass, a deserialization
6820 // could be triggered, which may result in request for building the
6821 // reflection info for the same TClass. This in turn will clear the caches
6822 // for the TClass in-flight and cause null ptr derefs.
6823 // FIXME: This is a quick fix, solving most of the issues. The actual
6824 // question is: Shouldn't TClass provide a lock mechanism on update or lock
6825 // itself until the update is done.
6826 //
6827 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
6828 std::vector<TClass*>::iterator it;
6829 it = set_difference(modifiedTClasses.begin(), modifiedTClasses.end(),
6830 ((TCling*)gCling)->GetModTClasses().begin(),
6831 ((TCling*)gCling)->GetModTClasses().end(),
6832 modifiedTClassesDiff.begin());
6833 modifiedTClassesDiff.resize(it - modifiedTClassesDiff.begin());
6834
6835 // Lock the TClass for updates
6836 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
6837 modifiedTClassesDiff.end());
6838 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
6839 E = modifiedTClassesDiff.end(); I != E; ++I) {
6840 // Make sure the TClass has not been deleted.
6841 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
6842 continue;
6843 }
6844 // Could trigger deserialization of decls.
6845 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
6846 // Unlock the TClass for updates
6847 ((TCling*)gCling)->GetModTClasses().erase(*I);
6848
6849 }
6850}
6851
6852///\brief Invalidate stored TCling state for declarations included in transaction `T'.
6853///
6854void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
6855{
6857
6858 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6859 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6860 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6861 (TListOfEnums *)gROOT->GetListOfEnums());
6862
6863 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
6864 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6865 I != E; ++I) {
6866 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
6867 continue;
6868 if (I->m_Call == cling::Transaction::kCCINone) {
6869 UpdateListsOnUnloaded(*(*iNested));
6870 ++iNested;
6871 continue;
6872 }
6873
6874 for (auto &D : I->m_DGR)
6875 InvalidateCachedDecl(Lists, D);
6876 }
6877}
6878
6879///\brief Invalidate cached TCling information for the given global declaration.
6880///
6881void TCling::InvalidateGlobal(const Decl *D) {
6882 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6883 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6884 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6885 (TListOfEnums *)gROOT->GetListOfEnums());
6886 InvalidateCachedDecl(Lists, D);
6887}
6888
6889///\brief Invalidate cached TCling information for the given declaration, and
6890/// removed it from the appropriate object list.
6891///\param[in] Lists - std::tuple<TListOfDataMembers&, TListOfFunctions&,
6892/// TListOfFunctionTemplates&, TListOfEnums&>
6893/// of pointers to the (global/class) object lists.
6894///\param[in] D - Decl to discard.
6895///
6899 TListOfEnums*> &Lists, const Decl *D) {
6900 if (D->isFromASTFile()) // `D' came from the PCH; ignore
6901 return;
6902
6903 TListOfDataMembers &LODM = *(std::get<0>(Lists));
6904 TListOfFunctions &LOF = *(std::get<1>(Lists));
6905 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
6906 TListOfEnums &LOE = *(std::get<3>(Lists));
6907
6908 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D)) {
6909 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
6910 if (LODM.GetClass())
6911 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
6912 else
6913 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
6914 } else if (isa<FunctionDecl>(D)) {
6916 } else if (isa<FunctionTemplateDecl>(D)) {
6918 } else if (isa<EnumDecl>(D)) {
6919 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
6920 if (!E)
6921 return;
6922
6923 // Try to invalidate enumerators (for unscoped enumerations).
6924 for (TIter I = E->GetConstants(); auto EC = (TEnumConstant *)I(); )
6926 (TEnumConstant *)LODM.FindObject(EC->GetName()));
6927
6929 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
6930 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->isCompleteDefinition())
6931 return;
6932
6933 std::vector<TClass *> Classes;
6934 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
6935 return;
6936 for (auto &C : Classes) {
6937 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
6938 (TListOfFunctions *)C->GetListOfMethods(),
6939 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
6940 (TListOfEnums *)C->GetListOfEnums());
6941 for (auto &I : cast<DeclContext>(D)->decls())
6942 InvalidateCachedDecl(Lists, I);
6943
6944 // For NamespaceDecl (redeclarable), only invalidate this redecl.
6945 if (D->getKind() != Decl::Namespace
6946 || cast<NamespaceDecl>(D)->isOriginalNamespace())
6947 C->ResetClassInfo();
6948 }
6949 }
6950}
6951
6952////////////////////////////////////////////////////////////////////////////////
6953// If an autoparse was done during a transaction and that it is rolled back,
6954// we need to make sure the next request for the same autoparse will be
6955// honored.
6956void TCling::TransactionRollback(const cling::Transaction &T) {
6957 auto const &triter = fTransactionHeadersMap.find(&T);
6958 if (triter != fTransactionHeadersMap.end()) {
6959 std::size_t normNameHash = triter->second;
6960
6961 fLookedUpClasses.erase(normNameHash);
6962
6963 auto const &iter = fClassesHeadersMap.find(normNameHash);
6964 if (iter != fClassesHeadersMap.end()) {
6965 auto const &hNamesPtrs = iter->second;
6966 for (auto &hName : hNamesPtrs) {
6967 if (gDebug > 0) {
6968 Info("TransactionRollback",
6969 "Restoring ability to autoaparse: %s", hName);
6970 }
6971 fParsedPayloadsAddresses.erase(hName);
6972 }
6973 }
6974 }
6975}
6976
6977////////////////////////////////////////////////////////////////////////////////
6978
6979void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
6980// R__LOCKGUARD_CLING(gInterpreterMutex);
6981// UpdateListOfLoadedSharedLibraries();
6982}
6983
6984////////////////////////////////////////////////////////////////////////////////
6985
6986void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
6987 fPrevLoadedDynLibInfo = nullptr;
6988 fSharedLibs = "";
6989}
6990
6991////////////////////////////////////////////////////////////////////////////////
6992/// Return the list of shared libraries loaded into the process.
6993
6995{
6998 return fSharedLibs;
6999}
7000
7001static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
7002{
7003 if (!cls || !*cls)
7004 return {};
7005
7006 using namespace clang;
7007 if (const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
7008 /*type*/ nullptr, /*instantiate*/ false)) {
7009 if (!D->isFromASTFile()) {
7010 if (gDebug > 5)
7011 Warning("GetClassSharedLibsForModule", "Decl found for %s is not part of a module", cls);
7012 return {};
7013 }
7014 class ModuleCollector : public ConstDeclVisitor<ModuleCollector> {
7015 llvm::DenseSet<Module *> &m_TopLevelModules;
7016
7017 public:
7018 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
7019 void Collect(const Decl *D) { Visit(D); }
7020
7021 void VisitDecl(const Decl *D)
7022 {
7023 // FIXME: Such case is described ROOT-7765 where
7024 // ROOT_GENERATE_DICTIONARY does not contain the list of headers.
7025 // They are specified as #includes in the LinkDef file. This leads to
7026 // generation of incomplete modulemap files and this logic fails to
7027 // compute the corresponding module of D.
7028 // FIXME: If we want to support such a case, we should not rely on
7029 // the contents of the modulemap but mangle D and look it up in the
7030 // .so files.
7031 if (!D->hasOwningModule())
7032 return;
7033 if (Module *M = D->getOwningModule()->getTopLevelModule())
7034 m_TopLevelModules.insert(M);
7035 }
7036
7037 void VisitTemplateArgument(const TemplateArgument &TA)
7038 {
7039 switch (TA.getKind()) {
7040 case TemplateArgument::Null:
7041 case TemplateArgument::Integral:
7042 case TemplateArgument::Pack:
7043 case TemplateArgument::NullPtr:
7044 case TemplateArgument::Expression:
7045 case TemplateArgument::Template:
7046 case TemplateArgument::TemplateExpansion: return;
7047 case TemplateArgument::Type:
7048 if (const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
7049 return Visit(TagTy->getDecl());
7050 return;
7051 case TemplateArgument::Declaration: return Visit(TA.getAsDecl());
7052 }
7053 llvm_unreachable("Invalid TemplateArgument::Kind!");
7054 }
7055
7056 void VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *CTSD)
7057 {
7058 if (CTSD->getOwningModule())
7059 VisitDecl(CTSD);
7060 else
7061 VisitDecl(CTSD->getSpecializedTemplate());
7062 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
7063 for (const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
7064 VisitTemplateArgument(*Arg);
7065 }
7066 }
7067 };
7068
7069 llvm::DenseSet<Module *> TopLevelModules;
7070 ModuleCollector m(TopLevelModules);
7071 m.Collect(D);
7072 std::string result;
7073 for (auto M : TopLevelModules) {
7074 // ROOT-unaware modules (i.e. not processed by rootcling) do not have a
7075 // link declaration.
7076 if (!M->LinkLibraries.size())
7077 continue;
7078 // We have preloaded the Core module thus libCore.so
7079 if (M->Name == "Core")
7080 continue;
7081 assert(M->LinkLibraries.size() == 1);
7082 if (!result.empty())
7083 result += ' ';
7084 result += M->LinkLibraries[0].Library;
7085 }
7086 return result;
7087 }
7088 return {};
7089}
7090
7091////////////////////////////////////////////////////////////////////////////////
7092/// Get the list of shared libraries containing the code for class cls.
7093/// The first library in the list is the one containing the class, the
7094/// others are the libraries the first one depends on. Returns 0
7095/// in case the library is not found.
7096
7097const char* TCling::GetClassSharedLibs(const char* cls)
7098{
7099 if (fCxxModulesEnabled) {
7100 // Lock the interpreter mutex before interacting with cling.
7101 // TODO: Can we move this further deep? In principle the lock should be in
7102 // GetClassSharedLibsForModule, but it might be needed also for
7103 // getLookupHelper?
7105 llvm::StringRef className = cls;
7106 // If we get a class name containing lambda, we cannot parse it and we
7107 // can exit early.
7108 // FIXME: This works around a bug when we are instantiating a template
7109 // make_unique and the substitution fails. Seen in most of the dataframe
7110 // tests.
7111 if (className.contains("(lambda)"))
7112 return nullptr;
7113 // Limit the recursion which can be induced by GetClassSharedLibsForModule.
7114 SuspendAutoLoadingRAII AutoLoadingDisabled(this);
7115 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
7116 std::string libs = GetClassSharedLibsForModule(cls, LH);
7117 if (!libs.empty()) {
7118 fAutoLoadLibStorage.push_back(libs);
7119 return fAutoLoadLibStorage.back().c_str();
7120 }
7121 }
7122
7123 if (!cls || !*cls) {
7124 return nullptr;
7125 }
7126 // lookup class to find list of libraries
7127 if (fMapfile) {
7128 TEnvRec* libs_record = nullptr;
7129 libs_record = fMapfile->Lookup(cls);
7130 if (libs_record) {
7131 const char* libs = libs_record->GetValue();
7132 return (*libs) ? libs : nullptr;
7133 }
7134 else {
7135 // Try the old format...
7136 TString c = TString("Library.") + cls;
7137 // convert "::" to "@@", we used "@@" because TEnv
7138 // considers "::" a terminator
7139 c.ReplaceAll("::", "@@");
7140 // convert "-" to " ", since class names may have
7141 // blanks and TEnv considers a blank a terminator
7142 c.ReplaceAll(" ", "-");
7143 // Use TEnv::Lookup here as the rootmap file must start with Library.
7144 // and do not support using any stars (so we do not need to waste time
7145 // with the search made by TEnv::GetValue).
7146 TEnvRec* libs_record = nullptr;
7147 libs_record = fMapfile->Lookup(c);
7148 if (libs_record) {
7149 const char* libs = libs_record->GetValue();
7150 return (*libs) ? libs : nullptr;
7151 }
7152 }
7153 }
7154 return nullptr;
7155}
7156
7157/// This interface returns a list of dependent libraries in the form:
7158/// lib libA.so libB.so libC.so. The first library is the library we are
7159/// searching dependencies for.
7160/// Note: In order to speed up the search, we display the dependencies of the
7161/// libraries which are not yet loaded. For instance, if libB.so was already
7162/// loaded the list would contain: lib libA.so libC.so.
7163static std::string GetSharedLibImmediateDepsSlow(std::string lib,
7164 cling::Interpreter *interp,
7165 bool skipLoadedLibs = true)
7166{
7167 TString LibFullPath(lib);
7168 if (!llvm::sys::path::is_absolute(lib)) {
7169 if (!gSystem->FindDynamicLibrary(LibFullPath, /*quiet=*/true)) {
7170 Error("TCling__GetSharedLibImmediateDepsSlow", "Cannot find library '%s'", lib.c_str());
7171 return "";
7172 }
7173 } else {
7174 assert(llvm::sys::fs::exists(lib) && "Must exist!");
7175 lib = llvm::sys::path::filename(lib).str();
7176 }
7177
7178 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
7179 if (!ObjF) {
7180 Warning("TCling__GetSharedLibImmediateDepsSlow", "Failed to read object file %s", lib.c_str());
7181 return "";
7182 }
7183
7184 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7185
7186 std::set<string> DedupSet;
7187 std::string Result = lib + ' ';
7188 for (const auto &S : BinObjFile->symbols()) {
7189 uint32_t Flags = llvm::cantFail(S.getFlags());
7190 // Skip defined symbols: we have them.
7191 if (!(Flags & llvm::object::SymbolRef::SF_Undefined))
7192 continue;
7193 // Skip undefined weak symbols: if we don't have them we won't need them.
7194 // `__gmon_start__` being a typical example.
7195 if (Flags & llvm::object::SymbolRef::SF_Weak)
7196 continue;
7197 llvm::Expected<StringRef> SymNameErr = S.getName();
7198 if (!SymNameErr) {
7199 Warning("GetSharedLibDepsForModule", "Failed to read symbol");
7200 continue;
7201 }
7202 llvm::StringRef SymName = SymNameErr.get();
7203 if (SymName.empty())
7204 continue;
7205
7206 if (BinObjFile->isELF()) {
7207 // Skip the symbols which are part of the C/C++ runtime and have a
7208 // fixed library version. See binutils ld VERSION. Those reside in
7209 // 'system' libraries, which we avoid in FindLibraryForSymbol.
7210 if (SymName.contains("@GLIBCXX") || SymName.contains("@CXXABI") ||
7211 SymName.contains("@GLIBC") || SymName.contains("@GCC"))
7212 continue;
7213
7214 // Those are 'weak undefined' symbols produced by gcc. We can
7215 // ignore them.
7216 // FIXME: It is unclear whether we can ignore all weak undefined
7217 // symbols:
7218 // http://lists.llvm.org/pipermail/llvm-dev/2017-October/118177.html
7219 static constexpr llvm::StringRef RegisterClasses("_Jv_RegisterClasses");
7220 static constexpr llvm::StringRef RegisterCloneTable("_ITM_registerTMCloneTable");
7221 static constexpr llvm::StringRef DeregisterCloneTable("_ITM_deregisterTMCloneTable");
7222 if (SymName == RegisterClasses ||
7223 SymName == RegisterCloneTable ||
7224 SymName == DeregisterCloneTable)
7225 continue;
7226 }
7227
7228 // If we can find the address of the symbol, we have loaded it. Skip.
7229 if (skipLoadedLibs) {
7230 std::string SymNameForDlsym = ROOT::TMetaUtils::DemangleNameForDlsym(SymName.str());
7231 if (llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymNameForDlsym))
7232 continue;
7233 }
7234
7236 std::string found = interp->getDynamicLibraryManager()->searchLibrariesForSymbol(SymName, /*searchSystem*/false);
7237 // The expected output is just filename without the full path, which
7238 // is not very accurate, because our Dyld implementation might find
7239 // a match in location a/b/c.so and if we return just c.so ROOT might
7240 // resolve it to y/z/c.so and there we might not be ABI compatible.
7241 // FIXME: Teach the users of GetSharedLibDeps to work with full paths.
7242 if (!found.empty()) {
7243 std::string cand = llvm::sys::path::filename(found).str();
7244 if (!DedupSet.insert(cand).second)
7245 continue;
7246
7247 Result += cand + ' ';
7248 }
7249 }
7250
7251 return Result;
7252}
7253
7254static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
7255{
7256 // Check if we have parsed a rootmap file.
7257 llvm::SmallString<256> rootmapName;
7258 if (!lib.startswith("lib"))
7259 rootmapName.append("lib");
7260
7261 rootmapName.append(llvm::sys::path::filename(lib));
7262 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7263
7264 if (gCling->GetRootMapFiles()->FindObject(rootmapName.c_str()))
7265 return true;
7266
7267 // Perform a last resort by dropping the lib prefix.
7268 llvm::StringRef rootmapNameNoLib = rootmapName.str();
7269 if (rootmapNameNoLib.consume_front("lib"))
7270 return gCling->GetRootMapFiles()->FindObject(rootmapNameNoLib.data());
7271
7272 return false;
7273}
7274
7275static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
7276{
7277 if (gCling->HasPCMForLibrary(lib.data()))
7278 return true;
7279
7280 return hasParsedRootmapForLibrary(lib);
7281}
7282
7283////////////////////////////////////////////////////////////////////////////////
7284/// Get the list a libraries on which the specified lib depends. The
7285/// returned string contains as first element the lib itself.
7286/// Returns 0 in case the lib does not exist or does not have
7287/// any dependencies. If useDyld is true, we iterate through all available
7288/// libraries and try to construct the dependency chain by resolving each
7289/// symbol.
7290
7291const char* TCling::GetSharedLibDeps(const char* lib, bool useDyld/* = false*/)
7292{
7293 if (llvm::sys::path::is_absolute(lib) && !llvm::sys::fs::exists(lib))
7294 return nullptr;
7295
7296 if (!hasParsedRootmapForLibrary(lib)) {
7297 llvm::SmallString<512> rootmapName(lib);
7298 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7299 if (llvm::sys::fs::exists(rootmapName)) {
7300 if (gDebug > 0)
7301 Info("Load", "loading %s", rootmapName.c_str());
7302 gInterpreter->LoadLibraryMap(rootmapName.c_str());
7303 }
7304 }
7305
7306 if (hasPrecomputedLibraryDeps(lib) && useDyld) {
7307 if (gDebug > 0)
7308 Warning("TCling::GetSharedLibDeps", "Precomputed dependencies available but scanning '%s'", lib);
7309 }
7310
7311 if (useDyld) {
7312 std::string libs = GetSharedLibImmediateDepsSlow(lib, GetInterpreterImpl());
7313 if (!libs.empty()) {
7314 fAutoLoadLibStorage.push_back(libs);
7315 return fAutoLoadLibStorage.back().c_str();
7316 }
7317 }
7318
7319 if (!fMapfile || !lib || !lib[0]) {
7320 return nullptr;
7321 }
7322 TString libname(lib);
7323 Ssiz_t idx = libname.Last('.');
7324 if (idx != kNPOS) {
7325 libname.Remove(idx);
7326 }
7327 TEnvRec* rec;
7328 TIter next(fMapfile->GetTable());
7329 size_t len = libname.Length();
7330 while ((rec = (TEnvRec*) next())) {
7331 const char* libs = rec->GetValue();
7332 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7333 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
7334 return libs;
7335 }
7336 }
7337 return nullptr;
7338}
7339
7340////////////////////////////////////////////////////////////////////////////////
7341/// If error messages are disabled, the interpreter should suppress its
7342/// failures and warning messages from stdout.
7343
7345{
7346#if defined(R__MUST_REVISIT)
7347#if R__MUST_REVISIT(6,2)
7348 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
7349#endif
7350#endif
7351 return kTRUE;
7352}
7353
7354////////////////////////////////////////////////////////////////////////////////
7355/// If error messages are disabled, the interpreter should suppress its
7356/// failures and warning messages from stdout. Return the previous state.
7357
7359{
7360#if defined(R__MUST_REVISIT)
7361#if R__MUST_REVISIT(6,2)
7362 Warning("SetErrorMessages", "Interface not available yet.");
7363#endif
7364#endif
7366}
7367
7368////////////////////////////////////////////////////////////////////////////////
7369/// Refresh the list of include paths known to the interpreter and return it
7370/// with -I prepended.
7371
7373{
7375
7376 fIncludePath = "";
7377
7378 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7379 //false - no system header, true - with flags.
7380 fInterpreter->GetIncludePaths(includePaths, false, true);
7381 if (const size_t nPaths = includePaths.size()) {
7382 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
7383
7384 for (size_t i = 0; i < nPaths; i += 2) {
7385 if (i)
7386 fIncludePath.Append(' ');
7387 fIncludePath.Append(includePaths[i].c_str());
7388
7389 if (includePaths[i] != "-I")
7390 fIncludePath.Append(' ');
7391 fIncludePath.Append('"');
7392 fIncludePath.Append(includePaths[i + 1], includePaths[i + 1].length());
7393 fIncludePath.Append('"');
7394 }
7395 }
7396
7397 return fIncludePath;
7398}
7399
7400////////////////////////////////////////////////////////////////////////////////
7401/// Return the directory containing CINT's stl cintdlls.
7402
7403const char* TCling::GetSTLIncludePath() const
7404{
7405 return "";
7406}
7407
7408//______________________________________________________________________________
7409// M I S C
7410//______________________________________________________________________________
7411
7412int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
7413{
7414 // Interface to cling function
7415 return 0;
7416}
7417
7418////////////////////////////////////////////////////////////////////////////////
7419/// Interface to cling function
7420
7421int TCling::DisplayIncludePath(FILE *fout) const
7422{
7423 assert(fout != nullptr && "DisplayIncludePath, 'fout' parameter is null");
7424
7425 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7426 //false - no system header, true - with flags.
7427 fInterpreter->GetIncludePaths(includePaths, false, true);
7428 if (const size_t nPaths = includePaths.size()) {
7429 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
7430
7431 std::string allIncludes("include path:");
7432 for (size_t i = 0; i < nPaths; i += 2) {
7433 allIncludes += ' ';
7434 allIncludes += includePaths[i];
7435
7436 if (includePaths[i] != "-I")
7437 allIncludes += ' ';
7438 allIncludes += includePaths[i + 1];
7439 }
7440
7441 fprintf(fout, "%s\n", allIncludes.c_str());
7442 }
7443
7444 return 0;
7445}
7446
7447////////////////////////////////////////////////////////////////////////////////
7448/// Interface to cling function
7449
7450void* TCling::FindSym(const char* entry) const
7451{
7453 return fInterpreter->getAddressOfGlobal(entry);
7454}
7455
7456////////////////////////////////////////////////////////////////////////////////
7457/// Let the interpreter issue a generic error, and set its error state.
7458
7459void TCling::GenericError(const char* error) const
7460{
7461#if defined(R__MUST_REVISIT)
7462#if R__MUST_REVISIT(6,2)
7463 Warning("GenericError","Interface not available yet.");
7464#endif
7465#endif
7466}
7467
7468////////////////////////////////////////////////////////////////////////////////
7469/// This routines used to return the address of the internal wrapper
7470/// function (of the interpreter) that was used to call *all* the
7471/// interpreted functions that were bytecode compiled (no longer
7472/// interpreted line by line). In Cling, there is no such
7473/// wrapper function.
7474/// In practice this routines was use to decipher whether the
7475/// pointer returns by InterfaceMethod could be used to uniquely
7476/// represent the function. In Cling if the function is in a
7477/// useable state (its compiled version is available), this is
7478/// always the case.
7479/// See TClass::GetMethod.
7480
7482{
7483 return 0;
7484}
7485
7486////////////////////////////////////////////////////////////////////////////////
7487/// Interface to cling function
7488
7490{
7491#if defined(R__MUST_REVISIT)
7492#if R__MUST_REVISIT(6,2)
7493 Warning("GetSecurityError", "Interface not available yet.");
7494#endif
7495#endif
7496 return 0;
7497}
7498
7499////////////////////////////////////////////////////////////////////////////////
7500/// Load a source file or library called path into the interpreter.
7501
7502int TCling::LoadFile(const char* path) const
7503{
7504 // Modifying the interpreter state needs locking.
7506 cling::Interpreter::CompilationResult compRes;
7507 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(".L %s", path), compRes, /*cling::Value*/nullptr);
7508 return compRes == cling::Interpreter::kFailure;
7509}
7510
7511////////////////////////////////////////////////////////////////////////////////
7512/// Load the declarations from text into the interpreter.
7513/// Note that this cannot be (top level) statements; text must contain
7514/// top level declarations.
7515/// Returns true on success, false on failure.
7516
7517Bool_t TCling::LoadText(const char* text) const
7518{
7519 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7520}
7521
7522////////////////////////////////////////////////////////////////////////////////
7523/// Interface to cling function
7524
7525const char* TCling::MapCppName(const char* name) const
7526{
7527 TTHREAD_TLS_DECL(std::string,buffer);
7529 return buffer.c_str(); // NOLINT
7530}
7531
7532////////////////////////////////////////////////////////////////////////////////
7533/// [Place holder for Mutex Lock]
7534/// Provide the interpreter with a way to
7535/// acquire a lock used to protect critical section
7536/// of its code (non-thread safe parts).
7537
7538void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7539{
7540 // nothing to do for now.
7541}
7542
7543////////////////////////////////////////////////////////////////////////////////
7544/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7545/// release a lock used to protect critical section
7546/// of its code (non-thread safe parts).
7547
7548void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7549{
7550 // nothing to do for now.
7551}
7552
7553////////////////////////////////////////////////////////////////////////////////
7554/// Returns if class AutoLoading is currently enabled.
7555
7557{
7558 if (IsFromRootCling())
7559 return false;
7560 if (!fClingCallbacks)
7561 return false;
7563}
7564
7565////////////////////////////////////////////////////////////////////////////////
7566/// Enable/Disable the AutoLoading of libraries.
7567/// Returns the old value, i.e whether it was enabled or not.
7568
7569int TCling::SetClassAutoLoading(int autoload) const
7570{
7571 // If no state change is required, exit early.
7572 // FIXME: In future we probably want to complain if we made a request which
7573 // was with the same state as before in order to catch programming errors.
7574 if ((bool) autoload == IsClassAutoLoadingEnabled())
7575 return autoload;
7576
7577 assert(fClingCallbacks && "We must have callbacks!");
7578 bool oldVal = fClingCallbacks->IsAutoLoadingEnabled();
7580 return oldVal;
7581}
7582
7583////////////////////////////////////////////////////////////////////////////////
7584/// Enable/Disable the Autoparsing of headers.
7585/// Returns the old value, i.e whether it was enabled or not.
7586
7588{
7589 bool oldVal = fHeaderParsingOnDemand;
7590 fHeaderParsingOnDemand = autoparse;
7591 return oldVal;
7592}
7593
7594////////////////////////////////////////////////////////////////////////////////
7595/// Suspend the Autoparsing of headers.
7596/// Returns the old value, i.e whether it was suspended or not.
7597
7602 return old;
7603}
7604
7605////////////////////////////////////////////////////////////////////////////////
7606/// Set a callback to receive error messages.
7607
7609{
7610#if defined(R__MUST_REVISIT)
7611#if R__MUST_REVISIT(6,2)
7612 Warning("SetErrmsgcallback", "Interface not available yet.");
7613#endif
7614#endif
7615}
7616
7618{
7619 if (enable) {
7620 auto consumer = new TClingDelegateDiagnosticPrinter(
7621 &fInterpreter->getDiagnostics().getDiagnosticOptions(),
7622 fInterpreter->getCI()->getLangOpts(),
7623 [] (clang::DiagnosticsEngine::Level Level, const std::string &Info) {
7624 if (Level == clang::DiagnosticsEngine::Warning) {
7625 ::Warning("cling", "%s", Info.c_str());
7626 } else if (Level == clang::DiagnosticsEngine::Error
7627 || Level == clang::DiagnosticsEngine::Fatal) {
7628 ::Error("cling", "%s", Info.c_str());
7629 } else {
7630 ::Info("cling", "%s", Info.c_str());
7631 }
7632 });
7633 fInterpreter->replaceDiagnosticConsumer(consumer, /*Own=*/true);
7634 } else {
7635 fInterpreter->replaceDiagnosticConsumer(nullptr);
7636 }
7637}
7638
7639
7640////////////////////////////////////////////////////////////////////////////////
7641/// Create / close a scope for temporaries. No-op for cling; use
7642/// cling::Value instead.
7643
7644void TCling::SetTempLevel(int val) const
7645{
7646}
7647
7648////////////////////////////////////////////////////////////////////////////////
7649
7650int TCling::UnloadFile(const char* path) const
7651{
7652 // Modifying the interpreter state needs locking.
7654 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7655 std::string canonical = DLM->lookupLibrary(path);
7656 if (canonical.empty()) {
7657 canonical = path;
7658 }
7659 // Unload a shared library or a source file.
7660 cling::Interpreter::CompilationResult compRes;
7661 HandleInterpreterException(GetMetaProcessorImpl(), Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/nullptr);
7662 return compRes == cling::Interpreter::kFailure;
7663}
7664
7665std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7666 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7667}
7668
7669////////////////////////////////////////////////////////////////////////////////
7670/// The call to Cling's tab complition.
7671
7672void TCling::CodeComplete(const std::string& line, size_t& cursor,
7673 std::vector<std::string>& completions)
7674{
7675 fInterpreter->codeComplete(line, cursor, completions);
7676}
7677
7678////////////////////////////////////////////////////////////////////////////////
7679/// Get the interpreter value corresponding to the statement.
7681{
7682 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7683 auto compRes = fInterpreter->evaluate(code, *V);
7684 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7685}
7686
7687////////////////////////////////////////////////////////////////////////////////
7688
7690{
7691 using namespace cling;
7692 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7694}
7695
7696////////////////////////////////////////////////////////////////////////////////
7697/// Register value as a temporary, extending its lifetime to that of the
7698/// interpreter. This is needed for TCling's compatibility interfaces
7699/// returning long - the address of the temporary objects.
7700/// As such, "simple" types don't need to be stored; they are returned by
7701/// value; only pointers / references / objects need to be stored.
7702
7703void TCling::RegisterTemporary(const cling::Value& value)
7704{
7705 if (value.isValid() && value.needsManagedAllocation()) {
7707 fTemporaries->push_back(value);
7708 }
7709}
7710
7711////////////////////////////////////////////////////////////////////////////////
7712/// If the interpreter encounters Name, check whether that is an object ROOT
7713/// could retrieve. To not re-read objects from disk, cache the name/object
7714/// pair for a given LookupCtx.
7715
7716TObject* TCling::GetObjectAddress(const char *Name, void *&LookupCtx)
7717{
7718 // The call to FindSpecialObject might induces any kind of use
7719 // of the interpreter ... (library loading, function calling, etc.)
7720 // ... and we _know_ we are in the middle of parsing, so let's make
7721 // sure to save the state and then restore it.
7722
7723 if (gDirectory) {
7724 auto iSpecObjMap = fSpecialObjectMaps.find(gDirectory);
7725 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7726 auto iSpecObj = iSpecObjMap->second.find(Name);
7727 if (iSpecObj != iSpecObjMap->second.end()) {
7728 LookupCtx = gDirectory;
7729 return iSpecObj->second;
7730 }
7731 }
7732 }
7733
7734 // Save state of the PP
7735 Sema &SemaR = fInterpreter->getSema();
7736 ASTContext& C = SemaR.getASTContext();
7737 Preprocessor &PP = SemaR.getPreprocessor();
7738 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7739 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7740 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7741 // After we have saved the token reset the current one to something which
7742 // is safe (semi colon usually means empty decl)
7743 Token& Tok = const_cast<Token&>(P.getCurToken());
7744 Tok.setKind(tok::semi);
7745
7746 // We can't PushDeclContext, because we go up and the routine that pops
7747 // the DeclContext assumes that we drill down always.
7748 // We have to be on the global context. At that point we are in a
7749 // wrapper function so the parent context must be the global.
7750 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7751 SemaR.TUScope);
7752
7753 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7754 if (specObj) {
7755 if (!LookupCtx) {
7756 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7757 } else {
7758 fSpecialObjectMaps[LookupCtx][Name] = specObj;
7759 }
7760 }
7761 return specObj;
7762}
7763
7764////////////////////////////////////////////////////////////////////////////////
7765/// Inject function as a friend into klass.
7766/// With function being f in void f() {new N::PrivKlass(); } this enables
7767/// I/O of non-public classes.
7768
7769void TCling::AddFriendToClass(clang::FunctionDecl* function,
7770 clang::CXXRecordDecl* klass) const
7771{
7772 using namespace clang;
7773 ASTContext& Ctx = klass->getASTContext();
7774 FriendDecl::FriendUnion friendUnion(function);
7775 // one dummy object for the source location
7776 SourceLocation sl;
7777 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
7778 klass->pushFriendDecl(friendDecl);
7779}
7780
7781//______________________________________________________________________________
7782//
7783// DeclId getter.
7784//
7785
7786////////////////////////////////////////////////////////////////////////////////
7787/// Return a unique identifier of the declaration represented by the
7788/// CallFunc
7789
7791{
7792 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
7793 return nullptr;
7794}
7795
7796////////////////////////////////////////////////////////////////////////////////
7797/// Return a (almost) unique identifier of the declaration represented by the
7798/// ClassInfo. In ROOT, this identifier can point to more than one TClass
7799/// when the underlying class is a template instance involving one of the
7800/// opaque typedef.
7801
7803{
7804 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
7805 return nullptr;
7806}
7807
7808////////////////////////////////////////////////////////////////////////////////
7809/// Return a unique identifier of the declaration represented by the
7810/// MethodInfo
7811
7813{
7814 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
7815 return nullptr;
7816}
7817
7818////////////////////////////////////////////////////////////////////////////////
7819/// Return a unique identifier of the declaration represented by the
7820/// MethodInfo
7821
7823{
7824 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
7825 return nullptr;
7826}
7827
7828////////////////////////////////////////////////////////////////////////////////
7829/// Return a unique identifier of the declaration represented by the
7830/// TypedefInfo
7831
7833{
7834 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
7835 return nullptr;
7836}
7837
7838//______________________________________________________________________________
7839//
7840// CallFunc interface
7841//
7842
7843////////////////////////////////////////////////////////////////////////////////
7844
7845void TCling::CallFunc_Delete(CallFunc_t* func) const
7846{
7847 delete (TClingCallFunc*) func;
7848}
7849
7850////////////////////////////////////////////////////////////////////////////////
7851
7852void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
7853{
7854 TClingCallFunc* f = (TClingCallFunc*) func;
7855 f->Exec(address);
7856}
7857
7858////////////////////////////////////////////////////////////////////////////////
7859
7860void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
7861{
7862 TClingCallFunc* f = (TClingCallFunc*) func;
7863 f->Exec(address, &val);
7864}
7865
7866////////////////////////////////////////////////////////////////////////////////
7867
7868void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
7869{
7870 TClingCallFunc* f = (TClingCallFunc*) func;
7871 f->ExecWithReturn(address, ret);
7872}
7873
7874////////////////////////////////////////////////////////////////////////////////
7875
7876void TCling::CallFunc_ExecWithArgsAndReturn(CallFunc_t* func, void* address,
7877 const void* args[] /*=0*/,
7878 int nargs /*=0*/,
7879 void* ret/*=0*/) const
7880{
7881 TClingCallFunc* f = (TClingCallFunc*) func;
7882 f->ExecWithArgsAndReturn(address, args, nargs, ret);
7883}
7884
7885////////////////////////////////////////////////////////////////////////////////
7886
7887Longptr_t TCling::CallFunc_ExecInt(CallFunc_t* func, void* address) const
7888{
7889 TClingCallFunc* f = (TClingCallFunc*) func;
7890 return f->ExecInt(address);
7891}
7892
7893////////////////////////////////////////////////////////////////////////////////
7894
7895Long64_t TCling::CallFunc_ExecInt64(CallFunc_t* func, void* address) const
7896{
7897 TClingCallFunc* f = (TClingCallFunc*) func;
7898 return f->ExecInt64(address);
7899}
7900
7901////////////////////////////////////////////////////////////////////////////////
7902
7903Double_t TCling::CallFunc_ExecDouble(CallFunc_t* func, void* address) const
7904{
7905 TClingCallFunc* f = (TClingCallFunc*) func;
7906 return f->ExecDouble(address);
7907}
7908
7909////////////////////////////////////////////////////////////////////////////////
7910
7911CallFunc_t* TCling::CallFunc_Factory() const
7912{
7914 return (CallFunc_t*) new TClingCallFunc(GetInterpreterImpl());
7915}
7916
7917////////////////////////////////////////////////////////////////////////////////
7918
7919CallFunc_t* TCling::CallFunc_FactoryCopy(CallFunc_t* func) const
7920{
7921 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
7922}
7923
7924////////////////////////////////////////////////////////////////////////////////
7925
7926MethodInfo_t* TCling::CallFunc_FactoryMethod(CallFunc_t* func) const
7927{
7928 TClingCallFunc* f = (TClingCallFunc*) func;
7929 return (MethodInfo_t*) f->FactoryMethod();
7930}
7931
7932////////////////////////////////////////////////////////////////////////////////
7933
7934void TCling::CallFunc_IgnoreExtraArgs(CallFunc_t* func, bool ignore) const
7935{
7936 TClingCallFunc* f = (TClingCallFunc*) func;
7937 f->IgnoreExtraArgs(ignore);
7938}
7939
7940////////////////////////////////////////////////////////////////////////////////
7941
7942void TCling::CallFunc_Init(CallFunc_t* func) const
7943{
7945 TClingCallFunc* f = (TClingCallFunc*) func;
7946 f->Init();
7947}
7948
7949////////////////////////////////////////////////////////////////////////////////
7950
7951bool TCling::CallFunc_IsValid(CallFunc_t* func) const
7952{
7953 TClingCallFunc* f = (TClingCallFunc*) func;
7954 return f->IsValid();
7955}
7956
7957////////////////////////////////////////////////////////////////////////////////
7958
7960TCling::CallFunc_IFacePtr(CallFunc_t * func) const
7961{
7962 TClingCallFunc* f = (TClingCallFunc*) func;
7963 return f->IFacePtr();
7964}
7965
7966////////////////////////////////////////////////////////////////////////////////
7967
7968void TCling::CallFunc_ResetArg(CallFunc_t* func) const
7969{
7970 TClingCallFunc* f = (TClingCallFunc*) func;
7971 f->ResetArg();
7972}
7973
7974////////////////////////////////////////////////////////////////////////////////
7975
7976void TCling::CallFunc_SetArg(CallFunc_t* func, Long_t param) const
7977{
7978 TClingCallFunc* f = (TClingCallFunc*) func;
7979 f->SetArg(param);
7980}
7981
7982////////////////////////////////////////////////////////////////////////////////
7983
7984void TCling::CallFunc_SetArg(CallFunc_t* func, ULong_t param) const
7985{
7986 TClingCallFunc* f = (TClingCallFunc*) func;
7987 f->SetArg(param);
7988}
7989
7990////////////////////////////////////////////////////////////////////////////////
7991
7992void TCling::CallFunc_SetArg(CallFunc_t* func, Float_t param) const
7993{
7994 TClingCallFunc* f = (TClingCallFunc*) func;
7995 f->SetArg(param);
7996}
7997
7998////////////////////////////////////////////////////////////////////////////////
7999
8000void TCling::CallFunc_SetArg(CallFunc_t* func, Double_t param) const
8001{
8002 TClingCallFunc* f = (TClingCallFunc*) func;
8003 f->SetArg(param);
8004}
8005
8006////////////////////////////////////////////////////////////////////////////////
8007
8008void TCling::CallFunc_SetArg(CallFunc_t* func, Long64_t param) const
8009{
8010 TClingCallFunc* f = (TClingCallFunc*) func;
8011 f->SetArg(param);
8012}
8013
8014////////////////////////////////////////////////////////////////////////////////
8015
8016void TCling::CallFunc_SetArg(CallFunc_t* func, ULong64_t param) const
8017{
8018 TClingCallFunc* f = (TClingCallFunc*) func;
8019 f->SetArg(param);
8020}
8021
8022////////////////////////////////////////////////////////////////////////////////
8023
8024void TCling::CallFunc_SetArgArray(CallFunc_t* func, Longptr_t* paramArr, Int_t nparam) const
8025{
8026 TClingCallFunc* f = (TClingCallFunc*) func;
8027 f->SetArgArray(paramArr, nparam);
8028}
8029
8030////////////////////////////////////////////////////////////////////////////////
8031
8032void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
8033{
8034 TClingCallFunc* f = (TClingCallFunc*) func;
8035 f->SetArgs(param);
8036}
8037
8038////////////////////////////////////////////////////////////////////////////////
8039
8040void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Longptr_t* offset) const
8041{
8042 TClingCallFunc* f = (TClingCallFunc*) func;
8043 TClingClassInfo* ci = (TClingClassInfo*) info;
8044 f->SetFunc(ci, method, params, offset);
8045}
8046
8047////////////////////////////////////////////////////////////////////////////////
8048
8049void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Longptr_t* offset) const
8050{
8051 TClingCallFunc* f = (TClingCallFunc*) func;
8052 TClingClassInfo* ci = (TClingClassInfo*) info;
8053 f->SetFunc(ci, method, params, objectIsConst, offset);
8054}
8055////////////////////////////////////////////////////////////////////////////////
8056
8057void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
8058{
8059 TClingCallFunc* f = (TClingCallFunc*) func;
8060 TClingMethodInfo* minfo = (TClingMethodInfo*) info;
8061 f->SetFunc(minfo);
8062}
8063
8064////////////////////////////////////////////////////////////////////////////////
8065/// Interface to cling function
8066
8067void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8068{
8069 TClingCallFunc* f = (TClingCallFunc*) func;
8070 TClingClassInfo* ci = (TClingClassInfo*) info;
8071 f->SetFuncProto(ci, method, proto, offset, mode);
8072}
8073
8074////////////////////////////////////////////////////////////////////////////////
8075/// Interface to cling function
8076
8077void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8078{
8079 TClingCallFunc* f = (TClingCallFunc*) func;
8080 TClingClassInfo* ci = (TClingClassInfo*) info;
8081 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
8082}
8083
8084////////////////////////////////////////////////////////////////////////////////
8085/// Interface to cling function
8086
8087void 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
8088{
8089 TClingCallFunc* f = (TClingCallFunc*) func;
8090 TClingClassInfo* ci = (TClingClassInfo*) info;
8091 llvm::SmallVector<clang::QualType, 4> funcProto;
8092 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8093 iter != end; ++iter) {
8094 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8095 }
8096 f->SetFuncProto(ci, method, funcProto, offset, mode);
8097}
8098
8099////////////////////////////////////////////////////////////////////////////////
8100/// Interface to cling function
8101
8102void 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
8103{
8104 TClingCallFunc* f = (TClingCallFunc*) func;
8105 TClingClassInfo* ci = (TClingClassInfo*) info;
8106 llvm::SmallVector<clang::QualType, 4> funcProto;
8107 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8108 iter != end; ++iter) {
8109 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8110 }
8111 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
8112}
8113
8114std::string TCling::CallFunc_GetWrapperCode(CallFunc_t *func) const
8115{
8116 TClingCallFunc *f = (TClingCallFunc *)func;
8117 std::string wrapper_name;
8118 std::string wrapper;
8119 f->get_wrapper_code(wrapper_name, wrapper);
8120 return wrapper;
8121}
8122
8123//______________________________________________________________________________
8124//
8125// ClassInfo interface
8126//
8127
8128////////////////////////////////////////////////////////////////////////////////
8129/// Return true if the entity pointed to by 'declid' is declared in
8130/// the context described by 'info'. If info is null, look into the
8131/// global scope (translation unit scope).
8132
8133Bool_t TCling::ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const
8134{
8135 if (!declid)
8136 return kFALSE;
8137
8138 const clang::DeclContext *ctxt = nullptr;
8139 if (info) {
8140 ctxt = clang::Decl::castToDeclContext(((TClingClassInfo*)info)->GetDecl());
8141 } else {
8142 ctxt = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
8143 }
8144 if (!ctxt)
8145 return kFALSE;
8146
8147 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
8148 if (!decl)
8149 return kFALSE;
8150
8151 const clang::DeclContext *declDC = decl->getDeclContext();
8152 // ClassInfo_t-s are always "spellable" scopes, never unnamed or inline ones.
8153 while (true) {
8154 if (declDC->isTransparentContext()) {
8155 declDC = declDC->getParent();
8156 continue;
8157 }
8158 if (const auto *declRD = llvm::dyn_cast<clang::RecordDecl>(declDC)) {
8159 if (declRD->isAnonymousStructOrUnion()) {
8160 declDC = declRD->getParent();
8161 continue;
8162 }
8163 }
8164 if (const auto *declNS = llvm::dyn_cast<clang::NamespaceDecl>(declDC)) {
8165 if (declNS->isAnonymousNamespace() || declNS->isInlineNamespace()) {
8166 declDC = declNS->getParent();
8167 continue;
8168 }
8169 }
8170 break;
8171 }
8172
8173 return declDC->Equals(ctxt);
8174}
8175
8176////////////////////////////////////////////////////////////////////////////////
8177
8179{
8180 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8181 return TClinginfo->ClassProperty();
8182}
8183
8184////////////////////////////////////////////////////////////////////////////////
8185
8186void TCling::ClassInfo_Delete(ClassInfo_t* cinfo) const
8187{
8188 delete (TClingClassInfo*) cinfo;
8189}
8190
8191////////////////////////////////////////////////////////////////////////////////
8192
8193void TCling::ClassInfo_Delete(ClassInfo_t* cinfo, void* arena) const
8194{
8195 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8196 TClinginfo->Delete(arena,*fNormalizedCtxt);
8197}
8198
8199////////////////////////////////////////////////////////////////////////////////
8200
8201void TCling::ClassInfo_DeleteArray(ClassInfo_t* cinfo, void* arena, bool dtorOnly) const
8202{
8203 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8204 TClinginfo->DeleteArray(arena, dtorOnly,*fNormalizedCtxt);
8205}
8206
8207////////////////////////////////////////////////////////////////////////////////
8208
8209void TCling::ClassInfo_Destruct(ClassInfo_t* cinfo, void* arena) const
8210{
8211 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8212 TClinginfo->Destruct(arena,*fNormalizedCtxt);
8213}
8214
8215////////////////////////////////////////////////////////////////////////////////
8216
8217ClassInfo_t* TCling::ClassInfo_Factory(Bool_t all) const
8218{
8220 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), all);
8221}
8222
8223////////////////////////////////////////////////////////////////////////////////
8224
8225ClassInfo_t* TCling::ClassInfo_Factory(ClassInfo_t* cinfo) const
8226{
8227 return (ClassInfo_t*) new TClingClassInfo(*(TClingClassInfo*)cinfo);
8228}
8229
8230////////////////////////////////////////////////////////////////////////////////
8231
8232ClassInfo_t* TCling::ClassInfo_Factory(const char* name) const
8233{
8235 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), name);
8236}
8237
8238ClassInfo_t* TCling::ClassInfo_Factory(DeclId_t declid) const
8239{
8241 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), (const clang::Decl*)declid);
8242}
8243
8244
8245////////////////////////////////////////////////////////////////////////////////
8246
8247int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
8248{
8249 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8250 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
8251}
8252
8253////////////////////////////////////////////////////////////////////////////////
8254
8255bool TCling::ClassInfo_HasDefaultConstructor(ClassInfo_t* cinfo, Bool_t testio) const
8256{
8257 TClingClassInfo *TClinginfo = (TClingClassInfo *) cinfo;
8259}
8260
8261////////////////////////////////////////////////////////////////////////////////
8262
8263bool TCling::ClassInfo_HasMethod(ClassInfo_t* cinfo, const char* name) const
8264{
8265 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8266 return TClinginfo->HasMethod(name);
8267}
8268
8269////////////////////////////////////////////////////////////////////////////////
8270
8271void TCling::ClassInfo_Init(ClassInfo_t* cinfo, const char* name) const
8272{
8274 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8275 TClinginfo->Init(name);
8276}
8277
8278////////////////////////////////////////////////////////////////////////////////
8279
8280void TCling::ClassInfo_Init(ClassInfo_t* cinfo, int tagnum) const
8281{
8283 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8284 TClinginfo->Init(tagnum);
8285}
8286
8287////////////////////////////////////////////////////////////////////////////////
8288
8289bool TCling::ClassInfo_IsBase(ClassInfo_t* cinfo, const char* name) const
8290{
8291 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8292 return TClinginfo->IsBase(name);
8293}
8294
8295////////////////////////////////////////////////////////////////////////////////
8296
8297bool TCling::ClassInfo_IsEnum(const char* name) const
8298{
8300}
8301
8302////////////////////////////////////////////////////////////////////////////////
8303
8305{
8306 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8307 return TClinginfo->IsScopedEnum();
8308}
8309
8310
8311////////////////////////////////////////////////////////////////////////////////
8312
8314{
8315 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8316 return TClinginfo->GetUnderlyingType();
8317}
8318
8319
8320////////////////////////////////////////////////////////////////////////////////
8321
8322bool TCling::ClassInfo_IsLoaded(ClassInfo_t* cinfo) const
8323{
8324 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8325 return TClinginfo->IsLoaded();
8326}
8327
8328////////////////////////////////////////////////////////////////////////////////
8329
8330bool TCling::ClassInfo_IsValid(ClassInfo_t* cinfo) const
8331{
8332 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8333 return TClinginfo->IsValid();
8334}
8335
8336////////////////////////////////////////////////////////////////////////////////
8337
8338bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8339{
8340 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8341 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
8342}
8343
8344////////////////////////////////////////////////////////////////////////////////
8345
8346bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst, Longptr_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8347{
8348 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8349 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8350}
8351
8352////////////////////////////////////////////////////////////////////////////////
8353
8354int TCling::ClassInfo_Next(ClassInfo_t* cinfo) const
8355{
8356 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8357 return TClinginfo->Next();
8358}
8359
8360////////////////////////////////////////////////////////////////////////////////
8361
8362void* TCling::ClassInfo_New(ClassInfo_t* cinfo) const
8363{
8364 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8365 return TClinginfo->New(*fNormalizedCtxt);
8366}
8367
8368////////////////////////////////////////////////////////////////////////////////
8369
8370void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n) const
8371{
8372 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8373 return TClinginfo->New(n,*fNormalizedCtxt);
8374}
8375
8376////////////////////////////////////////////////////////////////////////////////
8377
8378void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n, void* arena) const
8379{
8380 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8381 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8382}
8383
8384////////////////////////////////////////////////////////////////////////////////
8385
8386void* TCling::ClassInfo_New(ClassInfo_t* cinfo, void* arena) const
8387{
8388 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8389 return TClinginfo->New(arena,*fNormalizedCtxt);
8390}
8391
8392////////////////////////////////////////////////////////////////////////////////
8393
8394Long_t TCling::ClassInfo_Property(ClassInfo_t* cinfo) const
8395{
8396 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8397 return TClinginfo->Property();
8398}
8399
8400////////////////////////////////////////////////////////////////////////////////
8401
8402int TCling::ClassInfo_Size(ClassInfo_t* cinfo) const
8403{
8404 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8405 return TClinginfo->Size();
8406}
8407
8408////////////////////////////////////////////////////////////////////////////////
8409
8410Longptr_t TCling::ClassInfo_Tagnum(ClassInfo_t* cinfo) const
8411{
8412 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8413 return TClinginfo->Tagnum();
8414}
8415
8416////////////////////////////////////////////////////////////////////////////////
8417
8418const char* TCling::ClassInfo_FileName(ClassInfo_t* cinfo) const
8419{
8420 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8421 return TClinginfo->FileName();
8422}
8423
8424////////////////////////////////////////////////////////////////////////////////
8425
8426const char* TCling::ClassInfo_FullName(ClassInfo_t* cinfo) const
8427{
8428 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8429 TTHREAD_TLS_DECL(std::string,output);
8430 TClinginfo->FullName(output,*fNormalizedCtxt);
8431 return output.c_str(); // NOLINT
8432}
8433
8434////////////////////////////////////////////////////////////////////////////////
8435
8436const char* TCling::ClassInfo_Name(ClassInfo_t* cinfo) const
8437{
8438 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8439 return TClinginfo->Name();
8440}
8441
8442////////////////////////////////////////////////////////////////////////////////
8443
8444const char* TCling::ClassInfo_Title(ClassInfo_t* cinfo) const
8445{
8446 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8447 return TClinginfo->Title();
8448}
8449
8450////////////////////////////////////////////////////////////////////////////////
8451
8452const char* TCling::ClassInfo_TmpltName(ClassInfo_t* cinfo) const
8453{
8454 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8455 return TClinginfo->TmpltName();
8456}
8457
8458
8459
8460//______________________________________________________________________________
8461//
8462// BaseClassInfo interface
8463//
8464
8465////////////////////////////////////////////////////////////////////////////////
8466
8467void TCling::BaseClassInfo_Delete(BaseClassInfo_t* bcinfo) const
8468{
8469 delete(TClingBaseClassInfo*) bcinfo;
8470}
8471
8472////////////////////////////////////////////////////////////////////////////////
8473
8474BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo) const
8475{
8477 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8478 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo);
8479}
8480
8481////////////////////////////////////////////////////////////////////////////////
8482
8483BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* derived,
8484 ClassInfo_t* base) const
8485{
8487 TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
8488 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) base;
8489 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo, TClinginfoBase);
8490}
8491
8492////////////////////////////////////////////////////////////////////////////////
8493
8494int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo) const
8495{
8496 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8497 return TClinginfo->Next();
8498}
8499
8500////////////////////////////////////////////////////////////////////////////////
8501
8502int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo, int onlyDirect) const
8503{
8504 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8505 return TClinginfo->Next(onlyDirect);
8506}
8507
8508////////////////////////////////////////////////////////////////////////////////
8509
8510Longptr_t TCling::BaseClassInfo_Offset(BaseClassInfo_t* toBaseClassInfo, void * address, bool isDerivedObject) const
8511{
8512 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) toBaseClassInfo;
8513 return TClinginfo->Offset(address, isDerivedObject);
8514}
8515
8516////////////////////////////////////////////////////////////////////////////////
8517
8518Longptr_t TCling::ClassInfo_GetBaseOffset(ClassInfo_t* fromDerived, ClassInfo_t* toBase, void * address, bool isDerivedObject) const
8519{
8520 TClingClassInfo* TClinginfo = (TClingClassInfo*) fromDerived;
8521 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) toBase;
8522 // Offset to the class itself.
8523 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8524 return 0;
8525 }
8526 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8527}
8528
8529////////////////////////////////////////////////////////////////////////////////
8530
8531Long_t TCling::BaseClassInfo_Property(BaseClassInfo_t* bcinfo) const
8532{
8533 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8534 return TClinginfo->Property();
8535}
8536
8537////////////////////////////////////////////////////////////////////////////////
8538
8539ClassInfo_t *TCling::BaseClassInfo_ClassInfo(BaseClassInfo_t *bcinfo) const
8540{
8541 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8542 return (ClassInfo_t *)TClinginfo->GetBase();
8543}
8544
8545////////////////////////////////////////////////////////////////////////////////
8546
8547Longptr_t TCling::BaseClassInfo_Tagnum(BaseClassInfo_t* bcinfo) const
8548{
8549 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8550 return TClinginfo->Tagnum();
8551}
8552
8553////////////////////////////////////////////////////////////////////////////////
8554
8555const char* TCling::BaseClassInfo_FullName(BaseClassInfo_t* bcinfo) const
8556{
8557 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8558 TTHREAD_TLS_DECL(std::string,output);
8559 TClinginfo->FullName(output,*fNormalizedCtxt);
8560 return output.c_str(); // NOLINT
8561}
8562
8563////////////////////////////////////////////////////////////////////////////////
8564
8565const char* TCling::BaseClassInfo_Name(BaseClassInfo_t* bcinfo) const
8566{
8567 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8568 return TClinginfo->Name();
8569}
8570
8571////////////////////////////////////////////////////////////////////////////////
8572
8573const char* TCling::BaseClassInfo_TmpltName(BaseClassInfo_t* bcinfo) const
8574{
8575 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8576 return TClinginfo->TmpltName();
8577}
8578
8579//______________________________________________________________________________
8580//
8581// DataMemberInfo interface
8582//
8583
8584////////////////////////////////////////////////////////////////////////////////
8585
8586int TCling::DataMemberInfo_ArrayDim(DataMemberInfo_t* dminfo) const
8587{
8588 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8589 return TClinginfo->ArrayDim();
8590}
8591
8592////////////////////////////////////////////////////////////////////////////////
8593
8594void TCling::DataMemberInfo_Delete(DataMemberInfo_t* dminfo) const
8595{
8596 delete(TClingDataMemberInfo*) dminfo;
8597}
8598
8599////////////////////////////////////////////////////////////////////////////////
8600
8601DataMemberInfo_t* TCling::DataMemberInfo_Factory(ClassInfo_t* clinfo, TDictionary::EMemberSelection selection) const
8602{
8604 TClingClassInfo* TClingclass_info = (TClingClassInfo*) clinfo;
8605 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), TClingclass_info, selection);
8606}
8607
8608////////////////////////////////////////////////////////////////////////////////
8609
8610DataMemberInfo_t* TCling::DataMemberInfo_Factory(DeclId_t declid, ClassInfo_t* clinfo) const
8611{
8613 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8614 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8615 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), vd, (TClingClassInfo*)clinfo);
8616}
8617
8618////////////////////////////////////////////////////////////////////////////////
8619
8620DataMemberInfo_t* TCling::DataMemberInfo_FactoryCopy(DataMemberInfo_t* dminfo) const
8621{
8622 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8623 return (DataMemberInfo_t*) new TClingDataMemberInfo(*TClinginfo);
8624}
8625
8626////////////////////////////////////////////////////////////////////////////////
8627
8628bool TCling::DataMemberInfo_IsValid(DataMemberInfo_t* dminfo) const
8629{
8630 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8631 return TClinginfo->IsValid();
8632}
8633
8634////////////////////////////////////////////////////////////////////////////////
8635
8636int TCling::DataMemberInfo_MaxIndex(DataMemberInfo_t* dminfo, Int_t dim) const
8637{
8638 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8639 return TClinginfo->MaxIndex(dim);
8640}
8641
8642////////////////////////////////////////////////////////////////////////////////
8643
8644int TCling::DataMemberInfo_Next(DataMemberInfo_t* dminfo) const
8645{
8646 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8647 return TClinginfo->Next();
8648}
8649
8650////////////////////////////////////////////////////////////////////////////////
8651
8652Longptr_t TCling::DataMemberInfo_Offset(DataMemberInfo_t* dminfo) const
8653{
8654 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8655 return TClinginfo->Offset();
8656}
8657
8658////////////////////////////////////////////////////////////////////////////////
8659
8660Long_t TCling::DataMemberInfo_Property(DataMemberInfo_t* dminfo) const
8661{
8662 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8663 return TClinginfo->Property();
8664}
8665
8666////////////////////////////////////////////////////////////////////////////////
8667
8668Long_t TCling::DataMemberInfo_TypeProperty(DataMemberInfo_t* dminfo) const
8669{
8670 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8671 return TClinginfo->TypeProperty();
8672}
8673
8674////////////////////////////////////////////////////////////////////////////////
8675
8676int TCling::DataMemberInfo_TypeSize(DataMemberInfo_t* dminfo) const
8677{
8678 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8679 return TClinginfo->TypeSize();
8680}
8681
8682////////////////////////////////////////////////////////////////////////////////
8683
8684const char* TCling::DataMemberInfo_TypeName(DataMemberInfo_t* dminfo) const
8685{
8686 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8687 return TClinginfo->TypeName();
8688}
8689
8690////////////////////////////////////////////////////////////////////////////////
8691
8692const char* TCling::DataMemberInfo_TypeTrueName(DataMemberInfo_t* dminfo) const
8693{
8694 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8695 return TClinginfo->TypeTrueName(*fNormalizedCtxt);
8696}
8697
8698////////////////////////////////////////////////////////////////////////////////
8699
8700const char* TCling::DataMemberInfo_Name(DataMemberInfo_t* dminfo) const
8701{
8702 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8703 return TClinginfo->Name();
8704}
8705
8706////////////////////////////////////////////////////////////////////////////////
8707
8708const char* TCling::DataMemberInfo_Title(DataMemberInfo_t* dminfo) const
8709{
8710 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8711 return TClinginfo->Title();
8712}
8713
8714////////////////////////////////////////////////////////////////////////////////
8715
8716const char* TCling::DataMemberInfo_ValidArrayIndex(DataMemberInfo_t* dminfo) const
8717{
8718 TTHREAD_TLS_DECL(std::string,result);
8719
8720 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8721 result = TClinginfo->ValidArrayIndex().str();
8722 return result.c_str(); // NOLINT
8723}
8724
8725////////////////////////////////////////////////////////////////////////////////
8726
8727void TCling::SetDeclAttr(DeclId_t declId, const char* attribute)
8728{
8729 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8730 ASTContext &C = decl->getASTContext();
8731 decl->addAttr(AnnotateAttr::CreateImplicit(C, attribute));
8732}
8733
8734//______________________________________________________________________________
8735//
8736// Function Template interface
8737//
8738
8739////////////////////////////////////////////////////////////////////////////////
8740
8741static void ConstructorName(std::string &name, const clang::Decl *decl,
8742 cling::Interpreter &interp,
8743 const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
8744{
8745 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8746 if (!td) return;
8747
8748 clang::QualType qualType(td->getTypeForDecl(),0);
8749 ROOT::TMetaUtils::GetNormalizedName(name, qualType, interp, normCtxt);
8750 unsigned int level = 0;
8751 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8752 if (name[cursor] == '>') ++level;
8753 else if (name[cursor] == '<' && level) --level;
8754 else if (level == 0 && name[cursor] == ':') {
8755 name.erase(0,cursor+1);
8756 break;
8757 }
8758 }
8759}
8760
8761////////////////////////////////////////////////////////////////////////////////
8762
8763void TCling::GetFunctionName(const clang::Decl *decl, std::string &output) const
8764{
8765 output.clear();
8766
8767 const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(decl);
8768 if (const auto *USD = llvm::dyn_cast<clang::UsingShadowDecl>(decl)) {
8769 FD = llvm::dyn_cast<clang::FunctionDecl>(USD->getTargetDecl());
8770 }
8771 if (!FD) {
8772 Error("GetFunctionName", "NULL Decl!");
8773 return;
8774 }
8775
8776 // For using-decls, show "Derived", not "Base", i.e. use the
8777 // name of the decl context of the UsingShadowDecl (aka `decl`)
8778 // not the name of FD's decl context.
8779 if (llvm::isa<clang::CXXConstructorDecl>(FD))
8780 {
8782
8783 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
8784 {
8786 output.insert(output.begin(), '~');
8787 } else {
8788 llvm::raw_string_ostream stream(output);
8789 auto printPolicy = decl->getASTContext().getPrintingPolicy();
8790 // Don't trigger fopen of the source file to count lines:
8791 printPolicy.AnonymousTagLocations = false;
8792 FD->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
8793 }
8794}
8795
8796////////////////////////////////////////////////////////////////////////////////
8797/// Return a unique identifier of the declaration represented by the
8798/// FuncTempInfo
8799
8801{
8802 return (DeclId_t)info;
8803}
8804
8805////////////////////////////////////////////////////////////////////////////////
8806/// Delete the FuncTempInfo_t
8807
8808void TCling::FuncTempInfo_Delete(FuncTempInfo_t * /* ft_info */) const
8809{
8810 // Currently the address of ft_info is actually the decl itself,
8811 // so we have nothing to do.
8812}
8813
8814////////////////////////////////////////////////////////////////////////////////
8815/// Construct a FuncTempInfo_t
8816
8817FuncTempInfo_t *TCling::FuncTempInfo_Factory(DeclId_t declid) const
8818{
8819 // Currently the address of ft_info is actually the decl itself,
8820 // so we have nothing to do.
8821
8822 return (FuncTempInfo_t*)const_cast<void*>(declid);
8823}
8824
8825////////////////////////////////////////////////////////////////////////////////
8826/// Construct a FuncTempInfo_t
8827
8828FuncTempInfo_t *TCling::FuncTempInfo_FactoryCopy(FuncTempInfo_t *ft_info) const
8829{
8830 // Currently the address of ft_info is actually the decl itself,
8831 // so we have nothing to do.
8832
8833 return (FuncTempInfo_t*)ft_info;
8834}
8835
8836////////////////////////////////////////////////////////////////////////////////
8837/// Check validity of a FuncTempInfo_t
8838
8839Bool_t TCling::FuncTempInfo_IsValid(FuncTempInfo_t *t_info) const
8840{
8841 // Currently the address of ft_info is actually the decl itself,
8842 // so we have nothing to do.
8843
8844 return t_info != nullptr;
8845}
8846
8847////////////////////////////////////////////////////////////////////////////////
8848/// Return the maximum number of template arguments of the
8849/// function template described by ft_info.
8850
8851UInt_t TCling::FuncTempInfo_TemplateNargs(FuncTempInfo_t *ft_info) const
8852{
8853 if (!ft_info) return 0;
8854 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8855 return ft->getTemplateParameters()->size();
8856}
8857
8858////////////////////////////////////////////////////////////////////////////////
8859/// Return the number of required template arguments of the
8860/// function template described by ft_info.
8861
8863{
8864 if (!ft_info) return 0;
8865 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8866 return ft->getTemplateParameters()->getMinRequiredArguments();
8867}
8868
8869////////////////////////////////////////////////////////////////////////////////
8870/// Return the property of the function template.
8871
8872Long_t TCling::FuncTempInfo_Property(FuncTempInfo_t *ft_info) const
8873{
8874 if (!ft_info) return 0;
8875
8876 long property = 0L;
8877 property |= kIsCompiled;
8878
8879 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8880
8881 switch (ft->getAccess()) {
8882 case clang::AS_public:
8883 property |= kIsPublic;
8884 break;
8885 case clang::AS_protected:
8886 property |= kIsProtected;
8887 break;
8888 case clang::AS_private:
8889 property |= kIsPrivate;
8890 break;
8891 case clang::AS_none:
8892 if (ft->getDeclContext()->isNamespace())
8894 break;
8895 default:
8896 // IMPOSSIBLE
8897 assert(false && "Unexpected value for the access property value in Clang");
8898 break;
8899 }
8900
8901 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8902 if (const clang::CXXMethodDecl *md =
8903 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
8904 if (md->getMethodQualifiers().hasConst()) {
8905 property |= kIsConstant | kIsConstMethod;
8906 }
8907 if (md->isVirtual()) {
8908 property |= kIsVirtual;
8909 }
8910 if (md->isPure()) {
8911 property |= kIsPureVirtual;
8912 }
8913 if (const clang::CXXConstructorDecl *cd =
8914 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
8915 if (cd->isExplicit()) {
8916 property |= kIsExplicit;
8917 }
8918 }
8919 else if (const clang::CXXConversionDecl *cd =
8920 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
8921 if (cd->isExplicit()) {
8922 property |= kIsExplicit;
8923 }
8924 }
8925 }
8926 return property;
8927}
8928
8929////////////////////////////////////////////////////////////////////////////////
8930/// Return the property not already defined in Property
8931/// See TDictionary's EFunctionProperty
8932
8933Long_t TCling::FuncTempInfo_ExtraProperty(FuncTempInfo_t* ft_info) const
8934{
8935 if (!ft_info) return 0;
8936
8937 long property = 0L;
8938 property |= kIsCompiled;
8939
8940 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8941 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8942
8943 if (fd->isOverloadedOperator())
8945 if (llvm::isa<clang::CXXConversionDecl>(fd))
8947 if (llvm::isa<clang::CXXConstructorDecl>(fd))
8949 if (llvm::isa<clang::CXXDestructorDecl>(fd))
8951 if (fd->isInlined())
8953 return property;
8954}
8955
8956////////////////////////////////////////////////////////////////////////////////
8957/// Return the name of this function template.
8958
8959void TCling::FuncTempInfo_Name(FuncTempInfo_t *ft_info, TString &output) const
8960{
8961 output.Clear();
8962 if (!ft_info) return;
8963 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8964 std::string buf;
8965 GetFunctionName(ft->getTemplatedDecl(), buf);
8966 output = buf;
8967}
8968
8969////////////////////////////////////////////////////////////////////////////////
8970/// Return the comments associates with this function template.
8971
8972void TCling::FuncTempInfo_Title(FuncTempInfo_t *ft_info, TString &output) const
8973{
8974 output.Clear();
8975 if (!ft_info) return;
8976 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8977
8978 // Iterate over the redeclarations, we can have multiple definitions in the
8979 // redecl chain (came from merging of pcms).
8980 if (const RedeclarableTemplateDecl *AnnotFD
8981 = ROOT::TMetaUtils::GetAnnotatedRedeclarable((const RedeclarableTemplateDecl*)ft)) {
8982 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
8983 output = A->getAnnotation().str();
8984 return;
8985 }
8986 }
8987 if (!ft->isFromASTFile()) {
8988 // Try to get the comment from the header file if present
8989 // but not for decls from AST file, where rootcling would have
8990 // created an annotation
8992 }
8993}
8994
8995
8996//______________________________________________________________________________
8997//
8998// MethodInfo interface
8999//
9000
9001////////////////////////////////////////////////////////////////////////////////
9002/// Interface to cling function
9003
9004void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
9005{
9006 delete(TClingMethodInfo*) minfo;
9007}
9008
9009////////////////////////////////////////////////////////////////////////////////
9010
9011void TCling::MethodInfo_CreateSignature(MethodInfo_t* minfo, TString& signature) const
9012{
9013 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9014 // The next call locks the interpreter mutex.
9015 info->CreateSignature(signature);
9016}
9017
9018////////////////////////////////////////////////////////////////////////////////
9019
9020MethodInfo_t* TCling::MethodInfo_Factory() const
9021{
9023 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl());
9024}
9025
9026////////////////////////////////////////////////////////////////////////////////
9027
9028MethodInfo_t* TCling::MethodInfo_Factory(ClassInfo_t* clinfo) const
9029{
9031 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
9032}
9033
9034////////////////////////////////////////////////////////////////////////////////
9035
9036MethodInfo_t* TCling::MethodInfo_Factory(DeclId_t declid) const
9037{
9038 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
9040 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), decl);
9041}
9042
9043////////////////////////////////////////////////////////////////////////////////
9044
9045MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
9046{
9047 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
9048}
9049
9050////////////////////////////////////////////////////////////////////////////////
9051
9052void* TCling::MethodInfo_InterfaceMethod(MethodInfo_t* minfo) const
9053{
9054 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9055 // The next call locks the interpreter mutex.
9056 return info->InterfaceMethod();
9057}
9058
9059////////////////////////////////////////////////////////////////////////////////
9060
9061bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
9062{
9063 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9064 return info->IsValid();
9065}
9066
9067////////////////////////////////////////////////////////////////////////////////
9068
9069int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
9070{
9071 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9072 return info->NArg();
9073}
9074
9075////////////////////////////////////////////////////////////////////////////////
9076
9077int TCling::MethodInfo_NDefaultArg(MethodInfo_t* minfo) const
9078{
9079 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9080 return info->NDefaultArg();
9081}
9082
9083////////////////////////////////////////////////////////////////////////////////
9084
9085int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
9086{
9087 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9088 return info->Next();
9089}
9090
9091////////////////////////////////////////////////////////////////////////////////
9092
9093Long_t TCling::MethodInfo_Property(MethodInfo_t* minfo) const
9094{
9095 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9096 // The next call locks the interpreter mutex.
9097 return info->Property();
9098}
9099
9100////////////////////////////////////////////////////////////////////////////////
9101
9103{
9104 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9105 // The next call locks the interpreter mutex.
9106 return info->ExtraProperty();
9107}
9108
9109////////////////////////////////////////////////////////////////////////////////
9110
9111TypeInfo_t* TCling::MethodInfo_Type(MethodInfo_t* minfo) const
9112{
9113 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9114 // The next call locks the interpreter mutex.
9115 return (TypeInfo_t*)info->Type();
9116}
9117
9118////////////////////////////////////////////////////////////////////////////////
9119
9120const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
9121{
9122 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9123 TTHREAD_TLS_DECL(TString, mangled_name);
9124 // The next call locks the interpreter mutex.
9125 mangled_name = info->GetMangledName();
9126 return mangled_name;
9127}
9128
9129////////////////////////////////////////////////////////////////////////////////
9130
9131const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
9132{
9133 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9134 // The next call locks the interpreter mutex.
9135 return info->GetPrototype();
9136}
9137
9138////////////////////////////////////////////////////////////////////////////////
9139
9140const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
9141{
9142 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9143 // The next call locks the interpreter mutex.
9144 return info->Name();
9145}
9146
9147////////////////////////////////////////////////////////////////////////////////
9148
9149const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
9150{
9151 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9152 // The next call locks the interpreter mutex.
9153 return info->TypeName();
9154}
9155
9156////////////////////////////////////////////////////////////////////////////////
9157
9158std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
9159{
9160 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9161 // The next part locks the interpreter mutex.
9162 if (info && info->IsValid())
9163 return info->Type()->NormalizedName(*fNormalizedCtxt);
9164 else
9165 return "";
9166}
9167
9168////////////////////////////////////////////////////////////////////////////////
9169
9170const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
9171{
9172 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9173 // The next call locks the interpreter mutex.
9174 return info->Title();
9175}
9176
9177////////////////////////////////////////////////////////////////////////////////
9178
9180{
9181 if (func) {
9182 return MethodInfo_MethodCallReturnType(func->fInfo);
9183 } else {
9184 return EReturnType::kOther;
9185 }
9186}
9187
9188////////////////////////////////////////////////////////////////////////////////
9189
9191{
9192 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9193 if (info && info->IsValid()) {
9194 TClingTypeInfo *typeinfo = info->Type();
9195 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
9196 if (QT->isEnumeralType()) {
9197 return EReturnType::kLong;
9198 } else if (QT->isPointerType()) {
9199 // Look for char*
9200 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
9201 if ( QT->isCharType() ) {
9202 return EReturnType::kString;
9203 } else {
9204 return EReturnType::kOther;
9205 }
9206 } else if ( QT->isFloatingType() ) {
9207 int sz = typeinfo->Size();
9208 if (sz == 4 || sz == 8) {
9209 // Support only float and double.
9210 return EReturnType::kDouble;
9211 } else {
9212 return EReturnType::kOther;
9213 }
9214 } else if ( QT->isIntegerType() ) {
9215 int sz = typeinfo->Size();
9216 if (sz <= 8) {
9217 // Support only up to long long ... but
9218 // FIXME the TMethodCall::Execute only
9219 // return long (4 bytes) ...
9220 // The v5 implementation of TMethodCall::ReturnType
9221 // was not making the distinction so we let it go
9222 // as is for now, but we really need to upgrade
9223 // TMethodCall::Execute ...
9224 return EReturnType::kLong;
9225 } else {
9226 return EReturnType::kOther;
9227 }
9228 } else {
9229 return EReturnType::kOther;
9230 }
9231 } else {
9232 return EReturnType::kOther;
9233 }
9234}
9235
9236//______________________________________________________________________________
9237//
9238// MethodArgInfo interface
9239//
9240
9241////////////////////////////////////////////////////////////////////////////////
9242
9243void TCling::MethodArgInfo_Delete(MethodArgInfo_t* marginfo) const
9244{
9245 delete(TClingMethodArgInfo*) marginfo;
9246}
9247
9248////////////////////////////////////////////////////////////////////////////////
9249
9250MethodArgInfo_t* TCling::MethodArgInfo_Factory() const
9251{
9253 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl());
9254}
9255
9256////////////////////////////////////////////////////////////////////////////////
9257
9258MethodArgInfo_t* TCling::MethodArgInfo_Factory(MethodInfo_t *minfo) const
9259{
9261 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl(), (TClingMethodInfo*)minfo);
9262}
9263
9264////////////////////////////////////////////////////////////////////////////////
9265
9266MethodArgInfo_t* TCling::MethodArgInfo_FactoryCopy(MethodArgInfo_t* marginfo) const
9267{
9268 return (MethodArgInfo_t*)
9270}
9271
9272////////////////////////////////////////////////////////////////////////////////
9273
9274bool TCling::MethodArgInfo_IsValid(MethodArgInfo_t* marginfo) const
9275{
9276 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9277 return info->IsValid();
9278}
9279
9280////////////////////////////////////////////////////////////////////////////////
9281
9282int TCling::MethodArgInfo_Next(MethodArgInfo_t* marginfo) const
9283{
9284 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9285 return info->Next();
9286}
9287
9288////////////////////////////////////////////////////////////////////////////////
9289
9290Long_t TCling::MethodArgInfo_Property(MethodArgInfo_t* marginfo) const
9291{
9292 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9293 return info->Property();
9294}
9295
9296////////////////////////////////////////////////////////////////////////////////
9297
9298const char* TCling::MethodArgInfo_DefaultValue(MethodArgInfo_t* marginfo) const
9299{
9300 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9301 return info->DefaultValue();
9302}
9303
9304////////////////////////////////////////////////////////////////////////////////
9305
9306const char* TCling::MethodArgInfo_Name(MethodArgInfo_t* marginfo) const
9307{
9308 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9309 return info->Name();
9310}
9311
9312////////////////////////////////////////////////////////////////////////////////
9313
9314const char* TCling::MethodArgInfo_TypeName(MethodArgInfo_t* marginfo) const
9315{
9316 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9317 return info->TypeName();
9318}
9319
9320////////////////////////////////////////////////////////////////////////////////
9321
9322std::string TCling::MethodArgInfo_TypeNormalizedName(MethodArgInfo_t* marginfo) const
9323{
9324 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9325 return info->Type()->NormalizedName(*fNormalizedCtxt);
9326}
9327
9328////////////////////////////////////////////////////////////////////////////////
9329
9330TypeInfo_t* TCling::MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
9331{
9332 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9333 return (TypeInfo_t*) info->Type();
9334}
9335
9336//______________________________________________________________________________
9337//
9338// TypeInfo interface
9339//
9340
9341////////////////////////////////////////////////////////////////////////////////
9342
9343void TCling::TypeInfo_Delete(TypeInfo_t* tinfo) const
9344{
9345 delete (TClingTypeInfo*) tinfo;
9346}
9347
9348////////////////////////////////////////////////////////////////////////////////
9349
9350TypeInfo_t* TCling::TypeInfo_Factory() const
9351{
9353 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl());
9354}
9355
9356////////////////////////////////////////////////////////////////////////////////
9357
9358TypeInfo_t* TCling::TypeInfo_Factory(const char *name) const
9359{
9361 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl(), name);
9362}
9363
9364////////////////////////////////////////////////////////////////////////////////
9365
9366TypeInfo_t* TCling::TypeInfo_FactoryCopy(TypeInfo_t* tinfo) const
9367{
9368 return (TypeInfo_t*) new TClingTypeInfo(*(TClingTypeInfo*)tinfo);
9369}
9370
9371////////////////////////////////////////////////////////////////////////////////
9372
9373void TCling::TypeInfo_Init(TypeInfo_t* tinfo, const char* name) const
9374{
9376 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9377 TClinginfo->Init(name);
9378}
9379
9380////////////////////////////////////////////////////////////////////////////////
9381
9382bool TCling::TypeInfo_IsValid(TypeInfo_t* tinfo) const
9383{
9384 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9385 return TClinginfo->IsValid();
9386}
9387
9388////////////////////////////////////////////////////////////////////////////////
9389
9390const char* TCling::TypeInfo_Name(TypeInfo_t* tinfo) const
9391{
9392 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9393 return TClinginfo->Name();
9394}
9395
9396////////////////////////////////////////////////////////////////////////////////
9397
9398Long_t TCling::TypeInfo_Property(TypeInfo_t* tinfo) const
9399{
9400 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9401 return TClinginfo->Property();
9402}
9403
9404////////////////////////////////////////////////////////////////////////////////
9405
9406int TCling::TypeInfo_RefType(TypeInfo_t* tinfo) const
9407{
9408 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9409 return TClinginfo->RefType();
9410}
9411
9412////////////////////////////////////////////////////////////////////////////////
9413
9414int TCling::TypeInfo_Size(TypeInfo_t* tinfo) const
9415{
9416 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9417 return TClinginfo->Size();
9418}
9419
9420////////////////////////////////////////////////////////////////////////////////
9421
9422const char* TCling::TypeInfo_TrueName(TypeInfo_t* tinfo) const
9423{
9424 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9425 return TClinginfo->TrueName(*fNormalizedCtxt);
9426}
9427
9428////////////////////////////////////////////////////////////////////////////////
9429
9430void* TCling::TypeInfo_QualTypePtr(TypeInfo_t* tinfo) const
9431{
9432 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9433 return TClinginfo->QualTypePtr();
9434}
9435
9436
9437//______________________________________________________________________________
9438//
9439// TypedefInfo interface
9440//
9441
9442////////////////////////////////////////////////////////////////////////////////
9443
9444void TCling::TypedefInfo_Delete(TypedefInfo_t* tinfo) const
9445{
9446 delete(TClingTypedefInfo*) tinfo;
9447}
9448
9449////////////////////////////////////////////////////////////////////////////////
9450
9451TypedefInfo_t* TCling::TypedefInfo_Factory() const
9452{
9454 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl());
9455}
9456
9457////////////////////////////////////////////////////////////////////////////////
9458
9459TypedefInfo_t* TCling::TypedefInfo_Factory(const char *name) const
9460{
9462 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl(), name);
9463}
9464
9465////////////////////////////////////////////////////////////////////////////////
9466
9467TypedefInfo_t* TCling::TypedefInfo_FactoryCopy(TypedefInfo_t* tinfo) const
9468{
9469 return (TypedefInfo_t*) new TClingTypedefInfo(*(TClingTypedefInfo*)tinfo);
9470}
9471
9472////////////////////////////////////////////////////////////////////////////////
9473
9474void TCling::TypedefInfo_Init(TypedefInfo_t* tinfo,
9475 const char* name) const
9476{
9478 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9479 TClinginfo->Init(name);
9480}
9481
9482////////////////////////////////////////////////////////////////////////////////
9483
9484bool TCling::TypedefInfo_IsValid(TypedefInfo_t* tinfo) const
9485{
9486 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9487 return TClinginfo->IsValid();
9488}
9489
9490////////////////////////////////////////////////////////////////////////////////
9491
9492Int_t TCling::TypedefInfo_Next(TypedefInfo_t* tinfo) const
9493{
9494 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9495 return TClinginfo->Next();
9496}
9497
9498////////////////////////////////////////////////////////////////////////////////
9499
9500Long_t TCling::TypedefInfo_Property(TypedefInfo_t* tinfo) const
9501{
9502 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9503 return TClinginfo->Property();
9504}
9505
9506////////////////////////////////////////////////////////////////////////////////
9507
9508int TCling::TypedefInfo_Size(TypedefInfo_t* tinfo) const
9509{
9510 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9511 return TClinginfo->Size();
9512}
9513
9514////////////////////////////////////////////////////////////////////////////////
9515
9516const char* TCling::TypedefInfo_TrueName(TypedefInfo_t* tinfo) const
9517{
9518 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9519 return TClinginfo->TrueName(*fNormalizedCtxt);
9520}
9521
9522////////////////////////////////////////////////////////////////////////////////
9523
9524const char* TCling::TypedefInfo_Name(TypedefInfo_t* tinfo) const
9525{
9526 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9527 return TClinginfo->Name();
9528}
9529
9530////////////////////////////////////////////////////////////////////////////////
9531
9532const char* TCling::TypedefInfo_Title(TypedefInfo_t* tinfo) const
9533{
9534 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9535 return TClinginfo->Title();
9536}
9537
9538////////////////////////////////////////////////////////////////////////////////
9539
9540bool TCling::IsSameType(const void * QualTypePtr1, const void * QualTypePtr2) const
9541{
9542 clang::QualType QT1 = clang::QualType::getFromOpaquePtr(QualTypePtr1);
9543 clang::QualType QT2 = clang::QualType::getFromOpaquePtr(QualTypePtr2);
9544 return fInterpreter->getCI()->getASTContext().hasSameType(QT1, QT2);
9545}
9546
9547////////////////////////////////////////////////////////////////////////////////
9548
9549bool TCling::IsIntegerType(const void * QualTypePtr) const
9550{
9551 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9552 return QT->hasIntegerRepresentation();
9553}
9554
9555////////////////////////////////////////////////////////////////////////////////
9556
9557bool TCling::IsSignedIntegerType(const void * QualTypePtr) const
9558{
9559 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9560 return QT->hasSignedIntegerRepresentation();
9561}
9562
9563////////////////////////////////////////////////////////////////////////////////
9564
9565bool TCling::IsUnsignedIntegerType(const void * QualTypePtr) const
9566{
9567 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9568 return QT->hasUnsignedIntegerRepresentation();
9569}
9570
9571////////////////////////////////////////////////////////////////////////////////
9572
9573bool TCling::IsFloatingType(const void * QualTypePtr) const
9574{
9575 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9576 return QT->hasFloatingRepresentation();
9577}
9578
9579////////////////////////////////////////////////////////////////////////////////
9580
9581bool TCling::IsPointerType(const void * QualTypePtr) const
9582{
9583 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9584 return QT->hasPointerRepresentation();
9585}
9586
9587////////////////////////////////////////////////////////////////////////////////
9588
9589bool TCling::IsVoidPointerType(const void * QualTypePtr) const
9590{
9591 clang::QualType QT = clang::QualType::getFromOpaquePtr(QualTypePtr);
9592 return QT->isVoidPointerType();
9593}
9594
9595////////////////////////////////////////////////////////////////////////////////
9596
9598{
9599 clang::FunctionDecl *FD = (clang::FunctionDecl *) fdeclid;
9600 return llvm::isa_and_nonnull<clang::CXXMethodDecl>(FD);
9601}
9602
9603////////////////////////////////////////////////////////////////////////////////
9604
9606{
9607 if (!fInitialMutex) {
9609 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
9610 }
9612 }
9613 // We will "forget" this lock once we backed out of all interpreter frames.
9614 // Here we are entering one, so ++.
9616}
9617
9618////////////////////////////////////////////////////////////////////////////////
9619
9621{
9622 if (!fInitialMutex)
9623 return;
9624 if (fInitialMutex.fRecurseCount == 0) {
9625 Error("ForgetMutexState", "mutex state's recurse count already 0!");
9626 }
9627 else if (--fInitialMutex.fRecurseCount == 0) {
9628 // We have returned from all interpreter frames. Reset the initial lock state.
9629 fInitialMutex.fState.reset();
9630 }
9631}
9632
9633////////////////////////////////////////////////////////////////////////////////
9634/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
9635
9637{
9638 if (gInterpreterMutex) {
9639 if (delta) {
9640 auto typedDelta = static_cast<MutexStateAndRecurseCountDelta *>(delta);
9641 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP{typedDelta};
9642 gCoreMutex->Apply(std::move(typedDelta->fDelta));
9643 // Now that we have the lock, update the global
9644 R__ASSERT(fInitialMutex.fRecurseCount == 0 && "Inconsistent state of fInitialMutex! Another thread within Interpreter critical section.");
9645 std::swap(fInitialMutex, typedDelta->fInitialState);
9646 } else {
9647 // This case happens when EnableThreadSafety is first called from
9648 // the interpreter function we just handled.
9649 // Since thread safety was not enabled at the time we rewound, there was
9650 // no lock taken and even-though we should be locking the rest of this
9651 // interpreter handling/modifying code (since there might be threads in
9652 // flight), we can't because there would not be any lock guard to release the
9653 // locks
9655 Error("ApplyToInterpreterMutex",
9656 "After returning from user code that turned on thread safety support, we notice that fInitialMutex is already used ... "
9657 "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.");
9658 }
9659 }
9660}
9661
9662////////////////////////////////////////////////////////////////////////////////
9663/// Reset the interpreter lock to the state it had before interpreter-related
9664/// calls happened.
9665
9667{
9668 if (fInitialMutex) {
9669 // Need to start a new recurse count.
9670 std::unique_ptr<MutexStateAndRecurseCountDelta> uniqueP(new MutexStateAndRecurseCountDelta());
9671 std::swap(uniqueP->fInitialState, fInitialMutex);
9672 uniqueP->fDelta = gCoreMutex->Rewind(*uniqueP->fInitialState.fState);
9673 return uniqueP.release();
9674 }
9676 return nullptr;
9677}
#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
RooAbsReal & function()
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Definition RtypesCore.h:63
int Int_t
Definition RtypesCore.h:45
long Longptr_t
Definition RtypesCore.h:82
short Version_t
Definition RtypesCore.h:65
unsigned long ULong_t
Definition RtypesCore.h:55
long Long_t
Definition RtypesCore.h:54
unsigned int UInt_t
Definition RtypesCore.h:46
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
constexpr Ssiz_t kNPOS
Definition RtypesCore.h:124
long long Long64_t
Definition RtypesCore.h:80
unsigned long long ULong64_t
Definition RtypesCore.h:81
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
TClass *(* DictFuncPtr_t)()
Definition Rtypes.h:80
R__EXTERN TApplication * gApplication
R__EXTERN TClassTable * gClassTable
Definition TClassTable.h:97
static bool IsFromRootCling()
Definition TClass.cxx:174
static void indent(ostringstream &buf, int indent_level)
The file contains facilities to work with C++ module files extensions used to store rdict files.
void TCling__RestoreInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:341
void TCling__TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:579
static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
Definition TCling.cxx:1308
static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
Definition TCling.cxx:7254
static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
Definition TCling.cxx:7001
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:901
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:3914
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:1948
static Bool_t s_IsLibraryLoaded(const char *libname, cling::Interpreter *fInterpreter)
Definition TCling.cxx:3138
static GlobalModuleIndex * loadGlobalModuleIndex(cling::Interpreter &interp)
Definition TCling.cxx:1089
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:910
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:1074
void TCling__UnlockCompilationDuringUserCodeExecution(void *)
Unlock the interpreter.
Definition TCling.cxx:379
const char * TCling__GetClassSharedLibs(const char *className)
Definition TCling.cxx:633
static std::string AlternateTuple(const char *classname, const cling::LookupHelper &lh, Bool_t silent)
Definition TCling.cxx:3956
static bool R__InitStreamerInfoFactory()
Helper to initialize TVirtualStreamerInfo's factor early.
Definition TCling.cxx:1673
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:1088
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:3932
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:1039
static void RegisterCxxModules(cling::Interpreter &clingInterp)
Definition TCling.cxx:1192
static void ConstructorName(std::string &name, const clang::Decl *decl, cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition TCling.cxx:8741
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:2432
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:7163
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:1973
TInterpreter * CreateInterpreter(void *interpLibHandle, const char *argv[])
Definition TCling.cxx:608
const char * fantomline
Definition TCling.cxx:848
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:6341
static bool requiresRootMap(const char *rootmapfile)
Definition TCling.cxx:5521
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:1061
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:7275
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)
Definition TError.h:118
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:218
constexpr Int_t kWarning
Definition TError.h:45
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:185
Int_t gErrorIgnoreLevel
Error handling routines.
Definition TError.cxx:31
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:229
void Fatal(const char *location, const char *msgfmt,...)
Use this function in case of a fatal error. It will abort the program.
Definition TError.cxx:244
#define N
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void 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 data
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:555
R__EXTERN TVirtualMutex * gGlobalMutex
#define R__LOCKGUARD(mutex)
#define R__WRITE_LOCKGUARD(mutex)
#define R__READ_LOCKGUARD(mutex)
const char * proto
Definition civetweb.c:17536
#define free
Definition civetweb.c:1539
#define snprintf
Definition civetweb.c:1540
void AddTemplAndNargsToKeep(const clang::ClassTemplateDecl *templ, unsigned int i)
const Config_t & GetConfig() const
virtual std::unique_ptr< StateDelta > Rewind(const State &earlierState)=0
virtual void Apply(std::unique_ptr< StateDelta > &&delta)=0
virtual std::unique_ptr< State > GetStateBefore()=0
static Longptr_t ExecuteFile(const char *file, Int_t *error=nullptr, Bool_t keep=kFALSE)
Execute a file containing a C++ macro (static method).
virtual TApplicationImp * GetApplicationImp()
virtual Bool_t IsCmdThread()
Each class (see TClass) has a linked list of its base class(es).
Definition TBaseClass.h:33
TClassRef is used to implement a permanent reference to a TClass object.
Definition TClassRef.h:28
static DictFuncPtr_t GetDict(const char *cname)
Given the class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProtoNorm(const char *cname)
Given the class normalized name returns the TClassProto object for the class.
static DictFuncPtr_t GetDictNorm(const char *cname)
Given the normalized class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProto(const char *cname)
Given the class name returns the TClassProto object for the class.
static Bool_t Check(const char *cname, std::string &normname)
static void Add(const char *cname, Version_t id, const std::type_info &info, DictFuncPtr_t dict, Int_t pragmabits)
Add a class to the class table (this is a static function).
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:81
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
Definition TClass.cxx:3439
EState GetState() const
Definition TClass.h:488
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition TClass.cxx:2886
EState fState
cached of the streaming method to use
Definition TClass.h:277
std::atomic< TList * > fBase
Definition TClass.h:201
static void AddClassToDeclIdMap(TDictionary::DeclId_t id, TClass *cl)
static: Add a TClass* to the map of classes.
Definition TClass.cxx:511
Version_t fClassVersion
Definition TClass.h:221
TList * GetListOfFunctionTemplates(Bool_t load=kTRUE)
Return TListOfFunctionTemplates for a class.
Definition TClass.cxx:3798
void * DynamicCast(const TClass *base, void *obj, Bool_t up=kTRUE)
Cast obj of this class type up to baseclass cl if up is true.
Definition TClass.cxx:4915
static void RemoveClassDeclId(TDictionary::DeclId_t id)
Definition TClass.cxx:536
Bool_t CallShowMembers(const void *obj, TMemberInspector &insp, Bool_t isTransient=kFALSE) const
Call ShowMembers() on the obj of this class type, passing insp and parent.
Definition TClass.cxx:2205
std::atomic< TListOfEnums * > fEnums
Definition TClass.h:205
static Bool_t HasNoInfoOrEmuOrFwdDeclaredDecl(const char *)
Definition TClass.cxx:3398
virtual void PostLoadCheck()
Do the initialization that can only be done after the CINT dictionary has been fully populated and ca...
Definition TClass.cxx:5959
static TClass * LoadClass(const char *requestedname, Bool_t silent)
Helper function used by TClass::GetClass().
Definition TClass.cxx:5749
Int_t Size() const
Return size of object of this class.
Definition TClass.cxx:5704
@ kLoading
Definition TClass.h:332
@ kUnloading
Definition TClass.h:332
TObjArray * fStreamerInfo
Definition TClass.h:198
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition TClass.cxx:5912
ClassInfo_t * GetClassInfo() const
Definition TClass.h:433
ClassInfo_t * fClassInfo
Definition TClass.h:222
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:2897
void ResetCaches()
To clean out all caches.
Definition TClass.cxx:4215
Long_t Property() const override
Returns the properties of the TClass as a bit field stored as a Long_t value.
Definition TClass.cxx:6086
static Int_t ReadRules()
Read the class.rules files from the default location:.
Definition TClass.cxx:1820
@ kInterpreted
Definition TClass.h:126
@ kHasTClassInit
Definition TClass.h:127
@ kEmulated
Definition TClass.h:125
@ kForwardDeclared
Definition TClass.h:124
@ kNamespaceForMeta
Definition TClass.h:131
Version_t GetClassVersion() const
Definition TClass.h:420
std::atomic< Bool_t > fHasRootPcmInfo
C++ Property of the class (is abstract, has virtual table, etc.)
Definition TClass.h:259
const char * GetDeclFileName() const
Return name of the file containing the declaration of this class.
Definition TClass.cxx:3463
@ kIsTObject
Definition TClass.h:100
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition TClass.cxx:2968
Emulation of the CINT BaseClassInfo class.
const char * TmpltName() const
const char * Name() const
ptrdiff_t Offset(void *address=0, bool isDerivedObject=true) const
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
TClingClassInfo * GetBase() const
Emulation of the CINT CallFunc class.
void ExecWithReturn(void *address, void *ret=nullptr)
void SetArgs(const char *args)
double ExecDouble(void *address)
void SetArgArray(Longptr_t *argArr, int narg)
bool IsValid() const
Longptr_t ExecInt(void *address)
TInterpreter::CallFuncIFacePtr_t IFacePtr()
void SetFunc(const TClingClassInfo *info, const char *method, const char *arglist, Longptr_t *poffset)
void ExecWithArgsAndReturn(void *address, const void *args[]=0, int nargs=0, void *ret=0)
void Exec(void *address, TInterpreterValue *interpVal=0)
TClingMethodInfo * FactoryMethod() const
int get_wrapper_code(std::string &wrapper_name, std::string &wrapper)
void IgnoreExtraArgs(bool ignore)
void SetArg(T arg)
long long ExecInt64(void *address)
bool IsAutoLoadingEnabled() const
void SetAutoParsingSuspended(bool val=true)
void SetAutoLoadingEnabled(bool val=true)
Emulation of the CINT ClassInfo class.
const char * Title()
static bool IsEnum(cling::Interpreter *interp, const char *name)
long ClassProperty() const
void Init(const char *name)
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
EDataType GetUnderlyingType() const
const char * TmpltName() const
const clang::Type * GetType() const
ptrdiff_t GetBaseOffset(TClingClassInfo *toBase, void *address, bool isDerivedObject)
Longptr_t Tagnum() const
bool IsScopedEnum() const
ROOT::TMetaUtils::EIOCtorCategory HasDefaultConstructor(bool checkio=false, std::string *type_name=nullptr) const
TClingMethodInfo GetMethodWithArgs(const char *fname, const char *arglist, Longptr_t *poffset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch, EInheritanceMode imode=kWithInheritance) const
const clang::FunctionTemplateDecl * GetFunctionTemplate(const char *fname) const
int GetMethodNArg(const char *method, const char *proto, Bool_t objectIsConst, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
bool IsValidMethod(const char *method, const char *proto, Bool_t objectIsConst, Longptr_t *offset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
bool HasMethod(const char *name) const
TDictionary::DeclId_t GetDeclId() const
void DeleteArray(void *arena, bool dtorOnly, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
void * New(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
TClingMethodInfo GetMethod(const char *fname) const
bool IsLoaded() const
const clang::ValueDecl * GetDataMember(const char *name) const
void Destruct(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
std::vector< std::string > GetUsingNamespaces()
const char * FileName()
bool IsBase(const char *name) const
void Delete(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Emulation of the CINT DataMemberInfo class.
const char * TypeName() const
const char * TypeTrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
llvm::StringRef ValidArrayIndex() const
const char * Name() const override
virtual const char * Name() const
virtual bool IsValid() const
virtual const clang::Decl * GetDecl() const
Uses clang::TextDiagnosticPrinter to format diagnostics, which are then passed to a user-specified fu...
Emulation of the CINT MethodInfo class.
bool IsValid() const override
const char * DefaultValue() const
const TClingTypeInfo * Type() const
const char * TypeName() const
Emulation of the CINT MethodInfo class.
std::string GetMangledName() const
const char * TypeName() const
const char * Name() const override
const clang::FunctionDecl * GetTargetFunctionDecl() const
Get the FunctionDecl, or if this represents a UsingShadowDecl, the underlying target FunctionDecl.
const char * GetPrototype()
long ExtraProperty() const
void * InterfaceMethod() const
void CreateSignature(TString &signature) const
TDictionary::DeclId_t GetDeclId() const
TClingTypeInfo * Type() const
Emulation of the CINT TypeInfo class.
long Property() const
std::string NormalizedName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
const char * Name() const override
int RefType() const
void * QualTypePtr() const
Return the QualType as a void pointer.
bool IsValid() const override
clang::QualType GetQualType() const
void Init(const char *name)
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
Emulation of the CINT TypedefInfo class.
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Get the name of the underlying type of the current typedef.
long Property() const
Return a bit mask of metadata about the current typedef.
const char * Name() const override
Get the name of the current typedef.
void Init(const char *name)
Lookup named typedef and reset the iterator to point to it.
int Next()
Increment the iterator.
int Size() const
Return the size in bytes of the underlying type of the current typedef.
Bridge between cling::Value and ROOT.
Definition TClingValue.h:36
const char * Data()
Definition TCling.cxx:1015
bool Append(const std::string &str)
Append string to the storage if not added already.
Definition TCling.cxx:1023
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:6213
const char * MethodArgInfo_DefaultValue(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9298
bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const final
Definition TCling.cxx:8304
const char * TypeInfo_Name(TypeInfo_t *) const final
Definition TCling.cxx:9390
void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const final
Definition TCling.cxx:9052
void LoadEnums(TListOfEnums &cl) const final
Create list of pointers to enums for TClass cl.
Definition TCling.cxx:4404
void UpdateListOfGlobals() final
No op: see TClingCallbacks (used to update the list of globals)
Definition TCling.cxx:3894
bool TypedefInfo_IsValid(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9484
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE) final
Load library containing the specified class.
Definition TCling.cxx:6274
void CallFunc_Init(CallFunc_t *func) const final
Definition TCling.cxx:7942
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:3657
bool LibraryLoadingFailed(const std::string &, const std::string &, bool, bool)
Definition TCling.cxx:6577
void GenericError(const char *error) const final
Let the interpreter issue a generic error, and set its error state.
Definition TCling.cxx:7459
std::vector< void * > fRegisterModuleDyLibs
Definition TCling.h:138
void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const final
Definition TCling.cxx:7868
TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const final
Definition TCling.cxx:9111
std::vector< std::string > fAutoLoadLibStorage
Definition TCling.h:118
void CallFunc_Delete(CallFunc_t *func) const final
Definition TCling.cxx:7845
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:7502
void ResetAll() final
Reset the Cling state to its initial state.
Definition TCling.cxx:3733
void SetDeclAttr(DeclId_t, const char *) final
Definition TCling.cxx:8727
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:6896
Long_t MethodInfo_Property(MethodInfo_t *minfo) const final
Definition TCling.cxx:9093
virtual void LoadFunctionTemplates(TClass *cl) const final
Create list of pointers to function templates for TClass cl.
Definition TCling.cxx:4451
bool ClassInfo_IsValidMethod(ClassInfo_t *info, const char *method, const char *proto, Longptr_t *offset, ROOT::EFunctionMatchMode=ROOT::kConversionMatch) const final
Definition TCling.cxx:8338
Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8660
int SetClassAutoparsing(int) final
Enable/Disable the Autoparsing of headers.
Definition TCling.cxx:7587
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:4498
void RewindDictionary() final
Rewind Cling dictionary to the point where it was before executing the current macro.
Definition TCling.cxx:3778
bool ClassInfo_IsValid(ClassInfo_t *info) const final
Definition TCling.cxx:8330
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition TCling.cxx:6770
int TypeInfo_RefType(TypeInfo_t *) const final
Definition TCling.cxx:9406
void CreateListOfBaseClasses(TClass *cl) const final
Create list of pointers to base class(es) for TClass cl.
Definition TCling.cxx:4380
ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const final
Definition TCling.cxx:8217
const char * MethodInfo_Name(MethodInfo_t *minfo) const final
Definition TCling.cxx:9140
BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const final
Definition TCling.cxx:8474
Bool_t LoadText(const char *text) const final
Load the declarations from text into the interpreter.
Definition TCling.cxx:7517
const char * GetSharedLibDeps(const char *lib, bool tryDyld=false) final
Get the list a libraries on which the specified lib depends.
Definition TCling.cxx:7291
EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const final
Definition TCling.cxx:9190
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition TCling.cxx:7716
Longptr_t ProcessLineAsynch(const char *line, EErrorCode *error=nullptr)
Let cling process a command line asynch.
Definition TCling.cxx:3569
bool MethodInfo_IsValid(MethodInfo_t *minfo) const final
Definition TCling.cxx:9061
FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8817
TypeInfo_t * TypeInfo_Factory() const final
Definition TCling.cxx:9350
bool IsClassAutoLoadingEnabled() const
Returns if class AutoLoading is currently enabled.
Definition TCling.cxx:7556
void InvalidateGlobal(const clang::Decl *D)
Invalidate cached TCling information for the given global declaration.
Definition TCling.cxx:6881
int Evaluate(const char *, TInterpreterValue &) final
Get the interpreter value corresponding to the statement.
Definition TCling.cxx:7680
std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const final
Definition TCling.cxx:7665
void UpdateListOfLoadedSharedLibraries()
Definition TCling.cxx:3357
const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9532
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:8067
void InitRootmapFile(const char *name)
Create a resource table and read the (possibly) three resource files, i.e.
Definition TCling.cxx:5664
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:6532
bool FunctionDeclId_IsMethod(DeclId_t fdeclid) const
Definition TCling.cxx:9597
void LoadPCM(std::string pcmFileNameFullPath)
Tries to load a rdict PCM, issues diagnostics if it fails.
Definition TCling.cxx:1820
void UpdateListOfMethods(TClass *cl) const final
Update the list of pointers to method for TClass cl This is now a nop.
Definition TCling.cxx:4516
virtual ~TCling()
Destroy the interpreter interface.
Definition TCling.cxx:1627
void AddFriendToClass(clang::FunctionDecl *, clang::CXXRecordDecl *) const
Inject function as a friend into klass.
Definition TCling.cxx:7769
void PrintIntro() final
No-op; see TRint instead.
Definition TCling.cxx:2657
Bool_t fCxxModulesEnabled
Definition TCling.h:128
int BaseClassInfo_Next(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8494
void RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
Internal function. Actually do the update of the ClassInfo when seeing.
Definition TCling.cxx:6644
CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const final
Definition TCling.cxx:7919
Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7903
void CallFunc_ResetArg(CallFunc_t *func) const final
Definition TCling.cxx:7968
const char * GetCurrentMacroName() const final
Return the file name of the currently interpreted file, included or not.
Definition TCling.cxx:5472
Bool_t IsLoaded(const char *filename) const final
Return true if the file has already been loaded by cint.
Definition TCling.cxx:3181
void SaveGlobalsContext() final
Save the current Cling state of global objects.
Definition TCling.cxx:3881
void CallFunc_IgnoreExtraArgs(CallFunc_t *func, bool ignore) const final
Definition TCling.cxx:7934
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition TCling.cxx:9636
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition TCling.cxx:6600
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:4732
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:8133
Bool_t IsLibraryLoaded(const char *libname) const final
Definition TCling.cxx:3147
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:7481
int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8586
TypeInfo_t * MethodArgInfo_TypeInfo(MethodArgInfo_t *marginfo) const
Definition TCling.cxx:9330
DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8620
Bool_t HandleNewTransaction(const cling::Transaction &T)
Helper function to increase the internal Cling count of transactions that change the AST.
Definition TCling.cxx:3674
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:5537
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition TCling.h:153
int ClassInfo_Next(ClassInfo_t *info) const final
Definition TCling.cxx:8354
void SetErrmsgcallback(void *p) const final
Set a callback to receive error messages.
Definition TCling.cxx:7608
bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9274
int TypeInfo_Size(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9414
Int_t DeleteGlobal(void *obj) final
Delete obj from Cling symbol table so it cannot be accessed anymore.
Definition TCling.cxx:3792
int GetSecurityError() const final
Interface to cling function.
Definition TCling.cxx:7489
void SetTempLevel(int val) const final
Create / close a scope for temporaries.
Definition TCling.cxx:7644
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:8851
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:5164
TypedefInfo_t * TypedefInfo_Factory() const final
Definition TCling.cxx:9451
TObjArray * fRootmapFiles
Definition TCling.h:126
bool IsVoidPointerType(const void *QualTypePtr) const
Definition TCling.cxx:9589
Longptr_t ProcessLine(const char *line, EErrorCode *error=nullptr) final
Definition TCling.cxx:2462
int ClassInfo_Size(ClassInfo_t *info) const final
Definition TCling.cxx:8402
const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9314
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:5412
std::vector< std::pair< TClass *, DictFuncPtr_t > > fClassesToUpdate
Definition TCling.h:146
int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8644
const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9524
void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8467
Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const final
Definition TCling.cxx:9102
void LoadMacro(const char *filename, EErrorCode *error=nullptr) final
Load a macro file in cling's memory.
Definition TCling.cxx:3561
const char * GetClassSharedLibs(const char *cls) final
Get the list of shared libraries containing the code for class cls.
Definition TCling.cxx:7097
FuncTempInfo_t * FuncTempInfo_FactoryCopy(FuncTempInfo_t *) const final
Construct a FuncTempInfo_t.
Definition TCling.cxx:8828
int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const final
Definition TCling.cxx:8636
Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const final
Check validity of a FuncTempInfo_t.
Definition TCling.cxx:8839
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:2671
bool ClassInfo_IsBase(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8289
void RecursiveRemove(TObject *obj) final
Delete object from cling symbol table so it can not be used anymore.
Definition TCling.cxx:3692
const char * DataMemberInfo_TypeName(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8684
DeclId_t GetDataMemberAtAddr(const void *addr) const final
Return pointer to cling DeclId for a data member with a given name.
Definition TCling.cxx:4959
void CallFunc_SetArgArray(CallFunc_t *func, Longptr_t *paramArr, Int_t nparam) const final
Definition TCling.cxx:8024
std::string CallFunc_GetWrapperCode(CallFunc_t *func) const final
Definition TCling.cxx:8114
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition TCling.cxx:9666
const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9306
Bool_t HasPCMForLibrary(const char *libname) const final
Return true if ROOT has cxxmodules pcm for a given library name.
Definition TCling.cxx:3156
void TypedefInfo_Init(TypedefInfo_t *tinfo, const char *name) const final
Definition TCling.cxx:9474
const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8708
Longptr_t CallFunc_ExecInt(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7887
void ClearStack() final
Delete existing temporary values.
Definition TCling.cxx:3094
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:7538
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:7358
MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const final
Definition TCling.cxx:7926
bool IsUnsignedIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9565
TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9467
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:5057
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:2402
std::string MethodArgInfo_TypeNormalizedName(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9322
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:4841
Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9290
int TypedefInfo_Size(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9508
void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=nullptr, int nargs=0, void *ret=nullptr) const final
Definition TCling.cxx:7876
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:5209
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:6750
Int_t Load(const char *filenam, Bool_t system=kFALSE) final
Load a library file in cling's memory.
Definition TCling.cxx:3524
int TypedefInfo_Next(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9492
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:5016
void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const final
Definition TCling.cxx:9373
Bool_t SetSuspendAutoParsing(Bool_t value) final
Suspend the Autoparsing of headers.
Definition TCling.cxx:7598
int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8676
static void * fgSetOfSpecials
Definition TCling.h:105
const char * ClassInfo_Title(ClassInfo_t *info) const final
Definition TCling.cxx:8444
const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8700
const char * TypeName(const char *typeDesc) final
Return the absolute type of typeDesc.
Definition TCling.cxx:5487
ROOT::TMetaUtils::TNormalizedCtxt * fNormalizedCtxt
Definition TCling.h:134
bool IsSignedIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9557
void ForgetMutexState() final
Definition TCling.cxx:9620
int MethodInfo_Next(MethodInfo_t *minfo) const final
Definition TCling.cxx:9085
Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const final
Definition TCling.cxx:8178
void MethodInfo_Delete(MethodInfo_t *minfo) const final
Interface to cling function.
Definition TCling.cxx:9004
bool fIsShuttingDown
Definition TCling.h:187
void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9243
DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo, TDictionary::EMemberSelection selection) const final
Definition TCling.cxx:8601
void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const final
Definition TCling.cxx:8209
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:6119
Int_t UnloadAllSharedLibraryMaps() final
Unload the library map entries coming from all the loaded shared libraries.
Definition TCling.cxx:6007
void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const final
Definition TCling.cxx:8271
std::set< TClass * > & GetModTClasses()
Definition TCling.h:579
ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const final
Definition TCling.cxx:8539
TClingCallbacks * fClingCallbacks
Definition TCling.h:139
Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7895
Long_t ClassInfo_Property(ClassInfo_t *info) const final
Definition TCling.cxx:8394
Longptr_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8518
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:5394
Bool_t IsErrorMessagesEnabled() const final
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition TCling.cxx:7344
TString fIncludePath
Definition TCling.h:115
int DisplayIncludePath(FILE *fout) const final
Interface to cling function.
Definition TCling.cxx:7421
void TransactionRollback(const cling::Transaction &T)
Definition TCling.cxx:6956
Long_t FuncTempInfo_Property(FuncTempInfo_t *) const final
Return the property of the function template.
Definition TCling.cxx:8872
TEnum * CreateEnum(void *VD, TClass *cl) const final
Definition TCling.cxx:469
const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9422
Int_t UnloadLibraryMap(const char *library) final
Unload library map entries coming from the specified library.
Definition TCling.cxx:6025
void RegisterTemporary(const TInterpreterValue &value)
Definition TCling.cxx:7689
MutexStateAndRecurseCount fInitialMutex
Definition TCling.h:174
const char * GetSharedLibs() final
Return the list of shared libraries loaded into the process.
Definition TCling.cxx:6994
int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9282
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx) final
Definition TCling.cxx:9605
Long_t TypeInfo_Property(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9398
const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const final
Definition TCling.cxx:9131
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:8862
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:2019
static Int_t ShallowAutoLoadImpl(const char *cls)
Definition TCling.cxx:6165
void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const final
Definition TCling.cxx:9011
Bool_t CheckClassTemplate(const char *name) final
Return true if there is a class template by the given name ...
Definition TCling.cxx:4358
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6979
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:2393
TObjArray * GetRootMapFiles() const final
Definition TCling.h:223
bool DataMemberInfo_IsValid(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8628
bool ClassInfo_IsEnum(const char *name) const final
Definition TCling.cxx:8297
int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9077
void CreateListOfMethods(TClass *cl) const final
Create list of pointers to methods for TClass cl.
Definition TCling.cxx:4507
Int_t RescanLibraryMap() final
Scan again along the dynamic path for library maps.
Definition TCling.cxx:5934
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:7617
const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9120
Bool_t fHeaderParsingOnDemand
Definition TCling.h:181
bool IsIntegerType(const void *QualTypePtr) const
Definition TCling.cxx:9549
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:5119
void * ClassInfo_New(ClassInfo_t *info) const final
Definition TCling.cxx:8362
int DisplayClass(FILE *fout, const char *name, int base, int start) const final
Definition TCling.cxx:7412
virtual void GetFunctionName(const clang::Decl *decl, std::string &name) const
Definition TCling.cxx:8763
void CreateListOfMethodArgs(TFunction *m) const final
Create list of pointers to method arguments for TMethod m.
Definition TCling.cxx:4532
virtual const char * GetSTLIncludePath() const final
Return the directory containing CINT's stl cintdlls.
Definition TCling.cxx:7403
MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const final
Definition TCling.cxx:9266
Longptr_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const final
Definition TCling.cxx:8510
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:4186
void * FindSym(const char *entry) const final
Interface to cling function.
Definition TCling.cxx:7450
void RegisterLoadedSharedLibrary(const char *name)
Register a new shared library name with the interpreter; add it to fSharedLibs.
Definition TCling.cxx:3424
void TypeInfo_Delete(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9343
int MethodInfo_NArg(MethodInfo_t *minfo) const final
Definition TCling.cxx:9069
DeclId_t GetDataMemberWithValue(const void *ptrvalue) const final
NOT IMPLEMENTED.
Definition TCling.cxx:4950
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition TCling.h:125
EReturnType MethodCallReturnType(TFunction *func) const final
Definition TCling.cxx:9179
void ProcessClassesToUpdate()
Definition TCling.cxx:1989
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:5142
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:4971
const char * MethodInfo_Title(MethodInfo_t *minfo) const final
Definition TCling.cxx:9170
TString fRootmapLoadPath
Definition TCling.h:116
const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8573
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:3107
const char * BaseClassInfo_FullName(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8555
void CallFunc_SetArgs(CallFunc_t *func, const char *param) const final
Definition TCling.cxx:8032
int UnloadFile(const char *path) const final
Definition TCling.cxx:7650
void SetClassInfo(TClass *cl, Bool_t reload=kFALSE, Bool_t silent=kFALSE) final
Set pointer to the TClingClassInfo in TClass.
Definition TCling.cxx:4050
void CallFunc_Exec(CallFunc_t *func, void *address) const final
Definition TCling.cxx:7852
bool IsPointerType(const void *QualTypePtr) const
Definition TCling.cxx:9581
bool IsFloatingType(const void *QualTypePtr) const
Definition TCling.cxx:9573
Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const final
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition TCling.cxx:8933
bool CallFunc_IsValid(CallFunc_t *func) const final
Definition TCling.cxx:7951
const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8565
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition TCling.h:135
const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8716
Int_t GetMore() const final
Return whether we are waiting for more input either because the collected input contains unbalanced b...
Definition TCling.cxx:4553
Bool_t fIsAutoParsingSuspended
Definition TCling.h:182
std::string ToString(const char *type, void *obj) final
Definition TCling.cxx:1032
DeclId_t GetDeclId(const llvm::GlobalValue *gv) const
Return pointer to cling DeclId for a global value.
Definition TCling.cxx:4881
void Execute(const char *function, const char *params, int *error=nullptr) final
Execute a global function with arguments params.
Definition TCling.cxx:5242
bool ClassInfo_IsLoaded(ClassInfo_t *info) const final
Definition TCling.cxx:8322
Longptr_t ClassInfo_Tagnum(ClassInfo_t *info) const final
Definition TCling.cxx:8410
Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8531
void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Longptr_t *Offset) const final
Definition TCling.cxx:8040
std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const final
Get the scopes representing using declarations of namespace.
Definition TCling.cxx:4487
const char * ClassInfo_FileName(ClassInfo_t *info) const final
Definition TCling.cxx:8418
void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const final
Return the comments associates with this function template.
Definition TCling.cxx:8972
const char * ClassInfo_TmpltName(ClassInfo_t *info) const final
Definition TCling.cxx:8452
void SaveContext() final
Save the current Cling state.
Definition TCling.cxx:3868
void LoadPCMImpl(TFile &pcmFile)
Tries to load a PCM from TFile; returns true on success.
Definition TCling.cxx:1705
Bool_t IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition TCling.cxx:6636
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:3749
void CodeComplete(const std::string &, size_t &, std::vector< std::string > &) final
The call to Cling's tab complition.
Definition TCling.cxx:7672
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:3763
const char * MapCppName(const char *) const final
Interface to cling function.
Definition TCling.cxx:7525
Longptr_t Calc(const char *line, EErrorCode *error=nullptr) final
Directly execute an executable statement (e.g.
Definition TCling.cxx:3594
Int_t ReloadAllSharedLibraryMaps() final
Reload the library map entries coming from all the loaded shared libraries, after first unloading the...
Definition TCling.cxx:5946
void UpdateListOfGlobalFunctions() final
No op: see TClingCallbacks (used to update the list of global functions)
Definition TCling.cxx:3901
void DataMemberInfo_Delete(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8594
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:5425
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:4525
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:2693
Int_t SetClassSharedLibs(const char *cls, const char *libs) final
Register the AutoLoading information for a class.
Definition TCling.cxx:6087
MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const final
Definition TCling.cxx:9045
std::set< const char * > fParsedPayloadsAddresses
Definition TCling.h:123
CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const final
Definition TCling.cxx:7960
MethodArgInfo_t * MethodArgInfo_Factory() const final
Definition TCling.cxx:9250
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition TCling.cxx:6744
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:5038
void ClassInfo_Delete(ClassInfo_t *info) const final
Definition TCling.cxx:8186
std::unique_ptr< cling::Interpreter > fInterpreter
Definition TCling.h:130
EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const final
Definition TCling.cxx:8313
void FuncTempInfo_Delete(FuncTempInfo_t *) const final
Delete the FuncTempInfo_t.
Definition TCling.cxx:8808
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:5186
Int_t DeleteVariable(const char *name) final
Undeclare obj called name.
Definition TCling.cxx:3807
Longptr_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8652
CallFunc_t * CallFunc_Factory() const final
Definition TCling.cxx:7911
MethodInfo_t * MethodInfo_Factory() const final
Definition TCling.cxx:9020
Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const final
Definition TCling.cxx:8668
void ClearFileBusy() final
Reset the interpreter internal state in case a previous action was not correctly terminated.
Definition TCling.cxx:3086
cling::MetaProcessor * GetMetaProcessorImpl() const
Definition TCling.h:645
bool DiagnoseIfInterpreterException(const std::exception &e) const final
Definition TCling.cxx:2451
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:7548
std::set< size_t > fLookedUpClasses
Definition TCling.h:121
virtual void AddAvailableIndentifiers(TSeqCollection &Idents) final
Definition TCling.cxx:2367
void TypedefInfo_Delete(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9444
void Reset() final
Pressing Ctrl+C should forward here.
Definition TCling.cxx:3717
const char * TypedefInfo_TrueName(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9516
int SetClassAutoLoading(int) const final
Enable/Disable the AutoLoading of libraries.
Definition TCling.cxx:7569
const char * ClassInfo_FullName(ClassInfo_t *info) const final
Definition TCling.cxx:8426
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:6390
const char * MethodInfo_TypeName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9149
void CallFunc_SetArg(CallFunc_t *func, Long_t param) const final
Definition TCling.cxx:7976
const char * GetIncludePath() final
Refresh the list of include paths known to the interpreter and return it with -I prepended.
Definition TCling.cxx:7372
void UpdateListsOnUnloaded(const cling::Transaction &T)
Invalidate stored TCling state for declarations included in transaction ‘T’.
Definition TCling.cxx:6854
void UpdateClassInfoWithDecl(const clang::NamedDecl *ND)
Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
Definition TCling.cxx:6686
bool IsSameType(const void *QualTypePtr1, const void *QualTypePtr2) const
Definition TCling.cxx:9540
virtual void Initialize() final
Initialize the interpreter, once TROOT::fInterpreter is set.
Definition TCling.cxx:1645
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:8247
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:4780
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:8959
std::unique_ptr< cling::MetaProcessor > fMetaProcessor
Definition TCling.h:131
bool TypeInfo_IsValid(TypeInfo_t *tinfo) const final
Definition TCling.cxx:9382
bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const final
Definition TCling.cxx:1915
std::string MethodInfo_TypeNormalizedName(MethodInfo_t *minfo) const final
Definition TCling.cxx:9158
const char * ClassInfo_Name(ClassInfo_t *info) const final
Definition TCling.cxx:8436
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE) final
Generate a TClass for the given class.
Definition TCling.cxx:4563
ULong64_t fTransactionCount
Definition TCling.h:148
bool ClassInfo_HasDefaultConstructor(ClassInfo_t *info, Bool_t testio=kFALSE) const final
Definition TCling.cxx:8255
void EndOfLineAction() final
It calls a "fantom" method to synchronize user keyboard input and ROOT prompt line.
Definition TCling.cxx:3130
TypeInfo_t * TypeInfo_FactoryCopy(TypeInfo_t *) const final
Definition TCling.cxx:9366
void * TypeInfo_QualTypePtr(TypeInfo_t *tinfo) const
Definition TCling.cxx:9430
bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const final
Definition TCling.cxx:8263
void ClassInfo_DeleteArray(ClassInfo_t *info, void *arena, bool dtorOnly) const final
Definition TCling.cxx:8201
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:8692
virtual void ShutDown() final
Definition TCling.cxx:1664
void UpdateListOfTypes() final
No op: see TClingCallbacks (used to update the list of types)
Definition TCling.cxx:3908
Long_t TypedefInfo_Property(TypedefInfo_t *tinfo) const final
Definition TCling.cxx:9500
void RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Register Rdict data for future loading by LoadPCM;.
Definition TCling.cxx:1687
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:3578
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:4998
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition TCling.cxx:6759
Int_t LoadLibraryMap(const char *rootmapfile=nullptr) final
Load map between class and library.
Definition TCling.cxx:5750
Longptr_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const final
Definition TCling.cxx:8547
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition TCling.cxx:6986
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 const char * GetClassSharedLibs(const char *cls)=0
virtual Bool_t Declare(const char *code)=0
std::vector< std::pair< std::string, int > > FwdDeclArgsToKeepCollection_t
TDictionary::DeclId_t DeclId_t
virtual TObjArray * GetRootMapFiles() const =0
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition TKey.h:28
A collection of TDataMember objects designed for fast access given a DeclId_t and for keep track of T...
TObject * FindObject(const char *name) const override
Specialize FindObject to do search for the a data member just by name or create it if its not already...
TDictionary * Find(DeclId_t id) const
Return (after creating it if necessary) the TDataMember describing the data member corresponding to t...
TClass * GetClass() const
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
TEnum * Find(DeclId_t id) const
Return the TEnum corresponding to the Decl 'id' or NULL if it does not exist.
TEnum * Get(DeclId_t id, const char *name)
Return (after creating it if necessary) the TEnum describing the enum corresponding to the Decl 'id'.
TClass * GetClass() const
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
TFunctionTemplate * Get(DeclId_t id)
Return (after creating it if necessary) the TMethod or TFunction describing the function correspondin...
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
TFunction * Find(DeclId_t id) const
Return the TMethod or TFunction describing the function corresponding to the Decl 'id'.
A doubly linked list.
Definition TList.h:38
void Add(TObject *obj) override
Definition TList.h:83
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:973
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:403
static TClass * Class()
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:987
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1015
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:483
virtual TClass * IsA() const
Definition TObject.h:243
void MakeZombie()
Definition TObject.h:53
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:72
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:961
Persistent version of a TClass.
Definition TProtoClass.h:38
static const TString & GetIncludeDir()
Get the include directory in the installation. Static utility function.
Definition TROOT.cxx:3042
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:2952
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition TROOT.cxx:3052
static const char **& GetExtraInterpreterArgs()
INTERNAL function! Used by rootcling to inject interpreter arguments through a C-interface layer.
Definition TROOT.cxx:2962
static const TString & GetSharedLibDir()
Get the shared libraries directory in the installation. Static utility function.
Definition TROOT.cxx:3031
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 mangled version of the C++ symbol/type (pass as 'input') that can...
std::pair< bool, int > GetTrivialIntegralReturnValue(const clang::FunctionDecl *funcCV, const cling::Interpreter &interp)
If the function contains 'just': return SomeValue; this routine will extract this value and return it...
std::string GetRealPath(const std::string &path)
void GetQualifiedName(std::string &qual_name, const clang::QualType &type, const clang::NamedDecl &forcontext)
Main implementation relying on GetFullyQualifiedTypeName All other GetQualifiedName functions leverag...
llvm::StringRef GetComment(const clang::Decl &decl, clang::SourceLocation *loc=nullptr)
Returns the comment (// striped away), annotating declaration in a meaningful for ROOT IO way.
void SetPathsForRelocatability(std::vector< std::string > &clingArgs)
Organise the parameters for cling in order to guarantee relocatability It treats the gcc toolchain an...
const clang::Type * GetUnderlyingType(clang::QualType type)
Return the base/underlying type of a chain of array or pointers type.
ROOT::ESTLType IsSTLCont(const clang::RecordDecl &cl)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container abs(result):...
bool ExtractAttrPropertyFromName(const clang::Decl &decl, const std::string &propName, std::string &propValue)
This routine counts on the "propName<separator>propValue" format.
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:194
Long_t fMemResident
Definition TSystem.h:193
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()