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.Data());
5491 }
5492 Int_t ret = ReadRootmapFile(p, &uniqueString);
5493
5494 if (ret == 0)
5496 if (ret == -3) {
5497 // old format
5499 fRootmapFiles->Add(new TNamed(f, p));
5500 }
5501 }
5502 // else {
5503 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
5504 // fRootmapFiles->FindObject(f)->ls();
5505 // }
5506 }
5507 }
5508 if (f.BeginsWith("rootmap")) {
5509 TString p;
5510 p = d + "/" + f;
5511 FileStat_t stat;
5512 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
5513 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
5514 }
5515 }
5516 }
5517 }
5518 gSystem->FreeDirectory(dirp);
5519 }
5520 }
5521 delete paths;
5522 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
5523 return -1;
5524 }
5525 }
5526 if (rootmapfile && *rootmapfile) {
5527 Int_t res = ReadRootmapFile(rootmapfile, &uniqueString);
5528 if (res == 0) {
5529 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
5530 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
5531 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5532 }
5533 else if (res == -3) {
5534 // old format
5536 fMapfile->ReadFile(rootmapfile, kEnvGlobal);
5537 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5538 fMapfile->IgnoreDuplicates(ignore);
5539 }
5540 }
5541 TEnvRec* rec;
5542 TIter next(fMapfile->GetTable());
5543 while ((rec = (TEnvRec*) next())) {
5544 TString cls = rec->GetName();
5545 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5546 // get the first lib from the list of lib and dependent libs
5547 TString libs = rec->GetValue();
5548 if (libs == "") {
5549 continue;
5550 }
5551 TString delim(" ");
5552 TObjArray* tokens = libs.Tokenize(delim);
5553 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5554 // convert "@@" to "::", we used "@@" because TEnv
5555 // considers "::" a terminator
5556 cls.Remove(0, 8);
5557 cls.ReplaceAll("@@", "::");
5558 // convert "-" to " ", since class names may have
5559 // blanks and TEnv considers a blank a terminator
5560 cls.ReplaceAll("-", " ");
5561 if (gDebug > 6) {
5562 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
5563 if (wlib) {
5564 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
5565 }
5566 else {
5567 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
5568 }
5569 delete[] wlib;
5570 }
5571 delete tokens;
5572 }
5573 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
5574 cls.Remove(0, 8);
5575 // convert "-" to " ", since class names may have
5576 // blanks and TEnv considers a blank a terminator
5577 cls.ReplaceAll("-", " ");
5578 fInterpreter->declare(cls.Data());
5579 }
5580 }
5581
5582 // Process the forward declarations collected
5583 cling::Transaction* T = nullptr;
5584 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
5585 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
5586
5587 if (compRes!=cling::Interpreter::kSuccess){
5588 Warning("LoadLibraryMap",
5589 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
5590 }
5591
5592 if (T){
5593 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
5594 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
5595 if (declIt->m_DGR.isSingleDecl()) {
5596 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
5597 if (NamespaceDecl* NSD = dyn_cast<NamespaceDecl>(D)) {
5598 evsAdder.TraverseDecl(NSD);
5599 }
5600 }
5601 }
5602 }
5603 }
5604
5605 // clear duplicates
5606
5607 return 0;
5608}
5609
5610////////////////////////////////////////////////////////////////////////////////
5611/// Scan again along the dynamic path for library maps. Entries for the loaded
5612/// shared libraries are unloaded first. This can be useful after reseting
5613/// the dynamic path through TSystem::SetDynamicPath()
5614/// In case of error -1 is returned, 0 otherwise.
5615
5617{
5620 return 0;
5621}
5622
5623////////////////////////////////////////////////////////////////////////////////
5624/// Reload the library map entries coming from all the loaded shared libraries,
5625/// after first unloading the current ones.
5626/// In case of error -1 is returned, 0 otherwise.
5627
5629{
5630 const TString sharedLibLStr = GetSharedLibs();
5631 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5632 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
5633 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
5634 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5635 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5636 const Int_t ret = UnloadLibraryMap(sharedLibBaseStr);
5637 if (ret < 0) {
5638 continue;
5639 }
5640 TString rootMapBaseStr = sharedLibBaseStr;
5641 if (sharedLibBaseStr.EndsWith(".dll")) {
5642 rootMapBaseStr.ReplaceAll(".dll", "");
5643 }
5644 else if (sharedLibBaseStr.EndsWith(".DLL")) {
5645 rootMapBaseStr.ReplaceAll(".DLL", "");
5646 }
5647 else if (sharedLibBaseStr.EndsWith(".so")) {
5648 rootMapBaseStr.ReplaceAll(".so", "");
5649 }
5650 else if (sharedLibBaseStr.EndsWith(".sl")) {
5651 rootMapBaseStr.ReplaceAll(".sl", "");
5652 }
5653 else if (sharedLibBaseStr.EndsWith(".dl")) {
5654 rootMapBaseStr.ReplaceAll(".dl", "");
5655 }
5656 else if (sharedLibBaseStr.EndsWith(".a")) {
5657 rootMapBaseStr.ReplaceAll(".a", "");
5658 }
5659 else {
5660 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
5661 delete sharedLibL;
5662 return -1;
5663 }
5664 rootMapBaseStr += ".rootmap";
5665 const char* rootMap = gSystem->Which(gSystem->GetDynamicPath(), rootMapBaseStr);
5666 if (!rootMap) {
5667 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
5668 delete[] rootMap;
5669 delete sharedLibL;
5670 return -1;
5671 }
5672 const Int_t status = LoadLibraryMap(rootMap);
5673 if (status < 0) {
5674 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
5675 delete[] rootMap;
5676 delete sharedLibL;
5677 return -1;
5678 }
5679 delete[] rootMap;
5680 }
5681 delete sharedLibL;
5682 return 0;
5683}
5684
5685////////////////////////////////////////////////////////////////////////////////
5686/// Unload the library map entries coming from all the loaded shared libraries.
5687/// Returns 0 if succesful
5688
5690{
5691 const TString sharedLibLStr = GetSharedLibs();
5692 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5693 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
5694 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5695 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5696 UnloadLibraryMap(sharedLibBaseStr);
5697 }
5698 delete sharedLibL;
5699 return 0;
5700}
5701
5702////////////////////////////////////////////////////////////////////////////////
5703/// Unload library map entries coming from the specified library.
5704/// Returns -1 in case no entries for the specified library were found,
5705/// 0 otherwise.
5706
5708{
5709 if (!fMapfile || !library || !*library) {
5710 return 0;
5711 }
5712 TString libname(library);
5713 Ssiz_t idx = libname.Last('.');
5714 if (idx != kNPOS) {
5715 libname.Remove(idx);
5716 }
5717 size_t len = libname.Length();
5718 TEnvRec *rec;
5719 TIter next(fMapfile->GetTable());
5721 Int_t ret = 0;
5722 while ((rec = (TEnvRec *) next())) {
5723 TString cls = rec->GetName();
5724 if (cls.Length() > 2) {
5725 // get the first lib from the list of lib and dependent libs
5726 TString libs = rec->GetValue();
5727 if (libs == "") {
5728 continue;
5729 }
5730 TString delim(" ");
5731 TObjArray* tokens = libs.Tokenize(delim);
5732 const char* lib = ((TObjString *)tokens->At(0))->GetName();
5733 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5734 // convert "@@" to "::", we used "@@" because TEnv
5735 // considers "::" a terminator
5736 cls.Remove(0, 8);
5737 cls.ReplaceAll("@@", "::");
5738 // convert "-" to " ", since class names may have
5739 // blanks and TEnv considers a blank a terminator
5740 cls.ReplaceAll("-", " ");
5741 }
5742 if (!strncmp(lib, libname.Data(), len)) {
5743 if (fMapfile->GetTable()->Remove(rec) == 0) {
5744 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
5745 ret = -1;
5746 }
5747 }
5748 delete tokens;
5749 }
5750 }
5751 if (ret >= 0) {
5752 TString library_rootmap(library);
5753 if (!library_rootmap.EndsWith(".rootmap"))
5754 library_rootmap.Append(".rootmap");
5755 TNamed* mfile = 0;
5756 while ((mfile = (TNamed *)fRootmapFiles->FindObject(library_rootmap))) {
5757 fRootmapFiles->Remove(mfile);
5758 delete mfile;
5759 }
5761 }
5762 return ret;
5763}
5764
5765////////////////////////////////////////////////////////////////////////////////
5766/// Register the autoloading information for a class.
5767/// libs is a space separated list of libraries.
5768
5769Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
5770{
5771 if (!cls || !*cls)
5772 return 0;
5773
5774 TString key = TString("Library.") + cls;
5775 // convert "::" to "@@", we used "@@" because TEnv
5776 // considers "::" a terminator
5777 key.ReplaceAll("::", "@@");
5778 // convert "-" to " ", since class names may have
5779 // blanks and TEnv considers a blank a terminator
5780 key.ReplaceAll(" ", "-");
5781
5783 if (!fMapfile) {
5784 fMapfile = new TEnv();
5786
5789
5790 InitRootmapFile(".rootmap");
5791 }
5792 //fMapfile->SetValue(key, libs);
5793 fMapfile->SetValue(cls, libs);
5794 return 1;
5795}
5796
5797////////////////////////////////////////////////////////////////////////////////
5798/// Demangle the name (from the typeinfo) and then request the class
5799/// via the usual name based interface (TClass::GetClass).
5800
5801TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
5802{
5803 int err = 0;
5804 char* demangled_name = TClassEdit::DemangleTypeIdName(typeinfo, err);
5805 if (err) return 0;
5806 TClass* theClass = TClass::GetClass(demangled_name, load, kTRUE);
5807 free(demangled_name);
5808 return theClass;
5809}
5810
5811////////////////////////////////////////////////////////////////////////////////
5812/// Load library containing the specified class. Returns 0 in case of error
5813/// and 1 in case if success.
5814
5815Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
5816{
5817 assert(IsClassAutoloadingEnabled() && "Calling when autoloading is off!");
5818
5819 int err = 0;
5820 char* demangled_name_c = TClassEdit::DemangleTypeIdName(typeinfo, err);
5821 if (err) {
5822 return 0;
5823 }
5824
5825 std::string demangled_name(demangled_name_c);
5826 free(demangled_name_c);
5827
5828 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
5829 // shortened name.
5831 splitname.ShortType(demangled_name, TClassEdit::kDropStlDefault | TClassEdit::kDropStd);
5832
5833 // No need to worry about typedef, they aren't any ... but there are
5834 // inlined namespaces ...
5835
5836 Int_t result = AutoLoad(demangled_name.c_str());
5837 if (result == 0) {
5838 demangled_name = TClassEdit::GetLong64_Name(demangled_name);
5839 result = AutoLoad(demangled_name.c_str(), knowDictNotLoaded);
5840 }
5841
5842 return result;
5843}
5844
5845////////////////////////////////////////////////////////////////////////////////
5846// Get the list of 'published'/'known' library for the class and load them.
5848{
5849 Int_t status = 0;
5850
5851 // lookup class to find list of dependent libraries
5852 TString deplibs = gCling->GetClassSharedLibs(cls);
5853 if (!deplibs.IsNull()) {
5854 TString delim(" ");
5855 TObjArray* tokens = deplibs.Tokenize(delim);
5856 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
5857 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
5858 if (gROOT->LoadClass(cls, deplib) == 0) {
5859 if (gDebug > 0) {
5860 gCling->Info("TCling::AutoLoad",
5861 "loaded dependent library %s for %s", deplib, cls);
5862 }
5863 }
5864 else {
5865 gCling->Error("TCling::AutoLoad",
5866 "failure loading dependent library %s for %s",
5867 deplib, cls);
5868 }
5869 }
5870 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5871 if (lib && lib[0]) {
5872 if (gROOT->LoadClass(cls, lib) == 0) {
5873 if (gDebug > 0) {
5874 gCling->Info("TCling::AutoLoad",
5875 "loaded library %s for %s", lib, cls);
5876 }
5877 status = 1;
5878 }
5879 else {
5880 gCling->Error("TCling::AutoLoad",
5881 "failure loading library %s for %s", lib, cls);
5882 }
5883 }
5884 delete tokens;
5885 }
5886
5887 return status;
5888}
5889
5890////////////////////////////////////////////////////////////////////////////////
5891// Iterate through the data member of the class (either through the TProtoClass
5892// or through Cling) and trigger, recursively, the loading the necessary libraries.
5894{
5895 Int_t status = ShallowAutoLoadImpl(cls);
5896 if (status) {
5897
5898 // This routine should be called only from AutoLoad which has already
5899 // taken the main ROOT lock so this should not have any race condition.
5900 // If the lock is removed from AutoLoad, a spin lock should be introduced here.
5901 // Note that it is actually alright if another thread is populating this
5902 // set since we can then exclude both the infinite recursion (the main goal)
5903 // and duplicate work.
5904 static std::set<std::string> gClassOnStack;
5905 auto insertResult = gClassOnStack.insert(std::string(cls));
5906 if (insertResult.second) {
5907 // Now look through the TProtoClass to load the required library/dictionary
5909 if (proto) {
5910 for(auto element : proto->GetData()) {
5911 const char *subtypename = element->GetTypeName();
5912 if (!element->IsBasic() && !TClassTable::GetDictNorm(subtypename)) {
5913 // Failure to load a dictionary is not (quite) a failure load
5914 // the top-level library. If we return false here, then
5915 // we would end up in a situation where the library and thus
5916 // the dictionary is loaded for "cls" but the TClass is
5917 // not created and/or marked as unavailable (in case where
5918 // AutoLoad is called from TClass::GetClass).
5919 (void) DeepAutoLoadImpl(subtypename);
5920 }
5921 }
5922 } else {
5923 auto classinfo = gInterpreter->ClassInfo_Factory(cls);
5924 if (classinfo && gInterpreter->ClassInfo_IsValid(classinfo)
5925 && !(gInterpreter->ClassInfo_Property(classinfo) & kIsEnum))
5926 {
5927 DataMemberInfo_t *memberinfo = gInterpreter->DataMemberInfo_Factory(classinfo);
5928 while (gInterpreter->DataMemberInfo_Next(memberinfo)) {
5929 auto membertypename = TClassEdit::GetLong64_Name(gInterpreter->TypeName(gInterpreter->DataMemberInfo_TypeTrueName(memberinfo)));
5930 if (!(gInterpreter->DataMemberInfo_TypeProperty(memberinfo) & ::kIsFundamental)
5931 && !TClassTable::GetDictNorm(membertypename.c_str()))
5932 {
5933 // Failure to load a dictionary is not (quite) a failure load
5934 // the top-level library. See detailed comment in the TProtoClass
5935 // branch (above).
5936 (void)DeepAutoLoadImpl(membertypename.c_str());
5937 }
5938 }
5939 gInterpreter->DataMemberInfo_Delete(memberinfo);
5940 }
5941 gInterpreter->ClassInfo_Delete(classinfo);
5942 }
5943 // Because they could have been failures, allow for another try later
5944 gClassOnStack.erase(insertResult.first);
5945 }
5946 }
5947 return status;
5948}
5949
5950////////////////////////////////////////////////////////////////////////////////
5951/// Load library containing the specified class. Returns 0 in case of error
5952/// and 1 in case if success.
5953
5954Int_t TCling::AutoLoad(const char *cls, Bool_t knowDictNotLoaded /* = kFALSE */)
5955{
5956 // TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
5957 // rootcling (in *_rdict.pcm file generation) it is a no op.
5958 // FIXME: We should avoid calling autoload when we know we are not supposed
5959 // to and transform this check into an assert.
5961 // Never load any library from rootcling/genreflex.
5962 if (gDebug > 2) {
5963 Info("TCling::AutoLoad", "Explicitly disabled (the class name is %s)", cls);
5964 }
5965 return 0;
5966 }
5967
5968 assert(IsClassAutoloadingEnabled() && "Calling when autoloading is off!");
5969
5971
5972 if (!knowDictNotLoaded && gClassTable->GetDictNorm(cls)) {
5973 // The library is already loaded as the class's dictionary is known.
5974 // Return success.
5975 // Note: the name (cls) is expected to be normalized as it comes either
5976 // from a callbacks (that can/should calculate the normalized name from the
5977 // decl) or from TClass::GetClass (which does also calculate the normalized
5978 // name).
5979 return 1;
5980 }
5981
5982 if (gDebug > 2) {
5983 Info("TCling::AutoLoad",
5984 "Trying to autoload for %s", cls);
5985 }
5986
5987 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
5988 if (gDebug > 2) {
5989 Info("TCling::AutoLoad",
5990 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
5991 }
5992 return 0;
5993 }
5994 // Prevent the recursion when the library dictionary are loaded.
5995 SuspendAutoloadingRAII autoLoadOff(this);
5996 // Try using externally provided callback first.
5997 if (fAutoLoadCallBack) {
5998 int success = (*(AutoLoadCallBack_t)fAutoLoadCallBack)(cls);
5999 if (success)
6000 return success;
6001 }
6002
6003 // During the 'Deep' part of the search we will call GetClassSharedLibsForModule
6004 // (when module are enabled) which might end up calling AutoParsing but
6005 // that should only be for the cases where the library has no generated pcm
6006 // and in that case a rootmap should be available.
6007 // This avoids a very costly operation (for generally no gain) but reduce the
6008 // quality of the search (i.e. bad in case of library with no pcm and no rootmap
6009 // file).
6010 TInterpreter::SuspendAutoParsing autoParseRaii(this);
6011 return DeepAutoLoadImpl(cls);
6012}
6013
6014////////////////////////////////////////////////////////////////////////////////
6015/// Parse the payload or header.
6016
6017static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
6018 Bool_t header,
6019 cling::Interpreter *interpreter)
6020{
6021 std::string code = gNonInterpreterClassDef ;
6022 if (!header) {
6023 // This is the complete header file content and not the
6024 // name of a header.
6025 code += what;
6026
6027 } else {
6028 code += ("#include \"");
6029 code += what;
6030 code += "\"\n";
6031 }
6032 code += ("#ifdef __ROOTCLING__\n"
6033 "#undef __ROOTCLING__\n"
6034 + gInterpreterClassDef +
6035 "#endif");
6036
6037 cling::Interpreter::CompilationResult cr;
6038 {
6039 // scope within which diagnostics are de-activated
6040 // For now we disable diagnostics because we saw them already at
6041 // dictionary generation time. That won't be an issue with the PCMs.
6042
6043 Sema &SemaR = interpreter->getSema();
6044 ROOT::Internal::ParsingStateRAII parsingStateRAII(interpreter->getParser(), SemaR);
6045 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
6046
6047 #if defined(R__MUST_REVISIT)
6048 #if R__MUST_REVISIT(6,2)
6049 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
6050 #endif
6051 #endif
6052
6053 cr = interpreter->parseForModule(code);
6054 }
6055 return cr;
6056}
6057
6058////////////////////////////////////////////////////////////////////////////////
6059/// Helper routine for TCling::AutoParse implementing the actual call to the
6060/// parser and looping over template parameters (if
6061/// any) and when they don't have a registered header to autoparse,
6062/// recurse over their template parameters.
6063///
6064/// Returns the number of header parsed.
6065
6066UInt_t TCling::AutoParseImplRecurse(const char *cls, bool topLevel)
6067{
6068 // We assume the lock has already been taken.
6069 // R__LOCKGUARD(gInterpreterMutex);
6070
6071 Int_t nHheadersParsed = 0;
6072 unsigned long offset = 0;
6073 if (strncmp(cls, "const ", 6) == 0) {
6074 offset = 6;
6075 }
6076
6077 // Loop on the possible autoparse keys
6078 bool skipFirstEntry = false;
6079 std::vector<std::string> autoparseKeys;
6080 if (strchr(cls, '<')) {
6081 int nestedLoc = 0;
6082 TClassEdit::GetSplit(cls + offset, autoparseKeys, nestedLoc, TClassEdit::kDropTrailStar);
6083 // Check if we can skip the name of the template in the autoparses
6084 // Take all the scopes one by one. If all of them are in the AST, we do not
6085 // need to autoparse for that particular template.
6086 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
6087 // autoparseKeys[0] is empty when the input is not a template instance.
6088 // The case strchr(cls, '<') != 0 but still not a template instance can
6089 // happens 'just' for string (GetSplit replaces the template by the short name
6090 // and then use that for thew splitting)
6091 TString templateName(autoparseKeys[0]);
6092 auto tokens = templateName.Tokenize("::");
6093 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
6094 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
6095 if (TClassEdit::IsStdClass(cls + offset))
6096 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
6097 auto nTokens = tokens->GetEntries();
6098 for (Int_t tk = 0; tk < nTokens; ++tk) {
6099 auto scopeObj = tokens->UncheckedAt(tk);
6100 auto scopeName = ((TObjString*) scopeObj)->String().Data();
6101 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
6102 // Check if we have multiple nodes in the AST with this name
6103 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
6104 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
6105 if (!previousScopeAsContext) break; // this is not a context
6106 }
6107 delete tokens;
6108 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
6109 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
6110 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
6111 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
6112 skipFirstEntry = templatedDecl->hasDefinition();
6113 }
6114 }
6115 }
6116
6117 }
6118 }
6119 if (topLevel) autoparseKeys.emplace_back(cls);
6120
6121 for (const auto & apKeyStr : autoparseKeys) {
6122 if (skipFirstEntry) {
6123 skipFirstEntry=false;
6124 continue;
6125 }
6126 if (apKeyStr.empty()) continue;
6127 const char *apKey = apKeyStr.c_str();
6128 std::size_t normNameHash(fStringHashFunction(apKey));
6129 // If the class was not looked up
6130 if (gDebug > 1) {
6131 Info("TCling::AutoParse",
6132 "Starting autoparse for %s\n", apKey);
6133 }
6134 if (fLookedUpClasses.insert(normNameHash).second) {
6135 auto const &iter = fClassesHeadersMap.find(normNameHash);
6136 if (iter != fClassesHeadersMap.end()) {
6137 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
6138 fTransactionHeadersMap.insert({T,normNameHash});
6139 auto const &hNamesPtrs = iter->second;
6140 if (gDebug > 1) {
6141 Info("TCling::AutoParse",
6142 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
6143 }
6144 for (auto & hName : hNamesPtrs) {
6145 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
6146 if (0 != fPayloads.count(normNameHash)) {
6147 float initRSSval=0.f, initVSIZEval=0.f;
6148 (void) initRSSval; // Avoid unused var warning
6149 (void) initVSIZEval;
6150 if (gDebug > 0) {
6151 Info("AutoParse",
6152 "Parsing full payload for %s", apKey);
6153 ProcInfo_t info;
6154 gSystem->GetProcInfo(&info);
6155 initRSSval = 1e-3*info.fMemResident;
6156 initVSIZEval = 1e-3*info.fMemVirtual;
6157 }
6158 auto cRes = ExecAutoParse(hName, kFALSE, GetInterpreterImpl());
6159 if (cRes != cling::Interpreter::kSuccess) {
6160 if (hName[0] == '\n')
6161 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
6162 } else {
6163 fParsedPayloadsAddresses.insert(hName);
6164 nHheadersParsed++;
6165 if (gDebug > 0){
6166 ProcInfo_t info;
6167 gSystem->GetProcInfo(&info);
6168 float endRSSval = 1e-3*info.fMemResident;
6169 float endVSIZEval = 1e-3*info.fMemVirtual;
6170 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6171 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6172 }
6173 }
6174 } else if (!IsLoaded(hName)) {
6175 if (gDebug > 0) {
6176 Info("AutoParse",
6177 "Parsing single header %s", hName);
6178 }
6179 auto cRes = ExecAutoParse(hName, kTRUE, GetInterpreterImpl());
6180 if (cRes != cling::Interpreter::kSuccess) {
6181 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
6182 } else {
6183 nHheadersParsed++;
6184 }
6185 }
6186 }
6187 }
6188 else {
6189 // There is no header registered for this class, if this a
6190 // template, it will be instantiated if/when it is requested
6191 // and if we do no load/parse its components we might end up
6192 // not using an eventual specialization.
6193 if (strchr(apKey, '<')) {
6194 nHheadersParsed += AutoParseImplRecurse(apKey, false);
6195 }
6196 }
6197 }
6198 }
6199
6200 return nHheadersParsed;
6201
6202}
6203
6204////////////////////////////////////////////////////////////////////////////////
6205/// Parse the headers relative to the class
6206/// Returns 1 in case of success, 0 in case of failure
6207
6208Int_t TCling::AutoParse(const char *cls)
6209{
6210 if (llvm::StringRef(cls).contains("(lambda)"))
6211 return 0;
6212
6215 return AutoLoad(cls);
6216 } else {
6217 return 0;
6218 }
6219 }
6220
6222
6223 if (gDebug > 1) {
6224 Info("TCling::AutoParse",
6225 "Trying to autoparse for %s", cls);
6226 }
6227
6228 // The catalogue of headers is in the dictionary
6230 && !gClassTable->GetDictNorm(cls)) {
6231 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
6232 ROOT::Internal::ParsingStateRAII parsingStateRAII(fInterpreter->getParser(),
6233 fInterpreter->getSema());
6234 AutoLoad(cls, true /*knowDictNotLoaded*/);
6235 }
6236
6237 // Prevent the recursion when the library dictionary are loaded.
6238 SuspendAutoloadingRAII autoLoadOff(this);
6239
6240 // No recursive header parsing on demand; we require headers to be standalone.
6241 SuspendAutoParsing autoParseRAII(this);
6242
6243 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
6244
6246
6247 return nHheadersParsed > 0 ? 1 : 0;
6248}
6249
6250// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6251// Try to solve the problem by autoloading. Return true when autoloading success, return
6252// false if not.
6253bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6254{
6255 StringRef errMsg(errmessage);
6256 if (errMsg.contains("undefined symbol: ")) {
6257 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6258 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6259 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6260 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6261 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6262 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6263 return true;
6264 } else {
6265 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6266 if ( ((TCling*)gCling)->LazyFunctionCreatorAutoload(errmessage))
6267 return true;
6268 }
6269
6270 return false;
6271}
6272
6273// This is a GNU implementation of hash used in bloom filter!
6274static uint32_t GNUHash(StringRef S) {
6275 uint32_t H = 5381;
6276 for (uint8_t C : S)
6277 H = (H << 5) + H + C;
6278 return H;
6279}
6280
6281static StringRef GetGnuHashSection(llvm::object::ObjectFile *file) {
6282 for (auto S : file->sections()) {
6283 StringRef name;
6284 S.getName(name);
6285 if (name == ".gnu.hash") {
6286 StringRef content;
6287 S.getContents(content);
6288 return content;
6289 }
6290 }
6291 return "";
6292}
6293
6294/// Bloom filter in a stohastic data structure which can tell us if a symbol
6295/// name does not exist in a library with 100% certainty. If it tells us it exists
6296/// this may not be true: https://blogs.oracle.com/solaris/gnu-hash-elf-sections-v2
6297///
6298/// ELF has this optimization in the new linkers by default, It is stored in the
6299/// gnu.hash section of the object file.
6300///
6301///\returns true true if the symbol may be in the library.
6302static bool MayExistInObjectFile(llvm::object::ObjectFile *soFile, uint32_t hash) {
6303 if (!soFile->isELF())
6304 return true;
6305
6306 // LLVM9: soFile->makeTriple().is64Bit()
6307 const int bits = 8 * soFile->getBytesInAddress();
6308
6309 StringRef contents = GetGnuHashSection(soFile);
6310 if (contents.size() < 16)
6311 // We need to search if the library doesn't have .gnu.hash section!
6312 return true;
6313 const char* hashContent = contents.data();
6314
6315 // See https://flapenguin.me/2017/05/10/elf-lookup-dt-gnu-hash/ for .gnu.hash table layout.
6316 uint32_t maskWords = *reinterpret_cast<const uint32_t *>(hashContent + 8);
6317 uint32_t shift2 = *reinterpret_cast<const uint32_t *>(hashContent + 12);
6318 uint32_t hash2 = hash >> shift2;
6319 uint32_t n = (hash / bits) % maskWords;
6320
6321 const char *bloomfilter = hashContent + 16;
6322 const char *hash_pos = bloomfilter + n*(bits/8); // * (Bits / 8)
6323 uint64_t word = *reinterpret_cast<const uint64_t *>(hash_pos);
6324 uint64_t bitmask = ( (1ULL << (hash % bits)) | (1ULL << (hash2 % bits)));
6325 return (bitmask & word) == bitmask;
6326}
6327
6328/// Looks up symbols from a an object file, representing the library.
6329///\returns true on success.
6330static bool FindSymbol(const std::string &library_filename,
6331 const std::string &mangled_name, unsigned IgnoreSymbolFlags = 0)
6332{
6333 auto ObjF = llvm::object::ObjectFile::createObjectFile(ROOT::TMetaUtils::GetRealPath(library_filename));
6334 if (!ObjF) {
6335 if (gDebug > 1)
6336 Warning("TCling__FindSymbol", "Failed to read object file %s", library_filename.c_str());
6337 return false;
6338 }
6339
6340 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
6341
6342 uint32_t hashedMangle = GNUHash(mangled_name);
6343 // If the symbol does not exist, exit early. In case it may exist, iterate.
6344 if (!MayExistInObjectFile(BinObjFile, hashedMangle))
6345 return false;
6346
6347 for (const auto &S : BinObjFile->symbols()) {
6348 uint32_t Flags = S.getFlags();
6349 // Do not insert in the table symbols flagged to ignore.
6350 if (Flags & IgnoreSymbolFlags)
6351 continue;
6352
6353 // Note, we are at last resort and loading library based on a weak
6354 // symbol is allowed. Otherwise, the JIT will issue an unresolved
6355 // symbol error.
6356 //
6357 // There are other weak symbol kinds (marked as 'V') to denote
6358 // typeinfo and vtables. It is unclear whether we should load such
6359 // libraries or from which library we should resolve the symbol.
6360 // We seem to not have a way to differentiate it from the symbol API.
6361
6362 llvm::Expected<StringRef> SymNameErr = S.getName();
6363 if (!SymNameErr) {
6364 Warning("TCling__FindSymbol", "Failed to read symbol %s", mangled_name.c_str());
6365 continue;
6366 }
6367
6368 if (SymNameErr.get() == mangled_name) {
6369 if (gDebug > 1)
6370 Info("TCling__FindSymbol", "Symbol %s found in %s\n",
6371 mangled_name.c_str(), library_filename.c_str());
6372 return true;
6373 }
6374 }
6375
6376 if (!BinObjFile->isELF())
6377 return false;
6378
6379 // ELF file format has .dynstr section for the dynamic symbol table.
6380 const auto *ElfObj = cast<llvm::object::ELFObjectFileBase>(BinObjFile);
6381
6382 for (const auto &S : ElfObj->getDynamicSymbolIterators()) {
6383 uint32_t Flags = S.getFlags();
6384 // DO NOT insert to table if symbol was undefined
6385 if (Flags & llvm::object::SymbolRef::SF_Undefined)
6386 continue;
6387
6388 // Note, we are at last resort and loading library based on a weak
6389 // symbol is allowed. Otherwise, the JIT will issue an unresolved
6390 // symbol error.
6391 //
6392 // There are other weak symbol kinds (marked as 'V') to denote
6393 // typeinfo and vtables. It is unclear whether we should load such
6394 // libraries or from which library we should resolve the symbol.
6395 // We seem to not have a way to differentiate it from the symbol API.
6396
6397 llvm::Expected<StringRef> SymNameErr = S.getName();
6398 if (!SymNameErr) {
6399 Warning("TCling__FindSymbol", "Failed to read symbol %s", mangled_name.c_str());
6400 continue;
6401 }
6402
6403 if (SymNameErr.get() == mangled_name)
6404 return true;
6405 }
6406
6407 return false;
6408}
6409
6410static std::string ResolveSymbol(const std::string& mangled_name,
6411 cling::Interpreter *interp,
6412 bool searchSystem = true) {
6413 assert(!mangled_name.empty());
6414 using namespace llvm::sys::path;
6415 using namespace llvm::sys::fs;
6416
6418
6419 static bool sFirstRun = true;
6420 static bool sFirstSystemLibrary = true;
6421 // LibraryPath contains a pair offset to the canonical dirname (stored as
6422 // sPaths[i]) and a filename. For example, `/home/foo/root/lib/libTMVA.so`,
6423 // the .first will contain an index in sPaths where `/home/foo/root/lib/`
6424 // will be stored and .second `libTMVA.so`.
6425 // This approach reduces the duplicate paths as at one location there may be
6426 // plenty of libraries.
6427 using LibraryPath = std::pair<uint32_t, std::string>;
6428 using LibraryPaths = std::vector<LibraryPath>;
6429 using BasePaths = std::vector<std::string>;
6430 static LibraryPaths sLibraries;
6431 static BasePaths sPaths;
6432 static LibraryPaths sQueriedLibraries;
6433
6434 // For system header autoloading
6435 static LibraryPaths sSysLibraries;
6436
6437 if (sFirstRun) {
6438 TCling__FindLoadedLibraries(sLibraries, sPaths, *interp, /* searchSystem */ false);
6439 sFirstRun = false;
6440 }
6441
6442 auto GetLibFileName = [](const LibraryPath &P, const BasePaths &BaseP) {
6443 llvm::SmallString<512> Vec(BaseP[P.first]);
6444 llvm::sys::path::append(Vec, StringRef(P.second));
6445 return Vec.str().str();
6446 };
6447
6448 if (!sQueriedLibraries.empty()) {
6449 // Last call we were asked if a library contains a symbol. Usually, the
6450 // caller wants to load this library. Check if was loaded and remove it
6451 // from our lists of not-yet-loaded libs.
6452 for (const LibraryPath &P : sQueriedLibraries) {
6453 const std::string LibName = GetLibFileName(P, sPaths);
6454 if (!gCling->IsLibraryLoaded(LibName.c_str()))
6455 continue;
6456
6457 sLibraries.erase(std::remove(sLibraries.begin(), sLibraries.end(), P), sLibraries.end());
6458 if (!sSysLibraries.empty())
6459 sSysLibraries.erase(std::remove(sSysLibraries.begin(), sSysLibraries.end(), P), sSysLibraries.end());
6460 }
6461 }
6462
6463 if (sFirstRun) {
6464 TCling__FindLoadedLibraries(sLibraries, sPaths, *interp, /* searchSystem */ false);
6465 sFirstRun = false;
6466 }
6467
6468 // Iterate over files under this path. We want to get each ".so" files
6469 for (const LibraryPath &P : sLibraries) {
6470 const std::string LibName = GetLibFileName(P, sPaths);
6471
6472 // FIXME: We should also iterate over the dynamic symbols for ROOT
6473 // libraries. However, it seems to be redundant for the moment as we do
6474 // not strictly require symbols from those sections. Enable after checking
6475 // performance!
6476 if (FindSymbol(LibName, mangled_name, /*ignore*/
6477 llvm::object::SymbolRef::SF_Undefined |
6478 llvm::object::SymbolRef::SF_Weak)) {
6479 sQueriedLibraries.push_back(P);
6480 return LibName;
6481 }
6482 }
6483
6484 if (!searchSystem)
6485 return "";
6486
6487 // Lookup in non-system libraries failed. Expand the search to the system.
6488 if (sFirstSystemLibrary) {
6489 TCling__FindLoadedLibraries(sSysLibraries, sPaths, *interp, /* searchSystem */ true);
6490 sFirstSystemLibrary = false;
6491 }
6492
6493 for (const LibraryPath &P : sSysLibraries) {
6494 const std::string LibName = GetLibFileName(P, sPaths);
6495
6496 if (FindSymbol(LibName, mangled_name, /*ignore*/
6497 llvm::object::SymbolRef::SF_Undefined |
6498 llvm::object::SymbolRef::SF_Weak)) {
6499 sQueriedLibraries.push_back(P);
6500 return LibName;
6501 }
6502 }
6503
6504 return ""; // Search found no match.
6505}
6506
6507static void* LazyFunctionCreatorAutoloadForModule(const std::string &mangled_name,
6508 cling::Interpreter *interp) {
6509// The JIT gives us a mangled name which has only one leading underscore on
6510// all platforms, for instance _ZN8TRandom34RndmEv. However, on OSX the
6511// linker stores this symbol as __ZN8TRandom34RndmEv (adding an extra _).
6512 std::string maybe_prefixed_mangled_name = mangled_name;
6513#ifdef R__MACOSX
6514 assert(!llvm::StringRef(mangled_name).startswith("__") && "Already added!");
6515 maybe_prefixed_mangled_name = "_" + maybe_prefixed_mangled_name;
6516#endif
6517
6518 std::string LibName = ResolveSymbol(maybe_prefixed_mangled_name, interp);
6519 if (LibName.empty())
6520 return nullptr;
6521
6522 if (gSystem->Load(LibName.c_str(), "", false) < 0)
6523 Error("TCling__LazyFunctionCreatorAutoloadForModule",
6524 "Failed to load library %s", LibName.c_str());
6525
6526 void* addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(mangled_name.c_str());
6527 return addr;
6528}
6529
6530////////////////////////////////////////////////////////////////////////////////
6531/// Autoload a library based on a missing symbol.
6532
6533void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {
6536
6537 // First see whether the symbol is in the library that we are currently
6538 // loading. It will have access to the symbols of its dependent libraries,
6539 // thus checking "back()" is sufficient.
6540 if (!fRegisterModuleDyLibs.empty()) {
6541 if (void* addr = dlsym(fRegisterModuleDyLibs.back(),
6542 mangled_name.c_str())) {
6543 return addr;
6544 }
6545 }
6546
6547 int err = 0;
6548 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.c_str(), err);
6549 if (err) {
6550 return 0;
6551 }
6552
6553 std::string name(demangled_name_c);
6554 free(demangled_name_c);
6555
6556 //fprintf(stderr, "demangled name: '%s'\n", demangled_name);
6557 //
6558 // Separate out the class or namespace part of the
6559 // function name.
6560 //
6561
6562 std::string::size_type pos = name.find("__thiscall ");
6563 if (pos != std::string::npos) {
6564 name.erase(0, pos + sizeof("__thiscall ")-1);
6565 }
6566 pos = name.find("__cdecl ");
6567 if (pos != std::string::npos) {
6568 name.erase(0, pos + sizeof("__cdecl ")-1);
6569 }
6570 if (!strncmp(name.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
6571 name.erase(0, sizeof("typeinfo for ")-1);
6572 } else if (!strncmp(name.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
6573 name.erase(0, sizeof("vtable for ")-1);
6574 } else if (!strncmp(name.c_str(), "operator", sizeof("operator")-1)
6575 && !isalnum(name[sizeof("operator")])) {
6576 // operator...(A, B) - let's try with A!
6577 name.erase(0, sizeof("operator")-1);
6578 pos = name.rfind('(');
6579 if (pos != std::string::npos) {
6580 name.erase(0, pos + 1);
6581 pos = name.find(",");
6582 if (pos != std::string::npos) {
6583 // remove next arg up to end, leaving only the first argument type.
6584 name.erase(pos);
6585 }
6586 pos = name.rfind(" const");
6587 if (pos != std::string::npos) {
6588 name.erase(pos, strlen(" const"));
6589 }
6590 while (!name.empty() && strchr("&*", name.back()))
6591 name.erase(name.length() - 1);
6592 }
6593 } else {
6596 name = fsi.fScopeName;
6597 }
6598 //fprintf(stderr, "name: '%s'\n", name.c_str());
6599 // Now we have the class or namespace name, so do the lookup.
6600 TString libs = GetClassSharedLibs(name.c_str());
6601 if (libs.IsNull()) {
6602 // Not found in the map, all done.
6603 return 0;
6604 }
6605 //fprintf(stderr, "library: %s\n", iter->second.c_str());
6606 // Now we have the name of the libraries to load, so load them.
6607
6608 TString lib;
6609 Ssiz_t posLib = 0;
6610 while (libs.Tokenize(lib, posLib)) {
6611 if (gSystem->Load(lib, "", kFALSE /*system*/) < 0) {
6612 // The library load failed, all done.
6613 //fprintf(stderr, "load failed: %s\n", errmsg.c_str());
6614 return 0;
6615 }
6616 }
6617
6618 //fprintf(stderr, "load succeeded.\n");
6619 // Get the address of the function being called.
6620 void* addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(mangled_name.c_str());
6621 //fprintf(stderr, "addr: %016lx\n", reinterpret_cast<unsigned long>(addr));
6622 return addr;
6623}
6624
6625////////////////////////////////////////////////////////////////////////////////
6626
6627Bool_t TCling::IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
6628{
6629 return fNSFromRootmaps.count(nsDecl) != 0;
6630}
6631
6632////////////////////////////////////////////////////////////////////////////////
6633/// Internal function. Actually do the update of the ClassInfo when seeing
6634// new TagDecl or NamespaceDecl.
6635void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6636{
6637
6639 if (cci) {
6640 // If we only had a forward declaration then update the
6641 // TClingClassInfo with the definition if we have it now.
6642 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6643 if (!oldDef || (def && def != oldDef)) {
6644 cl->ResetCaches();
6646 if (def) {
6647 // It's a tag decl, not a namespace decl.
6648 cci->Init(*cci->GetType());
6650 }
6651 }
6652 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6653 cl->ResetCaches();
6654 // yes, this is almost a waste of time, but we do need to lookup
6655 // the 'type' corresponding to the TClass anyway in order to
6656 // preserve the opaque typedefs (Double32_t)
6657 if (!alias && def != nullptr)
6658 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), def);
6659 else
6660 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), cl->GetName());
6661 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6662 // We now need to update the state and bits.
6663 if (cl->fState != TClass::kHasTClassInit) {
6664 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6667 }
6668 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6669 } else {
6670 delete ((TClingClassInfo *)cl->fClassInfo);
6671 cl->fClassInfo = nullptr;
6672 }
6673 }
6674}
6675
6676////////////////////////////////////////////////////////////////////////////////
6677/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6678void TCling::UpdateClassInfoWithDecl(const NamedDecl* ND)
6679{
6680 const TagDecl *td = dyn_cast<TagDecl>(ND);
6681 const NamespaceDecl *ns = dyn_cast<NamespaceDecl>(ND);
6682 const NamedDecl *canon = nullptr;
6683
6684 std::string name;
6685 TagDecl* tdDef = 0;
6686 if (td) {
6687 canon = tdDef = td->getDefinition();
6688 // Let's pass the decl to the TClass only if it has a definition.
6689 if (!tdDef) return;
6690
6691 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6692 // Ignore incomplete definition.
6693 // Ignore declaration within a function.
6694 return;
6695 }
6696
6697 auto declName = tdDef->getNameAsString();
6698 // Check if we have registered the unqualified name into the list
6699 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6700 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6701 // the unqualified name is sufficient (and the fully qualified name might be
6702 // 'wrong' if there is difference in spelling in the template paramters (for example)
6703 if (!TClass::HasNoInfoOrEmuOrFwdDeclaredDecl(declName.c_str())){
6704 // fprintf (stderr,"WARNING: Impossible to find a TClassEntry in kNoInfo or kEmulated the decl of which would be called %s. Skip w/o building the normalized name.\n",declName.c_str() );
6705 return;
6706 }
6707
6708 clang::QualType type(tdDef->getTypeForDecl(), 0);
6710 } else if (ns) {
6711 canon = ns->getCanonicalDecl();
6712 name = ND->getQualifiedNameAsString();
6713 } else {
6714 name = ND->getQualifiedNameAsString();
6715 }
6716
6717 // Supposedly we are being called while something is being
6718 // loaded ... let's now tell the autoloader to do the work
6719 // yet another time.
6720 SuspendAutoloadingRAII autoLoadOff(this);
6721 // FIXME: There can be more than one TClass for a single decl.
6722 // for example vector<double> and vector<Double32_t>
6723 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6724 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6725 RefreshClassInfo(cl, canon, false);
6726 }
6727 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6728 // and update them too:
6729 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6730 // RefreshClassInfo(cl, tdDef, true);
6731}
6732
6733////////////////////////////////////////////////////////////////////////////////
6734/// No op: see TClingCallbacks
6735
6736void TCling::UpdateClassInfo(char* item, Long_t tagnum)
6737{
6738}
6739
6740//______________________________________________________________________________
6741//FIXME: Factor out that function in TClass, because TClass does it already twice
6742void TCling::UpdateClassInfoWork(const char* item)
6743{
6744 // This is a no-op as part of the API.
6745 // TCling uses UpdateClassInfoWithDecl() instead.
6746}
6747
6748////////////////////////////////////////////////////////////////////////////////
6749/// Update all canvases at end the terminal input command.
6750
6752{
6753 TIter next(gROOT->GetListOfCanvases());
6754 TVirtualPad* canvas;
6755 while ((canvas = (TVirtualPad*)next())) {
6756 canvas->Update();
6757 }
6758}
6759
6760////////////////////////////////////////////////////////////////////////////////
6761
6762void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6763 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6764
6765 // If the transaction does not contain anything we can return earlier.
6766 if (!HandleNewTransaction(T)) return;
6767
6768 bool isTUTransaction = false;
6769 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
6770 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
6771 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
6772 // The is the first transaction, we have to expose to meta
6773 // what's already in the AST.
6774 isTUTransaction = true;
6775 }
6776 }
6777
6778 std::set<const void*> TransactionDeclSet;
6779 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
6780 const clang::Decl* WrapperFD = T.getWrapperFD();
6781 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6782 I != E; ++I) {
6783 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
6784 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
6785 continue;
6786
6787 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6788 DE = I->m_DGR.end(); DI != DE; ++DI) {
6789 if (*DI == WrapperFD)
6790 continue;
6791 TransactionDeclSet.insert(*DI);
6792 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
6793 }
6794 }
6795 }
6796
6797 // The above might trigger more decls to be deserialized.
6798 // Thus the iteration over the deserialized decls must be last.
6799 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
6800 E = T.deserialized_decls_end(); I != E; ++I) {
6801 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6802 DE = I->m_DGR.end(); DI != DE; ++DI)
6803 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
6804 //FIXME: HandleNewDecl should take DeclGroupRef
6805 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
6806 modifiedTClasses);
6807 }
6808 }
6809
6810
6811 // When fully building the reflection info in TClass, a deserialization
6812 // could be triggered, which may result in request for building the
6813 // reflection info for the same TClass. This in turn will clear the caches
6814 // for the TClass in-flight and cause null ptr derefs.
6815 // FIXME: This is a quick fix, solving most of the issues. The actual
6816 // question is: Shouldn't TClass provide a lock mechanism on update or lock
6817 // itself until the update is done.
6818 //
6819 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
6820 std::vector<TClass*>::iterator it;
6821 it = set_difference(modifiedTClasses.begin(), modifiedTClasses.end(),
6822 ((TCling*)gCling)->GetModTClasses().begin(),
6823 ((TCling*)gCling)->GetModTClasses().end(),
6824 modifiedTClassesDiff.begin());
6825 modifiedTClassesDiff.resize(it - modifiedTClassesDiff.begin());
6826
6827 // Lock the TClass for updates
6828 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
6829 modifiedTClassesDiff.end());
6830 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
6831 E = modifiedTClassesDiff.end(); I != E; ++I) {
6832 // Make sure the TClass has not been deleted.
6833 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
6834 continue;
6835 }
6836 // Could trigger deserialization of decls.
6837 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
6838 // Unlock the TClass for updates
6839 ((TCling*)gCling)->GetModTClasses().erase(*I);
6840
6841 }
6842}
6843
6844///\brief Invalidate stored TCling state for declarations included in transaction `T'.
6845///
6846void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
6847{
6849
6850 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6851 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6852 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6853 (TListOfEnums *)gROOT->GetListOfEnums());
6854
6855 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
6856 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6857 I != E; ++I) {
6858 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
6859 continue;
6860 if (I->m_Call == cling::Transaction::kCCINone) {
6861 UpdateListsOnUnloaded(*(*iNested));
6862 ++iNested;
6863 continue;
6864 }
6865
6866 for (auto &D : I->m_DGR)
6867 InvalidateCachedDecl(Lists, D);
6868 }
6869}
6870
6871///\brief Invalidate cached TCling information for the given global declaration.
6872///
6873void TCling::InvalidateGlobal(const Decl *D) {
6874 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6875 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6876 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6877 (TListOfEnums *)gROOT->GetListOfEnums());
6878 InvalidateCachedDecl(Lists, D);
6879}
6880
6881///\brief Invalidate cached TCling information for the given declaration, and
6882/// removed it from the appropriate object list.
6883///\param[in] Lists - std::tuple<TListOfDataMembers&, TListOfFunctions&,
6884/// TListOfFunctionTemplates&, TListOfEnums&>
6885/// of pointers to the (global/class) object lists.
6886///\param[in] D - Decl to discard.
6887///
6891 TListOfEnums*> &Lists, const Decl *D) {
6892 if (D->isFromASTFile()) // `D' came from the PCH; ignore
6893 return;
6894
6895 TListOfDataMembers &LODM = *(std::get<0>(Lists));
6896 TListOfFunctions &LOF = *(std::get<1>(Lists));
6897 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
6898 TListOfEnums &LOE = *(std::get<3>(Lists));
6899
6900 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D)) {
6901 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
6902 if (LODM.GetClass())
6903 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
6904 else
6905 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
6906 } else if (isa<FunctionDecl>(D)) {
6908 } else if (isa<FunctionTemplateDecl>(D)) {
6910 } else if (isa<EnumDecl>(D)) {
6911 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
6912 if (!E)
6913 return;
6914
6915 // Try to invalidate enumerators (for unscoped enumerations).
6916 for (TIter I = E->GetConstants(); auto EC = (TEnumConstant *)I(); )
6918 (TEnumConstant *)LODM.FindObject(EC->GetName()));
6919
6921 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
6922 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->isCompleteDefinition())
6923 return;
6924
6925 std::vector<TClass *> Classes;
6926 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
6927 return;
6928 for (auto &C : Classes) {
6929 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
6930 (TListOfFunctions *)C->GetListOfMethods(),
6931 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
6932 (TListOfEnums *)C->GetListOfEnums());
6933 for (auto &I : cast<DeclContext>(D)->decls())
6934 InvalidateCachedDecl(Lists, I);
6935
6936 // For NamespaceDecl (redeclarable), only invalidate this redecl.
6937 if (D->getKind() != Decl::Namespace
6938 || cast<NamespaceDecl>(D)->isOriginalNamespace())
6939 C->ResetClassInfo();
6940 }
6941 }
6942}
6943
6944////////////////////////////////////////////////////////////////////////////////
6945// If an autoparse was done during a transaction and that it is rolled back,
6946// we need to make sure the next request for the same autoparse will be
6947// honored.
6948void TCling::TransactionRollback(const cling::Transaction &T) {
6949 auto const &triter = fTransactionHeadersMap.find(&T);
6950 if (triter != fTransactionHeadersMap.end()) {
6951 std::size_t normNameHash = triter->second;
6952
6953 fLookedUpClasses.erase(normNameHash);
6954
6955 auto const &iter = fClassesHeadersMap.find(normNameHash);
6956 if (iter != fClassesHeadersMap.end()) {
6957 auto const &hNamesPtrs = iter->second;
6958 for (auto &hName : hNamesPtrs) {
6959 if (gDebug > 0) {
6960 Info("TransactionRollback",
6961 "Restoring ability to autoaparse: %s", hName);
6962 }
6963 fParsedPayloadsAddresses.erase(hName);
6964 }
6965 }
6966 }
6967}
6968
6969////////////////////////////////////////////////////////////////////////////////
6970
6971void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
6972// UpdateListOfLoadedSharedLibraries();
6973}
6974
6975////////////////////////////////////////////////////////////////////////////////
6976
6977void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
6979 fSharedLibs = "";
6980}
6981
6982////////////////////////////////////////////////////////////////////////////////
6983/// Return the list of shared libraries loaded into the process.
6984
6986{
6988 return fSharedLibs;
6989}
6990
6991static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
6992{
6993 if (!cls || !*cls)
6994 return {};
6995
6996 using namespace clang;
6997 if (const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
6998 /*type*/ nullptr, /*instantiate*/ false)) {
6999 if (!D->isFromASTFile()) {
7000 if (gDebug > 5)
7001 Warning("GetClassSharedLibsForModule", "Decl found for %s is not part of a module", cls);
7002 return {};
7003 }
7004 class ModuleCollector : public ConstDeclVisitor<ModuleCollector> {
7005 llvm::DenseSet<Module *> &m_TopLevelModules;
7006
7007 public:
7008 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
7009 void Collect(const Decl *D) { Visit(D); }
7010
7011 void VisitDecl(const Decl *D)
7012 {
7013 // FIXME: Such case is described ROOT-7765 where
7014 // ROOT_GENERATE_DICTIONARY does not contain the list of headers.
7015 // They are specified as #includes in the LinkDef file. This leads to
7016 // generation of incomplete modulemap files and this logic fails to
7017 // compute the corresponding module of D.
7018 // FIXME: If we want to support such a case, we should not rely on
7019 // the contents of the modulemap but mangle D and look it up in the
7020 // .so files.
7021 if (!D->hasOwningModule())
7022 return;
7023 if (Module *M = D->getOwningModule()->getTopLevelModule())
7024 m_TopLevelModules.insert(M);
7025 }
7026
7027 void VisitTemplateArgument(const TemplateArgument &TA)
7028 {
7029 switch (TA.getKind()) {
7031 case TemplateArgument::Integral:
7032 case TemplateArgument::Pack:
7033 case TemplateArgument::NullPtr:
7034 case TemplateArgument::Expression:
7035 case TemplateArgument::Template:
7036 case TemplateArgument::TemplateExpansion: return;
7038 if (const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
7039 return Visit(TagTy->getDecl());
7040 return;
7041 case TemplateArgument::Declaration: return Visit(TA.getAsDecl());
7042 }
7043 llvm_unreachable("Invalid TemplateArgument::Kind!");
7044 }
7045
7046 void VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *CTSD)
7047 {
7048 if (CTSD->getOwningModule())
7049 VisitDecl(CTSD);
7050 else
7051 VisitDecl(CTSD->getSpecializedTemplate());
7052 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
7053 for (const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
7054 VisitTemplateArgument(*Arg);
7055 }
7056 }
7057 };
7058
7059 llvm::DenseSet<Module *> TopLevelModules;
7060 ModuleCollector m(TopLevelModules);
7061 m.Collect(D);
7062 std::string result;
7063 for (auto M : TopLevelModules) {
7064 // ROOT-unaware modules (i.e. not processed by rootcling) do not have a
7065 // link declaration.
7066 if (!M->LinkLibraries.size())
7067 continue;
7068 // We have preloaded the Core module thus libCore.so
7069 if (M->Name == "Core")
7070 continue;
7071 assert(M->LinkLibraries.size() == 1);
7072 if (!result.empty())
7073 result += ' ';
7074 result += M->LinkLibraries[0].Library;
7075 }
7076 return result;
7077 }
7078 return {};
7079}
7080
7081////////////////////////////////////////////////////////////////////////////////
7082/// Get the list of shared libraries containing the code for class cls.
7083/// The first library in the list is the one containing the class, the
7084/// others are the libraries the first one depends on. Returns 0
7085/// in case the library is not found.
7086
7087const char* TCling::GetClassSharedLibs(const char* cls)
7088{
7089 if (fCxxModulesEnabled) {
7090 llvm::StringRef className = cls;
7091 // If we get a class name containing lambda, we cannot parse it and we
7092 // can exit early.
7093 // FIXME: This works around a bug when we are instantiating a template
7094 // make_unique and the substitution fails. Seen in most of the dataframe
7095 // tests.
7096 if (className.contains("(lambda)"))
7097 return nullptr;
7098 // Limit the recursion which can be induced by GetClassSharedLibsForModule.
7099 SuspendAutoloadingRAII AutoloadingDisabled(this);
7100 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
7101 std::string libs = GetClassSharedLibsForModule(cls, LH);
7102 if (!libs.empty()) {
7103 fAutoLoadLibStorage.push_back(libs);
7104 return fAutoLoadLibStorage.back().c_str();
7105 }
7106 }
7107
7108 if (!cls || !*cls) {
7109 return 0;
7110 }
7111 // lookup class to find list of libraries
7112 if (fMapfile) {
7113 TEnvRec* libs_record = 0;
7114 libs_record = fMapfile->Lookup(cls);
7115 if (libs_record) {
7116 const char* libs = libs_record->GetValue();
7117 return (*libs) ? libs : 0;
7118 }
7119 else {
7120 // Try the old format...
7121 TString c = TString("Library.") + cls;
7122 // convert "::" to "@@", we used "@@" because TEnv
7123 // considers "::" a terminator
7124 c.ReplaceAll("::", "@@");
7125 // convert "-" to " ", since class names may have
7126 // blanks and TEnv considers a blank a terminator
7127 c.ReplaceAll(" ", "-");
7128 // Use TEnv::Lookup here as the rootmap file must start with Library.
7129 // and do not support using any stars (so we do not need to waste time
7130 // with the search made by TEnv::GetValue).
7131 TEnvRec* libs_record = 0;
7132 libs_record = fMapfile->Lookup(c);
7133 if (libs_record) {
7134 const char* libs = libs_record->GetValue();
7135 return (*libs) ? libs : 0;
7136 }
7137 }
7138 }
7139 return 0;
7140}
7141
7142/// This interface returns a list of dependent libraries in the form:
7143/// lib libA.so libB.so libC.so. The first library is the library we are
7144/// searching dependencies for.
7145/// Note: In order to speed up the search, we display the dependencies of the
7146/// libraries which are not yet loaded. For instance, if libB.so was already
7147/// loaded the list would contain: lib libA.so libC.so.
7148static std::string GetSharedLibImmediateDepsSlow(std::string lib,
7149 cling::Interpreter *interp,
7150 bool skipLoadedLibs = true)
7151{
7152 TString LibFullPath(lib);
7153 if (!llvm::sys::path::is_absolute(lib)) {
7154 if (!gSystem->FindDynamicLibrary(LibFullPath, /*quiet=*/true)) {
7155 Error("TCling__GetSharedLibImmediateDepsSlow", "Cannot find library '%s'", lib.c_str());
7156 return "";
7157 }
7158 } else {
7159 lib = llvm::sys::path::filename(lib);
7160 }
7161
7162 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
7163 if (!ObjF) {
7164 Warning("TCling__GetSharedLibImmediateDepsSlow", "Failed to read object file %s", lib.c_str());
7165 return "";
7166 }
7167
7168 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7169
7170 std::set<string> DedupSet;
7171 std::string Result = lib + ' ';
7172 for (const auto &S : BinObjFile->symbols()) {
7173 uint32_t Flags = S.getFlags();
7174 if (Flags & llvm::object::SymbolRef::SF_Undefined) {
7175 llvm::Expected<StringRef> SymNameErr = S.getName();
7176 if (!SymNameErr) {
7177 Warning("GetSharedLibDepsForModule", "Failed to read symbol");
7178 continue;
7179 }
7180 llvm::StringRef SymName = SymNameErr.get();
7181 if (SymName.empty())
7182 continue;
7183
7184 if (BinObjFile->isELF()) {
7185 // Skip the symbols which are part of the C/C++ runtime and have a
7186 // fixed library version. See binutils ld VERSION. Those reside in
7187 // 'system' libraries, which we avoid in ResolveSymbol.
7188 if (SymName.contains("@@GLIBCXX") || SymName.contains("@@CXXABI") ||
7189 SymName.contains("@@GLIBC") || SymName.contains("@@GCC"))
7190 continue;
7191
7192 // Those are 'weak undefined' symbols produced by gcc. We can
7193 // ignore them.
7194 // FIXME: It is unclear whether we can ignore all weak undefined
7195 // symbols:
7196 // http://lists.llvm.org/pipermail/llvm-dev/2017-October/118177.html
7197 if (SymName == "_Jv_RegisterClasses" ||
7198 SymName == "_ITM_deregisterTMCloneTable" ||
7199 SymName == "_ITM_registerTMCloneTable")
7200 continue;
7201 }
7202
7203 // If we can find the address of the symbol, we have loaded it. Skip.
7204 if (skipLoadedLibs && llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymName))
7205 continue;
7206
7207 std::string found = ResolveSymbol(SymName, interp, /*searchSystem*/false);
7208 // The expected output is just filename without the full path, which
7209 // is not very accurate, because our Dyld implementation might find
7210 // a match in location a/b/c.so and if we return just c.so ROOT might
7211 // resolve it to y/z/c.so and there we might not be ABI compatible.
7212 // FIXME: Teach the users of GetSharedLibDeps to work with full paths.
7213 if (!found.empty()) {
7214 std::string cand = llvm::sys::path::filename(found).str();
7215 if (!DedupSet.insert(cand).second)
7216 continue;
7217
7218 Result += cand + ' ';
7219 }
7220 }
7221 }
7222
7223 return Result;
7224}
7225
7226
7227////////////////////////////////////////////////////////////////////////////////
7228/// Get the list a libraries on which the specified lib depends. The
7229/// returned string contains as first element the lib itself.
7230/// Returns 0 in case the lib does not exist or does not have
7231/// any dependencies. If useDyld is true, we iterate through all available
7232/// libraries and try to construct the dependency chain by resolving each
7233/// symbol.
7234
7235const char* TCling::GetSharedLibDeps(const char* lib, bool useDyld/* = false*/)
7236{
7237 if (useDyld) {
7238 std::string libs = GetSharedLibImmediateDepsSlow(lib, GetInterpreterImpl());
7239 if (!libs.empty()) {
7240 fAutoLoadLibStorage.push_back(libs);
7241 return fAutoLoadLibStorage.back().c_str();
7242 }
7243 }
7244
7245 if (!fMapfile || !lib || !lib[0]) {
7246 return 0;
7247 }
7248 TString libname(lib);
7249 Ssiz_t idx = libname.Last('.');
7250 if (idx != kNPOS) {
7251 libname.Remove(idx);
7252 }
7253 TEnvRec* rec;
7254 TIter next(fMapfile->GetTable());
7255 size_t len = libname.Length();
7256 while ((rec = (TEnvRec*) next())) {
7257 const char* libs = rec->GetValue();
7258 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7259 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
7260 return libs;
7261 }
7262 }
7263 return 0;
7264}
7265
7266////////////////////////////////////////////////////////////////////////////////
7267/// If error messages are disabled, the interpreter should suppress its
7268/// failures and warning messages from stdout.
7269
7271{
7272#if defined(R__MUST_REVISIT)
7273#if R__MUST_REVISIT(6,2)
7274 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
7275#endif
7276#endif
7277 return kTRUE;
7278}
7279
7280////////////////////////////////////////////////////////////////////////////////
7281/// If error messages are disabled, the interpreter should suppress its
7282/// failures and warning messages from stdout. Return the previous state.
7283
7285{
7286#if defined(R__MUST_REVISIT)
7287#if R__MUST_REVISIT(6,2)
7288 Warning("SetErrorMessages", "Interface not available yet.");
7289#endif
7290#endif
7292}
7293
7294////////////////////////////////////////////////////////////////////////////////
7295/// Refresh the list of include paths known to the interpreter and return it
7296/// with -I prepended.
7297
7299{
7301
7302 fIncludePath = "";
7303
7304 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7305 //false - no system header, true - with flags.
7306 fInterpreter->GetIncludePaths(includePaths, false, true);
7307 if (const size_t nPaths = includePaths.size()) {
7308 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
7309
7310 for (size_t i = 0; i < nPaths; i += 2) {
7311 if (i)
7312 fIncludePath.Append(' ');
7313 fIncludePath.Append(includePaths[i].c_str());
7314
7315 if (includePaths[i] != "-I")
7316 fIncludePath.Append(' ');
7317 fIncludePath.Append('"');
7318 fIncludePath.Append(includePaths[i + 1], includePaths[i + 1].length());
7319 fIncludePath.Append('"');
7320 }
7321 }
7322
7323 return fIncludePath;
7324}
7325
7326////////////////////////////////////////////////////////////////////////////////
7327/// Return the directory containing CINT's stl cintdlls.
7328
7329const char* TCling::GetSTLIncludePath() const
7330{
7331 return "";
7332}
7333
7334//______________________________________________________________________________
7335// M I S C
7336//______________________________________________________________________________
7337
7338int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
7339{
7340 // Interface to cling function
7341 return 0;
7342}
7343
7344////////////////////////////////////////////////////////////////////////////////
7345/// Interface to cling function
7346
7347int TCling::DisplayIncludePath(FILE *fout) const
7348{
7349 assert(fout != 0 && "DisplayIncludePath, 'fout' parameter is null");
7350
7351 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7352 //false - no system header, true - with flags.
7353 fInterpreter->GetIncludePaths(includePaths, false, true);
7354 if (const size_t nPaths = includePaths.size()) {
7355 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
7356
7357 std::string allIncludes("include path:");
7358 for (size_t i = 0; i < nPaths; i += 2) {
7359 allIncludes += ' ';
7360 allIncludes += includePaths[i];
7361
7362 if (includePaths[i] != "-I")
7363 allIncludes += ' ';
7364 allIncludes += includePaths[i + 1];
7365 }
7366
7367 fprintf(fout, "%s\n", allIncludes.c_str());
7368 }
7369
7370 return 0;
7371}
7372
7373////////////////////////////////////////////////////////////////////////////////
7374/// Interface to cling function
7375
7376void* TCling::FindSym(const char* entry) const
7377{
7378 return fInterpreter->getAddressOfGlobal(entry);
7379}
7380
7381////////////////////////////////////////////////////////////////////////////////
7382/// Let the interpreter issue a generic error, and set its error state.
7383
7384void TCling::GenericError(const char* error) const
7385{
7386#if defined(R__MUST_REVISIT)
7387#if R__MUST_REVISIT(6,2)
7388 Warning("GenericError","Interface not available yet.");
7389#endif
7390#endif
7391}
7392
7393////////////////////////////////////////////////////////////////////////////////
7394/// This routines used to return the address of the internal wrapper
7395/// function (of the interpreter) that was used to call *all* the
7396/// interpreted functions that were bytecode compiled (no longer
7397/// interpreted line by line). In Cling, there is no such
7398/// wrapper function.
7399/// In practice this routines was use to decipher whether the
7400/// pointer returns by InterfaceMethod could be used to uniquely
7401/// represent the function. In Cling if the function is in a
7402/// useable state (its compiled version is available), this is
7403/// always the case.
7404/// See TClass::GetMethod.
7405
7407{
7408 return 0;
7409}
7410
7411////////////////////////////////////////////////////////////////////////////////
7412/// Interface to cling function
7413
7415{
7416#if defined(R__MUST_REVISIT)
7417#if R__MUST_REVISIT(6,2)
7418 Warning("GetSecurityError", "Interface not available yet.");
7419#endif
7420#endif
7421 return 0;
7422}
7423
7424////////////////////////////////////////////////////////////////////////////////
7425/// Load a source file or library called path into the interpreter.
7426
7427int TCling::LoadFile(const char* path) const
7428{
7429 cling::Interpreter::CompilationResult compRes;
7430 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(".L %s", path), compRes, /*cling::Value*/0);
7431 return compRes == cling::Interpreter::kFailure;
7432}
7433
7434////////////////////////////////////////////////////////////////////////////////
7435/// Load the declarations from text into the interpreter.
7436/// Note that this cannot be (top level) statements; text must contain
7437/// top level declarations.
7438/// Returns true on success, false on failure.
7439
7440Bool_t TCling::LoadText(const char* text) const
7441{
7442 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7443}
7444
7445////////////////////////////////////////////////////////////////////////////////
7446/// Interface to cling function
7447
7448const char* TCling::MapCppName(const char* name) const
7449{
7450 TTHREAD_TLS_DECL(std::string,buffer);
7451 ROOT::TMetaUtils::GetCppName(buffer,name);
7452 return buffer.c_str();
7453}
7454
7455////////////////////////////////////////////////////////////////////////////////
7456/// [Place holder for Mutex Lock]
7457/// Provide the interpreter with a way to
7458/// acquire a lock used to protect critical section
7459/// of its code (non-thread safe parts).
7460
7461void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7462{
7463 // nothing to do for now.
7464}
7465
7466////////////////////////////////////////////////////////////////////////////////
7467/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7468/// release a lock used to protect critical section
7469/// of its code (non-thread safe parts).
7470
7471void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7472{
7473 // nothing to do for now.
7474}
7475
7476////////////////////////////////////////////////////////////////////////////////
7477/// Returns if class autoloading is currently enabled.
7478
7480{
7481 if (IsFromRootCling())
7482 return false;
7483 if (!fClingCallbacks)
7484 return false;
7486}
7487
7488////////////////////////////////////////////////////////////////////////////////
7489/// Enable/Disable the Autoloading of libraries.
7490/// Returns the old value, i.e whether it was enabled or not.
7491
7492int TCling::SetClassAutoloading(int autoload) const
7493{
7494 // If no state change is required, exit early.
7495 // FIXME: In future we probably want to complain if we made a request which
7496 // was with the same state as before in order to catch programming errors.
7497 if ((bool) autoload == IsClassAutoloadingEnabled())
7498 return autoload;
7499
7500 assert(fClingCallbacks && "We must have callbacks!");
7501 bool oldVal = fClingCallbacks->IsAutoloadingEnabled();
7503 return oldVal;
7504}
7505
7506////////////////////////////////////////////////////////////////////////////////
7507/// Enable/Disable the Autoparsing of headers.
7508/// Returns the old value, i.e whether it was enabled or not.
7509
7511{
7512 bool oldVal = fHeaderParsingOnDemand;
7513 fHeaderParsingOnDemand = autoparse;
7514 return oldVal;
7515}
7516
7517////////////////////////////////////////////////////////////////////////////////
7518/// Suspend the Autoparsing of headers.
7519/// Returns the old value, i.e whether it was suspended or not.
7520
7525 return old;
7526}
7527
7528////////////////////////////////////////////////////////////////////////////////
7529/// Set a callback to receive error messages.
7530
7531void TCling::SetErrmsgcallback(void* p) const
7532{
7533#if defined(R__MUST_REVISIT)
7534#if R__MUST_REVISIT(6,2)
7535 Warning("SetErrmsgcallback", "Interface not available yet.");
7536#endif
7537#endif
7538}
7539
7540
7541////////////////////////////////////////////////////////////////////////////////
7542/// Create / close a scope for temporaries. No-op for cling; use
7543/// cling::Value instead.
7544
7545void TCling::SetTempLevel(int val) const
7546{
7547}
7548
7549////////////////////////////////////////////////////////////////////////////////
7550
7551int TCling::UnloadFile(const char* path) const
7552{
7553 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7554 std::string canonical = DLM->lookupLibrary(path);
7555 if (canonical.empty()) {
7556 canonical = path;
7557 }
7558 // Unload a shared library or a source file.
7559 cling::Interpreter::CompilationResult compRes;
7560 HandleInterpreterException(GetMetaProcessorImpl(), Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/0);
7561 return compRes == cling::Interpreter::kFailure;
7562}
7563
7564std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7565 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7566}
7567
7568////////////////////////////////////////////////////////////////////////////////
7569/// The call to Cling's tab complition.
7570
7571void TCling::CodeComplete(const std::string& line, size_t& cursor,
7572 std::vector<std::string>& completions)
7573{
7574 fInterpreter->codeComplete(line, cursor, completions);
7575}
7576
7577////////////////////////////////////////////////////////////////////////////////
7578/// Get the interpreter value corresponding to the statement.
7579int TCling::Evaluate(const char* code, TInterpreterValue& value)
7580{
7581 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7582 auto compRes = fInterpreter->evaluate(code, *V);
7583 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7584}
7585
7586////////////////////////////////////////////////////////////////////////////////
7587
7589{
7590 using namespace cling;
7591 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7593}
7594
7595////////////////////////////////////////////////////////////////////////////////
7596/// Register value as a temporary, extending its lifetime to that of the
7597/// interpreter. This is needed for TCling's compatibility interfaces
7598/// returning long - the address of the temporary objects.
7599/// As such, "simple" types don't need to be stored; they are returned by
7600/// value; only pointers / references / objects need to be stored.
7601
7603{
7604 if (value.isValid() && value.needsManagedAllocation()) {
7606 fTemporaries->push_back(value);
7607 }
7608}
7609
7610////////////////////////////////////////////////////////////////////////////////
7611/// If the interpreter encounters Name, check whether that is an object ROOT
7612/// could retrieve. To not re-read objects from disk, cache the name/object
7613/// pair for a given LookupCtx.
7614
7615TObject* TCling::GetObjectAddress(const char *Name, void *&LookupCtx)
7616{
7617 // The call to FindSpecialObject might induces any kind of use
7618 // of the interpreter ... (library loading, function calling, etc.)
7619 // ... and we _know_ we are in the middle of parsing, so let's make
7620 // sure to save the state and then restore it.
7621
7622 if (gDirectory) {
7623 auto iSpecObjMap = fSpecialObjectMaps.find(gDirectory);
7624 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7625 auto iSpecObj = iSpecObjMap->second.find(Name);
7626 if (iSpecObj != iSpecObjMap->second.end()) {
7627 LookupCtx = gDirectory;
7628 return iSpecObj->second;
7629 }
7630 }
7631 }
7632
7633 // Save state of the PP
7634 Sema &SemaR = fInterpreter->getSema();
7635 ASTContext& C = SemaR.getASTContext();
7636 Preprocessor &PP = SemaR.getPreprocessor();
7637 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7638 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7639 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7640 // After we have saved the token reset the current one to something which
7641 // is safe (semi colon usually means empty decl)
7642 Token& Tok = const_cast<Token&>(P.getCurToken());
7643 Tok.setKind(tok::semi);
7644
7645 // We can't PushDeclContext, because we go up and the routine that pops
7646 // the DeclContext assumes that we drill down always.
7647 // We have to be on the global context. At that point we are in a
7648 // wrapper function so the parent context must be the global.
7649 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7650 SemaR.TUScope);
7651
7652 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7653 if (specObj) {
7654 if (!LookupCtx) {
7655 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7656 } else {
7657 fSpecialObjectMaps[LookupCtx][Name] = specObj;
7658 }
7659 }
7660 return specObj;
7661}
7662
7663////////////////////////////////////////////////////////////////////////////////
7664/// Inject function as a friend into klass.
7665/// With function being f in void f() {new N::PrivKlass(); } this enables
7666/// I/O of non-public classes.
7667
7668void TCling::AddFriendToClass(clang::FunctionDecl* function,
7669 clang::CXXRecordDecl* klass) const
7670{
7671 using namespace clang;
7672 ASTContext& Ctx = klass->getASTContext();
7673 FriendDecl::FriendUnion friendUnion(function);
7674 // one dummy object for the source location
7675 SourceLocation sl;
7676 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
7677 klass->pushFriendDecl(friendDecl);
7678}
7679
7680//______________________________________________________________________________
7681//
7682// DeclId getter.
7683//
7684
7685////////////////////////////////////////////////////////////////////////////////
7686/// Return a unique identifier of the declaration represented by the
7687/// CallFunc
7688
7690{
7691 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
7692 return 0;
7693}
7694
7695////////////////////////////////////////////////////////////////////////////////
7696/// Return a (almost) unique identifier of the declaration represented by the
7697/// ClassInfo. In ROOT, this identifier can point to more than one TClass
7698/// when the underlying class is a template instance involving one of the
7699/// opaque typedef.
7700
7702{
7703 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
7704 return 0;
7705}
7706
7707////////////////////////////////////////////////////////////////////////////////
7708/// Return a unique identifier of the declaration represented by the
7709/// MethodInfo
7710
7711TInterpreter::DeclId_t TCling::GetDeclId(DataMemberInfo_t* data) const
7712{
7713 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
7714 return 0;
7715}
7716
7717////////////////////////////////////////////////////////////////////////////////
7718/// Return a unique identifier of the declaration represented by the
7719/// MethodInfo
7720
7722{
7723 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
7724 return 0;
7725}
7726
7727////////////////////////////////////////////////////////////////////////////////
7728/// Return a unique identifier of the declaration represented by the
7729/// TypedefInfo
7730
7732{
7733 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
7734 return 0;
7735}
7736
7737//______________________________________________________________________________
7738//
7739// CallFunc interface
7740//
7741
7742////////////////////////////////////////////////////////////////////////////////
7743
7744void TCling::CallFunc_Delete(CallFunc_t* func) const
7745{
7746 delete (TClingCallFunc*) func;
7747}
7748
7749////////////////////////////////////////////////////////////////////////////////
7750
7751void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
7752{
7753 TClingCallFunc* f = (TClingCallFunc*) func;
7754 f->Exec(address);
7755}
7756
7757////////////////////////////////////////////////////////////////////////////////
7758
7759void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
7760{
7761 TClingCallFunc* f = (TClingCallFunc*) func;
7762 f->Exec(address, &val);
7763}
7764
7765////////////////////////////////////////////////////////////////////////////////
7766
7767void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
7768{
7769 TClingCallFunc* f = (TClingCallFunc*) func;
7770 f->ExecWithReturn(address, ret);
7771}
7772
7773////////////////////////////////////////////////////////////////////////////////
7774
7775void TCling::CallFunc_ExecWithArgsAndReturn(CallFunc_t* func, void* address,
7776 const void* args[] /*=0*/,
7777 int nargs /*=0*/,
7778 void* ret/*=0*/) const
7779{
7780 TClingCallFunc* f = (TClingCallFunc*) func;
7781 f->ExecWithArgsAndReturn(address, args, nargs, ret);
7782}
7783
7784////////////////////////////////////////////////////////////////////////////////
7785
7786Long_t TCling::CallFunc_ExecInt(CallFunc_t* func, void* address) const
7787{
7788 TClingCallFunc* f = (TClingCallFunc*) func;
7789 return f->ExecInt(address);
7790}
7791
7792////////////////////////////////////////////////////////////////////////////////
7793
7794Long64_t TCling::CallFunc_ExecInt64(CallFunc_t* func, void* address) const
7795{
7796 TClingCallFunc* f = (TClingCallFunc*) func;
7797 return f->ExecInt64(address);
7798}
7799
7800////////////////////////////////////////////////////////////////////////////////
7801
7802Double_t TCling::CallFunc_ExecDouble(CallFunc_t* func, void* address) const
7803{
7804 TClingCallFunc* f = (TClingCallFunc*) func;
7805 return f->ExecDouble(address);
7806}
7807
7808////////////////////////////////////////////////////////////////////////////////
7809
7810CallFunc_t* TCling::CallFunc_Factory() const
7811{
7813 return (CallFunc_t*) new TClingCallFunc(GetInterpreterImpl(), *fNormalizedCtxt);
7814}
7815
7816////////////////////////////////////////////////////////////////////////////////
7817
7818CallFunc_t* TCling::CallFunc_FactoryCopy(CallFunc_t* func) const
7819{
7820 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
7821}
7822
7823////////////////////////////////////////////////////////////////////////////////
7824
7825MethodInfo_t* TCling::CallFunc_FactoryMethod(CallFunc_t* func) const
7826{
7827 TClingCallFunc* f = (TClingCallFunc*) func;
7828 return (MethodInfo_t*) f->FactoryMethod();
7829}
7830
7831////////////////////////////////////////////////////////////////////////////////
7832
7833void TCling::CallFunc_IgnoreExtraArgs(CallFunc_t* func, bool ignore) const
7834{
7835 TClingCallFunc* f = (TClingCallFunc*) func;
7836 f->IgnoreExtraArgs(ignore);
7837}
7838
7839////////////////////////////////////////////////////////////////////////////////
7840
7841void TCling::CallFunc_Init(CallFunc_t* func) const
7842{
7844 TClingCallFunc* f = (TClingCallFunc*) func;
7845 f->Init();
7846}
7847
7848////////////////////////////////////////////////////////////////////////////////
7849
7850bool TCling::CallFunc_IsValid(CallFunc_t* func) const
7851{
7852 TClingCallFunc* f = (TClingCallFunc*) func;
7853 return f->IsValid();
7854}
7855
7856////////////////////////////////////////////////////////////////////////////////
7857
7859TCling::CallFunc_IFacePtr(CallFunc_t * func) const
7860{
7861 TClingCallFunc* f = (TClingCallFunc*) func;
7862 return f->IFacePtr();
7863}
7864
7865////////////////////////////////////////////////////////////////////////////////
7866
7867void TCling::CallFunc_ResetArg(CallFunc_t* func) const
7868{
7869 TClingCallFunc* f = (TClingCallFunc*) func;
7870 f->ResetArg();
7871}
7872
7873////////////////////////////////////////////////////////////////////////////////
7874
7875void TCling::CallFunc_SetArg(CallFunc_t* func, Long_t param) const
7876{
7877 TClingCallFunc* f = (TClingCallFunc*) func;
7878 f->SetArg(param);
7879}
7880
7881////////////////////////////////////////////////////////////////////////////////
7882
7883void TCling::CallFunc_SetArg(CallFunc_t* func, ULong_t param) const
7884{
7885 TClingCallFunc* f = (TClingCallFunc*) func;
7886 f->SetArg(param);
7887}
7888
7889////////////////////////////////////////////////////////////////////////////////
7890
7891void TCling::CallFunc_SetArg(CallFunc_t* func, Float_t param) const
7892{
7893 TClingCallFunc* f = (TClingCallFunc*) func;
7894 f->SetArg(param);
7895}
7896
7897////////////////////////////////////////////////////////////////////////////////
7898
7899void TCling::CallFunc_SetArg(CallFunc_t* func, Double_t param) const
7900{
7901 TClingCallFunc* f = (TClingCallFunc*) func;
7902 f->SetArg(param);
7903}
7904
7905////////////////////////////////////////////////////////////////////////////////
7906
7907void TCling::CallFunc_SetArg(CallFunc_t* func, Long64_t param) const
7908{
7909 TClingCallFunc* f = (TClingCallFunc*) func;
7910 f->SetArg(param);
7911}
7912
7913////////////////////////////////////////////////////////////////////////////////
7914
7915void TCling::CallFunc_SetArg(CallFunc_t* func, ULong64_t param) const
7916{
7917 TClingCallFunc* f = (TClingCallFunc*) func;
7918 f->SetArg(param);
7919}
7920
7921////////////////////////////////////////////////////////////////////////////////
7922
7923void TCling::CallFunc_SetArgArray(CallFunc_t* func, Long_t* paramArr, Int_t nparam) const
7924{
7925 TClingCallFunc* f = (TClingCallFunc*) func;
7926 f->SetArgArray(paramArr, nparam);
7927}
7928
7929////////////////////////////////////////////////////////////////////////////////
7930
7931void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
7932{
7933 TClingCallFunc* f = (TClingCallFunc*) func;
7934 f->SetArgs(param);
7935}
7936
7937////////////////////////////////////////////////////////////////////////////////
7938
7939void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Long_t* offset) const
7940{
7941 TClingCallFunc* f = (TClingCallFunc*) func;
7942 TClingClassInfo* ci = (TClingClassInfo*) info;
7943 f->SetFunc(ci, method, params, offset);
7944}
7945
7946////////////////////////////////////////////////////////////////////////////////
7947
7948void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Long_t* offset) const
7949{
7950 TClingCallFunc* f = (TClingCallFunc*) func;
7951 TClingClassInfo* ci = (TClingClassInfo*) info;
7952 f->SetFunc(ci, method, params, objectIsConst, offset);
7953}
7954////////////////////////////////////////////////////////////////////////////////
7955
7956void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
7957{
7958 TClingCallFunc* f = (TClingCallFunc*) func;
7959 TClingMethodInfo* minfo = (TClingMethodInfo*) info;
7960 f->SetFunc(minfo);
7961}
7962
7963////////////////////////////////////////////////////////////////////////////////
7964/// Interface to cling function
7965
7966void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
7967{
7968 TClingCallFunc* f = (TClingCallFunc*) func;
7969 TClingClassInfo* ci = (TClingClassInfo*) info;
7970 f->SetFuncProto(ci, method, proto, offset, mode);
7971}
7972
7973////////////////////////////////////////////////////////////////////////////////
7974/// Interface to cling function
7975
7976void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
7977{
7978 TClingCallFunc* f = (TClingCallFunc*) func;
7979 TClingClassInfo* ci = (TClingClassInfo*) info;
7980 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
7981}
7982
7983////////////////////////////////////////////////////////////////////////////////
7984/// Interface to cling function
7985
7986void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const std::vector<TypeInfo_t*> &proto, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
7987{
7988 TClingCallFunc* f = (TClingCallFunc*) func;
7989 TClingClassInfo* ci = (TClingClassInfo*) info;
7990 llvm::SmallVector<clang::QualType, 4> funcProto;
7991 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
7992 iter != end; ++iter) {
7993 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
7994 }
7995 f->SetFuncProto(ci, method, funcProto, offset, mode);
7996}
7997
7998////////////////////////////////////////////////////////////////////////////////
7999/// Interface to cling function
8000
8001void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const std::vector<TypeInfo_t*> &proto, bool objectIsConst, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8002{
8003 TClingCallFunc* f = (TClingCallFunc*) func;
8004 TClingClassInfo* ci = (TClingClassInfo*) info;
8005 llvm::SmallVector<clang::QualType, 4> funcProto;
8006 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
8007 iter != end; ++iter) {
8008 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
8009 }
8010 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
8011}
8012
8013std::string TCling::CallFunc_GetWrapperCode(CallFunc_t *func) const
8014{
8015 TClingCallFunc *f = (TClingCallFunc *)func;
8016 std::string wrapper_name;
8017 std::string wrapper;
8018 f->get_wrapper_code(wrapper_name, wrapper);
8019 return wrapper;
8020}
8021
8022//______________________________________________________________________________
8023//
8024// ClassInfo interface
8025//
8026
8027////////////////////////////////////////////////////////////////////////////////
8028/// Return true if the entity pointed to by 'declid' is declared in
8029/// the context described by 'info'. If info is null, look into the
8030/// global scope (translation unit scope).
8031
8032Bool_t TCling::ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const
8033{
8034 if (!declid) return kFALSE;
8035
8036 const clang::Decl *scope;
8037 if (info) scope = ((TClingClassInfo*)info)->GetDecl();
8038 else scope = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
8039
8040 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
8041 const clang::DeclContext *ctxt = clang::Decl::castToDeclContext(scope);
8042 if (!decl || !ctxt) return kFALSE;
8043 if (decl->getDeclContext()->Equals(ctxt))
8044 return kTRUE;
8045 else if ((decl->getDeclContext()->isTransparentContext()
8046 || decl->getDeclContext()->isInlineNamespace())
8047 && decl->getDeclContext()->getParent()->Equals(ctxt))
8048 return kTRUE;
8049 return kFALSE;
8050}
8051
8052////////////////////////////////////////////////////////////////////////////////
8053
8055{
8056 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8057 return TClinginfo->ClassProperty();
8058}
8059
8060////////////////////////////////////////////////////////////////////////////////
8061
8062void TCling::ClassInfo_Delete(ClassInfo_t* cinfo) const
8063{
8064 delete (TClingClassInfo*) cinfo;
8065}
8066
8067////////////////////////////////////////////////////////////////////////////////
8068
8069void TCling::ClassInfo_Delete(ClassInfo_t* cinfo, void* arena) const
8070{
8071 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8072 TClinginfo->Delete(arena,*fNormalizedCtxt);
8073}
8074
8075////////////////////////////////////////////////////////////////////////////////
8076
8077void TCling::ClassInfo_DeleteArray(ClassInfo_t* cinfo, void* arena, bool dtorOnly) const
8078{
8079 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8080 TClinginfo->DeleteArray(arena, dtorOnly,*fNormalizedCtxt);
8081}
8082
8083////////////////////////////////////////////////////////////////////////////////
8084
8085void TCling::ClassInfo_Destruct(ClassInfo_t* cinfo, void* arena) const
8086{
8087 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8088 TClinginfo->Destruct(arena,*fNormalizedCtxt);
8089}
8090
8091////////////////////////////////////////////////////////////////////////////////
8092
8093ClassInfo_t* TCling::ClassInfo_Factory(Bool_t all) const
8094{
8096 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), all);
8097}
8098
8099////////////////////////////////////////////////////////////////////////////////
8100
8101ClassInfo_t* TCling::ClassInfo_Factory(ClassInfo_t* cinfo) const
8102{
8103 return (ClassInfo_t*) new TClingClassInfo(*(TClingClassInfo*)cinfo);
8104}
8105
8106////////////////////////////////////////////////////////////////////////////////
8107
8108ClassInfo_t* TCling::ClassInfo_Factory(const char* name) const
8109{
8111 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), name);
8112}
8113
8114ClassInfo_t* TCling::ClassInfo_Factory(DeclId_t declid) const
8115{
8117 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), (const clang::Decl*)declid);
8118}
8119
8120
8121////////////////////////////////////////////////////////////////////////////////
8122
8123int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
8124{
8125 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8126 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
8127}
8128
8129////////////////////////////////////////////////////////////////////////////////
8130
8131bool TCling::ClassInfo_HasDefaultConstructor(ClassInfo_t* cinfo) const
8132{
8133 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8134 return TClinginfo->HasDefaultConstructor();
8135}
8136
8137////////////////////////////////////////////////////////////////////////////////
8138
8139bool TCling::ClassInfo_HasMethod(ClassInfo_t* cinfo, const char* name) const
8140{
8141 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8142 return TClinginfo->HasMethod(name);
8143}
8144
8145////////////////////////////////////////////////////////////////////////////////
8146
8147void TCling::ClassInfo_Init(ClassInfo_t* cinfo, const char* name) const
8148{
8150 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8151 TClinginfo->Init(name);
8152}
8153
8154////////////////////////////////////////////////////////////////////////////////
8155
8156void TCling::ClassInfo_Init(ClassInfo_t* cinfo, int tagnum) const
8157{
8159 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8160 TClinginfo->Init(tagnum);
8161}
8162
8163////////////////////////////////////////////////////////////////////////////////
8164
8165bool TCling::ClassInfo_IsBase(ClassInfo_t* cinfo, const char* name) const
8166{
8167 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8168 return TClinginfo->IsBase(name);
8169}
8170
8171////////////////////////////////////////////////////////////////////////////////
8172
8173bool TCling::ClassInfo_IsEnum(const char* name) const
8174{
8176}
8177
8178////////////////////////////////////////////////////////////////////////////////
8179
8181{
8182 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8183 return TClinginfo->IsScopedEnum();
8184}
8185
8186
8187////////////////////////////////////////////////////////////////////////////////
8188
8190{
8191 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8192 return TClinginfo->GetUnderlyingType();
8193}
8194
8195
8196////////////////////////////////////////////////////////////////////////////////
8197
8198bool TCling::ClassInfo_IsLoaded(ClassInfo_t* cinfo) const
8199{
8200 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8201 return TClinginfo->IsLoaded();
8202}
8203
8204////////////////////////////////////////////////////////////////////////////////
8205
8206bool TCling::ClassInfo_IsValid(ClassInfo_t* cinfo) const
8207{
8208 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8209 return TClinginfo->IsValid();
8210}
8211
8212////////////////////////////////////////////////////////////////////////////////
8213
8214bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8215{
8216 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8217 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
8218}
8219
8220////////////////////////////////////////////////////////////////////////////////
8221
8222bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8223{
8224 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8225 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8226}
8227
8228////////////////////////////////////////////////////////////////////////////////
8229
8230int TCling::ClassInfo_Next(ClassInfo_t* cinfo) const
8231{
8232 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8233 return TClinginfo->Next();
8234}
8235
8236////////////////////////////////////////////////////////////////////////////////
8237
8238void* TCling::ClassInfo_New(ClassInfo_t* cinfo) const
8239{
8240 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8241 return TClinginfo->New(*fNormalizedCtxt);
8242}
8243
8244////////////////////////////////////////////////////////////////////////////////
8245
8246void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n) const
8247{
8248 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8249 return TClinginfo->New(n,*fNormalizedCtxt);
8250}
8251
8252////////////////////////////////////////////////////////////////////////////////
8253
8254void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n, void* arena) const
8255{
8256 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8257 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8258}
8259
8260////////////////////////////////////////////////////////////////////////////////
8261
8262void* TCling::ClassInfo_New(ClassInfo_t* cinfo, void* arena) const
8263{
8264 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8265 return TClinginfo->New(arena,*fNormalizedCtxt);
8266}
8267
8268////////////////////////////////////////////////////////////////////////////////
8269
8270Long_t TCling::ClassInfo_Property(ClassInfo_t* cinfo) const
8271{
8272 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8273 return TClinginfo->Property();
8274}
8275
8276////////////////////////////////////////////////////////////////////////////////
8277
8278int TCling::ClassInfo_Size(ClassInfo_t* cinfo) const
8279{
8280 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8281 return TClinginfo->Size();
8282}
8283
8284////////////////////////////////////////////////////////////////////////////////
8285
8286Long_t TCling::ClassInfo_Tagnum(ClassInfo_t* cinfo) const
8287{
8288 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8289 return TClinginfo->Tagnum();
8290}
8291
8292////////////////////////////////////////////////////////////////////////////////
8293
8294const char* TCling::ClassInfo_FileName(ClassInfo_t* cinfo) const
8295{
8296 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8297 return TClinginfo->FileName();
8298}
8299
8300////////////////////////////////////////////////////////////////////////////////
8301
8302const char* TCling::ClassInfo_FullName(ClassInfo_t* cinfo) const
8303{
8304 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8305 TTHREAD_TLS_DECL(std::string,output);
8306 TClinginfo->FullName(output,*fNormalizedCtxt);
8307 return output.c_str();
8308}
8309
8310////////////////////////////////////////////////////////////////////////////////
8311
8312const char* TCling::ClassInfo_Name(ClassInfo_t* cinfo) const
8313{
8314 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8315 return TClinginfo->Name();
8316}
8317
8318////////////////////////////////////////////////////////////////////////////////
8319
8320const char* TCling::ClassInfo_Title(ClassInfo_t* cinfo) const
8321{
8322 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8323 return TClinginfo->Title();
8324}
8325
8326////////////////////////////////////////////////////////////////////////////////
8327
8328const char* TCling::ClassInfo_TmpltName(ClassInfo_t* cinfo) const
8329{
8330 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8331 return TClinginfo->TmpltName();
8332}
8333
8334
8335
8336//______________________________________________________________________________
8337//
8338// BaseClassInfo interface
8339//
8340
8341////////////////////////////////////////////////////////////////////////////////
8342
8343void TCling::BaseClassInfo_Delete(BaseClassInfo_t* bcinfo) const
8344{
8345 delete(TClingBaseClassInfo*) bcinfo;
8346}
8347
8348////////////////////////////////////////////////////////////////////////////////
8349
8350BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo) const
8351{
8353 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8354 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo);
8355}
8356
8357////////////////////////////////////////////////////////////////////////////////
8358
8359BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* derived,
8360 ClassInfo_t* base) const
8361{
8363 TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
8364 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) base;
8365 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo, TClinginfoBase);
8366}
8367
8368////////////////////////////////////////////////////////////////////////////////
8369
8370int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo) const
8371{
8372 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8373 return TClinginfo->Next();
8374}
8375
8376////////////////////////////////////////////////////////////////////////////////
8377
8378int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo, int onlyDirect) const
8379{
8380 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8381 return TClinginfo->Next(onlyDirect);
8382}
8383
8384////////////////////////////////////////////////////////////////////////////////
8385
8386Long_t TCling::BaseClassInfo_Offset(BaseClassInfo_t* toBaseClassInfo, void * address, bool isDerivedObject) const
8387{
8388 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) toBaseClassInfo;
8389 return TClinginfo->Offset(address, isDerivedObject);
8390}
8391
8392////////////////////////////////////////////////////////////////////////////////
8393
8394Long_t TCling::ClassInfo_GetBaseOffset(ClassInfo_t* fromDerived, ClassInfo_t* toBase, void * address, bool isDerivedObject) const
8395{
8396 TClingClassInfo* TClinginfo = (TClingClassInfo*) fromDerived;
8397 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) toBase;
8398 // Offset to the class itself.
8399 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8400 return 0;
8401 }
8402 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8403}
8404
8405////////////////////////////////////////////////////////////////////////////////
8406
8407Long_t TCling::BaseClassInfo_Property(BaseClassInfo_t* bcinfo) const
8408{
8409 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8410 return TClinginfo->Property();
8411}
8412
8413////////////////////////////////////////////////////////////////////////////////
8414
8415ClassInfo_t *TCling::BaseClassInfo_ClassInfo(BaseClassInfo_t *bcinfo) const
8416{
8417 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8418 return (ClassInfo_t *)TClinginfo->GetBase();
8419}
8420
8421////////////////////////////////////////////////////////////////////////////////
8422
8423Long_t TCling::BaseClassInfo_Tagnum(BaseClassInfo_t* bcinfo) const
8424{
8425 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8426 return TClinginfo->Tagnum();
8427}
8428
8429////////////////////////////////////////////////////////////////////////////////
8430
8431const char* TCling::BaseClassInfo_FullName(BaseClassInfo_t* bcinfo) const
8432{
8433 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8434 TTHREAD_TLS_DECL(std::string,output);
8435 TClinginfo->FullName(output,*fNormalizedCtxt);
8436 return output.c_str();
8437}
8438
8439////////////////////////////////////////////////////////////////////////////////
8440
8441const char* TCling::BaseClassInfo_Name(BaseClassInfo_t* bcinfo) const
8442{
8443 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8444 return TClinginfo->Name();
8445}
8446
8447////////////////////////////////////////////////////////////////////////////////
8448
8449const char* TCling::BaseClassInfo_TmpltName(BaseClassInfo_t* bcinfo) const
8450{
8451 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8452 return TClinginfo->TmpltName();
8453}
8454
8455//______________________________________________________________________________
8456//
8457// DataMemberInfo interface
8458//
8459
8460////////////////////////////////////////////////////////////////////////////////
8461
8462int TCling::DataMemberInfo_ArrayDim(DataMemberInfo_t* dminfo) const
8463{
8464 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8465 return TClinginfo->ArrayDim();
8466}
8467
8468////////////////////////////////////////////////////////////////////////////////
8469
8470void TCling::DataMemberInfo_Delete(DataMemberInfo_t* dminfo) const
8471{
8472 delete(TClingDataMemberInfo*) dminfo;
8473}
8474
8475////////////////////////////////////////////////////////////////////////////////
8476
8477DataMemberInfo_t* TCling::DataMemberInfo_Factory(ClassInfo_t* clinfo /*= 0*/) const
8478{
8480 TClingClassInfo* TClingclass_info = (TClingClassInfo*) clinfo;
8481 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), TClingclass_info);
8482}
8483
8484////////////////////////////////////////////////////////////////////////////////
8485
8486DataMemberInfo_t* TCling::DataMemberInfo_Factory(DeclId_t declid, ClassInfo_t* clinfo) const
8487{
8489 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8490 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8491 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), vd, (TClingClassInfo*)clinfo);
8492}
8493
8494////////////////////////////////////////////////////////////////////////////////
8495
8496DataMemberInfo_t* TCling::DataMemberInfo_FactoryCopy(DataMemberInfo_t* dminfo) const
8497{
8498 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8499 return (DataMemberInfo_t*) new TClingDataMemberInfo(*TClinginfo);
8500}
8501
8502////////////////////////////////////////////////////////////////////////////////
8503
8504bool TCling::DataMemberInfo_IsValid(DataMemberInfo_t* dminfo) const
8505{
8506 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8507 return TClinginfo->IsValid();
8508}
8509
8510////////////////////////////////////////////////////////////////////////////////
8511
8512int TCling::DataMemberInfo_MaxIndex(DataMemberInfo_t* dminfo, Int_t dim) const
8513{
8514 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8515 return TClinginfo->MaxIndex(dim);
8516}
8517
8518////////////////////////////////////////////////////////////////////////////////
8519
8520int TCling::DataMemberInfo_Next(DataMemberInfo_t* dminfo) const
8521{
8522 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8523 return TClinginfo->Next();
8524}
8525
8526////////////////////////////////////////////////////////////////////////////////
8527
8528Long_t TCling::DataMemberInfo_Offset(DataMemberInfo_t* dminfo) const
8529{
8530 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8531 return TClinginfo->Offset();
8532}
8533
8534////////////////////////////////////////////////////////////////////////////////
8535
8536Long_t TCling::DataMemberInfo_Property(DataMemberInfo_t* dminfo) const
8537{
8538 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8539 return TClinginfo->Property();
8540}
8541
8542////////////////////////////////////////////////////////////////////////////////
8543
8544Long_t TCling::DataMemberInfo_TypeProperty(DataMemberInfo_t* dminfo) const
8545{
8546 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8547 return TClinginfo->TypeProperty();
8548}
8549
8550////////////////////////////////////////////////////////////////////////////////
8551
8552int TCling::DataMemberInfo_TypeSize(DataMemberInfo_t* dminfo) const
8553{
8554 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8555 return TClinginfo->TypeSize();
8556}
8557
8558////////////////////////////////////////////////////////////////////////////////
8559
8560const char* TCling::DataMemberInfo_TypeName(DataMemberInfo_t* dminfo) const
8561{
8562 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8563 return TClinginfo->TypeName();
8564}
8565
8566////////////////////////////////////////////////////////////////////////////////
8567
8568const char* TCling::DataMemberInfo_TypeTrueName(DataMemberInfo_t* dminfo) const
8569{
8570 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8571 return TClinginfo->TypeTrueName(*fNormalizedCtxt);
8572}
8573
8574////////////////////////////////////////////////////////////////////////////////
8575
8576const char* TCling::DataMemberInfo_Name(DataMemberInfo_t* dminfo) const
8577{
8578 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8579 return TClinginfo->Name();
8580}
8581
8582////////////////////////////////////////////////////////////////////////////////
8583
8584const char* TCling::DataMemberInfo_Title(DataMemberInfo_t* dminfo) const
8585{
8586 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8587 return TClinginfo->Title();
8588}
8589
8590////////////////////////////////////////////////////////////////////////////////
8591
8592const char* TCling::DataMemberInfo_ValidArrayIndex(DataMemberInfo_t* dminfo) const
8593{
8594 TTHREAD_TLS_DECL(std::string,result);
8595
8596 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8597 result = TClinginfo->ValidArrayIndex().str();
8598 return result.c_str();
8599}
8600
8601////////////////////////////////////////////////////////////////////////////////
8602
8603void TCling::SetDeclAttr(DeclId_t declId, const char* attribute)
8604{
8605 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8606 ASTContext &C = decl->getASTContext();
8607 SourceRange commentRange; // this is a fake comment range
8608 decl->addAttr( new (C) AnnotateAttr( commentRange, C, attribute, 0 ) );
8609}
8610
8611//______________________________________________________________________________
8612//
8613// Function Template interface
8614//
8615
8616////////////////////////////////////////////////////////////////////////////////
8617
8618static void ConstructorName(std::string &name, const clang::NamedDecl *decl,
8619 cling::Interpreter &interp,
8620 const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
8621{
8622 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8623 if (!td) return;
8624
8625 clang::QualType qualType(td->getTypeForDecl(),0);
8626 ROOT::TMetaUtils::GetNormalizedName(name, qualType, interp, normCtxt);
8627 unsigned int level = 0;
8628 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8629 if (name[cursor] == '>') ++level;
8630 else if (name[cursor] == '<' && level) --level;
8631 else if (level == 0 && name[cursor] == ':') {
8632 name.erase(0,cursor+1);
8633 break;
8634 }
8635 }
8636}
8637
8638////////////////////////////////////////////////////////////////////////////////
8639
8640void TCling::GetFunctionName(const clang::FunctionDecl *decl, std::string &output) const
8641{
8642 output.clear();
8643 if (llvm::isa<clang::CXXConstructorDecl>(decl))
8644 {
8646
8647 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
8648 {
8650 output.insert(output.begin(), '~');
8651 } else {
8652 llvm::raw_string_ostream stream(output);
8653 auto printPolicy = decl->getASTContext().getPrintingPolicy();
8654 // Don't trigger fopen of the source file to count lines:
8655 printPolicy.AnonymousTagLocations = false;
8656 decl->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
8657 }
8658}
8659
8660////////////////////////////////////////////////////////////////////////////////
8661/// Return a unique identifier of the declaration represented by the
8662/// FuncTempInfo
8663
8665{
8666 return (DeclId_t)info;
8667}
8668
8669////////////////////////////////////////////////////////////////////////////////
8670/// Delete the FuncTempInfo_t
8671
8672void TCling::FuncTempInfo_Delete(FuncTempInfo_t * /* ft_info */) const
8673{
8674 // Currently the address of ft_info is actually the decl itself,
8675 // so we have nothing to do.
8676}
8677
8678////////////////////////////////////////////////////////////////////////////////
8679/// Construct a FuncTempInfo_t
8680
8681FuncTempInfo_t *TCling::FuncTempInfo_Factory(DeclId_t declid) const
8682{
8683 // Currently the address of ft_info is actually the decl itself,
8684 // so we have nothing to do.
8685
8686 return (FuncTempInfo_t*)const_cast<void*>(declid);
8687}
8688
8689////////////////////////////////////////////////////////////////////////////////
8690/// Construct a FuncTempInfo_t
8691
8692FuncTempInfo_t *TCling::FuncTempInfo_FactoryCopy(FuncTempInfo_t *ft_info) const
8693{
8694 // Currently the address of ft_info is actually the decl itself,
8695 // so we have nothing to do.
8696
8697 return (FuncTempInfo_t*)ft_info;
8698}
8699
8700////////////////////////////////////////////////////////////////////////////////
8701/// Check validity of a FuncTempInfo_t
8702
8703Bool_t TCling::FuncTempInfo_IsValid(FuncTempInfo_t *t_info) const
8704{
8705 // Currently the address of ft_info is actually the decl itself,
8706 // so we have nothing to do.
8707
8708 return t_info != 0;
8709}
8710
8711////////////////////////////////////////////////////////////////////////////////
8712/// Return the maximum number of template arguments of the
8713/// function template described by ft_info.
8714
8715UInt_t TCling::FuncTempInfo_TemplateNargs(FuncTempInfo_t *ft_info) const
8716{
8717 if (!ft_info) return 0;
8718 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8719 return ft->getTemplateParameters()->size();
8720}
8721
8722////////////////////////////////////////////////////////////////////////////////
8723/// Return the number of required template arguments of the
8724/// function template described by ft_info.
8725
8727{
8728 if (!ft_info) return 0;
8729 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8730 return ft->getTemplateParameters()->getMinRequiredArguments();
8731}
8732
8733////////////////////////////////////////////////////////////////////////////////
8734/// Return the property of the function template.
8735
8736Long_t TCling::FuncTempInfo_Property(FuncTempInfo_t *ft_info) const
8737{
8738 if (!ft_info) return 0;
8739
8740 long property = 0L;
8741 property |= kIsCompiled;
8742
8743 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8744
8745 switch (ft->getAccess()) {
8746 case clang::AS_public:
8747 property |= kIsPublic;
8748 break;
8749 case clang::AS_protected:
8750 property |= kIsProtected;
8751 break;
8752 case clang::AS_private:
8753 property |= kIsPrivate;
8754 break;
8755 case clang::AS_none:
8756 if (ft->getDeclContext()->isNamespace())
8757 property |= kIsPublic;
8758 break;
8759 default:
8760 // IMPOSSIBLE
8761 break;
8762 }
8763
8764 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8765 if (const clang::CXXMethodDecl *md =
8766 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
8767 if (md->getTypeQualifiers() & clang::Qualifiers::Const) {
8768 property |= kIsConstant | kIsConstMethod;
8769 }
8770 if (md->isVirtual()) {
8771 property |= kIsVirtual;
8772 }
8773 if (md->isPure()) {
8774 property |= kIsPureVirtual;
8775 }
8776 if (const clang::CXXConstructorDecl *cd =
8777 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
8778 if (cd->isExplicit()) {
8779 property |= kIsExplicit;
8780 }
8781 }
8782 else if (const clang::CXXConversionDecl *cd =
8783 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
8784 if (cd->isExplicit()) {
8785 property |= kIsExplicit;
8786 }
8787 }
8788 }
8789 return property;
8790}
8791
8792////////////////////////////////////////////////////////////////////////////////
8793/// Return the property not already defined in Property
8794/// See TDictionary's EFunctionProperty
8795
8796Long_t TCling::FuncTempInfo_ExtraProperty(FuncTempInfo_t* ft_info) const
8797{
8798 if (!ft_info) return 0;
8799
8800 long property = 0L;
8801 property |= kIsCompiled;
8802
8803 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8804 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8805
8806 if (fd->isOverloadedOperator())
8807 property |= kIsOperator;
8808 if (llvm::isa<clang::CXXConversionDecl>(fd))
8809 property |= kIsConversion;
8810 if (llvm::isa<clang::CXXConstructorDecl>(fd))
8811 property |= kIsConstructor;
8812 if (llvm::isa<clang::CXXDestructorDecl>(fd))
8813 property |= kIsDestructor;
8814 if (fd->isInlined())
8815 property |= kIsInlined;
8816 return property;
8817}
8818
8819////////////////////////////////////////////////////////////////////////////////
8820/// Return the name of this function template.
8821
8822void TCling::FuncTempInfo_Name(FuncTempInfo_t *ft_info, TString &output) const
8823{
8824 output.Clear();
8825 if (!ft_info) return;
8826 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8827 std::string buf;
8828 GetFunctionName(ft->getTemplatedDecl(), buf);
8829 output = buf;
8830}
8831
8832////////////////////////////////////////////////////////////////////////////////
8833/// Return the comments associates with this function template.
8834
8835void TCling::FuncTempInfo_Title(FuncTempInfo_t *ft_info, TString &output) const
8836{
8837 output.Clear();
8838 if (!ft_info) return;
8839 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8840
8841 // Iterate over the redeclarations, we can have multiple definitions in the
8842 // redecl chain (came from merging of pcms).
8843 if (const RedeclarableTemplateDecl *AnnotFD
8844 = ROOT::TMetaUtils::GetAnnotatedRedeclarable((const RedeclarableTemplateDecl*)ft)) {
8845 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
8846 output = A->getAnnotation().str();
8847 return;
8848 }
8849 }
8850 if (!ft->isFromASTFile()) {
8851 // Try to get the comment from the header file if present
8852 // but not for decls from AST file, where rootcling would have
8853 // created an annotation
8854 output = ROOT::TMetaUtils::GetComment(*ft).str();
8855 }
8856}
8857
8858
8859//______________________________________________________________________________
8860//
8861// MethodInfo interface
8862//
8863
8864////////////////////////////////////////////////////////////////////////////////
8865/// Interface to cling function
8866
8867void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
8868{
8869 delete(TClingMethodInfo*) minfo;
8870}
8871
8872////////////////////////////////////////////////////////////////////////////////
8873
8874void TCling::MethodInfo_CreateSignature(MethodInfo_t* minfo, TString& signature) const
8875{
8876 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8877 info->CreateSignature(signature);
8878}
8879
8880////////////////////////////////////////////////////////////////////////////////
8881
8882MethodInfo_t* TCling::MethodInfo_Factory() const
8883{
8885 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl());
8886}
8887
8888////////////////////////////////////////////////////////////////////////////////
8889
8890MethodInfo_t* TCling::MethodInfo_Factory(ClassInfo_t* clinfo) const
8891{
8893 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
8894}
8895
8896////////////////////////////////////////////////////////////////////////////////
8897
8898MethodInfo_t* TCling::MethodInfo_Factory(DeclId_t declid) const
8899{
8900 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8902 const clang::FunctionDecl* fd = llvm::dyn_cast_or_null<clang::FunctionDecl>(decl);
8903 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), fd);
8904}
8905
8906////////////////////////////////////////////////////////////////////////////////
8907
8908MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
8909{
8910 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
8911}
8912
8913////////////////////////////////////////////////////////////////////////////////
8914
8915void* TCling::MethodInfo_InterfaceMethod(MethodInfo_t* minfo) const
8916{
8917 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8918 return info->InterfaceMethod(*fNormalizedCtxt);
8919}
8920
8921////////////////////////////////////////////////////////////////////////////////
8922
8923bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
8924{
8925 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8926 return info->IsValid();
8927}
8928
8929////////////////////////////////////////////////////////////////////////////////
8930
8931int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
8932{
8933 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8934 return info->NArg();
8935}
8936
8937////////////////////////////////////////////////////////////////////////////////
8938
8939int TCling::MethodInfo_NDefaultArg(MethodInfo_t* minfo) const
8940{
8941 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8942 return info->NDefaultArg();
8943}
8944
8945////////////////////////////////////////////////////////////////////////////////
8946
8947int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
8948{
8949 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8950 return info->Next();
8951}
8952
8953////////////////////////////////////////////////////////////////////////////////
8954
8955Long_t TCling::MethodInfo_Property(MethodInfo_t* minfo) const
8956{
8957 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8958 return info->Property();
8959}
8960
8961////////////////////////////////////////////////////////////////////////////////
8962
8964{
8965 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8966 return info->ExtraProperty();
8967}
8968
8969////////////////////////////////////////////////////////////////////////////////
8970
8971TypeInfo_t* TCling::MethodInfo_Type(MethodInfo_t* minfo) const
8972{
8973 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8974 return (TypeInfo_t*)info->Type();
8975}
8976
8977////////////////////////////////////////////////////////////////////////////////
8978
8979const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
8980{
8981 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8982 TTHREAD_TLS_DECL(TString, mangled_name);
8983 mangled_name = info->GetMangledName();
8984 return mangled_name;
8985}
8986
8987////////////////////////////////////////////////////////////////////////////////
8988
8989const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
8990{
8991 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8992 return info->GetPrototype();
8993}
8994
8995////////////////////////////////////////////////////////////////////////////////
8996
8997const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
8998{
8999 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9000 return info->Name();
9001}
9002
9003////////////////////////////////////////////////////////////////////////////////
9004
9005const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
9006{
9007 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9008 return info->TypeName();
9009}
9010
9011////////////////////////////////////////////////////////////////////////////////
9012
9013std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
9014{
9015 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9016 if (info && info->IsValid())
9017 return info->Type()->NormalizedName(*fNormalizedCtxt);
9018 else
9019 return "";
9020}
9021
9022////////////////////////////////////////////////////////////////////////////////
9023
9024const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
9025{
9026 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9027 return info->Title();
9028}
9029
9030////////////////////////////////////////////////////////////////////////////////
9031
9033{
9034 if (func) {
9035 return MethodInfo_MethodCallReturnType(func->fInfo);
9036 } else {
9037 return EReturnType::kOther;
9038 }
9039}
9040
9041////////////////////////////////////////////////////////////////////////////////
9042
9044{
9045 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9046 if (info && info->IsValid()) {
9047 TClingTypeInfo *typeinfo = info->Type();
9048 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
9049 if (QT->isEnumeralType()) {
9050 return EReturnType::kLong;
9051 } else if (QT->isPointerType()) {
9052 // Look for char*
9053 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
9054 if ( QT->isCharType() ) {
9055 return EReturnType::kString;
9056 } else {
9057 return EReturnType::kOther;
9058 }
9059 } else if ( QT->isFloatingType() ) {
9060 int sz = typeinfo->Size();
9061 if (sz == 4 || sz == 8) {
9062 // Support only float and double.
9063 return EReturnType::kDouble;
9064 } else {
9065 return EReturnType::kOther;
9066 }
9067 } else if ( QT->isIntegerType() ) {
9068 int sz = typeinfo->Size();
9069 if (sz <= 8) {
9070 // Support only up to long long ... but
9071 // FIXME the TMethodCall::Execute only
9072 // return long (4 bytes) ...
9073 // The v5 implementation of TMethodCall::ReturnType
9074 // was not making the distinction so we let it go
9075 // as is for now, but we really need to upgrade
9076 // TMethodCall::Execute ...
9077 return EReturnType::kLong;
9078 } else {
9079 return EReturnType::kOther;
9080 }
9081 } else {
9082 return EReturnType::kOther;
9083 }
9084 } else {
9085 return EReturnType::kOther;
9086 }
9087}
9088
9089//______________________________________________________________________________
9090//
9091// MethodArgInfo interface
9092//
9093
9094////////////////////////////////////////////////////////////////////////////////
9095
9096void TCling::MethodArgInfo_Delete(MethodArgInfo_t* marginfo) const
9097{
9098 delete(TClingMethodArgInfo*) marginfo;
9099}
9100
9101////////////////////////////////////////////////////////////////////////////////
9102
9103MethodArgInfo_t* TCling::MethodArgInfo_Factory() const
9104{
9106 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl());
9107}
9108
9109////////////////////////////////////////////////////////////////////////////////
9110
9111MethodArgInfo_t* TCling::MethodArgInfo_Factory(MethodInfo_t *minfo) const
9112{
9114 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl(), (TClingMethodInfo*)minfo);
9115}
9116
9117////////////////////////////////////////////////////////////////////////////////
9118
9119MethodArgInfo_t* TCling::MethodArgInfo_FactoryCopy(MethodArgInfo_t* marginfo) const
9120{
9121 return (MethodArgInfo_t*)
9123}
9124
9125////////////////////////////////////////////////////////////////////////////////
9126
9127bool TCling::MethodArgInfo_IsValid(MethodArgInfo_t* marginfo) const
9128{
9129 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9130 return info->IsValid();
9131}
9132
9133////////////////////////////////////////////////////////////////////////////////
9134
9135int TCling::MethodArgInfo_Next(MethodArgInfo_t* marginfo) const
9136{
9137 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9138 return info->Next();
9139}
9140
9141////////////////////////////////////////////////////////////////////////////////
9142
9143Long_t TCling::MethodArgInfo_Property(MethodArgInfo_t* marginfo) const
9144{
9145 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9146 return info->Property();
9147}
9148
9149////////////////////////////////////////////////////////////////////////////////
9150
9151const char* TCling::MethodArgInfo_DefaultValue(MethodArgInfo_t* marginfo) const
9152{
9153 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9154 return info->DefaultValue();
9155}
9156
9157////////////////////////////////////////////////////////////////////////////////
9158
9159const char* TCling::MethodArgInfo_Name(MethodArgInfo_t* marginfo) const
9160{
9161 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9162 return info->Name();
9163}
9164
9165////////////////////////////////////////////////////////////////////////////////
9166
9167const char* TCling::MethodArgInfo_TypeName(MethodArgInfo_t* marginfo) const
9168{
9169 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9170 return info->TypeName();
9171}
9172
9173////////////////////////////////////////////////////////////////////////////////
9174
9175std::string TCling::MethodArgInfo_TypeNormalizedName(MethodArgInfo_t* marginfo) const
9176{
9177 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9178 return info->Type()->NormalizedName(*fNormalizedCtxt);
9179}
9180
9181//______________________________________________________________________________
9182//
9183// TypeInfo interface
9184//
9185
9186////////////////////////////////////////////////////////////////////////////////
9187
9188void TCling::TypeInfo_Delete(TypeInfo_t* tinfo) const
9189{
9190 delete (TClingTypeInfo*) tinfo;
9191}
9192
9193////////////////////////////////////////////////////////////////////////////////
9194
9195TypeInfo_t* TCling::TypeInfo_Factory() const
9196{
9198 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl());
9199}
9200
9201////////////////////////////////////////////////////////////////////////////////
9202
9203TypeInfo_t* TCling::TypeInfo_Factory(const char *name) const
9204{
9206 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl(), name);
9207}
9208
9209////////////////////////////////////////////////////////////////////////////////
9210
9211TypeInfo_t* TCling::TypeInfo_FactoryCopy(TypeInfo_t* tinfo) const
9212{
9213 return (TypeInfo_t*) new TClingTypeInfo(*(TClingTypeInfo*)tinfo);
9214}
9215
9216////////////////////////////////////////////////////////////////////////////////
9217
9218void TCling::TypeInfo_Init(TypeInfo_t* tinfo, const char* name) const
9219{
9221 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9222 TClinginfo->Init(name);
9223}
9224
9225////////////////////////////////////////////////////////////////////////////////
9226
9227bool TCling::TypeInfo_IsValid(TypeInfo_t* tinfo) const
9228{
9229 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9230 return TClinginfo->IsValid();
9231}
9232
9233////////////////////////////////////////////////////////////////////////////////
9234
9235const char* TCling::TypeInfo_Name(TypeInfo_t* tinfo) const
9236{
9237 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9238 return TClinginfo->Name();
9239}
9240
9241////////////////////////////////////////////////////////////////////////////////
9242
9243Long_t TCling::TypeInfo_Property(TypeInfo_t* tinfo) const
9244{
9245 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9246 return TClinginfo->Property();
9247}
9248
9249////////////////////////////////////////////////////////////////////////////////
9250
9251int TCling::TypeInfo_RefType(TypeInfo_t* tinfo) const
9252{
9253 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9254 return TClinginfo->RefType();
9255}
9256
9257////////////////////////////////////////////////////////////////////////////////
9258
9259int TCling::TypeInfo_Size(TypeInfo_t* tinfo) const
9260{
9261 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9262 return TClinginfo->Size();
9263}
9264
9265////////////////////////////////////////////////////////////////////////////////
9266
9267const char* TCling::TypeInfo_TrueName(TypeInfo_t* tinfo) const
9268{
9269 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9270 return TClinginfo->TrueName(*fNormalizedCtxt);
9271}
9272
9273
9274//______________________________________________________________________________
9275//
9276// TypedefInfo interface
9277//
9278
9279////////////////////////////////////////////////////////////////////////////////
9280
9281void TCling::TypedefInfo_Delete(TypedefInfo_t* tinfo) const
9282{
9283 delete(TClingTypedefInfo*) tinfo;
9284}
9285
9286////////////////////////////////////////////////////////////////////////////////
9287
9288TypedefInfo_t* TCling::TypedefInfo_Factory() const
9289{
9291 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl());
9292}
9293
9294////////////////////////////////////////////////////////////////////////////////
9295
9296TypedefInfo_t* TCling::TypedefInfo_Factory(const char *name) const
9297{
9299 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl(), name);
9300}
9301
9302////////////////////////////////////////////////////////////////////////////////
9303
9304TypedefInfo_t* TCling::TypedefInfo_FactoryCopy(TypedefInfo_t* tinfo) const
9305{
9306 return (TypedefInfo_t*) new TClingTypedefInfo(*(TClingTypedefInfo*)tinfo);
9307}
9308
9309////////////////////////////////////////////////////////////////////////////////
9310
9311void TCling::TypedefInfo_Init(TypedefInfo_t* tinfo,
9312 const char* name) const
9313{
9315 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9316 TClinginfo->Init(name);
9317}
9318
9319////////////////////////////////////////////////////////////////////////////////
9320
9321bool TCling::TypedefInfo_IsValid(TypedefInfo_t* tinfo) const
9322{
9323 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9324 return TClinginfo->IsValid();
9325}
9326
9327////////////////////////////////////////////////////////////////////////////////
9328
9329Int_t TCling::TypedefInfo_Next(TypedefInfo_t* tinfo) const
9330{
9331 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9332 return TClinginfo->Next();
9333}
9334
9335////////////////////////////////////////////////////////////////////////////////
9336
9337Long_t TCling::TypedefInfo_Property(TypedefInfo_t* tinfo) const
9338{
9339 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9340 return TClinginfo->Property();
9341}
9342
9343////////////////////////////////////////////////////////////////////////////////
9344
9345int TCling::TypedefInfo_Size(TypedefInfo_t* tinfo) const
9346{
9347 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9348 return TClinginfo->Size();
9349}
9350
9351////////////////////////////////////////////////////////////////////////////////
9352
9353const char* TCling::TypedefInfo_TrueName(TypedefInfo_t* tinfo) const
9354{
9355 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9356 return TClinginfo->TrueName(*fNormalizedCtxt);
9357}
9358
9359////////////////////////////////////////////////////////////////////////////////
9360
9361const char* TCling::TypedefInfo_Name(TypedefInfo_t* tinfo) const
9362{
9363 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9364 return TClinginfo->Name();
9365}
9366
9367////////////////////////////////////////////////////////////////////////////////
9368
9369const char* TCling::TypedefInfo_Title(TypedefInfo_t* tinfo) const
9370{
9371 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9372 return TClinginfo->Title();
9373}
9374
9375////////////////////////////////////////////////////////////////////////////////
9376
9378{
9379 if (!fInitialMutex.back()) {
9380 if (fInitialMutex.back().fRecurseCount) {
9381 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
9382 }
9383 fInitialMutex.back().fState = mtx->GetStateBefore();
9384 }
9385 // We will "forget" this lock once we backed out of all interpreter frames.
9386 // Here we are entering one, so ++.
9387 ++fInitialMutex.back().fRecurseCount;
9388}
9389
9390////////////////////////////////////////////////////////////////////////////////
9391
9393{
9394 if (!fInitialMutex.back())
9395 return;
9396 if (fInitialMutex.back().fRecurseCount == 0) {
9397 Error("ForgetMutexState", "mutex state's recurse count already 0!");
9398 }
9399 else if (--fInitialMutex.back().fRecurseCount == 0) {
9400 // We have returned from all interpreter frames. Reset the initial lock state.
9401 fInitialMutex.back().fState.reset();
9402 }
9403}
9404
9405////////////////////////////////////////////////////////////////////////////////
9406/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
9407
9409{
9410 R__ASSERT(!fInitialMutex.empty() && "Inconsistent state of fInitialMutex!");
9411 if (gInterpreterMutex) {
9412 if (delta) {
9413 auto typedDelta = static_cast<TVirtualRWMutex::StateDelta *>(delta);
9414 std::unique_ptr<TVirtualRWMutex::StateDelta> uniqueP{typedDelta};
9415 gCoreMutex->Apply(std::move(uniqueP));
9416 }
9417 }
9418 fInitialMutex.pop_back();
9419}
9420
9421////////////////////////////////////////////////////////////////////////////////
9422/// Reset the interpreter lock to the state it had before interpreter-related
9423/// calls happened.
9424
9426{
9427 if (fInitialMutex.back()) {
9428 std::unique_ptr<TVirtualRWMutex::StateDelta> uniqueP = gCoreMutex->Rewind(*fInitialMutex.back().fState);
9429 // Need to start a new recurse count.
9430 fInitialMutex.emplace_back();
9431 return uniqueP.release();
9432 }
9433 // Need to start a new recurse count.
9434 fInitialMutex.emplace_back();
9435 return nullptr;
9436}
void Class()
Definition: Class.C:29
#define R__EXTERN
Definition: DllImport.h:27
The file contains utilities which are foundational and could be used across the core component of ROO...
#define d(i)
Definition: RSha256.hxx:102
#define f(i)
Definition: RSha256.hxx:104
#define c(i)
Definition: RSha256.hxx:101
#define R(a, b, c, d, e, f, g, h, i)
Definition: RSha256.hxx:110
#define e(i)
Definition: RSha256.hxx:103
const Ssiz_t kNPOS
Definition: RtypesCore.h:111
int Int_t
Definition: RtypesCore.h:41
short Version_t
Definition: RtypesCore.h:61
int Ssiz_t
Definition: RtypesCore.h:63
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
unsigned long ULong_t
Definition: RtypesCore.h:51
long Long_t
Definition: RtypesCore.h:50
bool Bool_t
Definition: RtypesCore.h:59
double Double_t
Definition: RtypesCore.h:55
long long Long64_t
Definition: RtypesCore.h:69
unsigned long long ULong64_t
Definition: RtypesCore.h:70
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
TClass *(* DictFuncPtr_t)()
Definition: Rtypes.h:78
R__EXTERN Int_t gDebug
Definition: Rtypes.h:91
R__EXTERN TApplication * gApplication
Definition: TApplication.h:166
R__EXTERN TClassTable * gClassTable
Definition: TClassTable.h:95
static void indent(ostringstream &buf, int indent_level)
The file contains facilities to work with C++ module files extensions used to store rdict files.
static bool requiresRootMap(const char *rootmapfile, cling::Interpreter *interp)
Definition: TCling.cxx:5224
static void * LazyFunctionCreatorAutoloadForModule(const std::string &mangled_name, cling::Interpreter *interp)
Definition: TCling.cxx:6507
static std::string ResolveSymbol(const std::string &mangled_name, cling::Interpreter *interp, bool searchSystem=true)
Definition: TCling.cxx:6410
void TCling__RestoreInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition: TCling.cxx:336
void TCling__FindLoadedLibraries(std::vector< std::pair< uint32_t, std::string > > &sLibraries, std::vector< std::string > &sPaths, cling::Interpreter &interpreter, bool searchSystem)
void * llvmLazyFunctionCreator(const std::string &mangled_name)
Autoload a library provided the mangled name of a missing symbol.
Definition: TCling.cxx:696
void TCling__TransactionRollback(const cling::Transaction &T)
Definition: TCling.cxx:574
static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
Definition: TCling.cxx:1168
static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
Definition: TCling.cxx:6991
void TCling__InvalidateGlobal(const clang::Decl *D)
Definition: TCling.cxx:569
bool TClingLookupHelper__AutoParse(const char *cname)
Allow calling autoparsing from TMetaUtils.
Definition: TCling.cxx:908
R__EXTERN int optind
Definition: TCling.cxx:320
void * TCling__LockCompilationDuringUserCodeExecution()
Lock the interpreter.
Definition: TCling.cxx:363
void TCling__UpdateListsOnUnloaded(const cling::Transaction &T)
Definition: TCling.cxx:564
void TCling__GetNormalizedContext(const ROOT::TMetaUtils::TNormalizedCtxt *&normCtxt)
Definition: TCling.cxx:552
R__DLLEXPORT clang::DeclContext * TCling__DEBUG__getDeclContext(clang::Decl *D)
Definition: TCling.cxx:218
static std::string GetModuleNameAsString(clang::Module *M, const clang::Preprocessor &PP)
Definition: TCling.cxx:1076
ETupleOrdering
Check in what order the member of a tuple are layout.
Definition: TCling.cxx:3675
bool TCling__LibraryLoadingFailed(const std::string &errmessage, const std::string &libStem, bool permanent, bool resolved)
Lookup libraries in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH with mangled_name, which is extracted by er...
Definition: TCling.cxx:346
static const std::unordered_set< std::string > gIgnoredPCMNames
List of dicts that have the PCM information already in the PCH.
Definition: TCling.cxx:1822
static Bool_t s_IsLibraryLoaded(const char *libname, cling::Interpreter *fInterpreter)
Definition: TCling.cxx:2956
static std::string AlternateTuple(const char *classname, const cling::LookupHelper &lh)
Definition: TCling.cxx:3717
R__DLLEXPORT void TCling__DEBUG__printName(clang::Decl *D)
Definition: TCling.cxx:239
R__DLLEXPORT void TCling__DEBUG__decl_dump(void *D)
Definition: TCling.cxx:236
bool TClingLookupHelper__ExistingTypeCheck(const std::string &tname, std::string &result)
Try hard to avoid looking up in the Cling database as this could enduce an unwanted autoparsing.
Definition: TCling.cxx:917
R__DLLEXPORT clang::NamespaceDecl * TCling__DEBUG__DCtoNamespace(clang::DeclContext *DC)
Definition: TCling.cxx:221
void TCling__UnlockCompilationDuringUserCodeExecution(void *)
Unlock the interpreter.
Definition: TCling.cxx:374
const char * TCling__GetClassSharedLibs(const char *className)
Definition: TCling.cxx:627
static uint32_t GNUHash(StringRef S)
Definition: TCling.cxx:6274
R__DLLEXPORT clang::RecordDecl * TCling__DEBUG__DCtoRecordDecl(clang::DeclContext *DC)
Definition: TCling.cxx:224
static bool R__InitStreamerInfoFactory()
Helper to initialize TVirtualStreamerInfo's factor early.
Definition: TCling.cxx:1548
int TCling__AutoParseCallback(const char *className)
Definition: TCling.cxx:622
static void ConstructorName(std::string &name, const clang::NamedDecl *decl, cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition: TCling.cxx:8618
int TCling_GenerateDictionary(const std::vector< std::string > &classes, const std::vector< std::string > &headers, const std::vector< std::string > &fwdDecls, const std::vector< std::string > &unknown)
Definition: TCling.cxx:706
R__DLLEXPORT bool TCling__TEST_isInvalidDecl(clang::Decl *D)
Definition: TCling.cxx:254
R__DLLEXPORT void DestroyInterpreter(TInterpreter *interp)
Definition: TCling.cxx:610
void TCling__LibraryUnloadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition: TCling.cxx:588
void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter *)
Definition: TCling.cxx:559
const Decl * TCling__GetObjectDecl(TObject *obj)
Definition: TCling.cxx:599
static ETupleOrdering IsTupleAscending()
Definition: TCling.cxx:3693
R__DLLEXPORT TInterpreter * CreateInterpreter(void *interpLibHandle, const char *argv[])
Definition: TCling.cxx:603
void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Definition: TCling.cxx:583
R__DLLEXPORT void TCling__DEBUG__dump(clang::DeclContext *DC)
Definition: TCling.cxx:227
static void TCling__UpdateClassInfo(const NamedDecl *TD)
Update TClingClassInfo for a class (e.g. upon seeing a definition).
Definition: TCling.cxx:384
int TCling__CompileMacro(const char *fileName, const char *options)
Definition: TCling.cxx:638
#define R__DLLEXPORT
Definition: TCling.cxx:145
void * TCling__ResetInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition: TCling.cxx:355
static std::string FindLibraryName(void(*func)())
Wrapper around dladdr (and friends)
Definition: TCling.cxx:1485
int TCling__AutoLoadCallback(const char *className)
Definition: TCling.cxx:617
static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
Definition: TCling.cxx:1046
static void RegisterCxxModules(cling::Interpreter &clingInterp)
Definition: TCling.cxx:1091
static bool IsFromRootCling()
Definition: TCling.cxx:1070
void TCling__PrintStackTrace()
Print a StackTrace!
Definition: TCling.cxx:329
static bool FindSymbol(const std::string &library_filename, const std::string &mangled_name, unsigned IgnoreSymbolFlags=0)
Looks up symbols from a an object file, representing the library.
Definition: TCling.cxx:6330
static int HandleInterpreterException(cling::MetaProcessor *metaProcessor, const char *input_line, cling::Interpreter::CompilationResult &compRes, cling::Value *result)
Let cling process a command line.
Definition: TCling.cxx:2281
static std::string GetSharedLibImmediateDepsSlow(std::string lib, cling::Interpreter *interp, bool skipLoadedLibs=true)
This interface returns a list of dependent libraries in the form: lib libA.so libB....
Definition: TCling.cxx:7148
static bool MayExistInObjectFile(llvm::object::ObjectFile *soFile, uint32_t hash)
Bloom filter in a stohastic data structure which can tell us if a symbol name does not exist in a lib...
Definition: TCling.cxx:6302
static clang::ClassTemplateDecl * FindTemplateInNamespace(clang::Decl *decl)
Find a template decl within N nested namespaces, 0<=N<inf Assumes 1 and only 1 template present and 1...
Definition: TCling.cxx:679
static void PrintDlError(const char *dyLibName, const char *modulename)
Definition: TCling.cxx:1846
const char * fantomline
Definition: TCling.cxx:855
void TCling__LibraryLoadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition: TCling.cxx:578
static cling::Interpreter::CompilationResult ExecAutoParse(const char *what, Bool_t header, cling::Interpreter *interpreter)
Parse the payload or header.
Definition: TCling.cxx:6017
static StringRef GetGnuHashSection(llvm::object::ObjectFile *file)
Definition: TCling.cxx:6281
TObject * TCling__GetObjectAddress(const char *Name, void *&LookupCtx)
Definition: TCling.cxx:595
static void LoadModules(const std::vector< std::string > &modules, cling::Interpreter &interp)
Loads the C++ modules that we require to run any ROOT program.
Definition: TCling.cxx:1064
int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition: TCling.cxx:633
void TCling__SplitAclicMode(const char *fileName, string &mode, string &args, string &io, string &fname)
Definition: TCling.cxx:645
EDataType
Definition: TDataType.h:28
@ kULong64_t
Definition: TDataType.h:32
@ kLong64_t
Definition: TDataType.h:32
@ kIsDestructor
Definition: TDictionary.h:125
@ kIsConversion
Definition: TDictionary.h:124
@ kIsInlined
Definition: TDictionary.h:127
@ kIsConstructor
Definition: TDictionary.h:123
@ kIsOperator
Definition: TDictionary.h:126
@ kIsPublic
Definition: TDictionary.h:74
@ kIsConstant
Definition: TDictionary.h:86
@ kIsConstMethod
Definition: TDictionary.h:93
@ kIsClass
Definition: TDictionary.h:65
@ kIsEnum
Definition: TDictionary.h:68
@ kIsPrivate
Definition: TDictionary.h:76
@ kIsFundamental
Definition: TDictionary.h:70
@ kIsCompiled
Definition: TDictionary.h:85
@ kIsStatic
Definition: TDictionary.h:79
@ kIsExplicit
Definition: TDictionary.h:91
@ kIsStruct
Definition: TDictionary.h:66
@ kIsProtected
Definition: TDictionary.h:75
@ kIsVirtual
Definition: TDictionary.h:72
@ kIsUnion
Definition: TDictionary.h:67
@ kIsPureVirtual
Definition: TDictionary.h:73
@ kIsNamespace
Definition: TDictionary.h:92
#define gDirectory
Definition: TDirectory.h:223
@ kEnvUser
Definition: TEnv.h:72
@ kEnvGlobal
Definition: TEnv.h:71
@ kEnvLocal
Definition: TEnv.h:73
#define R__ASSERT(e)
Definition: TError.h:96
void Info(const char *location, const char *msgfmt,...)
void Error(const char *location, const char *msgfmt,...)
const Int_t kWarning
Definition: TError.h:38
R__EXTERN Int_t gErrorIgnoreLevel
Definition: TError.h:105
void Warning(const char *location, const char *msgfmt,...)
void Fatal(const char *location, const char *msgfmt,...)
char name[80]
Definition: TGX11.cxx:109
int type
Definition: TGX11.cxx:120
R__EXTERN TVirtualMutex * gInterpreterMutex
Definition: TInterpreter.h:40
#define R__LOCKGUARD_CLING(mutex)
Definition: TInterpreter.h:47
R__EXTERN TInterpreter * gCling
Definition: TInterpreter.h:556
#define gInterpreter
Definition: TInterpreter.h:555
#define gROOT
Definition: TROOT.h:415
char * Form(const char *fmt,...)
typedef void((*Func_t)())
@ kReadPermission
Definition: TSystem.h:48
Bool_t R_ISREG(Int_t mode)
Definition: TSystem.h:119
R__EXTERN TSystem * gSystem
Definition: TSystem.h:560
R__EXTERN TVirtualMutex * gGlobalMutex
Definition: TVirtualMutex.h:29
#define R__LOCKGUARD(mutex)
#define R__WRITE_LOCKGUARD(mutex)
#define R__READ_LOCKGUARD(mutex)
const char * proto
Definition: civetweb.c:16604
#define free
Definition: civetweb.c:1539
#define snprintf
Definition: civetweb.c:1540
virtual std::unique_ptr< StateDelta > Rewind(const State &earlierState)=0
virtual void Apply(std::unique_ptr< StateDelta > &&delta)=0
virtual std::unique_ptr< State > GetStateBefore()=0
static Long_t ExecuteFile(const char *file, Int_t *error=0, Bool_t keep=kFALSE)
Execute a file containing a C++ macro (static method).
virtual TApplicationImp * GetApplicationImp()
Definition: TApplication.h:132
virtual Bool_t IsCmdThread()
Definition: TApplication.h:131
Each class (see TClass) has a linked list of its base class(es).
Definition: TBaseClass.h:33
TClassRef is used to implement a permanent reference to a TClass object.
Definition: TClassRef.h:29
static DictFuncPtr_t GetDict(const char *cname)
Given the class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProtoNorm(const char *cname)
Given the class normalized name returns the TClassProto object for the class.
static DictFuncPtr_t GetDictNorm(const char *cname)
Given the normalized class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProto(const char *cname)
Given the class name returns the TClassProto object for the class.
static Bool_t Check(const char *cname, std::string &normname)
static void Add(const char *cname, Version_t id, const std::type_info &info, DictFuncPtr_t dict, Int_t pragmabits)
Add a class to the class table (this is a static function).
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:75
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
Definition: TClass.cxx:3299
@ kLoading
Definition: TClass.h:298
@ kUnloading
Definition: TClass.h:298
EState GetState() const
Definition: TClass.h:458
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition: TClass.cxx:2824
EState fState
cached of the streaming method to use
Definition: TClass.h:242
std::atomic< TList * > fBase
Definition: TClass.h:176
static void AddClassToDeclIdMap(TDictionary::DeclId_t id, TClass *cl)
static: Add a TClass* to the map of classes.
Definition: TClass.cxx:467
Version_t fClassVersion
Definition: TClass.h:195
TList * GetListOfFunctionTemplates(Bool_t load=kTRUE)
Return list containing the TEnums of a class.
Definition: TClass.cxx:3641
void * DynamicCast(const TClass *base, void *obj, Bool_t up=kTRUE)
Cast obj of this class type up to baseclass cl if up is true.
Definition: TClass.cxx:4749
static void RemoveClassDeclId(TDictionary::DeclId_t id)
Definition: TClass.cxx:492
Bool_t CallShowMembers(const void *obj, TMemberInspector &insp, Bool_t isTransient=kFALSE) const
Call ShowMembers() on the obj of this class type, passing insp and parent.
Definition: TClass.cxx:2135
std::atomic< TListOfEnums * > fEnums
Definition: TClass.h:179
static Bool_t HasNoInfoOrEmuOrFwdDeclaredDecl(const char *)
Definition: TClass.cxx:3258
virtual void PostLoadCheck()
Do the initialization that can only be done after the CINT dictionary has been fully populated and ca...
Definition: TClass.cxx:5707
static TClass * LoadClass(const char *requestedname, Bool_t silent)
Helper function used by TClass::GetClass().
Definition: TClass.cxx:5499
Int_t Size() const
Return size of object of this class.
Definition: TClass.cxx:5454
TObjArray * fStreamerInfo
Definition: TClass.h:173
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition: TClass.cxx:5662
ClassInfo_t * GetClassInfo() const
Definition: TClass.h:404
ClassInfo_t * fClassInfo
Definition: TClass.h:196
Long_t Property() const
Set TObject::fBits and fStreamerType to cache information about the class.
Definition: TClass.cxx:5788
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition: TClass.cxx:2835
void ResetCaches()
To clean out all caches.
Definition: TClass.cxx:4058
static Int_t ReadRules()
Read the class.rules files from the default location:.
Definition: TClass.cxx:1750
@ kInterpreted
Definition: TClass.h:120
@ kHasTClassInit
Definition: TClass.h:121
@ kEmulated
Definition: TClass.h:119
@ kForwardDeclared
Definition: TClass.h:118
@ kNamespaceForMeta
Definition: TClass.h:125
Version_t GetClassVersion() const
Definition: TClass.h:391
std::atomic< Bool_t > fHasRootPcmInfo
C++ Property of the class (is abstract, has virtual table, etc.)
Definition: TClass.h:224
const char * GetDeclFileName() const
Return name of the file containing the declaration of this class.
Definition: TClass.cxx:3323
@ kIsTObject
Definition: TClass.h:93
@ kIsEmulation
Definition: TClass.h:95
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2906
Emulation of the CINT BaseClassInfo class.
const char * TmpltName() const
const char * Name() const
ptrdiff_t Offset(void *address=0, bool isDerivedObject=true) const
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
TClingClassInfo * GetBase() const
Emulation of the CINT CallFunc class.
long ExecInt(void *address)
void SetArgs(const char *args)
void SetFunc(const TClingClassInfo *info, const char *method, const char *arglist, long *poffset)
void * InterfaceMethod()
void ExecWithArgsAndReturn(void *address, const void *args[]=0, int nargs=0, void *ret=0)
void Exec(void *address, TInterpreterValue *interpVal=0)
TClingMethodInfo * FactoryMethod() const
void SetAutoloadingEnabled(bool val=true)
bool IsAutoloadingEnabled()
void SetAutoParsingSuspended(bool val=true)
Emulation of the CINT ClassInfo class.
bool HasDefaultConstructor() const
const char * Title()
static bool IsEnum(cling::Interpreter *interp, const char *name)
long ClassProperty() const
void Init(const char *name)
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
long Property() const
EDataType GetUnderlyingType() const
TClingMethodInfo GetMethodWithArgs(const char *fname, const char *arglist, long *poffset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch, EInheritanceMode imode=kWithInheritance) const
const char * TmpltName() const
const clang::Type * GetType() const
ptrdiff_t GetBaseOffset(TClingClassInfo *toBase, void *address, bool isDerivedObject)
bool IsScopedEnum() const
const clang::FunctionTemplateDecl * GetFunctionTemplate(const char *fname) const
int GetMethodNArg(const char *method, const char *proto, Bool_t objectIsConst, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
bool HasMethod(const char *name) const
TDictionary::DeclId_t GetDeclId() const
void DeleteArray(void *arena, bool dtorOnly, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
void * New(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
bool IsValidMethod(const char *method, const char *proto, Bool_t objectIsConst, long *offset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
TClingMethodInfo GetMethod(const char *fname) const
bool IsLoaded() const
const clang::ValueDecl * GetDataMember(const char *name) const
void Destruct(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
std::vector< std::string > GetUsingNamespaces()
const char * FileName()
bool IsBase(const char *name) const
void Delete(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Emulation of the CINT DataMemberInfo class.
const char * TypeName() const
const char * TypeTrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
const char * Name() override
int MaxIndex(int dim) const
llvm::StringRef ValidArrayIndex() const
virtual const char * Name()
virtual bool IsValid() const
virtual const clang::Decl * GetDecl() const
Emulation of the CINT MethodInfo class.
bool IsValid() const override
const char * DefaultValue() const
const TClingTypeInfo * Type() const
const char * TypeName() const
Emulation of the CINT MethodInfo class.
const char * Name() override
std::string GetMangledName() const
const char * TypeName() const
void * InterfaceMethod(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
const char * GetPrototype()
const clang::FunctionDecl * GetMethodDecl() const
long ExtraProperty() const
void CreateSignature(TString &signature) const
const char * Title()
TDictionary::DeclId_t GetDeclId() const
TClingTypeInfo * Type() const
Emulation of the CINT TypeInfo class.
long Property() const
bool IsValid() const
std::string NormalizedName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
int Size() const
int RefType() const
const char * Name() const
clang::QualType GetQualType() const
void Init(const char *name)
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
Emulation of the CINT TypedefInfo class.
const char * Name() override
Get the name of the current typedef.
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Get the name of the underlying type of the current typedef.
long Property() const
Return a bit mask of metadata about the current typedef.
void Init(const char *name)
Lookup named typedef and reset the iterator to point to it.
int Next()
Increment the iterator.
int Size() const
Return the size in bytes of the underlying type of the current typedef.
Bridge between cling::Value and ROOT.
Definition: TClingValue.h:34
const char * Data()
Definition: TCling.cxx:1022
bool Append(const std::string &str)
Append string to the storage if not added already.
Definition: TCling.cxx:1030
std::string fContent
Definition: TCling.h:596
This class defines an interface to the cling C++ interpreter.
Definition: TCling.h:99
virtual const char * MethodArgInfo_DefaultValue(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:9151
virtual std::string CallFunc_GetWrapperCode(CallFunc_t *func) const
Definition: TCling.cxx:8013
virtual void FuncTempInfo_Name(FuncTempInfo_t *, TString &name) const
Return the name of this function template.
Definition: TCling.cxx:8822
virtual void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const
Return the comments associates with this function template.
Definition: TCling.cxx:8835
virtual int TypedefInfo_Next(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:9329
virtual bool DiagnoseIfInterpreterException(const std::exception &e) const
Definition: TCling.cxx:2300
virtual bool ClassInfo_IsValid(ClassInfo_t *info) const
Definition: TCling.cxx:8206
virtual bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const
Definition: TCling.cxx:8180
Long_t Calc(const char *line, EErrorCode *error=0)
Directly execute an executable statement (e.g.
Definition: TCling.cxx:3365
Bool_t HasPCMForLibrary(const char *libname) const
Return true if ROOT has cxxmodules pcm for a given library name.
Definition: TCling.cxx:2974
virtual MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const
Definition: TCling.cxx:8908
virtual const char * TypeInfo_Name(TypeInfo_t *) const
Definition: TCling.cxx:9235
DeclId_t GetFunction(ClassInfo_t *cl, const char *funcname)
Return pointer to cling interface function for a method of a class with a certain name.
Definition: TCling.cxx:4740
bool LibraryLoadingFailed(const std::string &, const std::string &, bool, bool)
Definition: TCling.cxx:6253
void ForgetMutexState()
Definition: TCling.cxx:9392
virtual bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const
Definition: TCling.cxx:8139
std::vector< void * > fRegisterModuleDyLibs
Definition: TCling.h:136
virtual MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const
Definition: TCling.cxx:7825
virtual bool MethodInfo_IsValid(MethodInfo_t *minfo) const
Definition: TCling.cxx:8923
std::vector< std::string > fAutoLoadLibStorage
Definition: TCling.h:116
Bool_t fLockProcessLine
Definition: TCling.h:125
virtual const char * DataMemberInfo_TypeTrueName(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8568
void CreateListOfDataMembers(TClass *cl) const
Create list of pointers to data members for TClass cl.
Definition: TCling.cxx:4206
void UnRegisterTClassUpdate(const TClass *oldcl)
If the dictionary is loaded, we can remove the class from the list (otherwise the class might be load...
Definition: TCling.cxx:2251
void HandleNewDecl(const void *DV, bool isDeserialized, std::set< TClass * > &modifiedClasses)
Definition: TCling.cxx:491
void InvalidateCachedDecl(const std::tuple< TListOfDataMembers *, TListOfFunctions *, TListOfFunctionTemplates *, TListOfEnums * > &Lists, const clang::Decl *D)
Invalidate cached TCling information for the given declaration, and removed it from the appropriate o...
Definition: TCling.cxx:6888
virtual const char * MethodInfo_TypeName(MethodInfo_t *minfo) const
Definition: TCling.cxx:9005
bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const
Definition: TCling.cxx:1784
virtual Long_t TypedefInfo_Property(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:9337
virtual void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:9096
virtual void LoadFunctionTemplates(TClass *cl) const
Create list of pointers to function templates for TClass cl.
Definition: TCling.cxx:4159
virtual CallFunc_t * CallFunc_Factory() const
Definition: TCling.cxx:7810
virtual TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:9304
std::vector< const char * > fCurExecutingMacros
Definition: TCling.h:147
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition: TCling.cxx:6762
virtual void SetAllocunlockfunc(void(*)()) const
[Place holder for Mutex Unlock] Provide the interpreter with a way to release a lock used to protect ...
Definition: TCling.cxx:7471
virtual Long_t ClassInfo_Tagnum(ClassInfo_t *info) const
Definition: TCling.cxx:8286
void UpdateListOfTypes()
No op: see TClingCallbacks (used to update the list of types)
Definition: TCling.cxx:3669
const char * GetSharedLibDeps(const char *lib, bool tryDyld=false)
Get the list a libraries on which the specified lib depends.
Definition: TCling.cxx:7235
virtual DeclId_t GetDataMemberAtAddr(const void *addr) const
Return pointer to cling DeclId for a data member with a given name.
Definition: TCling.cxx:4661
virtual int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8462
virtual bool ClassInfo_IsBase(ClassInfo_t *info, const char *name) const
Definition: TCling.cxx:8165
virtual int BaseClassInfo_Next(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:8370
virtual void GenericError(const char *error) const
Let the interpreter issue a generic error, and set its error state.
Definition: TCling.cxx:7384
virtual std::string MethodArgInfo_TypeNormalizedName(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:9175
virtual const char * ClassInfo_TmpltName(ClassInfo_t *info) const
Definition: TCling.cxx:8328
virtual TEnum * CreateEnum(void *VD, TClass *cl) const
Definition: TCling.cxx:464
virtual EReturnType MethodCallReturnType(TFunction *func) const
Definition: TCling.cxx:9032
virtual int UnloadFile(const char *path) const
Definition: TCling.cxx:7551
virtual int Evaluate(const char *, TInterpreterValue &)
Get the interpreter value corresponding to the statement.
Definition: TCling.cxx:7579
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition: TCling.cxx:7615
virtual Long_t TypeInfo_Property(TypeInfo_t *tinfo) const
Definition: TCling.cxx:9243
DeclId_t GetFunctionWithPrototype(ClassInfo_t *cl, const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
Return pointer to cling interface function for a method of a class with a certain prototype,...
Definition: TCling.cxx:4859
void InvalidateGlobal(const clang::Decl *D)
Invalidate cached TCling information for the given global declaration.
Definition: TCling.cxx:6873
void EndOfLineAction()
It calls a "fantom" method to synchronize user keyboard input and ROOT prompt line.
Definition: TCling.cxx:2948
DeclId_t GetFunctionWithValues(ClassInfo_t *cl, const char *method, const char *params, Bool_t objectIsConst=kFALSE)
Return pointer to cling DeclId for a method of a class with a certain prototype, i....
Definition: TCling.cxx:4837
void UpdateListOfLoadedSharedLibraries()
Definition: TCling.cxx:3133
void RegisterModule(const char *modulename, const char **headers, const char **includePaths, const char *payloadCode, const char *fwdDeclsCode, void(*triggerFunc)(), const FwdDeclArgsToKeepCollection_t &fwdDeclsArgToSkip, const char **classesHeaders, Bool_t lateRegistration=false, Bool_t hasCxxModule=false)
Inject the module named "modulename" into cling; load all headers.
Definition: TCling.cxx:1892
virtual const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8592
void InitRootmapFile(const char *name)
Create a resource table and read the (possibly) three resource files, i.e $ROOTSYS/etc/system<name> (...
Definition: TCling.cxx:5361
void CreateListOfMethodArgs(TFunction *m) const
Create list of pointers to method arguments for TMethod m.
Definition: TCling.cxx:4240
virtual void TypedefInfo_Init(TypedefInfo_t *tinfo, const char *name) const
Definition: TCling.cxx:9311
virtual Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const
Definition: TCling.cxx:8963
void LoadPCM(std::string pcmFileNameFullPath)
Tries to load a rdict PCM, issues diagnostics if it fails.
Definition: TCling.cxx:1695
virtual ~TCling()
Destroy the interpreter interface.
Definition: TCling.cxx:1450
void AddFriendToClass(clang::FunctionDecl *, clang::CXXRecordDecl *) const
Inject function as a friend into klass.
Definition: TCling.cxx:7668
std::vector< MutexStateAndRecurseCount > fInitialMutex
Definition: TCling.h:165
Bool_t fCxxModulesEnabled
Definition: TCling.h:126
void RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
Internal function. Actually do the update of the ClassInfo when seeing.
Definition: TCling.cxx:6635
void ExecuteWithArgsAndReturn(TMethod *method, void *address, const void *args[]=0, int nargs=0, void *ret=0) const
Definition: TCling.cxx:5089
virtual void FuncTempInfo_Delete(FuncTempInfo_t *) const
Delete the FuncTempInfo_t.
Definition: TCling.cxx:8672
Bool_t SetSuspendAutoParsing(Bool_t value)
Suspend the Autoparsing of headers.
Definition: TCling.cxx:7521
virtual DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8496
virtual CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const
Definition: TCling.cxx:7859
virtual void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const
Definition: TCling.cxx:7767
virtual MethodArgInfo_t * MethodArgInfo_Factory() const
Definition: TCling.cxx:9103
virtual void DataMemberInfo_Delete(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8470
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition: TCling.cxx:9408
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition: TCling.cxx:6533
virtual int LoadFile(const char *path) const
Load a source file or library called path into the interpreter.
Definition: TCling.cxx:7427
void CodeComplete(const std::string &, size_t &, std::vector< std::string > &)
The call to Cling's tab complition.
Definition: TCling.cxx:7571
virtual int SetClassAutoloading(int) const
Enable/Disable the Autoloading of libraries.
Definition: TCling.cxx:7492
virtual Long_t FuncTempInfo_Property(FuncTempInfo_t *) const
Return the property of the function template.
Definition: TCling.cxx:8736
virtual TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const
Definition: TCling.cxx:8971
virtual const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:9167
Bool_t HandleNewTransaction(const cling::Transaction &T)
Helper function to increase the internal Cling count of transactions that change the AST.
Definition: TCling.cxx:3435
virtual bool DataMemberInfo_IsValid(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8504
int ReadRootmapFile(const char *rootmapfile, TUniqueString *uniqueString=nullptr)
Read and parse a rootmapfile in its new format, and return 0 in case of success, -1 if the file has a...
Definition: TCling.cxx:5240
Bool_t IsLoaded(const char *filename) const
Return true if the file has already been loaded by cint.
Definition: TCling.cxx:2993
const char * GetSharedLibs()
Return the list of shared libraries loaded into the process.
Definition: TCling.cxx:6985
virtual const char * GetTopLevelMacroName() const
Return the file name of the current un-included interpreted file.
Definition: TCling.cxx:5120
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition: TCling.h:151
virtual DeclId_t GetDataMemberWithValue(const void *ptrvalue) const
NOT IMPLEMENTED.
Definition: TCling.cxx:4652
virtual bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:9127
Int_t ReloadAllSharedLibraryMaps()
Reload the library map entries coming from all the loaded shared libraries, after first unloading the...
Definition: TCling.cxx:5628
virtual void SetErrmsgcallback(void *p) const
Set a callback to receive error messages.
Definition: TCling.cxx:7531
virtual std::string ToString(const char *type, void *obj)
Definition: TCling.cxx:1039
virtual const char * MethodInfo_Title(MethodInfo_t *minfo) const
Definition: TCling.cxx:9024
virtual Long_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const
Definition: TCling.cxx:8394
virtual int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8552
virtual ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const
Definition: TCling.cxx:8093
virtual const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const
Definition: TCling.cxx:8979
virtual bool CallFunc_IsValid(CallFunc_t *func) const
Definition: TCling.cxx:7850
virtual const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:8449
virtual void SetAlloclockfunc(void(*)()) const
[Place holder for Mutex Lock] Provide the interpreter with a way to acquire a lock used to protect cr...
Definition: TCling.cxx:7461
virtual void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const
Definition: TCling.cxx:8874
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx)
Definition: TCling.cxx:9377
virtual Bool_t ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const
Return true if the entity pointed to by 'declid' is declared in the context described by 'info'.
Definition: TCling.cxx:8032
std::set< size_t > fPayloads
Definition: TCling.h:120
virtual const char * ClassInfo_Name(ClassInfo_t *info) const
Definition: TCling.cxx:8312
Int_t UnloadLibraryMap(const char *library)
Unload library map entries coming from the specified library.
Definition: TCling.cxx:5707
virtual ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const
Definition: TCling.cxx:8415
TObjArray * fRootmapFiles
Definition: TCling.h:124
virtual void CallFunc_Delete(CallFunc_t *func) const
Definition: TCling.cxx:7744
virtual Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const
Definition: TCling.cxx:8054
cling::Interpreter * GetInterpreterImpl() const
Definition: TCling.h:623
virtual bool ClassInfo_IsLoaded(ClassInfo_t *info) const
Definition: TCling.cxx:8198
std::vector< std::pair< TClass *, DictFuncPtr_t > > fClassesToUpdate
Definition: TCling.h:144
virtual int ClassInfo_GetMethodNArg(ClassInfo_t *info, const char *method, const char *proto, Bool_t objectIsConst=false, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
Definition: TCling.cxx:8123
Int_t DeleteGlobal(void *obj)
Delete obj from Cling symbol table so it cannot be accessed anymore.
Definition: TCling.cxx:3553
virtual const char * GetCurrentMacroName() const
Return the file name of the currently interpreted file, included or not.
Definition: TCling.cxx:5167
virtual void TypeInfo_Delete(TypeInfo_t *tinfo) const
Definition: TCling.cxx:9188
virtual Bool_t LoadText(const char *text) const
Load the declarations from text into the interpreter.
Definition: TCling.cxx:7440
void GetInterpreterTypeName(const char *name, std::string &output, Bool_t full=kFALSE)
The 'name' is known to the interpreter, this function returns the internal version of this name (usua...
Definition: TCling.cxx:4904
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition: TCling.cxx:9425
virtual Long_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const
Definition: TCling.cxx:8386
static Int_t DeepAutoLoadImpl(const char *cls)
Definition: TCling.cxx:5893
virtual int GetSecurityError() const
Interface to cling function.
Definition: TCling.cxx:7414
virtual UInt_t FuncTempInfo_TemplateMinReqArgs(FuncTempInfo_t *) const
Return the number of required template arguments of the function template described by ft_info.
Definition: TCling.cxx:8726
void ResetGlobals()
Reset in Cling the list of global variables to the state saved by the last call to TCling::SaveGlobal...
Definition: TCling.cxx:3510
virtual const char * ClassInfo_Title(ClassInfo_t *info) const
Definition: TCling.cxx:8320
bool IsClassAutoloadingEnabled() const
Returns if class autoloading is currently enabled.
Definition: TCling.cxx:7479
virtual Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:8407
virtual FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const
Construct a FuncTempInfo_t.
Definition: TCling.cxx:8681
void * GetInterfaceMethod(TClass *cl, const char *method, const char *params, Bool_t objectIsConst=kFALSE)
Return pointer to cling interface function for a method of a class with parameters params (params is ...
Definition: TCling.cxx:4718
virtual void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const
Definition: TCling.cxx:8085
virtual const char * BaseClassInfo_FullName(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:8431
virtual bool ClassInfo_IsEnum(const char *name) const
Definition: TCling.cxx:8173
Long_t ProcessLine(const char *line, EErrorCode *error=0)
Definition: TCling.cxx:2311
virtual void GetFunctionName(const clang::FunctionDecl *decl, std::string &name) const
Definition: TCling.cxx:8640
virtual void TypedefInfo_Delete(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:9281
void SetGetline(const char *(*getlineFunc)(const char *prompt), void(*histaddFunc)(const char *line))
Set a getline function to call when input is needed.
Definition: TCling.cxx:3418
Int_t fGlobalsListSerial
Definition: TCling.h:112
void RewindDictionary()
Rewind Cling dictionary to the point where it was before executing the current macro.
Definition: TCling.cxx:3539
TString fSharedLibs
Definition: TCling.h:111
std::map< std::string, llvm::StringRef > fPendingRdicts
Definition: TCling.h:613
virtual const char * MapCppName(const char *) const
Interface to cling function.
Definition: TCling.cxx:7448
static void UpdateClassInfoWork(const char *name)
Definition: TCling.cxx:6742
virtual Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition: TCling.cxx:8796
void PrintIntro()
No-op; see TRint instead.
Definition: TCling.cxx:2475
virtual CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const
Definition: TCling.cxx:7818
virtual const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8576
Bool_t Declare(const char *code)
Declare code to the interpreter, without any of the interpreter actions that could trigger a re-inter...
Definition: TCling.cxx:2903
Int_t DeleteVariable(const char *name)
Undeclare obj called name.
Definition: TCling.cxx:3568
virtual int ClassInfo_Next(ClassInfo_t *info) const
Definition: TCling.cxx:8230
static void * fgSetOfSpecials
Definition: TCling.h:102
void AddIncludePath(const char *path)
Add the given path to the list of directories in which the interpreter looks for include files.
Definition: TCling.cxx:2484
virtual void CallFunc_SetArgArray(CallFunc_t *func, Long_t *paramArr, Int_t nparam) const
Definition: TCling.cxx:7923
virtual const char * MethodInfo_Name(MethodInfo_t *minfo) const
Definition: TCling.cxx:8997
void ClearFileBusy()
Reset the interpreter internal state in case a previous action was not correctly terminated.
Definition: TCling.cxx:2882
virtual const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:9159
virtual Long_t ClassInfo_Property(ClassInfo_t *info) const
Definition: TCling.cxx:8270
Int_t fMore
Definition: TCling.h:106
ROOT::TMetaUtils::TNormalizedCtxt * fNormalizedCtxt
Definition: TCling.h:132
virtual int MethodInfo_Next(MethodInfo_t *minfo) const
Definition: TCling.cxx:8947
const char * TypeName(const char *typeDesc)
Return the absolute type of typeDesc.
Definition: TCling.cxx:5182
bool fIsShuttingDown
Definition: TCling.h:178
void SaveContext()
Save the current Cling state.
Definition: TCling.cxx:3629
std::set< TClass * > & GetModTClasses()
Definition: TCling.h:556
virtual bool TypeInfo_IsValid(TypeInfo_t *tinfo) const
Definition: TCling.cxx:9227
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE)
Load library containing the specified class.
Definition: TCling.cxx:5954
TClingCallbacks * fClingCallbacks
Definition: TCling.h:137
TString GetMangledNameWithPrototype(TClass *cl, const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
Return the cling mangled name for a method of a class with a certain prototype, i....
Definition: TCling.cxx:4700
void RegisterTClassUpdate(TClass *oldcl, DictFuncPtr_t dict)
Register classes that already existed prior to their dictionary loading and that already had a ClassI...
Definition: TCling.cxx:2242
virtual Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8536
void UpdateListOfGlobalFunctions()
No op: see TClingCallbacks (used to update the list of global functions)
Definition: TCling.cxx:3662
virtual const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const
Definition: TCling.cxx:8989
TString fIncludePath
Definition: TCling.h:113
virtual bool ClassInfo_IsValidMethod(ClassInfo_t *info, const char *method, const char *proto, Long_t *offset, ROOT::EFunctionMatchMode=ROOT::kConversionMatch) const
Definition: TCling.cxx:8214
virtual void * ClassInfo_New(ClassInfo_t *info) const
Definition: TCling.cxx:8238
virtual void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const
Definition: TCling.cxx:9218
Bool_t SetErrorMessages(Bool_t enable=kTRUE)
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition: TCling.cxx:7284
virtual const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8584
void TransactionRollback(const cling::Transaction &T)
Definition: TCling.cxx:6948
virtual EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const
Definition: TCling.cxx:8189
virtual void CallFunc_Init(CallFunc_t *func) const
Definition: TCling.cxx:7841
virtual UInt_t FuncTempInfo_TemplateNargs(FuncTempInfo_t *) const
Return the maximum number of template arguments of the function template described by ft_info.
Definition: TCling.cxx:8715
TString GetMangledName(TClass *cl, const char *method, const char *params, Bool_t objectIsConst=kFALSE)
Return the cling mangled name for a method of a class with parameters params (params is a string of a...
Definition: TCling.cxx:4673
virtual void SetTempLevel(int val) const
Create / close a scope for temporaries.
Definition: TCling.cxx:7545
virtual DeclId_t GetDataMember(ClassInfo_t *cl, const char *name) const
Return pointer to cling Decl of global/static variable that is located at the address given by addr.
Definition: TCling.cxx:4483
void RegisterTemporary(const TInterpreterValue &value)
Definition: TCling.cxx:7588
virtual void LoadEnums(TListOfEnums &cl) const
Create list of pointers to enums for TClass cl.
Definition: TCling.cxx:4112
virtual void CallFunc_SetArg(CallFunc_t *func, Long_t param) const
Definition: TCling.cxx:7875
virtual Long_t GetExecByteCode() const
This routines used to return the address of the internal wrapper function (of the interpreter) that w...
Definition: TCling.cxx:7406
virtual void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const
Definition: TCling.cxx:8915
Int_t UnloadAllSharedLibraryMaps()
Unload the library map entries coming from all the loaded shared libraries.
Definition: TCling.cxx:5689
virtual void CallFunc_IgnoreExtraArgs(CallFunc_t *func, bool ignore) const
Definition: TCling.cxx:7833
std::vector< cling::Value > * fTemporaries
Definition: TCling.h:131
virtual Long_t MethodInfo_Property(MethodInfo_t *minfo) const
Definition: TCling.cxx:8955
virtual std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const
Definition: TCling.cxx:7564
virtual Long_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8528
static Int_t ShallowAutoLoadImpl(const char *cls)
Definition: TCling.cxx:5847
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition: TCling.cxx:6971
virtual TypedefInfo_t * TypedefInfo_Factory() const
Definition: TCling.cxx:9288
void UpdateListOfGlobals()
No op: see TClingCallbacks (used to update the list of globals)
Definition: TCling.cxx:3655
void ClearStack()
Delete existing temporary values.
Definition: TCling.cxx:2890
std::map< const cling::Transaction *, size_t > fTransactionHeadersMap
Definition: TCling.h:118
virtual int SetClassAutoparsing(int)
Enable/Disable the Autoparsing of headers.
Definition: TCling.cxx:7510
Bool_t fHeaderParsingOnDemand
Definition: TCling.h:172
Int_t RescanLibraryMap()
Scan again along the dynamic path for library maps.
Definition: TCling.cxx:5616
virtual int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8520
void Reset()
Pressing Ctrl+C should forward here.
Definition: TCling.cxx:3478
Int_t Load(const char *filenam, Bool_t system=kFALSE)
Load a library file in cling's memory.
Definition: TCling.cxx:3295
void InspectMembers(TMemberInspector &, const void *obj, const TClass *cl, Bool_t isTransient)
Visit all members over members, recursing over base classes.
Definition: TCling.cxx:2498
std::hash< std::string > fStringHashFunction
Definition: TCling.h:122
TEnv * fMapfile
Definition: TCling.h:115
const char * GetIncludePath()
Refresh the list of include paths known to the interpreter and return it with -I prepended.
Definition: TCling.cxx:7298
static void RemoveAndInvalidateObject(List &L, Object *O)
Definition: TCling.h:568
virtual void ClassInfo_DeleteArray(ClassInfo_t *info, void *arena, bool dtorOnly) const
Definition: TCling.cxx:8077
Long_t ExecuteMacro(const char *filename, EErrorCode *error=0)
Execute a cling macro.
Definition: TCling.cxx:5107
virtual DeclId_t GetEnum(TClass *cl, const char *name) const
Return pointer to cling Decl of global/static variable that is located at the address given by addr.
Definition: TCling.cxx:4543
void GetFunctionOverloads(ClassInfo_t *cl, const char *funcname, std::vector< DeclId_t > &res) const
Insert overloads of name in cl to res.
Definition: TCling.cxx:4759
virtual void CallFunc_Exec(CallFunc_t *func, void *address) const
Definition: TCling.cxx:7751
virtual int DisplayIncludePath(FILE *fout) const
Interface to cling function.
Definition: TCling.cxx:7347
void RegisterLoadedSharedLibrary(const char *name)
Register a new shared library name with the interpreter; add it to fSharedLibs.
Definition: TCling.cxx:3214
virtual void UpdateEnumConstants(TEnum *enumObj, TClass *cl) const
Definition: TCling.cxx:416
void SaveGlobalsContext()
Save the current Cling state of global objects.
Definition: TCling.cxx:3642
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition: TCling.h:123
void ProcessClassesToUpdate()
Definition: TCling.cxx:1862
virtual Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:9143
virtual const char * GetSTLIncludePath() const
Return the directory containing CINT's stl cintdlls.
Definition: TCling.cxx:7329
TString fRootmapLoadPath
Definition: TCling.h:114
Int_t LoadLibraryMap(const char *rootmapfile=0)
Load map between class and library.
Definition: TCling.cxx:5432
virtual std::string MethodInfo_TypeNormalizedName(MethodInfo_t *minfo) const
Definition: TCling.cxx:9013
void Execute(const char *function, const char *params, int *error=0)
Execute a global function with arguments params.
Definition: TCling.cxx:4937
virtual const char * ClassInfo_FullName(ClassInfo_t *info) const
Definition: TCling.cxx:8302
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE)
Generate a TClass for the given class.
Definition: TCling.cxx:4263
virtual int TypeInfo_Size(TypeInfo_t *tinfo) const
Definition: TCling.cxx:9259
virtual int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:9135
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition: TCling.h:133
virtual bool ClassInfo_HasDefaultConstructor(ClassInfo_t *info) const
Definition: TCling.cxx:8131
virtual const char * TypedefInfo_TrueName(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:9353
Bool_t fIsAutoParsingSuspended
Definition: TCling.h:173
TClass * GetClass(const std::type_info &typeinfo, Bool_t load) const
Demangle the name (from the typeinfo) and then request the class via the usual name based interface (...
Definition: TCling.cxx:5801
DeclId_t GetDeclId(const llvm::GlobalValue *gv) const
Return pointer to cling DeclId for a global value.
Definition: TCling.cxx:4583
Long_t ProcessLineAsynch(const char *line, EErrorCode *error=0)
Let cling process a command line asynch.
Definition: TCling.cxx:3340
virtual std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const
Get the scopes representing using declarations of namespace.
Definition: TCling.cxx:4195
Int_t SetClassSharedLibs(const char *cls, const char *libs)
Register the autoloading information for a class.
Definition: TCling.cxx:5769
virtual void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const
Definition: TCling.cxx:8147
virtual TypeInfo_t * TypeInfo_FactoryCopy(TypeInfo_t *) const
Definition: TCling.cxx:9211
Bool_t CheckClassTemplate(const char *name)
Return true if there is a class template by the given name ...
Definition: TCling.cxx:4068
void LoadPCMImpl(TFile &pcmFile)
Tries to load a PCM from TFile; returns true on success.
Definition: TCling.cxx:1580
Bool_t IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition: TCling.cxx:6627
TObjArray * GetRootMapFiles() const
Definition: TCling.h:216
char fPrompt[64]
Definition: TCling.h:108
void * fPrevLoadedDynLibInfo
Definition: TCling.h:135
void UpdateListOfDataMembers(TClass *cl) const
Update the list of pointers to data members for TClass cl This is now a nop.
Definition: TCling.cxx:4233
virtual void SetDeclAttr(DeclId_t, const char *)
Definition: TCling.cxx:8603
virtual Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8544
virtual void ShutDown()
Definition: TCling.cxx:1476
virtual const char * DataMemberInfo_TypeName(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8560
virtual void CallFunc_SetArgs(CallFunc_t *func, const char *param) const
Definition: TCling.cxx:7931
virtual const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:8441
virtual void MethodInfo_Delete(MethodInfo_t *minfo) const
Interface to cling function.
Definition: TCling.cxx:8867
virtual const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const
Definition: TCling.cxx:9267
std::set< const char * > fParsedPayloadsAddresses
Definition: TCling.h:121
ECheckClassInfo CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly=kFALSE)
Checks if an entity with the specified name is defined in Cling.
Definition: TCling.cxx:3913
void EnableAutoLoading()
Enable the automatic loading of shared libraries when a class is used that is stored in a not yet loa...
Definition: TCling.cxx:2928
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition: TCling.cxx:6736
virtual void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:8343
void ResetGlobalVar(void *obj)
Reset the Cling 'user' global objects/variables state to the state saved by the last call to TCling::...
Definition: TCling.cxx:3524
std::unique_ptr< cling::Interpreter > fInterpreter
Definition: TCling.h:128
Bool_t IsLibraryLoaded(const char *libname) const
Definition: TCling.cxx:2965
virtual void Initialize()
Initialize the interpreter, once TROOT::fInterpreter is set.
Definition: TCling.cxx:1468
virtual void * FindSym(const char *entry) const
Interface to cling function.
Definition: TCling.cxx:7376
virtual Long_t CallFunc_ExecInt(CallFunc_t *func, void *address) const
Definition: TCling.cxx:7786
virtual int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const
Definition: TCling.cxx:8512
void SetClassInfo(TClass *cl, Bool_t reload=kFALSE)
Set pointer to the TClingClassInfo in TClass.
Definition: TCling.cxx:3788
Long_t ProcessLineSynch(const char *line, EErrorCode *error=0)
Let cling process a command line synchronously, i.e we are waiting it will be finished.
Definition: TCling.cxx:3349
virtual int TypeInfo_RefType(TypeInfo_t *) const
Definition: TCling.cxx:9251
cling::MetaProcessor * GetMetaProcessorImpl() const
Definition: TCling.h:624
void LoadMacro(const char *filename, EErrorCode *error=0)
Load a macro file in cling's memory.
Definition: TCling.cxx:3332
std::set< size_t > fLookedUpClasses
Definition: TCling.h:119
virtual void CallFunc_ResetArg(CallFunc_t *func) const
Definition: TCling.cxx:7867
virtual Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const
Definition: TCling.cxx:7794
virtual Long_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:8423
void ResetAll()
Reset the Cling state to its initial state.
Definition: TCling.cxx:3494
virtual void ClassInfo_Delete(ClassInfo_t *info) const
Definition: TCling.cxx:8062
virtual DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo=0) const
Definition: TCling.cxx:8477
virtual Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const
Definition: TCling.cxx:7802
UInt_t AutoParseImplRecurse(const char *cls, bool topLevel)
Helper routine for TCling::AutoParse implementing the actual call to the parser and looping over temp...
Definition: TCling.cxx:6066
virtual const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:9369
void CreateListOfBaseClasses(TClass *cl) const
Create list of pointers to base class(es) for TClass cl.
Definition: TCling.cxx:4088
void RecursiveRemove(TObject *obj)
Delete object from cling symbol table so it can not be used anymore.
Definition: TCling.cxx:3453
virtual MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:9119
void UpdateListsOnUnloaded(const cling::Transaction &T)
Invalidate stored TCling state for declarations included in transaction ‘T’.
Definition: TCling.cxx:6846
void UpdateClassInfoWithDecl(const clang::NamedDecl *ND)
Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
Definition: TCling.cxx:6678
virtual const char * ClassInfo_FileName(ClassInfo_t *info) const
Definition: TCling.cxx:8294
virtual void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=0, int nargs=0, void *ret=0) const
Definition: TCling.cxx:7775
DeclId_t GetFunctionTemplate(ClassInfo_t *cl, const char *funcname)
Return pointer to cling interface function for a method of a class with a certain name.
Definition: TCling.cxx:4881
virtual int MethodInfo_NArg(MethodInfo_t *minfo) const
Definition: TCling.cxx:8931
virtual FuncTempInfo_t * FuncTempInfo_FactoryCopy(FuncTempInfo_t *) const
Construct a FuncTempInfo_t.
Definition: TCling.cxx:8692
void * fAutoLoadCallBack
Definition: TCling.h:145
virtual int TypedefInfo_Size(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:9345
std::unique_ptr< cling::MetaProcessor > fMetaProcessor
Definition: TCling.h:129
virtual const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:9361
virtual void CallFunc_SetFuncProto(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *proto, Long_t *Offset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
Interface to cling function.
Definition: TCling.cxx:7966
virtual int DisplayClass(FILE *fout, const char *name, int base, int start) const
Definition: TCling.cxx:7338
const char * GetClassSharedLibs(const char *cls)
Get the list of shared libraries containing the code for class cls.
Definition: TCling.cxx:7087
Bool_t IsErrorMessagesEnabled() const
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition: TCling.cxx:7270
ULong64_t fTransactionCount
Definition: TCling.h:146
virtual Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const
Check validity of a FuncTempInfo_t.
Definition: TCling.cxx:8703
virtual BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const
Definition: TCling.cxx:8350
virtual bool TypedefInfo_IsValid(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:9321
virtual MethodInfo_t * MethodInfo_Factory() const
Definition: TCling.cxx:8882
Int_t AutoParse(const char *cls)
Parse the headers relative to the class Returns 1 in case of success, 0 in case of failure.
Definition: TCling.cxx:6208
virtual EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const
Definition: TCling.cxx:9043
void * GetInterfaceMethodWithPrototype(TClass *cl, const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
Return pointer to cling interface function for a method of a class with a certain prototype,...
Definition: TCling.cxx:4814
virtual TypeInfo_t * TypeInfo_Factory() const
Definition: TCling.cxx:9195
std::map< size_t, std::vector< const char * > > fClassesHeadersMap
Definition: TCling.h:117
virtual int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const
Definition: TCling.cxx:8939
Int_t GenerateDictionary(const char *classes, const char *includes="", const char *options=0)
Generate the dictionary for the C++ classes listed in the first argument (in a semi-colon separated l...
Definition: TCling.cxx:4435
virtual void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Long_t *Offset) const
Definition: TCling.cxx:7939
void CreateListOfMethods(TClass *cl) const
Create list of pointers to methods for TClass cl.
Definition: TCling.cxx:4215
void UpdateListOfMethods(TClass *cl) const
Update the list of pointers to method for TClass cl This is now a nop.
Definition: TCling.cxx:4224
void RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Register Rdict data for future loading by LoadPCM;.
Definition: TCling.cxx:1562
virtual int ClassInfo_Size(ClassInfo_t *info) const
Definition: TCling.cxx:8278
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition: TCling.cxx:6751
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition: TCling.cxx:6977
Collection abstract base class.
Definition: TCollection.h:63
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
virtual Int_t GetEntries() const
Definition: TCollection.h:177
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual void Add(TObject *obj)=0
All ROOT classes may have RTTI (run time type identification) support added.
Definition: TDataMember.h:31
Bool_t IsPersistent() const
Definition: TDataMember.h:89
Basic data type descriptor (datatype information is obtained from CINT).
Definition: TDataType.h:44
Int_t GetType() const
Definition: TDataType.h:68
const void * DeclId_t
Definition: TDictionary.h:209
TList * GetListOfKeys() const override
Small helper to keep current directory context.
Definition: TDirectory.h:41
void GetObject(const char *namecycle, T *&ptr)
Definition: TDirectory.h:149
The TEnumConstant class implements the constants of the enum type.
Definition: TEnumConstant.h:29
The TEnum class implements the enum type.
Definition: TEnum.h:33
const TSeqCollection * GetConstants() const
Definition: TEnum.h:59
static TEnum * GetEnum(const std::type_info &ti, ESearchAction sa=kALoadAndInterpLookup)
Definition: TEnum.cxx:143
DeclId_t GetDeclId() const
Definition: TEnum.cxx:116
@ kNone
Definition: TEnum.h:47
@ kAutoload
Definition: TEnum.h:48
Definition: TEnv.h:87
const char * GetValue() const
Definition: TEnv.h:111
const char * GetName() const
Returns name of object.
Definition: TEnv.h:110
The TEnv class reads config files, by default named .rootrc.
Definition: TEnv.h:125
THashList * GetTable() const
Definition: TEnv.h:141
Bool_t IgnoreDuplicates(Bool_t ignore)
If set to true, no warnings in case of duplicates are issued.
Definition: TEnv.cxx:793
virtual void SetRcName(const char *name)
Definition: TEnv.h:146
virtual Int_t ReadFile(const char *fname, EEnvLevel level)
Read and parse the resource file for a certain level.
Definition: TEnv.cxx:592
virtual TEnvRec * Lookup(const char *n) const
Loop over all resource records and return the one with name.
Definition: TEnv.cxx:547
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=0)
Set the value of a resource or create a new resource.
Definition: TEnv.cxx:736
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition: TFile.h:48
Global functions class (global functions are obtained from CINT).
Definition: TFunction.h:28
MethodInfo_t * fInfo
Definition: TFunction.h:34
Global variables class (global variables are obtained from CINT).
Definition: TGlobal.h:28
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:34
TObject * Remove(TObject *obj)
Remove object from the list.
Definition: THashList.cxx:378
THashTable implements a hash table to store TObject's.
Definition: THashTable.h:35
virtual const void * GetValAddr() const =0
This class defines an abstract interface to a generic command line interpreter.
Definition: TInterpreter.h:60
virtual bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const =0
virtual Int_t AutoParse(const char *cls)=0
int(* AutoLoadCallBack_t)(const char *)
Definition: TInterpreter.h:132
virtual const char * GetClassSharedLibs(const char *cls)=0
virtual Bool_t Declare(const char *code)=0
virtual Bool_t IsLibraryLoaded(const char *libname) const =0
std::vector< std::pair< std::string, int > > FwdDeclArgsToKeepCollection_t
Definition: TInterpreter.h:133
TDictionary::DeclId_t DeclId_t
Definition: TInterpreter.h:283
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:24
A collection of TDataMember objects designed for fast access given a DeclId_t and for keep track of T...
TDictionary * Find(DeclId_t id) const
Return (after creating it if necessary) the TDataMember describing the data member corresponding to t...
TClass * GetClass() const
virtual TObject * FindObject(const char *name) const
Specialize FindObject to do search for the a data member just by name or create it if its not already...
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
A collection of TEnum objects designed for fast access given a DeclId_t and for keep track of TEnum t...
Definition: TListOfEnums.h:33
TEnum * Find(DeclId_t id) const
Return the TEnum corresponding to the Decl 'id' or NULL if it does not exist.
TEnum * Get(DeclId_t id, const char *name)
Return (after creating it if necessary) the TEnum describing the enum corresponding to the Decl 'id'.
TClass * GetClass() const
Definition: TListOfEnums.h:62
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
TFunctionTemplate * Get(DeclId_t id)
Return (after creating it if necessary) the TMethod or TFunction describing the function correspondin...
A collection of TFunction objects designed for fast access given a DeclId_t and for keep track of TFu...
TFunction * Find(DeclId_t id) const
Return the TMethod or TFunction describing the function corresponding to the Decl 'id'.
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:354
A TMemFile is like a normal TFile except that it reads and writes only from memory.
Definition: TMemFile.h:19
Abstract base class for accessing the data-members of a class.
const char * GetParent() const
virtual void Inspect(TClass *cl, const char *parent, const char *name, const void *addr)
EObjectPointerState GetObjectValidity() const
virtual Bool_t IsTreatingNonAccessibleTypes()
void SetObjectValidity(EObjectPointerState val)
void InspectMember(const T &obj, const char *name, Bool_t isTransient)
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition: TMethodArg.h:31
const char * GetFullTypeName() const
Get full type description of method argument, e.g.: "class TDirectory*".
Definition: TMethodArg.cxx:75
const char * GetDefault() const
Get default value of method argument.
Definition: TMethodArg.cxx:58
Each ROOT class (see TClass) has a linked list of methods.
Definition: TMethod.h:38
virtual TList * GetListOfMethodArgs()
Returns methodarg list and additionally updates fDataMember in TMethod by calling FindDataMember();.
Definition: TMethod.cxx:306
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
TNamed()
Definition: TNamed.h:36
TString fName
Definition: TNamed.h:32
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
An array of TObjects.
Definition: TObjArray.h:37
Int_t GetEntriesFast() const
Definition: TObjArray.h:64
virtual void Expand(Int_t newSize)
Expand or shrink the array to newSize elements.
Definition: TObjArray.cxx:386
void Add(TObject *obj)
Definition: TObjArray.h:74
virtual void Compress()
Remove empty slots from array.
Definition: TObjArray.cxx:333
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:522
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
Definition: TObjArray.cxx:414
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:718
TObject * At(Int_t idx) const
Definition: TObjArray.h:166
Collectable string class.
Definition: TObjString.h:28
TString & String()
Definition: TObjString.h:48
Mother of all ROOT objects.
Definition: TObject.h:37
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
R__ALWAYS_INLINE Bool_t IsOnHeap() const
Definition: TObject.h:133
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:908
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:401
void MakeZombie()
Definition: TObject.h:49
void ResetBit(UInt_t f)
Definition: TObject.h:171
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition: TObject.h:68
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
Persistent version of a TClass.
Definition: TProtoClass.h:35
static const TString & GetIncludeDir()
Get the include directory in the installation. Static utility function.
Definition: TROOT.cxx:2977
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition: TROOT.cxx:2741
virtual ~TROOT()
Clean up and free resources used by ROOT (files, network sockets, shared memory segments,...
Definition: TROOT.cxx:904
static const std::vector< std::string > & AddExtraInterpreterArgs(const std::vector< std::string > &args)
Provide command line arguments to the interpreter construction.
Definition: TROOT.cxx:2898
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition: TROOT.cxx:2987
static const char **& GetExtraInterpreterArgs()
INTERNAL function! Used by rootcling to inject interpreter arguments through a C-interface layer.
Definition: TROOT.cxx:2908
static const TString & GetLibDir()
Get the library directory in the installation. Static utility function.
Definition: TROOT.cxx:2956
Int_t LastIndex() const
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:43
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2177
const char * Data() const
Definition: TString.h:364
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:892
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2197
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:610
TString & Prepend(const char *cs)
Definition: TString.h:656
Bool_t IsNull() const
Definition: TString.h:402
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
TString & Append(const char *cs)
Definition: TString.h:559
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2311
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:1014
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition: TSystem.cxx:853
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition: TSystem.cxx:844
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1653
virtual const char * GetIncludePath()
Get the list of include path.
Definition: TSystem.cxx:3955
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition: TSystem.cxx:4232
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition: TSystem.cxx:1062
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1527
virtual const char * HomeDirectory(const char *userName=0)
Return the user's home directory.
Definition: TSystem.cxx:895
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1845
int GetPathInfo(const char *path, Long_t *id, Long_t *size, Long_t *flags, Long_t *modtime)
Get info about a file: id, size, flags, modification time.
Definition: TSystem.cxx:1389
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition: TSystem.cxx:1072
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition: TSystem.cxx:1287
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition: TSystem.cxx:861
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition: TSystem.cxx:2534
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:942
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition: TSystem.cxx:1783
virtual const char * FindDynamicLibrary(TString &lib, Bool_t quiet=kFALSE)
Find a dynamic library using the system search paths.
Definition: TSystem.cxx:2036
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition: TSystem.cxx:447
virtual int CompileMacro(const char *filename, Option_t *opt="", const char *library_name="", const char *build_dir="", UInt_t dirmode=0)
This method compiles and loads a shared library containing the code from the file "filename".
Definition: TSystem.cxx:2875
virtual const char * WorkingDirectory()
Return working directory.
Definition: TSystem.cxx:879
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1537
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition: TSystem.cxx:1637
virtual void StackTrace()
Print a stack trace.
Definition: TSystem.cxx:742
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
Definition: TSystem.cxx:2022
virtual Int_t UnLock()=0
virtual Int_t Lock()=0
virtual TVirtualMutex * Factory(Bool_t=kFALSE)=0
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:50
virtual void Update()=0
static void SetFactory(TVirtualStreamerInfo *factory)
static function: Set the StreamerInfo factory
TText * text
TLine * line
Type
enumeration specifying the integration types.
const Int_t n
Definition: legend1.C:16
Double_t ex[n]
Definition: legend1.C:17
TF1 * f1
Definition: legend1.C:11
#define F(x, y, z)
#define I(x, y, z)
#define H(x, y, z)
TCppMethod_t GetMethod(TCppScope_t scope, TCppIndex_t imeth)
Definition: Cppyy.cxx:751
const std::string & GetPathSeparator()
const char & GetEnvPathSeparator()
R__EXTERN TROOT * gROOTLocal
Definition: TROOT.h:388
static double P[]
static double A[]
static double C[]
double T(double x)
Definition: ChebyshevPol.h:34
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
Definition: RExports.h:151
RVec< T > Filter(const RVec< T > &v, F &&f)
Create a new collection with the elements passing the filter expressed by the predicate.
Definition: RVec.hxx:938
VSD Structures.
Definition: StringConv.hxx:21
R__EXTERN TVirtualRWMutex * gCoreMutex
EFunctionMatchMode
Definition: TDictionary.h:155
@ kExactMatch
Definition: TDictionary.h:156
V GetOffset(E val1, E val2, V iso)
RooArgSet S(const RooAbsArg &v1)
bool IsStdArray(std::string_view name)
Definition: TClassEdit.h:186
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
std::string InsertStd(const char *tname)
bool SplitFunction(std::string_view decl, FunctionSplitInfo &result)
Split a function declaration into its different parts.
std::string GetLong64_Name(const char *original)
Replace 'long long' and 'unsigned long long' by 'Long64_t' and 'ULong64_t'.
Definition: TClassEdit.cxx:874
char * DemangleTypeIdName(const std::type_info &ti, int &errorCode)
Demangle in a portable way the type id name.
const char * GetUnqualifiedName(const char *name)
Return the start of the unqualified name include in 'original'.
Definition: TClassEdit.cxx:908
void Init(TClassEdit::TInterpreterLookupHelper *helper)
Definition: TClassEdit.cxx:155
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
char * DemangleName(const char *mangled_name, int &errorCode)
Definition: TClassEdit.h:205
int GetSplit(const char *type, std::vector< std::string > &output, int &nestedLoc, EModType mode=TClassEdit::kNone)
Stores in output (after emptying it) the split type.
Definition: TClassEdit.cxx:995
void GetNormalizedName(std::string &norm_name, std::string_view name)
Return the normalized name.
Definition: TClassEdit.cxx:832
@ kDropTrailStar
Definition: TClassEdit.h:76
@ kDropStlDefault
Definition: TClassEdit.h:81
EComplexType GetComplexType(const char *)
Definition: TClassEdit.cxx:121
static constexpr double s
static constexpr double ns
static constexpr double L
constexpr Double_t E()
Base of natural log:
Definition: TMath.h:97
Definition: file.py:1
const char * Name
Definition: TXMLSetup.cxx:66
const char * Value
Definition: TXMLSetup.cxx:72
const char * Null
Definition: TXMLSetup.cxx:53
Int_t fMode
Definition: TSystem.h:128
Long_t fMemVirtual
Definition: TSystem.h:197
Long_t fMemResident
Definition: TSystem.h:196
RAII used to store Parser, Sema, Preprocessor state for recursive parsing.
Definition: ClingRAII.h:22
State as returned by GetStateDelta() that can be passed to Restore()
Result of splitting a function declaration into fReturnType fScopeName::fFunctionName<fFunctionTempla...
Definition: TClassEdit.h:231
std::string fScopeName
Name of the scope qualification of the function, possibly empty.
Definition: TClassEdit.h:236
std::vector< std::string > fElements
Definition: TClassEdit.h:140
void ShortType(std::string &answer, int mode)
Return the absolute type of typeDesc into the string answ.
Definition: TClassEdit.cxx:234
A read-only memory range which we do not control.
Definition: TMemFile.h:23
auto * m
Definition: textangle.C:8
auto * l
Definition: textangle.C:4
auto * a
Definition: textangle.C:12
static void output(int code)
Definition: gifencode.c:226