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