Logo ROOT  
Reference Guide
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 "TBaseClass.h"
44#include "TDataMember.h"
45#include "TMemberInspector.h"
46#include "TMethod.h"
47#include "TMethodArg.h"
48#include "TFunctionTemplate.h"
49#include "TObjArray.h"
50#include "TObjString.h"
51#include "TString.h"
52#include "THashList.h"
53#include "TVirtualPad.h"
54#include "TSystem.h"
55#include "TVirtualMutex.h"
56#include "TError.h"
57#include "TEnv.h"
58#include "TEnum.h"
59#include "TEnumConstant.h"
60#include "THashTable.h"
62#include "RConfigure.h"
63#include "compiledata.h"
64#include "TClingUtils.h"
67#include "TListOfDataMembers.h"
68#include "TListOfEnums.h"
70#include "TListOfFunctions.h"
72#include "TMemFile.h"
73#include "TProtoClass.h"
74#include "TStreamerInfo.h" // This is here to avoid to use the plugin manager
75#include "ThreadLocalStorage.h"
76#include "TFile.h"
77#include "TKey.h"
78#include "ClingRAII.h"
79
80#include "clang/AST/ASTContext.h"
81#include "clang/AST/Decl.h"
82#include "clang/AST/DeclarationName.h"
83#include "clang/AST/GlobalDecl.h"
84#include "clang/AST/RecordLayout.h"
85#include "clang/AST/DeclVisitor.h"
86#include "clang/AST/RecursiveASTVisitor.h"
87#include "clang/AST/Type.h"
88#include "clang/Basic/SourceLocation.h"
89#include "clang/Basic/Specifiers.h"
90#include "clang/Basic/TargetInfo.h"
91#include "clang/CodeGen/ModuleBuilder.h"
92#include "clang/Frontend/CompilerInstance.h"
93#include "clang/Frontend/FrontendDiagnostic.h"
94#include "clang/Lex/HeaderSearch.h"
95#include "clang/Lex/Preprocessor.h"
96#include "clang/Lex/PreprocessorOptions.h"
97#include "clang/Parse/Parser.h"
98#include "clang/Sema/Lookup.h"
99#include "clang/Sema/Sema.h"
100#include "clang/Serialization/ASTReader.h"
101#include "clang/Serialization/GlobalModuleIndex.h"
102
103#include "cling/Interpreter/ClangInternalState.h"
104#include "cling/Interpreter/DynamicLibraryManager.h"
105#include "cling/Interpreter/Interpreter.h"
106#include "cling/Interpreter/LookupHelper.h"
107#include "cling/Interpreter/Value.h"
108#include "cling/Interpreter/Transaction.h"
109#include "cling/MetaProcessor/MetaProcessor.h"
110#include "cling/Utils/AST.h"
111#include "cling/Utils/ParserStateRAII.h"
112#include "cling/Utils/SourceNormalization.h"
113#include "cling/Interpreter/Exception.h"
114
115#include "llvm/IR/GlobalValue.h"
116#include "llvm/IR/Module.h"
117
118#include "llvm/Support/DynamicLibrary.h"
119#include "llvm/Support/raw_ostream.h"
120#include "llvm/Support/Path.h"
121#include "llvm/Support/Process.h"
122#include "llvm/Object/ELFObjectFile.h"
123#include "llvm/Object/ObjectFile.h"
124#include "llvm/Object/SymbolicFile.h"
125#include "llvm/Support/FileSystem.h"
126
127#include <algorithm>
128#include <iostream>
129#include <cassert>
130#include <map>
131#include <set>
132#include <stdexcept>
133#include <stdint.h>
134#include <fstream>
135#include <sstream>
136#include <string>
137#include <tuple>
138#include <typeinfo>
139#include <unordered_map>
140#include <unordered_set>
141#include <utility>
142#include <vector>
143#include <functional>
144
145#ifndef R__WIN32
146#include <cxxabi.h>
147#define R__DLLEXPORT __attribute__ ((visibility ("default")))
148#include <sys/stat.h>
149#endif
150#include <limits.h>
151#include <stdio.h>
152
153#ifdef __APPLE__
154#include <dlfcn.h>
155#include <mach-o/dyld.h>
156#include <mach-o/loader.h>
157#endif // __APPLE__
158
159#ifdef R__UNIX
160#include <dlfcn.h>
161#endif
162
163#ifdef R__LINUX
164# ifndef _GNU_SOURCE
165# define _GNU_SOURCE
166# endif
167# include <link.h> // dl_iterate_phdr()
168#endif
169
170#if defined(__CYGWIN__)
171#include <sys/cygwin.h>
172#define HMODULE void *
173extern "C" {
174 __declspec(dllimport) void * __stdcall GetCurrentProcess();
175 __declspec(dllimport) bool __stdcall EnumProcessModules(void *, void **, unsigned long, unsigned long *);
176 __declspec(dllimport) unsigned long __stdcall GetModuleFileNameExW(void *, void *, wchar_t *, unsigned long);
177}
178#endif
179
180// Fragment copied from LLVM's raw_ostream.cpp
181#if defined(_MSC_VER)
182#ifndef STDIN_FILENO
183# define STDIN_FILENO 0
184#endif
185#ifndef STDOUT_FILENO
186# define STDOUT_FILENO 1
187#endif
188#ifndef STDERR_FILENO
189# define STDERR_FILENO 2
190#endif
191#ifndef R__WIN32
192//#if defined(HAVE_UNISTD_H)
193# include <unistd.h>
194//#endif
195#else
196#include "Windows4Root.h"
197#include <Psapi.h>
198#undef GetModuleFileName
199#define RTLD_DEFAULT ((void *)::GetModuleHandle(NULL))
200#define dlsym(library, function_name) ::GetProcAddress((HMODULE)library, function_name)
201#define dlopen(library_name, flags) ::LoadLibraryA(library_name)
202#define dlclose(library) ::FreeLibrary((HMODULE)library)
203#define R__DLLEXPORT __declspec(dllexport)
204#endif
205#endif
206
207//______________________________________________________________________________
208// Infrastructure to detect and react to libCling being teared down.
209//
210namespace {
211 class TCling_UnloadMarker {
212 public:
213 ~~TCling_UnloadMarker() {
216 }
217 }
218 };
219 static TCling_UnloadMarker gTClingUnloadMarker;
220}
221
222
223
224//______________________________________________________________________________
225// These functions are helpers for debugging issues with non-LLVMDEV builds.
226//
227R__DLLEXPORT clang::DeclContext* TCling__DEBUG__getDeclContext(clang::Decl* D) {
228 return D->getDeclContext();
229}
230R__DLLEXPORT clang::NamespaceDecl* TCling__DEBUG__DCtoNamespace(clang::DeclContext* DC) {
231 return llvm::dyn_cast<clang::NamespaceDecl>(DC);
232}
233R__DLLEXPORT clang::RecordDecl* TCling__DEBUG__DCtoRecordDecl(clang::DeclContext* DC) {
234 return llvm::dyn_cast<clang::RecordDecl>(DC);
235}
236R__DLLEXPORT void TCling__DEBUG__dump(clang::DeclContext* DC) {
237 return DC->dumpDeclContext();
238}
239R__DLLEXPORT void TCling__DEBUG__dump(clang::Decl* D) {
240 return D->dump();
241}
242R__DLLEXPORT void TCling__DEBUG__dump(clang::FunctionDecl* FD) {
243 return FD->dump();
244}
246 return ((clang::Decl*)D)->dump();
247}
249 if (clang::NamedDecl* ND = llvm::dyn_cast<clang::NamedDecl>(D)) {
250 std::string name;
251 {
252 llvm::raw_string_ostream OS(name);
253 ND->getNameForDiagnostic(OS, D->getASTContext().getPrintingPolicy(),
254 true /*Qualified*/);
255 }
256 printf("%s\n", name.c_str());
257 }
258}
259//______________________________________________________________________________
260// These functions are helpers for testing issues directly rather than
261// relying on side effects.
262// This is used for the test for ROOT-7462/ROOT-6070
264 return D->isInvalidDecl();
265}
266R__DLLEXPORT bool TCling__TEST_isInvalidDecl(ClassInfo_t *input) {
267 TClingClassInfo *info( (TClingClassInfo*) input);
268 assert(info && info->IsValid());
269 return info->GetDecl()->isInvalidDecl();
270}
271
272using namespace std;
273using namespace clang;
274using namespace ROOT;
275
276namespace {
277 static const std::string gInterpreterClassDef = R"ICF(
278#undef ClassDef
279#define ClassDef(name, id) \
280_ClassDefInterp_(name,id,virtual,) \
281static int DeclFileLine() { return __LINE__; }
282#undef ClassDefNV
283#define ClassDefNV(name, id) \
284_ClassDefInterp_(name,id,,) \
285static int DeclFileLine() { return __LINE__; }
286#undef ClassDefOverride
287#define ClassDefOverride(name, id) \
288_ClassDefInterp_(name,id,,override) \
289static int DeclFileLine() { return __LINE__; }
290)ICF";
291
292 static const std::string gNonInterpreterClassDef = R"ICF(
293#define __ROOTCLING__ 1
294#undef ClassDef
295#define ClassDef(name,id) \
296_ClassDefOutline_(name,id,virtual,) \
297static int DeclFileLine() { return __LINE__; }
298#undef ClassDefNV
299#define ClassDefNV(name, id)\
300_ClassDefOutline_(name,id,,)\
301static int DeclFileLine() { return __LINE__; }
302#undef ClassDefOverride
303#define ClassDefOverride(name, id)\
304_ClassDefOutline_(name,id,,override)\
305static int DeclFileLine() { return __LINE__; }
306)ICF";
307
308// The macros below use ::Error, so let's ensure it is included
309 static const std::string gClassDefInterpMacro = R"ICF(
310#include "TError.h"
311
312#define _ClassDefInterp_(name,id,virtual_keyword, overrd) \
313private: \
314public: \
315 static TClass *Class() { static TClass* sIsA = 0; if (!sIsA) sIsA = TClass::GetClass(#name); return sIsA; } \
316 static const char *Class_Name() { return #name; } \
317 virtual_keyword Bool_t CheckTObjectHashConsistency() const overrd { return true; } \
318 static Version_t Class_Version() { return id; } \
319 static TClass *Dictionary() { return 0; } \
320 virtual_keyword TClass *IsA() const overrd { return name::Class(); } \
321 virtual_keyword void ShowMembers(TMemberInspector&insp) const overrd { ::ROOT::Class_ShowMembers(name::Class(), this, insp); } \
322 virtual_keyword void Streamer(TBuffer&) overrd { ::Error("Streamer", "Cannot stream interpreted class."); } \
323 void StreamerNVirtual(TBuffer&ClassDef_StreamerNVirtual_b) { name::Streamer(ClassDef_StreamerNVirtual_b); } \
324 static const char *DeclFileName() { return __FILE__; } \
325 static int ImplFileLine() { return 0; } \
326 static const char *ImplFileName() { return __FILE__; }
327)ICF";
328}
330
331// The functions are used to bridge cling/clang/llvm compiled with no-rtti and
332// ROOT (which uses rtti)
333
334////////////////////////////////////////////////////////////////////////////////
335/// Print a StackTrace!
336
337extern "C"
340}
341
342////////////////////////////////////////////////////////////////////////////////
343/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
344
345extern "C" void TCling__RestoreInterpreterMutex(void *delta)
346{
347 ((TCling*)gCling)->ApplyToInterpreterMutex(delta);
348}
349
350////////////////////////////////////////////////////////////////////////////////
351/// Lookup libraries in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH with mangled_name,
352/// which is extracted by error messages we get from callback from cling. Return true
353/// when the missing library was autoloaded.
354
355extern "C" bool TCling__LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
356{
357 return ((TCling*)gCling)->LibraryLoadingFailed(errmessage, libStem, permanent, resolved);
358}
359
360////////////////////////////////////////////////////////////////////////////////
361/// Reset the interpreter lock to the state it had before interpreter-related
362/// calls happened.
363
365{
366 return ((TCling*)gCling)->RewindInterpreterMutex();
367}
368
369////////////////////////////////////////////////////////////////////////////////
370/// Lock the interpreter.
371
373{
374 if (gInterpreterMutex) {
376 }
377 return nullptr;
378}
379
380////////////////////////////////////////////////////////////////////////////////
381/// Unlock the interpreter.
382
384{
385 if (gInterpreterMutex) {
387 }
388}
389
390////////////////////////////////////////////////////////////////////////////////
391/// Update TClingClassInfo for a class (e.g. upon seeing a definition).
392
393static void TCling__UpdateClassInfo(const NamedDecl* TD)
394{
395 static Bool_t entered = kFALSE;
396 static vector<const NamedDecl*> updateList;
397 Bool_t topLevel;
398
399 if (entered) topLevel = kFALSE;
400 else {
401 entered = kTRUE;
402 topLevel = kTRUE;
403 }
404 if (topLevel) {
405 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(TD);
406 } else {
407 // If we are called indirectly from within another call to
408 // TCling::UpdateClassInfo, we delay the update until the dictionary loading
409 // is finished (i.e. when we return to the top level TCling::UpdateClassInfo).
410 // This allows for the dictionary to be fully populated when we actually
411 // update the TClass object. The updating of the TClass sometimes
412 // (STL containers and when there is an emulated class) forces the building
413 // of the TClass object's real data (which needs the dictionary info).
414 updateList.push_back(TD);
415 }
416 if (topLevel) {
417 while (!updateList.empty()) {
418 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(updateList.back());
419 updateList.pop_back();
420 }
421 entered = kFALSE;
422 }
423}
424
425void TCling::UpdateEnumConstants(TEnum* enumObj, TClass* cl) const {
426 const clang::Decl* D = static_cast<const clang::Decl*>(enumObj->GetDeclId());
427 if(const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(D)) {
428 // Add the constants to the enum type.
429 for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin(),
430 EDE = ED->enumerator_end(); EDI != EDE; ++EDI) {
431 // Get name of the enum type.
432 std::string constbuf;
433 if (const NamedDecl* END = llvm::dyn_cast<NamedDecl>(*EDI)) {
434 PrintingPolicy Policy((*EDI)->getASTContext().getPrintingPolicy());
435 llvm::raw_string_ostream stream(constbuf);
436 // Don't trigger fopen of the source file to count lines:
437 Policy.AnonymousTagLocations = false;
438 (END)->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
439 }
440 const char* constantName = constbuf.c_str();
441
442 // Get value of the constant.
443 Long64_t value;
444 const llvm::APSInt valAPSInt = (*EDI)->getInitVal();
445 if (valAPSInt.isSigned()) {
446 value = valAPSInt.getSExtValue();
447 } else {
448 value = valAPSInt.getZExtValue();
449 }
450
451 // Create the TEnumConstant or update it if existing
452 TEnumConstant* enumConstant = nullptr;
453 TClingClassInfo* tcCInfo = (TClingClassInfo*)(cl ? cl->GetClassInfo() : 0);
454 TClingDataMemberInfo* tcDmInfo = new TClingDataMemberInfo(GetInterpreterImpl(), *EDI, tcCInfo);
455 DataMemberInfo_t* dmInfo = (DataMemberInfo_t*) tcDmInfo;
456 if (TObject* encAsTObj = enumObj->GetConstants()->FindObject(constantName)){
457 ((TEnumConstant*)encAsTObj)->Update(dmInfo);
458 } else {
459 enumConstant = new TEnumConstant(dmInfo, constantName, value, enumObj);
460 }
461
462 // Add the global constants to the list of Globals.
463 if (!cl) {
464 TCollection* globals = gROOT->GetListOfGlobals(false);
465 if (!globals->FindObject(constantName)) {
466 globals->Add(enumConstant);
467 }
468 }
469 }
470 }
471}
472
473TEnum* TCling::CreateEnum(void *VD, TClass *cl) const
474{
475 // Handle new enum declaration for either global and nested enums.
476
477 // Create the enum type.
478 TEnum* enumType = 0;
479 const clang::Decl* D = static_cast<const clang::Decl*>(VD);
480 std::string buf;
481 if (const EnumDecl* ED = llvm::dyn_cast<EnumDecl>(D)) {
482 // Get name of the enum type.
483 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
484 llvm::raw_string_ostream stream(buf);
485 // Don't trigger fopen of the source file to count lines:
486 Policy.AnonymousTagLocations = false;
487 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
488 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
489 }
490 if (buf.empty()) {
491 return 0;
492 }
493 const char* name = buf.c_str();
494 enumType = new TEnum(name, VD, cl);
495 UpdateEnumConstants(enumType, cl);
496
497 return enumType;
498}
499
500void TCling::HandleNewDecl(const void* DV, bool isDeserialized, std::set<TClass*> &modifiedTClasses) {
501 // Handle new declaration.
502 // Record the modified class, struct and namespaces in 'modifiedTClasses'.
503
504 const clang::Decl* D = static_cast<const clang::Decl*>(DV);
505
506 if (!D->isCanonicalDecl() && !isa<clang::NamespaceDecl>(D)
507 && !dyn_cast<clang::RecordDecl>(D)) return;
508
509 if (isa<clang::FunctionDecl>(D->getDeclContext())
510 || isa<clang::TagDecl>(D->getDeclContext()))
511 return;
512
513 // Don't list templates.
514 if (const clang::CXXRecordDecl* RD = dyn_cast<clang::CXXRecordDecl>(D)) {
515 if (RD->getDescribedClassTemplate())
516 return;
517 } else if (const clang::FunctionDecl* FD = dyn_cast<clang::FunctionDecl>(D)) {
518 if (FD->getDescribedFunctionTemplate())
519 return;
520 }
521
522 if (const RecordDecl *TD = dyn_cast<RecordDecl>(D)) {
523 if (TD->isCanonicalDecl() || TD->isThisDeclarationADefinition())
525 }
526 else if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
527
528 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
529 // Mostly just for EnumDecl (the other TagDecl are handled
530 // by the 'RecordDecl' if statement.
532 } else if (const NamespaceDecl* NSD = dyn_cast<NamespaceDecl>(D)) {
534 }
535
536 // We care about declarations on the global scope.
537 if (!isa<TranslationUnitDecl>(ND->getDeclContext()))
538 return;
539
540 // Enums are lazyly created, thus we don not need to handle them here.
541 if (isa<EnumDecl>(ND))
542 return;
543
544 // ROOT says that global is enum(lazylycreated)/var/field declared on the global
545 // scope.
546 if (!(isa<VarDecl>(ND)))
547 return;
548
549 // Skip if already in the list.
550 if (gROOT->GetListOfGlobals()->FindObject(ND->getNameAsString().c_str()))
551 return;
552
553 // Put the global constants and global enums in the corresponding lists.
554 gROOT->GetListOfGlobals()->Add(new TGlobal((DataMemberInfo_t *)
556 cast<ValueDecl>(ND), 0)));
557 }
558}
559
560extern "C"
562{
563 // We are sure in this context of the type of the interpreter
564 normCtxt = &( (TCling*) gInterpreter)->GetNormalizedContext();
565}
566
567extern "C"
568void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter*) {
569 ((TCling*)gCling)->UpdateListsOnCommitted(T);
570}
571
572extern "C"
573void TCling__UpdateListsOnUnloaded(const cling::Transaction &T) {
574 ((TCling*)gCling)->UpdateListsOnUnloaded(T);
575}
576
577extern "C"
578void TCling__InvalidateGlobal(const clang::Decl *D) {
579 ((TCling*)gCling)->InvalidateGlobal(D);
580}
581
582extern "C"
583void TCling__TransactionRollback(const cling::Transaction &T) {
584 ((TCling*)gCling)->TransactionRollback(T);
585}
586
587extern "C" void TCling__LibraryLoadedRTTI(const void* dyLibHandle,
588 const char* canonicalName) {
589 ((TCling*)gCling)->LibraryLoaded(dyLibHandle, canonicalName);
590}
591
592extern "C" void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
593{
594 ((TCling *)gCling)->RegisterRdictForLoadPCM(pcmFileNameFullPath, pcmContent);
595}
596
597extern "C" void TCling__LibraryUnloadedRTTI(const void* dyLibHandle,
598 const char* canonicalName) {
599 ((TCling*)gCling)->LibraryUnloaded(dyLibHandle, canonicalName);
600}
601
602
603extern "C"
604TObject* TCling__GetObjectAddress(const char *Name, void *&LookupCtx) {
605 return ((TCling*)gCling)->GetObjectAddress(Name, LookupCtx);
606}
607
608extern "C" const Decl* TCling__GetObjectDecl(TObject *obj) {
609 return ((TClingClassInfo*)obj->IsA()->GetClassInfo())->GetDecl();
610}
611
612extern "C" R__DLLEXPORT TInterpreter *CreateInterpreter(void* interpLibHandle,
613 const char* argv[])
614{
615 cling::DynamicLibraryManager::ExposeHiddenSharedLibrarySymbols(interpLibHandle);
616 return new TCling("C++", "cling C++ Interpreter", argv);
617}
618
620{
621 delete interp;
622}
623
624// Load library containing specified class. Returns 0 in case of error
625// and 1 in case if success.
626extern "C" int TCling__AutoLoadCallback(const char* className)
627{
628 return ((TCling*)gCling)->AutoLoad(className);
629}
630
631extern "C" int TCling__AutoParseCallback(const char* className)
632{
633 return ((TCling*)gCling)->AutoParse(className);
634}
635
636extern "C" const char* TCling__GetClassSharedLibs(const char* className)
637{
638 return ((TCling*)gCling)->GetClassSharedLibs(className);
639}
640
641// Returns 0 for failure 1 for success
642extern "C" int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
643{
644 return ((TCling*)gCling)->IsAutoLoadNamespaceCandidate(nsDecl);
645}
646
647extern "C" int TCling__CompileMacro(const char *fileName, const char *options)
648{
649 string file(fileName);
650 string opt(options);
651 return gSystem->CompileMacro(file.c_str(), opt.c_str());
652}
653
654extern "C" void TCling__SplitAclicMode(const char* fileName, string &mode,
655 string &args, string &io, string &fname)
656{
657 string file(fileName);
658 TString f, amode, arguments, aclicio;
659 f = gSystem->SplitAclicMode(file.c_str(), amode, arguments, aclicio);
660 mode = amode.Data(); args = arguments.Data();
661 io = aclicio.Data(); fname = f.Data();
662}
663
664//______________________________________________________________________________
665//
666//
667//
668
669#ifdef R__WIN32
670extern "C" {
671 char *__unDName(char *demangled, const char *mangled, int out_len,
672 void * (* pAlloc )(size_t), void (* pFree )(void *),
673 unsigned short int flags);
674}
675#endif
676
677////////////////////////////////////////////////////////////////////////////////
678/// Find a template decl within N nested namespaces, 0<=N<inf
679/// Assumes 1 and only 1 template present and 1 and only 1 entity contained
680/// by the namespace. Example: ns1::ns2::..::nsN::myTemplate
681/// Returns nullptr in case of error
682
683static clang::ClassTemplateDecl* FindTemplateInNamespace(clang::Decl* decl)
684{
685 using namespace clang;
686 if (NamespaceDecl* nsd = llvm::dyn_cast<NamespaceDecl>(decl)){
687 return FindTemplateInNamespace(*nsd->decls_begin());
688 }
689
690 if (ClassTemplateDecl* ctd = llvm::dyn_cast<ClassTemplateDecl>(decl)){
691 return ctd;
692 }
693
694 return nullptr; // something went wrong.
695}
696
697////////////////////////////////////////////////////////////////////////////////
698/// Autoload a library provided the mangled name of a missing symbol.
699
700void* llvmLazyFunctionCreator(const std::string& mangled_name)
701{
702 return ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
703}
704
705//______________________________________________________________________________
706//
707//
708//
709
710int TCling_GenerateDictionary(const std::vector<std::string> &classes,
711 const std::vector<std::string> &headers,
712 const std::vector<std::string> &fwdDecls,
713 const std::vector<std::string> &unknown)
714{
715 //This function automatically creates the "LinkDef.h" file for templated
716 //classes then executes CompileMacro on it.
717 //The name of the file depends on the class name, and it's not generated again
718 //if the file exist.
719 if (classes.empty()) {
720 return 0;
721 }
722 // Use the name of the first class as the main name.
723 const std::string& className = classes[0];
724 //(0) prepare file name
725 TString fileName = "AutoDict_";
726 std::string::const_iterator sIt;
727 for (sIt = className.begin(); sIt != className.end(); ++sIt) {
728 if (*sIt == '<' || *sIt == '>' ||
729 *sIt == ' ' || *sIt == '*' ||
730 *sIt == ',' || *sIt == '&' ||
731 *sIt == ':') {
732 fileName += '_';
733 }
734 else {
735 fileName += *sIt;
736 }
737 }
738 if (classes.size() > 1) {
739 Int_t chk = 0;
740 std::vector<std::string>::const_iterator it = classes.begin();
741 while ((++it) != classes.end()) {
742 for (UInt_t cursor = 0; cursor != it->length(); ++cursor) {
743 chk = chk * 3 + it->at(cursor);
744 }
745 }
746 fileName += TString::Format("_%u", chk);
747 }
748 fileName += ".cxx";
749 if (gSystem->AccessPathName(fileName) != 0) {
750 //file does not exist
751 //(1) prepare file data
752 // If STL, also request iterators' operators.
753 // vector is special: we need to check whether
754 // vector::iterator is a typedef to pointer or a
755 // class.
756 static const std::set<std::string> sSTLTypes {
757 "vector","list","forward_list","deque","map","unordered_map","multimap",
758 "unordered_multimap","set","unordered_set","multiset","unordered_multiset",
759 "queue","priority_queue","stack","iterator"};
760 std::vector<std::string>::const_iterator it;
761 std::string fileContent("");
762 for (it = headers.begin(); it != headers.end(); ++it) {
763 fileContent += "#include \"" + *it + "\"\n";
764 }
765 for (it = unknown.begin(); it != unknown.end(); ++it) {
766 TClass* cl = TClass::GetClass(it->c_str());
767 if (cl && cl->GetDeclFileName()) {
768 TString header = gSystem->BaseName(cl->GetDeclFileName());
770 TString dirbase(gSystem->BaseName(dir));
771 while (dirbase.Length() && dirbase != "."
772 && dirbase != "include" && dirbase != "inc"
773 && dirbase != "prec_stl") {
774 gSystem->PrependPathName(dirbase, header);
775 dir = gSystem->GetDirName(dir);
776 }
777 fileContent += TString("#include \"") + header + "\"\n";
778 }
779 }
780 for (it = fwdDecls.begin(); it != fwdDecls.end(); ++it) {
781 fileContent += "class " + *it + ";\n";
782 }
783 fileContent += "#ifdef __CINT__ \n";
784 fileContent += "#pragma link C++ nestedclasses;\n";
785 fileContent += "#pragma link C++ nestedtypedefs;\n";
786 for (it = classes.begin(); it != classes.end(); ++it) {
787 std::string n(*it);
788 size_t posTemplate = n.find('<');
789 std::set<std::string>::const_iterator iSTLType = sSTLTypes.end();
790 if (posTemplate != std::string::npos) {
791 n.erase(posTemplate, std::string::npos);
792 if (n.compare(0, 5, "std::") == 0) {
793 n.erase(0, 5);
794 }
795 iSTLType = sSTLTypes.find(n);
796 }
797 fileContent += "#pragma link C++ class ";
798 fileContent += *it + "+;\n" ;
799 fileContent += "#pragma link C++ class ";
800 if (iSTLType != sSTLTypes.end()) {
801 // STL class; we cannot (and don't need to) store iterators;
802 // their shadow and the compiler's version don't agree. So
803 // don't ask for the '+'
804 fileContent += *it + "::*;\n" ;
805 }
806 else {
807 // Not an STL class; we need to allow the I/O of contained
808 // classes (now that we have a dictionary for them).
809 fileContent += *it + "::*+;\n" ;
810 }
811 }
812 fileContent += "#endif\n";
813 //end(1)
814 //(2) prepare the file
815 FILE* filePointer;
816 filePointer = fopen(fileName, "w");
817 if (filePointer == NULL) {
818 //can't open a file
819 return 1;
820 }
821 //end(2)
822 //write data into the file
823 fprintf(filePointer, "%s", fileContent.c_str());
824 fclose(filePointer);
825 }
826 //(3) checking if we can compile a macro, if not then cleaning
827 Int_t oldErrorIgnoreLevel = gErrorIgnoreLevel;
828 gErrorIgnoreLevel = kWarning; // no "Info: creating library..."
829 Int_t ret = gSystem->CompileMacro(fileName, "k");
830 gErrorIgnoreLevel = oldErrorIgnoreLevel;
831 if (ret == 0) { //can't compile a macro
832 return 2;
833 }
834 //end(3)
835 return 0;
836}
837
838int TCling_GenerateDictionary(const std::string& className,
839 const std::vector<std::string> &headers,
840 const std::vector<std::string> &fwdDecls,
841 const std::vector<std::string> &unknown)
842{
843 //This function automatically creates the "LinkDef.h" file for templated
844 //classes then executes CompileMacro on it.
845 //The name of the file depends on the class name, and it's not generated again
846 //if the file exist.
847 std::vector<std::string> classes;
848 classes.push_back(className);
849 return TCling_GenerateDictionary(classes, headers, fwdDecls, unknown);
850}
851
852//______________________________________________________________________________
853//
854//
855//
856
857// It is a "fantom" method to synchronize user keyboard input
858// and ROOT prompt line (for WIN32)
859const char* fantomline = "TRint::EndOfLineAction();";
860
861//______________________________________________________________________________
862//
863//
864//
865
867
868//______________________________________________________________________________
869//
870// llvm error handler through exceptions; see also cling/UserInterface
871//
872namespace {
873 // Handle fatal llvm errors by throwing an exception.
874 // Yes, throwing exceptions in error handlers is bad.
875 // Doing nothing is pretty terrible, too.
876 void exceptionErrorHandler(void * /*user_data*/,
877 const std::string& reason,
878 bool /*gen_crash_diag*/) {
879 throw std::runtime_error(std::string(">>> Interpreter compilation error:\n") + reason);
880 }
881}
882
883//______________________________________________________________________________
884//
885//
886//
887
888////////////////////////////////////////////////////////////////////////////////
889
890namespace{
891 // An instance of this class causes the diagnostics of clang to be suppressed
892 // during its lifetime
893 class clangDiagSuppr {
894 public:
895 clangDiagSuppr(clang::DiagnosticsEngine& diag): fDiagEngine(diag){
896 fOldDiagValue = fDiagEngine.getIgnoreAllWarnings();
897 fDiagEngine.setIgnoreAllWarnings(true);
898 }
899
900 ~~clangDiagSuppr() {
901 fDiagEngine.setIgnoreAllWarnings(fOldDiagValue);
902 }
903 private:
904 clang::DiagnosticsEngine& fDiagEngine;
905 bool fOldDiagValue;
906 };
907
908}
909
910////////////////////////////////////////////////////////////////////////////////
911/// Allow calling autoparsing from TMetaUtils
912bool TClingLookupHelper__AutoParse(const char *cname)
913{
914 return gCling->AutoParse(cname);
915}
916
917////////////////////////////////////////////////////////////////////////////////
918/// Try hard to avoid looking up in the Cling database as this could enduce
919/// an unwanted autoparsing.
920
921bool TClingLookupHelper__ExistingTypeCheck(const std::string &tname,
922 std::string &result)
923{
924 result.clear();
925
926 unsigned long offset = 0;
927 if (strncmp(tname.c_str(), "const ", 6) == 0) {
928 offset = 6;
929 }
930 unsigned long end = tname.length();
931 while( end && (tname[end-1]=='&' || tname[end-1]=='*' || tname[end-1]==']') ) {
932 if ( tname[end-1]==']' ) {
933 --end;
934 while ( end && tname[end-1]!='[' ) --end;
935 }
936 --end;
937 }
938 std::string innerbuf;
939 const char *inner;
940 if (end != tname.length()) {
941 innerbuf = tname.substr(offset,end-offset);
942 inner = innerbuf.c_str();
943 } else {
944 inner = tname.c_str()+offset;
945 }
946
947 //if (strchr(tname.c_str(),'[')!=0) fprintf(stderr,"DEBUG: checking on %s vs %s %lu %lu\n",tname.c_str(),inner,offset,end);
948 if (gROOT->GetListOfClasses()->FindObject(inner)
949 || TClassTable::Check(inner,result) ) {
950 // This is a known class.
951 return true;
952 }
953
954 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
955 TDataType *type = (TDataType *)typeTable->THashTable::FindObject( inner );
956 if (type) {
957 // This is a raw type and an already loaded typedef.
958 const char *newname = type->GetFullTypeName();
959 if (type->GetType() == kLong64_t) {
960 newname = "Long64_t";
961 } else if (type->GetType() == kULong64_t) {
962 newname = "ULong64_t";
963 }
964 if (strcmp(inner,newname) == 0) {
965 return true;
966 }
967 if (offset) result = "const ";
968 result += newname;
969 if ( end != tname.length() ) {
970 result += tname.substr(end,tname.length()-end);
971 }
972 if (result == tname) result.clear();
973 return true;
974 }
975
976 // Check if the name is an enumerator
977 const auto lastPos = TClassEdit::GetUnqualifiedName(inner);
978 if (lastPos != inner) // Main switch: case 1 - scoped enum, case 2 global enum
979 {
980 // We have a scope
981 // All of this C gymnastic is to avoid allocations on the heap
982 const auto enName = lastPos;
983 const auto scopeNameSize = ((Long64_t)lastPos - (Long64_t)inner) / sizeof(decltype(*lastPos)) - 2;
984 char *scopeName = new char[scopeNameSize + 1];
985 strncpy(scopeName, inner, scopeNameSize);
986 scopeName[scopeNameSize] = '\0';
987 // Check if the scope is in the list of classes
988 if (auto scope = static_cast<TClass *>(gROOT->GetListOfClasses()->FindObject(scopeName))) {
989 auto enumTable = dynamic_cast<const THashList *>(scope->GetListOfEnums(false));
990 if (enumTable && enumTable->THashList::FindObject(enName)) { delete [] scopeName; return true; }
991 }
992 // It may still be in one of the loaded protoclasses
993 else if (auto scope = static_cast<TProtoClass *>(gClassTable->GetProtoNorm(scopeName))) {
994 auto listOfEnums = scope->GetListOfEnums();
995 if (listOfEnums) { // it could be null: no enumerators in the protoclass
996 auto enumTable = dynamic_cast<const THashList *>(listOfEnums);
997 if (enumTable && enumTable->THashList::FindObject(enName)) { delete [] scopeName; return true; }
998 }
999 }
1000 delete [] scopeName;
1001 } else
1002 {
1003 // We don't have any scope: this could only be a global enum
1004 auto enumTable = dynamic_cast<const THashList *>(gROOT->GetListOfEnums());
1005 if (enumTable && enumTable->THashList::FindObject(inner)) return true;
1006 }
1007
1008 if (gCling->GetClassSharedLibs(inner))
1009 {
1010 // This is a class name.
1011 return true;
1012 }
1013
1014 return false;
1015}
1016
1017////////////////////////////////////////////////////////////////////////////////
1018
1020{
1021 fContent.reserve(size);
1022}
1023
1024////////////////////////////////////////////////////////////////////////////////
1025
1027{
1028 return fContent.c_str();
1029}
1030
1031////////////////////////////////////////////////////////////////////////////////
1032/// Append string to the storage if not added already.
1033
1034inline bool TCling::TUniqueString::Append(const std::string& str)
1035{
1036 bool notPresent = fLinesHashSet.emplace(fHashFunc(str)).second;
1037 if (notPresent){
1038 fContent+=str;
1039 }
1040 return notPresent;
1041}
1042
1043std::string TCling::ToString(const char* type, void* obj)
1044{
1045 return fInterpreter->toString(type, obj);
1046}
1047
1048////////////////////////////////////////////////////////////////////////////////
1049///\returns true if the module was loaded.
1050static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
1051{
1052 // When starting up ROOT, cling would load all modulemap files on the include
1053 // paths. However, in a ROOT session, it is very common to run aclic which
1054 // will invoke rootcling and possibly produce a modulemap and a module in
1055 // the current folder.
1056 //
1057 // Before failing, try loading the modulemap in the current folder and try
1058 // loading the requested module from it.
1059 std::string currentDir = gSystem->WorkingDirectory();
1060 assert(!currentDir.empty());
1062 if (gDebug > 2)
1063 ::Info("TCling::__LoadModule", "Preloading module %s. \n",
1064 ModuleName.c_str());
1065
1066 return interp.loadModule(ModuleName, /*Complain=*/true);
1067}
1068
1069////////////////////////////////////////////////////////////////////////////////
1070/// Loads the C++ modules that we require to run any ROOT program. This is just
1071/// supposed to make a C++ module from a modulemap available to the interpreter.
1072static void LoadModules(const std::vector<std::string> &modules, cling::Interpreter &interp)
1073{
1074 for (const auto &modName : modules)
1075 LoadModule(modName, interp);
1076}
1077
1078static bool IsFromRootCling() {
1079 // rootcling also uses TCling for generating the dictionary ROOT files.
1080 const static bool foundSymbol = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
1081 return foundSymbol;
1082}
1083
1084/// Checks if there is an ASTFile on disk for the given module \c M.
1085static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName = nullptr)
1086{
1087 const HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
1088
1089 std::string ModuleFileName;
1090 if (!HSOpts.PrebuiltModulePaths.empty())
1091 // Load the module from *only* in the prebuilt module path.
1092 ModuleFileName = PP.getHeaderSearchInfo().getModuleFileName(M->Name, /*ModuleMapPath*/"", /*UsePrebuiltPath*/ true);
1093 if (FullFileName)
1094 *FullFileName = ModuleFileName;
1095
1096 return !ModuleFileName.empty();
1097}
1098
1099static bool HaveFullGlobalModuleIndex = false;
1100static GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc, cling::Interpreter &interp)
1101{
1102 CompilerInstance &CI = *interp.getCI();
1103 Preprocessor &PP = CI.getPreprocessor();
1104 auto ModuleManager = CI.getModuleManager();
1105 assert(ModuleManager);
1106 // StringRef ModuleIndexPath = HSI.getModuleCachePath();
1107 // HeaderSearch& HSI = PP.getHeaderSearchInfo();
1108 // HSI.setModuleCachePath(TROOT::GetLibDir().Data());
1109 std::string ModuleIndexPath = TROOT::GetLibDir().Data();
1110 if (ModuleIndexPath.empty())
1111 return nullptr;
1112 // Get an existing global index. This loads it if not already loaded.
1113 ModuleManager->resetForReload();
1114 ModuleManager->loadGlobalIndex();
1115 GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex();
1116
1117 // For finding modules needing to be imported for fixit messages,
1118 // we need to make the global index cover all modules, so we do that here.
1119 if (!GlobalIndex && !HaveFullGlobalModuleIndex) {
1120 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1121 bool RecreateIndex = false;
1122 for (ModuleMap::module_iterator I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1123 Module *TheModule = I->second;
1124 // We want the index only of the prebuilt modules.
1125 if (!HasASTFileOnDisk(TheModule, PP))
1126 continue;
1127 LoadModule(TheModule->Name, interp);
1128 RecreateIndex = true;
1129 }
1130 if (RecreateIndex) {
1131 GlobalModuleIndex::writeIndex(CI.getFileManager(), CI.getPCHContainerReader(), ModuleIndexPath);
1132 ModuleManager->resetForReload();
1133 ModuleManager->loadGlobalIndex();
1134 GlobalIndex = ModuleManager->getGlobalIndex();
1135 }
1137 }
1138 return GlobalIndex;
1139}
1140
1141static void RegisterCxxModules(cling::Interpreter &clingInterp)
1142{
1143 if (!clingInterp.getCI()->getLangOpts().Modules)
1144 return;
1145 // Setup core C++ modules if we have any to setup.
1146
1147 // Load libc and stl first.
1148 // Load vcruntime module for windows
1149#ifdef R__WIN32
1150 LoadModule("vcruntime", clingInterp);
1151#endif
1152
1153#ifdef R__MACOSX
1154 LoadModule("Darwin", clingInterp);
1155#else
1156 LoadModule("libc", clingInterp);
1157#endif
1158 LoadModule("std", clingInterp);
1159
1160 LoadModule("_Builtin_intrinsics", clingInterp);
1161
1162 // Load core modules
1163 // This should be vector in order to be able to pass it to LoadModules
1164 std::vector<std::string> CoreModules = {"ROOT_Foundation_C",
1165 "ROOT_Config",
1166 "ROOT_Rtypes",
1167 "ROOT_Foundation_Stage1_NoRTTI",
1168 "Core",
1169 "RIO"};
1170
1171 LoadModules(CoreModules, clingInterp);
1172
1173 // FIXME: Reducing those will let us be less dependent on rootmap files
1174 static constexpr std::array<const char *, 3> ExcludeModules = {
1175 {"Rtools", "RSQLite", "RInterface"}};
1176
1177 // Take this branch only from ROOT because we don't need to preload modules in rootcling
1178 if (!IsFromRootCling()) {
1179 std::vector<std::string> CommonModules = {"MathCore"};
1180 LoadModules(CommonModules, clingInterp);
1181
1182 // These modules should not be preloaded but they fix issues.
1183 std::vector<std::string> FIXMEModules = {"Hist", "Gpad", "Graf",
1184 "GenVector", "Smatrix", "Tree",
1185 "TreePlayer", "Physics",
1186 "Proof", "Geom"};
1187 LoadModules(FIXMEModules, clingInterp);
1188
1189 clang::CompilerInstance &CI = *clingInterp.getCI();
1190 GlobalModuleIndex *GlobalIndex = nullptr;
1191 const char *experimentalGMI = gSystem->Getenv("ROOT_EXPERIMENTAL_GMI");
1192 if (experimentalGMI && strcmp(experimentalGMI,"false") != 0) {
1193 loadGlobalModuleIndex(SourceLocation(), clingInterp);
1194 GlobalIndex = CI.getModuleManager()->getGlobalIndex();
1195 }
1196 llvm::StringSet<> KnownModuleFileNames;
1197 if (GlobalIndex)
1198 GlobalIndex->getKnownModuleFileNames(KnownModuleFileNames);
1199
1200 clang::Preprocessor &PP = CI.getPreprocessor();
1201 std::vector<std::string> PendingModules;
1202 PendingModules.reserve(256);
1203 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1204 for (auto I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1205 clang::Module *M = I->second;
1206 assert(M);
1207
1208 // We want to load only already created modules.
1209 std::string FullASTFilePath;
1210 if (!HasASTFileOnDisk(M, PP, &FullASTFilePath))
1211 continue;
1212
1213 if (GlobalIndex && KnownModuleFileNames.count(FullASTFilePath))
1214 continue;
1215
1216 if (M->IsMissingRequirement)
1217 continue;
1218
1219 if (GlobalIndex)
1220 LoadModule(M->Name, clingInterp);
1221 else {
1222 // FIXME: We may be able to remove those checks as cling::loadModule
1223 // checks if a module was alredy loaded.
1224 if (std::find(CoreModules.begin(), CoreModules.end(), M->Name) != CoreModules.end())
1225 continue; // This is a core module which was already loaded.
1226
1227 if (std::find(ExcludeModules.begin(), ExcludeModules.end(), M->Name) != ExcludeModules.end())
1228 continue;
1229
1230 // Load system modules now and delay the other modules after we have
1231 // loaded all system ones.
1232 if (M->IsSystem)
1233 LoadModule(M->Name, clingInterp);
1234 else
1235 PendingModules.push_back(M->Name);
1236 }
1237 }
1238 LoadModules(PendingModules, clingInterp);
1239 }
1240
1241 // Check that the gROOT macro was exported by any core module.
1242 assert(clingInterp.getMacro("gROOT") && "Couldn't load gROOT macro?");
1243
1244 // C99 decided that it's a very good idea to name a macro `I` (the letter I).
1245 // This seems to screw up nearly all the template code out there as `I` is
1246 // common template parameter name and iterator variable name.
1247 // Let's follow the GCC recommendation and undefine `I` in case any of the
1248 // core modules have defined it:
1249 // https://www.gnu.org/software/libc/manual/html_node/Complex-Numbers.html
1250 clingInterp.declare("#ifdef I\n #undef I\n #endif\n");
1251
1252 // libc++ complex.h has #define complex _Complex. Give preference to the one
1253 // in std.
1254 clingInterp.declare("#ifdef complex\n #undef complex\n #endif\n");
1255
1256 // These macros are from loading R related modules, which conflict with
1257 // user's code.
1258 clingInterp.declare("#ifdef PI\n #undef PI\n #endif\n");
1259 clingInterp.declare("#ifdef ERROR\n #undef ERROR\n #endif\n");
1260}
1261
1262static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
1263{
1264 std::string PreIncludes;
1265 bool hasCxxModules = clingInterp.getCI()->getLangOpts().Modules;
1266
1267 // For the list to also include string, we have to include it now.
1268 // rootcling does parts already if needed, e.g. genreflex does not want using
1269 // namespace std.
1270 if (IsFromRootCling()) {
1271 PreIncludes += "#include \"RtypesCore.h\"\n";
1272 } else {
1273 if (!hasCxxModules)
1274 PreIncludes += "#include \"Rtypes.h\"\n";
1275
1276 PreIncludes += gClassDefInterpMacro + "\n"
1277 + gInterpreterClassDef + "\n"
1278 "#undef ClassImp\n"
1279 "#define ClassImp(X);\n";
1280 }
1281 if (!hasCxxModules)
1282 PreIncludes += "#include <string>\n";
1283
1284 // We must include it even when we have modules because it is marked as
1285 // textual in the modulemap due to the nature of the assert header.
1286#ifndef R__WIN32
1287 PreIncludes += "#include <cassert>\n";
1288#endif
1289 PreIncludes += "using namespace std;\n";
1290 clingInterp.declare(PreIncludes);
1291}
1292
1293////////////////////////////////////////////////////////////////////////////////
1294/// Initialize the cling interpreter interface.
1295/// \param argv - array of arguments passed to the cling::Interpreter constructor
1296/// e.g. `-DFOO=bar`. The last element of the array must be `nullptr`.
1297
1298TCling::TCling(const char *name, const char *title, const char* const argv[])
1299: TInterpreter(name, title), fMore(0), fGlobalsListSerial(-1), fMapfile(nullptr),
1303{
1304 fPrompt[0] = 0;
1305 const bool fromRootCling = IsFromRootCling();
1306
1307 fCxxModulesEnabled = false;
1308#ifdef R__USE_CXXMODULES
1309 fCxxModulesEnabled = true;
1310#endif
1311
1312 llvm::install_fatal_error_handler(&exceptionErrorHandler);
1313
1314 fTemporaries = new std::vector<cling::Value>();
1315
1316 std::vector<std::string> clingArgsStorage;
1317 clingArgsStorage.push_back("cling4root");
1318 for (const char* const* arg = argv; *arg; ++arg)
1319 clingArgsStorage.push_back(*arg);
1320
1321 // rootcling sets its arguments through TROOT::GetExtraInterpreterArgs().
1322 if (!fromRootCling) {
1324
1325 // Add -I early so ASTReader can find the headers.
1326 std::string interpInclude(TROOT::GetEtcDir().Data());
1327 clingArgsStorage.push_back("-I" + interpInclude);
1328
1329 // Add include path to etc/cling.
1330 clingArgsStorage.push_back("-I" + interpInclude + "/cling");
1331
1332 // Add the root include directory and etc/ to list searched by default.
1333 clingArgsStorage.push_back(std::string(("-I" + TROOT::GetIncludeDir()).Data()));
1334
1335 // Add the current path to the include path
1336 // TCling::AddIncludePath(".");
1337
1338 // Attach the PCH (unless we have C++ modules enabled which provide the
1339 // same functionality).
1340 if (!fCxxModulesEnabled) {
1341 std::string pchFilename = interpInclude + "/allDict.cxx.pch";
1342 if (gSystem->Getenv("ROOT_PCH")) {
1343 pchFilename = gSystem->Getenv("ROOT_PCH");
1344 }
1345
1346 clingArgsStorage.push_back("-include-pch");
1347 clingArgsStorage.push_back(pchFilename);
1348 }
1349
1350 clingArgsStorage.push_back("-Wno-undefined-inline");
1351 clingArgsStorage.push_back("-fsigned-char");
1352 }
1353
1354 // Process externally passed arguments if present.
1355 llvm::Optional<std::string> EnvOpt = llvm::sys::Process::GetEnv("EXTRA_CLING_ARGS");
1356 if (EnvOpt.hasValue()) {
1357 StringRef Env(*EnvOpt);
1358 while (!Env.empty()) {
1359 StringRef Arg;
1360 std::tie(Arg, Env) = Env.split(' ');
1361 clingArgsStorage.push_back(Arg.str());
1362 }
1363 }
1364
1365 auto GetEnvVarPath = [](const std::string &EnvVar,
1366 std::vector<std::string> &Paths) {
1367 llvm::Optional<std::string> EnvOpt = llvm::sys::Process::GetEnv(EnvVar);
1368 if (EnvOpt.hasValue()) {
1369 StringRef Env(*EnvOpt);
1370 while (!Env.empty()) {
1371 StringRef Arg;
1372 std::tie(Arg, Env) = Env.split(ROOT::FoundationUtils::GetEnvPathSeparator());
1373 if (std::find(Paths.begin(), Paths.end(), Arg.str()) == Paths.end())
1374 Paths.push_back(Arg.str());
1375 }
1376 }
1377 };
1378
1379 if (fCxxModulesEnabled) {
1380 std::vector<std::string> Paths;
1381 // ROOT usually knows better where its libraries are. This way we can
1382 // discover modules without having to should thisroot.sh and should fix
1383 // gnuinstall.
1384 Paths.push_back(TROOT::GetLibDir().Data());
1385 GetEnvVarPath("CLING_PREBUILT_MODULE_PATH", Paths);
1386 //GetEnvVarPath("LD_LIBRARY_PATH", Paths);
1387 std::string EnvVarPath;
1388 for (const std::string& P : Paths)
1390 // FIXME: We should make cling -fprebuilt-module-path work.
1391 gSystem->Setenv("CLING_PREBUILT_MODULE_PATH", EnvVarPath.c_str());
1392 }
1393
1394 // FIXME: This only will enable frontend timing reports.
1395 EnvOpt = llvm::sys::Process::GetEnv("ROOT_CLING_TIMING");
1396 if (EnvOpt.hasValue())
1397 clingArgsStorage.push_back("-ftime-report");
1398
1399 // Add the overlay file. Note that we cannot factor it out for both root
1400 // and rootcling because rootcling activates modules only if -cxxmodule
1401 // flag is passed.
1402 if (fCxxModulesEnabled && !fromRootCling) {
1403 // For now we prefer rootcling to enumerate explicitly its modulemaps.
1404 std::vector<std::string> Paths;
1405 Paths.push_back(TROOT::GetIncludeDir().Data());
1406 GetEnvVarPath("CLING_MODULEMAP_PATH", Paths);
1407
1408 // Give highest precedence of the modulemap in the cwd.
1409 Paths.push_back(gSystem->WorkingDirectory());
1410
1411 for (const std::string& P : Paths) {
1412 std::string ModuleMapLoc = P + ROOT::FoundationUtils::GetPathSeparator()
1413 + "module.modulemap";
1414 if (!llvm::sys::fs::exists(ModuleMapLoc)) {
1415 if (gDebug > 1)
1416 ::Info("TCling::TCling", "Modulemap %s does not exist \n",
1417 ModuleMapLoc.c_str());
1418
1419 continue;
1420 }
1421
1422 clingArgsStorage.push_back("-fmodule-map-file=" + ModuleMapLoc);
1423 }
1424 std::string ModulesCachePath;
1425 EnvOpt = llvm::sys::Process::GetEnv("CLING_MODULES_CACHE_PATH");
1426 if (EnvOpt.hasValue()){
1427 StringRef Env(*EnvOpt);
1428 assert(llvm::sys::fs::exists(Env) && "Path does not exist!");
1429 ModulesCachePath = Env.str();
1430 } else {
1431 ModulesCachePath = TROOT::GetLibDir();
1432 }
1433
1434 clingArgsStorage.push_back("-fmodules-cache-path=" + ModulesCachePath);
1435 }
1436
1437 std::vector<const char*> interpArgs;
1438 for (std::vector<std::string>::const_iterator iArg = clingArgsStorage.begin(),
1439 eArg = clingArgsStorage.end(); iArg != eArg; ++iArg)
1440 interpArgs.push_back(iArg->c_str());
1441
1442 // Activate C++ modules support. If we are running within rootcling, it's up
1443 // to rootcling to set this flag depending on whether it wants to produce
1444 // C++ modules.
1445 TString vfsArg;
1446 if (fCxxModulesEnabled) {
1447 if (!fromRootCling) {
1448 // We only set this flag, rest is done by the CIFactory.
1449 interpArgs.push_back("-fmodules");
1450 interpArgs.push_back("-fno-implicit-module-maps");
1451 // We should never build modules during runtime, so let's enable the
1452 // module build remarks from clang to make it easier to spot when we do
1453 // this by accident.
1454 interpArgs.push_back("-Rmodule-build");
1455 }
1456 // ROOT implements its AutoLoading upon module's link directives. We
1457 // generate module A { header "A.h" link "A.so" export * } where ROOT's
1458 // facilities use the link directive to dynamically load the relevant
1459 // library. So, we need to suppress clang's default autolink behavior.
1460 interpArgs.push_back("-fno-autolink");
1461 }
1462
1463#ifdef R__FAST_MATH
1464 // Same setting as in rootcling_impl.cxx.
1465 interpArgs.push_back("-ffast-math");
1466#endif
1467
1468 TString llvmResourceDir = TROOT::GetEtcDir() + "/cling";
1469 // Add statically injected extra arguments, usually coming from rootcling.
1470 for (const char** extraArgs = TROOT::GetExtraInterpreterArgs();
1471 extraArgs && *extraArgs; ++extraArgs) {
1472 if (!strcmp(*extraArgs, "-resource-dir")) {
1473 // Take the next arg as the llvm resource directory.
1474 llvmResourceDir = *(++extraArgs);
1475 } else {
1476 interpArgs.push_back(*extraArgs);
1477 }
1478 }
1479
1480 for (const auto &arg: TROOT::AddExtraInterpreterArgs({})) {
1481 interpArgs.push_back(arg.c_str());
1482 }
1483
1484 // Add the Rdict module file extension.
1485 cling::Interpreter::ModuleFileExtensions extensions;
1486 EnvOpt = llvm::sys::Process::GetEnv("ROOTDEBUG_RDICT");
1487 if (!EnvOpt.hasValue())
1488 extensions.push_back(std::make_shared<TClingRdictModuleFileExtension>());
1489
1490 fInterpreter = llvm::make_unique<cling::Interpreter>(interpArgs.size(),
1491 &(interpArgs[0]),
1492 llvmResourceDir, extensions);
1493
1494 if (!fromRootCling) {
1495 fInterpreter->installLazyFunctionCreator(llvmLazyFunctionCreator);
1496 }
1497
1498 // Don't check whether modules' files exist.
1499 fInterpreter->getCI()->getPreprocessorOpts().DisablePCHValidation = true;
1500
1501 // Until we can disable AutoLoading during Sema::CorrectTypo() we have
1502 // to disable spell checking.
1503 fInterpreter->getCI()->getLangOpts().SpellChecking = false;
1504
1505 // We need stream that doesn't close its file descriptor, thus we are not
1506 // using llvm::outs. Keeping file descriptor open we will be able to use
1507 // the results in pipes (Savannah #99234).
1508 static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO, /*ShouldClose*/false);
1509 fMetaProcessor = llvm::make_unique<cling::MetaProcessor>(*fInterpreter, fMPOuts);
1510
1513
1514 // We are now ready (enough is loaded) to init the list of opaque typedefs.
1521
1522 // Disallow auto-parsing in rootcling
1523 fIsAutoParsingSuspended = fromRootCling;
1524
1525 ResetAll();
1526
1527 // Enable dynamic lookup
1528 if (!fromRootCling) {
1529 fInterpreter->enableDynamicLookup();
1530 }
1531
1532 // Enable ClinG's DefinitionShadower for ROOT.
1533 fInterpreter->allowRedefinition();
1534
1535 // Attach cling callbacks last; they might need TROOT::fInterpreter
1536 // and should thus not be triggered during the equivalent of
1537 // TROOT::fInterpreter = new TCling;
1538 std::unique_ptr<TClingCallbacks>
1539 clingCallbacks(new TClingCallbacks(GetInterpreterImpl(), /*hasCodeGen*/ !fromRootCling));
1540 fClingCallbacks = clingCallbacks.get();
1542 fInterpreter->setCallbacks(std::move(clingCallbacks));
1543
1544 if (!fromRootCling) {
1545 cling::DynamicLibraryManager& DLM = *fInterpreter->getDynamicLibraryManager();
1546 // Make sure cling looks into ROOT's libdir, even if not part of LD_LIBRARY_PATH
1547 // e.g. because of an RPATH build.
1548 DLM.addSearchPath(TROOT::GetLibDir().Data());
1549 auto ShouldPermanentlyIgnore = [](llvm::StringRef FileName) -> bool{
1550 llvm::StringRef stem = llvm::sys::path::stem(FileName);
1551 return stem.startswith("libNew") || stem.startswith("libcppyy_backend");
1552 };
1553 // Initialize the dyld for the llvmLazyFunctionCreator.
1554 DLM.initializeDyld(ShouldPermanentlyIgnore);
1555 }
1556}
1557
1558
1559////////////////////////////////////////////////////////////////////////////////
1560/// Destroy the interpreter interface.
1561
1563{
1564 // ROOT's atexit functions require the interepreter to be available.
1565 // Run them before shutting down.
1566 if (!IsFromRootCling())
1567 GetInterpreterImpl()->runAtExitFuncs();
1568 fIsShuttingDown = true;
1569 delete fMapfile;
1570 delete fRootmapFiles;
1571 delete fTemporaries;
1572 delete fNormalizedCtxt;
1573 delete fLookupHelper;
1574 gCling = 0;
1575}
1576
1577////////////////////////////////////////////////////////////////////////////////
1578/// Initialize the interpreter, once TROOT::fInterpreter is set.
1579
1581{
1583
1584 // We are set up. Enable ROOT's AutoLoading.
1585 if (IsFromRootCling())
1586 return;
1587
1588 // Read the rules before enabling the auto loading to not inadvertently
1589 // load the libraries for the classes concerned even-though the user is
1590 // *not* using them.
1591 // Note this call must happen before the first call to LoadLibraryMap.
1592 assert(GetRootMapFiles() == 0 && "Must be called before LoadLibraryMap!");
1593 TClass::ReadRules(); // Read the default customization rules ...
1594
1596 SetClassAutoLoading(true);
1597}
1598
1600{
1601 fIsShuttingDown = true;
1602 ResetGlobals();
1603}
1604
1605////////////////////////////////////////////////////////////////////////////////
1606/// Helper to initialize TVirtualStreamerInfo's factor early.
1607/// Use static initialization to insure only one TStreamerInfo is created.
1609{
1610 // Use lambda since SetFactory return void.
1611 auto setFactory = []() {
1613 return kTRUE;
1614 };
1615 static bool doneFactory = setFactory();
1616 return doneFactory; // avoid unused variable warning.
1617}
1618
1619////////////////////////////////////////////////////////////////////////////////
1620/// Register Rdict data for future loading by LoadPCM;
1621
1622void TCling::RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
1623{
1624 if (IsFromRootCling())
1625 return;
1626
1627 if (llvm::sys::fs::exists(pcmFileNameFullPath)) {
1628 ::Error("TCling::RegisterRdictForLoadPCM", "Rdict '%s' is both in Module extension and in File system.", pcmFileNameFullPath.c_str());
1629 return;
1630 }
1631
1632 // The pcmFileNameFullPath must be resolved already because we cannot resolve
1633 // a link to a non-existent file.
1634 fPendingRdicts[pcmFileNameFullPath] = *pcmContent;
1635}
1636
1637////////////////////////////////////////////////////////////////////////////////
1638/// Tries to load a PCM from TFile; returns true on success.
1639
1641{
1642 auto listOfKeys = pcmFile.GetListOfKeys();
1643
1644 // This is an empty pcm
1645 if (listOfKeys && ((listOfKeys->GetSize() == 0) || // Nothing here, or
1646 ((listOfKeys->GetSize() == 1) && // only one, and
1647 !strcmp(((TKey *)listOfKeys->At(0))->GetName(), "EMPTY") // name is EMPTY
1648 ))) {
1649 return;
1650 }
1651
1652 TObjArray *protoClasses;
1653 if (gDebug > 1)
1654 ::Info("TCling::LoadPCMImpl", "reading protoclasses for %s \n", pcmFile.GetName());
1655
1656 pcmFile.GetObject("__ProtoClasses", protoClasses);
1657
1658 if (protoClasses) {
1659 for (auto obj : *protoClasses) {
1660 TProtoClass *proto = (TProtoClass *)obj;
1662 }
1663 // Now that all TClass-es know how to set them up we can update
1664 // existing TClasses, which might cause the creation of e.g. TBaseClass
1665 // objects which in turn requires the creation of TClasses, that could
1666 // come from the PCH, but maybe later in the loop. Instead of resolving
1667 // a dependency graph the addition to the TClassTable above allows us
1668 // to create these dependent TClasses as needed below.
1669 for (auto proto : *protoClasses) {
1670 if (TClass *existingCl = (TClass *)gROOT->GetListOfClasses()->FindObject(proto->GetName())) {
1671 // We have an existing TClass object. It might be emulated
1672 // or interpreted; we now have more information available.
1673 // Make that available.
1674 if (existingCl->GetState() != TClass::kHasTClassInit) {
1675 DictFuncPtr_t dict = gClassTable->GetDict(proto->GetName());
1676 if (!dict) {
1677 ::Error("TCling::LoadPCM", "Inconsistent TClassTable for %s", proto->GetName());
1678 } else {
1679 // This will replace the existing TClass.
1680 TClass *ncl = (*dict)();
1681 if (ncl)
1682 ncl->PostLoadCheck();
1683 }
1684 }
1685 }
1686 }
1687
1688 protoClasses->Clear(); // Ownership was transfered to TClassTable.
1689 delete protoClasses;
1690 }
1691
1692 TObjArray *dataTypes;
1693 pcmFile.GetObject("__Typedefs", dataTypes);
1694 if (dataTypes) {
1695 for (auto typedf : *dataTypes)
1696 gROOT->GetListOfTypes()->Add(typedf);
1697 dataTypes->Clear(); // Ownership was transfered to TListOfTypes.
1698 delete dataTypes;
1699 }
1700
1701 TObjArray *enums;
1702 pcmFile.GetObject("__Enums", enums);
1703 if (enums) {
1704 // Cache the pointers
1705 auto listOfGlobals = gROOT->GetListOfGlobals();
1706 auto listOfEnums = dynamic_cast<THashList *>(gROOT->GetListOfEnums());
1707 // Loop on enums and then on enum constants
1708 for (auto selEnum : *enums) {
1709 const char *enumScope = selEnum->GetTitle();
1710 const char *enumName = selEnum->GetName();
1711 if (strcmp(enumScope, "") == 0) {
1712 // This is a global enum and is added to the
1713 // list of enums and its constants to the list of globals
1714 if (!listOfEnums->THashList::FindObject(enumName)) {
1715 ((TEnum *)selEnum)->SetClass(nullptr);
1716 listOfEnums->Add(selEnum);
1717 }
1718 for (auto enumConstant : *static_cast<TEnum *>(selEnum)->GetConstants()) {
1719 if (!listOfGlobals->FindObject(enumConstant)) {
1720 listOfGlobals->Add(enumConstant);
1721 }
1722 }
1723 } else {
1724 // This enum is in a namespace. A TClass entry is bootstrapped if
1725 // none exists yet and the enum is added to it
1726 TClass *nsTClassEntry = TClass::GetClass(enumScope);
1727 if (!nsTClassEntry) {
1728 nsTClassEntry = new TClass(enumScope, 0, TClass::kNamespaceForMeta, true);
1729 }
1730 auto listOfEnums = nsTClassEntry->fEnums.load();
1731 if (!listOfEnums) {
1732 if ((kIsClass | kIsStruct | kIsUnion) & nsTClassEntry->Property()) {
1733 // For this case, the list will be immutable once constructed
1734 // (i.e. in this case, by the end of this routine).
1735 listOfEnums = nsTClassEntry->fEnums = new TListOfEnums(nsTClassEntry);
1736 } else {
1737 // namespaces can have enums added to them
1738 listOfEnums = nsTClassEntry->fEnums = new TListOfEnumsWithLock(nsTClassEntry);
1739 }
1740 }
1741 if (listOfEnums && !listOfEnums->THashList::FindObject(enumName)) {
1742 ((TEnum *)selEnum)->SetClass(nsTClassEntry);
1743 listOfEnums->Add(selEnum);
1744 }
1745 }
1746 }
1747 enums->Clear();
1748 delete enums;
1749 }
1750}
1751
1752////////////////////////////////////////////////////////////////////////////////
1753/// Tries to load a rdict PCM, issues diagnostics if it fails.
1754
1755void TCling::LoadPCM(std::string pcmFileNameFullPath)
1756{
1757 SuspendAutoLoadingRAII autoloadOff(this);
1758 SuspendAutoParsing autoparseOff(this);
1759 assert(!pcmFileNameFullPath.empty());
1760 assert(llvm::sys::path::is_absolute(pcmFileNameFullPath));
1761
1762 // Easier to work with the ROOT interfaces.
1763 TString pcmFileName = pcmFileNameFullPath;
1764
1765 // Prevent the ROOT-PCMs hitting this during auto-load during
1766 // JITting - which will cause recursive compilation.
1767 // Avoid to call the plugin manager at all.
1769
1771 llvm::SaveAndRestore<Int_t> SaveGDebug(gDebug);
1772 if (gDebug > 5) {
1773 gDebug -= 5;
1774 ::Info("TCling::LoadPCM", "Loading ROOT PCM %s", pcmFileName.Data());
1775 } else {
1776 gDebug = 0;
1777 }
1778
1779 if (llvm::sys::fs::is_symlink_file(pcmFileNameFullPath))
1780 pcmFileNameFullPath = ROOT::TMetaUtils::GetRealPath(pcmFileNameFullPath);
1781
1782 auto pendingRdict = fPendingRdicts.find(pcmFileNameFullPath);
1783 if (pendingRdict != fPendingRdicts.end()) {
1784 llvm::StringRef pcmContent = pendingRdict->second;
1785 TMemFile::ZeroCopyView_t range{pcmContent.data(), pcmContent.size()};
1786 std::string RDictFileOpts = pcmFileNameFullPath + "?filetype=pcm";
1787 TMemFile pcmMemFile(RDictFileOpts.c_str(), range);
1788
1789 LoadPCMImpl(pcmMemFile);
1790 fPendingRdicts.erase(pendingRdict);
1791
1792 return;
1793 }
1794
1795 if (!llvm::sys::fs::exists(pcmFileNameFullPath)) {
1796 ::Error("TCling::LoadPCM", "ROOT PCM %s file does not exist",
1797 pcmFileNameFullPath.data());
1798 if (!fPendingRdicts.empty())
1799 for (const auto &rdict : fPendingRdicts)
1800 ::Info("TCling::LoadPCM", "In-memory ROOT PCM candidate %s\n",
1801 rdict.first.c_str());
1802 return;
1803 }
1804
1805 if (!gROOT->IsRootFile(pcmFileName)) {
1806 Fatal("LoadPCM", "The file %s is not a ROOT as was expected\n", pcmFileName.Data());
1807 return;
1808 }
1809 TFile pcmFile(pcmFileName + "?filetype=pcm", "READ");
1810 LoadPCMImpl(pcmFile);
1811}
1812
1813//______________________________________________________________________________
1814
1815namespace {
1816 using namespace clang;
1817
1818 class ExtLexicalStorageAdder: public RecursiveASTVisitor<ExtLexicalStorageAdder>{
1819 // This class is to be considered an helper for autoparsing.
1820 // It visits the AST and marks all classes (in all of their redeclarations)
1821 // with the setHasExternalLexicalStorage method.
1822 public:
1823 bool VisitRecordDecl(clang::RecordDecl* rcd){
1824 if (gDebug > 2)
1825 Info("ExtLexicalStorageAdder",
1826 "Adding external lexical storage to class %s",
1827 rcd->getNameAsString().c_str());
1828 auto reDeclPtr = rcd->getMostRecentDecl();
1829 do {
1830 reDeclPtr->setHasExternalLexicalStorage();
1831 } while ((reDeclPtr = reDeclPtr->getPreviousDecl()));
1832
1833 return false;
1834 }
1835 };
1836
1837
1838}
1839
1840////////////////////////////////////////////////////////////////////////////////
1841///\returns true if the module map was loaded, false on error or if the map was
1842/// already loaded.
1843bool TCling::RegisterPrebuiltModulePath(const std::string &FullPath,
1844 const std::string &ModuleMapName /*= "module.modulemap"*/) const
1845{
1846 assert(llvm::sys::path::is_absolute(FullPath));
1847 Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
1848 FileManager &FM = PP.getFileManager();
1849 // FIXME: In a ROOT session we can add an include path (through .I /inc/path)
1850 // We should look for modulemap files there too.
1851 const DirectoryEntry *DE = FM.getDirectory(FullPath);
1852 if (DE) {
1853 HeaderSearch &HS = PP.getHeaderSearchInfo();
1854 HeaderSearchOptions &HSOpts = HS.getHeaderSearchOpts();
1855 const auto &ModPaths = HSOpts.PrebuiltModulePaths;
1856 bool pathExists = std::find(ModPaths.begin(), ModPaths.end(), FullPath) != ModPaths.end();
1857 if (!pathExists)
1858 HSOpts.AddPrebuiltModulePath(FullPath);
1859 // We cannot use HS.lookupModuleMapFile(DE, /*IsFramework*/ false);
1860 // because its internal call to getFile has CacheFailure set to true.
1861 // In our case, modulemaps can appear any time due to ACLiC.
1862 // Code copied from HS.lookupModuleMapFile.
1863 llvm::SmallString<256> ModuleMapFileName(DE->getName());
1864 llvm::sys::path::append(ModuleMapFileName, ModuleMapName);
1865 const FileEntry *FE = FM.getFile(ModuleMapFileName, /*openFile*/ false,
1866 /*CacheFailure*/ false);
1867
1868 // FIXME: Calling IsLoaded is slow! Replace this with the appropriate
1869 // call to the clang::ModuleMap class.
1870 if (FE && !this->IsLoaded(FE->getName().data())) {
1871 if (!HS.loadModuleMapFile(FE, /*IsSystem*/ false))
1872 return true;
1873 Error("RegisterPrebuiltModulePath", "Could not load modulemap in %s", ModuleMapFileName.c_str());
1874 }
1875 }
1876 return false;
1877}
1878
1879////////////////////////////////////////////////////////////////////////////////
1880/// List of dicts that have the PCM information already in the PCH.
1881static const std::unordered_set<std::string> gIgnoredPCMNames = {"libCore",
1882 "libRint",
1883 "libThread",
1884 "libRIO",
1885 "libImt",
1886 "libcomplexDict",
1887 "libdequeDict",
1888 "liblistDict",
1889 "libforward_listDict",
1890 "libvectorDict",
1891 "libmapDict",
1892 "libmultimap2Dict",
1893 "libmap2Dict",
1894 "libmultimapDict",
1895 "libsetDict",
1896 "libmultisetDict",
1897 "libunordered_setDict",
1898 "libunordered_multisetDict",
1899 "libunordered_mapDict",
1900 "libunordered_multimapDict",
1901 "libvalarrayDict",
1902 "G__GenVector32",
1903 "G__Smatrix32"};
1904
1905static void PrintDlError(const char *dyLibName, const char *modulename)
1906{
1907#ifdef R__WIN32
1908 char dyLibError[1000];
1909 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1910 dyLibError, sizeof(dyLibError), NULL);
1911#else
1912 const char *dyLibError = dlerror();
1913#endif
1914 ::Error("TCling::RegisterModule", "Cannot open shared library %s for dictionary %s:\n %s", dyLibName, modulename,
1915 (dyLibError) ? dyLibError : "");
1916}
1917
1918////////////////////////////////////////////////////////////////////////////////
1919// Update all the TClass registered in fClassesToUpdate
1920
1922{
1923 while (!fClassesToUpdate.empty()) {
1924 TClass *oldcl = fClassesToUpdate.back().first;
1925 // If somehow the TClass has already been loaded (maybe it was registered several time),
1926 // we skip it. Otherwise, the existing TClass is in mode kInterpreted, kEmulated or
1927 // maybe even kForwardDeclared and needs to replaced.
1928 if (oldcl->GetState() != TClass::kHasTClassInit) {
1929 // if (gDebug > 2) Info("RegisterModule", "Forcing TClass init for %s", oldcl->GetName());
1930 DictFuncPtr_t dict = fClassesToUpdate.back().second;
1931 fClassesToUpdate.pop_back();
1932 // Calling func could manipulate the list so, let maintain the list
1933 // then call the dictionary function.
1934 TClass *ncl = dict();
1935 if (ncl) ncl->PostLoadCheck();
1936 } else {
1937 fClassesToUpdate.pop_back();
1938 }
1939 }
1940}
1941////////////////////////////////////////////////////////////////////////////////
1942/// Inject the module named "modulename" into cling; load all headers.
1943/// headers is a 0-terminated array of header files to #include after
1944/// loading the module. The module is searched for in all $LD_LIBRARY_PATH
1945/// entries (or %PATH% on Windows).
1946/// This function gets called by the static initialization of dictionary
1947/// libraries.
1948/// The payload code is injected "as is" in the interpreter.
1949/// The value of 'triggerFunc' is used to find the shared library location.
1950
1951void TCling::RegisterModule(const char* modulename,
1952 const char** headers,
1953 const char** includePaths,
1954 const char* payloadCode,
1955 const char* fwdDeclsCode,
1956 void (*triggerFunc)(),
1957 const FwdDeclArgsToKeepCollection_t& fwdDeclsArgToSkip,
1958 const char** classesHeaders,
1959 Bool_t lateRegistration /*=false*/,
1960 Bool_t hasCxxModule /*=false*/)
1961{
1962 const bool fromRootCling = IsFromRootCling();
1963 // We need the dictionary initialization but we don't want to inject the
1964 // declarations into the interpreter, except for those we really need for
1965 // I/O; see rootcling.cxx after the call to TCling__GetInterpreter().
1966 if (fromRootCling) return;
1967
1968 // When we cannot provide a module for the library we should enable header
1969 // parsing. This 'mixed' mode ensures gradual migration to modules.
1970 llvm::SaveAndRestore<bool> SaveHeaderParsing(fHeaderParsingOnDemand);
1971 fHeaderParsingOnDemand = !hasCxxModule;
1972
1973 // Treat Aclic Libs in a special way. Do not delay the parsing.
1974 bool hasHeaderParsingOnDemand = fHeaderParsingOnDemand;
1975 bool isACLiC = strstr(modulename, "_ACLiC_dict") != nullptr;
1976 if (hasHeaderParsingOnDemand && isACLiC) {
1977 if (gDebug>1)
1978 Info("TCling::RegisterModule",
1979 "Header parsing on demand is active but this is an Aclic library. Disabling it for this library.");
1980 hasHeaderParsingOnDemand = false;
1981 }
1982
1983
1984 // Make sure we relookup symbols that were search for before we loaded
1985 // their autoparse information. We could be more subtil and remove only
1986 // the failed one or only the one in this module, but for now this is
1987 // better than nothing.
1988 fLookedUpClasses.clear();
1989
1990 // Make sure we do not set off AutoLoading or autoparsing during the
1991 // module registration!
1992 SuspendAutoLoadingRAII autoLoadOff(this);
1993
1994 for (const char** inclPath = includePaths; *inclPath; ++inclPath) {
1995 TCling::AddIncludePath(*inclPath);
1996 }
1997 cling::Transaction* T = 0;
1998 // Put the template decls and the number of arguments to skip in the TNormalizedCtxt
1999 for (auto& fwdDeclArgToSkipPair : fwdDeclsArgToSkip){
2000 const std::string& fwdDecl = fwdDeclArgToSkipPair.first;
2001 const int nArgsToSkip = fwdDeclArgToSkipPair.second;
2002 auto compRes = fInterpreter->declare(fwdDecl.c_str(), &T);
2003 assert(cling::Interpreter::kSuccess == compRes &&
2004 "A fwd declaration could not be compiled");
2005 if (compRes!=cling::Interpreter::kSuccess){
2006 Warning("TCling::RegisterModule",
2007 "Problems in declaring string '%s' were encountered.",
2008 fwdDecl.c_str()) ;
2009 continue;
2010 }
2011
2012 // Drill through namespaces recursively until the template is found
2013 if(ClassTemplateDecl* TD = FindTemplateInNamespace(T->getFirstDecl().getSingleDecl())){
2014 fNormalizedCtxt->AddTemplAndNargsToKeep(TD->getCanonicalDecl(), nArgsToSkip);
2015 }
2016
2017 }
2018
2019 // FIXME: Remove #define __ROOTCLING__ once PCMs are there.
2020 // This is used to give Sema the same view on ACLiC'ed files (which
2021 // are then #included through the dictionary) as rootcling had.
2022 TString code = gNonInterpreterClassDef;
2023 if (payloadCode)
2024 code += payloadCode;
2025
2026 std::string dyLibName = cling::DynamicLibraryManager::getSymbolLocation(triggerFunc);
2027 assert(!llvm::sys::fs::is_symlink_file(dyLibName));
2028
2029 if (dyLibName.empty()) {
2030 ::Error("TCling::RegisterModule", "Dictionary trigger function for %s not found", modulename);
2031 return;
2032 }
2033
2034 // The triggerFunc may not be in a shared object but in an executable.
2035 bool isSharedLib = cling::DynamicLibraryManager::isSharedLibrary(dyLibName);
2036
2037 bool wasDlopened = false;
2038
2039 // If this call happens after dlopen has finished (i.e. late registration)
2040 // there is no need to dlopen the library recursively. See ROOT-8437 where
2041 // the dyLibName would correspond to the binary.
2042 if (!lateRegistration) {
2043
2044 if (isSharedLib) {
2045 // We need to open the dictionary shared library, to resolve symbols
2046 // requested by the JIT from it: as the library is currently being dlopen'ed,
2047 // its symbols are not yet reachable from the process.
2048 // Recursive dlopen seems to work just fine.
2049 void* dyLibHandle = dlopen(dyLibName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
2050 if (dyLibHandle) {
2051 fRegisterModuleDyLibs.push_back(dyLibHandle);
2052 wasDlopened = true;
2053 } else {
2054 PrintDlError(dyLibName.c_str(), modulename);
2055 }
2056 }
2057 } // if (!lateRegistration)
2058
2059 if (hasHeaderParsingOnDemand && fwdDeclsCode){
2060 // We now parse the forward declarations. All the classes are then modified
2061 // in order for them to have an external lexical storage.
2062 std::string fwdDeclsCodeLessEnums;
2063 {
2064 // Search for enum forward decls and only declare them if no
2065 // declaration exists yet.
2066 std::string fwdDeclsLine;
2067 std::istringstream fwdDeclsCodeStr(fwdDeclsCode);
2068 std::vector<std::string> scopes;
2069 while (std::getline(fwdDeclsCodeStr, fwdDeclsLine)) {
2070 const auto enumPos = fwdDeclsLine.find("enum __attribute__((annotate(\"");
2071 // We check if the line contains a fwd declaration of an enum
2072 if (enumPos != std::string::npos) {
2073 // We clear the scopes which we may have carried from a previous iteration
2074 scopes.clear();
2075 // We check if the enum is not in a scope. If yes, save its name
2076 // and the names of the enclosing scopes.
2077 if (enumPos != 0) {
2078 // it's enclosed in namespaces. We need to understand what they are
2079 auto nsPos = fwdDeclsLine.find("namespace");
2080 R__ASSERT(nsPos < enumPos && "Inconsistent enum and enclosing scope parsing!");
2081 while (nsPos < enumPos && nsPos != std::string::npos) {
2082 // we have a namespace, let's put it in the collection of scopes
2083 const auto nsNameStart = nsPos + 10;
2084 const auto nsNameEnd = fwdDeclsLine.find('{', nsNameStart);
2085 const auto nsName = fwdDeclsLine.substr(nsNameStart, nsNameEnd - nsNameStart);
2086 scopes.push_back(nsName);
2087 nsPos = fwdDeclsLine.find("namespace", nsNameEnd);
2088 }
2089 }
2090 clang::DeclContext* DC = 0;
2091 for (auto &&aScope: scopes) {
2092 DC = cling::utils::Lookup::Namespace(&fInterpreter->getSema(), aScope.c_str(), DC);
2093 if (!DC) {
2094 // No decl context means we have to fwd declare the enum.
2095 break;
2096 }
2097 }
2098 if (scopes.empty() || DC) {
2099 // We know the scope; let's look for the enum.
2100 size_t posEnumName = fwdDeclsLine.find("\"))) ", 32);
2101 R__ASSERT(posEnumName != std::string::npos && "Inconsistent enum fwd decl!");
2102 posEnumName += 5; // skip "\"))) "
2103 while (isspace(fwdDeclsLine[posEnumName]))
2104 ++posEnumName;
2105 size_t posEnumNameEnd = fwdDeclsLine.find(" : ", posEnumName);
2106 R__ASSERT(posEnumNameEnd != std::string::npos && "Inconsistent enum fwd decl (end)!");
2107 while (isspace(fwdDeclsLine[posEnumNameEnd]))
2108 --posEnumNameEnd;
2109 // posEnumNameEnd now points to the last character of the name.
2110
2111 std::string enumName = fwdDeclsLine.substr(posEnumName,
2112 posEnumNameEnd - posEnumName + 1);
2113
2114 if (clang::NamedDecl* enumDecl
2115 = cling::utils::Lookup::Named(&fInterpreter->getSema(),
2116 enumName.c_str(), DC)) {
2117 // We have an existing enum decl (forward or definition);
2118 // skip this.
2119 R__ASSERT(llvm::dyn_cast<clang::EnumDecl>(enumDecl) && "not an enum decl!");
2120 (void)enumDecl;
2121 continue;
2122 }
2123 }
2124 }
2125
2126 fwdDeclsCodeLessEnums += fwdDeclsLine + "\n";
2127 }
2128 }
2129
2130 if (fwdDeclsCodeLessEnums.size() != 0){ // Avoid the overhead if nothing is to be declared
2131 auto compRes = fInterpreter->declare(fwdDeclsCodeLessEnums, &T);
2132 assert(cling::Interpreter::kSuccess == compRes &&
2133 "The forward declarations could not be compiled");
2134 if (compRes!=cling::Interpreter::kSuccess){
2135 Warning("TCling::RegisterModule",
2136 "Problems in compiling forward declarations for module %s: '%s'",
2137 modulename, fwdDeclsCodeLessEnums.c_str()) ;
2138 }
2139 else if (T){
2140 // Loop over all decls in the transaction and go through them all
2141 // to mark them properly.
2142 // In order to do that, we first iterate over all the DelayedCallInfos
2143 // within the transaction. Then we loop over all Decls in the DeclGroupRef
2144 // contained in the DelayedCallInfos. For each decl, we traverse.
2145 ExtLexicalStorageAdder elsa;
2146 for (auto dciIt = T->decls_begin();dciIt!=T->decls_end();dciIt++){
2147 cling::Transaction::DelayCallInfo& dci = *dciIt;
2148 for(auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) {
2149 clang::Decl* declPtr = *dit;
2150 elsa.TraverseDecl(declPtr);
2151 }
2152 }
2153 }
2154 }
2155
2156 // Now we register all the headers necessary for the class
2157 // Typical format of the array:
2158 // {"A", "classes.h", "@",
2159 // "vector<A>", "vector", "@",
2160 // "myClass", payloadCode, "@",
2161 // nullptr};
2162
2163 std::string temp;
2164 for (const char** classesHeader = classesHeaders; *classesHeader; ++classesHeader) {
2165 temp=*classesHeader;
2166
2167 size_t theTemplateHash = 0;
2168 bool addTemplate = false;
2169 size_t posTemplate = temp.find('<');
2170 if (posTemplate != std::string::npos) {
2171 // Add an entry for the template itself.
2172 std::string templateName = temp.substr(0, posTemplate);
2173 theTemplateHash = fStringHashFunction(templateName);
2174 addTemplate = true;
2175 }
2176 size_t theHash = fStringHashFunction(temp);
2177 classesHeader++;
2178 for (const char** classesHeader_inner = classesHeader; 0!=strcmp(*classesHeader_inner,"@"); ++classesHeader_inner,++classesHeader){
2179 // This is done in order to distinguish headers from files and from the payloadCode
2180 if (payloadCode == *classesHeader_inner ){
2181 fPayloads.insert(theHash);
2182 if (addTemplate) fPayloads.insert(theTemplateHash);
2183 }
2184 if (gDebug > 2)
2185 Info("TCling::RegisterModule",
2186 "Adding a header for %s", temp.c_str());
2187 fClassesHeadersMap[theHash].push_back(*classesHeader_inner);
2188 if (addTemplate) {
2189 if (fClassesHeadersMap.find(theTemplateHash) == fClassesHeadersMap.end()) {
2190 fClassesHeadersMap[theTemplateHash].push_back(*classesHeader_inner);
2191 }
2192 addTemplate = false;
2193 }
2194 }
2195 }
2196 }
2197
2198 clang::Sema &TheSema = fInterpreter->getSema();
2199
2200 bool ModuleWasSuccessfullyLoaded = false;
2201 if (hasCxxModule) {
2202 std::string ModuleName = modulename;
2203 if (llvm::StringRef(modulename).startswith("lib"))
2204 ModuleName = llvm::StringRef(modulename).substr(3).str();
2205
2206 // In case we are directly loading the library via gSystem->Load() without
2207 // specifying the relevant include paths we should try loading the
2208 // modulemap next to the library location.
2209 clang::Preprocessor &PP = TheSema.getPreprocessor();
2210 std::string ModuleMapName;
2211 if (isACLiC)
2212 ModuleMapName = ModuleName + ".modulemap";
2213 else
2214 ModuleMapName = "module.modulemap";
2215 RegisterPrebuiltModulePath(llvm::sys::path::parent_path(dyLibName),
2216 ModuleMapName);
2217
2218 // FIXME: We should only complain for modules which we know to exist. For example, we should not complain about
2219 // modules such as GenVector32 because it needs to fall back to GenVector.
2220 ModuleWasSuccessfullyLoaded = LoadModule(ModuleName, *fInterpreter);
2221 if (!ModuleWasSuccessfullyLoaded) {
2222 // Only report if we found the module in the modulemap.
2223 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
2224 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
2225 if (moduleMap.findModule(ModuleName))
2226 Info("TCling::RegisterModule", "Module %s in modulemap failed to load.", ModuleName.c_str());
2227 }
2228 }
2229
2230 if (gIgnoredPCMNames.find(modulename) == gIgnoredPCMNames.end()) {
2231 llvm::SmallString<256> pcmFileNameFullPath(dyLibName);
2232 // The path dyLibName might not be absolute. This can happen if dyLibName
2233 // is linked to an executable in the same folder.
2234 llvm::sys::fs::make_absolute(pcmFileNameFullPath);
2235 llvm::sys::path::remove_filename(pcmFileNameFullPath);
2236 llvm::sys::path::append(pcmFileNameFullPath,
2238 LoadPCM(pcmFileNameFullPath.str().str());
2239 }
2240
2241 { // scope within which diagnostics are de-activated
2242 // For now we disable diagnostics because we saw them already at
2243 // dictionary generation time. That won't be an issue with the PCMs.
2244
2245 clangDiagSuppr diagSuppr(TheSema.getDiagnostics());
2246
2247#if defined(R__MUST_REVISIT)
2248#if R__MUST_REVISIT(6,2)
2249 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
2250#endif
2251#endif
2252
2253 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand){
2254 SuspendAutoParsing autoParseRaii(this);
2255
2256 const cling::Transaction* watermark = fInterpreter->getLastTransaction();
2257 cling::Interpreter::CompilationResult compRes = fInterpreter->parseForModule(code.Data());
2258 if (isACLiC) {
2259 // Register an unload point.
2260 fMetaProcessor->registerUnloadPoint(watermark, headers[0]);
2261 }
2262
2263 assert(cling::Interpreter::kSuccess == compRes &&
2264 "Payload code of a dictionary could not be parsed correctly.");
2265 if (compRes!=cling::Interpreter::kSuccess) {
2266 Warning("TCling::RegisterModule",
2267 "Problems declaring payload for module %s.", modulename) ;
2268 }
2269 }
2270 }
2271
2272 // Now that all the header have been registered/compiled, let's
2273 // make sure to 'reset' the TClass that have a class init in this module
2274 // but already had their type information available (using information/header
2275 // loaded from other modules or from class rules or from opening a TFile
2276 // or from loading header in a way that did not provoke the loading of
2277 // the library we just loaded).
2279
2280 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand) {
2281 // __ROOTCLING__ might be pulled in through PCH
2282 fInterpreter->declare("#ifdef __ROOTCLING__\n"
2283 "#undef __ROOTCLING__\n"
2284 + gInterpreterClassDef +
2285 "#endif");
2286 }
2287
2288 if (wasDlopened) {
2289 assert(isSharedLib);
2290 void* dyLibHandle = fRegisterModuleDyLibs.back();
2291 fRegisterModuleDyLibs.pop_back();
2292 dlclose(dyLibHandle);
2293 }
2294}
2295
2296////////////////////////////////////////////////////////////////////////////////
2297/// Register classes that already existed prior to their dictionary loading
2298/// and that already had a ClassInfo (and thus would not be refresh via
2299/// UpdateClassInfo.
2300
2302{
2303 fClassesToUpdate.push_back(std::make_pair(oldcl,dict));
2304}
2305
2306////////////////////////////////////////////////////////////////////////////////
2307/// If the dictionary is loaded, we can remove the class from the list
2308/// (otherwise the class might be loaded twice).
2309
2311{
2312 typedef std::vector<std::pair<TClass*,DictFuncPtr_t> >::iterator iterator;
2313 iterator stop = fClassesToUpdate.end();
2314 for(iterator i = fClassesToUpdate.begin();
2315 i != stop;
2316 ++i)
2317 {
2318 if ( i->first == oldcl ) {
2319 fClassesToUpdate.erase(i);
2320 return;
2321 }
2322 }
2323}
2324
2325
2326////////////////////////////////////////////////////////////////////////////////
2327/// Let cling process a command line.
2328///
2329/// If the command is executed and the error is 0, then the return value
2330/// is the int value corresponding to the result of the executed command
2331/// (float and double return values will be truncated).
2332///
2333
2334// Method for handling the interpreter exceptions.
2335// the MetaProcessor is passing in as argument to teh function, because
2336// cling::Interpreter::CompilationResult is a nested class and it cannot be
2337// forward declared, thus this method cannot be a static member function
2338// of TCling.
2339
2340static int HandleInterpreterException(cling::MetaProcessor* metaProcessor,
2341 const char* input_line,
2342 cling::Interpreter::CompilationResult& compRes,
2343 cling::Value* result)
2344{
2345 try {
2346 return metaProcessor->process(input_line, compRes, result);
2347 }
2348 catch (cling::InterpreterException& ex)
2349 {
2350 Error("HandleInterpreterException", "%s.\n%s", ex.what(), "Execution of your code was aborted.");
2351 ex.diagnose();
2352 compRes = cling::Interpreter::kFailure;
2353 }
2354 return 0;
2355}
2356
2357////////////////////////////////////////////////////////////////////////////////
2358
2359bool TCling::DiagnoseIfInterpreterException(const std::exception &e) const
2360{
2361 if (auto ie = dynamic_cast<const cling::InterpreterException*>(&e)) {
2362 ie->diagnose();
2363 return true;
2364 }
2365 return false;
2366}
2367
2368////////////////////////////////////////////////////////////////////////////////
2369
2370Long_t TCling::ProcessLine(const char* line, EErrorCode* error/*=0*/)
2371{
2372 // Copy the passed line, it comes from a static buffer in TApplication
2373 // which can be reentered through the Cling evaluation routines,
2374 // which would overwrite the static buffer and we would forget what we
2375 // were doing.
2376 //
2377 TString sLine(line);
2378 if (strstr(line,fantomline)) {
2379 // End-Of-Line action
2380 // See the comment (copied from above):
2381 // It is a "fantom" method to synchronize user keyboard input
2382 // and ROOT prompt line (for WIN32)
2383 // and is implemented by
2384 if (gApplication) {
2385 if (gApplication->IsCmdThread()) {
2387 gROOT->SetLineIsProcessing();
2388
2390
2391 gROOT->SetLineHasBeenProcessed();
2392 }
2393 }
2394 return 0;
2395 }
2396
2398 gGlobalMutex->Lock();
2399 if (!gInterpreterMutex)
2402 }
2404 gROOT->SetLineIsProcessing();
2405
2406 struct InterpreterFlagsRAII {
2407 cling::Interpreter* fInterpreter;
2408 bool fWasDynamicLookupEnabled;
2409
2410 InterpreterFlagsRAII(cling::Interpreter* interp):
2411 fInterpreter(interp),
2412 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2413 {
2414 fInterpreter->enableDynamicLookup(true);
2415 }
2416 ~~InterpreterFlagsRAII() {
2417 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2418 gROOT->SetLineHasBeenProcessed();
2419 }
2420 } interpreterFlagsRAII(GetInterpreterImpl());
2421
2422 // A non-zero returned value means the given line was
2423 // not a complete statement.
2424 int indent = 0;
2425 // This will hold the resulting value of the evaluation the given line.
2426 cling::Value result;
2427 cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess;
2428 if (!strncmp(sLine.Data(), ".L", 2) || !strncmp(sLine.Data(), ".x", 2) ||
2429 !strncmp(sLine.Data(), ".X", 2)) {
2430 // If there was a trailing "+", then CINT compiled the code above,
2431 // and we will need to strip the "+" before passing the line to cling.
2432 TString mod_line(sLine);
2433 TString aclicMode;
2434 TString arguments;
2435 TString io;
2436 TString fname = gSystem->SplitAclicMode(sLine.Data() + 3,
2437 aclicMode, arguments, io);
2438 if (aclicMode.Length()) {
2439 // Remove the leading '+'
2440 R__ASSERT(aclicMode[0]=='+' && "ACLiC mode must start with a +");
2441 aclicMode[0]='k'; // We always want to keep the .so around.
2442 if (aclicMode[1]=='+') {
2443 // We have a 2nd +
2444 aclicMode[1]='f'; // We want to force the recompilation.
2445 }
2446 if (!gSystem->CompileMacro(fname,aclicMode)) {
2447 // ACLiC failed.
2448 compRes = cling::Interpreter::kFailure;
2449 } else {
2450 if (strncmp(sLine.Data(), ".L", 2) != 0) {
2451 // if execution was requested.
2452
2453 if (arguments.Length()==0) {
2454 arguments = "()";
2455 }
2456 // We need to remove the extension.
2457 Ssiz_t ext = fname.Last('.');
2458 if (ext != kNPOS) {
2459 fname.Remove(ext);
2460 }
2461 const char *function = gSystem->BaseName(fname);
2462 mod_line = function + arguments + io;
2463 indent = HandleInterpreterException(GetMetaProcessorImpl(), mod_line, compRes, &result);
2464 }
2465 }
2466 } else {
2467 // not ACLiC
2468 size_t unnamedMacroOpenCurly;
2469 {
2470 std::string code;
2471 std::string codeline;
2472 std::ifstream in(fname);
2473 while (in) {
2474 std::getline(in, codeline);
2475 code += codeline + "\n";
2476 }
2477 unnamedMacroOpenCurly
2478 = cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
2479 }
2480
2481 fCurExecutingMacros.push_back(fname);
2482 if (unnamedMacroOpenCurly != std::string::npos) {
2483 compRes = fMetaProcessor->readInputFromFile(fname.Data(), &result,
2484 unnamedMacroOpenCurly);
2485 } else {
2486 // No DynLookup for .x, .L of named macros.
2487 fInterpreter->enableDynamicLookup(false);
2488 indent = HandleInterpreterException(GetMetaProcessorImpl(), mod_line, compRes, &result);
2489 }
2490 fCurExecutingMacros.pop_back();
2491 }
2492 } // .L / .X / .x
2493 else {
2494 if (0!=strncmp(sLine.Data(), ".autodict ",10) && sLine != ".autodict") {
2495 // explicitly ignore .autodict without having to support it
2496 // in cling.
2497
2498 // Turn off autoparsing if this is an include directive
2499 bool isInclusionDirective = sLine.Contains("\n#include") || sLine.BeginsWith("#include");
2500 if (isInclusionDirective) {
2501 SuspendAutoParsing autoParseRaii(this);
2502 indent = HandleInterpreterException(GetMetaProcessorImpl(), sLine, compRes, &result);
2503 } else {
2504 indent = HandleInterpreterException(GetMetaProcessorImpl(), sLine, compRes, &result);
2505 }
2506 }
2507 }
2508 if (result.isValid())
2509 RegisterTemporary(result);
2510 if (indent) {
2511 if (error)
2512 *error = kProcessing;
2513 return 0;
2514 }
2515 if (error) {
2516 switch (compRes) {
2517 case cling::Interpreter::kSuccess: *error = kNoError; break;
2518 case cling::Interpreter::kFailure: *error = kRecoverable; break;
2519 case cling::Interpreter::kMoreInputExpected: *error = kProcessing; break;
2520 }
2521 }
2522 if (compRes == cling::Interpreter::kSuccess
2523 && result.isValid()
2524 && !result.isVoid())
2525 {
2526 return result.simplisticCastAs<long>();
2527 }
2528 return 0;
2529}
2530
2531////////////////////////////////////////////////////////////////////////////////
2532/// No-op; see TRint instead.
2533
2535{
2536}
2537
2538////////////////////////////////////////////////////////////////////////////////
2539/// Add the given path to the list of directories in which the interpreter
2540/// looks for include files. Only one path item can be specified at a
2541/// time, i.e. "path1:path2" is NOT supported.
2542
2543void TCling::AddIncludePath(const char *path)
2544{
2546 // Favorite source of annoyance: gSystem->AddIncludePath() needs "-I",
2547 // gCling->AddIncludePath() does not! Work around that inconsistency:
2548 if (path[0] == '-' && path[1] == 'I')
2549 path += 2;
2550
2551 fInterpreter->AddIncludePath(path);
2552}
2553
2554////////////////////////////////////////////////////////////////////////////////
2555/// Visit all members over members, recursing over base classes.
2556
2557void TCling::InspectMembers(TMemberInspector& insp, const void* obj,
2558 const TClass* cl, Bool_t isTransient)
2559{
2563 }
2564
2565 if (!cl || cl->GetCollectionProxy()) {
2566 // We do not need to investigate the content of the STL
2567 // collection, they are opaque to us (and details are
2568 // uninteresting).
2569 return;
2570 }
2571
2572 static const TClassRef clRefString("std::string");
2573 if (clRefString == cl) {
2574 // We stream std::string without going through members..
2575 return;
2576 }
2577
2578 if (TClassEdit::IsStdArray(cl->GetName())) {
2579 // We treat std arrays as C arrays
2580 return;
2581 }
2582
2583 const char* cobj = (const char*) obj; // for ptr arithmetics
2584
2585 // Treat the case of std::complex in a special manner. We want to enforce
2586 // the layout of a stl implementation independent class, which is the
2587 // complex as implemented in ROOT5.
2588
2589 // A simple lambda to simplify the code
2590 auto inspInspect = [&] (ptrdiff_t offset){
2591 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_real", cobj, isTransient);
2592 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_imag", cobj + offset, isTransient);
2593 };
2594
2595 auto complexType = TClassEdit::GetComplexType(cl->GetName());
2596 switch(complexType) {
2598 {
2599 break;
2600 }
2602 {
2603 inspInspect(sizeof(float));
2604 return;
2605 }
2607 {
2608 inspInspect(sizeof(double));
2609 return;
2610 }
2612 {
2613 inspInspect(sizeof(int));
2614 return;
2615 }
2617 {
2618 inspInspect(sizeof(long));
2619 return;
2620 }
2621 }
2622
2623 static clang::PrintingPolicy
2624 printPol(fInterpreter->getCI()->getLangOpts());
2625 if (printPol.Indentation) {
2626 // not yet initialized
2627 printPol.Indentation = 0;
2628 printPol.SuppressInitializers = true;
2629 }
2630
2631 const char* clname = cl->GetName();
2632 // Printf("Inspecting class %s\n", clname);
2633
2634 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2635 const clang::Decl *scopeDecl = 0;
2636 const clang::Type *recordType = 0;
2637
2638 if (cl->GetClassInfo()) {
2639 TClingClassInfo * clingCI = (TClingClassInfo *)cl->GetClassInfo();
2640 scopeDecl = clingCI->GetDecl();
2641 recordType = clingCI->GetType();
2642 } else {
2643 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2644 // Diags will complain about private classes:
2645 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2646 &recordType);
2647 }
2648 if (!scopeDecl) {
2649 Error("InspectMembers", "Cannot find Decl for class %s", clname);
2650 return;
2651 }
2652 const clang::CXXRecordDecl* recordDecl
2653 = llvm::dyn_cast<const clang::CXXRecordDecl>(scopeDecl);
2654 if (!recordDecl) {
2655 Error("InspectMembers", "Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2656 return;
2657 }
2658
2659 {
2660 // Force possible deserializations first. We need to have no pending
2661 // Transaction when passing control flow to the inspector below (ROOT-7779).
2662 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2663
2664 astContext.getASTRecordLayout(recordDecl);
2665
2666 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2667 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2668 }
2669
2670 const clang::ASTRecordLayout& recLayout
2671 = astContext.getASTRecordLayout(recordDecl);
2672
2673 // TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
2674 // if (proxy && ( proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated ) ) {
2675 // Error("InspectMembers","The TClass for %s has an emulated proxy but we are looking at a compiled version of the collection!\n",
2676 // cl->GetName());
2677 // }
2678 if (cl->Size() != recLayout.getSize().getQuantity()) {
2679 Error("InspectMembers","TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2680 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2681 }
2682
2683 unsigned iNField = 0;
2684 // iterate over fields
2685 // FieldDecls are non-static, else it would be a VarDecl.
2686 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2687 eField = recordDecl->field_end(); iField != eField;
2688 ++iField, ++iNField) {
2689
2690
2691 clang::QualType memberQT = iField->getType();
2692 if (recordType) {
2693 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2694 memberQT = ROOT::TMetaUtils::ReSubstTemplateArg(memberQT, recordType);
2695 }
2696 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2697 if (memberQT.isNull()) {
2698 std::string memberName;
2699 llvm::raw_string_ostream stream(memberName);
2700 // Don't trigger fopen of the source file to count lines:
2701 printPol.AnonymousTagLocations = false;
2702 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2703 stream.flush();
2704 Error("InspectMembers",
2705 "Cannot retrieve QualType for member %s while inspecting class %s",
2706 memberName.c_str(), clname);
2707 continue; // skip member
2708 }
2709 const clang::Type* memType = memberQT.getTypePtr();
2710 if (!memType) {
2711 std::string memberName;
2712 llvm::raw_string_ostream stream(memberName);
2713 // Don't trigger fopen of the source file to count lines:
2714 printPol.AnonymousTagLocations = false;
2715 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2716 stream.flush();
2717 Error("InspectMembers",
2718 "Cannot retrieve Type for member %s while inspecting class %s",
2719 memberName.c_str(), clname);
2720 continue; // skip member
2721 }
2722
2723 const clang::Type* memNonPtrType = memType;
2724 Bool_t ispointer = false;
2725 if (memNonPtrType->isPointerType()) {
2726 ispointer = true;
2727 clang::QualType ptrQT
2728 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2729 if (recordType) {
2730 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2731 ptrQT = ROOT::TMetaUtils::ReSubstTemplateArg(ptrQT, recordType);
2732 }
2733 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2734 if (ptrQT.isNull()) {
2735 std::string memberName;
2736 llvm::raw_string_ostream stream(memberName);
2737 // Don't trigger fopen of the source file to count lines:
2738 printPol.AnonymousTagLocations = false;
2739 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2740 stream.flush();
2741 Error("InspectMembers",
2742 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2743 memberName.c_str(), clname);
2744 continue; // skip member
2745 }
2746 memNonPtrType = ptrQT.getTypePtr();
2747 }
2748
2749 // assemble array size(s): "[12][4][]"
2750 llvm::SmallString<8> arraySize;
2751 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2752 unsigned arrLevel = 0;
2753 bool haveErrorDueToArray = false;
2754 while (arrType) {
2755 ++arrLevel;
2756 arraySize += '[';
2757 const clang::ConstantArrayType* constArrType =
2758 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2759 if (constArrType) {
2760 constArrType->getSize().toStringUnsigned(arraySize);
2761 }
2762 arraySize += ']';
2763 clang::QualType subArrQT = arrType->getElementType();
2764 if (subArrQT.isNull()) {
2765 std::string memberName;
2766 llvm::raw_string_ostream stream(memberName);
2767 // Don't trigger fopen of the source file to count lines:
2768 printPol.AnonymousTagLocations = false;
2769 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2770 stream.flush();
2771 Error("InspectMembers",
2772 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
2773 arrLevel, subArrQT.getAsString(printPol).c_str(),
2774 memberName.c_str(), clname);
2775 haveErrorDueToArray = true;
2776 break;
2777 }
2778 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
2779 }
2780 if (haveErrorDueToArray) {
2781 continue; // skip member
2782 }
2783
2784 // construct member name
2785 std::string fieldName;
2786 if (memType->isPointerType()) {
2787 fieldName = "*";
2788 }
2789
2790 // Check if this field has a custom ioname, if not, just use the one of the decl
2791 std::string ioname(iField->getName());
2793 fieldName += ioname;
2794 fieldName += arraySize;
2795
2796 // get member offset
2797 // NOTE currently we do not support bitfield and do not support
2798 // member that are not aligned on 'bit' boundaries.
2799 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
2800 ptrdiff_t fieldOffset = offset.getQuantity();
2801
2802 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fBits[2]", fBits);
2803 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fName", &fName);
2804 // R__insp.InspectMember(fName, "fName.");
2805 // R__insp.Inspect(R__cl, R__insp.GetParent(), "*fClass", &fClass);
2806
2807 // If the class has a custom streamer and the type of the filed is a
2808 // private enum, struct or class, skip it.
2809 if (!insp.IsTreatingNonAccessibleTypes()){
2810 auto iFiledQtype = iField->getType();
2811 if (auto tagDecl = iFiledQtype->getAsTagDecl()){
2812 auto declAccess = tagDecl->getAccess();
2813 if (declAccess == AS_private || declAccess == AS_protected) {
2814 continue;
2815 }
2816 }
2817 }
2818
2819 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
2820
2821 if (!ispointer) {
2822 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
2823 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
2824 // nested objects get an extra call to InspectMember
2825 // R__insp.InspectMember("FileStat_t", (void*)&fFileStat, "fFileStat.", false);
2826 std::string sFieldRecName;
2827 if (!ROOT::TMetaUtils::ExtractAttrPropertyFromName(*fieldRecDecl,"iotype",sFieldRecName)){
2829 clang::QualType(memNonPtrType,0),
2830 *fInterpreter,
2832 }
2833
2834 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
2835 // if we can not find the member (which should not really happen),
2836 // let's consider it transient.
2837 Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();
2838
2839 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
2840 (fieldName + '.').c_str(), transient);
2841
2842 }
2843 }
2844 } // loop over fields
2845
2846 // inspect bases
2847 // TNamed::ShowMembers(R__insp);
2848 unsigned iNBase = 0;
2849 for (clang::CXXRecordDecl::base_class_const_iterator iBase
2850 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
2851 iBase != eBase; ++iBase, ++iNBase) {
2852 clang::QualType baseQT = iBase->getType();
2853 if (baseQT.isNull()) {
2854 Error("InspectMembers",
2855 "Cannot find QualType for base number %d while inspecting class %s",
2856 iNBase, clname);
2857 continue;
2858 }
2859 const clang::CXXRecordDecl* baseDecl
2860 = baseQT->getAsCXXRecordDecl();
2861 if (!baseDecl) {
2862 Error("InspectMembers",
2863 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
2864 iNBase, clname);
2865 continue;
2866 }
2867 TClass* baseCl=nullptr;
2868 std::string sBaseName;
2869 // Try with the DeclId
2870 std::vector<TClass*> foundClasses;
2871 TClass::GetClass(static_cast<DeclId_t>(baseDecl), foundClasses);
2872 if (foundClasses.size()==1){
2873 baseCl=foundClasses[0];
2874 } else {
2875 // Try with the normalised Name, as a fallback
2876 if (!baseCl){
2878 baseQT,
2879 *fInterpreter,
2881 baseCl = TClass::GetClass(sBaseName.c_str());
2882 }
2883 }
2884
2885 if (!baseCl){
2886 std::string qualNameForDiag;
2887 ROOT::TMetaUtils::GetQualifiedName(qualNameForDiag, *baseDecl);
2888 Error("InspectMembers",
2889 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
2890 continue;
2891 }
2892
2893 int64_t baseOffset;
2894 if (iBase->isVirtual()) {
2896 if (!isTransient) {
2897 Error("InspectMembers",
2898 "Base %s of class %s is virtual but no object provided",
2899 sBaseName.c_str(), clname);
2900 }
2902 } else {
2903 // We have an object to determine the vbase offset.
2905 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
2906 if (ci && baseCi) {
2907 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
2908 true /*isDerivedObj*/);
2909 if (baseOffset == -1) {
2910 Error("InspectMembers",
2911 "Error calculating offset of virtual base %s of class %s",
2912 sBaseName.c_str(), clname);
2913 }
2914 } else {
2915 Error("InspectMembers",
2916 "Cannot calculate offset of virtual base %s of class %s",
2917 sBaseName.c_str(), clname);
2918 continue;
2919 }
2920 }
2921 } else {
2922 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
2923 }
2924 // TOFIX: baseCl can be null here!
2925 if (baseCl->IsLoaded()) {
2926 // For loaded class, CallShowMember will (especially for TObject)
2927 // call the virtual ShowMember rather than the class specific version
2928 // resulting in an infinite recursion.
2929 InspectMembers(insp, cobj + baseOffset, baseCl, isTransient);
2930 } else {
2931 baseCl->CallShowMembers(cobj + baseOffset,
2932 insp, isTransient);
2933 }
2934 } // loop over bases
2935}
2936
2937////////////////////////////////////////////////////////////////////////////////
2938/// Reset the interpreter internal state in case a previous action was not correctly
2939/// terminated.
2940
2942{
2943 // No-op there is not equivalent state (to be cleared) in Cling.
2944}
2945
2946////////////////////////////////////////////////////////////////////////////////
2947/// Delete existing temporary values.
2948
2950{
2951 // No-op for cling due to cling::Value.
2952}
2953
2954////////////////////////////////////////////////////////////////////////////////
2955/// Declare code to the interpreter, without any of the interpreter actions
2956/// that could trigger a re-interpretation of the code. I.e. make cling
2957/// behave like a compiler: no dynamic lookup, no input wrapping for
2958/// subsequent execution, no automatic provision of declarations but just a
2959/// plain #include.
2960/// Returns true on success, false on failure.
2961
2962bool TCling::Declare(const char* code)
2963{
2965
2966 SuspendAutoLoadingRAII autoLoadOff(this);
2967 SuspendAutoParsing autoParseRaii(this);
2968
2969 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
2970 fInterpreter->enableDynamicLookup(false);
2971 bool oldRawInput = fInterpreter->isRawInputEnabled();
2972 fInterpreter->enableRawInput(true);
2973
2974 Bool_t ret = LoadText(code);
2975
2976 fInterpreter->enableRawInput(oldRawInput);
2977 fInterpreter->enableDynamicLookup(oldDynLookup);
2978 return ret;
2979}
2980
2981////////////////////////////////////////////////////////////////////////////////
2982/// It calls a "fantom" method to synchronize user keyboard input
2983/// and ROOT prompt line.
2984
2986{
2988}
2989
2990// This static function is a hop of TCling::IsLibraryLoaded, which is taking a lock and calling
2991// into this function. This is because we wanted to avoid a duplication in TCling::IsLoaded, which
2992// was already taking a lock.
2993static Bool_t s_IsLibraryLoaded(const char* libname, cling::Interpreter* fInterpreter)
2994{
2995 // Check shared library.
2996 TString tLibName(libname);
2997 if (gSystem->FindDynamicLibrary(tLibName, kTRUE))
2998 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
2999 return false;
3000}
3001
3002Bool_t TCling::IsLibraryLoaded(const char* libname) const
3003{
3005 return s_IsLibraryLoaded(libname, GetInterpreterImpl());
3006}
3007
3008////////////////////////////////////////////////////////////////////////////////
3009/// Return true if ROOT has cxxmodules pcm for a given library name.
3010// FIXME: We need to be able to support lazy loading of pcm generated by ACLiC.
3011Bool_t TCling::HasPCMForLibrary(const char *libname) const
3012{
3013 llvm::StringRef ModuleName(libname);
3014 ModuleName = llvm::sys::path::stem(ModuleName);
3015 ModuleName.consume_front("lib");
3016
3017 // FIXME: In case when the modulemap is not yet loaded we will return the
3018 // wrong result. Consider a call to HasPCMForLibrary(../test/libEvent.so)
3019 // We will only load the modulemap for libEvent.so after we dlopen libEvent
3020 // which may happen after calling this interface. Maybe we should also check
3021 // if there is a Event.pcm file and a module.modulemap, load it and return
3022 // true.
3023 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
3024 clang::Module *M = moduleMap.findModule(ModuleName);
3025 return M && !M->IsMissingRequirement && M->getASTFile();
3026}
3027
3028////////////////////////////////////////////////////////////////////////////////
3029/// Return true if the file has already been loaded by cint.
3030/// We will try in this order:
3031/// actual filename
3032/// filename as a path relative to
3033/// the include path
3034/// the shared library path
3035
3036Bool_t TCling::IsLoaded(const char* filename) const
3037{
3039
3040 //FIXME: if we use llvm::sys::fs::make_absolute all this can go away. See
3041 // cling::DynamicLibraryManager.
3042
3043 std::string file_name = filename;
3044 size_t at = std::string::npos;
3045 while ((at = file_name.find("/./")) != std::string::npos)
3046 file_name.replace(at, 3, "/");
3047
3048 std::string filesStr = "";
3049 llvm::raw_string_ostream filesOS(filesStr);
3050 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3051 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
3052 filesOS.flush();
3053
3054 llvm::SmallVector<llvm::StringRef, 100> files;
3055 llvm::StringRef(filesStr).split(files, "\n");
3056
3057 std::set<std::string> fileMap;
3058 // Fill fileMap; return early on exact match.
3059 for (llvm::SmallVector<llvm::StringRef, 100>::const_iterator
3060 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
3061 if ((*iF) == file_name.c_str()) return kTRUE; // exact match
3062 fileMap.insert(*iF);
3063 }
3064
3065 if (fileMap.empty()) return kFALSE;
3066
3067 // Check MacroPath.
3068 TString sFilename(file_name.c_str());
3070 && fileMap.count(sFilename.Data())) {
3071 return kTRUE;
3072 }
3073
3074 // Check IncludePath.
3075 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
3076 incPath.Append(":").Prepend(" "); // to match " -I" (note leading ' ')
3077 incPath.ReplaceAll(" -I", ":"); // of form :dir1 :dir2:dir3
3078 while (incPath.Index(" :") != -1) {
3079 incPath.ReplaceAll(" :", ":");
3080 }
3081 incPath.Prepend(".:");
3082 sFilename = file_name.c_str();
3083 if (gSystem->FindFile(incPath, sFilename, kReadPermission)
3084 && fileMap.count(sFilename.Data())) {
3085 return kTRUE;
3086 }
3087
3088 // Check shared library.
3089 if (s_IsLibraryLoaded(file_name.c_str(), GetInterpreterImpl()))
3090 return kTRUE;
3091
3092 //FIXME: We must use the cling::Interpreter::lookupFileOrLibrary iface.
3093 const clang::DirectoryLookup *CurDir = 0;
3094 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
3095 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
3096 const clang::FileEntry *FE = HS.LookupFile(file_name.c_str(),
3097 clang::SourceLocation(),
3098 /*isAngled*/ false,
3099 /*FromDir*/ 0, CurDir,
3100 clang::ArrayRef<std::pair<const clang::FileEntry *,
3101 const clang::DirectoryEntry *>>(),
3102 /*SearchPath*/ 0,
3103 /*RelativePath*/ 0,
3104 /*RequestingModule*/ 0,
3105 /*SuggestedModule*/ 0,
3106 /*IsMapped*/ 0,
3107 /*SkipCache*/ false,
3108 /*BuildSystemModule*/ false,
3109 /*OpenFile*/ false,
3110 /*CacheFail*/ false);
3111 if (FE && FE->isValid()) {
3112 // check in the source manager if the file is actually loaded
3113 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3114 // this works only with header (and source) files...
3115 clang::FileID FID = SM.translateFile(FE);
3116 if (!FID.isInvalid() && FID.getHashValue() == 0)
3117 return kFALSE;
3118 else {
3119 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
3120 if (SLocE.isFile() && SLocE.getFile().getContentCache()->getRawBuffer() == 0)
3121 return kFALSE;
3122 if (!FID.isInvalid())
3123 return kTRUE;
3124 }
3125 // ...then check shared library again, but with full path now
3126 sFilename = FE->getName();
3127 if (gSystem->FindDynamicLibrary(sFilename, kTRUE)
3128 && fileMap.count(sFilename.Data())) {
3129 return kTRUE;
3130 }
3131 }
3132 return kFALSE;
3133}
3134
3135
3136#if defined(R__MACOSX)
3137
3138////////////////////////////////////////////////////////////////////////////////
3139/// Check if lib is in the dynamic linker cache, returns true if it is, and if so,
3140/// modifies the library file name parameter `lib` from `/usr/lib/libFOO.dylib`
3141/// to `-lFOO` such that it can be passed to the linker.
3142/// This is a unique feature of macOS 11.
3143
3144static bool R__UpdateLibFileForLinking(TString &lib)
3145{
3146 const char *mapfile = nullptr;
3147#if __x86_64__
3148 mapfile = "/System/Library/dyld/dyld_shared_cache_x86_64.map";
3149#elif __arm64__
3150 mapfile = "/System/Library/dyld/dyld_shared_cache_arm64e.map";
3151#else
3152 #error unsupported architecture
3153#endif
3154 if (std::ifstream cacheMap{mapfile}) {
3155 std::string line;
3156 while (getline(cacheMap, line)) {
3157 if (line.find(lib) != std::string::npos) {
3158 lib.ReplaceAll("/usr/lib/lib","-l");
3159 lib.ReplaceAll(".dylib","");
3160 return true;
3161 }
3162 }
3163 return false;
3164 }
3165 return false;
3166}
3167#endif // R__MACOSX
3168
3169#ifdef R__LINUX
3170
3171////////////////////////////////////////////////////////////////////////////////
3172/// Callback for dl_iterate_phdr(), see `man dl_iterate_phdr`.
3173/// Collects opened libraries.
3174
3175static int callback_for_dl_iterate_phdr(struct dl_phdr_info *info, size_t size, void *data)
3176{
3177 // This function is called through UpdateListOfLoadedSharedLibraries() which is locked.
3178 static std::unordered_set<decltype(info->dlpi_addr)> sKnownLoadedLibBaseAddrs;
3179
3180 auto newLibs = static_cast<std::vector<std::string>*>(data);
3181 if (!sKnownLoadedLibBaseAddrs.count(info->dlpi_addr)) {
3182 // Skip \0, "", and kernel pseudo-libs linux-vdso.so.1 or linux-gate.so.1
3183 if (info->dlpi_name && info->dlpi_name[0]
3184 && strncmp(info->dlpi_name, "linux-vdso.so", 13)
3185 && strncmp(info->dlpi_name, "linux-gate.so", 13))
3186 newLibs->emplace_back(info->dlpi_name);
3187 sKnownLoadedLibBaseAddrs.insert(info->dlpi_addr);
3188 }
3189 // No matter what the doc says, return != 0 means "stop the iteration".
3190 return 0;
3191}
3192
3193#endif // R__LINUX
3194
3195
3196////////////////////////////////////////////////////////////////////////////////
3197
3199{
3200#if defined(R__WIN32) || defined(__CYGWIN__)
3201 HMODULE hModules[1024];
3202 void *hProcess;
3203 unsigned long cbModules;
3204 unsigned int i;
3205 hProcess = (void *)::GetCurrentProcess();
3206 ::EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbModules);
3207 // start at 1 to skip the executable itself
3208 for (i = 1; i < (cbModules / sizeof(void *)); i++) {
3209 static const int bufsize = 260;
3210 wchar_t winname[bufsize];
3211 char posixname[bufsize];
3212 ::GetModuleFileNameExW(hProcess, hModules[i], winname, bufsize);
3213#if defined(__CYGWIN__)
3214 cygwin_conv_path(CCP_WIN_W_TO_POSIX, winname, posixname, bufsize);
3215#else
3216 std::wstring wpath = winname;
3217 std::replace(wpath.begin(), wpath.end(), '\\', '/');
3218 string path(wpath.begin(), wpath.end());
3219 strncpy(posixname, path.c_str(), bufsize);
3220#endif
3221 if (!fSharedLibs.Contains(posixname)) {
3222 RegisterLoadedSharedLibrary(posixname);
3223 }
3224 }
3225#elif defined(R__MACOSX)
3226 // fPrevLoadedDynLibInfo stores the *next* image index to look at
3227 uint32_t imageIndex = (uint32_t) (size_t) fPrevLoadedDynLibInfo;
3228
3229 while (const mach_header* mh = _dyld_get_image_header(imageIndex)) {
3230 // Skip non-dylibs
3231 if (mh->filetype == MH_DYLIB) {
3232 if (const char* imageName = _dyld_get_image_name(imageIndex)) {
3233 RegisterLoadedSharedLibrary(imageName);
3234 }
3235 }
3236
3237 ++imageIndex;
3238 }
3239 fPrevLoadedDynLibInfo = (void*)(size_t)imageIndex;
3240#elif defined(R__LINUX)
3241 // fPrevLoadedDynLibInfo is unused on Linux.
3243
3244 std::vector<std::string> newLibs;
3245 dl_iterate_phdr(callback_for_dl_iterate_phdr, &newLibs);
3246 for (auto &&lib: newLibs)
3247 RegisterLoadedSharedLibrary(lib.c_str());
3248#else
3249 Error("TCling::UpdateListOfLoadedSharedLibraries",
3250 "Platform not supported!");
3251#endif
3252}
3253
3254////////////////////////////////////////////////////////////////////////////////
3255/// Register a new shared library name with the interpreter; add it to
3256/// fSharedLibs.
3257
3258void TCling::RegisterLoadedSharedLibrary(const char* filename)
3259{
3260 // Ignore NULL filenames, aka "the process".
3261 if (!filename) return;
3262
3263 // Tell the interpreter that this library is available; all libraries can be
3264 // used to resolve symbols.
3265 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3266 if (!DLM->isLibraryLoaded(filename)) {
3267 DLM->loadLibrary(filename, true /*permanent*/);
3268 }
3269
3270#if defined(R__MACOSX)
3271 // Check that this is not a system library
3272 auto lenFilename = strlen(filename);
3273 if (!strncmp(filename, "/usr/lib/system/", 16)
3274 || !strncmp(filename, "/usr/lib/libc++", 15)
3275 || !strncmp(filename, "/System/Library/Frameworks/", 27)
3276 || !strncmp(filename, "/System/Library/PrivateFrameworks/", 34)
3277 || !strncmp(filename, "/System/Library/CoreServices/", 29)
3278 || !strcmp(filename, "cl_kernels") // yepp, no directory
3279 || strstr(filename, "/usr/lib/libSystem")
3280 || strstr(filename, "/usr/lib/libstdc++")
3281 || strstr(filename, "/usr/lib/libicucore")
3282 || strstr(filename, "/usr/lib/libbsm")
3283 || strstr(filename, "/usr/lib/libobjc")
3284 || strstr(filename, "/usr/lib/libresolv")
3285 || strstr(filename, "/usr/lib/libauto")
3286 || strstr(filename, "/usr/lib/libcups")
3287 || strstr(filename, "/usr/lib/libDiagnosticMessagesClient")
3288 || strstr(filename, "/usr/lib/liblangid")
3289 || strstr(filename, "/usr/lib/libCRFSuite")
3290 || strstr(filename, "/usr/lib/libpam")
3291 || strstr(filename, "/usr/lib/libOpenScriptingUtil")
3292 || strstr(filename, "/usr/lib/libextension")
3293 || strstr(filename, "/usr/lib/libAudioToolboxUtility")
3294 || strstr(filename, "/usr/lib/liboah")
3295 || strstr(filename, "/usr/lib/libRosetta")
3296 // "cannot link directly with dylib/framework, your binary is not an allowed client of
3297 // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
3298 // SDKs/MacOSX.sdk/usr/lib/libAudioToolboxUtility.tbd for architecture x86_64
3299 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4, ".tbd")))
3300 return;
3301 TString sFileName(filename);
3302 R__UpdateLibFileForLinking(sFileName);
3303 filename = sFileName.Data();
3304#elif defined(__CYGWIN__)
3305 // Check that this is not a system library
3306 static const int bufsize = 260;
3307 char posixwindir[bufsize];
3308 char *windir = getenv("WINDIR");
3309 if (windir)
3310 cygwin_conv_path(CCP_WIN_A_TO_POSIX, windir, posixwindir, bufsize);
3311 else
3312 snprintf(posixwindir, sizeof(posixwindir), "/Windows/");
3313 if (strstr(filename, posixwindir) ||
3314 strstr(filename, "/usr/bin/cyg"))
3315 return;
3316#elif defined(R__WIN32)
3317 if (strstr(filename, "/Windows/"))
3318 return;
3319#elif defined (R__LINUX)
3320 if (strstr(filename, "/ld-linux")
3321 || strstr(filename, "linux-gnu/")
3322 || strstr(filename, "/libstdc++.")
3323 || strstr(filename, "/libgcc")
3324 || strstr(filename, "/libc.")
3325 || strstr(filename, "/libdl.")
3326 || strstr(filename, "/libm."))
3327 return;
3328#endif
3329 // Update string of available libraries.
3330 if (!fSharedLibs.IsNull()) {
3331 fSharedLibs.Append(" ");
3332 }
3333 fSharedLibs.Append(filename);
3334}
3335
3336////////////////////////////////////////////////////////////////////////////////
3337/// Load a library file in cling's memory.
3338/// if 'system' is true, the library is never unloaded.
3339/// Return 0 on success, -1 on failure.
3340
3341Int_t TCling::Load(const char* filename, Bool_t system)
3342{
3343 assert(!IsFromRootCling() && "Trying to load library from rootcling!");
3344
3345 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3347 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3348 std::string canonLib = DLM->lookupLibrary(filename);
3349 cling::DynamicLibraryManager::LoadLibResult res
3350 = cling::DynamicLibraryManager::kLoadLibNotFound;
3351 if (!canonLib.empty()) {
3352 if (system)
3353 res = DLM->loadLibrary(filename, system);
3354 else {
3355 // For the non system libs, we'd like to be able to unload them.
3356 // FIXME: Here we lose the information about kLoadLibAlreadyLoaded case.
3357 cling::Interpreter::CompilationResult compRes;
3358 HandleInterpreterException(GetMetaProcessorImpl(), Form(".L %s", canonLib.c_str()), compRes, /*cling::Value*/0);
3359 if (compRes == cling::Interpreter::kSuccess)
3360 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3361 }
3362 }
3363
3364 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3366 }
3367 switch (res) {
3368 case cling::DynamicLibraryManager::kLoadLibSuccess: return 0;
3369 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return 1;
3370 default: break;
3371 };
3372 return -1;
3373}
3374
3375////////////////////////////////////////////////////////////////////////////////
3376/// Load a macro file in cling's memory.
3377
3378void TCling::LoadMacro(const char* filename, EErrorCode* error)
3379{
3380 ProcessLine(Form(".L %s", filename), error);
3381}
3382
3383////////////////////////////////////////////////////////////////////////////////
3384/// Let cling process a command line asynch.
3385
3387{
3388 return ProcessLine(line, error);
3389}
3390
3391////////////////////////////////////////////////////////////////////////////////
3392/// Let cling process a command line synchronously, i.e we are waiting
3393/// it will be finished.
3394
3396{
3398 if (gApplication) {
3399 if (gApplication->IsCmdThread()) {
3400 return ProcessLine(line, error);
3401 }
3402 return 0;
3403 }
3404 return ProcessLine(line, error);
3405}
3406
3407////////////////////////////////////////////////////////////////////////////////
3408/// Directly execute an executable statement (e.g. "func()", "3+5", etc.
3409/// however not declarations, like "Int_t x;").
3410
3412{
3413#ifdef R__WIN32
3414 // Test on ApplicationImp not being 0 is needed because only at end of
3415 // TApplication ctor the IsLineProcessing flag is set to 0, so before
3416 // we can not use it.
3418 while (gROOT->IsLineProcessing() && !gApplication) {
3419 Warning("Calc", "waiting for cling thread to free");
3420 gSystem->Sleep(500);
3421 }
3422 gROOT->SetLineIsProcessing();
3423 }
3424#endif // R__WIN32
3426 if (error) {
3427 *error = TInterpreter::kNoError;
3428 }
3429 cling::Value valRef;
3430 cling::Interpreter::CompilationResult cr = fInterpreter->evaluate(line, valRef);
3431 if (cr != cling::Interpreter::kSuccess) {
3432 // Failure in compilation.
3433 if (error) {
3434 // Note: Yes these codes are weird.
3436 }
3437 return 0L;
3438 }
3439 if (!valRef.isValid()) {
3440 // Failure at runtime.
3441 if (error) {
3442 // Note: Yes these codes are weird.
3443 *error = TInterpreter::kDangerous;
3444 }
3445 return 0L;
3446 }
3447
3448 if (valRef.isVoid()) {
3449 return 0;
3450 }
3451
3452 RegisterTemporary(valRef);
3453#ifdef R__WIN32
3455 gROOT->SetLineHasBeenProcessed();
3456 }
3457#endif // R__WIN32
3458 return valRef.simplisticCastAs<long>();
3459}
3460
3461////////////////////////////////////////////////////////////////////////////////
3462/// Set a getline function to call when input is needed.
3463
3464void TCling::SetGetline(const char * (*getlineFunc)(const char* prompt),
3465 void (*histaddFunc)(const char* line))
3466{
3467 // If cling offers a replacement for G__pause(), it would need to
3468 // also offer a way to customize at least the history recording.
3469
3470#if defined(R__MUST_REVISIT)
3471#if R__MUST_REVISIT(6,2)
3472 Warning("SetGetline","Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3473#endif
3474#endif
3475}
3476
3477////////////////////////////////////////////////////////////////////////////////
3478/// Helper function to increase the internal Cling count of transactions
3479/// that change the AST.
3480
3481Bool_t TCling::HandleNewTransaction(const cling::Transaction &T)
3482{
3484
3485 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3486 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3487 || T.macros_begin() != T.macros_end()
3488 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3490 return true;
3491 }
3492 return false;
3493}
3494
3495////////////////////////////////////////////////////////////////////////////////
3496/// Delete object from cling symbol table so it can not be used anymore.
3497/// cling objects are always on the heap.
3498
3500{
3501 // NOTE: When replacing the mutex by a ReadWrite mutex, we **must**
3502 // put in place the Read/Write part here. Keeping the write lock
3503 // here is 'catasptrophic' for scaling as it means that ALL calls
3504 // to RecursiveRemove will take the write lock and performance
3505 // of many threads trying to access the write lock at the same
3506 // time is relatively bad.
3508 // Note that fgSetOfSpecials is supposed to be updated by TClingCallbacks::tryFindROOTSpecialInternal
3509 // (but isn't at the moment).
3510 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3511 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3512 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3514 DeleteGlobal(obj);
3515 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3516 }
3517 }
3518}
3519
3520////////////////////////////////////////////////////////////////////////////////
3521/// Pressing Ctrl+C should forward here. In the case where we have had
3522/// continuation requested we must reset it.
3523
3525{
3526 fMetaProcessor->cancelContinuation();
3527 // Reset the Cling state to the state saved by the last call to
3528 // TCling::SaveContext().
3529#if defined(R__MUST_REVISIT)
3530#if R__MUST_REVISIT(6,2)
3532 Warning("Reset","Cling should support the equivalent of scratch_upto(&fDictPos)");
3533#endif
3534#endif
3535}
3536
3537////////////////////////////////////////////////////////////////////////////////
3538/// Reset the Cling state to its initial state.
3539
3541{
3542#if defined(R__MUST_REVISIT)
3543#if R__MUST_REVISIT(6,2)
3545 Warning("ResetAll","Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3546#endif
3547#endif
3548}
3549
3550////////////////////////////////////////////////////////////////////////////////
3551/// Reset in Cling the list of global variables to the state saved by the last
3552/// call to TCling::SaveGlobalsContext().
3553///
3554/// Note: Right now, all we do is run the global destructors.
3555
3557{
3559 // TODO:
3560 // Here we should iterate over the transactions (N-3) and revert.
3561 // N-3 because the first three internal to cling.
3562
3563 fInterpreter->runAndRemoveStaticDestructors();
3564}
3565
3566////////////////////////////////////////////////////////////////////////////////
3567/// Reset the Cling 'user' global objects/variables state to the state saved by the last
3568/// call to TCling::SaveGlobalsContext().
3569
3571{
3572#if defined(R__MUST_REVISIT)
3573#if R__MUST_REVISIT(6,2)
3575 Warning("ResetGlobalVar","Cling should support the equivalent of resetglobalvar(obj)");
3576#endif
3577#endif
3578}
3579
3580////////////////////////////////////////////////////////////////////////////////
3581/// Rewind Cling dictionary to the point where it was before executing
3582/// the current macro. This function is typically called after SEGV or
3583/// ctlr-C after doing a longjmp back to the prompt.
3584
3586{
3587#if defined(R__MUST_REVISIT)
3588#if R__MUST_REVISIT(6,2)
3590 Warning("RewindDictionary","Cling should provide a way to revert transaction similar to rewinddictionary()");
3591#endif
3592#endif
3593}
3594
3595////////////////////////////////////////////////////////////////////////////////
3596/// Delete obj from Cling symbol table so it cannot be accessed anymore.
3597/// Returns 1 in case of success and 0 in case object was not in table.
3598
3600{
3601#if defined(R__MUST_REVISIT)
3602#if R__MUST_REVISIT(6,2)
3604 Warning("DeleteGlobal","Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3605#endif
3606#endif
3607 return 0;
3608}
3609
3610////////////////////////////////////////////////////////////////////////////////
3611/// Undeclare obj called name.
3612/// Returns 1 in case of success, 0 for failure.
3613
3615{
3616#if defined(R__MUST_REVISIT)
3617#if R__MUST_REVISIT(6,2)
3618 Warning("DeleteVariable","should do more that just reseting the value to zero");
3619#endif
3620#endif
3621
3623 llvm::StringRef srName(name);
3624 const char* unscopedName = name;
3625 llvm::StringRef::size_type posScope = srName.rfind("::");
3626 const clang::DeclContext* declCtx = 0;
3627 if (posScope != llvm::StringRef::npos) {
3628 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3629 const clang::Decl* scopeDecl
3630 = lh.findScope(srName.substr(0, posScope),
3631 cling::LookupHelper::WithDiagnostics);
3632 if (!scopeDecl) {
3633 Error("DeleteVariable", "Cannot find enclosing scope for variable %s",
3634 name);
3635 return 0;
3636 }
3637 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3638 if (!declCtx) {
3639 Error("DeleteVariable",
3640 "Enclosing scope for variable %s is not a declaration context",
3641 name);
3642 return 0;
3643 }
3644 unscopedName += posScope + 2;
3645 }
3646 // Could trigger deserialization of decls.
3647 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
3648 clang::NamedDecl* nVarDecl
3649 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3650 if (!nVarDecl) {
3651 Error("DeleteVariable", "Unknown variable %s", name);
3652 return 0;
3653 }
3654 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3655 if (!varDecl) {
3656 Error("DeleteVariable", "Entity %s is not a variable", name);
3657 return 0;
3658 }
3659
3660 clang::QualType qType = varDecl->getType();
3661 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3662 // Cannot set a reference's address to nullptr; the JIT can place it
3663 // into read-only memory (ROOT-7100).
3664 if (type->isPointerType()) {
3665 int** ppInt = (int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
3666 // set pointer to invalid.
3667 if (ppInt) *ppInt = 0;
3668 }
3669 return 1;
3670}
3671
3672////////////////////////////////////////////////////////////////////////////////
3673/// Save the current Cling state.
3674
3676{
3677#if defined(R__MUST_REVISIT)
3678#if R__MUST_REVISIT(6,2)
3680 Warning("SaveContext","Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
3681#endif
3682#endif
3683}
3684
3685////////////////////////////////////////////////////////////////////////////////
3686/// Save the current Cling state of global objects.
3687
3689{
3690#if defined(R__MUST_REVISIT)
3691#if R__MUST_REVISIT(6,2)
3693 Warning("SaveGlobalsContext","Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
3694#endif
3695#endif
3696}
3697
3698////////////////////////////////////////////////////////////////////////////////
3699/// No op: see TClingCallbacks (used to update the list of globals)
3700
3702{
3703}
3704
3705////////////////////////////////////////////////////////////////////////////////
3706/// No op: see TClingCallbacks (used to update the list of global functions)
3707
3709{
3710}
3711
3712////////////////////////////////////////////////////////////////////////////////
3713/// No op: see TClingCallbacks (used to update the list of types)
3714
3716{
3717}
3718
3719////////////////////////////////////////////////////////////////////////////////
3720/// Check in what order the member of a tuple are layout.
3721enum class ETupleOrdering {
3722 kAscending,
3725};
3726
3727struct AlternateTupleIntDoubleAsc
3728{
3729 Int_t _0;
3730 Double_t _1;
3731};
3732
3733struct AlternateTupleIntDoubleDes
3734{
3735 Double_t _1;
3736 Int_t _0;
3737};
3738
3740{
3741 std::tuple<int,double> value;
3742 AlternateTupleIntDoubleAsc asc;
3743 AlternateTupleIntDoubleDes des;
3744
3745 size_t offset0 = ((char*)&(std::get<0>(value))) - ((char*)&value);
3746 size_t offset1 = ((char*)&(std::get<1>(value))) - ((char*)&value);
3747
3748 size_t ascOffset0 = ((char*)&(asc._0)) - ((char*)&asc);
3749 size_t ascOffset1 = ((char*)&(asc._1)) - ((char*)&asc);
3750
3751 size_t desOffset0 = ((char*)&(des._0)) - ((char*)&des);
3752 size_t desOffset1 = ((char*)&(des._1)) - ((char*)&des);
3753
3754 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
3756 } else if (offset0 == desOffset0 && offset1 == desOffset1) {
3758 } else {
3760 }
3761}
3762
3763static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh)
3764{
3765 TClassEdit::TSplitType tupleContent(classname);
3766 std::string alternateName = "TEmulatedTuple";
3767 alternateName.append( classname + 5 );
3768
3769 std::string fullname = "ROOT::Internal::" + alternateName;
3770 if (lh.findScope(fullname, cling::LookupHelper::NoDiagnostics,
3771 /*resultType*/nullptr, /* intantiateTemplate= */ false))
3772 return fullname;
3773
3774 std::string guard_name;
3775 ROOT::TMetaUtils::GetCppName(guard_name,alternateName.c_str());
3776 std::ostringstream guard;
3777 guard << "ROOT_INTERNAL_TEmulated_";
3778 guard << guard_name;
3779
3780 std::ostringstream alternateTuple;
3781 alternateTuple << "#ifndef " << guard.str() << "\n";
3782 alternateTuple << "#define " << guard.str() << "\n";
3783 alternateTuple << "namespace ROOT { namespace Internal {\n";
3784 alternateTuple << "template <class... Types> struct TEmulatedTuple;\n";
3785 alternateTuple << "template <> struct " << alternateName << " {\n";
3786
3787 // This could also be a compile time choice ...
3788 switch(IsTupleAscending()) {
3790 unsigned int nMember = 0;
3791 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple)
3792 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
3793 while (iter != theEnd) {
3794 alternateTuple << " " << *iter << " _" << nMember << ";\n";
3795 ++iter;
3796 ++nMember;
3797 }
3798 break;
3799 }
3801 unsigned int nMember = tupleContent.fElements.size() - 3;
3802 auto iter = tupleContent.fElements.rbegin() + 1; // Skip the template name (tuple)
3803 auto theEnd = tupleContent.fElements.rend() - 1; // skip the 'stars'.
3804 while (iter != theEnd) {
3805 alternateTuple << " " << *iter << " _" << nMember << ";\n";
3806 ++iter;
3807 --nMember;
3808 }
3809 break;
3810 }
3812 Fatal("TCling::SetClassInfo::AlternateTuple",
3813 "Layout of std::tuple on this platform is unexpected.");
3814 break;
3815 }
3816 }
3817
3818 alternateTuple << "};\n";
3819 alternateTuple << "}}\n";
3820 alternateTuple << "#endif\n";
3821 if (!gCling->Declare(alternateTuple.str().c_str())) {
3822 Error("Load","Could not declare %s",alternateName.c_str());
3823 return "";
3824 }
3825 alternateName = "ROOT::Internal::" + alternateName;
3826 return alternateName;
3827}
3828
3829////////////////////////////////////////////////////////////////////////////////
3830/// Set pointer to the TClingClassInfo in TClass.
3831/// If 'reload' is true, (attempt to) generate a new ClassInfo even if we
3832/// already have one.
3833
3835{
3836 // We are shutting down, there is no point in reloading, it only triggers
3837 // redundant deserializations.
3838 if (fIsShuttingDown) {
3839 // Remove the decl_id from the DeclIdToTClass map
3840 if (cl->fClassInfo) {
3842 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
3843 // Test again as another thread may have set fClassInfo to nullptr.
3844 if (TClinginfo) {
3845 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
3846 }
3847 delete TClinginfo;
3848 cl->fClassInfo = nullptr;
3849 }
3850 return;
3851 }
3852
3854 if (cl->fClassInfo && !reload) {
3855 return;
3856 }
3857 //Remove the decl_id from the DeclIdToTClass map
3858 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
3859 if (TClinginfo) {
3860 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
3861 }
3862 delete TClinginfo;
3863 cl->fClassInfo = 0;
3864 std::string name(cl->GetName());
3865
3866 // Handle the special case of 'tuple' where we ignore the real implementation
3867 // details and just overlay a 'simpler'/'simplistic' version that is easy
3868 // for the I/O to understand and handle.
3869 if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
3870
3871 name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper());
3872
3873 }
3874
3875 bool instantiateTemplate = !cl->TestBit(TClass::kUnloading);
3876 // FIXME: Rather than adding an option to the TClingClassInfo, we should consider combining code
3877 // that is currently in the caller (like SetUnloaded) that disable AutoLoading and AutoParsing and
3878 // code is in the callee (disabling template instantiation) and end up with a more explicit class:
3879 // TClingClassInfoReadOnly.
3880 TClingClassInfo* info = new TClingClassInfo(GetInterpreterImpl(), name.c_str(), instantiateTemplate);
3881 if (!info->IsValid()) {
3882 if (cl->fState != TClass::kHasTClassInit) {
3883 if (cl->fStreamerInfo->GetEntries() != 0) {
3885 } else {
3887 }
3888 }
3889 delete info;
3890 return;
3891 }
3892 cl->fClassInfo = (ClassInfo_t*)info; // Note: We are transferring ownership here.
3893 // In case a class contains an external enum, the enum will be seen as a
3894 // class. We must detect this special case and make the class a Zombie.
3895 // Here we assume that a class has at least one method.
3896 // We can NOT call TClass::Property from here, because this method
3897 // assumes that the TClass is well formed to do a lot of information
3898 // caching. The method SetClassInfo (i.e. here) is usually called during
3899 // the building phase of the TClass, hence it is NOT well formed yet.
3900 Bool_t zombieCandidate = kFALSE;
3901 if (
3902 info->IsValid() &&
3903 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
3904 ) {
3905 zombieCandidate = kTRUE;
3906 }
3907 if (!info->IsLoaded()) {
3908 if (info->Property() & (kIsNamespace)) {
3909 // Namespaces can have info but no corresponding CINT dictionary
3910 // because they are auto-created if one of their contained
3911 // classes has a dictionary.
3912 zombieCandidate = kTRUE;
3913 }
3914 // this happens when no dictionary is available
3915 delete info;
3916 cl->fClassInfo = 0;
3917 }
3918 if (zombieCandidate && !cl->GetCollectionType()) {
3919 cl->MakeZombie();
3920 }
3921 // If we reach here, the info was valid (See early returns).
3922 if (cl->fState != TClass::kHasTClassInit) {
3923 if (cl->fClassInfo) {
3926 } else {
3927// if (TClassEdit::IsSTLCont(cl->GetName()) {
3928// There will be an emulated collection proxy, is that the same?
3929// cl->fState = TClass::kEmulated;
3930// } else {
3931 if (cl->fStreamerInfo->GetEntries() != 0) {
3933 } else {
3935 }
3936// }
3937 }
3938 }
3939 if (cl->fClassInfo) {
3940 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
3941 }
3942}
3943
3944////////////////////////////////////////////////////////////////////////////////
3945/// Checks if an entity with the specified name is defined in Cling.
3946/// Returns kUnknown if the entity is not defined.
3947/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
3948/// Returns kKnown if the entity is defined.
3949///
3950/// By default, structs, namespaces, classes, enums and unions are looked for.
3951/// If the flag isClassOrNamespaceOnly is true, classes, structs and
3952/// namespaces only are considered. I.e. if the name is an enum or a union,
3953/// the returned value is false.
3954///
3955/// In the case where the class is not loaded and belongs to a namespace
3956/// or is nested, looking for the full class name is outputting a lots of
3957/// (expected) error messages. Currently the only way to avoid this is to
3958/// specifically check that each level of nesting is already loaded.
3959/// In case of templates the idea is that everything between the outer
3960/// '<' and '>' has to be skipped, e.g.: aap<pippo<noot>::klaas>::a_class
3961
3963TCling::CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly /* = kFALSE*/)
3964{
3966 static const char *anonEnum = "anonymous enum ";
3967 static const int cmplen = strlen(anonEnum);
3968
3969 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
3970 return kUnknown;
3971 }
3972
3973 // Do not turn on the AutoLoading if it is globally off.
3974 autoload = autoload && IsClassAutoLoadingEnabled();
3975
3976 // Avoid the double search below in case the name is a fundamental type
3977 // or typedef to a fundamental type.
3978 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
3979 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
3980
3981 if (fundType && fundType->GetType() < TVirtualStreamerInfo::kObject
3982 && fundType->GetType() > 0) {
3983 // Fundamental type, no a class.
3984 return kUnknown;
3985 }
3986
3987 // Migrated from within TClass::GetClass
3988 // If we want to know if a class or a namespace with this name exists in the
3989 // interpreter and this is an enum in the type system, before or after loading
3990 // according to the autoload function argument, return kUnknown.
3991 if (isClassOrNamespaceOnly && TEnum::GetEnum(name, autoload ? TEnum::kAutoload : TEnum::kNone))
3992 return kUnknown;
3993
3994 const char *classname = name;
3995
3996 // RAII to suspend and restore auto-loading and auto-parsing based on some external conditions.
3997 class MaybeSuspendAutoLoadParse {
3998 int fStoreAutoLoad = 0;
3999 int fStoreAutoParse = 0;
4000 bool fSuspendedAutoParse = false;
4001 public:
4002 MaybeSuspendAutoLoadParse(int autoload) {
4003 fStoreAutoLoad = ((TCling*)gCling)->SetClassAutoLoading(autoload);
4004 }
4005
4006 void SuspendAutoParsing() {
4007 fSuspendedAutoParse = true;
4008 fStoreAutoParse = ((TCling*)gCling)->SetSuspendAutoParsing(true);
4009 }
4010
4011 ~~MaybeSuspendAutoLoadParse() {
4012 if (fSuspendedAutoParse)
4013 ((TCling*)gCling)->SetSuspendAutoParsing(fStoreAutoParse);
4014 ((TCling*)gCling)->SetClassAutoLoading(fStoreAutoLoad);
4015 }
4016 };
4017
4018 MaybeSuspendAutoLoadParse autoLoadParseRAII( autoload );
4019 if (TClassEdit::IsStdPair(classname) || TClassEdit::IsStdPairBase(classname))
4020 autoLoadParseRAII.SuspendAutoParsing();
4021
4022 // First we want to check whether the decl exist, but _without_
4023 // generating any template instantiation. However, the lookup
4024 // still will create a forward declaration of the class template instance
4025 // if it exist. In this case, the return value of findScope will still
4026 // be zero but the type will be initialized.
4027 // Note in the corresponding code in ROOT 5, CINT was not instantiating
4028 // this forward declaration.
4029 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4030 const clang::Type *type = 0;
4031 const clang::Decl *decl
4032 = lh.findScope(classname,
4033 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4034 : cling::LookupHelper::NoDiagnostics,
4035 &type, /* intantiateTemplate= */ false );
4036 if (!decl) {
4037 std::string buf = TClassEdit::InsertStd(classname);
4038 decl = lh.findScope(buf,
4039 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4040 : cling::LookupHelper::NoDiagnostics,
4041 &type,false);
4042 }
4043
4044 if (type) {
4045 // If decl==0 and the type is valid, then we have a forward declaration.
4046 if (!decl) {
4047 // If we have a forward declaration for a class template instantiation,
4048 // we want to ignore it if it was produced/induced by the call to
4049 // findScope, however we can not distinguish those from the
4050 // instantiation induce by 'soft' use (and thus also induce by the
4051 // same underlying code paths)
4052 // ['soft' use = use not requiring a complete definition]
4053 // So to reduce the amount of disruption to the existing code we
4054 // would just ignore those for STL collection, for which we really
4055 // need to have the compiled collection proxy (and thus the TClass
4056 // bootstrap).
4057 clang::ClassTemplateSpecializationDecl *tmpltDecl =
4058 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
4059 (type->getAsCXXRecordDecl());
4060 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
4061 // Since the point of instantiation is invalid, we 'guess' that
4062 // the 'instantiation' of the forwarded type appended in
4063 // findscope.
4064 if (ROOT::TMetaUtils::IsSTLCont(*tmpltDecl)) {
4065 // For STL Collection we return kUnknown.
4066 return kUnknown;
4067 }
4068 }
4069 }
4070 TClingClassInfo tci(GetInterpreterImpl(), *type);
4071 if (!tci.IsValid()) {
4072 return kUnknown;
4073 }
4074 auto propertiesMask = isClassOrNamespaceOnly ? kIsClass | kIsStruct | kIsNamespace :
4076
4077 if (tci.Property() & propertiesMask) {
4078 bool hasClassDefInline = false;
4079 if (isClassOrNamespaceOnly) {
4080 // We do not need to check for ClassDefInline when this is called from
4081 // TClass::Init, we only do it for the call from TClass::GetClass.
4082 auto hasDictionary = tci.GetMethod("Dictionary", "", false, 0, ROOT::kExactMatch);
4083 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, 0, ROOT::kExactMatch);
4084
4085 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
4086 int lineNumber = 0;
4087 bool success = false;
4088 std::tie(success, lineNumber) =
4089 ROOT::TMetaUtils::GetTrivialIntegralReturnValue(implLineFunc.GetAsFunctionDecl(), *fInterpreter);
4090 hasClassDefInline = success && (lineNumber == -1);
4091 }
4092 }
4093
4094 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
4095 // , hasClassDefInline);
4096
4097 // We are now sure that the entry is not in fact an autoload entry.
4098 if (hasClassDefInline)
4099 return kWithClassDefInline;
4100 else
4101 return kKnown;
4102 } else {
4103 // We are now sure that the entry is not in fact an autoload entry.
4104 return kUnknown;
4105 }
4106 }
4107
4108 if (decl)
4109 return kKnown;
4110 else
4111 return kUnknown;
4112
4113 // Setting up iterator part of TClingTypedefInfo is too slow.
4114 // Copy the lookup code instead:
4115 /*
4116 TClingTypedefInfo t(fInterpreter, name);
4117 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
4118 delete[] classname;
4119 return kTRUE;
4120 }
4121 */
4122
4123// const clang::Decl *decl = lh.findScope(name);
4124// if (!decl) {
4125// std::string buf = TClassEdit::InsertStd(name);
4126// decl = lh.findScope(buf);
4127// }
4128
4129// return (decl);
4130}
4131
4132////////////////////////////////////////////////////////////////////////////////
4133/// Return true if there is a class template by the given name ...
4134
4136{
4137 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4138 const clang::Decl *decl
4139 = lh.findClassTemplate(name,
4140 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4141 : cling::LookupHelper::NoDiagnostics);
4142 if (!decl) {
4143 std::string strname = "std::";
4144 strname += name;
4145 decl = lh.findClassTemplate(strname,
4146 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4147 : cling::LookupHelper::NoDiagnostics);
4148 }
4149 return 0 != decl;
4150}
4151
4152////////////////////////////////////////////////////////////////////////////////
4153/// Create list of pointers to base class(es) for TClass cl.
4154
4156{
4158 if (cl->fBase) {
4159 return;
4160 }
4162 if (!tci) return;
4164 TList *listOfBase = new TList;
4165 while (t.Next()) {
4166 // if name cannot be obtained no use to put in list
4167 if (t.IsValid() && t.Name()) {
4169 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
4170 }
4171 }
4172 // Now that is complete, publish it.
4173 cl->fBase = listOfBase;
4174}
4175
4176////////////////////////////////////////////////////////////////////////////////
4177/// Create list of pointers to enums for TClass cl.
4178
4179void TCling::LoadEnums(TListOfEnums& enumList) const
4180{
4182
4183 const Decl * D;
4184 TClass* cl = enumList.GetClass();
4185 if (cl) {
4186 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4187 }
4188 else {
4189 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4190 }
4191 // Iterate on the decl of the class and get the enums.
4192 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4193 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4194 // Collect all contexts of the namespace.
4195 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4196 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4197 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(), declEnd = allDeclContexts.end();
4198 declIter != declEnd; ++declIter) {
4199 // Iterate on all decls for each context.
4200 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4201 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4202 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4203 // Get name of the enum type.
4204 std::string buf;
4205 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4206 llvm::raw_string_ostream stream(buf);
4207 // Don't trigger fopen of the source file to count lines:
4208 Policy.AnonymousTagLocations = false;
4209 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
4210 stream.flush();
4211 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
4212 if (!buf.empty()) {
4213 const char* name = buf.c_str();
4214 // Add the enum to the list of loaded enums.
4215 enumList.Get(ED, name);
4216 }
4217 }
4218 }
4219 }
4220 }
4221}
4222
4223////////////////////////////////////////////////////////////////////////////////
4224/// Create list of pointers to function templates for TClass cl.
4225
4227{
4229
4230 const Decl * D;
4231 TListOfFunctionTemplates* funcTempList;
4232 if (cl) {
4233 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4234 funcTempList = (TListOfFunctionTemplates*)cl->GetListOfFunctionTemplates(false);
4235 }
4236 else {
4237 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4238 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4239 }
4240 // Iterate on the decl of the class and get the enums.
4241 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4242 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4243 // Collect all contexts of the namespace.
4244 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4245 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4246 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(),
4247 declEnd = allDeclContexts.end(); declIter != declEnd; ++declIter) {
4248 // Iterate on all decls for each context.
4249 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4250 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4251 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4252 funcTempList->Get(FTD);
4253 }
4254 }
4255 }
4256 }
4257}
4258
4259////////////////////////////////////////////////////////////////////////////////
4260/// Get the scopes representing using declarations of namespace
4261
4262std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4263{
4265 return ci->GetUsingNamespaces();
4266}
4267
4268////////////////////////////////////////////////////////////////////////////////
4269/// Create list of pointers to data members for TClass cl.
4270/// This is now a nop. The creation and updating is handled in
4271/// TListOfDataMembers.
4272
4274{
4275}
4276
4277////////////////////////////////////////////////////////////////////////////////
4278/// Create list of pointers to methods for TClass cl.
4279/// This is now a nop. The creation and updating is handled in
4280/// TListOfFunctions.
4281
4283{
4284}
4285
4286////////////////////////////////////////////////////////////////////////////////
4287/// Update the list of pointers to method for TClass cl
4288/// This is now a nop. The creation and updating is handled in
4289/// TListOfFunctions.
4290
4292{
4293}
4294
4295////////////////////////////////////////////////////////////////////////////////
4296/// Update the list of pointers to data members for TClass cl
4297/// This is now a nop. The creation and updating is handled in
4298/// TListOfDataMembers.
4299
4301{
4302}
4303
4304////////////////////////////////////////////////////////////////////////////////
4305/// Create list of pointers to method arguments for TMethod m.
4306
4308{
4310 if (m->fMethodArgs) {
4311 return;
4312 }
4313 TList *arglist = new TList;
4315 while (t.Next()) {
4316 if (t.IsValid()) {
4318 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4319 }
4320 }
4321 m->fMethodArgs = arglist;
4322}
4323
4324
4325////////////////////////////////////////////////////////////////////////////////
4326/// Generate a TClass for the given class.
4327/// Since the caller has already check the ClassInfo, let it give use the
4328/// result (via the value of emulation) rather than recalculate it.
4329
4330TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4331{
4332// For now the following line would lead to the (unwanted) instantiation
4333// of class template. This could/would need to be resurrected only if
4334// we re-introduce so sort of automatic instantiation. However this would
4335// have to include carefull look at the template parameter to avoid
4336// creating instance we can not really use (if the parameter are only forward
4337// declaration or do not have all the necessary interfaces).
4338
4339 // TClingClassInfo tci(fInterpreter, classname);
4340 // if (1 || !tci.IsValid()) {
4341
4342 Version_t version = 1;
4343 if (TClassEdit::IsSTLCont(classname)) {
4344 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4345 }
4347 TClass *cl = new TClass(classname, version, silent);
4348 if (emulation) {
4350 } else {
4351 // Set the class version if the class is versioned.
4352 // Note that we cannot just call CLASS::Class_Version() as we might not have
4353 // an execution engine (when invoked from rootcling).
4354
4355 // Do not call cl->GetClassVersion(), it has side effects!
4356 Version_t oldvers = cl->fClassVersion;
4357 if (oldvers == version && cl->GetClassInfo()) {
4358 // We have a version and it might need an update.
4359 Version_t newvers = oldvers;
4361 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4362 // Namespaces don't have class versions.
4363 return cl;
4364 }
4365 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", 0 /*poffset*/,
4368 if (!mi.IsValid()) {
4369 if (cl->TestBit(TClass::kIsTObject)) {
4370 Error("GenerateTClass",
4371 "Cannot find %s::Class_Version()! Class version might be wrong.",
4372 cl->GetName());
4373 }
4374 return cl;
4375 }
4376 newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4377 *fInterpreter);
4378 if (newvers == -1) {
4379 // Didn't manage to determine the class version from the AST.
4380 // Use runtime instead.
4381 if ((mi.Property() & kIsStatic)
4382 && !fInterpreter->isInSyntaxOnlyMode()) {
4383 // This better be a static function.
4385 callfunc.SetFunc(&mi);
4386 newvers = callfunc.ExecInt(0);
4387 } else {
4388 Error("GenerateTClass",
4389 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4390 cl->GetName());
4391 }
4392 }
4393 if (newvers != oldvers) {
4394 cl->fClassVersion = newvers;
4395 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4396 }
4397 }
4398 }
4399
4400 return cl;
4401
4402// } else {
4403// return GenerateTClass(&tci,silent);
4404// }
4405}
4406
4407#if 0
4408////////////////////////////////////////////////////////////////////////////////
4409
4410static void GenerateTClass_GatherInnerIncludes(cling::Interpreter *interp, TString &includes,TClingClassInfo *info)
4411{
4412 includes += info->FileName();
4413
4414 const clang::ClassTemplateSpecializationDecl *templateCl
4415 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4416 if (templateCl) {
4417 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4418 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4419 if (arg.getKind() == clang::TemplateArgument::Type) {
4420 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4421
4422 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4423 // We really need a header file.
4424 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4425 if (argdecl) {
4426 includes += ";";
4427 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4428 GenerateTClass_GatherInnerIncludes(interp, includes, &subinfo);
4429 } else {
4430 std::string Result;
4431 llvm::raw_string_ostream OS(Result);
4432 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4433 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4434 }
4435 }
4436 }
4437 }
4438 }
4439}
4440#endif
4441
4442////////////////////////////////////////////////////////////////////////////////
4443/// Generate a TClass for the given class.
4444
4445TClass *TCling::GenerateTClass(ClassInfo_t *classinfo, Bool_t silent /* = kFALSE */)
4446{
4447 TClingClassInfo *info = (TClingClassInfo*)classinfo;
4448 if (!info || !info->IsValid()) {
4449 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4450 return 0;
4451 }
4452 // We are in the case where we have AST nodes for this class.
4453 TClass *cl = 0;
4454 std::string classname;
4455 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4456 if (TClassEdit::IsSTLCont(classname)) {
4457#if 0
4458 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4459 // We need to build up the list of required headers, by
4460 // looking at each template arguments.
4461 TString includes;
4462 GenerateTClass_GatherInnerIncludes(fInterpreter,includes,info);
4463
4464 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4465 // 0 means success.
4466 cl = TClass::LoadClass(classnam.c_str(), silent);
4467 if (cl == 0) {
4468 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4469 }
4470 }
4471#endif
4472 if (cl == 0) {
4473 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4474 cl = new TClass(classinfo, version, 0, 0, -1, -1, silent);
4476 }
4477 } else {
4478 // For regular class, just create a TClass on the fly ...
4479 // Not quite useful yet, but that what CINT used to do anyway.
4480 cl = new TClass(classinfo, 1, 0, 0, -1, -1, silent);
4481 }
4482 // Add the new TClass to the map of declid and TClass*.
4483 if (cl) {
4485 }
4486 return cl;
4487}
4488
4489////////////////////////////////////////////////////////////////////////////////
4490/// Generate the dictionary for the C++ classes listed in the first
4491/// argument (in a semi-colon separated list).
4492/// 'includes' contains a semi-colon separated list of file to
4493/// #include in the dictionary.
4494/// For example:
4495/// ~~~ {.cpp}
4496/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4497/// ~~~
4498/// or
4499/// ~~~ {.cpp}
4500/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4501/// ~~~
4502
4503Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4504{
4505 if (classes == 0 || classes[0] == 0) {
4506 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4507 return 0;
4508 }
4509 // Split the input list
4510 std::vector<std::string> listClasses;
4511 for (
4512 const char* current = classes, *prev = classes;
4513 *current != 0;
4514 ++current
4515 ) {
4516 if (*current == ';') {
4517 listClasses.push_back(std::string(prev, current - prev));
4518 prev = current + 1;
4519 }
4520 else if (*(current + 1) == 0) {
4521 listClasses.push_back(std::string(prev, current + 1 - prev));
4522 prev = current + 1;
4523 }
4524 }
4525 std::vector<std::string> listIncludes;
4526 if (!includes)
4527 includes = "";
4528 for (
4529 const char* current = includes, *prev = includes;
4530 *current != 0;
4531 ++current
4532 ) {
4533 if (*current == ';') {
4534 listIncludes.push_back(std::string(prev, current - prev));
4535 prev = current + 1;
4536 }
4537 else if (*(current + 1) == 0) {
4538 listIncludes.push_back(std::string(prev, current + 1 - prev));
4539 prev = current + 1;
4540 }
4541 }
4542 // Generate the temporary dictionary file
4543 return !TCling_GenerateDictionary(listClasses, listIncludes,
4544 std::vector<std::string>(), std::vector<std::string>());
4545}
4546
4547////////////////////////////////////////////////////////////////////////////////
4548/// Return pointer to cling Decl of global/static variable that is located
4549/// at the address given by addr.
4550
4551TInterpreter::DeclId_t TCling::GetDataMember(ClassInfo_t *opaque_cl, const char *name) const
4552{
4554 DeclId_t d;
4555 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4556
4557 if (cl) {
4558 d = cl->GetDataMember(name);
4559 // We check if the decl of the data member has an annotation which indicates
4560 // an ioname.
4561 // In case this is true, if the name requested is not the ioname, we
4562 // return 0, as if the member did not exist. In some sense we override
4563 // the information in the TClassInfo instance, isolating the typesystem in
4564 // TClass from the one in the AST.
4565 if (const ValueDecl* decl = (const ValueDecl*) d){
4566 std::string ioName;
4567 bool hasIoName = ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"ioname",ioName);
4568 if (hasIoName && ioName != name) return 0;
4569 }
4570 return d;
4571 }
4572 // We are looking up for something on the TU scope.
4573 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
4574 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
4575 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
4576 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
4577 // are only fulfilling ROOT's understanding for a Data Member.
4578 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
4579 // similar as below.
4580 using namespace clang;
4581 Sema& SemaR = fInterpreter->getSema();
4582 DeclarationName DName = &SemaR.Context.Idents.get(name);
4583
4584 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
4585 Sema::ForRedeclaration);
4586
4587 // Could trigger deserialization of decls.
4588 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4589 cling::utils::Lookup::Named(&SemaR, R);
4590
4591 LookupResult::Filter F = R.makeFilter();
4592 // Filter the data-member looking decls.
4593 while (F.hasNext()) {
4594 NamedDecl *D = F.next();
4595 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) ||
4596 isa<IndirectFieldDecl>(D))
4597 continue;
4598 F.erase();
4599 }
4600 F.done();
4601
4602 if (R.isSingleResult())
4603 return R.getFoundDecl();
4604 return 0;
4605}
4606
4607////////////////////////////////////////////////////////////////////////////////
4608/// Return pointer to cling Decl of global/static variable that is located
4609/// at the address given by addr.
4610
4612{
4614
4615 const clang::Decl* possibleEnum = 0;
4616 // FInd the context of the decl.
4617 if (cl) {
4619 if (cci) {
4620 const clang::DeclContext* dc = 0;
4621 if (const clang::Decl* D = cci->GetDecl()) {
4622 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
4623 dc = dyn_cast<clang::RecordDecl>(D);
4624 }
4625 }
4626 if (dc) {
4627 // If it is a data member enum.
4628 // Could trigger deserialization of decls.
4629 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4630 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
4631 } else {
4632 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
4633 }
4634 }
4635 } else {
4636 // If it is a global enum.
4637 // Could trigger deserialization of decls.
4638 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4639 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
4640 }
4641 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
4642 && isa<clang::EnumDecl>(possibleEnum)) {
4643 return possibleEnum;
4644 }
4645 return 0;
4646}
4647
4648////////////////////////////////////////////////////////////////////////////////
4649/// Return pointer to cling DeclId for a global value
4650
4651TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
4652{
4653 if (!gv) return 0;
4654
4655 llvm::StringRef mangled_name = gv->getName();
4656
4657 int err = 0;
4658 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.str().c_str(), err);
4659 if (err) {
4660 if (err == -2) {
4661 // It might simply be an unmangled global name.
4662 DeclId_t d;
4664 d = gcl.GetDataMember(mangled_name.str().c_str());
4665 return d;
4666 }
4667 return 0;
4668 }
4669
4670 std::string scopename(demangled_name_c);
4671 free(demangled_name_c);
4672
4673 //
4674 // Separate out the class or namespace part of the
4675 // function name.
4676 //
4677 std::string dataname;
4678
4679 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
4680 scopename.erase(0, sizeof("typeinfo for ")-1);
4681 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
4682 scopename.erase(0, sizeof("vtable for ")-1);
4683 } else {
4684 // See if it is a function
4685 std::string::size_type pos = scopename.rfind('(');
4686 if (pos != std::string::npos) {
4687 return 0;
4688 }
4689 // Separate the scope and member name
4690 pos = scopename.rfind(':');
4691 if (pos != std::string::npos) {
4692 if ((pos != 0) && (scopename[pos-1] == ':')) {
4693 dataname = scopename.substr(pos+1);
4694 scopename.erase(pos-1);
4695 }
4696 } else {
4697 scopename.clear();
4698 dataname = scopename;
4699 }
4700 }
4701 //fprintf(stderr, "name: '%s'\n", name.c_str());
4702 // Now we have the class or namespace name, so do the lookup.
4703
4704
4705 DeclId_t d;
4706 if (scopename.size()) {
4707 TClingClassInfo cl(GetInterpreterImpl(), scopename.c_str());
4708 d = cl.GetDataMember(dataname.c_str());
4709 }
4710 else {
4712 d = gcl.GetDataMember(dataname.c_str());
4713 }
4714 return d;
4715}
4716
4717////////////////////////////////////////////////////////////////////////////////
4718/// NOT IMPLEMENTED.
4719
4721{
4722 Error("GetDataMemberWithValue()", "not implemented");
4723 return 0;
4724}
4725
4726////////////////////////////////////////////////////////////////////////////////
4727/// Return pointer to cling DeclId for a data member with a given name.
4728
4730{
4731 // NOT IMPLEMENTED.
4732 Error("GetDataMemberAtAddr()", "not implemented");
4733 return 0;
4734}
4735
4736////////////////////////////////////////////////////////////////////////////////
4737/// Return the cling mangled name for a method of a class with parameters
4738/// params (params is a string of actual arguments, not formal ones). If the
4739/// class is 0 the global function list will be searched.
4740
4741TString TCling::GetMangledName(TClass* cl, const char* method,
4742 const char* params, Bool_t objectIsConst /* = kFALSE */)
4743{
4746 if (cl) {
4747 Long_t offset;
4748 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4749 &offset);
4750 }
4751 else {
4753 Long_t offset;
4754 func.SetFunc(&gcl, method, params, &offset);
4755 }
4757 if (!mi) return "";
4758 TString mangled_name( mi->GetMangledName() );
4759 delete mi;
4760 return mangled_name;
4761}
4762
4763////////////////////////////////////////////////////////////////////////////////
4764/// Return the cling mangled name for a method of a class with a certain
4765/// prototype, i.e. "char*,int,float". If the class is 0 the global function
4766/// list will be searched.
4767
4769 const char* proto, Bool_t objectIsConst /* = kFALSE */,
4770 EFunctionMatchMode mode /* = kConversionMatch */)
4771{
4773 if (cl) {
4774 return ((TClingClassInfo*)cl->GetClassInfo())->
4775 GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetMangledName();
4776 }
4778 return gcl.GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetMangledName();
4779}
4780
4781////////////////////////////////////////////////////////////////////////////////
4782/// Return pointer to cling interface function for a method of a class with
4783/// parameters params (params is a string of actual arguments, not formal
4784/// ones). If the class is 0 the global function list will be searched.
4785
4786void* TCling::GetInterfaceMethod(TClass* cl, const char* method,
4787 const char* params, Bool_t objectIsConst /* = kFALSE */)
4788{
4791 if (cl) {
4792 Long_t offset;
4793 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4794 &offset);
4795 }
4796 else {
4798 Long_t offset;
4799 func.SetFunc(&gcl, method, params, &offset);
4800 }
4801 return (void*) func.InterfaceMethod();
4802}
4803
4804////////////////////////////////////////////////////////////////////////////////
4805/// Return pointer to cling interface function for a method of a class with
4806/// a certain name.
4807
4808TInterpreter::DeclId_t TCling::GetFunction(ClassInfo_t *opaque_cl, const char* method)
4809{
4811 DeclId_t f;
4812 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4813 if (cl) {
4814 f = cl->GetMethod(method).GetDeclId();
4815 }
4816 else {
4818 f = gcl.GetMethod(method).GetDeclId();
4819 }
4820 return f;
4821
4822}
4823
4824////////////////////////////////////////////////////////////////////////////////
4825/// Insert overloads of name in cl to res.
4826
4827void TCling::GetFunctionOverloads(ClassInfo_t *cl, const char *funcname,
4828 std::vector<DeclId_t>& res) const
4829{
4830 clang::Sema& S = fInterpreter->getSema();
4831 clang::ASTContext& Ctx = S.Context;
4832 const clang::Decl* CtxDecl
4833 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
4834 Ctx.getTranslationUnitDecl();
4835 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
4836 const clang::DeclContext* DeclCtx = RecDecl;
4837
4838 if (!DeclCtx)
4839 DeclCtx = dyn_cast<clang::NamespaceDecl>(CtxDecl);
4840 if (!DeclCtx) return;
4841
4842 clang::DeclarationName DName;
4843 // The DeclarationName is funcname, unless it's a ctor or dtor.
4844 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
4845
4846 if (RecDecl) {
4847 if (RecDecl->getNameAsString() == funcname) {
4848 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
4849 DName = Ctx.DeclarationNames.getCXXConstructorName(Ctx.getCanonicalType(QT));
4850 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
4851 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
4852 DName = Ctx.DeclarationNames.getCXXDestructorName(Ctx.getCanonicalType(QT));
4853 } else {
4854 DName = &Ctx.Idents.get(funcname);
4855 }
4856 } else {
4857 DName = &Ctx.Idents.get(funcname);
4858 }
4859
4860 // NotForRedeclaration: we want to find names in inline namespaces etc.
4861 clang::LookupResult R(S, DName, clang::SourceLocation(),
4862 Sema::LookupOrdinaryName, clang::Sema::NotForRedeclaration);
4863 R.suppressDiagnostics(); // else lookup with NotForRedeclaration will check access etc
4864 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
4865 if (R.empty()) return;
4866 R.resolveKind();
4867 res.reserve(res.size() + (R.end() - R.begin()));
4868 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
4869 IR != ER; ++IR) {
4870 if (const clang::FunctionDecl* FD
4871 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
4872 if (!FD->getDescribedFunctionTemplate()) {
4873 res.push_back(FD);
4874 }
4875 } else if (const auto *USD = llvm::dyn_cast<const clang::UsingShadowDecl>(*IR)) {
4876 // FIXME: multi-level using
4877 if (llvm::isa<clang::FunctionDecl>(USD->getTargetDecl())) {
4878 res.push_back(USD);
4879 }
4880 }
4881 }
4882}
4883
4884////////////////////////////////////////////////////////////////////////////////
4885/// Return pointer to cling interface function for a method of a class with
4886/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
4887/// function list will be searched.
4888
4890 const char* proto,
4891 Bool_t objectIsConst /* = kFALSE */,
4892 EFunctionMatchMode mode /* = kConversionMatch */)
4893{
4895 void* f;
4896 if (cl) {
4897 f = ((TClingClassInfo*)cl->GetClassInfo())->
4898 GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).InterfaceMethod(*fNormalizedCtxt);
4899 }
4900 else {
4902 f = gcl.GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).InterfaceMethod(*fNormalizedCtxt);
4903 }
4904 return f;
4905}
4906
4907////////////////////////////////////////////////////////////////////////////////
4908/// Return pointer to cling DeclId for a method of a class with
4909/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
4910/// function list will be searched.
4911
4912TInterpreter::DeclId_t TCling::GetFunctionWithValues(ClassInfo_t *opaque_cl, const char* method,
4913 const char* params,
4914 Bool_t objectIsConst /* = kFALSE */)
4915{
4917 DeclId_t f;
4918 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4919 if (cl) {
4920 f = cl->GetMethodWithArgs(method, params, objectIsConst, 0 /*poffset*/).GetDeclId();
4921 }
4922 else {
4924 f = gcl.GetMethod(method, params, objectIsConst, 0 /*poffset*/).GetDeclId();
4925 }
4926 return f;
4927}
4928
4929////////////////////////////////////////////////////////////////////////////////
4930/// Return pointer to cling interface function for a method of a class with
4931/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
4932/// function list will be searched.
4933
4934TInterpreter::DeclId_t TCling::GetFunctionWithPrototype(ClassInfo_t *opaque_cl, const char* method,
4935 const char* proto,
4936 Bool_t objectIsConst /* = kFALSE */,
4937 EFunctionMatchMode mode /* = kConversionMatch */)
4938{
4940 DeclId_t f;
4941 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4942 if (cl) {
4943 f = cl->GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetDeclId();
4944 }
4945 else {
4947 f = gcl.GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetDeclId();
4948 }
4949 return f;
4950}
4951
4952////////////////////////////////////////////////////////////////////////////////
4953/// Return pointer to cling interface function for a method of a class with
4954/// a certain name.
4955
4956TInterpreter::DeclId_t TCling::GetFunctionTemplate(ClassInfo_t *opaque_cl, const char* name)
4957{
4959 DeclId_t f;
4960 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4961 if (cl) {
4962 f = cl->GetFunctionTemplate(name);
4963 }
4964 else {
4966 f = gcl.GetFunctionTemplate(name);
4967 }
4968 return f;
4969
4970}
4971
4972////////////////////////////////////////////////////////////////////////////////
4973/// The 'name' is known to the interpreter, this function returns
4974/// the internal version of this name (usually just resolving typedefs)
4975/// This is used in particular to synchronize between the name used
4976/// by rootcling and by the run-time environment (TClass)
4977/// Return 0 if the name is not known.
4978
4979void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
4980{
4981 output.clear();
4982
4984
4986 if (!cl.IsValid()) {
4987 return ;
4988 }
4989 if (full) {
4991 return;
4992 }
4993 // Well well well, for backward compatibility we need to act a bit too
4994 // much like CINT.
4997
4998 return;
4999}
5000
5001////////////////////////////////////////////////////////////////////////////////
5002/// Execute a global function with arguments params.
5003///
5004/// FIXME: The cint-based version of this code does not check if the
5005/// SetFunc() call works, and does not do any real checking
5006/// for errors from the Exec() call. It did fetch the most
5007/// recent cint security error and return that in error, but
5008/// this does not really translate well to cling/clang. We
5009/// should enhance these interfaces so that we can report
5010/// compilation and runtime errors properly.
5011
5012void TCling::Execute(const char* function, const char* params, int* error)
5013{
5015 if (error) {
5016 *error = TInterpreter::kNoError;
5017 }
5019 Long_t offset = 0L;
5021 func.SetFunc(&cl, function, params, &offset);
5022 func.Exec(0);
5023}
5024
5025////////////////////////////////////////////////////////////////////////////////
5026/// Execute a method from class cl with arguments params.
5027///
5028/// FIXME: The cint-based version of this code does not check if the
5029/// SetFunc() call works, and does not do any real checking
5030/// for errors from the Exec() call. It did fetch the most
5031/// recent cint security error and return that in error, but
5032/// this does not really translate well to cling/clang. We
5033/// should enhance these interfaces so that we can report
5034/// compilation and runtime errors properly.
5035
5036void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5037 const char* params, Bool_t objectIsConst, int* error)
5038{
5040 if (error) {
5041 *error = TInterpreter::kNoError;
5042 }
5043 // If the actual class of this object inherits 2nd (or more) from TObject,
5044 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5045 // hence gInterpreter->Execute will improperly correct the offset.
5046 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5047 Long_t offset = 0L;
5049 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst, &offset);
5050 void* address = (void*)((Long_t)addr + offset);
5051 func.Exec(address);
5052}
5053
5054////////////////////////////////////////////////////////////////////////////////
5055
5056void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5057 const char* params, int* error)
5058{
5059 Execute(obj,cl,method,params,false,error);
5060}
5061
5062////////////////////////////////////////////////////////////////////////////////
5063/// Execute a method from class cl with the arguments in array params
5064/// (params[0] ... params[n] = array of TObjString parameters).
5065/// Convert the TObjArray array of TObjString parameters to a character
5066/// string of comma separated parameters.
5067/// The parameters of type 'char' are enclosed in double quotes and all
5068/// internal quotes are escaped.
5069
5070void TCling::Execute(TObject* obj, TClass* cl, TMethod* method,
5071 TObjArray* params, int* error)
5072{
5073 if (!method) {
5074 Error("Execute", "No method was defined");
5075 return;
5076 }
5077 TList* argList = method->GetListOfMethodArgs();
5078 // Check number of actual parameters against of expected formal ones
5079
5080 Int_t nparms = argList->LastIndex() + 1;
5081 Int_t argc = params ? params->GetEntries() : 0;
5082
5083 if (argc > nparms) {
5084 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
5085 return;
5086 }
5087 if (nparms != argc) {
5088 // Let's see if the 'missing' argument are all defaulted.
5089 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
5090 assert(nparms > 0);
5091
5092 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
5093 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5094 // There is a default value for the first missing
5095 // argument, so we are fine.
5096 } else {
5097 Int_t firstDefault = -1;
5098 for (Int_t i = 0; i < nparms; i ++) {
5099 arg = (TMethodArg *) argList->At( i );
5100 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5101 firstDefault = i;
5102 break;
5103 }
5104 }
5105 if (firstDefault >= 0) {
5106 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);
5107 } else {
5108 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
5109 }
5110 return;
5111 }
5112 }
5113
5114 const char* listpar = "";
5115 TString complete(10);
5116 if (params) {
5117 // Create a character string of parameters from TObjArray
5118 TIter next(params);
5119 for (Int_t i = 0; i < argc; i ++) {
5120 TMethodArg* arg = (TMethodArg*) argList->At(i);
5122 TObjString* nxtpar = (TObjString*) next();
5123 if (i) {
5124 complete += ',';
5125 }
5126 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
5127 TString chpar('\"');
5128 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
5129 // At this point we have to check if string contains \\"
5130 // and apply some more sophisticated parser. Not implemented yet!
5131 complete += chpar;
5132 complete += '\"';
5133 }
5134 else {
5135 complete += nxtpar->String();
5136 }
5137 }
5138 listpar = complete.Data();
5139 }
5140
5141 // And now execute it.
5143 if (error) {
5144 *error = TInterpreter::kNoError;
5145 }
5146 // If the actual class of this object inherits 2nd (or more) from TObject,
5147 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5148 // hence gInterpreter->Execute will improperly correct the offset.
5149 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5151 TClingMethodInfo *minfo = (TClingMethodInfo*)method->fInfo;
5152 func.Init(*minfo);
5153 func.SetArgs(listpar);
5154 // Now calculate the 'this' pointer offset for the method
5155 // when starting from the class described by cl.
5156 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetTargetFunctionDecl());
5157 Long_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
5158 void* address = (void*)((Long_t)addr + offset);
5159 func.Exec(address);
5160}
5161
5162////////////////////////////////////////////////////////////////////////////////
5163
5164void TCling::ExecuteWithArgsAndReturn(TMethod* method, void* address,
5165 const void* args[] /*=0*/,
5166 int nargs /*=0*/,
5167 void* ret/*= 0*/) const
5168{
5169 if (!method) {
5170 Error("ExecuteWithArgsAndReturn", "No method was defined");
5171 return;
5172 }
5173
5174 TClingMethodInfo* minfo = (TClingMethodInfo*) method->fInfo;
5175 TClingCallFunc func(*minfo,*fNormalizedCtxt);
5176 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5177}
5178
5179////////////////////////////////////////////////////////////////////////////////
5180/// Execute a cling macro.
5181
5182Long_t TCling::ExecuteMacro(const char* filename, EErrorCode* error)
5183{
5185 fCurExecutingMacros.push_back(filename);
5186 Long_t result = TApplication::ExecuteFile(filename, (int*)error);
5187 fCurExecutingMacros.pop_back();
5188 return result;
5189}
5190
5191////////////////////////////////////////////////////////////////////////////////
5192/// Return the file name of the current un-included interpreted file.
5193/// See the documentation for GetCurrentMacroName().
5194
5196{
5197 Warning("GetTopLevelMacroName", "Must change return type!");
5198 return fCurExecutingMacros.back();
5199}
5200
5201////////////////////////////////////////////////////////////////////////////////
5202/// Return the file name of the currently interpreted file,
5203/// included or not. Example to illustrate the difference between
5204/// GetCurrentMacroName() and GetTopLevelMacroName():
5205/// ~~~ {.cpp}
5206/// void inclfile() {
5207/// std::cout << "In inclfile.C" << std::endl;
5208/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5209/// TCling::GetCurrentMacroName() << std::endl;
5210/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5211/// TCling::GetTopLevelMacroName() << std::endl;
5212/// }
5213/// ~~~
5214/// ~~~ {.cpp}
5215/// void mymacro() {
5216/// std::cout << "In mymacro.C" << std::endl;
5217/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5218/// TCling::GetCurrentMacroName() << std::endl;
5219/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5220/// TCling::GetTopLevelMacroName() << std::endl;
5221/// std::cout << " Now calling inclfile..." << std::endl;
5222/// gInterpreter->ProcessLine(".x inclfile.C");;
5223/// }
5224/// ~~~
5225/// Running mymacro.C will print:
5226///
5227/// ~~~ {.cpp}
5228/// root [0] .x mymacro.C
5229/// ~~~
5230/// In mymacro.C
5231/// ~~~ {.cpp}
5232/// TCling::GetCurrentMacroName() returns ./mymacro.C
5233/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5234/// ~~~
5235/// Now calling inclfile...
5236/// In inclfile.h
5237/// ~~~ {.cpp}
5238/// TCling::GetCurrentMacroName() returns inclfile.C
5239/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5240/// ~~~
5241
5243{
5244#if defined(R__MUST_REVISIT)
5245#if R__MUST_REVISIT(6,0)
5246 Warning("GetCurrentMacroName", "Must change return type!");
5247#endif
5248#endif
5249 return fCurExecutingMacros.back();
5250}
5251
5252////////////////////////////////////////////////////////////////////////////////
5253/// Return the absolute type of typeDesc.
5254/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
5255/// You need to use the result immediately before it is being overwritten.
5256
5257const char* TCling::TypeName(const char* typeDesc)
5258{
5259 TTHREAD_TLS(char*) t = 0;
5260 TTHREAD_TLS(unsigned int) tlen = 0;
5261
5262 unsigned int dlen = strlen(typeDesc);
5263 if (dlen > tlen) {
5264 delete[] t;
5265 t = new char[dlen + 1];
5266 tlen = dlen;
5267 }
5268 const char* s, *template_start;
5269 if (!strstr(typeDesc, "(*)(")) {
5270 s = strchr(typeDesc, ' ');
5271 template_start = strchr(typeDesc, '<');
5272 if (!strcmp(typeDesc, "long long")) {
5273 strlcpy(t, typeDesc, dlen + 1);
5274 }
5275 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5276 strlcpy(t, typeDesc, dlen + 1);
5277 }
5278 // s is the position of the second 'word' (if any)
5279 // except in the case of templates where there will be a space
5280 // just before any closing '>': eg.
5281 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5282 else if (s && (template_start == 0 || (s < template_start))) {
5283 strlcpy(t, s + 1, dlen + 1);
5284 }
5285 else {
5286 strlcpy(t, typeDesc, dlen + 1);
5287 }
5288 }
5289 else {
5290 strlcpy(t, typeDesc, dlen + 1);
5291 }
5292 int l = strlen(t);
5293 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&')) {
5294 t[--l] = 0;
5295 }
5296 return t;
5297}
5298
5299static bool requiresRootMap(const char* rootmapfile, cling::Interpreter* interp)
5300{
5301 assert(rootmapfile && *rootmapfile);
5302
5303 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5304 libName.consume_back(".rootmap");
5305
5306 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5307}
5308
5309////////////////////////////////////////////////////////////////////////////////
5310/// Read and parse a rootmapfile in its new format, and return 0 in case of
5311/// success, -1 if the file has already been read, and -3 in case its format
5312/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5313/// error.
5314
5315int TCling::ReadRootmapFile(const char *rootmapfile, TUniqueString *uniqueString)
5316{
5317 if (!(rootmapfile && *rootmapfile))
5318 return 0;
5319
5320 if (!requiresRootMap(rootmapfile, GetInterpreterImpl()))
5321 return 0; // success
5322
5323 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5324 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5325
5326 std::string rootmapfileNoBackslash(rootmapfile);
5327#ifdef _MSC_VER
5328 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5329#endif
5330 // Add content of a specific rootmap file
5331 if (fRootmapFiles->FindObject(rootmapfileNoBackslash.c_str()))
5332 return -1;
5333
5334 if (uniqueString)
5335 uniqueString->Append(std::string("\n#line 1 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n");
5336
5337 std::ifstream file(rootmapfileNoBackslash);
5338 std::string line;
5339 line.reserve(200);
5340 std::string lib_name;
5341 line.reserve(100);
5342 bool newFormat = false;
5343 while (getline(file, line, '\n')) {
5344 if (!newFormat && (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5345 file.close();
5346 return -3; // old format
5347 }
5348 newFormat = true;
5349
5350 if (line.compare(0, 9, "{ decls }") == 0) {
5351 // forward declarations
5352
5353 while (getline(file, line, '\n')) {
5354 if (line[0] == '[')
5355 break;
5356 if (!uniqueString) {
5357 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5358 rootmapfileNoBackslash.c_str());
5359 return -4;
5360 }
5361 uniqueString->Append(line);
5362 }
5363 }
5364 const char firstChar = line[0];
5365 if (firstChar == '[') {
5366 // new section (library)
5367 auto brpos = line.find(']');
5368 if (brpos == string::npos)
5369 continue;
5370 lib_name = line.substr(1, brpos - 1);
5371 size_t nspaces = 0;
5372 while (lib_name[nspaces] == ' ')
5373 ++nspaces;
5374 if (nspaces)
5375 lib_name.replace(0, nspaces, "");
5376 if (gDebug > 3) {
5377 TString lib_nameTstr(lib_name.c_str());
5378 TObjArray *tokens = lib_nameTstr.Tokenize(" ");
5379 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5380 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5381 if (wlib) {
5382 Info("ReadRootmapFile", "new section for %s", lib_nameTstr.Data());
5383 } else {
5384 Info("ReadRootmapFile", "section for %s (library does not exist)", lib_nameTstr.Data());
5385 }
5386 delete[] wlib;
5387 delete tokens;
5388 }
5389 } else {
5390 auto keyLenIt = keyLenMap.find(firstChar);
5391 if (keyLenIt == keyLenMap.end())
5392 continue;
5393 unsigned int keyLen = keyLenIt->second;
5394 // Do not make a copy, just start after the key
5395 const char *keyname = line.c_str() + keyLen;
5396 if (gDebug > 6)
5397 Info("ReadRootmapFile", "class %s in %s", keyname, lib_name.c_str());
5398 TEnvRec *isThere = fMapfile->Lookup(keyname);
5399 if (isThere) {
5400 if (lib_name != isThere->GetValue()) { // the same key for two different libs
5401 if (firstChar == 'n') {
5402 if (gDebug > 3)
5403 Info("ReadRootmapFile", "namespace %s found in %s is already in %s", keyname, lib_name.c_str(),
5404 isThere->GetValue());
5405 } else if (firstChar == 'h') { // it is a header: add the libname to the list of libs to be loaded.
5406 lib_name += " ";
5407 lib_name += isThere->GetValue();
5408 fMapfile->SetValue(keyname, lib_name.c_str());
5409 } else if (!TClassEdit::IsSTLCont(keyname)) {
5410 Warning("ReadRootmapFile", "%s %s found in %s is already in %s", line.substr(0, keyLen).c_str(),
5411 keyname, lib_name.c_str(), isThere->GetValue());
5412 }
5413 } else { // the same key for the same lib
5414 if (gDebug > 3)
5415 Info("ReadRootmapFile", "Key %s was already defined for %s", keyname, lib_name.c_str());
5416 }
5417 } else {
5418 fMapfile->SetValue(keyname, lib_name.c_str());
5419 }
5420 }
5421 }
5422 file.close();
5423 return 0;
5424}
5425
5426////////////////////////////////////////////////////////////////////////////////
5427/// Create a resource table and read the (possibly) three resource files, i.e
5428/// $ROOTSYS/etc/system<name> (or ROOTETCDIR/system<name>), $HOME/<name> and
5429/// ./<name>. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You can
5430/// read additional user defined resource files by creating additional TEnv
5431/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5432/// the $HOME/<name> resource file will be skipped. This might be useful in
5433/// case the home directory resides on an automounted remote file system
5434/// and one wants to avoid the file system from being mounted.
5435
5437{
5438 assert(requiresRootMap(name, GetInterpreterImpl()) && "We have a module!");
5439
5441 return;
5442
5444
5446
5447 TString sname = "system";
5448 sname += name;
5449 char *s = gSystem->ConcatFileName(TROOT::GetEtcDir(), sname);
5450
5451 Int_t ret = ReadRootmapFile(s);
5452 if (ret == -3) // old format
5454 delete [] s;
5455 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5457 ret = ReadRootmapFile(s);
5458 if (ret == -3) // old format
5460 delete [] s;
5461 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
5462 ret = ReadRootmapFile(name);
5463 if (ret == -3) // old format
5465 }
5466 } else {
5467 ret = ReadRootmapFile(name);
5468 if (ret == -3) // old format
5470 }
5471 fMapfile->IgnoreDuplicates(ignore);
5472}
5473
5474
5475namespace {
5476 using namespace clang;
5477
5478 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5479 // This class is to be considered an helper for AutoLoading.
5480 // It is a recursive visitor is used to inspect namespaces coming from
5481 // forward declarations in rootmaps and to set the external visible
5482 // storage flag for them.
5483 public:
5484 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5485 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5486 // We want to enable the external lookup for this namespace
5487 // because it may shadow the lookup of other names contained
5488 // in that namespace
5489
5490 nsDecl->setHasExternalVisibleStorage();
5491 fNSSet.insert(nsDecl);
5492 return true;
5493 }
5494 private:
5495 std::unordered_set<const NamespaceDecl*>& fNSSet;
5496
5497 };
5498}
5499
5500////////////////////////////////////////////////////////////////////////////////
5501/// Load map between class and library. If rootmapfile is specified a
5502/// specific rootmap file can be added (typically used by ACLiC).
5503/// In case of error -1 is returned, 0 otherwise.
5504/// The interpreter uses this information to automatically load the shared
5505/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5506
5507Int_t TCling::LoadLibraryMap(const char* rootmapfile)
5508{
5509 if (rootmapfile && *rootmapfile && !requiresRootMap(rootmapfile, GetInterpreterImpl()))
5510 return 0;
5511
5513
5514 // open the [system].rootmap files
5515 if (!fMapfile) {
5516 fMapfile = new TEnv();
5520 InitRootmapFile(".rootmap");
5521 }
5522
5523 // Prepare a list of all forward declarations for cling
5524 // For some experiments it is easily as big as 500k characters. To be on the
5525 // safe side, we go for 1M.
5526 TUniqueString uniqueString(1048576);
5527
5528 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5529 // A rootmap file must end with the string ".rootmap".
5530 TString ldpath = gSystem->GetDynamicPath();
5531 if (ldpath != fRootmapLoadPath) {
5532 fRootmapLoadPath = ldpath;
5533#ifdef WIN32
5534 TObjArray* paths = ldpath.Tokenize(";");
5535#else
5536 TObjArray* paths = ldpath.Tokenize(":");
5537#endif
5538 TString d;
5539 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5540 d = ((TObjString *)paths->At(i))->GetString();
5541 // check if directory already scanned
5542 Int_t skip = 0;
5543 for (Int_t j = 0; j < i; j++) {
5544 TString pd = ((TObjString *)paths->At(j))->GetString();
5545 if (pd == d) {
5546 skip++;
5547 break;
5548 }
5549 }
5550 if (!skip) {
5551 void* dirp = gSystem->OpenDirectory(d);
5552 if (dirp) {
5553 if (gDebug > 3) {
5554 Info("LoadLibraryMap", "%s", d.Data());
5555 }
5556 const char* f1;
5557 while ((f1 = gSystem->GetDirEntry(dirp))) {
5558 TString f = f1;
5559 if (f.EndsWith(".rootmap")) {
5560 TString p;
5561 p = d + "/" + f;
5563 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
5564 if (gDebug > 4) {
5565 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
5566 }
5567 Int_t ret = ReadRootmapFile(p, &uniqueString);
5568
5569 if (ret == 0)
5571 if (ret == -3) {
5572 // old format
5574 fRootmapFiles->Add(new TNamed(f, p));
5575 }
5576 }
5577 // else {
5578 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
5579 // fRootmapFiles->FindObject(f)->ls();
5580 // }
5581 }
5582 }
5583 if (f.BeginsWith("rootmap")) {
5584 TString p;
5585 p = d + "/" + f;
5586 FileStat_t stat;
5587 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
5588 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
5589 }
5590 }
5591 }
5592 }
5593 gSystem->FreeDirectory(dirp);
5594 }
5595 }
5596 delete paths;
5597 if (fMapfile->GetTable() && !