Logo ROOT  
Reference Guide
TCling.cxx
Go to the documentation of this file.
1// @(#)root/meta:$Id$
2// vim: sw=3 ts=3 expandtab foldmethod=indent
3
4/*************************************************************************
5 * Copyright (C) 1995-2012, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TCling
13
14This class defines an interface to the cling C++ interpreter.
15
16Cling is a full ANSI compliant C++-11 interpreter based on
17clang/LLVM technology.
18*/
19
20#include "TCling.h"
21
23
24#include "TClingBaseClassInfo.h"
25#include "TClingCallFunc.h"
26#include "TClingClassInfo.h"
28#include "TClingMethodArgInfo.h"
29#include "TClingMethodInfo.h"
31#include "TClingTypedefInfo.h"
32#include "TClingTypeInfo.h"
33#include "TClingValue.h"
34
35#include "TROOT.h"
36#include "TApplication.h"
37#include "TGlobal.h"
38#include "TDataType.h"
39#include "TClass.h"
40#include "TClassEdit.h"
41#include "TClassTable.h"
42#include "TClingCallbacks.h"
43#include "TBaseClass.h"
44#include "TDataMember.h"
45#include "TMemberInspector.h"
46#include "TMethod.h"
47#include "TMethodArg.h"
48#include "TFunctionTemplate.h"
49#include "TObjArray.h"
50#include "TObjString.h"
51#include "TString.h"
52#include "THashList.h"
53#include "TVirtualPad.h"
54#include "TSystem.h"
55#include "TVirtualMutex.h"
56#include "TError.h"
57#include "TEnv.h"
58#include "TEnum.h"
59#include "TEnumConstant.h"
60#include "THashTable.h"
62#include "RConfigure.h"
63#include "compiledata.h"
64#include "TClingUtils.h"
67#include "TListOfDataMembers.h"
68#include "TListOfEnums.h"
70#include "TListOfFunctions.h"
72#include "TMemFile.h"
73#include "TProtoClass.h"
74#include "TStreamerInfo.h" // This is here to avoid to use the plugin manager
75#include "ThreadLocalStorage.h"
76#include "TFile.h"
77#include "TKey.h"
78#include "ClingRAII.h"
79
80#include "clang/AST/ASTContext.h"
81#include "clang/AST/Decl.h"
82#include "clang/AST/DeclarationName.h"
83#include "clang/AST/GlobalDecl.h"
84#include "clang/AST/RecordLayout.h"
85#include "clang/AST/DeclVisitor.h"
86#include "clang/AST/RecursiveASTVisitor.h"
87#include "clang/AST/Type.h"
88#include "clang/Basic/SourceLocation.h"
89#include "clang/Basic/Specifiers.h"
90#include "clang/Basic/TargetInfo.h"
91#include "clang/CodeGen/ModuleBuilder.h"
92#include "clang/Frontend/CompilerInstance.h"
93#include "clang/Frontend/FrontendDiagnostic.h"
94#include "clang/Lex/HeaderSearch.h"
95#include "clang/Lex/Preprocessor.h"
96#include "clang/Lex/PreprocessorOptions.h"
97#include "clang/Parse/Parser.h"
98#include "clang/Sema/Lookup.h"
99#include "clang/Sema/Sema.h"
100#include "clang/Serialization/ASTReader.h"
101#include "clang/Serialization/GlobalModuleIndex.h"
102
103#include "cling/Interpreter/ClangInternalState.h"
104#include "cling/Interpreter/DynamicLibraryManager.h"
105#include "cling/Interpreter/Interpreter.h"
106#include "cling/Interpreter/LookupHelper.h"
107#include "cling/Interpreter/Value.h"
108#include "cling/Interpreter/Transaction.h"
109#include "cling/MetaProcessor/MetaProcessor.h"
110#include "cling/Utils/AST.h"
111#include "cling/Utils/ParserStateRAII.h"
112#include "cling/Utils/SourceNormalization.h"
113#include "cling/Interpreter/Exception.h"
114
115#include "llvm/IR/GlobalValue.h"
116#include "llvm/IR/Module.h"
117
118#include "llvm/Support/DynamicLibrary.h"
119#include "llvm/Support/raw_ostream.h"
120#include "llvm/Support/Path.h"
121#include "llvm/Support/Process.h"
122#include "llvm/Object/ELFObjectFile.h"
123#include "llvm/Object/ObjectFile.h"
124#include "llvm/Object/SymbolicFile.h"
125#include "llvm/Support/FileSystem.h"
126
127#include <algorithm>
128#include <iostream>
129#include <cassert>
130#include <map>
131#include <set>
132#include <stdexcept>
133#include <stdint.h>
134#include <fstream>
135#include <sstream>
136#include <string>
137#include <tuple>
138#include <typeinfo>
139#include <unordered_map>
140#include <unordered_set>
141#include <utility>
142#include <vector>
143#include <functional>
144
145#ifndef R__WIN32
146#include <cxxabi.h>
147#define R__DLLEXPORT __attribute__ ((visibility ("default")))
148#include <sys/stat.h>
149#endif
150#include <limits.h>
151#include <stdio.h>
152
153#ifdef __APPLE__
154#include <dlfcn.h>
155#include <mach-o/dyld.h>
156#include <mach-o/loader.h>
157#endif // __APPLE__
158
159#ifdef R__UNIX
160#include <dlfcn.h>
161#endif
162
163#ifdef R__LINUX
164# ifndef _GNU_SOURCE
165# define _GNU_SOURCE
166# endif
167# include <link.h> // dl_iterate_phdr()
168#endif
169
170#if defined(__CYGWIN__)
171#include <sys/cygwin.h>
172#define HMODULE void *
173extern "C" {
174 __declspec(dllimport) void * __stdcall GetCurrentProcess();
175 __declspec(dllimport) bool __stdcall EnumProcessModules(void *, void **, unsigned long, unsigned long *);
176 __declspec(dllimport) unsigned long __stdcall GetModuleFileNameExW(void *, void *, wchar_t *, unsigned long);
177}
178#endif
179
180// Fragment copied from LLVM's raw_ostream.cpp
181#if defined(_MSC_VER)
182#ifndef STDIN_FILENO
183# define STDIN_FILENO 0
184#endif
185#ifndef STDOUT_FILENO
186# define STDOUT_FILENO 1
187#endif
188#ifndef STDERR_FILENO
189# define STDERR_FILENO 2
190#endif
191#ifndef R__WIN32
192//#if defined(HAVE_UNISTD_H)
193# include <unistd.h>
194//#endif
195#else
196#include "Windows4Root.h"
197#include <Psapi.h>
198#undef GetModuleFileName
199#define RTLD_DEFAULT ((void *)::GetModuleHandle(NULL))
200#define dlsym(library, function_name) ::GetProcAddress((HMODULE)library, function_name)
201#define dlopen(library_name, flags) ::LoadLibraryA(library_name)
202#define dlclose(library) ::FreeLibrary((HMODULE)library)
203#define R__DLLEXPORT __declspec(dllexport)
204#endif
205#endif
206
207//______________________________________________________________________________
208// Infrastructure to detect and react to libCling being teared down.
209//
210namespace {
211 class TCling_UnloadMarker {
212 public:
213 ~TCling_UnloadMarker() {
216 }
217 }
218 };
219 static TCling_UnloadMarker gTClingUnloadMarker;
220}
221
222
223
224//______________________________________________________________________________
225// These functions are helpers for debugging issues with non-LLVMDEV builds.
226//
227R__DLLEXPORT clang::DeclContext* TCling__DEBUG__getDeclContext(clang::Decl* D) {
228 return D->getDeclContext();
229}
230R__DLLEXPORT clang::NamespaceDecl* TCling__DEBUG__DCtoNamespace(clang::DeclContext* DC) {
231 return llvm::dyn_cast<clang::NamespaceDecl>(DC);
232}
233R__DLLEXPORT clang::RecordDecl* TCling__DEBUG__DCtoRecordDecl(clang::DeclContext* DC) {
234 return llvm::dyn_cast<clang::RecordDecl>(DC);
235}
236R__DLLEXPORT void TCling__DEBUG__dump(clang::DeclContext* DC) {
237 return DC->dumpDeclContext();
238}
239R__DLLEXPORT void TCling__DEBUG__dump(clang::Decl* D) {
240 return D->dump();
241}
242R__DLLEXPORT void TCling__DEBUG__dump(clang::FunctionDecl* FD) {
243 return FD->dump();
244}
246 return ((clang::Decl*)D)->dump();
247}
249 if (clang::NamedDecl* ND = llvm::dyn_cast<clang::NamedDecl>(D)) {
250 std::string name;
251 {
252 llvm::raw_string_ostream OS(name);
253 ND->getNameForDiagnostic(OS, D->getASTContext().getPrintingPolicy(),
254 true /*Qualified*/);
255 }
256 printf("%s\n", name.c_str());
257 }
258}
259//______________________________________________________________________________
260// These functions are helpers for testing issues directly rather than
261// relying on side effects.
262// This is used for the test for ROOT-7462/ROOT-6070
264 return D->isInvalidDecl();
265}
266R__DLLEXPORT bool TCling__TEST_isInvalidDecl(ClassInfo_t *input) {
267 TClingClassInfo *info( (TClingClassInfo*) input);
268 assert(info && info->IsValid());
269 return info->GetDecl()->isInvalidDecl();
270}
271
272using namespace std;
273using namespace clang;
274using namespace ROOT;
275
276namespace {
277 static const std::string gInterpreterClassDef = R"ICF(
278#undef ClassDef
279#define ClassDef(name, id) \
280_ClassDefInterp_(name,id,virtual,) \
281static int DeclFileLine() { return __LINE__; }
282#undef ClassDefNV
283#define ClassDefNV(name, id) \
284_ClassDefInterp_(name,id,,) \
285static int DeclFileLine() { return __LINE__; }
286#undef ClassDefOverride
287#define ClassDefOverride(name, id) \
288_ClassDefInterp_(name,id,,override) \
289static int DeclFileLine() { return __LINE__; }
290)ICF";
291
292 static const std::string gNonInterpreterClassDef = R"ICF(
293#define __ROOTCLING__ 1
294#undef ClassDef
295#define ClassDef(name,id) \
296_ClassDefOutline_(name,id,virtual,) \
297static int DeclFileLine() { return __LINE__; }
298#undef ClassDefNV
299#define ClassDefNV(name, id)\
300_ClassDefOutline_(name,id,,)\
301static int DeclFileLine() { return __LINE__; }
302#undef ClassDefOverride
303#define ClassDefOverride(name, id)\
304_ClassDefOutline_(name,id,,override)\
305static int DeclFileLine() { return __LINE__; }
306)ICF";
307
308// The macros below use ::Error, so let's ensure it is included
309 static const std::string gClassDefInterpMacro = R"ICF(
310#include "TError.h"
311
312#define _ClassDefInterp_(name,id,virtual_keyword, overrd) \
313private: \
314public: \
315 static TClass *Class() { static TClass* sIsA = 0; if (!sIsA) sIsA = TClass::GetClass(#name); return sIsA; } \
316 static const char *Class_Name() { return #name; } \
317 virtual_keyword Bool_t CheckTObjectHashConsistency() const overrd { return true; } \
318 static Version_t Class_Version() { return id; } \
319 static TClass *Dictionary() { return 0; } \
320 virtual_keyword TClass *IsA() const overrd { return name::Class(); } \
321 virtual_keyword void ShowMembers(TMemberInspector&insp) const overrd { ::ROOT::Class_ShowMembers(name::Class(), this, insp); } \
322 virtual_keyword void Streamer(TBuffer&) overrd { ::Error("Streamer", "Cannot stream interpreted class."); } \
323 void StreamerNVirtual(TBuffer&ClassDef_StreamerNVirtual_b) { name::Streamer(ClassDef_StreamerNVirtual_b); } \
324 static const char *DeclFileName() { return __FILE__; } \
325 static int ImplFileLine() { return 0; } \
326 static const char *ImplFileName() { return __FILE__; }
327)ICF";
328}
330
331// The functions are used to bridge cling/clang/llvm compiled with no-rtti and
332// ROOT (which uses rtti)
333
334////////////////////////////////////////////////////////////////////////////////
335/// Print a StackTrace!
336
337extern "C"
340}
341
342////////////////////////////////////////////////////////////////////////////////
343/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
344
345extern "C" void TCling__RestoreInterpreterMutex(void *delta)
346{
347 ((TCling*)gCling)->ApplyToInterpreterMutex(delta);
348}
349
350////////////////////////////////////////////////////////////////////////////////
351/// Lookup libraries in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH with mangled_name,
352/// which is extracted by error messages we get from callback from cling. Return true
353/// when the missing library was autoloaded.
354
355extern "C" bool TCling__LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
356{
357 return ((TCling*)gCling)->LibraryLoadingFailed(errmessage, libStem, permanent, resolved);
358}
359
360////////////////////////////////////////////////////////////////////////////////
361/// Reset the interpreter lock to the state it had before interpreter-related
362/// calls happened.
363
365{
366 return ((TCling*)gCling)->RewindInterpreterMutex();
367}
368
369////////////////////////////////////////////////////////////////////////////////
370/// Lock the interpreter.
371
373{
374 if (gInterpreterMutex) {
376 }
377 return nullptr;
378}
379
380////////////////////////////////////////////////////////////////////////////////
381/// Unlock the interpreter.
382
384{
385 if (gInterpreterMutex) {
387 }
388}
389
390////////////////////////////////////////////////////////////////////////////////
391/// Update TClingClassInfo for a class (e.g. upon seeing a definition).
392
393static void TCling__UpdateClassInfo(const NamedDecl* TD)
394{
395 static Bool_t entered = kFALSE;
396 static vector<const NamedDecl*> updateList;
397 Bool_t topLevel;
398
399 if (entered) topLevel = kFALSE;
400 else {
401 entered = kTRUE;
402 topLevel = kTRUE;
403 }
404 if (topLevel) {
405 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(TD);
406 } else {
407 // If we are called indirectly from within another call to
408 // TCling::UpdateClassInfo, we delay the update until the dictionary loading
409 // is finished (i.e. when we return to the top level TCling::UpdateClassInfo).
410 // This allows for the dictionary to be fully populated when we actually
411 // update the TClass object. The updating of the TClass sometimes
412 // (STL containers and when there is an emulated class) forces the building
413 // of the TClass object's real data (which needs the dictionary info).
414 updateList.push_back(TD);
415 }
416 if (topLevel) {
417 while (!updateList.empty()) {
418 ((TCling*)gInterpreter)->UpdateClassInfoWithDecl(updateList.back());
419 updateList.pop_back();
420 }
421 entered = kFALSE;
422 }
423}
424
425void TCling::UpdateEnumConstants(TEnum* enumObj, TClass* cl) const {
426 const clang::Decl* D = static_cast<const clang::Decl*>(enumObj->GetDeclId());
427 if(const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(D)) {
428 // Add the constants to the enum type.
429 for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin(),
430 EDE = ED->enumerator_end(); EDI != EDE; ++EDI) {
431 // Get name of the enum type.
432 std::string constbuf;
433 if (const NamedDecl* END = llvm::dyn_cast<NamedDecl>(*EDI)) {
434 PrintingPolicy Policy((*EDI)->getASTContext().getPrintingPolicy());
435 llvm::raw_string_ostream stream(constbuf);
436 // Don't trigger fopen of the source file to count lines:
437 Policy.AnonymousTagLocations = false;
438 (END)->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
439 }
440 const char* constantName = constbuf.c_str();
441
442 // Get value of the constant.
443 Long64_t value;
444 const llvm::APSInt valAPSInt = (*EDI)->getInitVal();
445 if (valAPSInt.isSigned()) {
446 value = valAPSInt.getSExtValue();
447 } else {
448 value = valAPSInt.getZExtValue();
449 }
450
451 // Create the TEnumConstant or update it if existing
452 TEnumConstant* enumConstant = nullptr;
453 TClingClassInfo* tcCInfo = (TClingClassInfo*)(cl ? cl->GetClassInfo() : 0);
454 TClingDataMemberInfo* tcDmInfo = new TClingDataMemberInfo(GetInterpreterImpl(), *EDI, tcCInfo);
455 DataMemberInfo_t* dmInfo = (DataMemberInfo_t*) tcDmInfo;
456 if (TObject* encAsTObj = enumObj->GetConstants()->FindObject(constantName)){
457 ((TEnumConstant*)encAsTObj)->Update(dmInfo);
458 } else {
459 enumConstant = new TEnumConstant(dmInfo, constantName, value, enumObj);
460 }
461
462 // Add the global constants to the list of Globals.
463 if (!cl) {
464 TCollection* globals = gROOT->GetListOfGlobals(false);
465 if (!globals->FindObject(constantName)) {
466 globals->Add(enumConstant);
467 }
468 }
469 }
470 }
471}
472
473TEnum* TCling::CreateEnum(void *VD, TClass *cl) const
474{
475 // Handle new enum declaration for either global and nested enums.
476
477 // Create the enum type.
478 TEnum* enumType = 0;
479 const clang::Decl* D = static_cast<const clang::Decl*>(VD);
480 std::string buf;
481 if (const EnumDecl* ED = llvm::dyn_cast<EnumDecl>(D)) {
482 // Get name of the enum type.
483 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
484 llvm::raw_string_ostream stream(buf);
485 // Don't trigger fopen of the source file to count lines:
486 Policy.AnonymousTagLocations = false;
487 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
488 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
489 }
490 if (buf.empty()) {
491 return 0;
492 }
493 const char* name = buf.c_str();
494 enumType = new TEnum(name, VD, cl);
495 UpdateEnumConstants(enumType, cl);
496
497 return enumType;
498}
499
500void TCling::HandleNewDecl(const void* DV, bool isDeserialized, std::set<TClass*> &modifiedTClasses) {
501 // Handle new declaration.
502 // Record the modified class, struct and namespaces in 'modifiedTClasses'.
503
504 const clang::Decl* D = static_cast<const clang::Decl*>(DV);
505
506 if (!D->isCanonicalDecl() && !isa<clang::NamespaceDecl>(D)
507 && !dyn_cast<clang::RecordDecl>(D)) return;
508
509 if (isa<clang::FunctionDecl>(D->getDeclContext())
510 || isa<clang::TagDecl>(D->getDeclContext()))
511 return;
512
513 // Don't list templates.
514 if (const clang::CXXRecordDecl* RD = dyn_cast<clang::CXXRecordDecl>(D)) {
515 if (RD->getDescribedClassTemplate())
516 return;
517 } else if (const clang::FunctionDecl* FD = dyn_cast<clang::FunctionDecl>(D)) {
518 if (FD->getDescribedFunctionTemplate())
519 return;
520 }
521
522 if (const RecordDecl *TD = dyn_cast<RecordDecl>(D)) {
523 if (TD->isCanonicalDecl() || TD->isThisDeclarationADefinition())
525 }
526 else if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
527
528 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
529 // Mostly just for EnumDecl (the other TagDecl are handled
530 // by the 'RecordDecl' if statement.
532 } else if (const NamespaceDecl* NSD = dyn_cast<NamespaceDecl>(D)) {
534 }
535
536 // We care about declarations on the global scope.
537 if (!isa<TranslationUnitDecl>(ND->getDeclContext()))
538 return;
539
540 // Enums are lazyly created, thus we don not need to handle them here.
541 if (isa<EnumDecl>(ND))
542 return;
543
544 // ROOT says that global is enum(lazylycreated)/var/field declared on the global
545 // scope.
546 if (!(isa<VarDecl>(ND)))
547 return;
548
549 // Skip if already in the list.
550 if (gROOT->GetListOfGlobals()->FindObject(ND->getNameAsString().c_str()))
551 return;
552
553 // Put the global constants and global enums in the corresponding lists.
554 gROOT->GetListOfGlobals()->Add(new TGlobal((DataMemberInfo_t *)
556 cast<ValueDecl>(ND), 0)));
557 }
558}
559
560extern "C"
562{
563 // We are sure in this context of the type of the interpreter
564 normCtxt = &( (TCling*) gInterpreter)->GetNormalizedContext();
565}
566
567extern "C"
568void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter*) {
569 ((TCling*)gCling)->UpdateListsOnCommitted(T);
570}
571
572extern "C"
573void TCling__UpdateListsOnUnloaded(const cling::Transaction &T) {
574 ((TCling*)gCling)->UpdateListsOnUnloaded(T);
575}
576
577extern "C"
578void TCling__InvalidateGlobal(const clang::Decl *D) {
579 ((TCling*)gCling)->InvalidateGlobal(D);
580}
581
582extern "C"
583void TCling__TransactionRollback(const cling::Transaction &T) {
584 ((TCling*)gCling)->TransactionRollback(T);
585}
586
587extern "C" void TCling__LibraryLoadedRTTI(const void* dyLibHandle,
588 const char* canonicalName) {
589 ((TCling*)gCling)->LibraryLoaded(dyLibHandle, canonicalName);
590}
591
592extern "C" void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
593{
594 ((TCling *)gCling)->RegisterRdictForLoadPCM(pcmFileNameFullPath, pcmContent);
595}
596
597extern "C" void TCling__LibraryUnloadedRTTI(const void* dyLibHandle,
598 const char* canonicalName) {
599 ((TCling*)gCling)->LibraryUnloaded(dyLibHandle, canonicalName);
600}
601
602
603extern "C"
604TObject* TCling__GetObjectAddress(const char *Name, void *&LookupCtx) {
605 return ((TCling*)gCling)->GetObjectAddress(Name, LookupCtx);
606}
607
608extern "C" const Decl* TCling__GetObjectDecl(TObject *obj) {
609 return ((TClingClassInfo*)obj->IsA()->GetClassInfo())->GetDecl();
610}
611
612extern "C" R__DLLEXPORT TInterpreter *CreateInterpreter(void* interpLibHandle,
613 const char* argv[])
614{
615 cling::DynamicLibraryManager::ExposeHiddenSharedLibrarySymbols(interpLibHandle);
616 return new TCling("C++", "cling C++ Interpreter", argv);
617}
618
620{
621 delete interp;
622}
623
624// Load library containing specified class. Returns 0 in case of error
625// and 1 in case if success.
626extern "C" int TCling__AutoLoadCallback(const char* className)
627{
628 return ((TCling*)gCling)->AutoLoad(className);
629}
630
631extern "C" int TCling__AutoParseCallback(const char* className)
632{
633 return ((TCling*)gCling)->AutoParse(className);
634}
635
636extern "C" const char* TCling__GetClassSharedLibs(const char* className)
637{
638 return ((TCling*)gCling)->GetClassSharedLibs(className);
639}
640
641// Returns 0 for failure 1 for success
642extern "C" int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
643{
644 return ((TCling*)gCling)->IsAutoLoadNamespaceCandidate(nsDecl);
645}
646
647extern "C" int TCling__CompileMacro(const char *fileName, const char *options)
648{
649 string file(fileName);
650 string opt(options);
651 return gSystem->CompileMacro(file.c_str(), opt.c_str());
652}
653
654extern "C" void TCling__SplitAclicMode(const char* fileName, string &mode,
655 string &args, string &io, string &fname)
656{
657 string file(fileName);
658 TString f, amode, arguments, aclicio;
659 f = gSystem->SplitAclicMode(file.c_str(), amode, arguments, aclicio);
660 mode = amode.Data(); args = arguments.Data();
661 io = aclicio.Data(); fname = f.Data();
662}
663
664//______________________________________________________________________________
665//
666//
667//
668
669#ifdef R__WIN32
670extern "C" {
671 char *__unDName(char *demangled, const char *mangled, int out_len,
672 void * (* pAlloc )(size_t), void (* pFree )(void *),
673 unsigned short int flags);
674}
675#endif
676
677////////////////////////////////////////////////////////////////////////////////
678/// Find a template decl within N nested namespaces, 0<=N<inf
679/// Assumes 1 and only 1 template present and 1 and only 1 entity contained
680/// by the namespace. Example: ns1::ns2::..::nsN::myTemplate
681/// Returns nullptr in case of error
682
683static clang::ClassTemplateDecl* FindTemplateInNamespace(clang::Decl* decl)
684{
685 using namespace clang;
686 if (NamespaceDecl* nsd = llvm::dyn_cast<NamespaceDecl>(decl)){
687 return FindTemplateInNamespace(*nsd->decls_begin());
688 }
689
690 if (ClassTemplateDecl* ctd = llvm::dyn_cast<ClassTemplateDecl>(decl)){
691 return ctd;
692 }
693
694 return nullptr; // something went wrong.
695}
696
697////////////////////////////////////////////////////////////////////////////////
698/// Autoload a library provided the mangled name of a missing symbol.
699
700void* llvmLazyFunctionCreator(const std::string& mangled_name)
701{
702 return ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
703}
704
705//______________________________________________________________________________
706//
707//
708//
709
710int TCling_GenerateDictionary(const std::vector<std::string> &classes,
711 const std::vector<std::string> &headers,
712 const std::vector<std::string> &fwdDecls,
713 const std::vector<std::string> &unknown)
714{
715 //This function automatically creates the "LinkDef.h" file for templated
716 //classes then executes CompileMacro on it.
717 //The name of the file depends on the class name, and it's not generated again
718 //if the file exist.
719 if (classes.empty()) {
720 return 0;
721 }
722 // Use the name of the first class as the main name.
723 const std::string& className = classes[0];
724 //(0) prepare file name
725 TString fileName = "AutoDict_";
726 std::string::const_iterator sIt;
727 for (sIt = className.begin(); sIt != className.end(); ++sIt) {
728 if (*sIt == '<' || *sIt == '>' ||
729 *sIt == ' ' || *sIt == '*' ||
730 *sIt == ',' || *sIt == '&' ||
731 *sIt == ':') {
732 fileName += '_';
733 }
734 else {
735 fileName += *sIt;
736 }
737 }
738 if (classes.size() > 1) {
739 Int_t chk = 0;
740 std::vector<std::string>::const_iterator it = classes.begin();
741 while ((++it) != classes.end()) {
742 for (UInt_t cursor = 0; cursor != it->length(); ++cursor) {
743 chk = chk * 3 + it->at(cursor);
744 }
745 }
746 fileName += TString::Format("_%u", chk);
747 }
748 fileName += ".cxx";
749 if (gSystem->AccessPathName(fileName) != 0) {
750 //file does not exist
751 //(1) prepare file data
752 // If STL, also request iterators' operators.
753 // vector is special: we need to check whether
754 // vector::iterator is a typedef to pointer or a
755 // class.
756 static const std::set<std::string> sSTLTypes {
757 "vector","list","forward_list","deque","map","unordered_map","multimap",
758 "unordered_multimap","set","unordered_set","multiset","unordered_multiset",
759 "queue","priority_queue","stack","iterator"};
760 std::vector<std::string>::const_iterator it;
761 std::string fileContent("");
762 for (it = headers.begin(); it != headers.end(); ++it) {
763 fileContent += "#include \"" + *it + "\"\n";
764 }
765 for (it = unknown.begin(); it != unknown.end(); ++it) {
766 TClass* cl = TClass::GetClass(it->c_str());
767 if (cl && cl->GetDeclFileName()) {
768 TString header = gSystem->BaseName(cl->GetDeclFileName());
770 TString dirbase(gSystem->BaseName(dir));
771 while (dirbase.Length() && dirbase != "."
772 && dirbase != "include" && dirbase != "inc"
773 && dirbase != "prec_stl") {
774 gSystem->PrependPathName(dirbase, header);
775 dir = gSystem->GetDirName(dir);
776 }
777 fileContent += TString("#include \"") + header + "\"\n";
778 }
779 }
780 for (it = fwdDecls.begin(); it != fwdDecls.end(); ++it) {
781 fileContent += "class " + *it + ";\n";
782 }
783 fileContent += "#ifdef __CINT__ \n";
784 fileContent += "#pragma link C++ nestedclasses;\n";
785 fileContent += "#pragma link C++ nestedtypedefs;\n";
786 for (it = classes.begin(); it != classes.end(); ++it) {
787 std::string n(*it);
788 size_t posTemplate = n.find('<');
789 std::set<std::string>::const_iterator iSTLType = sSTLTypes.end();
790 if (posTemplate != std::string::npos) {
791 n.erase(posTemplate, std::string::npos);
792 if (n.compare(0, 5, "std::") == 0) {
793 n.erase(0, 5);
794 }
795 iSTLType = sSTLTypes.find(n);
796 }
797 fileContent += "#pragma link C++ class ";
798 fileContent += *it + "+;\n" ;
799 fileContent += "#pragma link C++ class ";
800 if (iSTLType != sSTLTypes.end()) {
801 // STL class; we cannot (and don't need to) store iterators;
802 // their shadow and the compiler's version don't agree. So
803 // don't ask for the '+'
804 fileContent += *it + "::*;\n" ;
805 }
806 else {
807 // Not an STL class; we need to allow the I/O of contained
808 // classes (now that we have a dictionary for them).
809 fileContent += *it + "::*+;\n" ;
810 }
811 }
812 fileContent += "#endif\n";
813 //end(1)
814 //(2) prepare the file
815 FILE* filePointer;
816 filePointer = fopen(fileName, "w");
817 if (filePointer == NULL) {
818 //can't open a file
819 return 1;
820 }
821 //end(2)
822 //write data into the file
823 fprintf(filePointer, "%s", fileContent.c_str());
824 fclose(filePointer);
825 }
826 //(3) checking if we can compile a macro, if not then cleaning
827 Int_t oldErrorIgnoreLevel = gErrorIgnoreLevel;
828 gErrorIgnoreLevel = kWarning; // no "Info: creating library..."
829 Int_t ret = gSystem->CompileMacro(fileName, "k");
830 gErrorIgnoreLevel = oldErrorIgnoreLevel;
831 if (ret == 0) { //can't compile a macro
832 return 2;
833 }
834 //end(3)
835 return 0;
836}
837
838int TCling_GenerateDictionary(const std::string& className,
839 const std::vector<std::string> &headers,
840 const std::vector<std::string> &fwdDecls,
841 const std::vector<std::string> &unknown)
842{
843 //This function automatically creates the "LinkDef.h" file for templated
844 //classes then executes CompileMacro on it.
845 //The name of the file depends on the class name, and it's not generated again
846 //if the file exist.
847 std::vector<std::string> classes;
848 classes.push_back(className);
849 return TCling_GenerateDictionary(classes, headers, fwdDecls, unknown);
850}
851
852//______________________________________________________________________________
853//
854//
855//
856
857// It is a "fantom" method to synchronize user keyboard input
858// and ROOT prompt line (for WIN32)
859const char* fantomline = "TRint::EndOfLineAction();";
860
861//______________________________________________________________________________
862//
863//
864//
865
867
868//______________________________________________________________________________
869//
870// llvm error handler through exceptions; see also cling/UserInterface
871//
872namespace {
873 // Handle fatal llvm errors by throwing an exception.
874 // Yes, throwing exceptions in error handlers is bad.
875 // Doing nothing is pretty terrible, too.
876 void exceptionErrorHandler(void * /*user_data*/,
877 const std::string& reason,
878 bool /*gen_crash_diag*/) {
879 throw std::runtime_error(std::string(">>> Interpreter compilation error:\n") + reason);
880 }
881}
882
883//______________________________________________________________________________
884//
885//
886//
887
888////////////////////////////////////////////////////////////////////////////////
889
890namespace{
891 // An instance of this class causes the diagnostics of clang to be suppressed
892 // during its lifetime
893 class clangDiagSuppr {
894 public:
895 clangDiagSuppr(clang::DiagnosticsEngine& diag): fDiagEngine(diag){
896 fOldDiagValue = fDiagEngine.getIgnoreAllWarnings();
897 fDiagEngine.setIgnoreAllWarnings(true);
898 }
899
900 ~clangDiagSuppr() {
901 fDiagEngine.setIgnoreAllWarnings(fOldDiagValue);
902 }
903 private:
904 clang::DiagnosticsEngine& fDiagEngine;
905 bool fOldDiagValue;
906 };
907
908}
909
910////////////////////////////////////////////////////////////////////////////////
911/// Allow calling autoparsing from TMetaUtils
912bool TClingLookupHelper__AutoParse(const char *cname)
913{
914 return gCling->AutoParse(cname);
915}
916
917////////////////////////////////////////////////////////////////////////////////
918/// Try hard to avoid looking up in the Cling database as this could enduce
919/// an unwanted autoparsing.
920
921bool TClingLookupHelper__ExistingTypeCheck(const std::string &tname,
922 std::string &result)
923{
924 result.clear();
925
926 unsigned long offset = 0;
927 if (strncmp(tname.c_str(), "const ", 6) == 0) {
928 offset = 6;
929 }
930 unsigned long end = tname.length();
931 while( end && (tname[end-1]=='&' || tname[end-1]=='*' || tname[end-1]==']') ) {
932 if ( tname[end-1]==']' ) {
933 --end;
934 while ( end && tname[end-1]!='[' ) --end;
935 }
936 --end;
937 }
938 std::string innerbuf;
939 const char *inner;
940 if (end != tname.length()) {
941 innerbuf = tname.substr(offset,end-offset);
942 inner = innerbuf.c_str();
943 } else {
944 inner = tname.c_str()+offset;
945 }
946
947 //if (strchr(tname.c_str(),'[')!=0) fprintf(stderr,"DEBUG: checking on %s vs %s %lu %lu\n",tname.c_str(),inner,offset,end);
948 if (gROOT->GetListOfClasses()->FindObject(inner)
949 || TClassTable::Check(inner,result) ) {
950 // This is a known class.
951 return true;
952 }
953
954 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
955 TDataType *type = (TDataType *)typeTable->THashTable::FindObject( inner );
956 if (type) {
957 // This is a raw type and an already loaded typedef.
958 const char *newname = type->GetFullTypeName();
959 if (type->GetType() == kLong64_t) {
960 newname = "Long64_t";
961 } else if (type->GetType() == kULong64_t) {
962 newname = "ULong64_t";
963 }
964 if (strcmp(inner,newname) == 0) {
965 return true;
966 }
967 if (offset) result = "const ";
968 result += newname;
969 if ( end != tname.length() ) {
970 result += tname.substr(end,tname.length()-end);
971 }
972 if (result == tname) result.clear();
973 return true;
974 }
975
976 // Check if the name is an enumerator
977 const auto lastPos = TClassEdit::GetUnqualifiedName(inner);
978 if (lastPos != inner) // Main switch: case 1 - scoped enum, case 2 global enum
979 {
980 // We have a scope
981 // All of this C gymnastic is to avoid allocations on the heap
982 const auto enName = lastPos;
983 const auto scopeNameSize = ((Long64_t)lastPos - (Long64_t)inner) / sizeof(decltype(*lastPos)) - 2;
984 char *scopeName = new char[scopeNameSize + 1];
985 strncpy(scopeName, inner, scopeNameSize);
986 scopeName[scopeNameSize] = '\0';
987 // Check if the scope is in the list of classes
988 if (auto scope = static_cast<TClass *>(gROOT->GetListOfClasses()->FindObject(scopeName))) {
989 auto enumTable = dynamic_cast<const THashList *>(scope->GetListOfEnums(false));
990 if (enumTable && enumTable->THashList::FindObject(enName)) { delete [] scopeName; return true; }
991 }
992 // It may still be in one of the loaded protoclasses
993 else if (auto scope = static_cast<TProtoClass *>(gClassTable->GetProtoNorm(scopeName))) {
994 auto listOfEnums = scope->GetListOfEnums();
995 if (listOfEnums) { // it could be null: no enumerators in the protoclass
996 auto enumTable = dynamic_cast<const THashList *>(listOfEnums);
997 if (enumTable && enumTable->THashList::FindObject(enName)) { delete [] scopeName; return true; }
998 }
999 }
1000 delete [] scopeName;
1001 } else
1002 {
1003 // We don't have any scope: this could only be a global enum
1004 auto enumTable = dynamic_cast<const THashList *>(gROOT->GetListOfEnums());
1005 if (enumTable && enumTable->THashList::FindObject(inner)) return true;
1006 }
1007
1008 if (gCling->GetClassSharedLibs(inner))
1009 {
1010 // This is a class name.
1011 return true;
1012 }
1013
1014 return false;
1015}
1016
1017////////////////////////////////////////////////////////////////////////////////
1018
1020{
1021 fContent.reserve(size);
1022}
1023
1024////////////////////////////////////////////////////////////////////////////////
1025
1027{
1028 return fContent.c_str();
1029}
1030
1031////////////////////////////////////////////////////////////////////////////////
1032/// Append string to the storage if not added already.
1033
1034inline bool TCling::TUniqueString::Append(const std::string& str)
1035{
1036 bool notPresent = fLinesHashSet.emplace(fHashFunc(str)).second;
1037 if (notPresent){
1038 fContent+=str;
1039 }
1040 return notPresent;
1041}
1042
1043std::string TCling::ToString(const char* type, void* obj)
1044{
1045 return fInterpreter->toString(type, obj);
1046}
1047
1048////////////////////////////////////////////////////////////////////////////////
1049///\returns true if the module was loaded.
1050static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
1051{
1052 // When starting up ROOT, cling would load all modulemap files on the include
1053 // paths. However, in a ROOT session, it is very common to run aclic which
1054 // will invoke rootcling and possibly produce a modulemap and a module in
1055 // the current folder.
1056 //
1057 // Before failing, try loading the modulemap in the current folder and try
1058 // loading the requested module from it.
1059 std::string currentDir = gSystem->WorkingDirectory();
1060 assert(!currentDir.empty());
1062 if (gDebug > 2)
1063 ::Info("TCling::__LoadModule", "Preloading module %s. \n",
1064 ModuleName.c_str());
1065
1066 return interp.loadModule(ModuleName, /*Complain=*/true);
1067}
1068
1069////////////////////////////////////////////////////////////////////////////////
1070/// Loads the C++ modules that we require to run any ROOT program. This is just
1071/// supposed to make a C++ module from a modulemap available to the interpreter.
1072static void LoadModules(const std::vector<std::string> &modules, cling::Interpreter &interp)
1073{
1074 for (const auto &modName : modules)
1075 LoadModule(modName, interp);
1076}
1077
1078static bool IsFromRootCling() {
1079 // rootcling also uses TCling for generating the dictionary ROOT files.
1080 const static bool foundSymbol = dlsym(RTLD_DEFAULT, "usedToIdentifyRootClingByDlSym");
1081 return foundSymbol;
1082}
1083
1084/// Checks if there is an ASTFile on disk for the given module \c M.
1085static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName = nullptr)
1086{
1087 const HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
1088
1089 std::string ModuleFileName;
1090 if (!HSOpts.PrebuiltModulePaths.empty())
1091 // Load the module from *only* in the prebuilt module path.
1092 ModuleFileName = PP.getHeaderSearchInfo().getModuleFileName(M->Name, /*ModuleMapPath*/"", /*UsePrebuiltPath*/ true);
1093 if (FullFileName)
1094 *FullFileName = ModuleFileName;
1095
1096 return !ModuleFileName.empty();
1097}
1098
1099static bool HaveFullGlobalModuleIndex = false;
1100static GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc, cling::Interpreter &interp)
1101{
1102 CompilerInstance &CI = *interp.getCI();
1103 Preprocessor &PP = CI.getPreprocessor();
1104 auto ModuleManager = CI.getModuleManager();
1105 assert(ModuleManager);
1106 // StringRef ModuleIndexPath = HSI.getModuleCachePath();
1107 // HeaderSearch& HSI = PP.getHeaderSearchInfo();
1108 // HSI.setModuleCachePath(TROOT::GetLibDir().Data());
1109 std::string ModuleIndexPath = TROOT::GetLibDir().Data();
1110 if (ModuleIndexPath.empty())
1111 return nullptr;
1112 // Get an existing global index. This loads it if not already loaded.
1113 ModuleManager->resetForReload();
1114 ModuleManager->loadGlobalIndex();
1115 GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex();
1116
1117 // For finding modules needing to be imported for fixit messages,
1118 // we need to make the global index cover all modules, so we do that here.
1119 if (!GlobalIndex && !HaveFullGlobalModuleIndex) {
1120 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1121 bool RecreateIndex = false;
1122 for (ModuleMap::module_iterator I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1123 Module *TheModule = I->second;
1124 // We want the index only of the prebuilt modules.
1125 if (!HasASTFileOnDisk(TheModule, PP))
1126 continue;
1127 LoadModule(TheModule->Name, interp);
1128 RecreateIndex = true;
1129 }
1130 if (RecreateIndex) {
1131 GlobalModuleIndex::writeIndex(CI.getFileManager(), CI.getPCHContainerReader(), ModuleIndexPath);
1132 ModuleManager->resetForReload();
1133 ModuleManager->loadGlobalIndex();
1134 GlobalIndex = ModuleManager->getGlobalIndex();
1135 }
1137 }
1138 return GlobalIndex;
1139}
1140
1141static void RegisterCxxModules(cling::Interpreter &clingInterp)
1142{
1143 if (!clingInterp.getCI()->getLangOpts().Modules)
1144 return;
1145 // Setup core C++ modules if we have any to setup.
1146
1147 // Load libc and stl first.
1148 // Load vcruntime module for windows
1149#ifdef R__WIN32
1150 LoadModule("vcruntime", clingInterp);
1151#endif
1152
1153#ifdef R__MACOSX
1154 LoadModule("Darwin", clingInterp);
1155#else
1156 LoadModule("libc", clingInterp);
1157#endif
1158 LoadModule("std", clingInterp);
1159
1160 LoadModule("_Builtin_intrinsics", clingInterp);
1161
1162 // Load core modules
1163 // This should be vector in order to be able to pass it to LoadModules
1164 std::vector<std::string> CoreModules = {"ROOT_Foundation_C",
1165 "ROOT_Config",
1166 "ROOT_Rtypes",
1167 "ROOT_Foundation_Stage1_NoRTTI",
1168 "Core",
1169 "RIO"};
1170
1171 LoadModules(CoreModules, clingInterp);
1172
1173 // FIXME: Reducing those will let us be less dependent on rootmap files
1174 static constexpr std::array<const char *, 3> ExcludeModules = {
1175 {"Rtools", "RSQLite", "RInterface"}};
1176
1177 // Take this branch only from ROOT because we don't need to preload modules in rootcling
1178 if (!IsFromRootCling()) {
1179 std::vector<std::string> CommonModules = {"MathCore"};
1180 LoadModules(CommonModules, clingInterp);
1181
1182 // These modules should not be preloaded but they fix issues.
1183 std::vector<std::string> FIXMEModules = {"Hist", "Gpad", "Graf",
1184 "GenVector", "Smatrix", "Tree",
1185 "TreePlayer", "Physics",
1186 "Proof", "Geom"};
1187 LoadModules(FIXMEModules, clingInterp);
1188
1189 clang::CompilerInstance &CI = *clingInterp.getCI();
1190 GlobalModuleIndex *GlobalIndex = nullptr;
1191 const char *experimentalGMI = gSystem->Getenv("ROOT_EXPERIMENTAL_GMI");
1192 if (experimentalGMI && strcmp(experimentalGMI,"false") != 0) {
1193 loadGlobalModuleIndex(SourceLocation(), clingInterp);
1194 GlobalIndex = CI.getModuleManager()->getGlobalIndex();
1195 }
1196 llvm::StringSet<> KnownModuleFileNames;
1197 if (GlobalIndex)
1198 GlobalIndex->getKnownModuleFileNames(KnownModuleFileNames);
1199
1200 clang::Preprocessor &PP = CI.getPreprocessor();
1201 std::vector<std::string> PendingModules;
1202 PendingModules.reserve(256);
1203 ModuleMap &MMap = PP.getHeaderSearchInfo().getModuleMap();
1204 for (auto I = MMap.module_begin(), E = MMap.module_end(); I != E; ++I) {
1205 clang::Module *M = I->second;
1206 assert(M);
1207
1208 // We want to load only already created modules.
1209 std::string FullASTFilePath;
1210 if (!HasASTFileOnDisk(M, PP, &FullASTFilePath))
1211 continue;
1212
1213 if (GlobalIndex && KnownModuleFileNames.count(FullASTFilePath))
1214 continue;
1215
1216 if (M->IsMissingRequirement)
1217 continue;
1218
1219 if (GlobalIndex)
1220 LoadModule(M->Name, clingInterp);
1221 else {
1222 // FIXME: We may be able to remove those checks as cling::loadModule
1223 // checks if a module was alredy loaded.
1224 if (std::find(CoreModules.begin(), CoreModules.end(), M->Name) != CoreModules.end())
1225 continue; // This is a core module which was already loaded.
1226
1227 if (std::find(ExcludeModules.begin(), ExcludeModules.end(), M->Name) != ExcludeModules.end())
1228 continue;
1229
1230 // Load system modules now and delay the other modules after we have
1231 // loaded all system ones.
1232 if (M->IsSystem)
1233 LoadModule(M->Name, clingInterp);
1234 else
1235 PendingModules.push_back(M->Name);
1236 }
1237 }
1238 LoadModules(PendingModules, clingInterp);
1239 }
1240
1241 // Check that the gROOT macro was exported by any core module.
1242 assert(clingInterp.getMacro("gROOT") && "Couldn't load gROOT macro?");
1243
1244 // C99 decided that it's a very good idea to name a macro `I` (the letter I).
1245 // This seems to screw up nearly all the template code out there as `I` is
1246 // common template parameter name and iterator variable name.
1247 // Let's follow the GCC recommendation and undefine `I` in case any of the
1248 // core modules have defined it:
1249 // https://www.gnu.org/software/libc/manual/html_node/Complex-Numbers.html
1250 clingInterp.declare("#ifdef I\n #undef I\n #endif\n");
1251
1252 // libc++ complex.h has #define complex _Complex. Give preference to the one
1253 // in std.
1254 clingInterp.declare("#ifdef complex\n #undef complex\n #endif\n");
1255
1256 // These macros are from loading R related modules, which conflict with
1257 // user's code.
1258 clingInterp.declare("#ifdef PI\n #undef PI\n #endif\n");
1259 clingInterp.declare("#ifdef ERROR\n #undef ERROR\n #endif\n");
1260}
1261
1262static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
1263{
1264 std::string PreIncludes;
1265 bool hasCxxModules = clingInterp.getCI()->getLangOpts().Modules;
1266
1267 // For the list to also include string, we have to include it now.
1268 // rootcling does parts already if needed, e.g. genreflex does not want using
1269 // namespace std.
1270 if (IsFromRootCling()) {
1271 PreIncludes += "#include \"RtypesCore.h\"\n";
1272 } else {
1273 if (!hasCxxModules)
1274 PreIncludes += "#include \"Rtypes.h\"\n";
1275
1276 PreIncludes += gClassDefInterpMacro + "\n"
1277 + gInterpreterClassDef + "\n"
1278 "#undef ClassImp\n"
1279 "#define ClassImp(X);\n";
1280 }
1281 if (!hasCxxModules)
1282 PreIncludes += "#include <string>\n";
1283
1284 // We must include it even when we have modules because it is marked as
1285 // textual in the modulemap due to the nature of the assert header.
1286#ifndef R__WIN32
1287 PreIncludes += "#include <cassert>\n";
1288#endif
1289 PreIncludes += "using namespace std;\n";
1290 clingInterp.declare(PreIncludes);
1291}
1292
1293////////////////////////////////////////////////////////////////////////////////
1294/// Initialize the cling interpreter interface.
1295/// \param argv - array of arguments passed to the cling::Interpreter constructor
1296/// e.g. `-DFOO=bar`. The last element of the array must be `nullptr`.
1297
1298TCling::TCling(const char *name, const char *title, const char* const argv[])
1299: TInterpreter(name, title), fMore(0), fGlobalsListSerial(-1), fMapfile(nullptr),
1303{
1304 fPrompt[0] = 0;
1305 const bool fromRootCling = IsFromRootCling();
1306
1307 fCxxModulesEnabled = false;
1308#ifdef R__USE_CXXMODULES
1309 fCxxModulesEnabled = true;
1310#endif
1311
1312 llvm::install_fatal_error_handler(&exceptionErrorHandler);
1313
1314 fTemporaries = new std::vector<cling::Value>();
1315
1316 std::vector<std::string> clingArgsStorage;
1317 clingArgsStorage.push_back("cling4root");
1318 for (const char* const* arg = argv; *arg; ++arg)
1319 clingArgsStorage.push_back(*arg);
1320
1321 // rootcling sets its arguments through TROOT::GetExtraInterpreterArgs().
1322 if (!fromRootCling) {
1324
1325 // Add -I early so ASTReader can find the headers.
1326 std::string interpInclude(TROOT::GetEtcDir().Data());
1327 clingArgsStorage.push_back("-I" + interpInclude);
1328
1329 // Add include path to etc/cling.
1330 clingArgsStorage.push_back("-I" + interpInclude + "/cling");
1331
1332 // Add the root include directory and etc/ to list searched by default.
1333 clingArgsStorage.push_back(std::string(("-I" + TROOT::GetIncludeDir()).Data()));
1334
1335 // Add the current path to the include path
1336 // TCling::AddIncludePath(".");
1337
1338 // Attach the PCH (unless we have C++ modules enabled which provide the
1339 // same functionality).
1340 if (!fCxxModulesEnabled) {
1341 std::string pchFilename = interpInclude + "/allDict.cxx.pch";
1342 if (gSystem->Getenv("ROOT_PCH")) {
1343 pchFilename = gSystem->Getenv("ROOT_PCH");
1344 }
1345
1346 clingArgsStorage.push_back("-include-pch");
1347 clingArgsStorage.push_back(pchFilename);
1348 }
1349
1350 clingArgsStorage.push_back("-Wno-undefined-inline");
1351 clingArgsStorage.push_back("-fsigned-char");
1352 }
1353
1354 // Process externally passed arguments if present.
1355 llvm::Optional<std::string> EnvOpt = llvm::sys::Process::GetEnv("EXTRA_CLING_ARGS");
1356 if (EnvOpt.hasValue()) {
1357 StringRef Env(*EnvOpt);
1358 while (!Env.empty()) {
1359 StringRef Arg;
1360 std::tie(Arg, Env) = Env.split(' ');
1361 clingArgsStorage.push_back(Arg.str());
1362 }
1363 }
1364
1365 auto GetEnvVarPath = [](const std::string &EnvVar,
1366 std::vector<std::string> &Paths) {
1367 llvm::Optional<std::string> EnvOpt = llvm::sys::Process::GetEnv(EnvVar);
1368 if (EnvOpt.hasValue()) {
1369 StringRef Env(*EnvOpt);
1370 while (!Env.empty()) {
1371 StringRef Arg;
1372 std::tie(Arg, Env) = Env.split(ROOT::FoundationUtils::GetEnvPathSeparator());
1373 if (std::find(Paths.begin(), Paths.end(), Arg.str()) == Paths.end())
1374 Paths.push_back(Arg.str());
1375 }
1376 }
1377 };
1378
1379 if (fCxxModulesEnabled) {
1380 std::vector<std::string> Paths;
1381 // ROOT usually knows better where its libraries are. This way we can
1382 // discover modules without having to should thisroot.sh and should fix
1383 // gnuinstall.
1384 Paths.push_back(TROOT::GetLibDir().Data());
1385 GetEnvVarPath("CLING_PREBUILT_MODULE_PATH", Paths);
1386 //GetEnvVarPath("LD_LIBRARY_PATH", Paths);
1387 std::string EnvVarPath;
1388 for (const std::string& P : Paths)
1390 // FIXME: We should make cling -fprebuilt-module-path work.
1391 gSystem->Setenv("CLING_PREBUILT_MODULE_PATH", EnvVarPath.c_str());
1392 }
1393
1394 // FIXME: This only will enable frontend timing reports.
1395 EnvOpt = llvm::sys::Process::GetEnv("ROOT_CLING_TIMING");
1396 if (EnvOpt.hasValue())
1397 clingArgsStorage.push_back("-ftime-report");
1398
1399 // Add the overlay file. Note that we cannot factor it out for both root
1400 // and rootcling because rootcling activates modules only if -cxxmodule
1401 // flag is passed.
1402 if (fCxxModulesEnabled && !fromRootCling) {
1403 // For now we prefer rootcling to enumerate explicitly its modulemaps.
1404 std::vector<std::string> Paths;
1405 Paths.push_back(TROOT::GetIncludeDir().Data());
1406 GetEnvVarPath("CLING_MODULEMAP_PATH", Paths);
1407
1408 // Give highest precedence of the modulemap in the cwd.
1409 Paths.push_back(gSystem->WorkingDirectory());
1410
1411 for (const std::string& P : Paths) {
1412 std::string ModuleMapLoc = P + ROOT::FoundationUtils::GetPathSeparator()
1413 + "module.modulemap";
1414 if (!llvm::sys::fs::exists(ModuleMapLoc)) {
1415 if (gDebug > 1)
1416 ::Info("TCling::TCling", "Modulemap %s does not exist \n",
1417 ModuleMapLoc.c_str());
1418
1419 continue;
1420 }
1421
1422 clingArgsStorage.push_back("-fmodule-map-file=" + ModuleMapLoc);
1423 }
1424 std::string ModulesCachePath;
1425 EnvOpt = llvm::sys::Process::GetEnv("CLING_MODULES_CACHE_PATH");
1426 if (EnvOpt.hasValue()){
1427 StringRef Env(*EnvOpt);
1428 assert(llvm::sys::fs::exists(Env) && "Path does not exist!");
1429 ModulesCachePath = Env.str();
1430 } else {
1431 ModulesCachePath = TROOT::GetLibDir();
1432 }
1433
1434 clingArgsStorage.push_back("-fmodules-cache-path=" + ModulesCachePath);
1435 }
1436
1437 std::vector<const char*> interpArgs;
1438 for (std::vector<std::string>::const_iterator iArg = clingArgsStorage.begin(),
1439 eArg = clingArgsStorage.end(); iArg != eArg; ++iArg)
1440 interpArgs.push_back(iArg->c_str());
1441
1442 // Activate C++ modules support. If we are running within rootcling, it's up
1443 // to rootcling to set this flag depending on whether it wants to produce
1444 // C++ modules.
1445 TString vfsArg;
1446 if (fCxxModulesEnabled) {
1447 if (!fromRootCling) {
1448 // We only set this flag, rest is done by the CIFactory.
1449 interpArgs.push_back("-fmodules");
1450 interpArgs.push_back("-fno-implicit-module-maps");
1451 // We should never build modules during runtime, so let's enable the
1452 // module build remarks from clang to make it easier to spot when we do
1453 // this by accident.
1454 interpArgs.push_back("-Rmodule-build");
1455 }
1456 // ROOT implements its AutoLoading upon module's link directives. We
1457 // generate module A { header "A.h" link "A.so" export * } where ROOT's
1458 // facilities use the link directive to dynamically load the relevant
1459 // library. So, we need to suppress clang's default autolink behavior.
1460 interpArgs.push_back("-fno-autolink");
1461 }
1462
1463#ifdef R__FAST_MATH
1464 // Same setting as in rootcling_impl.cxx.
1465 interpArgs.push_back("-ffast-math");
1466#endif
1467
1468 TString llvmResourceDir = TROOT::GetEtcDir() + "/cling";
1469 // Add statically injected extra arguments, usually coming from rootcling.
1470 for (const char** extraArgs = TROOT::GetExtraInterpreterArgs();
1471 extraArgs && *extraArgs; ++extraArgs) {
1472 if (!strcmp(*extraArgs, "-resource-dir")) {
1473 // Take the next arg as the llvm resource directory.
1474 llvmResourceDir = *(++extraArgs);
1475 } else {
1476 interpArgs.push_back(*extraArgs);
1477 }
1478 }
1479
1480 for (const auto &arg: TROOT::AddExtraInterpreterArgs({})) {
1481 interpArgs.push_back(arg.c_str());
1482 }
1483
1484 // Add the Rdict module file extension.
1485 cling::Interpreter::ModuleFileExtensions extensions;
1486 EnvOpt = llvm::sys::Process::GetEnv("ROOTDEBUG_RDICT");
1487 if (!EnvOpt.hasValue())
1488 extensions.push_back(std::make_shared<TClingRdictModuleFileExtension>());
1489
1490 fInterpreter = llvm::make_unique<cling::Interpreter>(interpArgs.size(),
1491 &(interpArgs[0]),
1492 llvmResourceDir, extensions);
1493
1494 if (!fromRootCling) {
1495 fInterpreter->installLazyFunctionCreator(llvmLazyFunctionCreator);
1496 }
1497
1498 // Don't check whether modules' files exist.
1499 fInterpreter->getCI()->getPreprocessorOpts().DisablePCHValidation = true;
1500
1501 // Until we can disable AutoLoading during Sema::CorrectTypo() we have
1502 // to disable spell checking.
1503 fInterpreter->getCI()->getLangOpts().SpellChecking = false;
1504
1505 // We need stream that doesn't close its file descriptor, thus we are not
1506 // using llvm::outs. Keeping file descriptor open we will be able to use
1507 // the results in pipes (Savannah #99234).
1508 static llvm::raw_fd_ostream fMPOuts (STDOUT_FILENO, /*ShouldClose*/false);
1509 fMetaProcessor = llvm::make_unique<cling::MetaProcessor>(*fInterpreter, fMPOuts);
1510
1513
1514 // We are now ready (enough is loaded) to init the list of opaque typedefs.
1521
1522 // Disallow auto-parsing in rootcling
1523 fIsAutoParsingSuspended = fromRootCling;
1524
1525 ResetAll();
1526
1527 // Enable dynamic lookup
1528 if (!fromRootCling) {
1529 fInterpreter->enableDynamicLookup();
1530 }
1531
1532 // Enable ClinG's DefinitionShadower for ROOT.
1533 fInterpreter->allowRedefinition();
1534
1535 // Attach cling callbacks last; they might need TROOT::fInterpreter
1536 // and should thus not be triggered during the equivalent of
1537 // TROOT::fInterpreter = new TCling;
1538 std::unique_ptr<TClingCallbacks>
1539 clingCallbacks(new TClingCallbacks(GetInterpreterImpl(), /*hasCodeGen*/ !fromRootCling));
1540 fClingCallbacks = clingCallbacks.get();
1542 fInterpreter->setCallbacks(std::move(clingCallbacks));
1543
1544 if (!fromRootCling) {
1545 cling::DynamicLibraryManager& DLM = *fInterpreter->getDynamicLibraryManager();
1546 // Make sure cling looks into ROOT's libdir, even if not part of LD_LIBRARY_PATH
1547 // e.g. because of an RPATH build.
1548 DLM.addSearchPath(TROOT::GetLibDir().Data());
1549 auto ShouldPermanentlyIgnore = [](llvm::StringRef FileName) -> bool{
1550 llvm::StringRef stem = llvm::sys::path::stem(FileName);
1551 return stem.startswith("libNew") || stem.startswith("libcppyy_backend");
1552 };
1553 // Initialize the dyld for the llvmLazyFunctionCreator.
1554 DLM.initializeDyld(ShouldPermanentlyIgnore);
1555 }
1556}
1557
1558
1559////////////////////////////////////////////////////////////////////////////////
1560/// Destroy the interpreter interface.
1561
1563{
1564 // ROOT's atexit functions require the interepreter to be available.
1565 // Run them before shutting down.
1566 if (!IsFromRootCling())
1567 GetInterpreterImpl()->runAtExitFuncs();
1568 fIsShuttingDown = true;
1569 delete fMapfile;
1570 delete fRootmapFiles;
1571 delete fTemporaries;
1572 delete fNormalizedCtxt;
1573 delete fLookupHelper;
1574 gCling = 0;
1575}
1576
1577////////////////////////////////////////////////////////////////////////////////
1578/// Initialize the interpreter, once TROOT::fInterpreter is set.
1579
1581{
1583
1584 // We are set up. Enable ROOT's AutoLoading.
1585 if (IsFromRootCling())
1586 return;
1587
1588 // Read the rules before enabling the auto loading to not inadvertently
1589 // load the libraries for the classes concerned even-though the user is
1590 // *not* using them.
1591 // Note this call must happen before the first call to LoadLibraryMap.
1592 assert(GetRootMapFiles() == 0 && "Must be called before LoadLibraryMap!");
1593 TClass::ReadRules(); // Read the default customization rules ...
1594
1596 SetClassAutoLoading(true);
1597}
1598
1600{
1601 fIsShuttingDown = true;
1602 ResetGlobals();
1603}
1604
1605////////////////////////////////////////////////////////////////////////////////
1606/// Helper to initialize TVirtualStreamerInfo's factor early.
1607/// Use static initialization to insure only one TStreamerInfo is created.
1609{
1610 // Use lambda since SetFactory return void.
1611 auto setFactory = []() {
1613 return kTRUE;
1614 };
1615 static bool doneFactory = setFactory();
1616 return doneFactory; // avoid unused variable warning.
1617}
1618
1619////////////////////////////////////////////////////////////////////////////////
1620/// Register Rdict data for future loading by LoadPCM;
1621
1622void TCling::RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
1623{
1624 if (IsFromRootCling())
1625 return;
1626
1627 if (llvm::sys::fs::exists(pcmFileNameFullPath)) {
1628 ::Error("TCling::RegisterRdictForLoadPCM", "Rdict '%s' is both in Module extension and in File system.", pcmFileNameFullPath.c_str());
1629 return;
1630 }
1631
1632 // The pcmFileNameFullPath must be resolved already because we cannot resolve
1633 // a link to a non-existent file.
1634 fPendingRdicts[pcmFileNameFullPath] = *pcmContent;
1635}
1636
1637////////////////////////////////////////////////////////////////////////////////
1638/// Tries to load a PCM from TFile; returns true on success.
1639
1641{
1642 auto listOfKeys = pcmFile.GetListOfKeys();
1643
1644 // This is an empty pcm
1645 if (listOfKeys && ((listOfKeys->GetSize() == 0) || // Nothing here, or
1646 ((listOfKeys->GetSize() == 1) && // only one, and
1647 !strcmp(((TKey *)listOfKeys->At(0))->GetName(), "EMPTY") // name is EMPTY
1648 ))) {
1649 return;
1650 }
1651
1652 TObjArray *protoClasses;
1653 if (gDebug > 1)
1654 ::Info("TCling::LoadPCMImpl", "reading protoclasses for %s \n", pcmFile.GetName());
1655
1656 pcmFile.GetObject("__ProtoClasses", protoClasses);
1657
1658 if (protoClasses) {
1659 for (auto obj : *protoClasses) {
1660 TProtoClass *proto = (TProtoClass *)obj;
1662 }
1663 // Now that all TClass-es know how to set them up we can update
1664 // existing TClasses, which might cause the creation of e.g. TBaseClass
1665 // objects which in turn requires the creation of TClasses, that could
1666 // come from the PCH, but maybe later in the loop. Instead of resolving
1667 // a dependency graph the addition to the TClassTable above allows us
1668 // to create these dependent TClasses as needed below.
1669 for (auto proto : *protoClasses) {
1670 if (TClass *existingCl = (TClass *)gROOT->GetListOfClasses()->FindObject(proto->GetName())) {
1671 // We have an existing TClass object. It might be emulated
1672 // or interpreted; we now have more information available.
1673 // Make that available.
1674 if (existingCl->GetState() != TClass::kHasTClassInit) {
1675 DictFuncPtr_t dict = gClassTable->GetDict(proto->GetName());
1676 if (!dict) {
1677 ::Error("TCling::LoadPCM", "Inconsistent TClassTable for %s", proto->GetName());
1678 } else {
1679 // This will replace the existing TClass.
1680 TClass *ncl = (*dict)();
1681 if (ncl)
1682 ncl->PostLoadCheck();
1683 }
1684 }
1685 }
1686 }
1687
1688 protoClasses->Clear(); // Ownership was transfered to TClassTable.
1689 delete protoClasses;
1690 }
1691
1692 TObjArray *dataTypes;
1693 pcmFile.GetObject("__Typedefs", dataTypes);
1694 if (dataTypes) {
1695 for (auto typedf : *dataTypes)
1696 gROOT->GetListOfTypes()->Add(typedf);
1697 dataTypes->Clear(); // Ownership was transfered to TListOfTypes.
1698 delete dataTypes;
1699 }
1700
1701 TObjArray *enums;
1702 pcmFile.GetObject("__Enums", enums);
1703 if (enums) {
1704 // Cache the pointers
1705 auto listOfGlobals = gROOT->GetListOfGlobals();
1706 auto listOfEnums = dynamic_cast<THashList *>(gROOT->GetListOfEnums());
1707 // Loop on enums and then on enum constants
1708 for (auto selEnum : *enums) {
1709 const char *enumScope = selEnum->GetTitle();
1710 const char *enumName = selEnum->GetName();
1711 if (strcmp(enumScope, "") == 0) {
1712 // This is a global enum and is added to the
1713 // list of enums and its constants to the list of globals
1714 if (!listOfEnums->THashList::FindObject(enumName)) {
1715 ((TEnum *)selEnum)->SetClass(nullptr);
1716 listOfEnums->Add(selEnum);
1717 }
1718 for (auto enumConstant : *static_cast<TEnum *>(selEnum)->GetConstants()) {
1719 if (!listOfGlobals->FindObject(enumConstant)) {
1720 listOfGlobals->Add(enumConstant);
1721 }
1722 }
1723 } else {
1724 // This enum is in a namespace. A TClass entry is bootstrapped if
1725 // none exists yet and the enum is added to it
1726 TClass *nsTClassEntry = TClass::GetClass(enumScope);
1727 if (!nsTClassEntry) {
1728 nsTClassEntry = new TClass(enumScope, 0, TClass::kNamespaceForMeta, true);
1729 }
1730 auto listOfEnums = nsTClassEntry->fEnums.load();
1731 if (!listOfEnums) {
1732 if ((kIsClass | kIsStruct | kIsUnion) & nsTClassEntry->Property()) {
1733 // For this case, the list will be immutable once constructed
1734 // (i.e. in this case, by the end of this routine).
1735 listOfEnums = nsTClassEntry->fEnums = new TListOfEnums(nsTClassEntry);
1736 } else {
1737 // namespaces can have enums added to them
1738 listOfEnums = nsTClassEntry->fEnums = new TListOfEnumsWithLock(nsTClassEntry);
1739 }
1740 }
1741 if (listOfEnums && !listOfEnums->THashList::FindObject(enumName)) {
1742 ((TEnum *)selEnum)->SetClass(nsTClassEntry);
1743 listOfEnums->Add(selEnum);
1744 }
1745 }
1746 }
1747 enums->Clear();
1748 delete enums;
1749 }
1750}
1751
1752////////////////////////////////////////////////////////////////////////////////
1753/// Tries to load a rdict PCM, issues diagnostics if it fails.
1754
1755void TCling::LoadPCM(std::string pcmFileNameFullPath)
1756{
1757 SuspendAutoLoadingRAII autoloadOff(this);
1758 SuspendAutoParsing autoparseOff(this);
1759 assert(!pcmFileNameFullPath.empty());
1760 assert(llvm::sys::path::is_absolute(pcmFileNameFullPath));
1761
1762 // Easier to work with the ROOT interfaces.
1763 TString pcmFileName = pcmFileNameFullPath;
1764
1765 // Prevent the ROOT-PCMs hitting this during auto-load during
1766 // JITting - which will cause recursive compilation.
1767 // Avoid to call the plugin manager at all.
1769
1771 llvm::SaveAndRestore<Int_t> SaveGDebug(gDebug);
1772 if (gDebug > 5) {
1773 gDebug -= 5;
1774 ::Info("TCling::LoadPCM", "Loading ROOT PCM %s", pcmFileName.Data());
1775 } else {
1776 gDebug = 0;
1777 }
1778
1779 if (llvm::sys::fs::is_symlink_file(pcmFileNameFullPath))
1780 pcmFileNameFullPath = ROOT::TMetaUtils::GetRealPath(pcmFileNameFullPath);
1781
1782 auto pendingRdict = fPendingRdicts.find(pcmFileNameFullPath);
1783 if (pendingRdict != fPendingRdicts.end()) {
1784 llvm::StringRef pcmContent = pendingRdict->second;
1785 TMemFile::ZeroCopyView_t range{pcmContent.data(), pcmContent.size()};
1786 std::string RDictFileOpts = pcmFileNameFullPath + "?filetype=pcm";
1787 TMemFile pcmMemFile(RDictFileOpts.c_str(), range);
1788
1789 LoadPCMImpl(pcmMemFile);
1790 fPendingRdicts.erase(pendingRdict);
1791
1792 return;
1793 }
1794
1795 if (!llvm::sys::fs::exists(pcmFileNameFullPath)) {
1796 ::Error("TCling::LoadPCM", "ROOT PCM %s file does not exist",
1797 pcmFileNameFullPath.data());
1798 if (!fPendingRdicts.empty())
1799 for (const auto &rdict : fPendingRdicts)
1800 ::Info("TCling::LoadPCM", "In-memory ROOT PCM candidate %s\n",
1801 rdict.first.c_str());
1802 return;
1803 }
1804
1805 if (!gROOT->IsRootFile(pcmFileName)) {
1806 Fatal("LoadPCM", "The file %s is not a ROOT as was expected\n", pcmFileName.Data());
1807 return;
1808 }
1809 TFile pcmFile(pcmFileName + "?filetype=pcm", "READ");
1810 LoadPCMImpl(pcmFile);
1811}
1812
1813//______________________________________________________________________________
1814
1815namespace {
1816 using namespace clang;
1817
1818 class ExtLexicalStorageAdder: public RecursiveASTVisitor<ExtLexicalStorageAdder>{
1819 // This class is to be considered an helper for autoparsing.
1820 // It visits the AST and marks all classes (in all of their redeclarations)
1821 // with the setHasExternalLexicalStorage method.
1822 public:
1823 bool VisitRecordDecl(clang::RecordDecl* rcd){
1824 if (gDebug > 2)
1825 Info("ExtLexicalStorageAdder",
1826 "Adding external lexical storage to class %s",
1827 rcd->getNameAsString().c_str());
1828 auto reDeclPtr = rcd->getMostRecentDecl();
1829 do {
1830 reDeclPtr->setHasExternalLexicalStorage();
1831 } while ((reDeclPtr = reDeclPtr->getPreviousDecl()));
1832
1833 return false;
1834 }
1835 };
1836
1837
1838}
1839
1840////////////////////////////////////////////////////////////////////////////////
1841///\returns true if the module map was loaded, false on error or if the map was
1842/// already loaded.
1843bool TCling::RegisterPrebuiltModulePath(const std::string &FullPath,
1844 const std::string &ModuleMapName /*= "module.modulemap"*/) const
1845{
1846 assert(llvm::sys::path::is_absolute(FullPath));
1847 Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
1848 FileManager &FM = PP.getFileManager();
1849 // FIXME: In a ROOT session we can add an include path (through .I /inc/path)
1850 // We should look for modulemap files there too.
1851 const DirectoryEntry *DE = FM.getDirectory(FullPath);
1852 if (DE) {
1853 HeaderSearch &HS = PP.getHeaderSearchInfo();
1854 HeaderSearchOptions &HSOpts = HS.getHeaderSearchOpts();
1855 const auto &ModPaths = HSOpts.PrebuiltModulePaths;
1856 bool pathExists = std::find(ModPaths.begin(), ModPaths.end(), FullPath) != ModPaths.end();
1857 if (!pathExists)
1858 HSOpts.AddPrebuiltModulePath(FullPath);
1859 // We cannot use HS.lookupModuleMapFile(DE, /*IsFramework*/ false);
1860 // because its internal call to getFile has CacheFailure set to true.
1861 // In our case, modulemaps can appear any time due to ACLiC.
1862 // Code copied from HS.lookupModuleMapFile.
1863 llvm::SmallString<256> ModuleMapFileName(DE->getName());
1864 llvm::sys::path::append(ModuleMapFileName, ModuleMapName);
1865 const FileEntry *FE = FM.getFile(ModuleMapFileName, /*openFile*/ false,
1866 /*CacheFailure*/ false);
1867
1868 // FIXME: Calling IsLoaded is slow! Replace this with the appropriate
1869 // call to the clang::ModuleMap class.
1870 if (FE && !this->IsLoaded(FE->getName().data())) {
1871 if (!HS.loadModuleMapFile(FE, /*IsSystem*/ false))
1872 return true;
1873 Error("RegisterPrebuiltModulePath", "Could not load modulemap in %s", ModuleMapFileName.c_str());
1874 }
1875 }
1876 return false;
1877}
1878
1879////////////////////////////////////////////////////////////////////////////////
1880/// List of dicts that have the PCM information already in the PCH.
1881static const std::unordered_set<std::string> gIgnoredPCMNames = {"libCore",
1882 "libRint",
1883 "libThread",
1884 "libRIO",
1885 "libImt",
1886 "libcomplexDict",
1887 "libdequeDict",
1888 "liblistDict",
1889 "libforward_listDict",
1890 "libvectorDict",
1891 "libmapDict",
1892 "libmultimap2Dict",
1893 "libmap2Dict",
1894 "libmultimapDict",
1895 "libsetDict",
1896 "libmultisetDict",
1897 "libunordered_setDict",
1898 "libunordered_multisetDict",
1899 "libunordered_mapDict",
1900 "libunordered_multimapDict",
1901 "libvalarrayDict",
1902 "G__GenVector32",
1903 "G__Smatrix32"};
1904
1905static void PrintDlError(const char *dyLibName, const char *modulename)
1906{
1907#ifdef R__WIN32
1908 char dyLibError[1000];
1909 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1910 dyLibError, sizeof(dyLibError), NULL);
1911#else
1912 const char *dyLibError = dlerror();
1913#endif
1914 ::Error("TCling::RegisterModule", "Cannot open shared library %s for dictionary %s:\n %s", dyLibName, modulename,
1915 (dyLibError) ? dyLibError : "");
1916}
1917
1918////////////////////////////////////////////////////////////////////////////////
1919// Update all the TClass registered in fClassesToUpdate
1920
1922{
1923 while (!fClassesToUpdate.empty()) {
1924 TClass *oldcl = fClassesToUpdate.back().first;
1925 // If somehow the TClass has already been loaded (maybe it was registered several time),
1926 // we skip it. Otherwise, the existing TClass is in mode kInterpreted, kEmulated or
1927 // maybe even kForwardDeclared and needs to replaced.
1928 if (oldcl->GetState() != TClass::kHasTClassInit) {
1929 // if (gDebug > 2) Info("RegisterModule", "Forcing TClass init for %s", oldcl->GetName());
1930 DictFuncPtr_t dict = fClassesToUpdate.back().second;
1931 fClassesToUpdate.pop_back();
1932 // Calling func could manipulate the list so, let maintain the list
1933 // then call the dictionary function.
1934 TClass *ncl = dict();
1935 if (ncl) ncl->PostLoadCheck();
1936 } else {
1937 fClassesToUpdate.pop_back();
1938 }
1939 }
1940}
1941////////////////////////////////////////////////////////////////////////////////
1942/// Inject the module named "modulename" into cling; load all headers.
1943/// headers is a 0-terminated array of header files to #include after
1944/// loading the module. The module is searched for in all $LD_LIBRARY_PATH
1945/// entries (or %PATH% on Windows).
1946/// This function gets called by the static initialization of dictionary
1947/// libraries.
1948/// The payload code is injected "as is" in the interpreter.
1949/// The value of 'triggerFunc' is used to find the shared library location.
1950
1951void TCling::RegisterModule(const char* modulename,
1952 const char** headers,
1953 const char** includePaths,
1954 const char* payloadCode,
1955 const char* fwdDeclsCode,
1956 void (*triggerFunc)(),
1957 const FwdDeclArgsToKeepCollection_t& fwdDeclsArgToSkip,
1958 const char** classesHeaders,
1959 Bool_t lateRegistration /*=false*/,
1960 Bool_t hasCxxModule /*=false*/)
1961{
1962 const bool fromRootCling = IsFromRootCling();
1963 // We need the dictionary initialization but we don't want to inject the
1964 // declarations into the interpreter, except for those we really need for
1965 // I/O; see rootcling.cxx after the call to TCling__GetInterpreter().
1966 if (fromRootCling) return;
1967
1968 // When we cannot provide a module for the library we should enable header
1969 // parsing. This 'mixed' mode ensures gradual migration to modules.
1970 llvm::SaveAndRestore<bool> SaveHeaderParsing(fHeaderParsingOnDemand);
1971 fHeaderParsingOnDemand = !hasCxxModule;
1972
1973 // Treat Aclic Libs in a special way. Do not delay the parsing.
1974 bool hasHeaderParsingOnDemand = fHeaderParsingOnDemand;
1975 bool isACLiC = strstr(modulename, "_ACLiC_dict") != nullptr;
1976 if (hasHeaderParsingOnDemand && isACLiC) {
1977 if (gDebug>1)
1978 Info("TCling::RegisterModule",
1979 "Header parsing on demand is active but this is an Aclic library. Disabling it for this library.");
1980 hasHeaderParsingOnDemand = false;
1981 }
1982
1983
1984 // Make sure we relookup symbols that were search for before we loaded
1985 // their autoparse information. We could be more subtil and remove only
1986 // the failed one or only the one in this module, but for now this is
1987 // better than nothing.
1988 fLookedUpClasses.clear();
1989
1990 // Make sure we do not set off AutoLoading or autoparsing during the
1991 // module registration!
1992 SuspendAutoLoadingRAII autoLoadOff(this);
1993
1994 for (const char** inclPath = includePaths; *inclPath; ++inclPath) {
1995 TCling::AddIncludePath(*inclPath);
1996 }
1997 cling::Transaction* T = 0;
1998 // Put the template decls and the number of arguments to skip in the TNormalizedCtxt
1999 for (auto& fwdDeclArgToSkipPair : fwdDeclsArgToSkip){
2000 const std::string& fwdDecl = fwdDeclArgToSkipPair.first;
2001 const int nArgsToSkip = fwdDeclArgToSkipPair.second;
2002 auto compRes = fInterpreter->declare(fwdDecl.c_str(), &T);
2003 assert(cling::Interpreter::kSuccess == compRes &&
2004 "A fwd declaration could not be compiled");
2005 if (compRes!=cling::Interpreter::kSuccess){
2006 Warning("TCling::RegisterModule",
2007 "Problems in declaring string '%s' were encountered.",
2008 fwdDecl.c_str()) ;
2009 continue;
2010 }
2011
2012 // Drill through namespaces recursively until the template is found
2013 if(ClassTemplateDecl* TD = FindTemplateInNamespace(T->getFirstDecl().getSingleDecl())){
2014 fNormalizedCtxt->AddTemplAndNargsToKeep(TD->getCanonicalDecl(), nArgsToSkip);
2015 }
2016
2017 }
2018
2019 // FIXME: Remove #define __ROOTCLING__ once PCMs are there.
2020 // This is used to give Sema the same view on ACLiC'ed files (which
2021 // are then #included through the dictionary) as rootcling had.
2022 TString code = gNonInterpreterClassDef;
2023 if (payloadCode)
2024 code += payloadCode;
2025
2026 std::string dyLibName = cling::DynamicLibraryManager::getSymbolLocation(triggerFunc);
2027 assert(!llvm::sys::fs::is_symlink_file(dyLibName));
2028
2029 if (dyLibName.empty()) {
2030 ::Error("TCling::RegisterModule", "Dictionary trigger function for %s not found", modulename);
2031 return;
2032 }
2033
2034 // The triggerFunc may not be in a shared object but in an executable.
2035 bool isSharedLib = cling::DynamicLibraryManager::isSharedLibrary(dyLibName);
2036
2037 bool wasDlopened = false;
2038
2039 // If this call happens after dlopen has finished (i.e. late registration)
2040 // there is no need to dlopen the library recursively. See ROOT-8437 where
2041 // the dyLibName would correspond to the binary.
2042 if (!lateRegistration) {
2043
2044 if (isSharedLib) {
2045 // We need to open the dictionary shared library, to resolve symbols
2046 // requested by the JIT from it: as the library is currently being dlopen'ed,
2047 // its symbols are not yet reachable from the process.
2048 // Recursive dlopen seems to work just fine.
2049 void* dyLibHandle = dlopen(dyLibName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
2050 if (dyLibHandle) {
2051 fRegisterModuleDyLibs.push_back(dyLibHandle);
2052 wasDlopened = true;
2053 } else {
2054 PrintDlError(dyLibName.c_str(), modulename);
2055 }
2056 }
2057 } // if (!lateRegistration)
2058
2059 if (hasHeaderParsingOnDemand && fwdDeclsCode){
2060 // We now parse the forward declarations. All the classes are then modified
2061 // in order for them to have an external lexical storage.
2062 std::string fwdDeclsCodeLessEnums;
2063 {
2064 // Search for enum forward decls and only declare them if no
2065 // declaration exists yet.
2066 std::string fwdDeclsLine;
2067 std::istringstream fwdDeclsCodeStr(fwdDeclsCode);
2068 std::vector<std::string> scopes;
2069 while (std::getline(fwdDeclsCodeStr, fwdDeclsLine)) {
2070 const auto enumPos = fwdDeclsLine.find("enum __attribute__((annotate(\"");
2071 // We check if the line contains a fwd declaration of an enum
2072 if (enumPos != std::string::npos) {
2073 // We clear the scopes which we may have carried from a previous iteration
2074 scopes.clear();
2075 // We check if the enum is not in a scope. If yes, save its name
2076 // and the names of the enclosing scopes.
2077 if (enumPos != 0) {
2078 // it's enclosed in namespaces. We need to understand what they are
2079 auto nsPos = fwdDeclsLine.find("namespace");
2080 R__ASSERT(nsPos < enumPos && "Inconsistent enum and enclosing scope parsing!");
2081 while (nsPos < enumPos && nsPos != std::string::npos) {
2082 // we have a namespace, let's put it in the collection of scopes
2083 const auto nsNameStart = nsPos + 10;
2084 const auto nsNameEnd = fwdDeclsLine.find('{', nsNameStart);
2085 const auto nsName = fwdDeclsLine.substr(nsNameStart, nsNameEnd - nsNameStart);
2086 scopes.push_back(nsName);
2087 nsPos = fwdDeclsLine.find("namespace", nsNameEnd);
2088 }
2089 }
2090 clang::DeclContext* DC = 0;
2091 for (auto &&aScope: scopes) {
2092 DC = cling::utils::Lookup::Namespace(&fInterpreter->getSema(), aScope.c_str(), DC);
2093 if (!DC) {
2094 // No decl context means we have to fwd declare the enum.
2095 break;
2096 }
2097 }
2098 if (scopes.empty() || DC) {
2099 // We know the scope; let's look for the enum.
2100 size_t posEnumName = fwdDeclsLine.find("\"))) ", 32);
2101 R__ASSERT(posEnumName != std::string::npos && "Inconsistent enum fwd decl!");
2102 posEnumName += 5; // skip "\"))) "
2103 while (isspace(fwdDeclsLine[posEnumName]))
2104 ++posEnumName;
2105 size_t posEnumNameEnd = fwdDeclsLine.find(" : ", posEnumName);
2106 R__ASSERT(posEnumNameEnd != std::string::npos && "Inconsistent enum fwd decl (end)!");
2107 while (isspace(fwdDeclsLine[posEnumNameEnd]))
2108 --posEnumNameEnd;
2109 // posEnumNameEnd now points to the last character of the name.
2110
2111 std::string enumName = fwdDeclsLine.substr(posEnumName,
2112 posEnumNameEnd - posEnumName + 1);
2113
2114 if (clang::NamedDecl* enumDecl
2115 = cling::utils::Lookup::Named(&fInterpreter->getSema(),
2116 enumName.c_str(), DC)) {
2117 // We have an existing enum decl (forward or definition);
2118 // skip this.
2119 R__ASSERT(llvm::dyn_cast<clang::EnumDecl>(enumDecl) && "not an enum decl!");
2120 (void)enumDecl;
2121 continue;
2122 }
2123 }
2124 }
2125
2126 fwdDeclsCodeLessEnums += fwdDeclsLine + "\n";
2127 }
2128 }
2129
2130 if (fwdDeclsCodeLessEnums.size() != 0){ // Avoid the overhead if nothing is to be declared
2131 auto compRes = fInterpreter->declare(fwdDeclsCodeLessEnums, &T);
2132 assert(cling::Interpreter::kSuccess == compRes &&
2133 "The forward declarations could not be compiled");
2134 if (compRes!=cling::Interpreter::kSuccess){
2135 Warning("TCling::RegisterModule",
2136 "Problems in compiling forward declarations for module %s: '%s'",
2137 modulename, fwdDeclsCodeLessEnums.c_str()) ;
2138 }
2139 else if (T){
2140 // Loop over all decls in the transaction and go through them all
2141 // to mark them properly.
2142 // In order to do that, we first iterate over all the DelayedCallInfos
2143 // within the transaction. Then we loop over all Decls in the DeclGroupRef
2144 // contained in the DelayedCallInfos. For each decl, we traverse.
2145 ExtLexicalStorageAdder elsa;
2146 for (auto dciIt = T->decls_begin();dciIt!=T->decls_end();dciIt++){
2147 cling::Transaction::DelayCallInfo& dci = *dciIt;
2148 for(auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) {
2149 clang::Decl* declPtr = *dit;
2150 elsa.TraverseDecl(declPtr);
2151 }
2152 }
2153 }
2154 }
2155
2156 // Now we register all the headers necessary for the class
2157 // Typical format of the array:
2158 // {"A", "classes.h", "@",
2159 // "vector<A>", "vector", "@",
2160 // "myClass", payloadCode, "@",
2161 // nullptr};
2162
2163 std::string temp;
2164 for (const char** classesHeader = classesHeaders; *classesHeader; ++classesHeader) {
2165 temp=*classesHeader;
2166
2167 size_t theTemplateHash = 0;
2168 bool addTemplate = false;
2169 size_t posTemplate = temp.find('<');
2170 if (posTemplate != std::string::npos) {
2171 // Add an entry for the template itself.
2172 std::string templateName = temp.substr(0, posTemplate);
2173 theTemplateHash = fStringHashFunction(templateName);
2174 addTemplate = true;
2175 }
2176 size_t theHash = fStringHashFunction(temp);
2177 classesHeader++;
2178 for (const char** classesHeader_inner = classesHeader; 0!=strcmp(*classesHeader_inner,"@"); ++classesHeader_inner,++classesHeader){
2179 // This is done in order to distinguish headers from files and from the payloadCode
2180 if (payloadCode == *classesHeader_inner ){
2181 fPayloads.insert(theHash);
2182 if (addTemplate) fPayloads.insert(theTemplateHash);
2183 }
2184 if (gDebug > 2)
2185 Info("TCling::RegisterModule",
2186 "Adding a header for %s", temp.c_str());
2187 fClassesHeadersMap[theHash].push_back(*classesHeader_inner);
2188 if (addTemplate) {
2189 if (fClassesHeadersMap.find(theTemplateHash) == fClassesHeadersMap.end()) {
2190 fClassesHeadersMap[theTemplateHash].push_back(*classesHeader_inner);
2191 }
2192 addTemplate = false;
2193 }
2194 }
2195 }
2196 }
2197
2198 clang::Sema &TheSema = fInterpreter->getSema();
2199
2200 bool ModuleWasSuccessfullyLoaded = false;
2201 if (hasCxxModule) {
2202 std::string ModuleName = modulename;
2203 if (llvm::StringRef(modulename).startswith("lib"))
2204 ModuleName = llvm::StringRef(modulename).substr(3).str();
2205
2206 // In case we are directly loading the library via gSystem->Load() without
2207 // specifying the relevant include paths we should try loading the
2208 // modulemap next to the library location.
2209 clang::Preprocessor &PP = TheSema.getPreprocessor();
2210 std::string ModuleMapName;
2211 if (isACLiC)
2212 ModuleMapName = ModuleName + ".modulemap";
2213 else
2214 ModuleMapName = "module.modulemap";
2215 RegisterPrebuiltModulePath(llvm::sys::path::parent_path(dyLibName),
2216 ModuleMapName);
2217
2218 // FIXME: We should only complain for modules which we know to exist. For example, we should not complain about
2219 // modules such as GenVector32 because it needs to fall back to GenVector.
2220 ModuleWasSuccessfullyLoaded = LoadModule(ModuleName, *fInterpreter);
2221 if (!ModuleWasSuccessfullyLoaded) {
2222 // Only report if we found the module in the modulemap.
2223 clang::HeaderSearch &headerSearch = PP.getHeaderSearchInfo();
2224 clang::ModuleMap &moduleMap = headerSearch.getModuleMap();
2225 if (moduleMap.findModule(ModuleName))
2226 Info("TCling::RegisterModule", "Module %s in modulemap failed to load.", ModuleName.c_str());
2227 }
2228 }
2229
2230 if (gIgnoredPCMNames.find(modulename) == gIgnoredPCMNames.end()) {
2231 llvm::SmallString<256> pcmFileNameFullPath(dyLibName);
2232 // The path dyLibName might not be absolute. This can happen if dyLibName
2233 // is linked to an executable in the same folder.
2234 llvm::sys::fs::make_absolute(pcmFileNameFullPath);
2235 llvm::sys::path::remove_filename(pcmFileNameFullPath);
2236 llvm::sys::path::append(pcmFileNameFullPath,
2238 LoadPCM(pcmFileNameFullPath.str().str());
2239 }
2240
2241 { // scope within which diagnostics are de-activated
2242 // For now we disable diagnostics because we saw them already at
2243 // dictionary generation time. That won't be an issue with the PCMs.
2244
2245 clangDiagSuppr diagSuppr(TheSema.getDiagnostics());
2246
2247#if defined(R__MUST_REVISIT)
2248#if R__MUST_REVISIT(6,2)
2249 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
2250#endif
2251#endif
2252
2253 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand){
2254 SuspendAutoParsing autoParseRaii(this);
2255
2256 const cling::Transaction* watermark = fInterpreter->getLastTransaction();
2257 cling::Interpreter::CompilationResult compRes = fInterpreter->parseForModule(code.Data());
2258 if (isACLiC) {
2259 // Register an unload point.
2260 fMetaProcessor->registerUnloadPoint(watermark, headers[0]);
2261 }
2262
2263 assert(cling::Interpreter::kSuccess == compRes &&
2264 "Payload code of a dictionary could not be parsed correctly.");
2265 if (compRes!=cling::Interpreter::kSuccess) {
2266 Warning("TCling::RegisterModule",
2267 "Problems declaring payload for module %s.", modulename) ;
2268 }
2269 }
2270 }
2271
2272 // Now that all the header have been registered/compiled, let's
2273 // make sure to 'reset' the TClass that have a class init in this module
2274 // but already had their type information available (using information/header
2275 // loaded from other modules or from class rules or from opening a TFile
2276 // or from loading header in a way that did not provoke the loading of
2277 // the library we just loaded).
2279
2280 if (!ModuleWasSuccessfullyLoaded && !hasHeaderParsingOnDemand) {
2281 // __ROOTCLING__ might be pulled in through PCH
2282 fInterpreter->declare("#ifdef __ROOTCLING__\n"
2283 "#undef __ROOTCLING__\n"
2284 + gInterpreterClassDef +
2285 "#endif");
2286 }
2287
2288 if (wasDlopened) {
2289 assert(isSharedLib);
2290 void* dyLibHandle = fRegisterModuleDyLibs.back();
2291 fRegisterModuleDyLibs.pop_back();
2292 dlclose(dyLibHandle);
2293 }
2294}
2295
2296////////////////////////////////////////////////////////////////////////////////
2297/// Register classes that already existed prior to their dictionary loading
2298/// and that already had a ClassInfo (and thus would not be refresh via
2299/// UpdateClassInfo.
2300
2302{
2303 fClassesToUpdate.push_back(std::make_pair(oldcl,dict));
2304}
2305
2306////////////////////////////////////////////////////////////////////////////////
2307/// If the dictionary is loaded, we can remove the class from the list
2308/// (otherwise the class might be loaded twice).
2309
2311{
2312 typedef std::vector<std::pair<TClass*,DictFuncPtr_t> >::iterator iterator;
2313 iterator stop = fClassesToUpdate.end();
2314 for(iterator i = fClassesToUpdate.begin();
2315 i != stop;
2316 ++i)
2317 {
2318 if ( i->first == oldcl ) {
2319 fClassesToUpdate.erase(i);
2320 return;
2321 }
2322 }
2323}
2324
2325
2326////////////////////////////////////////////////////////////////////////////////
2327/// Let cling process a command line.
2328///
2329/// If the command is executed and the error is 0, then the return value
2330/// is the int value corresponding to the result of the executed command
2331/// (float and double return values will be truncated).
2332///
2333
2334// Method for handling the interpreter exceptions.
2335// the MetaProcessor is passing in as argument to teh function, because
2336// cling::Interpreter::CompilationResult is a nested class and it cannot be
2337// forward declared, thus this method cannot be a static member function
2338// of TCling.
2339
2340static int HandleInterpreterException(cling::MetaProcessor* metaProcessor,
2341 const char* input_line,
2342 cling::Interpreter::CompilationResult& compRes,
2343 cling::Value* result)
2344{
2345 try {
2346 return metaProcessor->process(input_line, compRes, result);
2347 }
2348 catch (cling::InterpreterException& ex)
2349 {
2350 Error("HandleInterpreterException", "%s.\n%s", ex.what(), "Execution of your code was aborted.");
2351 ex.diagnose();
2352 compRes = cling::Interpreter::kFailure;
2353 }
2354 return 0;
2355}
2356
2357////////////////////////////////////////////////////////////////////////////////
2358
2359bool TCling::DiagnoseIfInterpreterException(const std::exception &e) const
2360{
2361 if (auto ie = dynamic_cast<const cling::InterpreterException*>(&e)) {
2362 ie->diagnose();
2363 return true;
2364 }
2365 return false;
2366}
2367
2368////////////////////////////////////////////////////////////////////////////////
2369
2370Long_t TCling::ProcessLine(const char* line, EErrorCode* error/*=0*/)
2371{
2372 // Copy the passed line, it comes from a static buffer in TApplication
2373 // which can be reentered through the Cling evaluation routines,
2374 // which would overwrite the static buffer and we would forget what we
2375 // were doing.
2376 //
2377 TString sLine(line);
2378 if (strstr(line,fantomline)) {
2379 // End-Of-Line action
2380 // See the comment (copied from above):
2381 // It is a "fantom" method to synchronize user keyboard input
2382 // and ROOT prompt line (for WIN32)
2383 // and is implemented by
2384 if (gApplication) {
2385 if (gApplication->IsCmdThread()) {
2387 gROOT->SetLineIsProcessing();
2388
2390
2391 gROOT->SetLineHasBeenProcessed();
2392 }
2393 }
2394 return 0;
2395 }
2396
2398 gGlobalMutex->Lock();
2399 if (!gInterpreterMutex)
2402 }
2404 gROOT->SetLineIsProcessing();
2405
2406 struct InterpreterFlagsRAII {
2407 cling::Interpreter* fInterpreter;
2408 bool fWasDynamicLookupEnabled;
2409
2410 InterpreterFlagsRAII(cling::Interpreter* interp):
2411 fInterpreter(interp),
2412 fWasDynamicLookupEnabled(interp->isDynamicLookupEnabled())
2413 {
2414 fInterpreter->enableDynamicLookup(true);
2415 }
2416 ~InterpreterFlagsRAII() {
2417 fInterpreter->enableDynamicLookup(fWasDynamicLookupEnabled);
2418 gROOT->SetLineHasBeenProcessed();
2419 }
2420 } interpreterFlagsRAII(GetInterpreterImpl());
2421
2422 // A non-zero returned value means the given line was
2423 // not a complete statement.
2424 int indent = 0;
2425 // This will hold the resulting value of the evaluation the given line.
2426 cling::Value result;
2427 cling::Interpreter::CompilationResult compRes = cling::Interpreter::kSuccess;
2428 if (!strncmp(sLine.Data(), ".L", 2) || !strncmp(sLine.Data(), ".x", 2) ||
2429 !strncmp(sLine.Data(), ".X", 2)) {
2430 // If there was a trailing "+", then CINT compiled the code above,
2431 // and we will need to strip the "+" before passing the line to cling.
2432 TString mod_line(sLine);
2433 TString aclicMode;
2434 TString arguments;
2435 TString io;
2436 TString fname = gSystem->SplitAclicMode(sLine.Data() + 3,
2437 aclicMode, arguments, io);
2438 if (aclicMode.Length()) {
2439 // Remove the leading '+'
2440 R__ASSERT(aclicMode[0]=='+' && "ACLiC mode must start with a +");
2441 aclicMode[0]='k'; // We always want to keep the .so around.
2442 if (aclicMode[1]=='+') {
2443 // We have a 2nd +
2444 aclicMode[1]='f'; // We want to force the recompilation.
2445 }
2446 if (!gSystem->CompileMacro(fname,aclicMode)) {
2447 // ACLiC failed.
2448 compRes = cling::Interpreter::kFailure;
2449 } else {
2450 if (strncmp(sLine.Data(), ".L", 2) != 0) {
2451 // if execution was requested.
2452
2453 if (arguments.Length()==0) {
2454 arguments = "()";
2455 }
2456 // We need to remove the extension.
2457 Ssiz_t ext = fname.Last('.');
2458 if (ext != kNPOS) {
2459 fname.Remove(ext);
2460 }
2461 const char *function = gSystem->BaseName(fname);
2462 mod_line = function + arguments + io;
2463 indent = HandleInterpreterException(GetMetaProcessorImpl(), mod_line, compRes, &result);
2464 }
2465 }
2466 } else {
2467 // not ACLiC
2468 size_t unnamedMacroOpenCurly;
2469 {
2470 std::string code;
2471 std::string codeline;
2472 std::ifstream in(fname);
2473 while (in) {
2474 std::getline(in, codeline);
2475 code += codeline + "\n";
2476 }
2477 unnamedMacroOpenCurly
2478 = cling::utils::isUnnamedMacro(code, fInterpreter->getCI()->getLangOpts());
2479 }
2480
2481 fCurExecutingMacros.push_back(fname);
2482 if (unnamedMacroOpenCurly != std::string::npos) {
2483 compRes = fMetaProcessor->readInputFromFile(fname.Data(), &result,
2484 unnamedMacroOpenCurly);
2485 } else {
2486 // No DynLookup for .x, .L of named macros.
2487 fInterpreter->enableDynamicLookup(false);
2488 indent = HandleInterpreterException(GetMetaProcessorImpl(), mod_line, compRes, &result);
2489 }
2490 fCurExecutingMacros.pop_back();
2491 }
2492 } // .L / .X / .x
2493 else {
2494 if (0!=strncmp(sLine.Data(), ".autodict ",10) && sLine != ".autodict") {
2495 // explicitly ignore .autodict without having to support it
2496 // in cling.
2497
2498 // Turn off autoparsing if this is an include directive
2499 bool isInclusionDirective = sLine.Contains("\n#include") || sLine.BeginsWith("#include");
2500 if (isInclusionDirective) {
2501 SuspendAutoParsing autoParseRaii(this);
2502 indent = HandleInterpreterException(GetMetaProcessorImpl(), sLine, compRes, &result);
2503 } else {
2504 indent = HandleInterpreterException(GetMetaProcessorImpl(), sLine, compRes, &result);
2505 }
2506 }
2507 }
2508 if (result.isValid())
2509 RegisterTemporary(result);
2510 if (indent) {
2511 if (error)
2512 *error = kProcessing;
2513 return 0;
2514 }
2515 if (error) {
2516 switch (compRes) {
2517 case cling::Interpreter::kSuccess: *error = kNoError; break;
2518 case cling::Interpreter::kFailure: *error = kRecoverable; break;
2519 case cling::Interpreter::kMoreInputExpected: *error = kProcessing; break;
2520 }
2521 }
2522 if (compRes == cling::Interpreter::kSuccess
2523 && result.isValid()
2524 && !result.isVoid())
2525 {
2526 return result.simplisticCastAs<long>();
2527 }
2528 return 0;
2529}
2530
2531////////////////////////////////////////////////////////////////////////////////
2532/// No-op; see TRint instead.
2533
2535{
2536}
2537
2538////////////////////////////////////////////////////////////////////////////////
2539/// Add the given path to the list of directories in which the interpreter
2540/// looks for include files. Only one path item can be specified at a
2541/// time, i.e. "path1:path2" is NOT supported.
2542
2543void TCling::AddIncludePath(const char *path)
2544{
2546 // Favorite source of annoyance: gSystem->AddIncludePath() needs "-I",
2547 // gCling->AddIncludePath() does not! Work around that inconsistency:
2548 if (path[0] == '-' && path[1] == 'I')
2549 path += 2;
2550
2551 fInterpreter->AddIncludePath(path);
2552}
2553
2554////////////////////////////////////////////////////////////////////////////////
2555/// Visit all members over members, recursing over base classes.
2556
2557void TCling::InspectMembers(TMemberInspector& insp, const void* obj,
2558 const TClass* cl, Bool_t isTransient)
2559{
2563 }
2564
2565 if (!cl || cl->GetCollectionProxy()) {
2566 // We do not need to investigate the content of the STL
2567 // collection, they are opaque to us (and details are
2568 // uninteresting).
2569 return;
2570 }
2571
2572 static const TClassRef clRefString("std::string");
2573 if (clRefString == cl) {
2574 // We stream std::string without going through members..
2575 return;
2576 }
2577
2578 if (TClassEdit::IsStdArray(cl->GetName())) {
2579 // We treat std arrays as C arrays
2580 return;
2581 }
2582
2583 const char* cobj = (const char*) obj; // for ptr arithmetics
2584
2585 // Treat the case of std::complex in a special manner. We want to enforce
2586 // the layout of a stl implementation independent class, which is the
2587 // complex as implemented in ROOT5.
2588
2589 // A simple lambda to simplify the code
2590 auto inspInspect = [&] (ptrdiff_t offset){
2591 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_real", cobj, isTransient);
2592 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), "_imag", cobj + offset, isTransient);
2593 };
2594
2595 auto complexType = TClassEdit::GetComplexType(cl->GetName());
2596 switch(complexType) {
2598 {
2599 break;
2600 }
2602 {
2603 inspInspect(sizeof(float));
2604 return;
2605 }
2607 {
2608 inspInspect(sizeof(double));
2609 return;
2610 }
2612 {
2613 inspInspect(sizeof(int));
2614 return;
2615 }
2617 {
2618 inspInspect(sizeof(long));
2619 return;
2620 }
2621 }
2622
2623 static clang::PrintingPolicy
2624 printPol(fInterpreter->getCI()->getLangOpts());
2625 if (printPol.Indentation) {
2626 // not yet initialized
2627 printPol.Indentation = 0;
2628 printPol.SuppressInitializers = true;
2629 }
2630
2631 const char* clname = cl->GetName();
2632 // Printf("Inspecting class %s\n", clname);
2633
2634 const clang::ASTContext& astContext = fInterpreter->getCI()->getASTContext();
2635 const clang::Decl *scopeDecl = 0;
2636 const clang::Type *recordType = 0;
2637
2638 if (cl->GetClassInfo()) {
2639 TClingClassInfo * clingCI = (TClingClassInfo *)cl->GetClassInfo();
2640 scopeDecl = clingCI->GetDecl();
2641 recordType = clingCI->GetType();
2642 } else {
2643 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
2644 // Diags will complain about private classes:
2645 scopeDecl = lh.findScope(clname, cling::LookupHelper::NoDiagnostics,
2646 &recordType);
2647 }
2648 if (!scopeDecl) {
2649 Error("InspectMembers", "Cannot find Decl for class %s", clname);
2650 return;
2651 }
2652 const clang::CXXRecordDecl* recordDecl
2653 = llvm::dyn_cast<const clang::CXXRecordDecl>(scopeDecl);
2654 if (!recordDecl) {
2655 Error("InspectMembers", "Cannot find Decl for class %s is not a CXXRecordDecl.", clname);
2656 return;
2657 }
2658
2659 {
2660 // Force possible deserializations first. We need to have no pending
2661 // Transaction when passing control flow to the inspector below (ROOT-7779).
2662 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
2663
2664 astContext.getASTRecordLayout(recordDecl);
2665
2666 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2667 eField = recordDecl->field_end(); iField != eField; ++iField) {}
2668 }
2669
2670 const clang::ASTRecordLayout& recLayout
2671 = astContext.getASTRecordLayout(recordDecl);
2672
2673 // TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
2674 // if (proxy && ( proxy->GetProperties() & TVirtualCollectionProxy::kIsEmulated ) ) {
2675 // Error("InspectMembers","The TClass for %s has an emulated proxy but we are looking at a compiled version of the collection!\n",
2676 // cl->GetName());
2677 // }
2678 if (cl->Size() != recLayout.getSize().getQuantity()) {
2679 Error("InspectMembers","TClass and cling disagree on the size of the class %s, respectively %d %lld\n",
2680 cl->GetName(),cl->Size(),(Long64_t)recLayout.getSize().getQuantity());
2681 }
2682
2683 unsigned iNField = 0;
2684 // iterate over fields
2685 // FieldDecls are non-static, else it would be a VarDecl.
2686 for (clang::RecordDecl::field_iterator iField = recordDecl->field_begin(),
2687 eField = recordDecl->field_end(); iField != eField;
2688 ++iField, ++iNField) {
2689
2690
2691 clang::QualType memberQT = iField->getType();
2692 if (recordType) {
2693 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2694 memberQT = ROOT::TMetaUtils::ReSubstTemplateArg(memberQT, recordType);
2695 }
2696 memberQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, memberQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2697 if (memberQT.isNull()) {
2698 std::string memberName;
2699 llvm::raw_string_ostream stream(memberName);
2700 // Don't trigger fopen of the source file to count lines:
2701 printPol.AnonymousTagLocations = false;
2702 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2703 stream.flush();
2704 Error("InspectMembers",
2705 "Cannot retrieve QualType for member %s while inspecting class %s",
2706 memberName.c_str(), clname);
2707 continue; // skip member
2708 }
2709 const clang::Type* memType = memberQT.getTypePtr();
2710 if (!memType) {
2711 std::string memberName;
2712 llvm::raw_string_ostream stream(memberName);
2713 // Don't trigger fopen of the source file to count lines:
2714 printPol.AnonymousTagLocations = false;
2715 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2716 stream.flush();
2717 Error("InspectMembers",
2718 "Cannot retrieve Type for member %s while inspecting class %s",
2719 memberName.c_str(), clname);
2720 continue; // skip member
2721 }
2722
2723 const clang::Type* memNonPtrType = memType;
2724 Bool_t ispointer = false;
2725 if (memNonPtrType->isPointerType()) {
2726 ispointer = true;
2727 clang::QualType ptrQT
2728 = memNonPtrType->getAs<clang::PointerType>()->getPointeeType();
2729 if (recordType) {
2730 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
2731 ptrQT = ROOT::TMetaUtils::ReSubstTemplateArg(ptrQT, recordType);
2732 }
2733 ptrQT = cling::utils::Transform::GetPartiallyDesugaredType(astContext, ptrQT, fNormalizedCtxt->GetConfig(), false /* fully qualify */);
2734 if (ptrQT.isNull()) {
2735 std::string memberName;
2736 llvm::raw_string_ostream stream(memberName);
2737 // Don't trigger fopen of the source file to count lines:
2738 printPol.AnonymousTagLocations = false;
2739 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2740 stream.flush();
2741 Error("InspectMembers",
2742 "Cannot retrieve pointee Type for member %s while inspecting class %s",
2743 memberName.c_str(), clname);
2744 continue; // skip member
2745 }
2746 memNonPtrType = ptrQT.getTypePtr();
2747 }
2748
2749 // assemble array size(s): "[12][4][]"
2750 llvm::SmallString<8> arraySize;
2751 const clang::ArrayType* arrType = memNonPtrType->getAsArrayTypeUnsafe();
2752 unsigned arrLevel = 0;
2753 bool haveErrorDueToArray = false;
2754 while (arrType) {
2755 ++arrLevel;
2756 arraySize += '[';
2757 const clang::ConstantArrayType* constArrType =
2758 clang::dyn_cast<clang::ConstantArrayType>(arrType);
2759 if (constArrType) {
2760 constArrType->getSize().toStringUnsigned(arraySize);
2761 }
2762 arraySize += ']';
2763 clang::QualType subArrQT = arrType->getElementType();
2764 if (subArrQT.isNull()) {
2765 std::string memberName;
2766 llvm::raw_string_ostream stream(memberName);
2767 // Don't trigger fopen of the source file to count lines:
2768 printPol.AnonymousTagLocations = false;
2769 iField->getNameForDiagnostic(stream, printPol, true /*fqi*/);
2770 stream.flush();
2771 Error("InspectMembers",
2772 "Cannot retrieve QualType for array level %d (i.e. element type of %s) for member %s while inspecting class %s",
2773 arrLevel, subArrQT.getAsString(printPol).c_str(),
2774 memberName.c_str(), clname);
2775 haveErrorDueToArray = true;
2776 break;
2777 }
2778 arrType = subArrQT.getTypePtr()->getAsArrayTypeUnsafe();
2779 }
2780 if (haveErrorDueToArray) {
2781 continue; // skip member
2782 }
2783
2784 // construct member name
2785 std::string fieldName;
2786 if (memType->isPointerType()) {
2787 fieldName = "*";
2788 }
2789
2790 // Check if this field has a custom ioname, if not, just use the one of the decl
2791 std::string ioname(iField->getName());
2793 fieldName += ioname;
2794 fieldName += arraySize;
2795
2796 // get member offset
2797 // NOTE currently we do not support bitfield and do not support
2798 // member that are not aligned on 'bit' boundaries.
2799 clang::CharUnits offset(astContext.toCharUnitsFromBits(recLayout.getFieldOffset(iNField)));
2800 ptrdiff_t fieldOffset = offset.getQuantity();
2801
2802 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fBits[2]", fBits);
2803 // R__insp.Inspect(R__cl, R__insp.GetParent(), "fName", &fName);
2804 // R__insp.InspectMember(fName, "fName.");
2805 // R__insp.Inspect(R__cl, R__insp.GetParent(), "*fClass", &fClass);
2806
2807 // If the class has a custom streamer and the type of the filed is a
2808 // private enum, struct or class, skip it.
2809 if (!insp.IsTreatingNonAccessibleTypes()){
2810 auto iFiledQtype = iField->getType();
2811 if (auto tagDecl = iFiledQtype->getAsTagDecl()){
2812 auto declAccess = tagDecl->getAccess();
2813 if (declAccess == AS_private || declAccess == AS_protected) {
2814 continue;
2815 }
2816 }
2817 }
2818
2819 insp.Inspect(const_cast<TClass*>(cl), insp.GetParent(), fieldName.c_str(), cobj + fieldOffset, isTransient);
2820
2821 if (!ispointer) {
2822 const clang::CXXRecordDecl* fieldRecDecl = memNonPtrType->getAsCXXRecordDecl();
2823 if (fieldRecDecl && !fieldRecDecl->isAnonymousStructOrUnion()) {
2824 // nested objects get an extra call to InspectMember
2825 // R__insp.InspectMember("FileStat_t", (void*)&fFileStat, "fFileStat.", false);
2826 std::string sFieldRecName;
2827 if (!ROOT::TMetaUtils::ExtractAttrPropertyFromName(*fieldRecDecl,"iotype",sFieldRecName)){
2829 clang::QualType(memNonPtrType,0),
2830 *fInterpreter,
2832 }
2833
2834 TDataMember* mbr = cl->GetDataMember(ioname.c_str());
2835 // if we can not find the member (which should not really happen),
2836 // let's consider it transient.
2837 Bool_t transient = isTransient || !mbr || !mbr->IsPersistent();
2838
2839 insp.InspectMember(sFieldRecName.c_str(), cobj + fieldOffset,
2840 (fieldName + '.').c_str(), transient);
2841
2842 }
2843 }
2844 } // loop over fields
2845
2846 // inspect bases
2847 // TNamed::ShowMembers(R__insp);
2848 unsigned iNBase = 0;
2849 for (clang::CXXRecordDecl::base_class_const_iterator iBase
2850 = recordDecl->bases_begin(), eBase = recordDecl->bases_end();
2851 iBase != eBase; ++iBase, ++iNBase) {
2852 clang::QualType baseQT = iBase->getType();
2853 if (baseQT.isNull()) {
2854 Error("InspectMembers",
2855 "Cannot find QualType for base number %d while inspecting class %s",
2856 iNBase, clname);
2857 continue;
2858 }
2859 const clang::CXXRecordDecl* baseDecl
2860 = baseQT->getAsCXXRecordDecl();
2861 if (!baseDecl) {
2862 Error("InspectMembers",
2863 "Cannot find CXXRecordDecl for base number %d while inspecting class %s",
2864 iNBase, clname);
2865 continue;
2866 }
2867 TClass* baseCl=nullptr;
2868 std::string sBaseName;
2869 // Try with the DeclId
2870 std::vector<TClass*> foundClasses;
2871 TClass::GetClass(static_cast<DeclId_t>(baseDecl), foundClasses);
2872 if (foundClasses.size()==1){
2873 baseCl=foundClasses[0];
2874 } else {
2875 // Try with the normalised Name, as a fallback
2876 if (!baseCl){
2878 baseQT,
2879 *fInterpreter,
2881 baseCl = TClass::GetClass(sBaseName.c_str());
2882 }
2883 }
2884
2885 if (!baseCl){
2886 std::string qualNameForDiag;
2887 ROOT::TMetaUtils::GetQualifiedName(qualNameForDiag, *baseDecl);
2888 Error("InspectMembers",
2889 "Cannot find TClass for base class %s", qualNameForDiag.c_str() );
2890 continue;
2891 }
2892
2893 int64_t baseOffset;
2894 if (iBase->isVirtual()) {
2896 if (!isTransient) {
2897 Error("InspectMembers",
2898 "Base %s of class %s is virtual but no object provided",
2899 sBaseName.c_str(), clname);
2900 }
2902 } else {
2903 // We have an object to determine the vbase offset.
2905 TClingClassInfo* baseCi = (TClingClassInfo*)baseCl->GetClassInfo();
2906 if (ci && baseCi) {
2907 baseOffset = ci->GetBaseOffset(baseCi, const_cast<void*>(obj),
2908 true /*isDerivedObj*/);
2909 if (baseOffset == -1) {
2910 Error("InspectMembers",
2911 "Error calculating offset of virtual base %s of class %s",
2912 sBaseName.c_str(), clname);
2913 }
2914 } else {
2915 Error("InspectMembers",
2916 "Cannot calculate offset of virtual base %s of class %s",
2917 sBaseName.c_str(), clname);
2918 continue;
2919 }
2920 }
2921 } else {
2922 baseOffset = recLayout.getBaseClassOffset(baseDecl).getQuantity();
2923 }
2924 // TOFIX: baseCl can be null here!
2925 if (baseCl->IsLoaded()) {
2926 // For loaded class, CallShowMember will (especially for TObject)
2927 // call the virtual ShowMember rather than the class specific version
2928 // resulting in an infinite recursion.
2929 InspectMembers(insp, cobj + baseOffset, baseCl, isTransient);
2930 } else {
2931 baseCl->CallShowMembers(cobj + baseOffset,
2932 insp, isTransient);
2933 }
2934 } // loop over bases
2935}
2936
2937////////////////////////////////////////////////////////////////////////////////
2938/// Reset the interpreter internal state in case a previous action was not correctly
2939/// terminated.
2940
2942{
2943 // No-op there is not equivalent state (to be cleared) in Cling.
2944}
2945
2946////////////////////////////////////////////////////////////////////////////////
2947/// Delete existing temporary values.
2948
2950{
2951 // No-op for cling due to cling::Value.
2952}
2953
2954////////////////////////////////////////////////////////////////////////////////
2955/// Declare code to the interpreter, without any of the interpreter actions
2956/// that could trigger a re-interpretation of the code. I.e. make cling
2957/// behave like a compiler: no dynamic lookup, no input wrapping for
2958/// subsequent execution, no automatic provision of declarations but just a
2959/// plain #include.
2960/// Returns true on success, false on failure.
2961
2962bool TCling::Declare(const char* code)
2963{
2965
2966 SuspendAutoLoadingRAII autoLoadOff(this);
2967 SuspendAutoParsing autoParseRaii(this);
2968
2969 bool oldDynLookup = fInterpreter->isDynamicLookupEnabled();
2970 fInterpreter->enableDynamicLookup(false);
2971 bool oldRawInput = fInterpreter->isRawInputEnabled();
2972 fInterpreter->enableRawInput(true);
2973
2974 Bool_t ret = LoadText(code);
2975
2976 fInterpreter->enableRawInput(oldRawInput);
2977 fInterpreter->enableDynamicLookup(oldDynLookup);
2978 return ret;
2979}
2980
2981////////////////////////////////////////////////////////////////////////////////
2982/// It calls a "fantom" method to synchronize user keyboard input
2983/// and ROOT prompt line.
2984
2986{
2988}
2989
2990// This static function is a hop of TCling::IsLibraryLoaded, which is taking a lock and calling
2991// into this function. This is because we wanted to avoid a duplication in TCling::IsLoaded, which
2992// was already taking a lock.
2993static Bool_t s_IsLibraryLoaded(const char* libname, cling::Interpreter* fInterpreter)
2994{
2995 // Check shared library.
2996 TString tLibName(libname);
2997 if (gSystem->FindDynamicLibrary(tLibName, kTRUE))
2998 return fInterpreter->getDynamicLibraryManager()->isLibraryLoaded(tLibName.Data());
2999 return false;
3000}
3001
3002Bool_t TCling::IsLibraryLoaded(const char* libname) const
3003{
3005 return s_IsLibraryLoaded(libname, GetInterpreterImpl());
3006}
3007
3008////////////////////////////////////////////////////////////////////////////////
3009/// Return true if ROOT has cxxmodules pcm for a given library name.
3010// FIXME: We need to be able to support lazy loading of pcm generated by ACLiC.
3011Bool_t TCling::HasPCMForLibrary(const char *libname) const
3012{
3013 llvm::StringRef ModuleName(libname);
3014 ModuleName = llvm::sys::path::stem(ModuleName);
3015 ModuleName.consume_front("lib");
3016
3017 // FIXME: In case when the modulemap is not yet loaded we will return the
3018 // wrong result. Consider a call to HasPCMForLibrary(../test/libEvent.so)
3019 // We will only load the modulemap for libEvent.so after we dlopen libEvent
3020 // which may happen after calling this interface. Maybe we should also check
3021 // if there is a Event.pcm file and a module.modulemap, load it and return
3022 // true.
3023 clang::ModuleMap &moduleMap = fInterpreter->getCI()->getPreprocessor().getHeaderSearchInfo().getModuleMap();
3024 clang::Module *M = moduleMap.findModule(ModuleName);
3025 return M && !M->IsMissingRequirement && M->getASTFile();
3026}
3027
3028////////////////////////////////////////////////////////////////////////////////
3029/// Return true if the file has already been loaded by cint.
3030/// We will try in this order:
3031/// actual filename
3032/// filename as a path relative to
3033/// the include path
3034/// the shared library path
3035
3036Bool_t TCling::IsLoaded(const char* filename) const
3037{
3039
3040 //FIXME: if we use llvm::sys::fs::make_absolute all this can go away. See
3041 // cling::DynamicLibraryManager.
3042
3043 std::string file_name = filename;
3044 size_t at = std::string::npos;
3045 while ((at = file_name.find("/./")) != std::string::npos)
3046 file_name.replace(at, 3, "/");
3047
3048 std::string filesStr = "";
3049 llvm::raw_string_ostream filesOS(filesStr);
3050 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3051 cling::ClangInternalState::printIncludedFiles(filesOS, SM);
3052 filesOS.flush();
3053
3054 llvm::SmallVector<llvm::StringRef, 100> files;
3055 llvm::StringRef(filesStr).split(files, "\n");
3056
3057 std::set<std::string> fileMap;
3058 // Fill fileMap; return early on exact match.
3059 for (llvm::SmallVector<llvm::StringRef, 100>::const_iterator
3060 iF = files.begin(), iE = files.end(); iF != iE; ++iF) {
3061 if ((*iF) == file_name.c_str()) return kTRUE; // exact match
3062 fileMap.insert(*iF);
3063 }
3064
3065 if (fileMap.empty()) return kFALSE;
3066
3067 // Check MacroPath.
3068 TString sFilename(file_name.c_str());
3070 && fileMap.count(sFilename.Data())) {
3071 return kTRUE;
3072 }
3073
3074 // Check IncludePath.
3075 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
3076 incPath.Append(":").Prepend(" "); // to match " -I" (note leading ' ')
3077 incPath.ReplaceAll(" -I", ":"); // of form :dir1 :dir2:dir3
3078 while (incPath.Index(" :") != -1) {
3079 incPath.ReplaceAll(" :", ":");
3080 }
3081 incPath.Prepend(".:");
3082 sFilename = file_name.c_str();
3083 if (gSystem->FindFile(incPath, sFilename, kReadPermission)
3084 && fileMap.count(sFilename.Data())) {
3085 return kTRUE;
3086 }
3087
3088 // Check shared library.
3089 if (s_IsLibraryLoaded(file_name.c_str(), GetInterpreterImpl()))
3090 return kTRUE;
3091
3092 //FIXME: We must use the cling::Interpreter::lookupFileOrLibrary iface.
3093 const clang::DirectoryLookup *CurDir = 0;
3094 clang::Preprocessor &PP = fInterpreter->getCI()->getPreprocessor();
3095 clang::HeaderSearch &HS = PP.getHeaderSearchInfo();
3096 const clang::FileEntry *FE = HS.LookupFile(file_name.c_str(),
3097 clang::SourceLocation(),
3098 /*isAngled*/ false,
3099 /*FromDir*/ 0, CurDir,
3100 clang::ArrayRef<std::pair<const clang::FileEntry *,
3101 const clang::DirectoryEntry *>>(),
3102 /*SearchPath*/ 0,
3103 /*RelativePath*/ 0,
3104 /*RequestingModule*/ 0,
3105 /*SuggestedModule*/ 0,
3106 /*IsMapped*/ 0,
3107 /*SkipCache*/ false,
3108 /*BuildSystemModule*/ false,
3109 /*OpenFile*/ false,
3110 /*CacheFail*/ false);
3111 if (FE && FE->isValid()) {
3112 // check in the source manager if the file is actually loaded
3113 clang::SourceManager &SM = fInterpreter->getCI()->getSourceManager();
3114 // this works only with header (and source) files...
3115 clang::FileID FID = SM.translateFile(FE);
3116 if (!FID.isInvalid() && FID.getHashValue() == 0)
3117 return kFALSE;
3118 else {
3119 clang::SrcMgr::SLocEntry SLocE = SM.getSLocEntry(FID);
3120 if (SLocE.isFile() && SLocE.getFile().getContentCache()->getRawBuffer() == 0)
3121 return kFALSE;
3122 if (!FID.isInvalid())
3123 return kTRUE;
3124 }
3125 // ...then check shared library again, but with full path now
3126 sFilename = FE->getName();
3127 if (gSystem->FindDynamicLibrary(sFilename, kTRUE)
3128 && fileMap.count(sFilename.Data())) {
3129 return kTRUE;
3130 }
3131 }
3132 return kFALSE;
3133}
3134
3135
3136#if defined(R__MACOSX)
3137
3138////////////////////////////////////////////////////////////////////////////////
3139/// Check if lib is in the dynamic linker cache, returns true if it is, and if so,
3140/// modifies the library file name parameter `lib` from `/usr/lib/libFOO.dylib`
3141/// to `-lFOO` such that it can be passed to the linker.
3142/// This is a unique feature of macOS 11.
3143
3144static bool R__UpdateLibFileForLinking(TString &lib)
3145{
3146 const char *mapfile = nullptr;
3147#if __x86_64__
3148 mapfile = "/System/Library/dyld/dyld_shared_cache_x86_64.map";
3149#elif __arm64__
3150 mapfile = "/System/Library/dyld/dyld_shared_cache_arm64e.map";
3151#else
3152 #error unsupported architecture
3153#endif
3154 if (std::ifstream cacheMap{mapfile}) {
3155 std::string line;
3156 while (getline(cacheMap, line)) {
3157 if (line.find(lib) != std::string::npos) {
3158 lib.ReplaceAll("/usr/lib/lib","-l");
3159 lib.ReplaceAll(".dylib","");
3160 return true;
3161 }
3162 }
3163 return false;
3164 }
3165 return false;
3166}
3167#endif // R__MACOSX
3168
3169#ifdef R__LINUX
3170
3171////////////////////////////////////////////////////////////////////////////////
3172/// Callback for dl_iterate_phdr(), see `man dl_iterate_phdr`.
3173/// Collects opened libraries.
3174
3175static int callback_for_dl_iterate_phdr(struct dl_phdr_info *info, size_t size, void *data)
3176{
3177 // This function is called through UpdateListOfLoadedSharedLibraries() which is locked.
3178 static std::unordered_set<decltype(info->dlpi_addr)> sKnownLoadedLibBaseAddrs;
3179
3180 auto newLibs = static_cast<std::vector<std::string>*>(data);
3181 if (!sKnownLoadedLibBaseAddrs.count(info->dlpi_addr)) {
3182 // Skip \0, "", and kernel pseudo-libs linux-vdso.so.1 or linux-gate.so.1
3183 if (info->dlpi_name && info->dlpi_name[0]
3184 && strncmp(info->dlpi_name, "linux-vdso.so", 13)
3185 && strncmp(info->dlpi_name, "linux-gate.so", 13))
3186 newLibs->emplace_back(info->dlpi_name);
3187 sKnownLoadedLibBaseAddrs.insert(info->dlpi_addr);
3188 }
3189 // No matter what the doc says, return != 0 means "stop the iteration".
3190 return 0;
3191}
3192
3193#endif // R__LINUX
3194
3195
3196////////////////////////////////////////////////////////////////////////////////
3197
3199{
3200#if defined(R__WIN32) || defined(__CYGWIN__)
3201 HMODULE hModules[1024];
3202 void *hProcess;
3203 unsigned long cbModules;
3204 unsigned int i;
3205 hProcess = (void *)::GetCurrentProcess();
3206 ::EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbModules);
3207 // start at 1 to skip the executable itself
3208 for (i = 1; i < (cbModules / sizeof(void *)); i++) {
3209 static const int bufsize = 260;
3210 wchar_t winname[bufsize];
3211 char posixname[bufsize];
3212 ::GetModuleFileNameExW(hProcess, hModules[i], winname, bufsize);
3213#if defined(__CYGWIN__)
3214 cygwin_conv_path(CCP_WIN_W_TO_POSIX, winname, posixname, bufsize);
3215#else
3216 std::wstring wpath = winname;
3217 std::replace(wpath.begin(), wpath.end(), '\\', '/');
3218 string path(wpath.begin(), wpath.end());
3219 strncpy(posixname, path.c_str(), bufsize);
3220#endif
3221 if (!fSharedLibs.Contains(posixname)) {
3222 RegisterLoadedSharedLibrary(posixname);
3223 }
3224 }
3225#elif defined(R__MACOSX)
3226 // fPrevLoadedDynLibInfo stores the *next* image index to look at
3227 uint32_t imageIndex = (uint32_t) (size_t) fPrevLoadedDynLibInfo;
3228
3229 while (const mach_header* mh = _dyld_get_image_header(imageIndex)) {
3230 // Skip non-dylibs
3231 if (mh->filetype == MH_DYLIB) {
3232 if (const char* imageName = _dyld_get_image_name(imageIndex)) {
3233 RegisterLoadedSharedLibrary(imageName);
3234 }
3235 }
3236
3237 ++imageIndex;
3238 }
3239 fPrevLoadedDynLibInfo = (void*)(size_t)imageIndex;
3240#elif defined(R__LINUX)
3241 // fPrevLoadedDynLibInfo is unused on Linux.
3243
3244 std::vector<std::string> newLibs;
3245 dl_iterate_phdr(callback_for_dl_iterate_phdr, &newLibs);
3246 for (auto &&lib: newLibs)
3247 RegisterLoadedSharedLibrary(lib.c_str());
3248#else
3249 Error("TCling::UpdateListOfLoadedSharedLibraries",
3250 "Platform not supported!");
3251#endif
3252}
3253
3254////////////////////////////////////////////////////////////////////////////////
3255/// Register a new shared library name with the interpreter; add it to
3256/// fSharedLibs.
3257
3258void TCling::RegisterLoadedSharedLibrary(const char* filename)
3259{
3260 // Ignore NULL filenames, aka "the process".
3261 if (!filename) return;
3262
3263 // Tell the interpreter that this library is available; all libraries can be
3264 // used to resolve symbols.
3265 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3266 if (!DLM->isLibraryLoaded(filename)) {
3267 DLM->loadLibrary(filename, true /*permanent*/);
3268 }
3269
3270#if defined(R__MACOSX)
3271 // Check that this is not a system library
3272 auto lenFilename = strlen(filename);
3273 if (!strncmp(filename, "/usr/lib/system/", 16)
3274 || !strncmp(filename, "/usr/lib/libc++", 15)
3275 || !strncmp(filename, "/System/Library/Frameworks/", 27)
3276 || !strncmp(filename, "/System/Library/PrivateFrameworks/", 34)
3277 || !strncmp(filename, "/System/Library/CoreServices/", 29)
3278 || !strcmp(filename, "cl_kernels") // yepp, no directory
3279 || strstr(filename, "/usr/lib/libSystem")
3280 || strstr(filename, "/usr/lib/libstdc++")
3281 || strstr(filename, "/usr/lib/libicucore")
3282 || strstr(filename, "/usr/lib/libbsm")
3283 || strstr(filename, "/usr/lib/libobjc")
3284 || strstr(filename, "/usr/lib/libresolv")
3285 || strstr(filename, "/usr/lib/libauto")
3286 || strstr(filename, "/usr/lib/libcups")
3287 || strstr(filename, "/usr/lib/libDiagnosticMessagesClient")
3288 || strstr(filename, "/usr/lib/liblangid")
3289 || strstr(filename, "/usr/lib/libCRFSuite")
3290 || strstr(filename, "/usr/lib/libpam")
3291 || strstr(filename, "/usr/lib/libOpenScriptingUtil")
3292 || strstr(filename, "/usr/lib/libextension")
3293 || strstr(filename, "/usr/lib/libAudioToolboxUtility")
3294 || strstr(filename, "/usr/lib/liboah")
3295 || strstr(filename, "/usr/lib/libRosetta")
3296 // "cannot link directly with dylib/framework, your binary is not an allowed client of
3297 // /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
3298 // SDKs/MacOSX.sdk/usr/lib/libAudioToolboxUtility.tbd for architecture x86_64
3299 || (lenFilename > 4 && !strcmp(filename + lenFilename - 4, ".tbd")))
3300 return;
3301 TString sFileName(filename);
3302 R__UpdateLibFileForLinking(sFileName);
3303 filename = sFileName.Data();
3304#elif defined(__CYGWIN__)
3305 // Check that this is not a system library
3306 static const int bufsize = 260;
3307 char posixwindir[bufsize];
3308 char *windir = getenv("WINDIR");
3309 if (windir)
3310 cygwin_conv_path(CCP_WIN_A_TO_POSIX, windir, posixwindir, bufsize);
3311 else
3312 snprintf(posixwindir, sizeof(posixwindir), "/Windows/");
3313 if (strstr(filename, posixwindir) ||
3314 strstr(filename, "/usr/bin/cyg"))
3315 return;
3316#elif defined(R__WIN32)
3317 if (strstr(filename, "/Windows/"))
3318 return;
3319#elif defined (R__LINUX)
3320 if (strstr(filename, "/ld-linux")
3321 || strstr(filename, "linux-gnu/")
3322 || strstr(filename, "/libstdc++.")
3323 || strstr(filename, "/libgcc")
3324 || strstr(filename, "/libc.")
3325 || strstr(filename, "/libdl.")
3326 || strstr(filename, "/libm."))
3327 return;
3328#endif
3329 // Update string of available libraries.
3330 if (!fSharedLibs.IsNull()) {
3331 fSharedLibs.Append(" ");
3332 }
3333 fSharedLibs.Append(filename);
3334}
3335
3336////////////////////////////////////////////////////////////////////////////////
3337/// Load a library file in cling's memory.
3338/// if 'system' is true, the library is never unloaded.
3339/// Return 0 on success, -1 on failure.
3340
3341Int_t TCling::Load(const char* filename, Bool_t system)
3342{
3343 assert(!IsFromRootCling() && "Trying to load library from rootcling!");
3344
3345 // Used to return 0 on success, 1 on duplicate, -1 on failure, -2 on "fatal".
3347 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
3348 std::string canonLib = DLM->lookupLibrary(filename);
3349 cling::DynamicLibraryManager::LoadLibResult res
3350 = cling::DynamicLibraryManager::kLoadLibNotFound;
3351 if (!canonLib.empty()) {
3352 if (system)
3353 res = DLM->loadLibrary(filename, system);
3354 else {
3355 // For the non system libs, we'd like to be able to unload them.
3356 // FIXME: Here we lose the information about kLoadLibAlreadyLoaded case.
3357 cling::Interpreter::CompilationResult compRes;
3358 HandleInterpreterException(GetMetaProcessorImpl(), Form(".L %s", canonLib.c_str()), compRes, /*cling::Value*/0);
3359 if (compRes == cling::Interpreter::kSuccess)
3360 res = cling::DynamicLibraryManager::kLoadLibSuccess;
3361 }
3362 }
3363
3364 if (res == cling::DynamicLibraryManager::kLoadLibSuccess) {
3366 }
3367 switch (res) {
3368 case cling::DynamicLibraryManager::kLoadLibSuccess: return 0;
3369 case cling::DynamicLibraryManager::kLoadLibAlreadyLoaded: return 1;
3370 default: break;
3371 };
3372 return -1;
3373}
3374
3375////////////////////////////////////////////////////////////////////////////////
3376/// Load a macro file in cling's memory.
3377
3378void TCling::LoadMacro(const char* filename, EErrorCode* error)
3379{
3380 ProcessLine(Form(".L %s", filename), error);
3381}
3382
3383////////////////////////////////////////////////////////////////////////////////
3384/// Let cling process a command line asynch.
3385
3387{
3388 return ProcessLine(line, error);
3389}
3390
3391////////////////////////////////////////////////////////////////////////////////
3392/// Let cling process a command line synchronously, i.e we are waiting
3393/// it will be finished.
3394
3396{
3398 if (gApplication) {
3399 if (gApplication->IsCmdThread()) {
3400 return ProcessLine(line, error);
3401 }
3402 return 0;
3403 }
3404 return ProcessLine(line, error);
3405}
3406
3407////////////////////////////////////////////////////////////////////////////////
3408/// Directly execute an executable statement (e.g. "func()", "3+5", etc.
3409/// however not declarations, like "Int_t x;").
3410
3412{
3413#ifdef R__WIN32
3414 // Test on ApplicationImp not being 0 is needed because only at end of
3415 // TApplication ctor the IsLineProcessing flag is set to 0, so before
3416 // we can not use it.
3418 while (gROOT->IsLineProcessing() && !gApplication) {
3419 Warning("Calc", "waiting for cling thread to free");
3420 gSystem->Sleep(500);
3421 }
3422 gROOT->SetLineIsProcessing();
3423 }
3424#endif // R__WIN32
3426 if (error) {
3427 *error = TInterpreter::kNoError;
3428 }
3429 cling::Value valRef;
3430 cling::Interpreter::CompilationResult cr = fInterpreter->evaluate(line, valRef);
3431 if (cr != cling::Interpreter::kSuccess) {
3432 // Failure in compilation.
3433 if (error) {
3434 // Note: Yes these codes are weird.
3436 }
3437 return 0L;
3438 }
3439 if (!valRef.isValid()) {
3440 // Failure at runtime.
3441 if (error) {
3442 // Note: Yes these codes are weird.
3443 *error = TInterpreter::kDangerous;
3444 }
3445 return 0L;
3446 }
3447
3448 if (valRef.isVoid()) {
3449 return 0;
3450 }
3451
3452 RegisterTemporary(valRef);
3453#ifdef R__WIN32
3455 gROOT->SetLineHasBeenProcessed();
3456 }
3457#endif // R__WIN32
3458 return valRef.simplisticCastAs<long>();
3459}
3460
3461////////////////////////////////////////////////////////////////////////////////
3462/// Set a getline function to call when input is needed.
3463
3464void TCling::SetGetline(const char * (*getlineFunc)(const char* prompt),
3465 void (*histaddFunc)(const char* line))
3466{
3467 // If cling offers a replacement for G__pause(), it would need to
3468 // also offer a way to customize at least the history recording.
3469
3470#if defined(R__MUST_REVISIT)
3471#if R__MUST_REVISIT(6,2)
3472 Warning("SetGetline","Cling should support the equivalent of SetGetlineFunc(getlineFunc, histaddFunc)");
3473#endif
3474#endif
3475}
3476
3477////////////////////////////////////////////////////////////////////////////////
3478/// Helper function to increase the internal Cling count of transactions
3479/// that change the AST.
3480
3481Bool_t TCling::HandleNewTransaction(const cling::Transaction &T)
3482{
3484
3485 if ((std::distance(T.decls_begin(), T.decls_end()) != 1)
3486 || T.deserialized_decls_begin() != T.deserialized_decls_end()
3487 || T.macros_begin() != T.macros_end()
3488 || ((!T.getFirstDecl().isNull()) && ((*T.getFirstDecl().begin()) != T.getWrapperFD()))) {
3490 return true;
3491 }
3492 return false;
3493}
3494
3495////////////////////////////////////////////////////////////////////////////////
3496/// Delete object from cling symbol table so it can not be used anymore.
3497/// cling objects are always on the heap.
3498
3500{
3501 // NOTE: When replacing the mutex by a ReadWrite mutex, we **must**
3502 // put in place the Read/Write part here. Keeping the write lock
3503 // here is 'catasptrophic' for scaling as it means that ALL calls
3504 // to RecursiveRemove will take the write lock and performance
3505 // of many threads trying to access the write lock at the same
3506 // time is relatively bad.
3508 // Note that fgSetOfSpecials is supposed to be updated by TClingCallbacks::tryFindROOTSpecialInternal
3509 // (but isn't at the moment).
3510 if (obj->IsOnHeap() && fgSetOfSpecials && !((std::set<TObject*>*)fgSetOfSpecials)->empty()) {
3511 std::set<TObject*>::iterator iSpecial = ((std::set<TObject*>*)fgSetOfSpecials)->find(obj);
3512 if (iSpecial != ((std::set<TObject*>*)fgSetOfSpecials)->end()) {
3514 DeleteGlobal(obj);
3515 ((std::set<TObject*>*)fgSetOfSpecials)->erase(iSpecial);
3516 }
3517 }
3518}
3519
3520////////////////////////////////////////////////////////////////////////////////
3521/// Pressing Ctrl+C should forward here. In the case where we have had
3522/// continuation requested we must reset it.
3523
3525{
3526 fMetaProcessor->cancelContinuation();
3527 // Reset the Cling state to the state saved by the last call to
3528 // TCling::SaveContext().
3529#if defined(R__MUST_REVISIT)
3530#if R__MUST_REVISIT(6,2)
3532 Warning("Reset","Cling should support the equivalent of scratch_upto(&fDictPos)");
3533#endif
3534#endif
3535}
3536
3537////////////////////////////////////////////////////////////////////////////////
3538/// Reset the Cling state to its initial state.
3539
3541{
3542#if defined(R__MUST_REVISIT)
3543#if R__MUST_REVISIT(6,2)
3545 Warning("ResetAll","Cling should support the equivalent of complete reset (unload everything but the startup decls.");
3546#endif
3547#endif
3548}
3549
3550////////////////////////////////////////////////////////////////////////////////
3551/// Reset in Cling the list of global variables to the state saved by the last
3552/// call to TCling::SaveGlobalsContext().
3553///
3554/// Note: Right now, all we do is run the global destructors.
3555
3557{
3559 // TODO:
3560 // Here we should iterate over the transactions (N-3) and revert.
3561 // N-3 because the first three internal to cling.
3562
3563 fInterpreter->runAndRemoveStaticDestructors();
3564}
3565
3566////////////////////////////////////////////////////////////////////////////////
3567/// Reset the Cling 'user' global objects/variables state to the state saved by the last
3568/// call to TCling::SaveGlobalsContext().
3569
3571{
3572#if defined(R__MUST_REVISIT)
3573#if R__MUST_REVISIT(6,2)
3575 Warning("ResetGlobalVar","Cling should support the equivalent of resetglobalvar(obj)");
3576#endif
3577#endif
3578}
3579
3580////////////////////////////////////////////////////////////////////////////////
3581/// Rewind Cling dictionary to the point where it was before executing
3582/// the current macro. This function is typically called after SEGV or
3583/// ctlr-C after doing a longjmp back to the prompt.
3584
3586{
3587#if defined(R__MUST_REVISIT)
3588#if R__MUST_REVISIT(6,2)
3590 Warning("RewindDictionary","Cling should provide a way to revert transaction similar to rewinddictionary()");
3591#endif
3592#endif
3593}
3594
3595////////////////////////////////////////////////////////////////////////////////
3596/// Delete obj from Cling symbol table so it cannot be accessed anymore.
3597/// Returns 1 in case of success and 0 in case object was not in table.
3598
3600{
3601#if defined(R__MUST_REVISIT)
3602#if R__MUST_REVISIT(6,2)
3604 Warning("DeleteGlobal","Cling should provide the equivalent of deleteglobal(obj), see also DeleteVariable.");
3605#endif
3606#endif
3607 return 0;
3608}
3609
3610////////////////////////////////////////////////////////////////////////////////
3611/// Undeclare obj called name.
3612/// Returns 1 in case of success, 0 for failure.
3613
3615{
3616#if defined(R__MUST_REVISIT)
3617#if R__MUST_REVISIT(6,2)
3618 Warning("DeleteVariable","should do more that just reseting the value to zero");
3619#endif
3620#endif
3621
3623 llvm::StringRef srName(name);
3624 const char* unscopedName = name;
3625 llvm::StringRef::size_type posScope = srName.rfind("::");
3626 const clang::DeclContext* declCtx = 0;
3627 if (posScope != llvm::StringRef::npos) {
3628 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
3629 const clang::Decl* scopeDecl
3630 = lh.findScope(srName.substr(0, posScope),
3631 cling::LookupHelper::WithDiagnostics);
3632 if (!scopeDecl) {
3633 Error("DeleteVariable", "Cannot find enclosing scope for variable %s",
3634 name);
3635 return 0;
3636 }
3637 declCtx = llvm::dyn_cast<clang::DeclContext>(scopeDecl);
3638 if (!declCtx) {
3639 Error("DeleteVariable",
3640 "Enclosing scope for variable %s is not a declaration context",
3641 name);
3642 return 0;
3643 }
3644 unscopedName += posScope + 2;
3645 }
3646 // Could trigger deserialization of decls.
3647 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
3648 clang::NamedDecl* nVarDecl
3649 = cling::utils::Lookup::Named(&fInterpreter->getSema(), unscopedName, declCtx);
3650 if (!nVarDecl) {
3651 Error("DeleteVariable", "Unknown variable %s", name);
3652 return 0;
3653 }
3654 clang::VarDecl* varDecl = llvm::dyn_cast<clang::VarDecl>(nVarDecl);
3655 if (!varDecl) {
3656 Error("DeleteVariable", "Entity %s is not a variable", name);
3657 return 0;
3658 }
3659
3660 clang::QualType qType = varDecl->getType();
3661 const clang::Type* type = qType->getUnqualifiedDesugaredType();
3662 // Cannot set a reference's address to nullptr; the JIT can place it
3663 // into read-only memory (ROOT-7100).
3664 if (type->isPointerType()) {
3665 int** ppInt = (int**)fInterpreter->getAddressOfGlobal(GlobalDecl(varDecl));
3666 // set pointer to invalid.
3667 if (ppInt) *ppInt = 0;
3668 }
3669 return 1;
3670}
3671
3672////////////////////////////////////////////////////////////////////////////////
3673/// Save the current Cling state.
3674
3676{
3677#if defined(R__MUST_REVISIT)
3678#if R__MUST_REVISIT(6,2)
3680 Warning("SaveContext","Cling should provide a way to record a state watermark similar to store_dictposition(&fDictPos)");
3681#endif
3682#endif
3683}
3684
3685////////////////////////////////////////////////////////////////////////////////
3686/// Save the current Cling state of global objects.
3687
3689{
3690#if defined(R__MUST_REVISIT)
3691#if R__MUST_REVISIT(6,2)
3693 Warning("SaveGlobalsContext","Cling should provide a way to record a watermark for the list of global variable similar to store_dictposition(&fDictPosGlobals)");
3694#endif
3695#endif
3696}
3697
3698////////////////////////////////////////////////////////////////////////////////
3699/// No op: see TClingCallbacks (used to update the list of globals)
3700
3702{
3703}
3704
3705////////////////////////////////////////////////////////////////////////////////
3706/// No op: see TClingCallbacks (used to update the list of global functions)
3707
3709{
3710}
3711
3712////////////////////////////////////////////////////////////////////////////////
3713/// No op: see TClingCallbacks (used to update the list of types)
3714
3716{
3717}
3718
3719////////////////////////////////////////////////////////////////////////////////
3720/// Check in what order the member of a tuple are layout.
3721enum class ETupleOrdering {
3722 kAscending,
3725};
3726
3727struct AlternateTupleIntDoubleAsc
3728{
3729 Int_t _0;
3730 Double_t _1;
3731};
3732
3733struct AlternateTupleIntDoubleDes
3734{
3735 Double_t _1;
3736 Int_t _0;
3737};
3738
3740{
3741 std::tuple<int,double> value;
3742 AlternateTupleIntDoubleAsc asc;
3743 AlternateTupleIntDoubleDes des;
3744
3745 size_t offset0 = ((char*)&(std::get<0>(value))) - ((char*)&value);
3746 size_t offset1 = ((char*)&(std::get<1>(value))) - ((char*)&value);
3747
3748 size_t ascOffset0 = ((char*)&(asc._0)) - ((char*)&asc);
3749 size_t ascOffset1 = ((char*)&(asc._1)) - ((char*)&asc);
3750
3751 size_t desOffset0 = ((char*)&(des._0)) - ((char*)&des);
3752 size_t desOffset1 = ((char*)&(des._1)) - ((char*)&des);
3753
3754 if (offset0 == ascOffset0 && offset1 == ascOffset1) {
3756 } else if (offset0 == desOffset0 && offset1 == desOffset1) {
3758 } else {
3760 }
3761}
3762
3763static std::string AlternateTuple(const char *classname, const cling::LookupHelper& lh)
3764{
3765 TClassEdit::TSplitType tupleContent(classname);
3766 std::string alternateName = "TEmulatedTuple";
3767 alternateName.append( classname + 5 );
3768
3769 std::string fullname = "ROOT::Internal::" + alternateName;
3770 if (lh.findScope(fullname, cling::LookupHelper::NoDiagnostics,
3771 /*resultType*/nullptr, /* intantiateTemplate= */ false))
3772 return fullname;
3773
3774 std::string guard_name;
3775 ROOT::TMetaUtils::GetCppName(guard_name,alternateName.c_str());
3776 std::ostringstream guard;
3777 guard << "ROOT_INTERNAL_TEmulated_";
3778 guard << guard_name;
3779
3780 std::ostringstream alternateTuple;
3781 alternateTuple << "#ifndef " << guard.str() << "\n";
3782 alternateTuple << "#define " << guard.str() << "\n";
3783 alternateTuple << "namespace ROOT { namespace Internal {\n";
3784 alternateTuple << "template <class... Types> struct TEmulatedTuple;\n";
3785 alternateTuple << "template <> struct " << alternateName << " {\n";
3786
3787 // This could also be a compile time choice ...
3788 switch(IsTupleAscending()) {
3790 unsigned int nMember = 0;
3791 auto iter = tupleContent.fElements.begin() + 1; // Skip the template name (tuple)
3792 auto theEnd = tupleContent.fElements.end() - 1; // skip the 'stars'.
3793 while (iter != theEnd) {
3794 alternateTuple << " " << *iter << " _" << nMember << ";\n";
3795 ++iter;
3796 ++nMember;
3797 }
3798 break;
3799 }
3801 unsigned int nMember = tupleContent.fElements.size() - 3;
3802 auto iter = tupleContent.fElements.rbegin() + 1; // Skip the template name (tuple)
3803 auto theEnd = tupleContent.fElements.rend() - 1; // skip the 'stars'.
3804 while (iter != theEnd) {
3805 alternateTuple << " " << *iter << " _" << nMember << ";\n";
3806 ++iter;
3807 --nMember;
3808 }
3809 break;
3810 }
3812 Fatal("TCling::SetClassInfo::AlternateTuple",
3813 "Layout of std::tuple on this platform is unexpected.");
3814 break;
3815 }
3816 }
3817
3818 alternateTuple << "};\n";
3819 alternateTuple << "}}\n";
3820 alternateTuple << "#endif\n";
3821 if (!gCling->Declare(alternateTuple.str().c_str())) {
3822 Error("Load","Could not declare %s",alternateName.c_str());
3823 return "";
3824 }
3825 alternateName = "ROOT::Internal::" + alternateName;
3826 return alternateName;
3827}
3828
3829////////////////////////////////////////////////////////////////////////////////
3830/// Set pointer to the TClingClassInfo in TClass.
3831/// If 'reload' is true, (attempt to) generate a new ClassInfo even if we
3832/// already have one.
3833
3835{
3836 // We are shutting down, there is no point in reloading, it only triggers
3837 // redundant deserializations.
3838 if (fIsShuttingDown) {
3839 // Remove the decl_id from the DeclIdToTClass map
3840 if (cl->fClassInfo) {
3842 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
3843 // Test again as another thread may have set fClassInfo to nullptr.
3844 if (TClinginfo) {
3845 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
3846 }
3847 delete TClinginfo;
3848 cl->fClassInfo = nullptr;
3849 }
3850 return;
3851 }
3852
3854 if (cl->fClassInfo && !reload) {
3855 return;
3856 }
3857 //Remove the decl_id from the DeclIdToTClass map
3858 TClingClassInfo* TClinginfo = (TClingClassInfo*) cl->fClassInfo;
3859 if (TClinginfo) {
3860 TClass::RemoveClassDeclId(TClinginfo->GetDeclId());
3861 }
3862 delete TClinginfo;
3863 cl->fClassInfo = 0;
3864 std::string name(cl->GetName());
3865
3866 // Handle the special case of 'tuple' where we ignore the real implementation
3867 // details and just overlay a 'simpler'/'simplistic' version that is easy
3868 // for the I/O to understand and handle.
3869 if (strncmp(cl->GetName(),"tuple<",strlen("tuple<"))==0) {
3870
3871 name = AlternateTuple(cl->GetName(), fInterpreter->getLookupHelper());
3872
3873 }
3874
3875 bool instantiateTemplate = !cl->TestBit(TClass::kUnloading);
3876 // FIXME: Rather than adding an option to the TClingClassInfo, we should consider combining code
3877 // that is currently in the caller (like SetUnloaded) that disable AutoLoading and AutoParsing and
3878 // code is in the callee (disabling template instantiation) and end up with a more explicit class:
3879 // TClingClassInfoReadOnly.
3880 TClingClassInfo* info = new TClingClassInfo(GetInterpreterImpl(), name.c_str(), instantiateTemplate);
3881 if (!info->IsValid()) {
3882 if (cl->fState != TClass::kHasTClassInit) {
3883 if (cl->fStreamerInfo->GetEntries() != 0) {
3885 } else {
3887 }
3888 }
3889 delete info;
3890 return;
3891 }
3892 cl->fClassInfo = (ClassInfo_t*)info; // Note: We are transferring ownership here.
3893 // In case a class contains an external enum, the enum will be seen as a
3894 // class. We must detect this special case and make the class a Zombie.
3895 // Here we assume that a class has at least one method.
3896 // We can NOT call TClass::Property from here, because this method
3897 // assumes that the TClass is well formed to do a lot of information
3898 // caching. The method SetClassInfo (i.e. here) is usually called during
3899 // the building phase of the TClass, hence it is NOT well formed yet.
3900 Bool_t zombieCandidate = kFALSE;
3901 if (
3902 info->IsValid() &&
3903 !(info->Property() & (kIsClass | kIsStruct | kIsNamespace))
3904 ) {
3905 zombieCandidate = kTRUE;
3906 }
3907 if (!info->IsLoaded()) {
3908 if (info->Property() & (kIsNamespace)) {
3909 // Namespaces can have info but no corresponding CINT dictionary
3910 // because they are auto-created if one of their contained
3911 // classes has a dictionary.
3912 zombieCandidate = kTRUE;
3913 }
3914 // this happens when no dictionary is available
3915 delete info;
3916 cl->fClassInfo = 0;
3917 }
3918 if (zombieCandidate && !cl->GetCollectionType()) {
3919 cl->MakeZombie();
3920 }
3921 // If we reach here, the info was valid (See early returns).
3922 if (cl->fState != TClass::kHasTClassInit) {
3923 if (cl->fClassInfo) {
3926 } else {
3927// if (TClassEdit::IsSTLCont(cl->GetName()) {
3928// There will be an emulated collection proxy, is that the same?
3929// cl->fState = TClass::kEmulated;
3930// } else {
3931 if (cl->fStreamerInfo->GetEntries() != 0) {
3933 } else {
3935 }
3936// }
3937 }
3938 }
3939 if (cl->fClassInfo) {
3940 TClass::AddClassToDeclIdMap(((TClingClassInfo*)cl->fClassInfo)->GetDeclId(), cl);
3941 }
3942}
3943
3944////////////////////////////////////////////////////////////////////////////////
3945/// Checks if an entity with the specified name is defined in Cling.
3946/// Returns kUnknown if the entity is not defined.
3947/// Returns kWithClassDefInline if the entity exists and has a ClassDefInline
3948/// Returns kKnown if the entity is defined.
3949///
3950/// By default, structs, namespaces, classes, enums and unions are looked for.
3951/// If the flag isClassOrNamespaceOnly is true, classes, structs and
3952/// namespaces only are considered. I.e. if the name is an enum or a union,
3953/// the returned value is false.
3954///
3955/// In the case where the class is not loaded and belongs to a namespace
3956/// or is nested, looking for the full class name is outputting a lots of
3957/// (expected) error messages. Currently the only way to avoid this is to
3958/// specifically check that each level of nesting is already loaded.
3959/// In case of templates the idea is that everything between the outer
3960/// '<' and '>' has to be skipped, e.g.: aap<pippo<noot>::klaas>::a_class
3961
3963TCling::CheckClassInfo(const char *name, Bool_t autoload, Bool_t isClassOrNamespaceOnly /* = kFALSE*/)
3964{
3966 static const char *anonEnum = "anonymous enum ";
3967 static const int cmplen = strlen(anonEnum);
3968
3969 if (fIsShuttingDown || 0 == strncmp(name, anonEnum, cmplen)) {
3970 return kUnknown;
3971 }
3972
3973 // Do not turn on the AutoLoading if it is globally off.
3974 autoload = autoload && IsClassAutoLoadingEnabled();
3975
3976 // Avoid the double search below in case the name is a fundamental type
3977 // or typedef to a fundamental type.
3978 THashTable *typeTable = dynamic_cast<THashTable*>( gROOT->GetListOfTypes() );
3979 TDataType *fundType = (TDataType *)typeTable->THashTable::FindObject( name );
3980
3981 if (fundType && fundType->GetType() < TVirtualStreamerInfo::kObject
3982 && fundType->GetType() > 0) {
3983 // Fundamental type, no a class.
3984 return kUnknown;
3985 }
3986
3987 // Migrated from within TClass::GetClass
3988 // If we want to know if a class or a namespace with this name exists in the
3989 // interpreter and this is an enum in the type system, before or after loading
3990 // according to the autoload function argument, return kUnknown.
3991 if (isClassOrNamespaceOnly && TEnum::GetEnum(name, autoload ? TEnum::kAutoload : TEnum::kNone))
3992 return kUnknown;
3993
3994 const char *classname = name;
3995
3996 // RAII to suspend and restore auto-loading and auto-parsing based on some external conditions.
3997 class MaybeSuspendAutoLoadParse {
3998 int fStoreAutoLoad = 0;
3999 int fStoreAutoParse = 0;
4000 bool fSuspendedAutoParse = false;
4001 public:
4002 MaybeSuspendAutoLoadParse(int autoload) {
4003 fStoreAutoLoad = ((TCling*)gCling)->SetClassAutoLoading(autoload);
4004 }
4005
4006 void SuspendAutoParsing() {
4007 fSuspendedAutoParse = true;
4008 fStoreAutoParse = ((TCling*)gCling)->SetSuspendAutoParsing(true);
4009 }
4010
4011 ~MaybeSuspendAutoLoadParse() {
4012 if (fSuspendedAutoParse)
4013 ((TCling*)gCling)->SetSuspendAutoParsing(fStoreAutoParse);
4014 ((TCling*)gCling)->SetClassAutoLoading(fStoreAutoLoad);
4015 }
4016 };
4017
4018 MaybeSuspendAutoLoadParse autoLoadParseRAII( autoload );
4019 if (TClassEdit::IsStdPair(classname) || TClassEdit::IsStdPairBase(classname))
4020 autoLoadParseRAII.SuspendAutoParsing();
4021
4022 // First we want to check whether the decl exist, but _without_
4023 // generating any template instantiation. However, the lookup
4024 // still will create a forward declaration of the class template instance
4025 // if it exist. In this case, the return value of findScope will still
4026 // be zero but the type will be initialized.
4027 // Note in the corresponding code in ROOT 5, CINT was not instantiating
4028 // this forward declaration.
4029 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4030 const clang::Type *type = 0;
4031 const clang::Decl *decl
4032 = lh.findScope(classname,
4033 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4034 : cling::LookupHelper::NoDiagnostics,
4035 &type, /* intantiateTemplate= */ false );
4036 if (!decl) {
4037 std::string buf = TClassEdit::InsertStd(classname);
4038 decl = lh.findScope(buf,
4039 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4040 : cling::LookupHelper::NoDiagnostics,
4041 &type,false);
4042 }
4043
4044 if (type) {
4045 // If decl==0 and the type is valid, then we have a forward declaration.
4046 if (!decl) {
4047 // If we have a forward declaration for a class template instantiation,
4048 // we want to ignore it if it was produced/induced by the call to
4049 // findScope, however we can not distinguish those from the
4050 // instantiation induce by 'soft' use (and thus also induce by the
4051 // same underlying code paths)
4052 // ['soft' use = use not requiring a complete definition]
4053 // So to reduce the amount of disruption to the existing code we
4054 // would just ignore those for STL collection, for which we really
4055 // need to have the compiled collection proxy (and thus the TClass
4056 // bootstrap).
4057 clang::ClassTemplateSpecializationDecl *tmpltDecl =
4058 llvm::dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>
4059 (type->getAsCXXRecordDecl());
4060 if (tmpltDecl && !tmpltDecl->getPointOfInstantiation().isValid()) {
4061 // Since the point of instantiation is invalid, we 'guess' that
4062 // the 'instantiation' of the forwarded type appended in
4063 // findscope.
4064 if (ROOT::TMetaUtils::IsSTLCont(*tmpltDecl)) {
4065 // For STL Collection we return kUnknown.
4066 return kUnknown;
4067 }
4068 }
4069 }
4071 if (!tci.IsValid()) {
4072 return kUnknown;
4073 }
4074 auto propertiesMask = isClassOrNamespaceOnly ? kIsClass | kIsStruct | kIsNamespace :
4076
4077 if (tci.Property() & propertiesMask) {
4078 bool hasClassDefInline = false;
4079 if (isClassOrNamespaceOnly) {
4080 // We do not need to check for ClassDefInline when this is called from
4081 // TClass::Init, we only do it for the call from TClass::GetClass.
4082 auto hasDictionary = tci.GetMethod("Dictionary", "", false, 0, ROOT::kExactMatch);
4083 auto implLineFunc = tci.GetMethod("ImplFileLine", "", false, 0, ROOT::kExactMatch);
4084
4085 if (hasDictionary.IsValid() && implLineFunc.IsValid()) {
4086 int lineNumber = 0;
4087 bool success = false;
4088 std::tie(success, lineNumber) =
4089 ROOT::TMetaUtils::GetTrivialIntegralReturnValue(implLineFunc.GetAsFunctionDecl(), *fInterpreter);
4090 hasClassDefInline = success && (lineNumber == -1);
4091 }
4092 }
4093
4094 // fprintf(stderr,"CheckClassInfo: %s had dict=%d inline=%d\n",name,hasDictionary.IsValid()
4095 // , hasClassDefInline);
4096
4097 // We are now sure that the entry is not in fact an autoload entry.
4098 if (hasClassDefInline)
4099 return kWithClassDefInline;
4100 else
4101 return kKnown;
4102 } else {
4103 // We are now sure that the entry is not in fact an autoload entry.
4104 return kUnknown;
4105 }
4106 }
4107
4108 if (decl)
4109 return kKnown;
4110 else
4111 return kUnknown;
4112
4113 // Setting up iterator part of TClingTypedefInfo is too slow.
4114 // Copy the lookup code instead:
4115 /*
4116 TClingTypedefInfo t(fInterpreter, name);
4117 if (t.IsValid() && !(t.Property() & kIsFundamental)) {
4118 delete[] classname;
4119 return kTRUE;
4120 }
4121 */
4122
4123// const clang::Decl *decl = lh.findScope(name);
4124// if (!decl) {
4125// std::string buf = TClassEdit::InsertStd(name);
4126// decl = lh.findScope(buf);
4127// }
4128
4129// return (decl);
4130}
4131
4132////////////////////////////////////////////////////////////////////////////////
4133/// Return true if there is a class template by the given name ...
4134
4136{
4137 const cling::LookupHelper& lh = fInterpreter->getLookupHelper();
4138 const clang::Decl *decl
4139 = lh.findClassTemplate(name,
4140 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4141 : cling::LookupHelper::NoDiagnostics);
4142 if (!decl) {
4143 std::string strname = "std::";
4144 strname += name;
4145 decl = lh.findClassTemplate(strname,
4146 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
4147 : cling::LookupHelper::NoDiagnostics);
4148 }
4149 return 0 != decl;
4150}
4151
4152////////////////////////////////////////////////////////////////////////////////
4153/// Create list of pointers to base class(es) for TClass cl.
4154
4156{
4158 if (cl->fBase) {
4159 return;
4160 }
4162 if (!tci) return;
4164 TList *listOfBase = new TList;
4165 while (t.Next()) {
4166 // if name cannot be obtained no use to put in list
4167 if (t.IsValid() && t.Name()) {
4169 listOfBase->Add(new TBaseClass((BaseClassInfo_t *)a, cl));
4170 }
4171 }
4172 // Now that is complete, publish it.
4173 cl->fBase = listOfBase;
4174}
4175
4176////////////////////////////////////////////////////////////////////////////////
4177/// Create list of pointers to enums for TClass cl.
4178
4179void TCling::LoadEnums(TListOfEnums& enumList) const
4180{
4182
4183 const Decl * D;
4184 TClass* cl = enumList.GetClass();
4185 if (cl) {
4186 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4187 }
4188 else {
4189 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4190 }
4191 // Iterate on the decl of the class and get the enums.
4192 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4193 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4194 // Collect all contexts of the namespace.
4195 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4196 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4197 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(), declEnd = allDeclContexts.end();
4198 declIter != declEnd; ++declIter) {
4199 // Iterate on all decls for each context.
4200 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4201 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4202 if (const clang::EnumDecl* ED = dyn_cast<clang::EnumDecl>(*DI)) {
4203 // Get name of the enum type.
4204 std::string buf;
4205 PrintingPolicy Policy(ED->getASTContext().getPrintingPolicy());
4206 llvm::raw_string_ostream stream(buf);
4207 // Don't trigger fopen of the source file to count lines:
4208 Policy.AnonymousTagLocations = false;
4209 ED->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
4210 stream.flush();
4211 // If the enum is unnamed we do not add it to the list of enums i.e unusable.
4212 if (!buf.empty()) {
4213 const char* name = buf.c_str();
4214 // Add the enum to the list of loaded enums.
4215 enumList.Get(ED, name);
4216 }
4217 }
4218 }
4219 }
4220 }
4221}
4222
4223////////////////////////////////////////////////////////////////////////////////
4224/// Create list of pointers to function templates for TClass cl.
4225
4227{
4229
4230 const Decl * D;
4231 TListOfFunctionTemplates* funcTempList;
4232 if (cl) {
4233 D = ((TClingClassInfo*)cl->GetClassInfo())->GetDecl();
4234 funcTempList = (TListOfFunctionTemplates*)cl->GetListOfFunctionTemplates(false);
4235 }
4236 else {
4237 D = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
4238 funcTempList = (TListOfFunctionTemplates*)gROOT->GetListOfFunctionTemplates();
4239 }
4240 // Iterate on the decl of the class and get the enums.
4241 if (const clang::DeclContext* DC = dyn_cast<clang::DeclContext>(D)) {
4242 cling::Interpreter::PushTransactionRAII deserRAII(GetInterpreterImpl());
4243 // Collect all contexts of the namespace.
4244 llvm::SmallVector< DeclContext *, 4> allDeclContexts;
4245 const_cast< clang::DeclContext *>(DC)->collectAllContexts(allDeclContexts);
4246 for (llvm::SmallVector<DeclContext*, 4>::iterator declIter = allDeclContexts.begin(),
4247 declEnd = allDeclContexts.end(); declIter != declEnd; ++declIter) {
4248 // Iterate on all decls for each context.
4249 for (clang::DeclContext::decl_iterator DI = (*declIter)->decls_begin(),
4250 DE = (*declIter)->decls_end(); DI != DE; ++DI) {
4251 if (const clang::FunctionTemplateDecl* FTD = dyn_cast<clang::FunctionTemplateDecl>(*DI)) {
4252 funcTempList->Get(FTD);
4253 }
4254 }
4255 }
4256 }
4257}
4258
4259////////////////////////////////////////////////////////////////////////////////
4260/// Get the scopes representing using declarations of namespace
4261
4262std::vector<std::string> TCling::GetUsingNamespaces(ClassInfo_t *cl) const
4263{
4265 return ci->GetUsingNamespaces();
4266}
4267
4268////////////////////////////////////////////////////////////////////////////////
4269/// Create list of pointers to data members for TClass cl.
4270/// This is now a nop. The creation and updating is handled in
4271/// TListOfDataMembers.
4272
4274{
4275}
4276
4277////////////////////////////////////////////////////////////////////////////////
4278/// Create list of pointers to methods for TClass cl.
4279/// This is now a nop. The creation and updating is handled in
4280/// TListOfFunctions.
4281
4283{
4284}
4285
4286////////////////////////////////////////////////////////////////////////////////
4287/// Update the list of pointers to method for TClass cl
4288/// This is now a nop. The creation and updating is handled in
4289/// TListOfFunctions.
4290
4292{
4293}
4294
4295////////////////////////////////////////////////////////////////////////////////
4296/// Update the list of pointers to data members for TClass cl
4297/// This is now a nop. The creation and updating is handled in
4298/// TListOfDataMembers.
4299
4301{
4302}
4303
4304////////////////////////////////////////////////////////////////////////////////
4305/// Create list of pointers to method arguments for TMethod m.
4306
4308{
4310 if (m->fMethodArgs) {
4311 return;
4312 }
4313 TList *arglist = new TList;
4315 while (t.Next()) {
4316 if (t.IsValid()) {
4318 arglist->Add(new TMethodArg((MethodArgInfo_t*)a, m));
4319 }
4320 }
4321 m->fMethodArgs = arglist;
4322}
4323
4324
4325////////////////////////////////////////////////////////////////////////////////
4326/// Generate a TClass for the given class.
4327/// Since the caller has already check the ClassInfo, let it give use the
4328/// result (via the value of emulation) rather than recalculate it.
4329
4330TClass *TCling::GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent /* = kFALSE */)
4331{
4332// For now the following line would lead to the (unwanted) instantiation
4333// of class template. This could/would need to be resurrected only if
4334// we re-introduce so sort of automatic instantiation. However this would
4335// have to include carefull look at the template parameter to avoid
4336// creating instance we can not really use (if the parameter are only forward
4337// declaration or do not have all the necessary interfaces).
4338
4339 // TClingClassInfo tci(fInterpreter, classname);
4340 // if (1 || !tci.IsValid()) {
4341
4342 Version_t version = 1;
4343 if (TClassEdit::IsSTLCont(classname)) {
4344 version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4345 }
4347 TClass *cl = new TClass(classname, version, silent);
4348 if (emulation) {
4350 } else {
4351 // Set the class version if the class is versioned.
4352 // Note that we cannot just call CLASS::Class_Version() as we might not have
4353 // an execution engine (when invoked from rootcling).
4354
4355 // Do not call cl->GetClassVersion(), it has side effects!
4356 Version_t oldvers = cl->fClassVersion;
4357 if (oldvers == version && cl->GetClassInfo()) {
4358 // We have a version and it might need an update.
4359 Version_t newvers = oldvers;
4361 if (llvm::isa<clang::NamespaceDecl>(cli->GetDecl())) {
4362 // Namespaces don't have class versions.
4363 return cl;
4364 }
4365 TClingMethodInfo mi = cli->GetMethod("Class_Version", "", 0 /*poffset*/,
4368 if (!mi.IsValid()) {
4369 if (cl->TestBit(TClass::kIsTObject)) {
4370 Error("GenerateTClass",
4371 "Cannot find %s::Class_Version()! Class version might be wrong.",
4372 cl->GetName());
4373 }
4374 return cl;
4375 }
4376 newvers = ROOT::TMetaUtils::GetClassVersion(llvm::dyn_cast<clang::RecordDecl>(cli->GetDecl()),
4377 *fInterpreter);
4378 if (newvers == -1) {
4379 // Didn't manage to determine the class version from the AST.
4380 // Use runtime instead.
4381 if ((mi.Property() & kIsStatic)
4382 && !fInterpreter->isInSyntaxOnlyMode()) {
4383 // This better be a static function.
4385 callfunc.SetFunc(&mi);
4386 newvers = callfunc.ExecInt(0);
4387 } else {
4388 Error("GenerateTClass",
4389 "Cannot invoke %s::Class_Version()! Class version might be wrong.",
4390 cl->GetName());
4391 }
4392 }
4393 if (newvers != oldvers) {
4394 cl->fClassVersion = newvers;
4395 cl->fStreamerInfo->Expand(newvers + 2 + 10);
4396 }
4397 }
4398 }
4399
4400 return cl;
4401
4402// } else {
4403// return GenerateTClass(&tci,silent);
4404// }
4405}
4406
4407#if 0
4408////////////////////////////////////////////////////////////////////////////////
4409
4410static void GenerateTClass_GatherInnerIncludes(cling::Interpreter *interp, TString &includes,TClingClassInfo *info)
4411{
4412 includes += info->FileName();
4413
4414 const clang::ClassTemplateSpecializationDecl *templateCl
4415 = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(info->GetDecl());
4416 if (templateCl) {
4417 for(unsigned int i=0; i < templateCl->getTemplateArgs().size(); ++i) {
4418 const clang::TemplateArgument &arg( templateCl->getTemplateArgs().get(i) );
4419 if (arg.getKind() == clang::TemplateArgument::Type) {
4420 const clang::Type *uType = ROOT::TMetaUtils::GetUnderlyingType( arg.getAsType() );
4421
4422 if (!uType->isFundamentalType() && !uType->isEnumeralType()) {
4423 // We really need a header file.
4424 const clang::CXXRecordDecl *argdecl = uType->getAsCXXRecordDecl();
4425 if (argdecl) {
4426 includes += ";";
4427 TClingClassInfo subinfo(interp,*(argdecl->getASTContext().getRecordType(argdecl).getTypePtr()));
4428 GenerateTClass_GatherInnerIncludes(interp, includes, &subinfo);
4429 } else {
4430 std::string Result;
4431 llvm::raw_string_ostream OS(Result);
4432 arg.print(argdecl->getASTContext().getPrintingPolicy(),OS);
4433 Warning("TCling::GenerateTClass","Missing header file for %s",OS.str().c_str());
4434 }
4435 }
4436 }
4437 }
4438 }
4439}
4440#endif
4441
4442////////////////////////////////////////////////////////////////////////////////
4443/// Generate a TClass for the given class.
4444
4445TClass *TCling::GenerateTClass(ClassInfo_t *classinfo, Bool_t silent /* = kFALSE */)
4446{
4447 TClingClassInfo *info = (TClingClassInfo*)classinfo;
4448 if (!info || !info->IsValid()) {
4449 Fatal("GenerateTClass","Requires a valid ClassInfo object");
4450 return 0;
4451 }
4452 // We are in the case where we have AST nodes for this class.
4453 TClass *cl = 0;
4454 std::string classname;
4455 info->FullName(classname,*fNormalizedCtxt); // Could we use Name()?
4456 if (TClassEdit::IsSTLCont(classname)) {
4457#if 0
4458 Info("GenerateTClass","Will (try to) generate the compiled TClass for %s.",classname.c_str());
4459 // We need to build up the list of required headers, by
4460 // looking at each template arguments.
4461 TString includes;
4462 GenerateTClass_GatherInnerIncludes(fInterpreter,includes,info);
4463
4464 if (0 == GenerateDictionary(classname.c_str(),includes)) {
4465 // 0 means success.
4466 cl = TClass::LoadClass(classnam.c_str(), silent);
4467 if (cl == 0) {
4468 Error("GenerateTClass","Even though the dictionary generation for %s seemed successful we can't find the TClass bootstrap!",classname.c_str());
4469 }
4470 }
4471#endif
4472 if (cl == 0) {
4473 int version = TClass::GetClass("TVirtualStreamerInfo")->GetClassVersion();
4474 cl = new TClass(classinfo, version, 0, 0, -1, -1, silent);
4476 }
4477 } else {
4478 // For regular class, just create a TClass on the fly ...
4479 // Not quite useful yet, but that what CINT used to do anyway.
4480 cl = new TClass(classinfo, 1, 0, 0, -1, -1, silent);
4481 }
4482 // Add the new TClass to the map of declid and TClass*.
4483 if (cl) {
4485 }
4486 return cl;
4487}
4488
4489////////////////////////////////////////////////////////////////////////////////
4490/// Generate the dictionary for the C++ classes listed in the first
4491/// argument (in a semi-colon separated list).
4492/// 'includes' contains a semi-colon separated list of file to
4493/// #include in the dictionary.
4494/// For example:
4495/// ~~~ {.cpp}
4496/// gInterpreter->GenerateDictionary("vector<vector<float> >;list<vector<float> >","list;vector");
4497/// ~~~
4498/// or
4499/// ~~~ {.cpp}
4500/// gInterpreter->GenerateDictionary("myclass","myclass.h;myhelper.h");
4501/// ~~~
4502
4503Int_t TCling::GenerateDictionary(const char* classes, const char* includes /* = "" */, const char* /* options = 0 */)
4504{
4505 if (classes == 0 || classes[0] == 0) {
4506 Error("TCling::GenerateDictionary", "Cannot generate dictionary without passing classes.");
4507 return 0;
4508 }
4509 // Split the input list
4510 std::vector<std::string> listClasses;
4511 for (
4512 const char* current = classes, *prev = classes;
4513 *current != 0;
4514 ++current
4515 ) {
4516 if (*current == ';') {
4517 listClasses.push_back(std::string(prev, current - prev));
4518 prev = current + 1;
4519 }
4520 else if (*(current + 1) == 0) {
4521 listClasses.push_back(std::string(prev, current + 1 - prev));
4522 prev = current + 1;
4523 }
4524 }
4525 std::vector<std::string> listIncludes;
4526 if (!includes)
4527 includes = "";
4528 for (
4529 const char* current = includes, *prev = includes;
4530 *current != 0;
4531 ++current
4532 ) {
4533 if (*current == ';') {
4534 listIncludes.push_back(std::string(prev, current - prev));
4535 prev = current + 1;
4536 }
4537 else if (*(current + 1) == 0) {
4538 listIncludes.push_back(std::string(prev, current + 1 - prev));
4539 prev = current + 1;
4540 }
4541 }
4542 // Generate the temporary dictionary file
4543 return !TCling_GenerateDictionary(listClasses, listIncludes,
4544 std::vector<std::string>(), std::vector<std::string>());
4545}
4546
4547////////////////////////////////////////////////////////////////////////////////
4548/// Return pointer to cling Decl of global/static variable that is located
4549/// at the address given by addr.
4550
4551TInterpreter::DeclId_t TCling::GetDataMember(ClassInfo_t *opaque_cl, const char *name) const
4552{
4554 DeclId_t d;
4555 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4556
4557 if (cl) {
4558 d = cl->GetDataMember(name);
4559 // We check if the decl of the data member has an annotation which indicates
4560 // an ioname.
4561 // In case this is true, if the name requested is not the ioname, we
4562 // return 0, as if the member did not exist. In some sense we override
4563 // the information in the TClassInfo instance, isolating the typesystem in
4564 // TClass from the one in the AST.
4565 if (const ValueDecl* decl = (const ValueDecl*) d){
4566 std::string ioName;
4567 bool hasIoName = ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"ioname",ioName);
4568 if (hasIoName && ioName != name) return 0;
4569 }
4570 return d;
4571 }
4572 // We are looking up for something on the TU scope.
4573 // FIXME: We do not want to go through TClingClassInfo(fInterpreter) because of redundant deserializations. That
4574 // interface will actually construct iterators and walk over the decls on the global scope. In would return the first
4575 // occurrence of a decl with the looked up name. However, that's not what C++ lookup would do: if we want to switch
4576 // to a more complete C++ lookup interface we need sift through the found names and pick up the declarations which
4577 // are only fulfilling ROOT's understanding for a Data Member.
4578 // FIXME: We should probably deprecate the TClingClassInfo(fInterpreter) interface and replace it withe something
4579 // similar as below.
4580 using namespace clang;
4581 Sema& SemaR = fInterpreter->getSema();
4582 DeclarationName DName = &SemaR.Context.Idents.get(name);
4583
4584 LookupResult R(SemaR, DName, SourceLocation(), Sema::LookupOrdinaryName,
4585 Sema::ForRedeclaration);
4586
4587 // Could trigger deserialization of decls.
4588 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4589 cling::utils::Lookup::Named(&SemaR, R);
4590
4591 LookupResult::Filter F = R.makeFilter();
4592 // Filter the data-member looking decls.
4593 while (F.hasNext()) {
4594 NamedDecl *D = F.next();
4595 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) ||
4596 isa<IndirectFieldDecl>(D))
4597 continue;
4598 F.erase();
4599 }
4600 F.done();
4601
4602 if (R.isSingleResult())
4603 return R.getFoundDecl();
4604 return 0;
4605}
4606
4607////////////////////////////////////////////////////////////////////////////////
4608/// Return pointer to cling Decl of global/static variable that is located
4609/// at the address given by addr.
4610
4612{
4614
4615 const clang::Decl* possibleEnum = 0;
4616 // FInd the context of the decl.
4617 if (cl) {
4619 if (cci) {
4620 const clang::DeclContext* dc = 0;
4621 if (const clang::Decl* D = cci->GetDecl()) {
4622 if (!(dc = dyn_cast<clang::NamespaceDecl>(D))) {
4623 dc = dyn_cast<clang::RecordDecl>(D);
4624 }
4625 }
4626 if (dc) {
4627 // If it is a data member enum.
4628 // Could trigger deserialization of decls.
4629 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4630 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name, dc);
4631 } else {
4632 Error("TCling::GetEnum", "DeclContext not found for %s .\n", name);
4633 }
4634 }
4635 } else {
4636 // If it is a global enum.
4637 // Could trigger deserialization of decls.
4638 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
4639 possibleEnum = cling::utils::Lookup::Tag(&fInterpreter->getSema(), name);
4640 }
4641 if (possibleEnum && (possibleEnum != (clang::Decl*)-1)
4642 && isa<clang::EnumDecl>(possibleEnum)) {
4643 return possibleEnum;
4644 }
4645 return 0;
4646}
4647
4648////////////////////////////////////////////////////////////////////////////////
4649/// Return pointer to cling DeclId for a global value
4650
4651TInterpreter::DeclId_t TCling::GetDeclId( const llvm::GlobalValue *gv ) const
4652{
4653 if (!gv) return 0;
4654
4655 llvm::StringRef mangled_name = gv->getName();
4656
4657 int err = 0;
4658 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.str().c_str(), err);
4659 if (err) {
4660 if (err == -2) {
4661 // It might simply be an unmangled global name.
4662 DeclId_t d;
4664 d = gcl.GetDataMember(mangled_name.str().c_str());
4665 return d;
4666 }
4667 return 0;
4668 }
4669
4670 std::string scopename(demangled_name_c);
4671 free(demangled_name_c);
4672
4673 //
4674 // Separate out the class or namespace part of the
4675 // function name.
4676 //
4677 std::string dataname;
4678
4679 if (!strncmp(scopename.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
4680 scopename.erase(0, sizeof("typeinfo for ")-1);
4681 } else if (!strncmp(scopename.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
4682 scopename.erase(0, sizeof("vtable for ")-1);
4683 } else {
4684 // See if it is a function
4685 std::string::size_type pos = scopename.rfind('(');
4686 if (pos != std::string::npos) {
4687 return 0;
4688 }
4689 // Separate the scope and member name
4690 pos = scopename.rfind(':');
4691 if (pos != std::string::npos) {
4692 if ((pos != 0) && (scopename[pos-1] == ':')) {
4693 dataname = scopename.substr(pos+1);
4694 scopename.erase(pos-1);
4695 }
4696 } else {
4697 scopename.clear();
4698 dataname = scopename;
4699 }
4700 }
4701 //fprintf(stderr, "name: '%s'\n", name.c_str());
4702 // Now we have the class or namespace name, so do the lookup.
4703
4704
4705 DeclId_t d;
4706 if (scopename.size()) {
4707 TClingClassInfo cl(GetInterpreterImpl(), scopename.c_str());
4708 d = cl.GetDataMember(dataname.c_str());
4709 }
4710 else {
4712 d = gcl.GetDataMember(dataname.c_str());
4713 }
4714 return d;
4715}
4716
4717////////////////////////////////////////////////////////////////////////////////
4718/// NOT IMPLEMENTED.
4719
4721{
4722 Error("GetDataMemberWithValue()", "not implemented");
4723 return 0;
4724}
4725
4726////////////////////////////////////////////////////////////////////////////////
4727/// Return pointer to cling DeclId for a data member with a given name.
4728
4730{
4731 // NOT IMPLEMENTED.
4732 Error("GetDataMemberAtAddr()", "not implemented");
4733 return 0;
4734}
4735
4736////////////////////////////////////////////////////////////////////////////////
4737/// Return the cling mangled name for a method of a class with parameters
4738/// params (params is a string of actual arguments, not formal ones). If the
4739/// class is 0 the global function list will be searched.
4740
4741TString TCling::GetMangledName(TClass* cl, const char* method,
4742 const char* params, Bool_t objectIsConst /* = kFALSE */)
4743{
4746 if (cl) {
4747 Long_t offset;
4748 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4749 &offset);
4750 }
4751 else {
4753 Long_t offset;
4754 func.SetFunc(&gcl, method, params, &offset);
4755 }
4757 if (!mi) return "";
4758 TString mangled_name( mi->GetMangledName() );
4759 delete mi;
4760 return mangled_name;
4761}
4762
4763////////////////////////////////////////////////////////////////////////////////
4764/// Return the cling mangled name for a method of a class with a certain
4765/// prototype, i.e. "char*,int,float". If the class is 0 the global function
4766/// list will be searched.
4767
4769 const char* proto, Bool_t objectIsConst /* = kFALSE */,
4770 EFunctionMatchMode mode /* = kConversionMatch */)
4771{
4773 if (cl) {
4774 return ((TClingClassInfo*)cl->GetClassInfo())->
4775 GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetMangledName();
4776 }
4778 return gcl.GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetMangledName();
4779}
4780
4781////////////////////////////////////////////////////////////////////////////////
4782/// Return pointer to cling interface function for a method of a class with
4783/// parameters params (params is a string of actual arguments, not formal
4784/// ones). If the class is 0 the global function list will be searched.
4785
4786void* TCling::GetInterfaceMethod(TClass* cl, const char* method,
4787 const char* params, Bool_t objectIsConst /* = kFALSE */)
4788{
4791 if (cl) {
4792 Long_t offset;
4793 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst,
4794 &offset);
4795 }
4796 else {
4798 Long_t offset;
4799 func.SetFunc(&gcl, method, params, &offset);
4800 }
4801 return (void*) func.InterfaceMethod();
4802}
4803
4804////////////////////////////////////////////////////////////////////////////////
4805/// Return pointer to cling interface function for a method of a class with
4806/// a certain name.
4807
4808TInterpreter::DeclId_t TCling::GetFunction(ClassInfo_t *opaque_cl, const char* method)
4809{
4811 DeclId_t f;
4812 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4813 if (cl) {
4814 f = cl->GetMethod(method).GetDeclId();
4815 }
4816 else {
4818 f = gcl.GetMethod(method).GetDeclId();
4819 }
4820 return f;
4821
4822}
4823
4824////////////////////////////////////////////////////////////////////////////////
4825/// Insert overloads of name in cl to res.
4826
4827void TCling::GetFunctionOverloads(ClassInfo_t *cl, const char *funcname,
4828 std::vector<DeclId_t>& res) const
4829{
4830 clang::Sema& S = fInterpreter->getSema();
4831 clang::ASTContext& Ctx = S.Context;
4832 const clang::Decl* CtxDecl
4833 = cl ? (const clang::Decl*)((TClingClassInfo*)cl)->GetDeclId():
4834 Ctx.getTranslationUnitDecl();
4835 auto RecDecl = llvm::dyn_cast<const clang::RecordDecl>(CtxDecl);
4836 const clang::DeclContext* DeclCtx = RecDecl;
4837
4838 if (!DeclCtx)
4839 DeclCtx = dyn_cast<clang::NamespaceDecl>(CtxDecl);
4840 if (!DeclCtx) return;
4841
4842 clang::DeclarationName DName;
4843 // The DeclarationName is funcname, unless it's a ctor or dtor.
4844 // FIXME: or operator or conversion! See enum clang::DeclarationName::NameKind.
4845
4846 if (RecDecl) {
4847 if (RecDecl->getNameAsString() == funcname) {
4848 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
4849 DName = Ctx.DeclarationNames.getCXXConstructorName(Ctx.getCanonicalType(QT));
4850 } else if (funcname[0] == '~' && RecDecl->getNameAsString() == funcname + 1) {
4851 clang::QualType QT = Ctx.getTypeDeclType(RecDecl);
4852 DName = Ctx.DeclarationNames.getCXXDestructorName(Ctx.getCanonicalType(QT));
4853 } else {
4854 DName = &Ctx.Idents.get(funcname);
4855 }
4856 } else {
4857 DName = &Ctx.Idents.get(funcname);
4858 }
4859
4860 // NotForRedeclaration: we want to find names in inline namespaces etc.
4861 clang::LookupResult R(S, DName, clang::SourceLocation(),
4862 Sema::LookupOrdinaryName, clang::Sema::NotForRedeclaration);
4863 R.suppressDiagnostics(); // else lookup with NotForRedeclaration will check access etc
4864 S.LookupQualifiedName(R, const_cast<DeclContext*>(DeclCtx));
4865 if (R.empty()) return;
4866 R.resolveKind();
4867 res.reserve(res.size() + (R.end() - R.begin()));
4868 for (clang::LookupResult::iterator IR = R.begin(), ER = R.end();
4869 IR != ER; ++IR) {
4870 if (const clang::FunctionDecl* FD
4871 = llvm::dyn_cast<const clang::FunctionDecl>(*IR)) {
4872 if (!FD->getDescribedFunctionTemplate()) {
4873 res.push_back(FD);
4874 }
4875 } else if (const auto *USD = llvm::dyn_cast<const clang::UsingShadowDecl>(*IR)) {
4876 // FIXME: multi-level using
4877 if (llvm::isa<clang::FunctionDecl>(USD->getTargetDecl())) {
4878 res.push_back(USD);
4879 }
4880 }
4881 }
4882}
4883
4884////////////////////////////////////////////////////////////////////////////////
4885/// Return pointer to cling interface function for a method of a class with
4886/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
4887/// function list will be searched.
4888
4890 const char* proto,
4891 Bool_t objectIsConst /* = kFALSE */,
4892 EFunctionMatchMode mode /* = kConversionMatch */)
4893{
4895 void* f;
4896 if (cl) {
4897 f = ((TClingClassInfo*)cl->GetClassInfo())->
4898 GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).InterfaceMethod(*fNormalizedCtxt);
4899 }
4900 else {
4902 f = gcl.GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).InterfaceMethod(*fNormalizedCtxt);
4903 }
4904 return f;
4905}
4906
4907////////////////////////////////////////////////////////////////////////////////
4908/// Return pointer to cling DeclId for a method of a class with
4909/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
4910/// function list will be searched.
4911
4912TInterpreter::DeclId_t TCling::GetFunctionWithValues(ClassInfo_t *opaque_cl, const char* method,
4913 const char* params,
4914 Bool_t objectIsConst /* = kFALSE */)
4915{
4917 DeclId_t f;
4918 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4919 if (cl) {
4920 f = cl->GetMethodWithArgs(method, params, objectIsConst, 0 /*poffset*/).GetDeclId();
4921 }
4922 else {
4924 f = gcl.GetMethod(method, params, objectIsConst, 0 /*poffset*/).GetDeclId();
4925 }
4926 return f;
4927}
4928
4929////////////////////////////////////////////////////////////////////////////////
4930/// Return pointer to cling interface function for a method of a class with
4931/// a certain prototype, i.e. "char*,int,float". If the class is 0 the global
4932/// function list will be searched.
4933
4934TInterpreter::DeclId_t TCling::GetFunctionWithPrototype(ClassInfo_t *opaque_cl, const char* method,
4935 const char* proto,
4936 Bool_t objectIsConst /* = kFALSE */,
4937 EFunctionMatchMode mode /* = kConversionMatch */)
4938{
4940 DeclId_t f;
4941 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4942 if (cl) {
4943 f = cl->GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetDeclId();
4944 }
4945 else {
4947 f = gcl.GetMethod(method, proto, objectIsConst, 0 /*poffset*/, mode).GetDeclId();
4948 }
4949 return f;
4950}
4951
4952////////////////////////////////////////////////////////////////////////////////
4953/// Return pointer to cling interface function for a method of a class with
4954/// a certain name.
4955
4956TInterpreter::DeclId_t TCling::GetFunctionTemplate(ClassInfo_t *opaque_cl, const char* name)
4957{
4959 DeclId_t f;
4960 TClingClassInfo *cl = (TClingClassInfo*)opaque_cl;
4961 if (cl) {
4962 f = cl->GetFunctionTemplate(name);
4963 }
4964 else {
4966 f = gcl.GetFunctionTemplate(name);
4967 }
4968 return f;
4969
4970}
4971
4972////////////////////////////////////////////////////////////////////////////////
4973/// The 'name' is known to the interpreter, this function returns
4974/// the internal version of this name (usually just resolving typedefs)
4975/// This is used in particular to synchronize between the name used
4976/// by rootcling and by the run-time environment (TClass)
4977/// Return 0 if the name is not known.
4978
4979void TCling::GetInterpreterTypeName(const char* name, std::string &output, Bool_t full)
4980{
4981 output.clear();
4982
4984
4986 if (!cl.IsValid()) {
4987 return ;
4988 }
4989 if (full) {
4991 return;
4992 }
4993 // Well well well, for backward compatibility we need to act a bit too
4994 // much like CINT.
4997
4998 return;
4999}
5000
5001////////////////////////////////////////////////////////////////////////////////
5002/// Execute a global function with arguments params.
5003///
5004/// FIXME: The cint-based version of this code does not check if the
5005/// SetFunc() call works, and does not do any real checking
5006/// for errors from the Exec() call. It did fetch the most
5007/// recent cint security error and return that in error, but
5008/// this does not really translate well to cling/clang. We
5009/// should enhance these interfaces so that we can report
5010/// compilation and runtime errors properly.
5011
5012void TCling::Execute(const char* function, const char* params, int* error)
5013{
5015 if (error) {
5016 *error = TInterpreter::kNoError;
5017 }
5019 Long_t offset = 0L;
5021 func.SetFunc(&cl, function, params, &offset);
5022 func.Exec(0);
5023}
5024
5025////////////////////////////////////////////////////////////////////////////////
5026/// Execute a method from class cl with arguments params.
5027///
5028/// FIXME: The cint-based version of this code does not check if the
5029/// SetFunc() call works, and does not do any real checking
5030/// for errors from the Exec() call. It did fetch the most
5031/// recent cint security error and return that in error, but
5032/// this does not really translate well to cling/clang. We
5033/// should enhance these interfaces so that we can report
5034/// compilation and runtime errors properly.
5035
5036void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5037 const char* params, Bool_t objectIsConst, int* error)
5038{
5040 if (error) {
5041 *error = TInterpreter::kNoError;
5042 }
5043 // If the actual class of this object inherits 2nd (or more) from TObject,
5044 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5045 // hence gInterpreter->Execute will improperly correct the offset.
5046 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5047 Long_t offset = 0L;
5049 func.SetFunc((TClingClassInfo*)cl->GetClassInfo(), method, params, objectIsConst, &offset);
5050 void* address = (void*)((Long_t)addr + offset);
5051 func.Exec(address);
5052}
5053
5054////////////////////////////////////////////////////////////////////////////////
5055
5056void TCling::Execute(TObject* obj, TClass* cl, const char* method,
5057 const char* params, int* error)
5058{
5059 Execute(obj,cl,method,params,false,error);
5060}
5061
5062////////////////////////////////////////////////////////////////////////////////
5063/// Execute a method from class cl with the arguments in array params
5064/// (params[0] ... params[n] = array of TObjString parameters).
5065/// Convert the TObjArray array of TObjString parameters to a character
5066/// string of comma separated parameters.
5067/// The parameters of type 'char' are enclosed in double quotes and all
5068/// internal quotes are escaped.
5069
5070void TCling::Execute(TObject* obj, TClass* cl, TMethod* method,
5071 TObjArray* params, int* error)
5072{
5073 if (!method) {
5074 Error("Execute", "No method was defined");
5075 return;
5076 }
5077 TList* argList = method->GetListOfMethodArgs();
5078 // Check number of actual parameters against of expected formal ones
5079
5080 Int_t nparms = argList->LastIndex() + 1;
5081 Int_t argc = params ? params->GetEntries() : 0;
5082
5083 if (argc > nparms) {
5084 Error("Execute","Too many parameters to call %s, got %d but expected at most %d.",method->GetName(),argc,nparms);
5085 return;
5086 }
5087 if (nparms != argc) {
5088 // Let's see if the 'missing' argument are all defaulted.
5089 // if nparms==0 then either we stopped earlier either argc is also zero and we can't reach here.
5090 assert(nparms > 0);
5091
5092 TMethodArg *arg = (TMethodArg *) argList->At( 0 );
5093 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5094 // There is a default value for the first missing
5095 // argument, so we are fine.
5096 } else {
5097 Int_t firstDefault = -1;
5098 for (Int_t i = 0; i < nparms; i ++) {
5099 arg = (TMethodArg *) argList->At( i );
5100 if (arg && arg->GetDefault() && arg->GetDefault()[0]) {
5101 firstDefault = i;
5102 break;
5103 }
5104 }
5105 if (firstDefault >= 0) {
5106 Error("Execute","Too few arguments to call %s, got only %d but expected at least %d and at most %d.",method->GetName(),argc,firstDefault,nparms);
5107 } else {
5108 Error("Execute","Too few arguments to call %s, got only %d but expected %d.",method->GetName(),argc,nparms);
5109 }
5110 return;
5111 }
5112 }
5113
5114 const char* listpar = "";
5115 TString complete(10);
5116 if (params) {
5117 // Create a character string of parameters from TObjArray
5118 TIter next(params);
5119 for (Int_t i = 0; i < argc; i ++) {
5120 TMethodArg* arg = (TMethodArg*) argList->At(i);
5122 TObjString* nxtpar = (TObjString*) next();
5123 if (i) {
5124 complete += ',';
5125 }
5126 if (strstr(type.TrueName(*fNormalizedCtxt), "char")) {
5127 TString chpar('\"');
5128 chpar += (nxtpar->String()).ReplaceAll("\"", "\\\"");
5129 // At this point we have to check if string contains \\"
5130 // and apply some more sophisticated parser. Not implemented yet!
5131 complete += chpar;
5132 complete += '\"';
5133 }
5134 else {
5135 complete += nxtpar->String();
5136 }
5137 }
5138 listpar = complete.Data();
5139 }
5140
5141 // And now execute it.
5143 if (error) {
5144 *error = TInterpreter::kNoError;
5145 }
5146 // If the actual class of this object inherits 2nd (or more) from TObject,
5147 // 'obj' is unlikely to be the start of the object (as described by IsA()),
5148 // hence gInterpreter->Execute will improperly correct the offset.
5149 void* addr = cl->DynamicCast(TObject::Class(), obj, kFALSE);
5151 TClingMethodInfo *minfo = (TClingMethodInfo*)method->fInfo;
5152 func.Init(*minfo);
5153 func.SetArgs(listpar);
5154 // Now calculate the 'this' pointer offset for the method
5155 // when starting from the class described by cl.
5156 const CXXMethodDecl * mdecl = dyn_cast<CXXMethodDecl>(minfo->GetTargetFunctionDecl());
5157 Long_t offset = ((TClingClassInfo*)cl->GetClassInfo())->GetOffset(mdecl);
5158 void* address = (void*)((Long_t)addr + offset);
5159 func.Exec(address);
5160}
5161
5162////////////////////////////////////////////////////////////////////////////////
5163
5164void TCling::ExecuteWithArgsAndReturn(TMethod* method, void* address,
5165 const void* args[] /*=0*/,
5166 int nargs /*=0*/,
5167 void* ret/*= 0*/) const
5168{
5169 if (!method) {
5170 Error("ExecuteWithArgsAndReturn", "No method was defined");
5171 return;
5172 }
5173
5174 TClingMethodInfo* minfo = (TClingMethodInfo*) method->fInfo;
5175 TClingCallFunc func(*minfo,*fNormalizedCtxt);
5176 func.ExecWithArgsAndReturn(address, args, nargs, ret);
5177}
5178
5179////////////////////////////////////////////////////////////////////////////////
5180/// Execute a cling macro.
5181
5182Long_t TCling::ExecuteMacro(const char* filename, EErrorCode* error)
5183{
5185 fCurExecutingMacros.push_back(filename);
5186 Long_t result = TApplication::ExecuteFile(filename, (int*)error);
5187 fCurExecutingMacros.pop_back();
5188 return result;
5189}
5190
5191////////////////////////////////////////////////////////////////////////////////
5192/// Return the file name of the current un-included interpreted file.
5193/// See the documentation for GetCurrentMacroName().
5194
5196{
5197 Warning("GetTopLevelMacroName", "Must change return type!");
5198 return fCurExecutingMacros.back();
5199}
5200
5201////////////////////////////////////////////////////////////////////////////////
5202/// Return the file name of the currently interpreted file,
5203/// included or not. Example to illustrate the difference between
5204/// GetCurrentMacroName() and GetTopLevelMacroName():
5205/// ~~~ {.cpp}
5206/// void inclfile() {
5207/// std::cout << "In inclfile.C" << std::endl;
5208/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5209/// TCling::GetCurrentMacroName() << std::endl;
5210/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5211/// TCling::GetTopLevelMacroName() << std::endl;
5212/// }
5213/// ~~~
5214/// ~~~ {.cpp}
5215/// void mymacro() {
5216/// std::cout << "In mymacro.C" << std::endl;
5217/// std::cout << " TCling::GetCurrentMacroName() returns " <<
5218/// TCling::GetCurrentMacroName() << std::endl;
5219/// std::cout << " TCling::GetTopLevelMacroName() returns " <<
5220/// TCling::GetTopLevelMacroName() << std::endl;
5221/// std::cout << " Now calling inclfile..." << std::endl;
5222/// gInterpreter->ProcessLine(".x inclfile.C");;
5223/// }
5224/// ~~~
5225/// Running mymacro.C will print:
5226///
5227/// ~~~ {.cpp}
5228/// root [0] .x mymacro.C
5229/// ~~~
5230/// In mymacro.C
5231/// ~~~ {.cpp}
5232/// TCling::GetCurrentMacroName() returns ./mymacro.C
5233/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5234/// ~~~
5235/// Now calling inclfile...
5236/// In inclfile.h
5237/// ~~~ {.cpp}
5238/// TCling::GetCurrentMacroName() returns inclfile.C
5239/// TCling::GetTopLevelMacroName() returns ./mymacro.C
5240/// ~~~
5241
5243{
5244#if defined(R__MUST_REVISIT)
5245#if R__MUST_REVISIT(6,0)
5246 Warning("GetCurrentMacroName", "Must change return type!");
5247#endif
5248#endif
5249 return fCurExecutingMacros.back();
5250}
5251
5252////////////////////////////////////////////////////////////////////////////////
5253/// Return the absolute type of typeDesc.
5254/// E.g.: typeDesc = "class TNamed**", returns "TNamed".
5255/// You need to use the result immediately before it is being overwritten.
5256
5257const char* TCling::TypeName(const char* typeDesc)
5258{
5259 TTHREAD_TLS(char*) t = 0;
5260 TTHREAD_TLS(unsigned int) tlen = 0;
5261
5262 unsigned int dlen = strlen(typeDesc);
5263 if (dlen > tlen) {
5264 delete[] t;
5265 t = new char[dlen + 1];
5266 tlen = dlen;
5267 }
5268 const char* s, *template_start;
5269 if (!strstr(typeDesc, "(*)(")) {
5270 s = strchr(typeDesc, ' ');
5271 template_start = strchr(typeDesc, '<');
5272 if (!strcmp(typeDesc, "long long")) {
5273 strlcpy(t, typeDesc, dlen + 1);
5274 }
5275 else if (!strncmp(typeDesc, "unsigned ", s + 1 - typeDesc)) {
5276 strlcpy(t, typeDesc, dlen + 1);
5277 }
5278 // s is the position of the second 'word' (if any)
5279 // except in the case of templates where there will be a space
5280 // just before any closing '>': eg.
5281 // TObj<std::vector<UShort_t,__malloc_alloc_template<0> > >*
5282 else if (s && (template_start == 0 || (s < template_start))) {
5283 strlcpy(t, s + 1, dlen + 1);
5284 }
5285 else {
5286 strlcpy(t, typeDesc, dlen + 1);
5287 }
5288 }
5289 else {
5290 strlcpy(t, typeDesc, dlen + 1);
5291 }
5292 int l = strlen(t);
5293 while (l > 0 && (t[l - 1] == '*' || t[l - 1] == '&')) {
5294 t[--l] = 0;
5295 }
5296 return t;
5297}
5298
5299static bool requiresRootMap(const char* rootmapfile, cling::Interpreter* interp)
5300{
5301 assert(rootmapfile && *rootmapfile);
5302
5303 llvm::StringRef libName = llvm::sys::path::filename(rootmapfile);
5304 libName.consume_back(".rootmap");
5305
5306 return !gInterpreter->HasPCMForLibrary(libName.str().c_str());
5307}
5308
5309////////////////////////////////////////////////////////////////////////////////
5310/// Read and parse a rootmapfile in its new format, and return 0 in case of
5311/// success, -1 if the file has already been read, and -3 in case its format
5312/// is the old one (e.g. containing "Library.ClassName"), -4 in case of syntax
5313/// error.
5314
5315int TCling::ReadRootmapFile(const char *rootmapfile, TUniqueString *uniqueString)
5316{
5317 if (!(rootmapfile && *rootmapfile))
5318 return 0;
5319
5320 if (!requiresRootMap(rootmapfile, GetInterpreterImpl()))
5321 return 0; // success
5322
5323 // For "class ", "namespace ", "typedef ", "header ", "enum ", "var " respectively
5324 const std::map<char, unsigned int> keyLenMap = {{'c',6},{'n',10},{'t',8},{'h',7},{'e',5},{'v',4}};
5325
5326 std::string rootmapfileNoBackslash(rootmapfile);
5327#ifdef _MSC_VER
5328 std::replace(rootmapfileNoBackslash.begin(), rootmapfileNoBackslash.end(), '\\', '/');
5329#endif
5330 // Add content of a specific rootmap file
5331 if (fRootmapFiles->FindObject(rootmapfileNoBackslash.c_str()))
5332 return -1;
5333
5334 if (uniqueString)
5335 uniqueString->Append(std::string("\n#line 1 \"Forward declarations from ") + rootmapfileNoBackslash + "\"\n");
5336
5337 std::ifstream file(rootmapfileNoBackslash);
5338 std::string line;
5339 line.reserve(200);
5340 std::string lib_name;
5341 line.reserve(100);
5342 bool newFormat = false;
5343 while (getline(file, line, '\n')) {
5344 if (!newFormat && (line.compare(0, 8, "Library.") == 0 || line.compare(0, 8, "Declare.") == 0)) {
5345 file.close();
5346 return -3; // old format
5347 }
5348 newFormat = true;
5349
5350 if (line.compare(0, 9, "{ decls }") == 0) {
5351 // forward declarations
5352
5353 while (getline(file, line, '\n')) {
5354 if (line[0] == '[')
5355 break;
5356 if (!uniqueString) {
5357 Error("ReadRootmapFile", "Cannot handle \"{ decls }\" sections in custom rootmap file %s",
5358 rootmapfileNoBackslash.c_str());
5359 return -4;
5360 }
5361 uniqueString->Append(line);
5362 }
5363 }
5364 const char firstChar = line[0];
5365 if (firstChar == '[') {
5366 // new section (library)
5367 auto brpos = line.find(']');
5368 if (brpos == string::npos)
5369 continue;
5370 lib_name = line.substr(1, brpos - 1);
5371 size_t nspaces = 0;
5372 while (lib_name[nspaces] == ' ')
5373 ++nspaces;
5374 if (nspaces)
5375 lib_name.replace(0, nspaces, "");
5376 if (gDebug > 3) {
5377 TString lib_nameTstr(lib_name.c_str());
5378 TObjArray *tokens = lib_nameTstr.Tokenize(" ");
5379 const char *lib = ((TObjString *)tokens->At(0))->GetName();
5380 const char *wlib = gSystem->DynamicPathName(lib, kTRUE);
5381 if (wlib) {
5382 Info("ReadRootmapFile", "new section for %s", lib_nameTstr.Data());
5383 } else {
5384 Info("ReadRootmapFile", "section for %s (library does not exist)", lib_nameTstr.Data());
5385 }
5386 delete[] wlib;
5387 delete tokens;
5388 }
5389 } else {
5390 auto keyLenIt = keyLenMap.find(firstChar);
5391 if (keyLenIt == keyLenMap.end())
5392 continue;
5393 unsigned int keyLen = keyLenIt->second;
5394 // Do not make a copy, just start after the key
5395 const char *keyname = line.c_str() + keyLen;
5396 if (gDebug > 6)
5397 Info("ReadRootmapFile", "class %s in %s", keyname, lib_name.c_str());
5398 TEnvRec *isThere = fMapfile->Lookup(keyname);
5399 if (isThere) {
5400 if (lib_name != isThere->GetValue()) { // the same key for two different libs
5401 if (firstChar == 'n') {
5402 if (gDebug > 3)
5403 Info("ReadRootmapFile", "namespace %s found in %s is already in %s", keyname, lib_name.c_str(),
5404 isThere->GetValue());
5405 } else if (firstChar == 'h') { // it is a header: add the libname to the list of libs to be loaded.
5406 lib_name += " ";
5407 lib_name += isThere->GetValue();
5408 fMapfile->SetValue(keyname, lib_name.c_str());
5409 } else if (!TClassEdit::IsSTLCont(keyname)) {
5410 Warning("ReadRootmapFile", "%s %s found in %s is already in %s", line.substr(0, keyLen).c_str(),
5411 keyname, lib_name.c_str(), isThere->GetValue());
5412 }
5413 } else { // the same key for the same lib
5414 if (gDebug > 3)
5415 Info("ReadRootmapFile", "Key %s was already defined for %s", keyname, lib_name.c_str());
5416 }
5417 } else {
5418 fMapfile->SetValue(keyname, lib_name.c_str());
5419 }
5420 }
5421 }
5422 file.close();
5423 return 0;
5424}
5425
5426////////////////////////////////////////////////////////////////////////////////
5427/// Create a resource table and read the (possibly) three resource files, i.e
5428/// $ROOTSYS/etc/system<name> (or ROOTETCDIR/system<name>), $HOME/<name> and
5429/// ./<name>. ROOT always reads ".rootrc" (in TROOT::InitSystem()). You can
5430/// read additional user defined resource files by creating additional TEnv
5431/// objects. By setting the shell variable ROOTENV_NO_HOME=1 the reading of
5432/// the $HOME/<name> resource file will be skipped. This might be useful in
5433/// case the home directory resides on an automounted remote file system
5434/// and one wants to avoid the file system from being mounted.
5435
5437{
5438 assert(requiresRootMap(name, GetInterpreterImpl()) && "We have a module!");
5439
5441 return;
5442
5444
5446
5447 TString sname = "system";
5448 sname += name;
5449 char *s = gSystem->ConcatFileName(TROOT::GetEtcDir(), sname);
5450
5451 Int_t ret = ReadRootmapFile(s);
5452 if (ret == -3) // old format
5454 delete [] s;
5455 if (!gSystem->Getenv("ROOTENV_NO_HOME")) {
5457 ret = ReadRootmapFile(s);
5458 if (ret == -3) // old format
5460 delete [] s;
5461 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
5462 ret = ReadRootmapFile(name);
5463 if (ret == -3) // old format
5465 }
5466 } else {
5467 ret = ReadRootmapFile(name);
5468 if (ret == -3) // old format
5470 }
5471 fMapfile->IgnoreDuplicates(ignore);
5472}
5473
5474
5475namespace {
5476 using namespace clang;
5477
5478 class ExtVisibleStorageAdder: public RecursiveASTVisitor<ExtVisibleStorageAdder>{
5479 // This class is to be considered an helper for AutoLoading.
5480 // It is a recursive visitor is used to inspect namespaces coming from
5481 // forward declarations in rootmaps and to set the external visible
5482 // storage flag for them.
5483 public:
5484 ExtVisibleStorageAdder(std::unordered_set<const NamespaceDecl*>& nsSet): fNSSet(nsSet) {};
5485 bool VisitNamespaceDecl(NamespaceDecl* nsDecl) {
5486 // We want to enable the external lookup for this namespace
5487 // because it may shadow the lookup of other names contained
5488 // in that namespace
5489
5490 nsDecl->setHasExternalVisibleStorage();
5491 fNSSet.insert(nsDecl);
5492 return true;
5493 }
5494 private:
5495 std::unordered_set<const NamespaceDecl*>& fNSSet;
5496
5497 };
5498}
5499
5500////////////////////////////////////////////////////////////////////////////////
5501/// Load map between class and library. If rootmapfile is specified a
5502/// specific rootmap file can be added (typically used by ACLiC).
5503/// In case of error -1 is returned, 0 otherwise.
5504/// The interpreter uses this information to automatically load the shared
5505/// library for a class (autoload mechanism), see the AutoLoad() methods below.
5506
5507Int_t TCling::LoadLibraryMap(const char* rootmapfile)
5508{
5509 if (rootmapfile && *rootmapfile && !requiresRootMap(rootmapfile, GetInterpreterImpl()))
5510 return 0;
5511
5513
5514 // open the [system].rootmap files
5515 if (!fMapfile) {
5516 fMapfile = new TEnv();
5520 InitRootmapFile(".rootmap");
5521 }
5522
5523 // Prepare a list of all forward declarations for cling
5524 // For some experiments it is easily as big as 500k characters. To be on the
5525 // safe side, we go for 1M.
5526 TUniqueString uniqueString(1048576);
5527
5528 // Load all rootmap files in the dynamic load path ((DY)LD_LIBRARY_PATH, etc.).
5529 // A rootmap file must end with the string ".rootmap".
5530 TString ldpath = gSystem->GetDynamicPath();
5531 if (ldpath != fRootmapLoadPath) {
5532 fRootmapLoadPath = ldpath;
5533#ifdef WIN32
5534 TObjArray* paths = ldpath.Tokenize(";");
5535#else
5536 TObjArray* paths = ldpath.Tokenize(":");
5537#endif
5538 TString d;
5539 for (Int_t i = 0; i < paths->GetEntriesFast(); i++) {
5540 d = ((TObjString *)paths->At(i))->GetString();
5541 // check if directory already scanned
5542 Int_t skip = 0;
5543 for (Int_t j = 0; j < i; j++) {
5544 TString pd = ((TObjString *)paths->At(j))->GetString();
5545 if (pd == d) {
5546 skip++;
5547 break;
5548 }
5549 }
5550 if (!skip) {
5551 void* dirp = gSystem->OpenDirectory(d);
5552 if (dirp) {
5553 if (gDebug > 3) {
5554 Info("LoadLibraryMap", "%s", d.Data());
5555 }
5556 const char* f1;
5557 while ((f1 = gSystem->GetDirEntry(dirp))) {
5558 TString f = f1;
5559 if (f.EndsWith(".rootmap")) {
5560 TString p;
5561 p = d + "/" + f;
5563 if (!fRootmapFiles->FindObject(f) && f != ".rootmap") {
5564 if (gDebug > 4) {
5565 Info("LoadLibraryMap", " rootmap file: %s", p.Data());
5566 }
5567 Int_t ret = ReadRootmapFile(p, &uniqueString);
5568
5569 if (ret == 0)
5571 if (ret == -3) {
5572 // old format
5574 fRootmapFiles->Add(new TNamed(f, p));
5575 }
5576 }
5577 // else {
5578 // fprintf(stderr,"Reject %s because %s is already there\n",p.Data(),f.Data());
5579 // fRootmapFiles->FindObject(f)->ls();
5580 // }
5581 }
5582 }
5583 if (f.BeginsWith("rootmap")) {
5584 TString p;
5585 p = d + "/" + f;
5586 FileStat_t stat;
5587 if (gSystem->GetPathInfo(p, stat) == 0 && R_ISREG(stat.fMode)) {
5588 Warning("LoadLibraryMap", "please rename %s to end with \".rootmap\"", p.Data());
5589 }
5590 }
5591 }
5592 }
5593 gSystem->FreeDirectory(dirp);
5594 }
5595 }
5596 delete paths;
5597 if (fMapfile->GetTable() && !fMapfile->GetTable()->GetEntries()) {
5598 return -1;
5599 }
5600 }
5601 if (rootmapfile && *rootmapfile) {
5602 Int_t res = ReadRootmapFile(rootmapfile, &uniqueString);
5603 if (res == 0) {
5604 //TString p = gSystem->ConcatFileName(gSystem->pwd(), rootmapfile);
5605 //fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), p.Data()));
5606 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5607 }
5608 else if (res == -3) {
5609 // old format
5611 fMapfile->ReadFile(rootmapfile, kEnvGlobal);
5612 fRootmapFiles->Add(new TNamed(gSystem->BaseName(rootmapfile), rootmapfile));
5613 fMapfile->IgnoreDuplicates(ignore);
5614 }
5615 }
5616 TEnvRec* rec;
5617 TIter next(fMapfile->GetTable());
5618 while ((rec = (TEnvRec*) next())) {
5619 TString cls = rec->GetName();
5620 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5621 // get the first lib from the list of lib and dependent libs
5622 TString libs = rec->GetValue();
5623 if (libs == "") {
5624 continue;
5625 }
5626 TString delim(" ");
5627 TObjArray* tokens = libs.Tokenize(delim);
5628 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5629 // convert "@@" to "::", we used "@@" because TEnv
5630 // considers "::" a terminator
5631 cls.Remove(0, 8);
5632 cls.ReplaceAll("@@", "::");
5633 // convert "-" to " ", since class names may have
5634 // blanks and TEnv considers a blank a terminator
5635 cls.ReplaceAll("-", " ");
5636 if (gDebug > 6) {
5637 const char* wlib = gSystem->DynamicPathName(lib, kTRUE);
5638 if (wlib) {
5639 Info("LoadLibraryMap", "class %s in %s", cls.Data(), wlib);
5640 }
5641 else {
5642 Info("LoadLibraryMap", "class %s in %s (library does not exist)", cls.Data(), lib);
5643 }
5644 delete[] wlib;
5645 }
5646 delete tokens;
5647 }
5648 else if (!strncmp(cls.Data(), "Declare.", 8) && cls.Length() > 8) {
5649 cls.Remove(0, 8);
5650 // convert "-" to " ", since class names may have
5651 // blanks and TEnv considers a blank a terminator
5652 cls.ReplaceAll("-", " ");
5653 fInterpreter->declare(cls.Data());
5654 }
5655 }
5656
5657 // Process the forward declarations collected
5658 cling::Transaction* T = nullptr;
5659 auto compRes= fInterpreter->declare(uniqueString.Data(), &T);
5660 assert(cling::Interpreter::kSuccess == compRes && "A declaration in a rootmap could not be compiled");
5661
5662 if (compRes!=cling::Interpreter::kSuccess){
5663 Warning("LoadLibraryMap",
5664 "Problems in %s declaring '%s' were encountered.", rootmapfile, uniqueString.Data()) ;
5665 }
5666
5667 if (T){
5668 ExtVisibleStorageAdder evsAdder(fNSFromRootmaps);
5669 for (auto declIt = T->decls_begin(); declIt < T->decls_end(); ++declIt) {
5670 if (declIt->m_DGR.isSingleDecl()) {
5671 if (Decl* D = declIt->m_DGR.getSingleDecl()) {
5672 if (NamespaceDecl* NSD = dyn_cast<NamespaceDecl>(D)) {
5673 evsAdder.TraverseDecl(NSD);
5674 }
5675 }
5676 }
5677 }
5678 }
5679
5680 // clear duplicates
5681
5682 return 0;
5683}
5684
5685////////////////////////////////////////////////////////////////////////////////
5686/// Scan again along the dynamic path for library maps. Entries for the loaded
5687/// shared libraries are unloaded first. This can be useful after reseting
5688/// the dynamic path through TSystem::SetDynamicPath()
5689/// In case of error -1 is returned, 0 otherwise.
5690
5692{
5695 return 0;
5696}
5697
5698////////////////////////////////////////////////////////////////////////////////
5699/// Reload the library map entries coming from all the loaded shared libraries,
5700/// after first unloading the current ones.
5701/// In case of error -1 is returned, 0 otherwise.
5702
5704{
5705 const TString sharedLibLStr = GetSharedLibs();
5706 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5707 const Int_t nrSharedLibs = sharedLibL->GetEntriesFast();
5708 for (Int_t ilib = 0; ilib < nrSharedLibs; ilib++) {
5709 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5710 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5711 const Int_t ret = UnloadLibraryMap(sharedLibBaseStr);
5712 if (ret < 0) {
5713 continue;
5714 }
5715 TString rootMapBaseStr = sharedLibBaseStr;
5716 if (sharedLibBaseStr.EndsWith(".dll")) {
5717 rootMapBaseStr.ReplaceAll(".dll", "");
5718 }
5719 else if (sharedLibBaseStr.EndsWith(".DLL")) {
5720 rootMapBaseStr.ReplaceAll(".DLL", "");
5721 }
5722 else if (sharedLibBaseStr.EndsWith(".so")) {
5723 rootMapBaseStr.ReplaceAll(".so", "");
5724 }
5725 else if (sharedLibBaseStr.EndsWith(".sl")) {
5726 rootMapBaseStr.ReplaceAll(".sl", "");
5727 }
5728 else if (sharedLibBaseStr.EndsWith(".dl")) {
5729 rootMapBaseStr.ReplaceAll(".dl", "");
5730 }
5731 else if (sharedLibBaseStr.EndsWith(".a")) {
5732 rootMapBaseStr.ReplaceAll(".a", "");
5733 }
5734 else {
5735 Error("ReloadAllSharedLibraryMaps", "Unknown library type %s", sharedLibBaseStr.Data());
5736 delete sharedLibL;
5737 return -1;
5738 }
5739 rootMapBaseStr += ".rootmap";
5740 const char* rootMap = gSystem->Which(gSystem->GetDynamicPath(), rootMapBaseStr);
5741 if (!rootMap) {
5742 Error("ReloadAllSharedLibraryMaps", "Could not find rootmap %s in path", rootMapBaseStr.Data());
5743 delete[] rootMap;
5744 delete sharedLibL;
5745 return -1;
5746 }
5747 const Int_t status = LoadLibraryMap(rootMap);
5748 if (status < 0) {
5749 Error("ReloadAllSharedLibraryMaps", "Error loading map %s", rootMap);
5750 delete[] rootMap;
5751 delete sharedLibL;
5752 return -1;
5753 }
5754 delete[] rootMap;
5755 }
5756 delete sharedLibL;
5757 return 0;
5758}
5759
5760////////////////////////////////////////////////////////////////////////////////
5761/// Unload the library map entries coming from all the loaded shared libraries.
5762/// Returns 0 if succesful
5763
5765{
5766 const TString sharedLibLStr = GetSharedLibs();
5767 const TObjArray* sharedLibL = sharedLibLStr.Tokenize(" ");
5768 for (Int_t ilib = 0; ilib < sharedLibL->GetEntriesFast(); ilib++) {
5769 const TString sharedLibStr = ((TObjString*)sharedLibL->At(ilib))->GetString();
5770 const TString sharedLibBaseStr = gSystem->BaseName(sharedLibStr);
5771 UnloadLibraryMap(sharedLibBaseStr);
5772 }
5773 delete sharedLibL;
5774 return 0;
5775}
5776
5777////////////////////////////////////////////////////////////////////////////////
5778/// Unload library map entries coming from the specified library.
5779/// Returns -1 in case no entries for the specified library were found,
5780/// 0 otherwise.
5781
5783{
5784 if (!fMapfile || !library || !*library) {
5785 return 0;
5786 }
5787 TString libname(library);
5788 Ssiz_t idx = libname.Last('.');
5789 if (idx != kNPOS) {
5790 libname.Remove(idx);
5791 }
5792 size_t len = libname.Length();
5793 TEnvRec *rec;
5794 TIter next(fMapfile->GetTable());
5796 Int_t ret = 0;
5797 while ((rec = (TEnvRec *) next())) {
5798 TString cls = rec->GetName();
5799 if (cls.Length() > 2) {
5800 // get the first lib from the list of lib and dependent libs
5801 TString libs = rec->GetValue();
5802 if (libs == "") {
5803 continue;
5804 }
5805 TString delim(" ");
5806 TObjArray* tokens = libs.Tokenize(delim);
5807 const char* lib = ((TObjString *)tokens->At(0))->GetName();
5808 if (!strncmp(cls.Data(), "Library.", 8) && cls.Length() > 8) {
5809 // convert "@@" to "::", we used "@@" because TEnv
5810 // considers "::" a terminator
5811 cls.Remove(0, 8);
5812 cls.ReplaceAll("@@", "::");
5813 // convert "-" to " ", since class names may have
5814 // blanks and TEnv considers a blank a terminator
5815 cls.ReplaceAll("-", " ");
5816 }
5817 if (!strncmp(lib, libname.Data(), len)) {
5818 if (fMapfile->GetTable()->Remove(rec) == 0) {
5819 Error("UnloadLibraryMap", "entry for <%s, %s> not found in library map table", cls.Data(), lib);
5820 ret = -1;
5821 }
5822 }
5823 delete tokens;
5824 }
5825 }
5826 if (ret >= 0) {
5827 TString library_rootmap(library);
5828 if (!library_rootmap.EndsWith(".rootmap"))
5829 library_rootmap.Append(".rootmap");
5830 TNamed* mfile = 0;
5831 while ((mfile = (TNamed *)fRootmapFiles->FindObject(library_rootmap))) {
5832 fRootmapFiles->Remove(mfile);
5833 delete mfile;
5834 }
5836 }
5837 return ret;
5838}
5839
5840////////////////////////////////////////////////////////////////////////////////
5841/// Register the AutoLoading information for a class.
5842/// libs is a space separated list of libraries.
5843
5844Int_t TCling::SetClassSharedLibs(const char *cls, const char *libs)
5845{
5846 if (!cls || !*cls)
5847 return 0;
5848
5849 TString key = TString("Library.") + cls;
5850 // convert "::" to "@@", we used "@@" because TEnv
5851 // considers "::" a terminator
5852 key.ReplaceAll("::", "@@");
5853 // convert "-" to " ", since class names may have
5854 // blanks and TEnv considers a blank a terminator
5855 key.ReplaceAll(" ", "-");
5856
5858 if (!fMapfile) {
5859 fMapfile = new TEnv();
5861
5864
5865 InitRootmapFile(".rootmap");
5866 }
5867 //fMapfile->SetValue(key, libs);
5868 fMapfile->SetValue(cls, libs);
5869 return 1;
5870}
5871
5872////////////////////////////////////////////////////////////////////////////////
5873/// Demangle the name (from the typeinfo) and then request the class
5874/// via the usual name based interface (TClass::GetClass).
5875
5876TClass *TCling::GetClass(const std::type_info& typeinfo, Bool_t load) const
5877{
5878 int err = 0;
5879 char* demangled_name = TClassEdit::DemangleTypeIdName(typeinfo, err);
5880 if (err) return 0;
5881 TClass* theClass = TClass::GetClass(demangled_name, load, kTRUE);
5882 free(demangled_name);
5883 return theClass;
5884}
5885
5886////////////////////////////////////////////////////////////////////////////////
5887/// Load library containing the specified class. Returns 0 in case of error
5888/// and 1 in case if success.
5889
5890Int_t TCling::AutoLoad(const std::type_info& typeinfo, Bool_t knowDictNotLoaded /* = kFALSE */)
5891{
5892 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
5893
5894 int err = 0;
5895 char* demangled_name_c = TClassEdit::DemangleTypeIdName(typeinfo, err);
5896 if (err) {
5897 return 0;
5898 }
5899
5900 std::string demangled_name(demangled_name_c);
5901 free(demangled_name_c);
5902
5903 // AutoLoad expects (because TClass::GetClass already prepares it that way) a
5904 // shortened name.
5906 splitname.ShortType(demangled_name, TClassEdit::kDropStlDefault | TClassEdit::kDropStd);
5907
5908 // No need to worry about typedef, they aren't any ... but there are
5909 // inlined namespaces ...
5910
5911 Int_t result = AutoLoad(demangled_name.c_str());
5912 if (result == 0) {
5913 demangled_name = TClassEdit::GetLong64_Name(demangled_name);
5914 result = AutoLoad(demangled_name.c_str(), knowDictNotLoaded);
5915 }
5916
5917 return result;
5918}
5919
5920////////////////////////////////////////////////////////////////////////////////
5921// Get the list of 'published'/'known' library for the class and load them.
5923{
5924 Int_t status = 0;
5925
5926 // lookup class to find list of dependent libraries
5927 TString deplibs = gCling->GetClassSharedLibs(cls);
5928 if (!deplibs.IsNull()) {
5929 TString delim(" ");
5930 TObjArray* tokens = deplibs.Tokenize(delim);
5931 for (Int_t i = (tokens->GetEntriesFast() - 1); i > 0; --i) {
5932 const char* deplib = ((TObjString*)tokens->At(i))->GetName();
5933 if (gROOT->LoadClass(cls, deplib) == 0) {
5934 if (gDebug > 0) {
5935 gCling->Info("TCling::AutoLoad",
5936 "loaded dependent library %s for %s", deplib, cls);
5937 }
5938 }
5939 else {
5940 gCling->Error("TCling::AutoLoad",
5941 "failure loading dependent library %s for %s",
5942 deplib, cls);
5943 }
5944 }
5945 const char* lib = ((TObjString*)tokens->At(0))->GetName();
5946 if (lib && lib[0]) {
5947 if (gROOT->LoadClass(cls, lib) == 0) {
5948 if (gDebug > 0) {
5949 gCling->Info("TCling::AutoLoad",
5950 "loaded library %s for %s", lib, cls);
5951 }
5952 status = 1;
5953 }
5954 else {
5955 gCling->Error("TCling::AutoLoad",
5956 "failure loading library %s for %s", lib, cls);
5957 }
5958 }
5959 delete tokens;
5960 }
5961
5962 return status;
5963}
5964
5965////////////////////////////////////////////////////////////////////////////////
5966// Iterate through the data member of the class (either through the TProtoClass
5967// or through Cling) and trigger, recursively, the loading the necessary libraries.
5969{
5970 Int_t status = ShallowAutoLoadImpl(cls);
5971 if (status) {
5972
5973 // This routine should be called only from AutoLoad which has already
5974 // taken the main ROOT lock so this should not have any race condition.
5975 // If the lock is removed from AutoLoad, a spin lock should be introduced here.
5976 // Note that it is actually alright if another thread is populating this
5977 // set since we can then exclude both the infinite recursion (the main goal)
5978 // and duplicate work.
5979 static std::set<std::string> gClassOnStack;
5980 auto insertResult = gClassOnStack.insert(std::string(cls));
5981 if (insertResult.second) {
5982 // Now look through the TProtoClass to load the required library/dictionary
5984 if (proto) {
5985 for(auto element : proto->GetData()) {
5986 const char *subtypename = element->GetTypeName();
5987 if (!element->IsBasic() && !TClassTable::GetDictNorm(subtypename)) {
5988 // Failure to load a dictionary is not (quite) a failure load
5989 // the top-level library. If we return false here, then
5990 // we would end up in a situation where the library and thus
5991 // the dictionary is loaded for "cls" but the TClass is
5992 // not created and/or marked as unavailable (in case where
5993 // AutoLoad is called from TClass::GetClass).
5994 (void) DeepAutoLoadImpl(subtypename);
5995 }
5996 }
5997 } else {
5998 auto classinfo = gInterpreter->ClassInfo_Factory(cls);
5999 if (classinfo && gInterpreter->ClassInfo_IsValid(classinfo)
6000 && !(gInterpreter->ClassInfo_Property(classinfo) & kIsEnum))
6001 {
6002 DataMemberInfo_t *memberinfo = gInterpreter->DataMemberInfo_Factory(classinfo, TDictionary::EMemberSelection::kNoUsingDecls);
6003 while (gInterpreter->DataMemberInfo_Next(memberinfo)) {
6004 auto membertypename = TClassEdit::GetLong64_Name(gInterpreter->TypeName(gInterpreter->DataMemberInfo_TypeTrueName(memberinfo)));
6005 if (!(gInterpreter->DataMemberInfo_TypeProperty(memberinfo) & ::kIsFundamental)
6006 && !TClassTable::GetDictNorm(membertypename.c_str()))
6007 {
6008 // Failure to load a dictionary is not (quite) a failure load
6009 // the top-level library. See detailed comment in the TProtoClass
6010 // branch (above).
6011 (void)DeepAutoLoadImpl(membertypename.c_str());
6012 }
6013 }
6014 gInterpreter->DataMemberInfo_Delete(memberinfo);
6015 }
6016 gInterpreter->ClassInfo_Delete(classinfo);
6017 }
6018 // Because they could have been failures, allow for another try later
6019 gClassOnStack.erase(insertResult.first);
6020 }
6021 }
6022 return status;
6023}
6024
6025////////////////////////////////////////////////////////////////////////////////
6026/// Load library containing the specified class. Returns 0 in case of error
6027/// and 1 in case if success.
6028
6029Int_t TCling::AutoLoad(const char *cls, Bool_t knowDictNotLoaded /* = kFALSE */)
6030{
6031 // Prevent update to IsClassAutoloading between our check and our actions.
6033
6034 // TClass::GetClass explicitly calls gInterpreter->AutoLoad. When called from
6035 // rootcling (in *_rdict.pcm file generation) it is a no op.
6036 // FIXME: We should avoid calling autoload when we know we are not supposed
6037 // to and transform this check into an assert.
6039 // Never load any library from rootcling/genreflex.
6040 if (gDebug > 2) {
6041 Info("TCling::AutoLoad", "Explicitly disabled (the class name is %s)", cls);
6042 }
6043 return 0;
6044 }
6045
6046 assert(IsClassAutoLoadingEnabled() && "Calling when AutoLoading is off!");
6047
6049
6050 if (!knowDictNotLoaded && gClassTable->GetDictNorm(cls)) {
6051 // The library is already loaded as the class's dictionary is known.
6052 // Return success.
6053 // Note: the name (cls) is expected to be normalized as it comes either
6054 // from a callbacks (that can/should calculate the normalized name from the
6055 // decl) or from TClass::GetClass (which does also calculate the normalized
6056 // name).
6057 return 1;
6058 }
6059
6060 if (gDebug > 2) {
6061 Info("TCling::AutoLoad",
6062 "Trying to autoload for %s", cls);
6063 }
6064
6065 if (!gROOT || !gInterpreter || gROOT->TestBit(TObject::kInvalidObject)) {
6066 if (gDebug > 2) {
6067 Info("TCling::AutoLoad",
6068 "Disabled due to gROOT or gInterpreter being invalid/not ready (the class name is %s)", cls);
6069 }
6070 return 0;
6071 }
6072 // Prevent the recursion when the library dictionary are loaded.
6073 SuspendAutoLoadingRAII autoLoadOff(this);
6074 // Try using externally provided callback first.
6075 if (fAutoLoadCallBack) {
6076 int success = (*(AutoLoadCallBack_t)fAutoLoadCallBack)(cls);
6077 if (success)
6078 return success;
6079 }
6080
6081 // During the 'Deep' part of the search we will call GetClassSharedLibsForModule
6082 // (when module are enabled) which might end up calling AutoParsing but
6083 // that should only be for the cases where the library has no generated pcm
6084 // and in that case a rootmap should be available.
6085 // This avoids a very costly operation (for generally no gain) but reduce the
6086 // quality of the search (i.e. bad in case of library with no pcm and no rootmap
6087 // file).
6088 TInterpreter::SuspendAutoParsing autoParseRaii(this);
6089 return DeepAutoLoadImpl(cls);
6090}
6091
6092////////////////////////////////////////////////////////////////////////////////
6093/// Parse the payload or header.
6094
6095static cling::Interpreter::CompilationResult ExecAutoParse(const char *what,
6096 Bool_t header,
6097 cling::Interpreter *interpreter)
6098{
6099 std::string code = gNonInterpreterClassDef ;
6100 if (!header) {
6101 // This is the complete header file content and not the
6102 // name of a header.
6103 code += what;
6104
6105 } else {
6106 code += ("#include \"");
6107 code += what;
6108 code += "\"\n";
6109 }
6110 code += ("#ifdef __ROOTCLING__\n"
6111 "#undef __ROOTCLING__\n"
6112 + gInterpreterClassDef +
6113 "#endif");
6114
6115 cling::Interpreter::CompilationResult cr;
6116 {
6117 // scope within which diagnostics are de-activated
6118 // For now we disable diagnostics because we saw them already at
6119 // dictionary generation time. That won't be an issue with the PCMs.
6120
6121 Sema &SemaR = interpreter->getSema();
6122 ROOT::Internal::ParsingStateRAII parsingStateRAII(interpreter->getParser(), SemaR);
6123 clangDiagSuppr diagSuppr(SemaR.getDiagnostics());
6124
6125 #if defined(R__MUST_REVISIT)
6126 #if R__MUST_REVISIT(6,2)
6127 Warning("TCling::RegisterModule","Diagnostics suppression should be gone by now.");
6128 #endif
6129 #endif
6130
6131 cr = interpreter->parseForModule(code);
6132 }
6133 return cr;
6134}
6135
6136////////////////////////////////////////////////////////////////////////////////
6137/// Helper routine for TCling::AutoParse implementing the actual call to the
6138/// parser and looping over template parameters (if
6139/// any) and when they don't have a registered header to autoparse,
6140/// recurse over their template parameters.
6141///
6142/// Returns the number of header parsed.
6143
6144UInt_t TCling::AutoParseImplRecurse(const char *cls, bool topLevel)
6145{
6146 // We assume the lock has already been taken.
6147 // R__LOCKGUARD(gInterpreterMutex);
6148
6149 Int_t nHheadersParsed = 0;
6150 unsigned long offset = 0;
6151 if (strncmp(cls, "const ", 6) == 0) {
6152 offset = 6;
6153 }
6154
6155 // Loop on the possible autoparse keys
6156 bool skipFirstEntry = false;
6157 std::vector<std::string> autoparseKeys;
6158 if (strchr(cls, '<')) {
6159 int nestedLoc = 0;
6160 TClassEdit::GetSplit(cls + offset, autoparseKeys, nestedLoc, TClassEdit::kDropTrailStar);
6161 // Check if we can skip the name of the template in the autoparses
6162 // Take all the scopes one by one. If all of them are in the AST, we do not
6163 // need to autoparse for that particular template.
6164 if (!autoparseKeys.empty() && !autoparseKeys[0].empty()) {
6165 // autoparseKeys[0] is empty when the input is not a template instance.
6166 // The case strchr(cls, '<') != 0 but still not a template instance can
6167 // happens 'just' for string (GetSplit replaces the template by the short name
6168 // and then use that for thew splitting)
6169 TString templateName(autoparseKeys[0]);
6170 auto tokens = templateName.Tokenize("::");
6171 clang::NamedDecl* previousScopeAsNamedDecl = nullptr;
6172 clang::DeclContext* previousScopeAsContext = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
6173 if (TClassEdit::IsStdClass(cls + offset))
6174 previousScopeAsContext = fInterpreter->getSema().getStdNamespace();
6175 auto nTokens = tokens->GetEntriesFast();
6176 for (Int_t tk = 0; tk < nTokens; ++tk) {
6177 auto scopeObj = tokens->UncheckedAt(tk);
6178 auto scopeName = ((TObjString*) scopeObj)->String().Data();
6179 previousScopeAsNamedDecl = cling::utils::Lookup::Named(&fInterpreter->getSema(), scopeName, previousScopeAsContext);
6180 // Check if we have multiple nodes in the AST with this name
6181 if ((clang::NamedDecl*)-1 == previousScopeAsNamedDecl) break;
6182 previousScopeAsContext = llvm::dyn_cast_or_null<clang::DeclContext>(previousScopeAsNamedDecl);
6183 if (!previousScopeAsContext) break; // this is not a context
6184 }
6185 delete tokens;
6186 // Now, let's check if the last scope, the template, has a definition, i.e. it's not a fwd decl
6187 if ((clang::NamedDecl*)-1 != previousScopeAsNamedDecl) {
6188 if (auto templateDecl = llvm::dyn_cast_or_null<clang::ClassTemplateDecl>(previousScopeAsNamedDecl)) {
6189 if (auto templatedDecl = templateDecl->getTemplatedDecl()) {
6190 skipFirstEntry = templatedDecl->hasDefinition();
6191 }
6192 }
6193 }
6194
6195 }
6196 }
6197 if (topLevel) autoparseKeys.emplace_back(cls);
6198
6199 for (const auto & apKeyStr : autoparseKeys) {
6200 if (skipFirstEntry) {
6201 skipFirstEntry=false;
6202 continue;
6203 }
6204 if (apKeyStr.empty()) continue;
6205 const char *apKey = apKeyStr.c_str();
6206 std::size_t normNameHash(fStringHashFunction(apKey));
6207 // If the class was not looked up
6208 if (gDebug > 1) {
6209 Info("TCling::AutoParse",
6210 "Starting autoparse for %s\n", apKey);
6211 }
6212 if (fLookedUpClasses.insert(normNameHash).second) {
6213 auto const &iter = fClassesHeadersMap.find(normNameHash);
6214 if (iter != fClassesHeadersMap.end()) {
6215 const cling::Transaction *T = fInterpreter->getCurrentTransaction();
6216 fTransactionHeadersMap.insert({T,normNameHash});
6217 auto const &hNamesPtrs = iter->second;
6218 if (gDebug > 1) {
6219 Info("TCling::AutoParse",
6220 "We can proceed for %s. We have %s headers.", apKey, std::to_string(hNamesPtrs.size()).c_str());
6221 }
6222 for (auto & hName : hNamesPtrs) {
6223 if (fParsedPayloadsAddresses.count(hName) == 1) continue;
6224 if (0 != fPayloads.count(normNameHash)) {
6225 float initRSSval=0.f, initVSIZEval=0.f;
6226 (void) initRSSval; // Avoid unused var warning
6227 (void) initVSIZEval;
6228 if (gDebug > 0) {
6229 Info("AutoParse",
6230 "Parsing full payload for %s", apKey);
6231 ProcInfo_t info;
6232 gSystem->GetProcInfo(&info);
6233 initRSSval = 1e-3*info.fMemResident;
6234 initVSIZEval = 1e-3*info.fMemVirtual;
6235 }
6236 auto cRes = ExecAutoParse(hName, kFALSE, GetInterpreterImpl());
6237 if (cRes != cling::Interpreter::kSuccess) {
6238 if (hName[0] == '\n')
6239 Error("AutoParse", "Error parsing payload code for class %s with content:\n%s", apKey, hName);
6240 } else {
6241 fParsedPayloadsAddresses.insert(hName);
6242 nHheadersParsed++;
6243 if (gDebug > 0){
6244 ProcInfo_t info;
6245 gSystem->GetProcInfo(&info);
6246 float endRSSval = 1e-3*info.fMemResident;
6247 float endVSIZEval = 1e-3*info.fMemVirtual;
6248 Info("Autoparse", ">>> RSS key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initRSSval, endRSSval, endRSSval-initRSSval);
6249 Info("Autoparse", ">>> VSIZE key %s - before %.3f MB - after %.3f MB - delta %.3f MB", apKey, initVSIZEval, endVSIZEval, endVSIZEval-initVSIZEval);
6250 }
6251 }
6252 } else if (!IsLoaded(hName)) {
6253 if (gDebug > 0) {
6254 Info("AutoParse",
6255 "Parsing single header %s", hName);
6256 }
6257 auto cRes = ExecAutoParse(hName, kTRUE, GetInterpreterImpl());
6258 if (cRes != cling::Interpreter::kSuccess) {
6259 Error("AutoParse", "Error parsing headerfile %s for class %s.", hName, apKey);
6260 } else {
6261 nHheadersParsed++;
6262 }
6263 }
6264 }
6265 }
6266 else {
6267 // There is no header registered for this class, if this a
6268 // template, it will be instantiated if/when it is requested
6269 // and if we do no load/parse its components we might end up
6270 // not using an eventual specialization.
6271 if (strchr(apKey, '<')) {
6272 nHheadersParsed += AutoParseImplRecurse(apKey, false);
6273 }
6274 }
6275 }
6276 }
6277
6278 return nHheadersParsed;
6279
6280}
6281
6282////////////////////////////////////////////////////////////////////////////////
6283/// Parse the headers relative to the class
6284/// Returns 1 in case of success, 0 in case of failure
6285
6286Int_t TCling::AutoParse(const char *cls)
6287{
6288 if (llvm::StringRef(cls).contains("(lambda)"))
6289 return 0;
6290
6293 return AutoLoad(cls);
6294 } else {
6295 return 0;
6296 }
6297 }
6298
6300
6301 if (gDebug > 1) {
6302 Info("TCling::AutoParse",
6303 "Trying to autoparse for %s", cls);
6304 }
6305
6306 // The catalogue of headers is in the dictionary
6308 && !gClassTable->GetDictNorm(cls)) {
6309 // Need RAII against recursive (dictionary payload) parsing (ROOT-8445).
6310 ROOT::Internal::ParsingStateRAII parsingStateRAII(fInterpreter->getParser(),
6311 fInterpreter->getSema());
6312 AutoLoad(cls, true /*knowDictNotLoaded*/);
6313 }
6314
6315 // Prevent the recursion when the library dictionary are loaded.
6316 SuspendAutoLoadingRAII autoLoadOff(this);
6317
6318 // No recursive header parsing on demand; we require headers to be standalone.
6319 SuspendAutoParsing autoParseRAII(this);
6320
6321 Int_t nHheadersParsed = AutoParseImplRecurse(cls,/*topLevel=*/ true);
6322
6324
6325 return nHheadersParsed > 0 ? 1 : 0;
6326}
6327
6328// This is a function which gets callback from cling when DynamicLibraryManager->loadLibrary failed for some reason.
6329// Try to solve the problem by AutoLoading. Return true when AutoLoading success, return
6330// false if not.
6331bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::string& libStem, bool permanent, bool resolved)
6332{
6333 StringRef errMsg(errmessage);
6334 if (errMsg.contains("undefined symbol: ")) {
6335 // This branch is taken when the callback was from DynamicLibraryManager::loadLibrary
6336 std::string mangled_name = std::string(errMsg.split("undefined symbol: ").second);
6337 void* res = ((TCling*)gCling)->LazyFunctionCreatorAutoload(mangled_name);
6338 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
6339 if (res && DLM && (DLM->loadLibrary(libStem, permanent, resolved) == cling::DynamicLibraryManager::kLoadLibSuccess))
6340 // Return success when LazyFunctionCreatorAutoload could find mangled_name
6341 return true;
6342 } else {
6343 // The callback is from IncrementalExecutor::diagnoseUnresolvedSymbols
6344 if ( ((TCling*)gCling)->LazyFunctionCreatorAutoload(errmessage))
6345 return true;
6346 }
6347
6348 return false;
6349}
6350
6351static void* LazyFunctionCreatorAutoloadForModule(const std::string &mangled_name,
6352 const cling::DynamicLibraryManager &DLM) {
6354
6355 auto LibLoader = [](const std::string& LibName) -> bool {
6356 if (gSystem->Load(LibName.c_str(), "", false) < 0) {
6357 Error("TCling__LazyFunctionCreatorAutoloadForModule",
6358 "Failed to load library %s", LibName.c_str());
6359 return false;
6360 }
6361 return true; //success.
6362 };
6363
6364#ifdef R__MACOSX
6365 // The JIT gives us a mangled name which has only one leading underscore on
6366 // all platforms, for instance _ZN8TRandom34RndmEv. However, on OSX the
6367 // linker stores this symbol as __ZN8TRandom34RndmEv (adding an extra _).
6368 assert(!llvm::StringRef(mangled_name).startswith("__") && "Already added!");
6369 std::string libName = DLM.searchLibrariesForSymbol('_' + mangled_name,
6370 /*searchSystem=*/ true);
6371#else
6372 std::string libName = DLM.searchLibrariesForSymbol(mangled_name,
6373 /*searchSystem=*/ true);
6374#endif //R__MACOSX
6375
6376 assert(!llvm::StringRef(libName).startswith("libNew") &&
6377 "We must not resolve symbols from libNew!");
6378
6379 if (libName.empty())
6380 return nullptr;
6381
6382 if (!LibLoader(libName))
6383 return nullptr;
6384
6385 return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(mangled_name);
6386
6387}
6388
6389////////////////////////////////////////////////////////////////////////////////
6390/// Autoload a library based on a missing symbol.
6391
6392void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {
6394 return LazyFunctionCreatorAutoloadForModule(mangled_name,
6395 *GetInterpreterImpl()->getDynamicLibraryManager());
6396
6397 // First see whether the symbol is in the library that we are currently
6398 // loading. It will have access to the symbols of its dependent libraries,
6399 // thus checking "back()" is sufficient.
6400 if (!fRegisterModuleDyLibs.empty()) {
6401 if (void* addr = dlsym(fRegisterModuleDyLibs.back(),
6402 mangled_name.c_str())) {
6403 return addr;
6404 }
6405 }
6406
6407 int err = 0;
6408 char* demangled_name_c = TClassEdit::DemangleName(mangled_name.c_str(), err);
6409 if (err) {
6410 return 0;
6411 }
6412
6413 std::string name(demangled_name_c);
6414 free(demangled_name_c);
6415
6416 //fprintf(stderr, "demangled name: '%s'\n", demangled_name);
6417 //
6418 // Separate out the class or namespace part of the
6419 // function name.
6420 //
6421
6422 std::string::size_type pos = name.find("__thiscall ");
6423 if (pos != std::string::npos) {
6424 name.erase(0, pos + sizeof("__thiscall ")-1);
6425 }
6426 pos = name.find("__cdecl ");
6427 if (pos != std::string::npos) {
6428 name.erase(0, pos + sizeof("__cdecl ")-1);
6429 }
6430 if (!strncmp(name.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
6431 name.erase(0, sizeof("typeinfo for ")-1);
6432 } else if (!strncmp(name.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
6433 name.erase(0, sizeof("vtable for ")-1);
6434 } else if (!strncmp(name.c_str(), "operator", sizeof("operator")-1)
6435 && !isalnum(name[sizeof("operator")])) {
6436 // operator...(A, B) - let's try with A!
6437 name.erase(0, sizeof("operator")-1);
6438 pos = name.rfind('(');
6439 if (pos != std::string::npos) {
6440 name.erase(0, pos + 1);
6441 pos = name.find(",");
6442 if (pos != std::string::npos) {
6443 // remove next arg up to end, leaving only the first argument type.
6444 name.erase(pos);
6445 }
6446 pos = name.rfind(" const");
6447 if (pos != std::string::npos) {
6448 name.erase(pos, strlen(" const"));
6449 }
6450 while (!name.empty() && strchr("&*", name.back()))
6451 name.erase(name.length() - 1);
6452 }
6453 } else {
6456 name = fsi.fScopeName;
6457 }
6458 //fprintf(stderr, "name: '%s'\n", name.c_str());
6459 // Now we have the class or namespace name, so do the lookup.
6460 TString libs = GetClassSharedLibs(name.c_str());
6461 if (libs.IsNull()) {
6462 // Not found in the map, all done.
6463 return 0;
6464 }
6465 //fprintf(stderr, "library: %s\n", iter->second.c_str());
6466 // Now we have the name of the libraries to load, so load them.
6467
6468 TString lib;
6469 Ssiz_t posLib = 0;
6470 while (libs.Tokenize(lib, posLib)) {
6471 if (gSystem->Load(lib, "", kFALSE /*system*/) < 0) {
6472 // The library load failed, all done.
6473 //fprintf(stderr, "load failed: %s\n", errmsg.c_str());
6474 return 0;
6475 }
6476 }
6477
6478 //fprintf(stderr, "load succeeded.\n");
6479 // Get the address of the function being called.
6480 void* addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(mangled_name.c_str());
6481 //fprintf(stderr, "addr: %016lx\n", reinterpret_cast<unsigned long>(addr));
6482 return addr;
6483}
6484
6485////////////////////////////////////////////////////////////////////////////////
6486
6487Bool_t TCling::IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl* nsDecl)
6488{
6489 return fNSFromRootmaps.count(nsDecl) != 0;
6490}
6491
6492////////////////////////////////////////////////////////////////////////////////
6493/// Internal function. Actually do the update of the ClassInfo when seeing
6494// new TagDecl or NamespaceDecl.
6495void TCling::RefreshClassInfo(TClass *cl, const clang::NamedDecl *def, bool alias)
6496{
6497
6499 if (cci) {
6500 // If we only had a forward declaration then update the
6501 // TClingClassInfo with the definition if we have it now.
6502 const NamedDecl *oldDef = llvm::dyn_cast_or_null<NamedDecl>(cci->GetDecl());
6503 if (!oldDef || (def && def != oldDef)) {
6504 cl->ResetCaches();
6506 if (def) {
6507 // It's a tag decl, not a namespace decl.
6508 cci->Init(*cci->GetType());
6510 }
6511 }
6512 } else if (!cl->TestBit(TClass::kLoading) && !cl->fHasRootPcmInfo) {
6513 cl->ResetCaches();
6514 // yes, this is almost a waste of time, but we do need to lookup
6515 // the 'type' corresponding to the TClass anyway in order to
6516 // preserve the opaque typedefs (Double32_t)
6517 if (!alias && def != nullptr)
6518 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), def);
6519 else
6520 cl->fClassInfo = (ClassInfo_t *)new TClingClassInfo(GetInterpreterImpl(), cl->GetName());
6521 if (((TClingClassInfo *)cl->fClassInfo)->IsValid()) {
6522 // We now need to update the state and bits.
6523 if (cl->fState != TClass::kHasTClassInit) {
6524 // if (!cl->fClassInfo->IsValid()) cl->fState = TClass::kForwardDeclared; else
6527 }
6528 TClass::AddClassToDeclIdMap(((TClingClassInfo *)(cl->fClassInfo))->GetDeclId(), cl);
6529 } else {
6530 delete ((TClingClassInfo *)cl->fClassInfo);
6531 cl->fClassInfo = nullptr;
6532 }
6533 }
6534}
6535
6536////////////////////////////////////////////////////////////////////////////////
6537/// Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
6538void TCling::UpdateClassInfoWithDecl(const NamedDecl* ND)
6539{
6540 const TagDecl *td = dyn_cast<TagDecl>(ND);
6541 const NamespaceDecl *ns = dyn_cast<NamespaceDecl>(ND);
6542 const NamedDecl *canon = nullptr;
6543
6544 std::string name;
6545 TagDecl* tdDef = 0;
6546 if (td) {
6547 canon = tdDef = td->getDefinition();
6548 // Let's pass the decl to the TClass only if it has a definition.
6549 if (!tdDef) return;
6550
6551 if (!tdDef->isCompleteDefinition() || llvm::isa<clang::FunctionDecl>(tdDef->getDeclContext())) {
6552 // Ignore incomplete definition.
6553 // Ignore declaration within a function.
6554 return;
6555 }
6556
6557 auto declName = tdDef->getNameAsString();
6558 // Check if we have registered the unqualified name into the list
6559 // of TClass that are in kNoInfo, kEmulated or kFwdDeclaredState.
6560 // Since this is used as heureutistic to avoid spurrious calls to GetNormalizedName
6561 // the unqualified name is sufficient (and the fully qualified name might be
6562 // 'wrong' if there is difference in spelling in the template paramters (for example)
6563 if (!TClass::HasNoInfoOrEmuOrFwdDeclaredDecl(declName.c_str())){
6564 // 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() );
6565 return;
6566 }
6567
6568 clang::QualType type(tdDef->getTypeForDecl(), 0);
6570 } else if (ns) {
6571 canon = ns->getCanonicalDecl();
6572 name = ND->getQualifiedNameAsString();
6573 } else {
6574 name = ND->getQualifiedNameAsString();
6575 }
6576
6577 // Supposedly we are being called while something is being
6578 // loaded ... let's now tell the autoloader to do the work
6579 // yet another time.
6580 SuspendAutoLoadingRAII autoLoadOff(this);
6581 // FIXME: There can be more than one TClass for a single decl.
6582 // for example vector<double> and vector<Double32_t>
6583 TClass* cl = (TClass*)gROOT->GetListOfClasses()->FindObject(name.c_str());
6584 if (cl && GetModTClasses().find(cl) == GetModTClasses().end()) {
6585 RefreshClassInfo(cl, canon, false);
6586 }
6587 // And here we should find the other 'aliases' (eg. vector<Double32_t>)
6588 // and update them too:
6589 // foreach(aliascl in gROOT->GetListOfClasses()->FindAliasesOf(name.c_str()))
6590 // RefreshClassInfo(cl, tdDef, true);
6591}
6592
6593////////////////////////////////////////////////////////////////////////////////
6594/// No op: see TClingCallbacks
6595
6596void TCling::UpdateClassInfo(char* item, Long_t tagnum)
6597{
6598}
6599
6600//______________________________________________________________________________
6601//FIXME: Factor out that function in TClass, because TClass does it already twice
6602void TCling::UpdateClassInfoWork(const char* item)
6603{
6604 // This is a no-op as part of the API.
6605 // TCling uses UpdateClassInfoWithDecl() instead.
6606}
6607
6608////////////////////////////////////////////////////////////////////////////////
6609/// Update all canvases at end the terminal input command.
6610
6612{
6613 TIter next(gROOT->GetListOfCanvases());
6614 TVirtualPad* canvas;
6615 while ((canvas = (TVirtualPad*)next())) {
6616 canvas->Update();
6617 }
6618}
6619
6620////////////////////////////////////////////////////////////////////////////////
6621
6622void TCling::UpdateListsOnCommitted(const cling::Transaction &T) {
6623 std::set<TClass*> modifiedTClasses; // TClasses that require update after this transaction
6624
6625 // If the transaction does not contain anything we can return earlier.
6626 if (!HandleNewTransaction(T)) return;
6627
6628 bool isTUTransaction = false;
6629 if (!T.empty() && T.decls_begin() + 1 == T.decls_end() && !T.hasNestedTransactions()) {
6630 clang::Decl* FirstDecl = *(T.decls_begin()->m_DGR.begin());
6631 if (llvm::isa<clang::TranslationUnitDecl>(FirstDecl)) {
6632 // The is the first transaction, we have to expose to meta
6633 // what's already in the AST.
6634 isTUTransaction = true;
6635 }
6636 }
6637
6638 std::set<const void*> TransactionDeclSet;
6639 if (!isTUTransaction && T.decls_end() - T.decls_begin()) {
6640 const clang::Decl* WrapperFD = T.getWrapperFD();
6641 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6642 I != E; ++I) {
6643 if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl
6644 && I->m_Call != cling::Transaction::kCCIHandleTagDeclDefinition)
6645 continue;
6646
6647 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6648 DE = I->m_DGR.end(); DI != DE; ++DI) {
6649 if (*DI == WrapperFD)
6650 continue;
6651 TransactionDeclSet.insert(*DI);
6652 ((TCling*)gCling)->HandleNewDecl(*DI, false, modifiedTClasses);
6653 }
6654 }
6655 }
6656
6657 // The above might trigger more decls to be deserialized.
6658 // Thus the iteration over the deserialized decls must be last.
6659 for (cling::Transaction::const_iterator I = T.deserialized_decls_begin(),
6660 E = T.deserialized_decls_end(); I != E; ++I) {
6661 for (DeclGroupRef::const_iterator DI = I->m_DGR.begin(),
6662 DE = I->m_DGR.end(); DI != DE; ++DI)
6663 if (TransactionDeclSet.find(*DI) == TransactionDeclSet.end()) {
6664 //FIXME: HandleNewDecl should take DeclGroupRef
6665 ((TCling*)gCling)->HandleNewDecl(*DI, /*isDeserialized*/true,
6666 modifiedTClasses);
6667 }
6668 }
6669
6670
6671 // When fully building the reflection info in TClass, a deserialization
6672 // could be triggered, which may result in request for building the
6673 // reflection info for the same TClass. This in turn will clear the caches
6674 // for the TClass in-flight and cause null ptr derefs.
6675 // FIXME: This is a quick fix, solving most of the issues. The actual
6676 // question is: Shouldn't TClass provide a lock mechanism on update or lock
6677 // itself until the update is done.
6678 //
6679 std::vector<TClass*> modifiedTClassesDiff(modifiedTClasses.size());
6680 std::vector<TClass*>::iterator it;
6681 it = set_difference(modifiedTClasses.begin(), modifiedTClasses.end(),
6682 ((TCling*)gCling)->GetModTClasses().begin(),
6683 ((TCling*)gCling)->GetModTClasses().end(),
6684 modifiedTClassesDiff.begin());
6685 modifiedTClassesDiff.resize(it - modifiedTClassesDiff.begin());
6686
6687 // Lock the TClass for updates
6688 ((TCling*)gCling)->GetModTClasses().insert(modifiedTClassesDiff.begin(),
6689 modifiedTClassesDiff.end());
6690 for (std::vector<TClass*>::const_iterator I = modifiedTClassesDiff.begin(),
6691 E = modifiedTClassesDiff.end(); I != E; ++I) {
6692 // Make sure the TClass has not been deleted.
6693 if (!gROOT->GetListOfClasses()->FindObject(*I)) {
6694 continue;
6695 }
6696 // Could trigger deserialization of decls.
6697 cling::Interpreter::PushTransactionRAII RAII(GetInterpreterImpl());
6698 // Unlock the TClass for updates
6699 ((TCling*)gCling)->GetModTClasses().erase(*I);
6700
6701 }
6702}
6703
6704///\brief Invalidate stored TCling state for declarations included in transaction `T'.
6705///
6706void TCling::UpdateListsOnUnloaded(const cling::Transaction &T)
6707{
6709
6710 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6711 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6712 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6713 (TListOfEnums *)gROOT->GetListOfEnums());
6714
6715 cling::Transaction::const_nested_iterator iNested = T.nested_begin();
6716 for (cling::Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
6717 I != E; ++I) {
6718 if (I->m_Call == cling::Transaction::kCCIHandleVTable)
6719 continue;
6720 if (I->m_Call == cling::Transaction::kCCINone) {
6721 UpdateListsOnUnloaded(*(*iNested));
6722 ++iNested;
6723 continue;
6724 }
6725
6726 for (auto &D : I->m_DGR)
6727 InvalidateCachedDecl(Lists, D);
6728 }
6729}
6730
6731///\brief Invalidate cached TCling information for the given global declaration.
6732///
6733void TCling::InvalidateGlobal(const Decl *D) {
6734 auto Lists = std::make_tuple((TListOfDataMembers *)gROOT->GetListOfGlobals(),
6735 (TListOfFunctions *)gROOT->GetListOfGlobalFunctions(),
6736 (TListOfFunctionTemplates *)gROOT->GetListOfFunctionTemplates(),
6737 (TListOfEnums *)gROOT->GetListOfEnums());
6738 InvalidateCachedDecl(Lists, D);
6739}
6740
6741///\brief Invalidate cached TCling information for the given declaration, and
6742/// removed it from the appropriate object list.
6743///\param[in] Lists - std::tuple<TListOfDataMembers&, TListOfFunctions&,
6744/// TListOfFunctionTemplates&, TListOfEnums&>
6745/// of pointers to the (global/class) object lists.
6746///\param[in] D - Decl to discard.
6747///
6751 TListOfEnums*> &Lists, const Decl *D) {
6752 if (D->isFromASTFile()) // `D' came from the PCH; ignore
6753 return;
6754
6755 TListOfDataMembers &LODM = *(std::get<0>(Lists));
6756 TListOfFunctions &LOF = *(std::get<1>(Lists));
6757 TListOfFunctionTemplates &LOFT = *(std::get<2>(Lists));
6758 TListOfEnums &LOE = *(std::get<3>(Lists));
6759
6760 if (isa<VarDecl>(D) || isa<FieldDecl>(D) || isa<EnumConstantDecl>(D)) {
6761 TObject *O = LODM.Find((TDictionary::DeclId_t)D);
6762 if (LODM.GetClass())
6763 RemoveAndInvalidateObject(LODM, static_cast<TDataMember *>(O));
6764 else
6765 RemoveAndInvalidateObject(LODM, static_cast<TGlobal *>(O));
6766 } else if (isa<FunctionDecl>(D)) {
6768 } else if (isa<FunctionTemplateDecl>(D)) {
6770 } else if (isa<EnumDecl>(D)) {
6771 TEnum *E = LOE.Find((TDictionary::DeclId_t)D);
6772 if (!E)
6773 return;
6774
6775 // Try to invalidate enumerators (for unscoped enumerations).
6776 for (TIter I = E->GetConstants(); auto EC = (TEnumConstant *)I(); )
6778 (TEnumConstant *)LODM.FindObject(EC->GetName()));
6779
6781 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
6782 if (isa<RecordDecl>(D) && !cast<RecordDecl>(D)->isCompleteDefinition())
6783 return;
6784
6785 std::vector<TClass *> Classes;
6786 if (!TClass::GetClass(D->getCanonicalDecl(), Classes))
6787 return;
6788 for (auto &C : Classes) {
6789 auto Lists = std::make_tuple((TListOfDataMembers *)C->GetListOfDataMembers(),
6790 (TListOfFunctions *)C->GetListOfMethods(),
6791 (TListOfFunctionTemplates *)C->GetListOfFunctionTemplates(),
6792 (TListOfEnums *)C->GetListOfEnums());
6793 for (auto &I : cast<DeclContext>(D)->decls())
6794 InvalidateCachedDecl(Lists, I);
6795
6796 // For NamespaceDecl (redeclarable), only invalidate this redecl.
6797 if (D->getKind() != Decl::Namespace
6798 || cast<NamespaceDecl>(D)->isOriginalNamespace())
6799 C->ResetClassInfo();
6800 }
6801 }
6802}
6803
6804////////////////////////////////////////////////////////////////////////////////
6805// If an autoparse was done during a transaction and that it is rolled back,
6806// we need to make sure the next request for the same autoparse will be
6807// honored.
6808void TCling::TransactionRollback(const cling::Transaction &T) {
6809 auto const &triter = fTransactionHeadersMap.find(&T);
6810 if (triter != fTransactionHeadersMap.end()) {
6811 std::size_t normNameHash = triter->second;
6812
6813 fLookedUpClasses.erase(normNameHash);
6814
6815 auto const &iter = fClassesHeadersMap.find(normNameHash);
6816 if (iter != fClassesHeadersMap.end()) {
6817 auto const &hNamesPtrs = iter->second;
6818 for (auto &hName : hNamesPtrs) {
6819 if (gDebug > 0) {
6820 Info("TransactionRollback",
6821 "Restoring ability to autoaparse: %s", hName);
6822 }
6823 fParsedPayloadsAddresses.erase(hName);
6824 }
6825 }
6826 }
6827}
6828
6829////////////////////////////////////////////////////////////////////////////////
6830
6831void TCling::LibraryLoaded(const void* dyLibHandle, const char* canonicalName) {
6832// R__LOCKGUARD_CLING(gInterpreterMutex);
6833// UpdateListOfLoadedSharedLibraries();
6834}
6835
6836////////////////////////////////////////////////////////////////////////////////
6837
6838void TCling::LibraryUnloaded(const void* dyLibHandle, const char* canonicalName) {
6840 fSharedLibs = "";
6841}
6842
6843////////////////////////////////////////////////////////////////////////////////
6844/// Return the list of shared libraries loaded into the process.
6845
6847{
6850 return fSharedLibs;
6851}
6852
6853static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
6854{
6855 if (!cls || !*cls)
6856 return {};
6857
6858 using namespace clang;
6859 if (const Decl *D = LH.findScope(cls, cling::LookupHelper::NoDiagnostics,
6860 /*type*/ nullptr, /*instantiate*/ false)) {
6861 if (!D->isFromASTFile()) {
6862 if (gDebug > 5)
6863 Warning("GetClassSharedLibsForModule", "Decl found for %s is not part of a module", cls);
6864 return {};
6865 }
6866 class ModuleCollector : public ConstDeclVisitor<ModuleCollector> {
6867 llvm::DenseSet<Module *> &m_TopLevelModules;
6868
6869 public:
6870 ModuleCollector(llvm::DenseSet<Module *> &TopLevelModules) : m_TopLevelModules(TopLevelModules) {}
6871 void Collect(const Decl *D) { Visit(D); }
6872
6873 void VisitDecl(const Decl *D)
6874 {
6875 // FIXME: Such case is described ROOT-7765 where
6876 // ROOT_GENERATE_DICTIONARY does not contain the list of headers.
6877 // They are specified as #includes in the LinkDef file. This leads to
6878 // generation of incomplete modulemap files and this logic fails to
6879 // compute the corresponding module of D.
6880 // FIXME: If we want to support such a case, we should not rely on
6881 // the contents of the modulemap but mangle D and look it up in the
6882 // .so files.
6883 if (!D->hasOwningModule())
6884 return;
6885 if (Module *M = D->getOwningModule()->getTopLevelModule())
6886 m_TopLevelModules.insert(M);
6887 }
6888
6889 void VisitTemplateArgument(const TemplateArgument &TA)
6890 {
6891 switch (TA.getKind()) {
6893 case TemplateArgument::Integral:
6894 case TemplateArgument::Pack:
6895 case TemplateArgument::NullPtr:
6896 case TemplateArgument::Expression:
6897 case TemplateArgument::Template:
6898 case TemplateArgument::TemplateExpansion: return;
6900 if (const TagType *TagTy = dyn_cast<TagType>(TA.getAsType()))
6901 return Visit(TagTy->getDecl());
6902 return;
6903 case TemplateArgument::Declaration: return Visit(TA.getAsDecl());
6904 }
6905 llvm_unreachable("Invalid TemplateArgument::Kind!");
6906 }
6907
6908 void VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *CTSD)
6909 {
6910 if (CTSD->getOwningModule())
6911 VisitDecl(CTSD);
6912 else
6913 VisitDecl(CTSD->getSpecializedTemplate());
6914 const TemplateArgumentList &ArgList = CTSD->getTemplateArgs();
6915 for (const TemplateArgument *Arg = ArgList.data(), *ArgEnd = Arg + ArgList.size(); Arg != ArgEnd; ++Arg) {
6916 VisitTemplateArgument(*Arg);
6917 }
6918 }
6919 };
6920
6921 llvm::DenseSet<Module *> TopLevelModules;
6922 ModuleCollector m(TopLevelModules);
6923 m.Collect(D);
6924 std::string result;
6925 for (auto M : TopLevelModules) {
6926 // ROOT-unaware modules (i.e. not processed by rootcling) do not have a
6927 // link declaration.
6928 if (!M->LinkLibraries.size())
6929 continue;
6930 // We have preloaded the Core module thus libCore.so
6931 if (M->Name == "Core")
6932 continue;
6933 assert(M->LinkLibraries.size() == 1);
6934 if (!result.empty())
6935 result += ' ';
6936 result += M->LinkLibraries[0].Library;
6937 }
6938 return result;
6939 }
6940 return {};
6941}
6942
6943////////////////////////////////////////////////////////////////////////////////
6944/// Get the list of shared libraries containing the code for class cls.
6945/// The first library in the list is the one containing the class, the
6946/// others are the libraries the first one depends on. Returns 0
6947/// in case the library is not found.
6948
6949const char* TCling::GetClassSharedLibs(const char* cls)
6950{
6951 if (fCxxModulesEnabled) {
6952 llvm::StringRef className = cls;
6953 // If we get a class name containing lambda, we cannot parse it and we
6954 // can exit early.
6955 // FIXME: This works around a bug when we are instantiating a template
6956 // make_unique and the substitution fails. Seen in most of the dataframe
6957 // tests.
6958 if (className.contains("(lambda)"))
6959 return nullptr;
6960 // Limit the recursion which can be induced by GetClassSharedLibsForModule.
6961 SuspendAutoLoadingRAII AutoLoadingDisabled(this);
6962 cling::LookupHelper &LH = fInterpreter->getLookupHelper();
6963 std::string libs = GetClassSharedLibsForModule(cls, LH);
6964 if (!libs.empty()) {
6965 fAutoLoadLibStorage.push_back(libs);
6966 return fAutoLoadLibStorage.back().c_str();
6967 }
6968 }
6969
6970 if (!cls || !*cls) {
6971 return 0;
6972 }
6973 // lookup class to find list of libraries
6974 if (fMapfile) {
6975 TEnvRec* libs_record = 0;
6976 libs_record = fMapfile->Lookup(cls);
6977 if (libs_record) {
6978 const char* libs = libs_record->GetValue();
6979 return (*libs) ? libs : 0;
6980 }
6981 else {
6982 // Try the old format...
6983 TString c = TString("Library.") + cls;
6984 // convert "::" to "@@", we used "@@" because TEnv
6985 // considers "::" a terminator
6986 c.ReplaceAll("::", "@@");
6987 // convert "-" to " ", since class names may have
6988 // blanks and TEnv considers a blank a terminator
6989 c.ReplaceAll(" ", "-");
6990 // Use TEnv::Lookup here as the rootmap file must start with Library.
6991 // and do not support using any stars (so we do not need to waste time
6992 // with the search made by TEnv::GetValue).
6993 TEnvRec* libs_record = 0;
6994 libs_record = fMapfile->Lookup(c);
6995 if (libs_record) {
6996 const char* libs = libs_record->GetValue();
6997 return (*libs) ? libs : 0;
6998 }
6999 }
7000 }
7001 return 0;
7002}
7003
7004/// This interface returns a list of dependent libraries in the form:
7005/// lib libA.so libB.so libC.so. The first library is the library we are
7006/// searching dependencies for.
7007/// Note: In order to speed up the search, we display the dependencies of the
7008/// libraries which are not yet loaded. For instance, if libB.so was already
7009/// loaded the list would contain: lib libA.so libC.so.
7010static std::string GetSharedLibImmediateDepsSlow(std::string lib,
7011 cling::Interpreter *interp,
7012 bool skipLoadedLibs = true)
7013{
7014 TString LibFullPath(lib);
7015 if (!llvm::sys::path::is_absolute(lib)) {
7016 if (!gSystem->FindDynamicLibrary(LibFullPath, /*quiet=*/true)) {
7017 Error("TCling__GetSharedLibImmediateDepsSlow", "Cannot find library '%s'", lib.c_str());
7018 return "";
7019 }
7020 } else {
7021 assert(llvm::sys::fs::exists(lib) && "Must exist!");
7022 lib = llvm::sys::path::filename(lib);
7023 }
7024
7025 auto ObjF = llvm::object::ObjectFile::createObjectFile(LibFullPath.Data());
7026 if (!ObjF) {
7027 Warning("TCling__GetSharedLibImmediateDepsSlow", "Failed to read object file %s", lib.c_str());
7028 return "";
7029 }
7030
7031 llvm::object::ObjectFile *BinObjFile = ObjF.get().getBinary();
7032
7033 std::set<string> DedupSet;
7034 std::string Result = lib + ' ';
7035 for (const auto &S : BinObjFile->symbols()) {
7036 uint32_t Flags = S.getFlags();
7037 if (Flags & llvm::object::SymbolRef::SF_Undefined) {
7038 llvm::Expected<StringRef> SymNameErr = S.getName();
7039 if (!SymNameErr) {
7040 Warning("GetSharedLibDepsForModule", "Failed to read symbol");
7041 continue;
7042 }
7043 llvm::StringRef SymName = SymNameErr.get();
7044 if (SymName.empty())
7045 continue;
7046
7047 if (BinObjFile->isELF()) {
7048 // Skip the symbols which are part of the C/C++ runtime and have a
7049 // fixed library version. See binutils ld VERSION. Those reside in
7050 // 'system' libraries, which we avoid in FindLibraryForSymbol.
7051 if (SymName.contains("@@GLIBCXX") || SymName.contains("@@CXXABI") ||
7052 SymName.contains("@@GLIBC") || SymName.contains("@@GCC"))
7053 continue;
7054
7055 // Those are 'weak undefined' symbols produced by gcc. We can
7056 // ignore them.
7057 // FIXME: It is unclear whether we can ignore all weak undefined
7058 // symbols:
7059 // http://lists.llvm.org/pipermail/llvm-dev/2017-October/118177.html
7060 if (SymName == "_Jv_RegisterClasses" ||
7061 SymName == "_ITM_deregisterTMCloneTable" ||
7062 SymName == "_ITM_registerTMCloneTable")
7063 continue;
7064 }
7065
7066// FIXME: this might really depend on MachO library format instead of R__MACOSX.
7067#ifdef R__MACOSX
7068 // MacOS symbols sometimes have an extra "_", see
7069 // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlsym.3.html
7070 if (skipLoadedLibs && SymName[0] == '_'
7071 && llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymName.drop_front()))
7072 continue;
7073#endif
7074
7075 // If we can find the address of the symbol, we have loaded it. Skip.
7076 if (skipLoadedLibs && llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(SymName))
7077 continue;
7078
7080 std::string found = interp->getDynamicLibraryManager()->searchLibrariesForSymbol(SymName, /*searchSystem*/false);
7081 // The expected output is just filename without the full path, which
7082 // is not very accurate, because our Dyld implementation might find
7083 // a match in location a/b/c.so and if we return just c.so ROOT might
7084 // resolve it to y/z/c.so and there we might not be ABI compatible.
7085 // FIXME: Teach the users of GetSharedLibDeps to work with full paths.
7086 if (!found.empty()) {
7087 std::string cand = llvm::sys::path::filename(found).str();
7088 if (!DedupSet.insert(cand).second)
7089 continue;
7090
7091 Result += cand + ' ';
7092 }
7093 }
7094 }
7095
7096 return Result;
7097}
7098
7099static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
7100{
7101 // Check if we have parsed a rootmap file.
7102 llvm::SmallString<256> rootmapName;
7103 if (!lib.startswith("lib"))
7104 rootmapName.append("lib");
7105
7106 rootmapName.append(llvm::sys::path::filename(lib));
7107 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7108
7109 if (gCling->GetRootMapFiles()->FindObject(rootmapName.c_str()))
7110 return true;
7111
7112 // Perform a last resort by dropping the lib prefix.
7113 llvm::StringRef rootmapNameNoLib = rootmapName.str();
7114 if (rootmapNameNoLib.consume_front("lib"))
7115 return gCling->GetRootMapFiles()->FindObject(rootmapNameNoLib.data());
7116
7117 return false;
7118}
7119
7120static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
7121{
7122 if (gCling->HasPCMForLibrary(lib.data()))
7123 return true;
7124
7125 return hasParsedRootmapForLibrary(lib);
7126}
7127
7128////////////////////////////////////////////////////////////////////////////////
7129/// Get the list a libraries on which the specified lib depends. The
7130/// returned string contains as first element the lib itself.
7131/// Returns 0 in case the lib does not exist or does not have
7132/// any dependencies. If useDyld is true, we iterate through all available
7133/// libraries and try to construct the dependency chain by resolving each
7134/// symbol.
7135
7136const char* TCling::GetSharedLibDeps(const char* lib, bool useDyld/* = false*/)
7137{
7138 if (llvm::sys::path::is_absolute(lib) && !llvm::sys::fs::exists(lib))
7139 return nullptr;
7140
7141 if (!hasParsedRootmapForLibrary(lib)) {
7142 llvm::SmallString<512> rootmapName(lib);
7143 llvm::sys::path::replace_extension(rootmapName, "rootmap");
7144 if (llvm::sys::fs::exists(rootmapName)) {
7145 if (gDebug > 0)
7146 Info("Load", "loading %s", rootmapName.c_str());
7147 gInterpreter->LoadLibraryMap(rootmapName.c_str());
7148 }
7149 }
7150
7151 if (hasPrecomputedLibraryDeps(lib) && useDyld) {
7152 if (gDebug > 0)
7153 Warning("TCling::GetSharedLibDeps", "Precomputed dependencies available but scanning '%s'", lib);
7154 }
7155
7156 if (useDyld) {
7157 std::string libs = GetSharedLibImmediateDepsSlow(lib, GetInterpreterImpl());
7158 if (!libs.empty()) {
7159 fAutoLoadLibStorage.push_back(libs);
7160 return fAutoLoadLibStorage.back().c_str();
7161 }
7162 }
7163
7164 if (!fMapfile || !lib || !lib[0]) {
7165 return 0;
7166 }
7167 TString libname(lib);
7168 Ssiz_t idx = libname.Last('.');
7169 if (idx != kNPOS) {
7170 libname.Remove(idx);
7171 }
7172 TEnvRec* rec;
7173 TIter next(fMapfile->GetTable());
7174 size_t len = libname.Length();
7175 while ((rec = (TEnvRec*) next())) {
7176 const char* libs = rec->GetValue();
7177 if (!strncmp(libs, libname.Data(), len) && strlen(libs) >= len
7178 && (!libs[len] || libs[len] == ' ' || libs[len] == '.')) {
7179 return libs;
7180 }
7181 }
7182 return 0;
7183}
7184
7185////////////////////////////////////////////////////////////////////////////////
7186/// If error messages are disabled, the interpreter should suppress its
7187/// failures and warning messages from stdout.
7188
7190{
7191#if defined(R__MUST_REVISIT)
7192#if R__MUST_REVISIT(6,2)
7193 Warning("IsErrorMessagesEnabled", "Interface not available yet.");
7194#endif
7195#endif
7196 return kTRUE;
7197}
7198
7199////////////////////////////////////////////////////////////////////////////////
7200/// If error messages are disabled, the interpreter should suppress its
7201/// failures and warning messages from stdout. Return the previous state.
7202
7204{
7205#if defined(R__MUST_REVISIT)
7206#if R__MUST_REVISIT(6,2)
7207 Warning("SetErrorMessages", "Interface not available yet.");
7208#endif
7209#endif
7211}
7212
7213////////////////////////////////////////////////////////////////////////////////
7214/// Refresh the list of include paths known to the interpreter and return it
7215/// with -I prepended.
7216
7218{
7220
7221 fIncludePath = "";
7222
7223 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7224 //false - no system header, true - with flags.
7225 fInterpreter->GetIncludePaths(includePaths, false, true);
7226 if (const size_t nPaths = includePaths.size()) {
7227 assert(!(nPaths & 1) && "GetIncludePath, number of paths and options is not equal");
7228
7229 for (size_t i = 0; i < nPaths; i += 2) {
7230 if (i)
7231 fIncludePath.Append(' ');
7232 fIncludePath.Append(includePaths[i].c_str());
7233
7234 if (includePaths[i] != "-I")
7235 fIncludePath.Append(' ');
7236 fIncludePath.Append('"');
7237 fIncludePath.Append(includePaths[i + 1], includePaths[i + 1].length());
7238 fIncludePath.Append('"');
7239 }
7240 }
7241
7242 return fIncludePath;
7243}
7244
7245////////////////////////////////////////////////////////////////////////////////
7246/// Return the directory containing CINT's stl cintdlls.
7247
7248const char* TCling::GetSTLIncludePath() const
7249{
7250 return "";
7251}
7252
7253//______________________________________________________________________________
7254// M I S C
7255//______________________________________________________________________________
7256
7257int TCling::DisplayClass(FILE* /*fout*/, const char* /*name*/, int /*base*/, int /*start*/) const
7258{
7259 // Interface to cling function
7260 return 0;
7261}
7262
7263////////////////////////////////////////////////////////////////////////////////
7264/// Interface to cling function
7265
7266int TCling::DisplayIncludePath(FILE *fout) const
7267{
7268 assert(fout != 0 && "DisplayIncludePath, 'fout' parameter is null");
7269
7270 llvm::SmallVector<std::string, 10> includePaths;//Why 10? Hell if I know.
7271 //false - no system header, true - with flags.
7272 fInterpreter->GetIncludePaths(includePaths, false, true);
7273 if (const size_t nPaths = includePaths.size()) {
7274 assert(!(nPaths & 1) && "DisplayIncludePath, number of paths and options is not equal");
7275
7276 std::string allIncludes("include path:");
7277 for (size_t i = 0; i < nPaths; i += 2) {
7278 allIncludes += ' ';
7279 allIncludes += includePaths[i];
7280
7281 if (includePaths[i] != "-I")
7282 allIncludes += ' ';
7283 allIncludes += includePaths[i + 1];
7284 }
7285
7286 fprintf(fout, "%s\n", allIncludes.c_str());
7287 }
7288
7289 return 0;
7290}
7291
7292////////////////////////////////////////////////////////////////////////////////
7293/// Interface to cling function
7294
7295void* TCling::FindSym(const char* entry) const
7296{
7297 return fInterpreter->getAddressOfGlobal(entry);
7298}
7299
7300////////////////////////////////////////////////////////////////////////////////
7301/// Let the interpreter issue a generic error, and set its error state.
7302
7303void TCling::GenericError(const char* error) const
7304{
7305#if defined(R__MUST_REVISIT)
7306#if R__MUST_REVISIT(6,2)
7307 Warning("GenericError","Interface not available yet.");
7308#endif
7309#endif
7310}
7311
7312////////////////////////////////////////////////////////////////////////////////
7313/// This routines used to return the address of the internal wrapper
7314/// function (of the interpreter) that was used to call *all* the
7315/// interpreted functions that were bytecode compiled (no longer
7316/// interpreted line by line). In Cling, there is no such
7317/// wrapper function.
7318/// In practice this routines was use to decipher whether the
7319/// pointer returns by InterfaceMethod could be used to uniquely
7320/// represent the function. In Cling if the function is in a
7321/// useable state (its compiled version is available), this is
7322/// always the case.
7323/// See TClass::GetMethod.
7324
7326{
7327 return 0;
7328}
7329
7330////////////////////////////////////////////////////////////////////////////////
7331/// Interface to cling function
7332
7334{
7335#if defined(R__MUST_REVISIT)
7336#if R__MUST_REVISIT(6,2)
7337 Warning("GetSecurityError", "Interface not available yet.");
7338#endif
7339#endif
7340 return 0;
7341}
7342
7343////////////////////////////////////////////////////////////////////////////////
7344/// Load a source file or library called path into the interpreter.
7345
7346int TCling::LoadFile(const char* path) const
7347{
7348 cling::Interpreter::CompilationResult compRes;
7349 HandleInterpreterException(GetMetaProcessorImpl(), TString::Format(".L %s", path), compRes, /*cling::Value*/0);
7350 return compRes == cling::Interpreter::kFailure;
7351}
7352
7353////////////////////////////////////////////////////////////////////////////////
7354/// Load the declarations from text into the interpreter.
7355/// Note that this cannot be (top level) statements; text must contain
7356/// top level declarations.
7357/// Returns true on success, false on failure.
7358
7359Bool_t TCling::LoadText(const char* text) const
7360{
7361 return (fInterpreter->declare(text) == cling::Interpreter::kSuccess);
7362}
7363
7364////////////////////////////////////////////////////////////////////////////////
7365/// Interface to cling function
7366
7367const char* TCling::MapCppName(const char* name) const
7368{
7369 TTHREAD_TLS_DECL(std::string,buffer);
7371 return buffer.c_str();
7372}
7373
7374////////////////////////////////////////////////////////////////////////////////
7375/// [Place holder for Mutex Lock]
7376/// Provide the interpreter with a way to
7377/// acquire a lock used to protect critical section
7378/// of its code (non-thread safe parts).
7379
7380void TCling::SetAlloclockfunc(void (* /* p */ )()) const
7381{
7382 // nothing to do for now.
7383}
7384
7385////////////////////////////////////////////////////////////////////////////////
7386/// [Place holder for Mutex Unlock] Provide the interpreter with a way to
7387/// release a lock used to protect critical section
7388/// of its code (non-thread safe parts).
7389
7390void TCling::SetAllocunlockfunc(void (* /* p */ )()) const
7391{
7392 // nothing to do for now.
7393}
7394
7395////////////////////////////////////////////////////////////////////////////////
7396/// Returns if class AutoLoading is currently enabled.
7397
7399{
7400 if (IsFromRootCling())
7401 return false;
7402 if (!fClingCallbacks)
7403 return false;
7405}
7406
7407////////////////////////////////////////////////////////////////////////////////
7408/// Enable/Disable the AutoLoading of libraries.
7409/// Returns the old value, i.e whether it was enabled or not.
7410
7411int TCling::SetClassAutoLoading(int autoload) const
7412{
7413 // If no state change is required, exit early.
7414 // FIXME: In future we probably want to complain if we made a request which
7415 // was with the same state as before in order to catch programming errors.
7416 if ((bool) autoload == IsClassAutoLoadingEnabled())
7417 return autoload;
7418
7419 assert(fClingCallbacks && "We must have callbacks!");
7420 bool oldVal = fClingCallbacks->IsAutoLoadingEnabled();
7422 return oldVal;
7423}
7424
7425////////////////////////////////////////////////////////////////////////////////
7426/// Enable/Disable the Autoparsing of headers.
7427/// Returns the old value, i.e whether it was enabled or not.
7428
7430{
7431 bool oldVal = fHeaderParsingOnDemand;
7432 fHeaderParsingOnDemand = autoparse;
7433 return oldVal;
7434}
7435
7436////////////////////////////////////////////////////////////////////////////////
7437/// Suspend the Autoparsing of headers.
7438/// Returns the old value, i.e whether it was suspended or not.
7439
7444 return old;
7445}
7446
7447////////////////////////////////////////////////////////////////////////////////
7448/// Set a callback to receive error messages.
7449
7450void TCling::SetErrmsgcallback(void* p) const
7451{
7452#if defined(R__MUST_REVISIT)
7453#if R__MUST_REVISIT(6,2)
7454 Warning("SetErrmsgcallback", "Interface not available yet.");
7455#endif
7456#endif
7457}
7458
7459
7460////////////////////////////////////////////////////////////////////////////////
7461/// Create / close a scope for temporaries. No-op for cling; use
7462/// cling::Value instead.
7463
7464void TCling::SetTempLevel(int val) const
7465{
7466}
7467
7468////////////////////////////////////////////////////////////////////////////////
7469
7470int TCling::UnloadFile(const char* path) const
7471{
7472 cling::DynamicLibraryManager* DLM = fInterpreter->getDynamicLibraryManager();
7473 std::string canonical = DLM->lookupLibrary(path);
7474 if (canonical.empty()) {
7475 canonical = path;
7476 }
7477 // Unload a shared library or a source file.
7478 cling::Interpreter::CompilationResult compRes;
7479 HandleInterpreterException(GetMetaProcessorImpl(), Form(".U %s", canonical.c_str()), compRes, /*cling::Value*/0);
7480 return compRes == cling::Interpreter::kFailure;
7481}
7482
7483std::unique_ptr<TInterpreterValue> TCling::MakeInterpreterValue() const {
7484 return std::unique_ptr<TInterpreterValue>(new TClingValue);
7485}
7486
7487////////////////////////////////////////////////////////////////////////////////
7488/// The call to Cling's tab complition.
7489
7490void TCling::CodeComplete(const std::string& line, size_t& cursor,
7491 std::vector<std::string>& completions)
7492{
7493 fInterpreter->codeComplete(line, cursor, completions);
7494}
7495
7496////////////////////////////////////////////////////////////////////////////////
7497/// Get the interpreter value corresponding to the statement.
7498int TCling::Evaluate(const char* code, TInterpreterValue& value)
7499{
7500 auto V = reinterpret_cast<cling::Value*>(value.GetValAddr());
7501 auto compRes = fInterpreter->evaluate(code, *V);
7502 return compRes!=cling::Interpreter::kSuccess ? 0 : 1 ;
7503}
7504
7505////////////////////////////////////////////////////////////////////////////////
7506
7508{
7509 using namespace cling;
7510 const Value* V = reinterpret_cast<const Value*>(value.GetValAddr());
7512}
7513
7514////////////////////////////////////////////////////////////////////////////////
7515/// Register value as a temporary, extending its lifetime to that of the
7516/// interpreter. This is needed for TCling's compatibility interfaces
7517/// returning long - the address of the temporary objects.
7518/// As such, "simple" types don't need to be stored; they are returned by
7519/// value; only pointers / references / objects need to be stored.
7520
7522{
7523 if (value.isValid() && value.needsManagedAllocation()) {
7525 fTemporaries->push_back(value);
7526 }
7527}
7528
7529////////////////////////////////////////////////////////////////////////////////
7530/// If the interpreter encounters Name, check whether that is an object ROOT
7531/// could retrieve. To not re-read objects from disk, cache the name/object
7532/// pair for a given LookupCtx.
7533
7534TObject* TCling::GetObjectAddress(const char *Name, void *&LookupCtx)
7535{
7536 // The call to FindSpecialObject might induces any kind of use
7537 // of the interpreter ... (library loading, function calling, etc.)
7538 // ... and we _know_ we are in the middle of parsing, so let's make
7539 // sure to save the state and then restore it.
7540
7541 if (gDirectory) {
7542 auto iSpecObjMap = fSpecialObjectMaps.find(gDirectory);
7543 if (iSpecObjMap != fSpecialObjectMaps.end()) {
7544 auto iSpecObj = iSpecObjMap->second.find(Name);
7545 if (iSpecObj != iSpecObjMap->second.end()) {
7546 LookupCtx = gDirectory;
7547 return iSpecObj->second;
7548 }
7549 }
7550 }
7551
7552 // Save state of the PP
7553 Sema &SemaR = fInterpreter->getSema();
7554 ASTContext& C = SemaR.getASTContext();
7555 Preprocessor &PP = SemaR.getPreprocessor();
7556 Parser& P = const_cast<Parser&>(fInterpreter->getParser());
7557 Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP);
7558 Parser::ParserCurTokRestoreRAII savedCurToken(P);
7559 // After we have saved the token reset the current one to something which
7560 // is safe (semi colon usually means empty decl)
7561 Token& Tok = const_cast<Token&>(P.getCurToken());
7562 Tok.setKind(tok::semi);
7563
7564 // We can't PushDeclContext, because we go up and the routine that pops
7565 // the DeclContext assumes that we drill down always.
7566 // We have to be on the global context. At that point we are in a
7567 // wrapper function so the parent context must be the global.
7568 Sema::ContextAndScopeRAII pushedDCAndS(SemaR, C.getTranslationUnitDecl(),
7569 SemaR.TUScope);
7570
7571 TObject* specObj = gROOT->FindSpecialObject(Name, LookupCtx);
7572 if (specObj) {
7573 if (!LookupCtx) {
7574 Error("GetObjectAddress", "Got a special object without LookupCtx!");
7575 } else {
7576 fSpecialObjectMaps[LookupCtx][Name] = specObj;
7577 }
7578 }
7579 return specObj;
7580}
7581
7582////////////////////////////////////////////////////////////////////////////////
7583/// Inject function as a friend into klass.
7584/// With function being f in void f() {new N::PrivKlass(); } this enables
7585/// I/O of non-public classes.
7586
7587void TCling::AddFriendToClass(clang::FunctionDecl* function,
7588 clang::CXXRecordDecl* klass) const
7589{
7590 using namespace clang;
7591 ASTContext& Ctx = klass->getASTContext();
7592 FriendDecl::FriendUnion friendUnion(function);
7593 // one dummy object for the source location
7594 SourceLocation sl;
7595 FriendDecl* friendDecl = FriendDecl::Create(Ctx, klass, sl, friendUnion, sl);
7596 klass->pushFriendDecl(friendDecl);
7597}
7598
7599//______________________________________________________________________________
7600//
7601// DeclId getter.
7602//
7603
7604////////////////////////////////////////////////////////////////////////////////
7605/// Return a unique identifier of the declaration represented by the
7606/// CallFunc
7607
7609{
7610 if (func) return ((TClingCallFunc*)func)->GetDecl()->getCanonicalDecl();
7611 return 0;
7612}
7613
7614////////////////////////////////////////////////////////////////////////////////
7615/// Return a (almost) unique identifier of the declaration represented by the
7616/// ClassInfo. In ROOT, this identifier can point to more than one TClass
7617/// when the underlying class is a template instance involving one of the
7618/// opaque typedef.
7619
7621{
7622 if (cinfo) return ((TClingClassInfo*)cinfo)->GetDeclId();
7623 return 0;
7624}
7625
7626////////////////////////////////////////////////////////////////////////////////
7627/// Return a unique identifier of the declaration represented by the
7628/// MethodInfo
7629
7630TInterpreter::DeclId_t TCling::GetDeclId(DataMemberInfo_t* data) const
7631{
7632 if (data) return ((TClingDataMemberInfo*)data)->GetDeclId();
7633 return 0;
7634}
7635
7636////////////////////////////////////////////////////////////////////////////////
7637/// Return a unique identifier of the declaration represented by the
7638/// MethodInfo
7639
7641{
7642 if (method) return ((TClingMethodInfo*)method)->GetDeclId();
7643 return 0;
7644}
7645
7646////////////////////////////////////////////////////////////////////////////////
7647/// Return a unique identifier of the declaration represented by the
7648/// TypedefInfo
7649
7651{
7652 if (tinfo) return ((TClingTypedefInfo*)tinfo)->GetDecl()->getCanonicalDecl();
7653 return 0;
7654}
7655
7656//______________________________________________________________________________
7657//
7658// CallFunc interface
7659//
7660
7661////////////////////////////////////////////////////////////////////////////////
7662
7663void TCling::CallFunc_Delete(CallFunc_t* func) const
7664{
7665 delete (TClingCallFunc*) func;
7666}
7667
7668////////////////////////////////////////////////////////////////////////////////
7669
7670void TCling::CallFunc_Exec(CallFunc_t* func, void* address) const
7671{
7672 TClingCallFunc* f = (TClingCallFunc*) func;
7673 f->Exec(address);
7674}
7675
7676////////////////////////////////////////////////////////////////////////////////
7677
7678void TCling::CallFunc_Exec(CallFunc_t* func, void* address, TInterpreterValue& val) const
7679{
7680 TClingCallFunc* f = (TClingCallFunc*) func;
7681 f->Exec(address, &val);
7682}
7683
7684////////////////////////////////////////////////////////////////////////////////
7685
7686void TCling::CallFunc_ExecWithReturn(CallFunc_t* func, void* address, void* ret) const
7687{
7688 TClingCallFunc* f = (TClingCallFunc*) func;
7689 f->ExecWithReturn(address, ret);
7690}
7691
7692////////////////////////////////////////////////////////////////////////////////
7693
7694void TCling::CallFunc_ExecWithArgsAndReturn(CallFunc_t* func, void* address,
7695 const void* args[] /*=0*/,
7696 int nargs /*=0*/,
7697 void* ret/*=0*/) const
7698{
7699 TClingCallFunc* f = (TClingCallFunc*) func;
7700 f->ExecWithArgsAndReturn(address, args, nargs, ret);
7701}
7702
7703////////////////////////////////////////////////////////////////////////////////
7704
7705Long_t TCling::CallFunc_ExecInt(CallFunc_t* func, void* address) const
7706{
7707 TClingCallFunc* f = (TClingCallFunc*) func;
7708 return f->ExecInt(address);
7709}
7710
7711////////////////////////////////////////////////////////////////////////////////
7712
7713Long64_t TCling::CallFunc_ExecInt64(CallFunc_t* func, void* address) const
7714{
7715 TClingCallFunc* f = (TClingCallFunc*) func;
7716 return f->ExecInt64(address);
7717}
7718
7719////////////////////////////////////////////////////////////////////////////////
7720
7721Double_t TCling::CallFunc_ExecDouble(CallFunc_t* func, void* address) const
7722{
7723 TClingCallFunc* f = (TClingCallFunc*) func;
7724 return f->ExecDouble(address);
7725}
7726
7727////////////////////////////////////////////////////////////////////////////////
7728
7729CallFunc_t* TCling::CallFunc_Factory() const
7730{
7732 return (CallFunc_t*) new TClingCallFunc(GetInterpreterImpl(), *fNormalizedCtxt);
7733}
7734
7735////////////////////////////////////////////////////////////////////////////////
7736
7737CallFunc_t* TCling::CallFunc_FactoryCopy(CallFunc_t* func) const
7738{
7739 return (CallFunc_t*) new TClingCallFunc(*(TClingCallFunc*)func);
7740}
7741
7742////////////////////////////////////////////////////////////////////////////////
7743
7744MethodInfo_t* TCling::CallFunc_FactoryMethod(CallFunc_t* func) const
7745{
7746 TClingCallFunc* f = (TClingCallFunc*) func;
7747 return (MethodInfo_t*) f->FactoryMethod();
7748}
7749
7750////////////////////////////////////////////////////////////////////////////////
7751
7752void TCling::CallFunc_IgnoreExtraArgs(CallFunc_t* func, bool ignore) const
7753{
7754 TClingCallFunc* f = (TClingCallFunc*) func;
7755 f->IgnoreExtraArgs(ignore);
7756}
7757
7758////////////////////////////////////////////////////////////////////////////////
7759
7760void TCling::CallFunc_Init(CallFunc_t* func) const
7761{
7763 TClingCallFunc* f = (TClingCallFunc*) func;
7764 f->Init();
7765}
7766
7767////////////////////////////////////////////////////////////////////////////////
7768
7769bool TCling::CallFunc_IsValid(CallFunc_t* func) const
7770{
7771 TClingCallFunc* f = (TClingCallFunc*) func;
7772 return f->IsValid();
7773}
7774
7775////////////////////////////////////////////////////////////////////////////////
7776
7778TCling::CallFunc_IFacePtr(CallFunc_t * func) const
7779{
7780 TClingCallFunc* f = (TClingCallFunc*) func;
7781 return f->IFacePtr();
7782}
7783
7784////////////////////////////////////////////////////////////////////////////////
7785
7786void TCling::CallFunc_ResetArg(CallFunc_t* func) const
7787{
7788 TClingCallFunc* f = (TClingCallFunc*) func;
7789 f->ResetArg();
7790}
7791
7792////////////////////////////////////////////////////////////////////////////////
7793
7794void TCling::CallFunc_SetArg(CallFunc_t* func, Long_t param) const
7795{
7796 TClingCallFunc* f = (TClingCallFunc*) func;
7797 f->SetArg(param);
7798}
7799
7800////////////////////////////////////////////////////////////////////////////////
7801
7802void TCling::CallFunc_SetArg(CallFunc_t* func, ULong_t param) const
7803{
7804 TClingCallFunc* f = (TClingCallFunc*) func;
7805 f->SetArg(param);
7806}
7807
7808////////////////////////////////////////////////////////////////////////////////
7809
7810void TCling::CallFunc_SetArg(CallFunc_t* func, Float_t param) const
7811{
7812 TClingCallFunc* f = (TClingCallFunc*) func;
7813 f->SetArg(param);
7814}
7815
7816////////////////////////////////////////////////////////////////////////////////
7817
7818void TCling::CallFunc_SetArg(CallFunc_t* func, Double_t param) const
7819{
7820 TClingCallFunc* f = (TClingCallFunc*) func;
7821 f->SetArg(param);
7822}
7823
7824////////////////////////////////////////////////////////////////////////////////
7825
7826void TCling::CallFunc_SetArg(CallFunc_t* func, Long64_t param) const
7827{
7828 TClingCallFunc* f = (TClingCallFunc*) func;
7829 f->SetArg(param);
7830}
7831
7832////////////////////////////////////////////////////////////////////////////////
7833
7834void TCling::CallFunc_SetArg(CallFunc_t* func, ULong64_t param) const
7835{
7836 TClingCallFunc* f = (TClingCallFunc*) func;
7837 f->SetArg(param);
7838}
7839
7840////////////////////////////////////////////////////////////////////////////////
7841
7842void TCling::CallFunc_SetArgArray(CallFunc_t* func, Long_t* paramArr, Int_t nparam) const
7843{
7844 TClingCallFunc* f = (TClingCallFunc*) func;
7845 f->SetArgArray(paramArr, nparam);
7846}
7847
7848////////////////////////////////////////////////////////////////////////////////
7849
7850void TCling::CallFunc_SetArgs(CallFunc_t* func, const char* param) const
7851{
7852 TClingCallFunc* f = (TClingCallFunc*) func;
7853 f->SetArgs(param);
7854}
7855
7856////////////////////////////////////////////////////////////////////////////////
7857
7858void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, Long_t* offset) const
7859{
7860 TClingCallFunc* f = (TClingCallFunc*) func;
7861 TClingClassInfo* ci = (TClingClassInfo*) info;
7862 f->SetFunc(ci, method, params, offset);
7863}
7864
7865////////////////////////////////////////////////////////////////////////////////
7866
7867void TCling::CallFunc_SetFunc(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* params, bool objectIsConst, Long_t* offset) const
7868{
7869 TClingCallFunc* f = (TClingCallFunc*) func;
7870 TClingClassInfo* ci = (TClingClassInfo*) info;
7871 f->SetFunc(ci, method, params, objectIsConst, offset);
7872}
7873////////////////////////////////////////////////////////////////////////////////
7874
7875void TCling::CallFunc_SetFunc(CallFunc_t* func, MethodInfo_t* info) const
7876{
7877 TClingCallFunc* f = (TClingCallFunc*) func;
7878 TClingMethodInfo* minfo = (TClingMethodInfo*) info;
7879 f->SetFunc(minfo);
7880}
7881
7882////////////////////////////////////////////////////////////////////////////////
7883/// Interface to cling function
7884
7885void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
7886{
7887 TClingCallFunc* f = (TClingCallFunc*) func;
7888 TClingClassInfo* ci = (TClingClassInfo*) info;
7889 f->SetFuncProto(ci, method, proto, offset, mode);
7890}
7891
7892////////////////////////////////////////////////////////////////////////////////
7893/// Interface to cling function
7894
7895void TCling::CallFunc_SetFuncProto(CallFunc_t* func, ClassInfo_t* info, const char* method, const char* proto, bool objectIsConst, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
7896{
7897 TClingCallFunc* f = (TClingCallFunc*) func;
7898 TClingClassInfo* ci = (TClingClassInfo*) info;
7899 f->SetFuncProto(ci, method, proto, objectIsConst, offset, mode);
7900}
7901
7902////////////////////////////////////////////////////////////////////////////////
7903/// Interface to cling function
7904
7905void 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
7906{
7907 TClingCallFunc* f = (TClingCallFunc*) func;
7908 TClingClassInfo* ci = (TClingClassInfo*) info;
7909 llvm::SmallVector<clang::QualType, 4> funcProto;
7910 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
7911 iter != end; ++iter) {
7912 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
7913 }
7914 f->SetFuncProto(ci, method, funcProto, offset, mode);
7915}
7916
7917////////////////////////////////////////////////////////////////////////////////
7918/// Interface to cling function
7919
7920void 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
7921{
7922 TClingCallFunc* f = (TClingCallFunc*) func;
7923 TClingClassInfo* ci = (TClingClassInfo*) info;
7924 llvm::SmallVector<clang::QualType, 4> funcProto;
7925 for (std::vector<TypeInfo_t*>::const_iterator iter = proto.begin(), end = proto.end();
7926 iter != end; ++iter) {
7927 funcProto.push_back( ((TClingTypeInfo*)(*iter))->GetQualType() );
7928 }
7929 f->SetFuncProto(ci, method, funcProto, objectIsConst, offset, mode);
7930}
7931
7932std::string TCling::CallFunc_GetWrapperCode(CallFunc_t *func) const
7933{
7934 TClingCallFunc *f = (TClingCallFunc *)func;
7935 std::string wrapper_name;
7936 std::string wrapper;
7937 f->get_wrapper_code(wrapper_name, wrapper);
7938 return wrapper;
7939}
7940
7941//______________________________________________________________________________
7942//
7943// ClassInfo interface
7944//
7945
7946////////////////////////////////////////////////////////////////////////////////
7947/// Return true if the entity pointed to by 'declid' is declared in
7948/// the context described by 'info'. If info is null, look into the
7949/// global scope (translation unit scope).
7950
7951Bool_t TCling::ClassInfo_Contains(ClassInfo_t *info, DeclId_t declid) const
7952{
7953 if (!declid)
7954 return kFALSE;
7955
7956 const clang::DeclContext *ctxt = nullptr;
7957 if (info) {
7958 ctxt = clang::Decl::castToDeclContext(((TClingClassInfo*)info)->GetDecl());
7959 } else {
7960 ctxt = fInterpreter->getCI()->getASTContext().getTranslationUnitDecl();
7961 }
7962 if (!ctxt)
7963 return kFALSE;
7964
7965 const clang::Decl *decl = reinterpret_cast<const clang::Decl*>(declid);
7966 if (!decl)
7967 return kFALSE;
7968
7969 const clang::DeclContext *declDC = decl->getDeclContext();
7970 // ClassInfo_t-s are always "spellable" scopes, never unnamed or inline ones.
7971 while (true) {
7972 if (declDC->isTransparentContext()) {
7973 declDC = declDC->getParent();
7974 continue;
7975 }
7976 if (const auto *declRD = llvm::dyn_cast<clang::RecordDecl>(declDC)) {
7977 if (declRD->isAnonymousStructOrUnion()) {
7978 declDC = declRD->getParent();
7979 continue;
7980 }
7981 }
7982 if (const auto *declNS = llvm::dyn_cast<clang::NamespaceDecl>(declDC)) {
7983 if (declNS->isAnonymousNamespace() || declNS->isInlineNamespace()) {
7984 declDC = declNS->getParent();
7985 continue;
7986 }
7987 }
7988 break;
7989 }
7990
7991 return declDC->Equals(ctxt);
7992}
7993
7994////////////////////////////////////////////////////////////////////////////////
7995
7997{
7998 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
7999 return TClinginfo->ClassProperty();
8000}
8001
8002////////////////////////////////////////////////////////////////////////////////
8003
8004void TCling::ClassInfo_Delete(ClassInfo_t* cinfo) const
8005{
8006 delete (TClingClassInfo*) cinfo;
8007}
8008
8009////////////////////////////////////////////////////////////////////////////////
8010
8011void TCling::ClassInfo_Delete(ClassInfo_t* cinfo, void* arena) const
8012{
8013 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8014 TClinginfo->Delete(arena,*fNormalizedCtxt);
8015}
8016
8017////////////////////////////////////////////////////////////////////////////////
8018
8019void TCling::ClassInfo_DeleteArray(ClassInfo_t* cinfo, void* arena, bool dtorOnly) const
8020{
8021 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8022 TClinginfo->DeleteArray(arena, dtorOnly,*fNormalizedCtxt);
8023}
8024
8025////////////////////////////////////////////////////////////////////////////////
8026
8027void TCling::ClassInfo_Destruct(ClassInfo_t* cinfo, void* arena) const
8028{
8029 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8030 TClinginfo->Destruct(arena,*fNormalizedCtxt);
8031}
8032
8033////////////////////////////////////////////////////////////////////////////////
8034
8035ClassInfo_t* TCling::ClassInfo_Factory(Bool_t all) const
8036{
8038 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), all);
8039}
8040
8041////////////////////////////////////////////////////////////////////////////////
8042
8043ClassInfo_t* TCling::ClassInfo_Factory(ClassInfo_t* cinfo) const
8044{
8045 return (ClassInfo_t*) new TClingClassInfo(*(TClingClassInfo*)cinfo);
8046}
8047
8048////////////////////////////////////////////////////////////////////////////////
8049
8050ClassInfo_t* TCling::ClassInfo_Factory(const char* name) const
8051{
8053 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), name);
8054}
8055
8056ClassInfo_t* TCling::ClassInfo_Factory(DeclId_t declid) const
8057{
8059 return (ClassInfo_t*) new TClingClassInfo(GetInterpreterImpl(), (const clang::Decl*)declid);
8060}
8061
8062
8063////////////////////////////////////////////////////////////////////////////////
8064
8065int TCling::ClassInfo_GetMethodNArg(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst /* = false */, EFunctionMatchMode mode /* = kConversionMatch */) const
8066{
8067 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8068 return TClinginfo->GetMethodNArg(method, proto, objectIsConst, mode);
8069}
8070
8071////////////////////////////////////////////////////////////////////////////////
8072
8073bool TCling::ClassInfo_HasDefaultConstructor(ClassInfo_t* cinfo, Bool_t testio) const
8074{
8075 TClingClassInfo *TClinginfo = (TClingClassInfo *) cinfo;
8077}
8078
8079////////////////////////////////////////////////////////////////////////////////
8080
8081bool TCling::ClassInfo_HasMethod(ClassInfo_t* cinfo, const char* name) const
8082{
8083 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8084 return TClinginfo->HasMethod(name);
8085}
8086
8087////////////////////////////////////////////////////////////////////////////////
8088
8089void TCling::ClassInfo_Init(ClassInfo_t* cinfo, const char* name) const
8090{
8092 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8093 TClinginfo->Init(name);
8094}
8095
8096////////////////////////////////////////////////////////////////////////////////
8097
8098void TCling::ClassInfo_Init(ClassInfo_t* cinfo, int tagnum) const
8099{
8101 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8102 TClinginfo->Init(tagnum);
8103}
8104
8105////////////////////////////////////////////////////////////////////////////////
8106
8107bool TCling::ClassInfo_IsBase(ClassInfo_t* cinfo, const char* name) const
8108{
8109 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8110 return TClinginfo->IsBase(name);
8111}
8112
8113////////////////////////////////////////////////////////////////////////////////
8114
8115bool TCling::ClassInfo_IsEnum(const char* name) const
8116{
8118}
8119
8120////////////////////////////////////////////////////////////////////////////////
8121
8123{
8124 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8125 return TClinginfo->IsScopedEnum();
8126}
8127
8128
8129////////////////////////////////////////////////////////////////////////////////
8130
8132{
8133 TClingClassInfo* TClinginfo = (TClingClassInfo*) info;
8134 return TClinginfo->GetUnderlyingType();
8135}
8136
8137
8138////////////////////////////////////////////////////////////////////////////////
8139
8140bool TCling::ClassInfo_IsLoaded(ClassInfo_t* cinfo) const
8141{
8142 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8143 return TClinginfo->IsLoaded();
8144}
8145
8146////////////////////////////////////////////////////////////////////////////////
8147
8148bool TCling::ClassInfo_IsValid(ClassInfo_t* cinfo) const
8149{
8150 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8151 return TClinginfo->IsValid();
8152}
8153
8154////////////////////////////////////////////////////////////////////////////////
8155
8156bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8157{
8158 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8159 return TClinginfo->IsValidMethod(method, proto, false, offset, mode);
8160}
8161
8162////////////////////////////////////////////////////////////////////////////////
8163
8164bool TCling::ClassInfo_IsValidMethod(ClassInfo_t* cinfo, const char* method, const char* proto, Bool_t objectIsConst, Long_t* offset, EFunctionMatchMode mode /* = kConversionMatch */) const
8165{
8166 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8167 return TClinginfo->IsValidMethod(method, proto, objectIsConst, offset, mode);
8168}
8169
8170////////////////////////////////////////////////////////////////////////////////
8171
8172int TCling::ClassInfo_Next(ClassInfo_t* cinfo) const
8173{
8174 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8175 return TClinginfo->Next();
8176}
8177
8178////////////////////////////////////////////////////////////////////////////////
8179
8180void* TCling::ClassInfo_New(ClassInfo_t* cinfo) const
8181{
8182 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8183 return TClinginfo->New(*fNormalizedCtxt);
8184}
8185
8186////////////////////////////////////////////////////////////////////////////////
8187
8188void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n) const
8189{
8190 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8191 return TClinginfo->New(n,*fNormalizedCtxt);
8192}
8193
8194////////////////////////////////////////////////////////////////////////////////
8195
8196void* TCling::ClassInfo_New(ClassInfo_t* cinfo, int n, void* arena) const
8197{
8198 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8199 return TClinginfo->New(n, arena,*fNormalizedCtxt);
8200}
8201
8202////////////////////////////////////////////////////////////////////////////////
8203
8204void* TCling::ClassInfo_New(ClassInfo_t* cinfo, void* arena) const
8205{
8206 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8207 return TClinginfo->New(arena,*fNormalizedCtxt);
8208}
8209
8210////////////////////////////////////////////////////////////////////////////////
8211
8212Long_t TCling::ClassInfo_Property(ClassInfo_t* cinfo) const
8213{
8214 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8215 return TClinginfo->Property();
8216}
8217
8218////////////////////////////////////////////////////////////////////////////////
8219
8220int TCling::ClassInfo_Size(ClassInfo_t* cinfo) const
8221{
8222 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8223 return TClinginfo->Size();
8224}
8225
8226////////////////////////////////////////////////////////////////////////////////
8227
8228Long_t TCling::ClassInfo_Tagnum(ClassInfo_t* cinfo) const
8229{
8230 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8231 return TClinginfo->Tagnum();
8232}
8233
8234////////////////////////////////////////////////////////////////////////////////
8235
8236const char* TCling::ClassInfo_FileName(ClassInfo_t* cinfo) const
8237{
8238 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8239 return TClinginfo->FileName();
8240}
8241
8242////////////////////////////////////////////////////////////////////////////////
8243
8244const char* TCling::ClassInfo_FullName(ClassInfo_t* cinfo) const
8245{
8246 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8247 TTHREAD_TLS_DECL(std::string,output);
8248 TClinginfo->FullName(output,*fNormalizedCtxt);
8249 return output.c_str();
8250}
8251
8252////////////////////////////////////////////////////////////////////////////////
8253
8254const char* TCling::ClassInfo_Name(ClassInfo_t* cinfo) const
8255{
8256 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8257 return TClinginfo->Name();
8258}
8259
8260////////////////////////////////////////////////////////////////////////////////
8261
8262const char* TCling::ClassInfo_Title(ClassInfo_t* cinfo) const
8263{
8264 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8265 return TClinginfo->Title();
8266}
8267
8268////////////////////////////////////////////////////////////////////////////////
8269
8270const char* TCling::ClassInfo_TmpltName(ClassInfo_t* cinfo) const
8271{
8272 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8273 return TClinginfo->TmpltName();
8274}
8275
8276
8277
8278//______________________________________________________________________________
8279//
8280// BaseClassInfo interface
8281//
8282
8283////////////////////////////////////////////////////////////////////////////////
8284
8285void TCling::BaseClassInfo_Delete(BaseClassInfo_t* bcinfo) const
8286{
8287 delete(TClingBaseClassInfo*) bcinfo;
8288}
8289
8290////////////////////////////////////////////////////////////////////////////////
8291
8292BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* cinfo) const
8293{
8295 TClingClassInfo* TClinginfo = (TClingClassInfo*) cinfo;
8296 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo);
8297}
8298
8299////////////////////////////////////////////////////////////////////////////////
8300
8301BaseClassInfo_t* TCling::BaseClassInfo_Factory(ClassInfo_t* derived,
8302 ClassInfo_t* base) const
8303{
8305 TClingClassInfo* TClinginfo = (TClingClassInfo*) derived;
8306 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) base;
8307 return (BaseClassInfo_t*) new TClingBaseClassInfo(GetInterpreterImpl(), TClinginfo, TClinginfoBase);
8308}
8309
8310////////////////////////////////////////////////////////////////////////////////
8311
8312int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo) const
8313{
8314 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8315 return TClinginfo->Next();
8316}
8317
8318////////////////////////////////////////////////////////////////////////////////
8319
8320int TCling::BaseClassInfo_Next(BaseClassInfo_t* bcinfo, int onlyDirect) const
8321{
8322 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8323 return TClinginfo->Next(onlyDirect);
8324}
8325
8326////////////////////////////////////////////////////////////////////////////////
8327
8328Long_t TCling::BaseClassInfo_Offset(BaseClassInfo_t* toBaseClassInfo, void * address, bool isDerivedObject) const
8329{
8330 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) toBaseClassInfo;
8331 return TClinginfo->Offset(address, isDerivedObject);
8332}
8333
8334////////////////////////////////////////////////////////////////////////////////
8335
8336Long_t TCling::ClassInfo_GetBaseOffset(ClassInfo_t* fromDerived, ClassInfo_t* toBase, void * address, bool isDerivedObject) const
8337{
8338 TClingClassInfo* TClinginfo = (TClingClassInfo*) fromDerived;
8339 TClingClassInfo* TClinginfoBase = (TClingClassInfo*) toBase;
8340 // Offset to the class itself.
8341 if (TClinginfo->GetDecl() == TClinginfoBase->GetDecl()) {
8342 return 0;
8343 }
8344 return TClinginfo->GetBaseOffset(TClinginfoBase, address, isDerivedObject);
8345}
8346
8347////////////////////////////////////////////////////////////////////////////////
8348
8349Long_t TCling::BaseClassInfo_Property(BaseClassInfo_t* bcinfo) const
8350{
8351 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8352 return TClinginfo->Property();
8353}
8354
8355////////////////////////////////////////////////////////////////////////////////
8356
8357ClassInfo_t *TCling::BaseClassInfo_ClassInfo(BaseClassInfo_t *bcinfo) const
8358{
8359 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8360 return (ClassInfo_t *)TClinginfo->GetBase();
8361}
8362
8363////////////////////////////////////////////////////////////////////////////////
8364
8365Long_t TCling::BaseClassInfo_Tagnum(BaseClassInfo_t* bcinfo) const
8366{
8367 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8368 return TClinginfo->Tagnum();
8369}
8370
8371////////////////////////////////////////////////////////////////////////////////
8372
8373const char* TCling::BaseClassInfo_FullName(BaseClassInfo_t* bcinfo) const
8374{
8375 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8376 TTHREAD_TLS_DECL(std::string,output);
8377 TClinginfo->FullName(output,*fNormalizedCtxt);
8378 return output.c_str();
8379}
8380
8381////////////////////////////////////////////////////////////////////////////////
8382
8383const char* TCling::BaseClassInfo_Name(BaseClassInfo_t* bcinfo) const
8384{
8385 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8386 return TClinginfo->Name();
8387}
8388
8389////////////////////////////////////////////////////////////////////////////////
8390
8391const char* TCling::BaseClassInfo_TmpltName(BaseClassInfo_t* bcinfo) const
8392{
8393 TClingBaseClassInfo* TClinginfo = (TClingBaseClassInfo*) bcinfo;
8394 return TClinginfo->TmpltName();
8395}
8396
8397//______________________________________________________________________________
8398//
8399// DataMemberInfo interface
8400//
8401
8402////////////////////////////////////////////////////////////////////////////////
8403
8404int TCling::DataMemberInfo_ArrayDim(DataMemberInfo_t* dminfo) const
8405{
8406 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8407 return TClinginfo->ArrayDim();
8408}
8409
8410////////////////////////////////////////////////////////////////////////////////
8411
8412void TCling::DataMemberInfo_Delete(DataMemberInfo_t* dminfo) const
8413{
8414 delete(TClingDataMemberInfo*) dminfo;
8415}
8416
8417////////////////////////////////////////////////////////////////////////////////
8418
8419DataMemberInfo_t* TCling::DataMemberInfo_Factory(ClassInfo_t* clinfo, TDictionary::EMemberSelection selection) const
8420{
8422 TClingClassInfo* TClingclass_info = (TClingClassInfo*) clinfo;
8423 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), TClingclass_info, selection);
8424}
8425
8426////////////////////////////////////////////////////////////////////////////////
8427
8428DataMemberInfo_t* TCling::DataMemberInfo_Factory(DeclId_t declid, ClassInfo_t* clinfo) const
8429{
8431 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8432 const clang::ValueDecl* vd = llvm::dyn_cast_or_null<clang::ValueDecl>(decl);
8433 return (DataMemberInfo_t*) new TClingDataMemberInfo(GetInterpreterImpl(), vd, (TClingClassInfo*)clinfo);
8434}
8435
8436////////////////////////////////////////////////////////////////////////////////
8437
8438DataMemberInfo_t* TCling::DataMemberInfo_FactoryCopy(DataMemberInfo_t* dminfo) const
8439{
8440 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8441 return (DataMemberInfo_t*) new TClingDataMemberInfo(*TClinginfo);
8442}
8443
8444////////////////////////////////////////////////////////////////////////////////
8445
8446bool TCling::DataMemberInfo_IsValid(DataMemberInfo_t* dminfo) const
8447{
8448 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8449 return TClinginfo->IsValid();
8450}
8451
8452////////////////////////////////////////////////////////////////////////////////
8453
8454int TCling::DataMemberInfo_MaxIndex(DataMemberInfo_t* dminfo, Int_t dim) const
8455{
8456 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8457 return TClinginfo->MaxIndex(dim);
8458}
8459
8460////////////////////////////////////////////////////////////////////////////////
8461
8462int TCling::DataMemberInfo_Next(DataMemberInfo_t* dminfo) const
8463{
8464 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8465 return TClinginfo->Next();
8466}
8467
8468////////////////////////////////////////////////////////////////////////////////
8469
8470Long_t TCling::DataMemberInfo_Offset(DataMemberInfo_t* dminfo) const
8471{
8472 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8473 return TClinginfo->Offset();
8474}
8475
8476////////////////////////////////////////////////////////////////////////////////
8477
8478Long_t TCling::DataMemberInfo_Property(DataMemberInfo_t* dminfo) const
8479{
8480 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8481 return TClinginfo->Property();
8482}
8483
8484////////////////////////////////////////////////////////////////////////////////
8485
8486Long_t TCling::DataMemberInfo_TypeProperty(DataMemberInfo_t* dminfo) const
8487{
8488 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8489 return TClinginfo->TypeProperty();
8490}
8491
8492////////////////////////////////////////////////////////////////////////////////
8493
8494int TCling::DataMemberInfo_TypeSize(DataMemberInfo_t* dminfo) const
8495{
8496 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8497 return TClinginfo->TypeSize();
8498}
8499
8500////////////////////////////////////////////////////////////////////////////////
8501
8502const char* TCling::DataMemberInfo_TypeName(DataMemberInfo_t* dminfo) const
8503{
8504 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8505 return TClinginfo->TypeName();
8506}
8507
8508////////////////////////////////////////////////////////////////////////////////
8509
8510const char* TCling::DataMemberInfo_TypeTrueName(DataMemberInfo_t* dminfo) const
8511{
8512 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8513 return TClinginfo->TypeTrueName(*fNormalizedCtxt);
8514}
8515
8516////////////////////////////////////////////////////////////////////////////////
8517
8518const char* TCling::DataMemberInfo_Name(DataMemberInfo_t* dminfo) const
8519{
8520 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8521 return TClinginfo->Name();
8522}
8523
8524////////////////////////////////////////////////////////////////////////////////
8525
8526const char* TCling::DataMemberInfo_Title(DataMemberInfo_t* dminfo) const
8527{
8528 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8529 return TClinginfo->Title();
8530}
8531
8532////////////////////////////////////////////////////////////////////////////////
8533
8534const char* TCling::DataMemberInfo_ValidArrayIndex(DataMemberInfo_t* dminfo) const
8535{
8536 TTHREAD_TLS_DECL(std::string,result);
8537
8538 TClingDataMemberInfo* TClinginfo = (TClingDataMemberInfo*) dminfo;
8539 result = TClinginfo->ValidArrayIndex().str();
8540 return result.c_str();
8541}
8542
8543////////////////////////////////////////////////////////////////////////////////
8544
8545void TCling::SetDeclAttr(DeclId_t declId, const char* attribute)
8546{
8547 Decl* decl = static_cast<Decl*>(const_cast<void*>(declId));
8548 ASTContext &C = decl->getASTContext();
8549 SourceRange commentRange; // this is a fake comment range
8550 decl->addAttr( new (C) AnnotateAttr( commentRange, C, attribute, 0 ) );
8551}
8552
8553//______________________________________________________________________________
8554//
8555// Function Template interface
8556//
8557
8558////////////////////////////////////////////////////////////////////////////////
8559
8560static void ConstructorName(std::string &name, const clang::Decl *decl,
8561 cling::Interpreter &interp,
8562 const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
8563{
8564 const clang::TypeDecl* td = llvm::dyn_cast<clang::TypeDecl>(decl->getDeclContext());
8565 if (!td) return;
8566
8567 clang::QualType qualType(td->getTypeForDecl(),0);
8568 ROOT::TMetaUtils::GetNormalizedName(name, qualType, interp, normCtxt);
8569 unsigned int level = 0;
8570 for(size_t cursor = name.length()-1; cursor != 0; --cursor) {
8571 if (name[cursor] == '>') ++level;
8572 else if (name[cursor] == '<' && level) --level;
8573 else if (level == 0 && name[cursor] == ':') {
8574 name.erase(0,cursor+1);
8575 break;
8576 }
8577 }
8578}
8579
8580////////////////////////////////////////////////////////////////////////////////
8581
8582void TCling::GetFunctionName(const clang::Decl *decl, std::string &output) const
8583{
8584 output.clear();
8585
8586 const auto *FD = llvm::dyn_cast<clang::FunctionDecl>(decl);
8587 if (const auto *USD = llvm::dyn_cast<clang::UsingShadowDecl>(decl)) {
8588 FD = llvm::dyn_cast<clang::FunctionDecl>(USD->getTargetDecl());
8589 }
8590 if (!FD) {
8591 Error("GetFunctionName", "NULL Decl!");
8592 return;
8593 }
8594
8595 // For using-decls, show "Derived", not "Base", i.e. use the
8596 // name of the decl context of the UsingShadowDecl (aka `decl`)
8597 // not the name of FD's decl context.
8598 if (llvm::isa<clang::CXXConstructorDecl>(FD))
8599 {
8601
8602 } else if (llvm::isa<clang::CXXDestructorDecl>(decl))
8603 {
8605 output.insert(output.begin(), '~');
8606 } else {
8607 llvm::raw_string_ostream stream(output);
8608 auto printPolicy = decl->getASTContext().getPrintingPolicy();
8609 // Don't trigger fopen of the source file to count lines:
8610 printPolicy.AnonymousTagLocations = false;
8611 FD->getNameForDiagnostic(stream, printPolicy, /*Qualified=*/false);
8612 }
8613}
8614
8615////////////////////////////////////////////////////////////////////////////////
8616/// Return a unique identifier of the declaration represented by the
8617/// FuncTempInfo
8618
8620{
8621 return (DeclId_t)info;
8622}
8623
8624////////////////////////////////////////////////////////////////////////////////
8625/// Delete the FuncTempInfo_t
8626
8627void TCling::FuncTempInfo_Delete(FuncTempInfo_t * /* ft_info */) const
8628{
8629 // Currently the address of ft_info is actually the decl itself,
8630 // so we have nothing to do.
8631}
8632
8633////////////////////////////////////////////////////////////////////////////////
8634/// Construct a FuncTempInfo_t
8635
8636FuncTempInfo_t *TCling::FuncTempInfo_Factory(DeclId_t declid) const
8637{
8638 // Currently the address of ft_info is actually the decl itself,
8639 // so we have nothing to do.
8640
8641 return (FuncTempInfo_t*)const_cast<void*>(declid);
8642}
8643
8644////////////////////////////////////////////////////////////////////////////////
8645/// Construct a FuncTempInfo_t
8646
8647FuncTempInfo_t *TCling::FuncTempInfo_FactoryCopy(FuncTempInfo_t *ft_info) const
8648{
8649 // Currently the address of ft_info is actually the decl itself,
8650 // so we have nothing to do.
8651
8652 return (FuncTempInfo_t*)ft_info;
8653}
8654
8655////////////////////////////////////////////////////////////////////////////////
8656/// Check validity of a FuncTempInfo_t
8657
8658Bool_t TCling::FuncTempInfo_IsValid(FuncTempInfo_t *t_info) const
8659{
8660 // Currently the address of ft_info is actually the decl itself,
8661 // so we have nothing to do.
8662
8663 return t_info != 0;
8664}
8665
8666////////////////////////////////////////////////////////////////////////////////
8667/// Return the maximum number of template arguments of the
8668/// function template described by ft_info.
8669
8670UInt_t TCling::FuncTempInfo_TemplateNargs(FuncTempInfo_t *ft_info) const
8671{
8672 if (!ft_info) return 0;
8673 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8674 return ft->getTemplateParameters()->size();
8675}
8676
8677////////////////////////////////////////////////////////////////////////////////
8678/// Return the number of required template arguments of the
8679/// function template described by ft_info.
8680
8682{
8683 if (!ft_info) return 0;
8684 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8685 return ft->getTemplateParameters()->getMinRequiredArguments();
8686}
8687
8688////////////////////////////////////////////////////////////////////////////////
8689/// Return the property of the function template.
8690
8691Long_t TCling::FuncTempInfo_Property(FuncTempInfo_t *ft_info) const
8692{
8693 if (!ft_info) return 0;
8694
8695 long property = 0L;
8696 property |= kIsCompiled;
8697
8698 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8699
8700 switch (ft->getAccess()) {
8701 case clang::AS_public:
8702 property |= kIsPublic;
8703 break;
8704 case clang::AS_protected:
8705 property |= kIsProtected;
8706 break;
8707 case clang::AS_private:
8708 property |= kIsPrivate;
8709 break;
8710 case clang::AS_none:
8711 if (ft->getDeclContext()->isNamespace())
8712 property |= kIsPublic;
8713 break;
8714 default:
8715 // IMPOSSIBLE
8716 break;
8717 }
8718
8719 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8720 if (const clang::CXXMethodDecl *md =
8721 llvm::dyn_cast<clang::CXXMethodDecl>(fd)) {
8722 if (md->getTypeQualifiers() & clang::Qualifiers::Const) {
8723 property |= kIsConstant | kIsConstMethod;
8724 }
8725 if (md->isVirtual()) {
8726 property |= kIsVirtual;
8727 }
8728 if (md->isPure()) {
8729 property |= kIsPureVirtual;
8730 }
8731 if (const clang::CXXConstructorDecl *cd =
8732 llvm::dyn_cast<clang::CXXConstructorDecl>(md)) {
8733 if (cd->isExplicit()) {
8734 property |= kIsExplicit;
8735 }
8736 }
8737 else if (const clang::CXXConversionDecl *cd =
8738 llvm::dyn_cast<clang::CXXConversionDecl>(md)) {
8739 if (cd->isExplicit()) {
8740 property |= kIsExplicit;
8741 }
8742 }
8743 }
8744 return property;
8745}
8746
8747////////////////////////////////////////////////////////////////////////////////
8748/// Return the property not already defined in Property
8749/// See TDictionary's EFunctionProperty
8750
8751Long_t TCling::FuncTempInfo_ExtraProperty(FuncTempInfo_t* ft_info) const
8752{
8753 if (!ft_info) return 0;
8754
8755 long property = 0L;
8756 property |= kIsCompiled;
8757
8758 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8759 const clang::FunctionDecl *fd = ft->getTemplatedDecl();
8760
8761 if (fd->isOverloadedOperator())
8762 property |= kIsOperator;
8763 if (llvm::isa<clang::CXXConversionDecl>(fd))
8764 property |= kIsConversion;
8765 if (llvm::isa<clang::CXXConstructorDecl>(fd))
8766 property |= kIsConstructor;
8767 if (llvm::isa<clang::CXXDestructorDecl>(fd))
8768 property |= kIsDestructor;
8769 if (fd->isInlined())
8770 property |= kIsInlined;
8771 return property;
8772}
8773
8774////////////////////////////////////////////////////////////////////////////////
8775/// Return the name of this function template.
8776
8777void TCling::FuncTempInfo_Name(FuncTempInfo_t *ft_info, TString &output) const
8778{
8779 output.Clear();
8780 if (!ft_info) return;
8781 const clang::FunctionTemplateDecl *ft = (clang::FunctionTemplateDecl*)ft_info;
8782 std::string buf;
8783 GetFunctionName(ft->getTemplatedDecl(), buf);
8784 output = buf;
8785}
8786
8787////////////////////////////////////////////////////////////////////////////////
8788/// Return the comments associates with this function template.
8789
8790void TCling::FuncTempInfo_Title(FuncTempInfo_t *ft_info, TString &output) const
8791{
8792 output.Clear();
8793 if (!ft_info) return;
8794 const clang::FunctionTemplateDecl *ft = (const clang::FunctionTemplateDecl*)ft_info;
8795
8796 // Iterate over the redeclarations, we can have multiple definitions in the
8797 // redecl chain (came from merging of pcms).
8798 if (const RedeclarableTemplateDecl *AnnotFD
8799 = ROOT::TMetaUtils::GetAnnotatedRedeclarable((const RedeclarableTemplateDecl*)ft)) {
8800 if (AnnotateAttr *A = AnnotFD->getAttr<AnnotateAttr>()) {
8801 output = A->getAnnotation().str();
8802 return;
8803 }
8804 }
8805 if (!ft->isFromASTFile()) {
8806 // Try to get the comment from the header file if present
8807 // but not for decls from AST file, where rootcling would have
8808 // created an annotation
8810 }
8811}
8812
8813
8814//______________________________________________________________________________
8815//
8816// MethodInfo interface
8817//
8818
8819////////////////////////////////////////////////////////////////////////////////
8820/// Interface to cling function
8821
8822void TCling::MethodInfo_Delete(MethodInfo_t* minfo) const
8823{
8824 delete(TClingMethodInfo*) minfo;
8825}
8826
8827////////////////////////////////////////////////////////////////////////////////
8828
8829void TCling::MethodInfo_CreateSignature(MethodInfo_t* minfo, TString& signature) const
8830{
8831 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8832 info->CreateSignature(signature);
8833}
8834
8835////////////////////////////////////////////////////////////////////////////////
8836
8837MethodInfo_t* TCling::MethodInfo_Factory() const
8838{
8840 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl());
8841}
8842
8843////////////////////////////////////////////////////////////////////////////////
8844
8845MethodInfo_t* TCling::MethodInfo_Factory(ClassInfo_t* clinfo) const
8846{
8848 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), (TClingClassInfo*)clinfo);
8849}
8850
8851////////////////////////////////////////////////////////////////////////////////
8852
8853MethodInfo_t* TCling::MethodInfo_Factory(DeclId_t declid) const
8854{
8855 const clang::Decl* decl = reinterpret_cast<const clang::Decl*>(declid);
8857 return (MethodInfo_t*) new TClingMethodInfo(GetInterpreterImpl(), decl);
8858}
8859
8860////////////////////////////////////////////////////////////////////////////////
8861
8862MethodInfo_t* TCling::MethodInfo_FactoryCopy(MethodInfo_t* minfo) const
8863{
8864 return (MethodInfo_t*) new TClingMethodInfo(*(TClingMethodInfo*)minfo);
8865}
8866
8867////////////////////////////////////////////////////////////////////////////////
8868
8869void* TCling::MethodInfo_InterfaceMethod(MethodInfo_t* minfo) const
8870{
8871 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8872 return info->InterfaceMethod(*fNormalizedCtxt);
8873}
8874
8875////////////////////////////////////////////////////////////////////////////////
8876
8877bool TCling::MethodInfo_IsValid(MethodInfo_t* minfo) const
8878{
8879 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8880 return info->IsValid();
8881}
8882
8883////////////////////////////////////////////////////////////////////////////////
8884
8885int TCling::MethodInfo_NArg(MethodInfo_t* minfo) const
8886{
8887 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8888 return info->NArg();
8889}
8890
8891////////////////////////////////////////////////////////////////////////////////
8892
8893int TCling::MethodInfo_NDefaultArg(MethodInfo_t* minfo) const
8894{
8895 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8896 return info->NDefaultArg();
8897}
8898
8899////////////////////////////////////////////////////////////////////////////////
8900
8901int TCling::MethodInfo_Next(MethodInfo_t* minfo) const
8902{
8903 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8904 return info->Next();
8905}
8906
8907////////////////////////////////////////////////////////////////////////////////
8908
8909Long_t TCling::MethodInfo_Property(MethodInfo_t* minfo) const
8910{
8911 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8912 return info->Property();
8913}
8914
8915////////////////////////////////////////////////////////////////////////////////
8916
8918{
8919 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8920 return info->ExtraProperty();
8921}
8922
8923////////////////////////////////////////////////////////////////////////////////
8924
8925TypeInfo_t* TCling::MethodInfo_Type(MethodInfo_t* minfo) const
8926{
8927 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8928 return (TypeInfo_t*)info->Type();
8929}
8930
8931////////////////////////////////////////////////////////////////////////////////
8932
8933const char* TCling::MethodInfo_GetMangledName(MethodInfo_t* minfo) const
8934{
8935 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8936 TTHREAD_TLS_DECL(TString, mangled_name);
8937 mangled_name = info->GetMangledName();
8938 return mangled_name;
8939}
8940
8941////////////////////////////////////////////////////////////////////////////////
8942
8943const char* TCling::MethodInfo_GetPrototype(MethodInfo_t* minfo) const
8944{
8945 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8946 return info->GetPrototype();
8947}
8948
8949////////////////////////////////////////////////////////////////////////////////
8950
8951const char* TCling::MethodInfo_Name(MethodInfo_t* minfo) const
8952{
8953 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8954 return info->Name();
8955}
8956
8957////////////////////////////////////////////////////////////////////////////////
8958
8959const char* TCling::MethodInfo_TypeName(MethodInfo_t* minfo) const
8960{
8961 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8962 return info->TypeName();
8963}
8964
8965////////////////////////////////////////////////////////////////////////////////
8966
8967std::string TCling::MethodInfo_TypeNormalizedName(MethodInfo_t* minfo) const
8968{
8969 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8970 if (info && info->IsValid())
8971 return info->Type()->NormalizedName(*fNormalizedCtxt);
8972 else
8973 return "";
8974}
8975
8976////////////////////////////////////////////////////////////////////////////////
8977
8978const char* TCling::MethodInfo_Title(MethodInfo_t* minfo) const
8979{
8980 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
8981 return info->Title();
8982}
8983
8984////////////////////////////////////////////////////////////////////////////////
8985
8987{
8988 if (func) {
8989 return MethodInfo_MethodCallReturnType(func->fInfo);
8990 } else {
8991 return EReturnType::kOther;
8992 }
8993}
8994
8995////////////////////////////////////////////////////////////////////////////////
8996
8998{
8999 TClingMethodInfo* info = (TClingMethodInfo*) minfo;
9000 if (info && info->IsValid()) {
9001 TClingTypeInfo *typeinfo = info->Type();
9002 clang::QualType QT( typeinfo->GetQualType().getCanonicalType() );
9003 if (QT->isEnumeralType()) {
9004 return EReturnType::kLong;
9005 } else if (QT->isPointerType()) {
9006 // Look for char*
9007 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
9008 if ( QT->isCharType() ) {
9009 return EReturnType::kString;
9010 } else {
9011 return EReturnType::kOther;
9012 }
9013 } else if ( QT->isFloatingType() ) {
9014 int sz = typeinfo->Size();
9015 if (sz == 4 || sz == 8) {
9016 // Support only float and double.
9017 return EReturnType::kDouble;
9018 } else {
9019 return EReturnType::kOther;
9020 }
9021 } else if ( QT->isIntegerType() ) {
9022 int sz = typeinfo->Size();
9023 if (sz <= 8) {
9024 // Support only up to long long ... but
9025 // FIXME the TMethodCall::Execute only
9026 // return long (4 bytes) ...
9027 // The v5 implementation of TMethodCall::ReturnType
9028 // was not making the distinction so we let it go
9029 // as is for now, but we really need to upgrade
9030 // TMethodCall::Execute ...
9031 return EReturnType::kLong;
9032 } else {
9033 return EReturnType::kOther;
9034 }
9035 } else {
9036 return EReturnType::kOther;
9037 }
9038 } else {
9039 return EReturnType::kOther;
9040 }
9041}
9042
9043//______________________________________________________________________________
9044//
9045// MethodArgInfo interface
9046//
9047
9048////////////////////////////////////////////////////////////////////////////////
9049
9050void TCling::MethodArgInfo_Delete(MethodArgInfo_t* marginfo) const
9051{
9052 delete(TClingMethodArgInfo*) marginfo;
9053}
9054
9055////////////////////////////////////////////////////////////////////////////////
9056
9057MethodArgInfo_t* TCling::MethodArgInfo_Factory() const
9058{
9060 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl());
9061}
9062
9063////////////////////////////////////////////////////////////////////////////////
9064
9065MethodArgInfo_t* TCling::MethodArgInfo_Factory(MethodInfo_t *minfo) const
9066{
9068 return (MethodArgInfo_t*) new TClingMethodArgInfo(GetInterpreterImpl(), (TClingMethodInfo*)minfo);
9069}
9070
9071////////////////////////////////////////////////////////////////////////////////
9072
9073MethodArgInfo_t* TCling::MethodArgInfo_FactoryCopy(MethodArgInfo_t* marginfo) const
9074{
9075 return (MethodArgInfo_t*)
9077}
9078
9079////////////////////////////////////////////////////////////////////////////////
9080
9081bool TCling::MethodArgInfo_IsValid(MethodArgInfo_t* marginfo) const
9082{
9083 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9084 return info->IsValid();
9085}
9086
9087////////////////////////////////////////////////////////////////////////////////
9088
9089int TCling::MethodArgInfo_Next(MethodArgInfo_t* marginfo) const
9090{
9091 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9092 return info->Next();
9093}
9094
9095////////////////////////////////////////////////////////////////////////////////
9096
9097Long_t TCling::MethodArgInfo_Property(MethodArgInfo_t* marginfo) const
9098{
9099 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9100 return info->Property();
9101}
9102
9103////////////////////////////////////////////////////////////////////////////////
9104
9105const char* TCling::MethodArgInfo_DefaultValue(MethodArgInfo_t* marginfo) const
9106{
9107 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9108 return info->DefaultValue();
9109}
9110
9111////////////////////////////////////////////////////////////////////////////////
9112
9113const char* TCling::MethodArgInfo_Name(MethodArgInfo_t* marginfo) const
9114{
9115 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9116 return info->Name();
9117}
9118
9119////////////////////////////////////////////////////////////////////////////////
9120
9121const char* TCling::MethodArgInfo_TypeName(MethodArgInfo_t* marginfo) const
9122{
9123 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9124 return info->TypeName();
9125}
9126
9127////////////////////////////////////////////////////////////////////////////////
9128
9129std::string TCling::MethodArgInfo_TypeNormalizedName(MethodArgInfo_t* marginfo) const
9130{
9131 TClingMethodArgInfo* info = (TClingMethodArgInfo*) marginfo;
9132 return info->Type()->NormalizedName(*fNormalizedCtxt);
9133}
9134
9135//______________________________________________________________________________
9136//
9137// TypeInfo interface
9138//
9139
9140////////////////////////////////////////////////////////////////////////////////
9141
9142void TCling::TypeInfo_Delete(TypeInfo_t* tinfo) const
9143{
9144 delete (TClingTypeInfo*) tinfo;
9145}
9146
9147////////////////////////////////////////////////////////////////////////////////
9148
9149TypeInfo_t* TCling::TypeInfo_Factory() const
9150{
9152 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl());
9153}
9154
9155////////////////////////////////////////////////////////////////////////////////
9156
9157TypeInfo_t* TCling::TypeInfo_Factory(const char *name) const
9158{
9160 return (TypeInfo_t*) new TClingTypeInfo(GetInterpreterImpl(), name);
9161}
9162
9163////////////////////////////////////////////////////////////////////////////////
9164
9165TypeInfo_t* TCling::TypeInfo_FactoryCopy(TypeInfo_t* tinfo) const
9166{
9167 return (TypeInfo_t*) new TClingTypeInfo(*(TClingTypeInfo*)tinfo);
9168}
9169
9170////////////////////////////////////////////////////////////////////////////////
9171
9172void TCling::TypeInfo_Init(TypeInfo_t* tinfo, const char* name) const
9173{
9175 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9176 TClinginfo->Init(name);
9177}
9178
9179////////////////////////////////////////////////////////////////////////////////
9180
9181bool TCling::TypeInfo_IsValid(TypeInfo_t* tinfo) const
9182{
9183 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9184 return TClinginfo->IsValid();
9185}
9186
9187////////////////////////////////////////////////////////////////////////////////
9188
9189const char* TCling::TypeInfo_Name(TypeInfo_t* tinfo) const
9190{
9191 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9192 return TClinginfo->Name();
9193}
9194
9195////////////////////////////////////////////////////////////////////////////////
9196
9197Long_t TCling::TypeInfo_Property(TypeInfo_t* tinfo) const
9198{
9199 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9200 return TClinginfo->Property();
9201}
9202
9203////////////////////////////////////////////////////////////////////////////////
9204
9205int TCling::TypeInfo_RefType(TypeInfo_t* tinfo) const
9206{
9207 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9208 return TClinginfo->RefType();
9209}
9210
9211////////////////////////////////////////////////////////////////////////////////
9212
9213int TCling::TypeInfo_Size(TypeInfo_t* tinfo) const
9214{
9215 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9216 return TClinginfo->Size();
9217}
9218
9219////////////////////////////////////////////////////////////////////////////////
9220
9221const char* TCling::TypeInfo_TrueName(TypeInfo_t* tinfo) const
9222{
9223 TClingTypeInfo* TClinginfo = (TClingTypeInfo*) tinfo;
9224 return TClinginfo->TrueName(*fNormalizedCtxt);
9225}
9226
9227
9228//______________________________________________________________________________
9229//
9230// TypedefInfo interface
9231//
9232
9233////////////////////////////////////////////////////////////////////////////////
9234
9235void TCling::TypedefInfo_Delete(TypedefInfo_t* tinfo) const
9236{
9237 delete(TClingTypedefInfo*) tinfo;
9238}
9239
9240////////////////////////////////////////////////////////////////////////////////
9241
9242TypedefInfo_t* TCling::TypedefInfo_Factory() const
9243{
9245 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl());
9246}
9247
9248////////////////////////////////////////////////////////////////////////////////
9249
9250TypedefInfo_t* TCling::TypedefInfo_Factory(const char *name) const
9251{
9253 return (TypedefInfo_t*) new TClingTypedefInfo(GetInterpreterImpl(), name);
9254}
9255
9256////////////////////////////////////////////////////////////////////////////////
9257
9258TypedefInfo_t* TCling::TypedefInfo_FactoryCopy(TypedefInfo_t* tinfo) const
9259{
9260 return (TypedefInfo_t*) new TClingTypedefInfo(*(TClingTypedefInfo*)tinfo);
9261}
9262
9263////////////////////////////////////////////////////////////////////////////////
9264
9265void TCling::TypedefInfo_Init(TypedefInfo_t* tinfo,
9266 const char* name) const
9267{
9269 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9270 TClinginfo->Init(name);
9271}
9272
9273////////////////////////////////////////////////////////////////////////////////
9274
9275bool TCling::TypedefInfo_IsValid(TypedefInfo_t* tinfo) const
9276{
9277 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9278 return TClinginfo->IsValid();
9279}
9280
9281////////////////////////////////////////////////////////////////////////////////
9282
9283Int_t TCling::TypedefInfo_Next(TypedefInfo_t* tinfo) const
9284{
9285 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9286 return TClinginfo->Next();
9287}
9288
9289////////////////////////////////////////////////////////////////////////////////
9290
9291Long_t TCling::TypedefInfo_Property(TypedefInfo_t* tinfo) const
9292{
9293 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9294 return TClinginfo->Property();
9295}
9296
9297////////////////////////////////////////////////////////////////////////////////
9298
9299int TCling::TypedefInfo_Size(TypedefInfo_t* tinfo) const
9300{
9301 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9302 return TClinginfo->Size();
9303}
9304
9305////////////////////////////////////////////////////////////////////////////////
9306
9307const char* TCling::TypedefInfo_TrueName(TypedefInfo_t* tinfo) const
9308{
9309 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9310 return TClinginfo->TrueName(*fNormalizedCtxt);
9311}
9312
9313////////////////////////////////////////////////////////////////////////////////
9314
9315const char* TCling::TypedefInfo_Name(TypedefInfo_t* tinfo) const
9316{
9317 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9318 return TClinginfo->Name();
9319}
9320
9321////////////////////////////////////////////////////////////////////////////////
9322
9323const char* TCling::TypedefInfo_Title(TypedefInfo_t* tinfo) const
9324{
9325 TClingTypedefInfo* TClinginfo = (TClingTypedefInfo*) tinfo;
9326 return TClinginfo->Title();
9327}
9328
9329////////////////////////////////////////////////////////////////////////////////
9330
9332{
9333 if (!fInitialMutex.back()) {
9334 if (fInitialMutex.back().fRecurseCount) {
9335 Error("SnapshotMutexState", "fRecurseCount != 0 even though initial mutex state is unset!");
9336 }
9337 fInitialMutex.back().fState = mtx->GetStateBefore();
9338 }
9339 // We will "forget" this lock once we backed out of all interpreter frames.
9340 // Here we are entering one, so ++.
9341 ++fInitialMutex.back().fRecurseCount;
9342}
9343
9344////////////////////////////////////////////////////////////////////////////////
9345
9347{
9348 if (!fInitialMutex.back())
9349 return;
9350 if (fInitialMutex.back().fRecurseCount == 0) {
9351 Error("ForgetMutexState", "mutex state's recurse count already 0!");
9352 }
9353 else if (--fInitialMutex.back().fRecurseCount == 0) {
9354 // We have returned from all interpreter frames. Reset the initial lock state.
9355 fInitialMutex.back().fState.reset();
9356 }
9357}
9358
9359////////////////////////////////////////////////////////////////////////////////
9360/// Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
9361
9363{
9364 R__ASSERT(!fInitialMutex.empty() && "Inconsistent state of fInitialMutex!");
9365 if (gInterpreterMutex) {
9366 if (delta) {
9367 auto typedDelta = static_cast<TVirtualRWMutex::StateDelta *>(delta);
9368 std::unique_ptr<TVirtualRWMutex::StateDelta> uniqueP{typedDelta};
9369 gCoreMutex->Apply(std::move(uniqueP));
9370 }
9371 }
9372 fInitialMutex.pop_back();
9373}
9374
9375////////////////////////////////////////////////////////////////////////////////
9376/// Reset the interpreter lock to the state it had before interpreter-related
9377/// calls happened.
9378
9380{
9381 if (fInitialMutex.back()) {
9382 std::unique_ptr<TVirtualRWMutex::StateDelta> uniqueP = gCoreMutex->Rewind(*fInitialMutex.back().fState);
9383 // Need to start a new recurse count.
9384 fInitialMutex.emplace_back();
9385 return uniqueP.release();
9386 }
9387 // Need to start a new recurse count.
9388 fInitialMutex.emplace_back();
9389 return nullptr;
9390}
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:113
int Int_t
Definition: RtypesCore.h:43
short Version_t
Definition: RtypesCore.h:63
unsigned int UInt_t
Definition: RtypesCore.h:44
const Bool_t kFALSE
Definition: RtypesCore.h:90
unsigned long ULong_t
Definition: RtypesCore.h:53
long Long_t
Definition: RtypesCore.h:52
bool Bool_t
Definition: RtypesCore.h:61
double Double_t
Definition: RtypesCore.h:57
R__EXTERN Int_t gDebug
Definition: RtypesCore.h:117
long long Long64_t
Definition: RtypesCore.h:71
unsigned long long ULong64_t
Definition: RtypesCore.h:72
const Bool_t kTRUE
Definition: RtypesCore.h:89
TClass *(* DictFuncPtr_t)()
Definition: Rtypes.h:78
R__EXTERN TApplication * gApplication
Definition: TApplication.h:166
R__EXTERN TClassTable * gClassTable
Definition: TClassTable.h:94
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:5299
void TCling__RestoreInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition: TCling.cxx:345
void * llvmLazyFunctionCreator(const std::string &mangled_name)
Autoload a library provided the mangled name of a missing symbol.
Definition: TCling.cxx:700
void TCling__TransactionRollback(const cling::Transaction &T)
Definition: TCling.cxx:583
static void RegisterPreIncludedHeaders(cling::Interpreter &clingInterp)
Definition: TCling.cxx:1262
static bool hasParsedRootmapForLibrary(llvm::StringRef lib)
Definition: TCling.cxx:7099
static std::string GetClassSharedLibsForModule(const char *cls, cling::LookupHelper &LH)
Definition: TCling.cxx:6853
void TCling__InvalidateGlobal(const clang::Decl *D)
Definition: TCling.cxx:578
bool TClingLookupHelper__AutoParse(const char *cname)
Allow calling autoparsing from TMetaUtils.
Definition: TCling.cxx:912
R__EXTERN int optind
Definition: TCling.cxx:329
void * TCling__LockCompilationDuringUserCodeExecution()
Lock the interpreter.
Definition: TCling.cxx:372
void TCling__UpdateListsOnUnloaded(const cling::Transaction &T)
Definition: TCling.cxx:573
void TCling__GetNormalizedContext(const ROOT::TMetaUtils::TNormalizedCtxt *&normCtxt)
Definition: TCling.cxx:561
R__DLLEXPORT clang::DeclContext * TCling__DEBUG__getDeclContext(clang::Decl *D)
Definition: TCling.cxx:227
ETupleOrdering
Check in what order the member of a tuple are layout.
Definition: TCling.cxx:3721
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:355
static const std::unordered_set< std::string > gIgnoredPCMNames
List of dicts that have the PCM information already in the PCH.
Definition: TCling.cxx:1881
static Bool_t s_IsLibraryLoaded(const char *libname, cling::Interpreter *fInterpreter)
Definition: TCling.cxx:2993
static std::string AlternateTuple(const char *classname, const cling::LookupHelper &lh)
Definition: TCling.cxx:3763
R__DLLEXPORT void TCling__DEBUG__printName(clang::Decl *D)
Definition: TCling.cxx:248
R__DLLEXPORT void TCling__DEBUG__decl_dump(void *D)
Definition: TCling.cxx:245
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:921
static bool HasASTFileOnDisk(clang::Module *M, const clang::Preprocessor &PP, std::string *FullFileName=nullptr)
Checks if there is an ASTFile on disk for the given module M.
Definition: TCling.cxx:1085
R__DLLEXPORT clang::NamespaceDecl * TCling__DEBUG__DCtoNamespace(clang::DeclContext *DC)
Definition: TCling.cxx:230
void TCling__UnlockCompilationDuringUserCodeExecution(void *)
Unlock the interpreter.
Definition: TCling.cxx:383
const char * TCling__GetClassSharedLibs(const char *className)
Definition: TCling.cxx:636
R__DLLEXPORT clang::RecordDecl * TCling__DEBUG__DCtoRecordDecl(clang::DeclContext *DC)
Definition: TCling.cxx:233
static bool R__InitStreamerInfoFactory()
Helper to initialize TVirtualStreamerInfo's factor early.
Definition: TCling.cxx:1608
int TCling__AutoParseCallback(const char *className)
Definition: TCling.cxx:631
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:710
R__DLLEXPORT bool TCling__TEST_isInvalidDecl(clang::Decl *D)
Definition: TCling.cxx:263
static bool HaveFullGlobalModuleIndex
Definition: TCling.cxx:1099
R__DLLEXPORT void DestroyInterpreter(TInterpreter *interp)
Definition: TCling.cxx:619
void TCling__LibraryUnloadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition: TCling.cxx:597
void TCling__UpdateListsOnCommitted(const cling::Transaction &T, cling::Interpreter *)
Definition: TCling.cxx:568
const Decl * TCling__GetObjectDecl(TObject *obj)
Definition: TCling.cxx:608
static ETupleOrdering IsTupleAscending()
Definition: TCling.cxx:3739
R__DLLEXPORT TInterpreter * CreateInterpreter(void *interpLibHandle, const char *argv[])
Definition: TCling.cxx:612
void TCling__RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Definition: TCling.cxx:592
R__DLLEXPORT void TCling__DEBUG__dump(clang::DeclContext *DC)
Definition: TCling.cxx:236
static void TCling__UpdateClassInfo(const NamedDecl *TD)
Update TClingClassInfo for a class (e.g. upon seeing a definition).
Definition: TCling.cxx:393
int TCling__CompileMacro(const char *fileName, const char *options)
Definition: TCling.cxx:647
#define R__DLLEXPORT
Definition: TCling.cxx:147
void * TCling__ResetInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition: TCling.cxx:364
static void * LazyFunctionCreatorAutoloadForModule(const std::string &mangled_name, const cling::DynamicLibraryManager &DLM)
Definition: TCling.cxx:6351
int TCling__AutoLoadCallback(const char *className)
Definition: TCling.cxx:626
static bool LoadModule(const std::string &ModuleName, cling::Interpreter &interp)
Definition: TCling.cxx:1050
static void RegisterCxxModules(cling::Interpreter &clingInterp)
Definition: TCling.cxx:1141
static bool IsFromRootCling()
Definition: TCling.cxx:1078
static void ConstructorName(std::string &name, const clang::Decl *decl, cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
Definition: TCling.cxx:8560
void TCling__PrintStackTrace()
Print a StackTrace!
Definition: TCling.cxx:338
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:2340
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:7010
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:683
static void PrintDlError(const char *dyLibName, const char *modulename)
Definition: TCling.cxx:1905
const char * fantomline
Definition: TCling.cxx:859
void TCling__LibraryLoadedRTTI(const void *dyLibHandle, const char *canonicalName)
Definition: TCling.cxx:587
static cling::Interpreter::CompilationResult ExecAutoParse(const char *what, Bool_t header, cling::Interpreter *interpreter)
Parse the payload or header.
Definition: TCling.cxx:6095
static GlobalModuleIndex * loadGlobalModuleIndex(SourceLocation TriggerLoc, cling::Interpreter &interp)
Definition: TCling.cxx:1100
TObject * TCling__GetObjectAddress(const char *Name, void *&LookupCtx)
Definition: TCling.cxx:604
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:1072
int TCling__IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition: TCling.cxx:642
static bool hasPrecomputedLibraryDeps(llvm::StringRef lib)
Definition: TCling.cxx:7120
void TCling__SplitAclicMode(const char *fileName, string &mode, string &args, string &io, string &fname)
Definition: TCling.cxx:654
EDataType
Definition: TDataType.h:28
@ kULong64_t
Definition: TDataType.h:32
@ kLong64_t
Definition: TDataType.h:32
@ kIsDestructor
Definition: TDictionary.h:129
@ kIsConversion
Definition: TDictionary.h:128
@ kIsInlined
Definition: TDictionary.h:131
@ kIsConstructor
Definition: TDictionary.h:127
@ kIsOperator
Definition: TDictionary.h:130
@ kIsPublic
Definition: TDictionary.h:75
@ kIsConstant
Definition: TDictionary.h:88
@ kIsConstMethod
Definition: TDictionary.h:96
@ kIsClass
Definition: TDictionary.h:65
@ kIsEnum
Definition: TDictionary.h:68
@ kIsPrivate
Definition: TDictionary.h:77
@ kIsFundamental
Definition: TDictionary.h:70
@ kIsCompiled
Definition: TDictionary.h:86
@ kIsStatic
Definition: TDictionary.h:80
@ kIsExplicit
Definition: TDictionary.h:94
@ kIsStruct
Definition: TDictionary.h:66
@ kIsProtected
Definition: TDictionary.h:76
@ kIsVirtual
Definition: TDictionary.h:72
@ kIsUnion
Definition: TDictionary.h:67
@ kIsPureVirtual
Definition: TDictionary.h:73
@ kIsNamespace
Definition: TDictionary.h:95
#define gDirectory
Definition: TDirectory.h:229
@ 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:41
#define R__LOCKGUARD_CLING(mutex)
Definition: TInterpreter.h:48
R__EXTERN TInterpreter * gCling
Definition: TInterpreter.h:557
#define gInterpreter
Definition: TInterpreter.h:556
#define gROOT
Definition: TROOT.h:406
char * Form(const char *fmt,...)
typedef void((*Func_t)())
@ kReadPermission
Definition: TSystem.h:46
Bool_t R_ISREG(Int_t mode)
Definition: TSystem.h:117
R__EXTERN TSystem * gSystem
Definition: TSystem.h:556
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
void AddTemplAndNargsToKeep(const clang::ClassTemplateDecl *templ, unsigned int i)
const Config_t & GetConfig() const
virtual std::unique_ptr< StateDelta > Rewind(const State &earlierState)=0
virtual void Apply(std::unique_ptr< StateDelta > &&delta)=0
virtual std::unique_ptr< State > GetStateBefore()=0
static 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:28
static DictFuncPtr_t GetDict(const char *cname)
Given the class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProtoNorm(const char *cname)
Given the class normalized name returns the TClassProto object for the class.
static DictFuncPtr_t GetDictNorm(const char *cname)
Given the normalized class name returns the Dictionary() function of a class (uses hash of name).
static TProtoClass * GetProto(const char *cname)
Given the class name returns the TClassProto object for the class.
static Bool_t Check(const char *cname, std::string &normname)
static void Add(const char *cname, Version_t id, const std::type_info &info, DictFuncPtr_t dict, Int_t pragmabits)
Add a class to the class table (this is a static function).
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:80
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
Definition: TClass.cxx:3407
EState GetState() const
Definition: TClass.h:485
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition: TClass.cxx:2866
EState fState
cached of the streaming method to use
Definition: TClass.h:274
std::atomic< TList * > fBase
Definition: TClass.h:201
static void AddClassToDeclIdMap(TDictionary::DeclId_t id, TClass *cl)
static: Add a TClass* to the map of classes.
Definition: TClass.cxx:509
Version_t fClassVersion
Definition: TClass.h:221
TList * GetListOfFunctionTemplates(Bool_t load=kTRUE)
Return list containing the TEnums of a class.
Definition: TClass.cxx:3766
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:4878
static void RemoveClassDeclId(TDictionary::DeclId_t id)
Definition: TClass.cxx:534
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:2185
std::atomic< TListOfEnums * > fEnums
Definition: TClass.h:205
static Bool_t HasNoInfoOrEmuOrFwdDeclaredDecl(const char *)
Definition: TClass.cxx:3366
virtual void PostLoadCheck()
Do the initialization that can only be done after the CINT dictionary has been fully populated and ca...
Definition: TClass.cxx:5922
static TClass * LoadClass(const char *requestedname, Bool_t silent)
Helper function used by TClass::GetClass().
Definition: TClass.cxx:5712
Int_t Size() const
Return size of object of this class.
Definition: TClass.cxx:5667
@ kLoading
Definition: TClass.h:330
@ kUnloading
Definition: TClass.h:330
TObjArray * fStreamerInfo
Definition: TClass.h:198
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition: TClass.cxx:5875
ClassInfo_t * GetClassInfo() const
Definition: TClass.h:430
ClassInfo_t * fClassInfo
Definition: TClass.h:222
Long_t Property() const
Returns the properties of the TClass as a bit field stored as a Long_t value.
Definition: TClass.cxx:6010
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition: TClass.cxx:2877
void ResetCaches()
To clean out all caches.
Definition: TClass.cxx:4178
static Int_t ReadRules()
Read the class.rules files from the default location:.
Definition: TClass.cxx:1800
@ kInterpreted
Definition: TClass.h:126
@ kHasTClassInit
Definition: TClass.h:127
@ kEmulated
Definition: TClass.h:125
@ kForwardDeclared
Definition: TClass.h:124
@ kNamespaceForMeta
Definition: TClass.h:131
Version_t GetClassVersion() const
Definition: TClass.h:417
std::atomic< Bool_t > fHasRootPcmInfo
C++ Property of the class (is abstract, has virtual table, etc.)
Definition: TClass.h:256
const char * GetDeclFileName() const
Return name of the file containing the declaration of this class.
Definition: TClass.cxx:3431
@ kIsTObject
Definition: TClass.h:99
@ kIsEmulation
Definition: TClass.h:101
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:2948
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
bool IsAutoLoadingEnabled()
void SetAutoParsingSuspended(bool val=true)
void SetAutoLoadingEnabled(bool val=true)
Emulation of the CINT ClassInfo class.
const char * Title()
static bool IsEnum(cling::Interpreter *interp, const char *name)
long ClassProperty() const
void Init(const char *name)
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
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
ROOT::TMetaUtils::EIOCtorCategory HasDefaultConstructor(bool checkio=false, std::string *type_name=nullptr) 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
int MaxIndex(int dim) const
llvm::StringRef ValidArrayIndex() const
const char * Name() const override
virtual const char * Name() const
virtual bool IsValid() const
virtual const clang::Decl * GetDecl() const
Emulation of the CINT MethodInfo class.
bool IsValid() const override
const char * DefaultValue() const
const TClingTypeInfo * Type() const
const char * TypeName() const
Emulation of the CINT MethodInfo class.
std::string GetMangledName() const
const char * TypeName() const
const char * Name() const override
void * InterfaceMethod(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
const clang::FunctionDecl * GetTargetFunctionDecl() const
Get the FunctionDecl, or if this represents a UsingShadowDecl, the underlying target FunctionDecl.
const char * GetPrototype()
long ExtraProperty() const
void CreateSignature(TString &signature) const
const char * Title()
TDictionary::DeclId_t GetDeclId() const
TClingTypeInfo * Type() const
Emulation of the CINT TypeInfo class.
long Property() const
std::string NormalizedName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
const char * Name() const override
int Size() const
int RefType() const
bool IsValid() const override
clang::QualType GetQualType() const
void Init(const char *name)
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Return the normalized name of the type (i.e.
Emulation of the CINT TypedefInfo class.
const char * TrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Get the name of the underlying type of the current typedef.
long Property() const
Return a bit mask of metadata about the current typedef.
const char * Name() const override
Get the name of the current typedef.
void Init(const char *name)
Lookup named typedef and reset the iterator to point to it.
int Next()
Increment the iterator.
int Size() const
Return the size in bytes of the underlying type of the current typedef.
Bridge between cling::Value and ROOT.
Definition: TClingValue.h:34
const char * Data()
Definition: TCling.cxx:1026
bool Append(const std::string &str)
Append string to the storage if not added already.
Definition: TCling.cxx:1034
std::string fContent
Definition: TCling.h:595
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:9105
virtual std::string CallFunc_GetWrapperCode(CallFunc_t *func) const
Definition: TCling.cxx:7932
virtual void FuncTempInfo_Name(FuncTempInfo_t *, TString &name) const
Return the name of this function template.
Definition: TCling.cxx:8777
virtual void FuncTempInfo_Title(FuncTempInfo_t *, TString &name) const
Return the comments associates with this function template.
Definition: TCling.cxx:8790
virtual int TypedefInfo_Next(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:9283
virtual bool DiagnoseIfInterpreterException(const std::exception &e) const
Definition: TCling.cxx:2359
virtual bool ClassInfo_IsValid(ClassInfo_t *info) const
Definition: TCling.cxx:8148
virtual bool ClassInfo_IsScopedEnum(ClassInfo_t *info) const
Definition: TCling.cxx:8122
Long_t Calc(const char *line, EErrorCode *error=0)
Directly execute an executable statement (e.g.
Definition: TCling.cxx:3411
Bool_t HasPCMForLibrary(const char *libname) const
Return true if ROOT has cxxmodules pcm for a given library name.
Definition: TCling.cxx:3011
virtual MethodInfo_t * MethodInfo_FactoryCopy(MethodInfo_t *minfo) const
Definition: TCling.cxx:8862
virtual const char * TypeInfo_Name(TypeInfo_t *) const
Definition: TCling.cxx:9189
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:4808
bool LibraryLoadingFailed(const std::string &, const std::string &, bool, bool)
Definition: TCling.cxx:6331
void ForgetMutexState()
Definition: TCling.cxx:9346
virtual bool ClassInfo_HasMethod(ClassInfo_t *info, const char *name) const
Definition: TCling.cxx:8081
std::vector< void * > fRegisterModuleDyLibs
Definition: TCling.h:136
virtual MethodInfo_t * CallFunc_FactoryMethod(CallFunc_t *func) const
Definition: TCling.cxx:7744
virtual bool MethodInfo_IsValid(MethodInfo_t *minfo) const
Definition: TCling.cxx:8877
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:8510
void CreateListOfDataMembers(TClass *cl) const
Create list of pointers to data members for TClass cl.
Definition: TCling.cxx:4273
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:2310
void HandleNewDecl(const void *DV, bool isDeserialized, std::set< TClass * > &modifiedClasses)
Definition: TCling.cxx:500
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:6748
virtual const char * MethodInfo_TypeName(MethodInfo_t *minfo) const
Definition: TCling.cxx:8959
bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const
Definition: TCling.cxx:1843
virtual Long_t TypedefInfo_Property(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:9291
virtual void MethodArgInfo_Delete(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:9050
virtual void LoadFunctionTemplates(TClass *cl) const
Create list of pointers to function templates for TClass cl.
Definition: TCling.cxx:4226
virtual CallFunc_t * CallFunc_Factory() const
Definition: TCling.cxx:7729
virtual TypedefInfo_t * TypedefInfo_FactoryCopy(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:9258
std::vector< const char * > fCurExecutingMacros
Definition: TCling.h:147
void UpdateListsOnCommitted(const cling::Transaction &T)
Definition: TCling.cxx:6622
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:7390
virtual Long_t ClassInfo_Tagnum(ClassInfo_t *info) const
Definition: TCling.cxx:8228
void UpdateListOfTypes()
No op: see TClingCallbacks (used to update the list of types)
Definition: TCling.cxx:3715
const char * GetSharedLibDeps(const char *lib, bool tryDyld=false)
Get the list a libraries on which the specified lib depends.
Definition: TCling.cxx:7136
virtual DeclId_t GetDataMemberAtAddr(const void *addr) const
Return pointer to cling DeclId for a data member with a given name.
Definition: TCling.cxx:4729
virtual int DataMemberInfo_ArrayDim(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8404
virtual bool ClassInfo_IsBase(ClassInfo_t *info, const char *name) const
Definition: TCling.cxx:8107
virtual int BaseClassInfo_Next(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:8312
virtual void GenericError(const char *error) const
Let the interpreter issue a generic error, and set its error state.
Definition: TCling.cxx:7303
virtual std::string MethodArgInfo_TypeNormalizedName(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:9129
virtual const char * ClassInfo_TmpltName(ClassInfo_t *info) const
Definition: TCling.cxx:8270
virtual TEnum * CreateEnum(void *VD, TClass *cl) const
Definition: TCling.cxx:473
virtual EReturnType MethodCallReturnType(TFunction *func) const
Definition: TCling.cxx:8986
virtual int UnloadFile(const char *path) const
Definition: TCling.cxx:7470
virtual int Evaluate(const char *, TInterpreterValue &)
Get the interpreter value corresponding to the statement.
Definition: TCling.cxx:7498
TObject * GetObjectAddress(const char *Name, void *&LookupCtx)
If the interpreter encounters Name, check whether that is an object ROOT could retrieve.
Definition: TCling.cxx:7534
virtual Long_t TypeInfo_Property(TypeInfo_t *tinfo) const
Definition: TCling.cxx:9197
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:4934
bool IsClassAutoLoadingEnabled() const
Returns if class AutoLoading is currently enabled.
Definition: TCling.cxx:7398
void InvalidateGlobal(const clang::Decl *D)
Invalidate cached TCling information for the given global declaration.
Definition: TCling.cxx:6733
void EndOfLineAction()
It calls a "fantom" method to synchronize user keyboard input and ROOT prompt line.
Definition: TCling.cxx:2985
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:4912
void UpdateListOfLoadedSharedLibraries()
Definition: TCling.cxx:3198
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:1951
virtual const char * DataMemberInfo_ValidArrayIndex(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8534
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:5436
void CreateListOfMethodArgs(TFunction *m) const
Create list of pointers to method arguments for TMethod m.
Definition: TCling.cxx:4307
virtual void TypedefInfo_Init(TypedefInfo_t *tinfo, const char *name) const
Definition: TCling.cxx:9265
virtual Long_t MethodInfo_ExtraProperty(MethodInfo_t *minfo) const
Definition: TCling.cxx:8917
void LoadPCM(std::string pcmFileNameFullPath)
Tries to load a rdict PCM, issues diagnostics if it fails.
Definition: TCling.cxx:1755
virtual ~TCling()
Destroy the interpreter interface.
Definition: TCling.cxx:1562
void AddFriendToClass(clang::FunctionDecl *, clang::CXXRecordDecl *) const
Inject function as a friend into klass.
Definition: TCling.cxx:7587
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:6495
void ExecuteWithArgsAndReturn(TMethod *method, void *address, const void *args[]=0, int nargs=0, void *ret=0) const
Definition: TCling.cxx:5164
virtual void FuncTempInfo_Delete(FuncTempInfo_t *) const
Delete the FuncTempInfo_t.
Definition: TCling.cxx:8627
Bool_t SetSuspendAutoParsing(Bool_t value)
Suspend the Autoparsing of headers.
Definition: TCling.cxx:7440
virtual DataMemberInfo_t * DataMemberInfo_FactoryCopy(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8438
virtual CallFuncIFacePtr_t CallFunc_IFacePtr(CallFunc_t *func) const
Definition: TCling.cxx:7778
virtual void CallFunc_ExecWithReturn(CallFunc_t *func, void *address, void *ret) const
Definition: TCling.cxx:7686
virtual MethodArgInfo_t * MethodArgInfo_Factory() const
Definition: TCling.cxx:9057
virtual void DataMemberInfo_Delete(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8412
void ApplyToInterpreterMutex(void *delta)
Re-apply the lock count delta that TCling__ResetInterpreterMutex() caused.
Definition: TCling.cxx:9362
void * LazyFunctionCreatorAutoload(const std::string &mangled_name)
Autoload a library based on a missing symbol.
Definition: TCling.cxx:6392
virtual int LoadFile(const char *path) const
Load a source file or library called path into the interpreter.
Definition: TCling.cxx:7346
void CodeComplete(const std::string &, size_t &, std::vector< std::string > &)
The call to Cling's tab complition.
Definition: TCling.cxx:7490
virtual Long_t FuncTempInfo_Property(FuncTempInfo_t *) const
Return the property of the function template.
Definition: TCling.cxx:8691
virtual TypeInfo_t * MethodInfo_Type(MethodInfo_t *minfo) const
Definition: TCling.cxx:8925
virtual const char * MethodArgInfo_TypeName(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:9121
Bool_t HandleNewTransaction(const cling::Transaction &T)
Helper function to increase the internal Cling count of transactions that change the AST.
Definition: TCling.cxx:3481
virtual bool ClassInfo_HasDefaultConstructor(ClassInfo_t *info, Bool_t testio=kFALSE) const
Definition: TCling.cxx:8073
virtual bool DataMemberInfo_IsValid(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8446
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:5315
Bool_t IsLoaded(const char *filename) const
Return true if the file has already been loaded by cint.
Definition: TCling.cxx:3036
const char * GetSharedLibs()
Return the list of shared libraries loaded into the process.
Definition: TCling.cxx:6846
virtual const char * GetTopLevelMacroName() const
Return the file name of the current un-included interpreted file.
Definition: TCling.cxx:5195
std::map< SpecialObjectLookupCtx_t, SpecialObjectMap_t > fSpecialObjectMaps
Definition: TCling.h:151
virtual DeclId_t GetDataMemberWithValue(const void *ptrvalue) const
NOT IMPLEMENTED.
Definition: TCling.cxx:4720
virtual bool MethodArgInfo_IsValid(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:9081
Int_t ReloadAllSharedLibraryMaps()
Reload the library map entries coming from all the loaded shared libraries, after first unloading the...
Definition: TCling.cxx:5703
virtual void SetErrmsgcallback(void *p) const
Set a callback to receive error messages.
Definition: TCling.cxx:7450
virtual std::string ToString(const char *type, void *obj)
Definition: TCling.cxx:1043
virtual const char * MethodInfo_Title(MethodInfo_t *minfo) const
Definition: TCling.cxx:8978
virtual Long_t ClassInfo_GetBaseOffset(ClassInfo_t *fromDerived, ClassInfo_t *toBase, void *address, bool isDerivedObject) const
Definition: TCling.cxx:8336
virtual int DataMemberInfo_TypeSize(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8494
virtual ClassInfo_t * ClassInfo_Factory(Bool_t all=kTRUE) const
Definition: TCling.cxx:8035
virtual const char * MethodInfo_GetMangledName(MethodInfo_t *minfo) const
Definition: TCling.cxx:8933
virtual bool CallFunc_IsValid(CallFunc_t *func) const
Definition: TCling.cxx:7769
virtual const char * BaseClassInfo_TmpltName(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:8391
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:7380
virtual void MethodInfo_CreateSignature(MethodInfo_t *minfo, TString &signature) const
Definition: TCling.cxx:8829
void SnapshotMutexState(ROOT::TVirtualRWMutex *mtx)
Definition: TCling.cxx:9331
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:7951
std::set< size_t > fPayloads
Definition: TCling.h:120
virtual const char * ClassInfo_Name(ClassInfo_t *info) const
Definition: TCling.cxx:8254
Int_t UnloadLibraryMap(const char *library)
Unload library map entries coming from the specified library.
Definition: TCling.cxx:5782
virtual ClassInfo_t * BaseClassInfo_ClassInfo(BaseClassInfo_t *) const
Definition: TCling.cxx:8357
TObjArray * fRootmapFiles
Definition: TCling.h:124
virtual void CallFunc_Delete(CallFunc_t *func) const
Definition: TCling.cxx:7663
virtual Long_t ClassInfo_ClassProperty(ClassInfo_t *info) const
Definition: TCling.cxx:7996
cling::Interpreter * GetInterpreterImpl() const
Definition: TCling.h:622
virtual bool ClassInfo_IsLoaded(ClassInfo_t *info) const
Definition: TCling.cxx:8140
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:8065
Int_t DeleteGlobal(void *obj)
Delete obj from Cling symbol table so it cannot be accessed anymore.
Definition: TCling.cxx:3599
virtual const char * GetCurrentMacroName() const
Return the file name of the currently interpreted file, included or not.
Definition: TCling.cxx:5242
virtual void TypeInfo_Delete(TypeInfo_t *tinfo) const
Definition: TCling.cxx:9142
virtual Bool_t LoadText(const char *text) const
Load the declarations from text into the interpreter.
Definition: TCling.cxx:7359
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:4979
void * RewindInterpreterMutex()
Reset the interpreter lock to the state it had before interpreter-related calls happened.
Definition: TCling.cxx:9379
virtual Long_t BaseClassInfo_Offset(BaseClassInfo_t *toBaseClassInfo, void *address, bool isDerivedObject) const
Definition: TCling.cxx:8328
static Int_t DeepAutoLoadImpl(const char *cls)
Definition: TCling.cxx:5968
virtual int GetSecurityError() const
Interface to cling function.
Definition: TCling.cxx:7333
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:8681
void ResetGlobals()
Reset in Cling the list of global variables to the state saved by the last call to TCling::SaveGlobal...
Definition: TCling.cxx:3556
virtual const char * ClassInfo_Title(ClassInfo_t *info) const
Definition: TCling.cxx:8262
virtual Long_t BaseClassInfo_Property(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:8349
virtual FuncTempInfo_t * FuncTempInfo_Factory(DeclId_t declid) const
Construct a FuncTempInfo_t.
Definition: TCling.cxx:8636
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:4786
virtual void ClassInfo_Destruct(ClassInfo_t *info, void *arena) const
Definition: TCling.cxx:8027
virtual const char * BaseClassInfo_FullName(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:8373
virtual bool ClassInfo_IsEnum(const char *name) const
Definition: TCling.cxx:8115
virtual DataMemberInfo_t * DataMemberInfo_Factory(ClassInfo_t *clinfo, TDictionary::EMemberSelection selection) const
Definition: TCling.cxx:8419
Long_t ProcessLine(const char *line, EErrorCode *error=0)
Definition: TCling.cxx:2370
virtual void TypedefInfo_Delete(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:9235
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:3464
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:3585
TString fSharedLibs
Definition: TCling.h:111
std::map< std::string, llvm::StringRef > fPendingRdicts
Definition: TCling.h:612
virtual const char * MapCppName(const char *) const
Interface to cling function.
Definition: TCling.cxx:7367
static void UpdateClassInfoWork(const char *name)
Definition: TCling.cxx:6602
virtual Long_t FuncTempInfo_ExtraProperty(FuncTempInfo_t *) const
Return the property not already defined in Property See TDictionary's EFunctionProperty.
Definition: TCling.cxx:8751
void PrintIntro()
No-op; see TRint instead.
Definition: TCling.cxx:2534
virtual CallFunc_t * CallFunc_FactoryCopy(CallFunc_t *func) const
Definition: TCling.cxx:7737
virtual const char * DataMemberInfo_Name(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8518
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:2962
Int_t DeleteVariable(const char *name)
Undeclare obj called name.
Definition: TCling.cxx:3614
virtual int ClassInfo_Next(ClassInfo_t *info) const
Definition: TCling.cxx:8172
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:2543
virtual void CallFunc_SetArgArray(CallFunc_t *func, Long_t *paramArr, Int_t nparam) const
Definition: TCling.cxx:7842
virtual const char * MethodInfo_Name(MethodInfo_t *minfo) const
Definition: TCling.cxx:8951
void ClearFileBusy()
Reset the interpreter internal state in case a previous action was not correctly terminated.
Definition: TCling.cxx:2941
virtual const char * MethodArgInfo_Name(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:9113
virtual Long_t ClassInfo_Property(ClassInfo_t *info) const
Definition: TCling.cxx:8212
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:8901
const char * TypeName(const char *typeDesc)
Return the absolute type of typeDesc.
Definition: TCling.cxx:5257
bool fIsShuttingDown
Definition: TCling.h:178
void SaveContext()
Save the current Cling state.
Definition: TCling.cxx:3675
std::set< TClass * > & GetModTClasses()
Definition: TCling.h:555
virtual bool TypeInfo_IsValid(TypeInfo_t *tinfo) const
Definition: TCling.cxx:9181
Int_t AutoLoad(const char *classname, Bool_t knowDictNotLoaded=kFALSE)
Load library containing the specified class.
Definition: TCling.cxx:6029
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:4768
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:2301
virtual Long_t DataMemberInfo_Property(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8478
void UpdateListOfGlobalFunctions()
No op: see TClingCallbacks (used to update the list of global functions)
Definition: TCling.cxx:3708
virtual const char * MethodInfo_GetPrototype(MethodInfo_t *minfo) const
Definition: TCling.cxx:8943
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:8156
virtual void * ClassInfo_New(ClassInfo_t *info) const
Definition: TCling.cxx:8180
virtual void TypeInfo_Init(TypeInfo_t *tinfo, const char *funcname) const
Definition: TCling.cxx:9172
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:7203
virtual const char * DataMemberInfo_Title(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8526
void TransactionRollback(const cling::Transaction &T)
Definition: TCling.cxx:6808
virtual EDataType ClassInfo_GetUnderlyingType(ClassInfo_t *info) const
Definition: TCling.cxx:8131
virtual void CallFunc_Init(CallFunc_t *func) const
Definition: TCling.cxx:7760
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:8670
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:4741
virtual void SetTempLevel(int val) const
Create / close a scope for temporaries.
Definition: TCling.cxx:7464
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:4551
void RegisterTemporary(const TInterpreterValue &value)
Definition: TCling.cxx:7507
virtual void LoadEnums(TListOfEnums &cl) const
Create list of pointers to enums for TClass cl.
Definition: TCling.cxx:4179
virtual void CallFunc_SetArg(CallFunc_t *func, Long_t param) const
Definition: TCling.cxx:7794
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:7325
virtual void * MethodInfo_InterfaceMethod(MethodInfo_t *minfo) const
Definition: TCling.cxx:8869
Int_t UnloadAllSharedLibraryMaps()
Unload the library map entries coming from all the loaded shared libraries.
Definition: TCling.cxx:5764
virtual void CallFunc_IgnoreExtraArgs(CallFunc_t *func, bool ignore) const
Definition: TCling.cxx:7752
std::vector< cling::Value > * fTemporaries
Definition: TCling.h:131
virtual Long_t MethodInfo_Property(MethodInfo_t *minfo) const
Definition: TCling.cxx:8909
virtual std::unique_ptr< TInterpreterValue > MakeInterpreterValue() const
Definition: TCling.cxx:7483
virtual Long_t DataMemberInfo_Offset(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8470
static Int_t ShallowAutoLoadImpl(const char *cls)
Definition: TCling.cxx:5922
void LibraryLoaded(const void *dyLibHandle, const char *canonicalName)
Definition: TCling.cxx:6831
virtual TypedefInfo_t * TypedefInfo_Factory() const
Definition: TCling.cxx:9242
void UpdateListOfGlobals()
No op: see TClingCallbacks (used to update the list of globals)
Definition: TCling.cxx:3701
void ClearStack()
Delete existing temporary values.
Definition: TCling.cxx:2949
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:7429
Bool_t fHeaderParsingOnDemand
Definition: TCling.h:172
virtual int SetClassAutoLoading(int) const
Enable/Disable the AutoLoading of libraries.
Definition: TCling.cxx:7411
Int_t RescanLibraryMap()
Scan again along the dynamic path for library maps.
Definition: TCling.cxx:5691
virtual int DataMemberInfo_Next(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8462
void Reset()
Pressing Ctrl+C should forward here.
Definition: TCling.cxx:3524
Int_t Load(const char *filenam, Bool_t system=kFALSE)
Load a library file in cling's memory.
Definition: TCling.cxx:3341
void InspectMembers(TMemberInspector &, const void *obj, const TClass *cl, Bool_t isTransient)
Visit all members over members, recursing over base classes.
Definition: TCling.cxx:2557
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:7217
static void RemoveAndInvalidateObject(List &L, Object *O)
Definition: TCling.h:567
virtual void ClassInfo_DeleteArray(ClassInfo_t *info, void *arena, bool dtorOnly) const
Definition: TCling.cxx:8019
virtual void GetFunctionName(const clang::Decl *decl, std::string &name) const
Definition: TCling.cxx:8582
Long_t ExecuteMacro(const char *filename, EErrorCode *error=0)
Execute a cling macro.
Definition: TCling.cxx:5182
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:4611
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:4827
virtual void CallFunc_Exec(CallFunc_t *func, void *address) const
Definition: TCling.cxx:7670
virtual int DisplayIncludePath(FILE *fout) const
Interface to cling function.
Definition: TCling.cxx:7266
void RegisterLoadedSharedLibrary(const char *name)
Register a new shared library name with the interpreter; add it to fSharedLibs.
Definition: TCling.cxx:3258
virtual void UpdateEnumConstants(TEnum *enumObj, TClass *cl) const
Definition: TCling.cxx:425
void SaveGlobalsContext()
Save the current Cling state of global objects.
Definition: TCling.cxx:3688
std::unordered_set< const clang::NamespaceDecl * > fNSFromRootmaps
Definition: TCling.h:123
void ProcessClassesToUpdate()
Definition: TCling.cxx:1921
virtual Long_t MethodArgInfo_Property(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:9097
virtual const char * GetSTLIncludePath() const
Return the directory containing CINT's stl cintdlls.
Definition: TCling.cxx:7248
TString fRootmapLoadPath
Definition: TCling.h:114
Int_t LoadLibraryMap(const char *rootmapfile=0)
Load map between class and library.
Definition: TCling.cxx:5507
virtual std::string MethodInfo_TypeNormalizedName(MethodInfo_t *minfo) const
Definition: TCling.cxx:8967
void Execute(const char *function, const char *params, int *error=0)
Execute a global function with arguments params.
Definition: TCling.cxx:5012
virtual const char * ClassInfo_FullName(ClassInfo_t *info) const
Definition: TCling.cxx:8244
TClass * GenerateTClass(const char *classname, Bool_t emulation, Bool_t silent=kFALSE)
Generate a TClass for the given class.
Definition: TCling.cxx:4330
virtual int TypeInfo_Size(TypeInfo_t *tinfo) const
Definition: TCling.cxx:9213
virtual int MethodArgInfo_Next(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:9089
ROOT::TMetaUtils::TClingLookupHelper * fLookupHelper
Definition: TCling.h:133
virtual const char * TypedefInfo_TrueName(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:9307
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:5876
DeclId_t GetDeclId(const llvm::GlobalValue *gv) const
Return pointer to cling DeclId for a global value.
Definition: TCling.cxx:4651
Long_t ProcessLineAsynch(const char *line, EErrorCode *error=0)
Let cling process a command line asynch.
Definition: TCling.cxx:3386
virtual std::vector< std::string > GetUsingNamespaces(ClassInfo_t *cl) const
Get the scopes representing using declarations of namespace.
Definition: TCling.cxx:4262
Int_t SetClassSharedLibs(const char *cls, const char *libs)
Register the AutoLoading information for a class.
Definition: TCling.cxx:5844
virtual void ClassInfo_Init(ClassInfo_t *info, const char *funcname) const
Definition: TCling.cxx:8089
virtual TypeInfo_t * TypeInfo_FactoryCopy(TypeInfo_t *) const
Definition: TCling.cxx:9165
Bool_t CheckClassTemplate(const char *name)
Return true if there is a class template by the given name ...
Definition: TCling.cxx:4135
void LoadPCMImpl(TFile &pcmFile)
Tries to load a PCM from TFile; returns true on success.
Definition: TCling.cxx:1640
Bool_t IsAutoLoadNamespaceCandidate(const clang::NamespaceDecl *nsDecl)
Definition: TCling.cxx:6487
TObjArray * GetRootMapFiles() const
Definition: TCling.h:215
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:4300
virtual void SetDeclAttr(DeclId_t, const char *)
Definition: TCling.cxx:8545
virtual Long_t DataMemberInfo_TypeProperty(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8486
virtual void ShutDown()
Definition: TCling.cxx:1599
virtual const char * DataMemberInfo_TypeName(DataMemberInfo_t *dminfo) const
Definition: TCling.cxx:8502
virtual void CallFunc_SetArgs(CallFunc_t *func, const char *param) const
Definition: TCling.cxx:7850
virtual const char * BaseClassInfo_Name(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:8383
virtual void MethodInfo_Delete(MethodInfo_t *minfo) const
Interface to cling function.
Definition: TCling.cxx:8822
virtual const char * TypeInfo_TrueName(TypeInfo_t *tinfo) const
Definition: TCling.cxx:9221
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:3963
static void UpdateClassInfo(char *name, Long_t tagnum)
No op: see TClingCallbacks.
Definition: TCling.cxx:6596
virtual void BaseClassInfo_Delete(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:8285
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:3570
std::unique_ptr< cling::Interpreter > fInterpreter
Definition: TCling.h:128
Bool_t IsLibraryLoaded(const char *libname) const
Definition: TCling.cxx:3002
virtual void Initialize()
Initialize the interpreter, once TROOT::fInterpreter is set.
Definition: TCling.cxx:1580
virtual void * FindSym(const char *entry) const
Interface to cling function.
Definition: TCling.cxx:7295
virtual Long_t CallFunc_ExecInt(CallFunc_t *func, void *address) const
Definition: TCling.cxx:7705
virtual int DataMemberInfo_MaxIndex(DataMemberInfo_t *dminfo, Int_t dim) const
Definition: TCling.cxx:8454
void SetClassInfo(TClass *cl, Bool_t reload=kFALSE)
Set pointer to the TClingClassInfo in TClass.
Definition: TCling.cxx:3834
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:3395
virtual int TypeInfo_RefType(TypeInfo_t *) const
Definition: TCling.cxx:9205
cling::MetaProcessor * GetMetaProcessorImpl() const
Definition: TCling.h:623
void LoadMacro(const char *filename, EErrorCode *error=0)
Load a macro file in cling's memory.
Definition: TCling.cxx:3378
std::set< size_t > fLookedUpClasses
Definition: TCling.h:119
virtual void CallFunc_ResetArg(CallFunc_t *func) const
Definition: TCling.cxx:7786
virtual Long64_t CallFunc_ExecInt64(CallFunc_t *func, void *address) const
Definition: TCling.cxx:7713
virtual Long_t BaseClassInfo_Tagnum(BaseClassInfo_t *bcinfo) const
Definition: TCling.cxx:8365
void ResetAll()
Reset the Cling state to its initial state.
Definition: TCling.cxx:3540
virtual void ClassInfo_Delete(ClassInfo_t *info) const
Definition: TCling.cxx:8004
virtual Double_t CallFunc_ExecDouble(CallFunc_t *func, void *address) const
Definition: TCling.cxx:7721
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:6144
virtual const char * TypedefInfo_Title(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:9323
void CreateListOfBaseClasses(TClass *cl) const
Create list of pointers to base class(es) for TClass cl.
Definition: TCling.cxx:4155
void RecursiveRemove(TObject *obj)
Delete object from cling symbol table so it can not be used anymore.
Definition: TCling.cxx:3499
virtual MethodArgInfo_t * MethodArgInfo_FactoryCopy(MethodArgInfo_t *marginfo) const
Definition: TCling.cxx:9073
void UpdateListsOnUnloaded(const cling::Transaction &T)
Invalidate stored TCling state for declarations included in transaction ‘T’.
Definition: TCling.cxx:6706
void UpdateClassInfoWithDecl(const clang::NamedDecl *ND)
Internal function. Inform a TClass about its new TagDecl or NamespaceDecl.
Definition: TCling.cxx:6538
virtual const char * ClassInfo_FileName(ClassInfo_t *info) const
Definition: TCling.cxx:8236
virtual void CallFunc_ExecWithArgsAndReturn(CallFunc_t *func, void *address, const void *args[]=0, int nargs=0, void *ret=0) const
Definition: TCling.cxx:7694
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:4956
virtual int MethodInfo_NArg(MethodInfo_t *minfo) const
Definition: TCling.cxx:8885
virtual FuncTempInfo_t * FuncTempInfo_FactoryCopy(FuncTempInfo_t *) const
Construct a FuncTempInfo_t.
Definition: TCling.cxx:8647
void * fAutoLoadCallBack
Definition: TCling.h:145
virtual int TypedefInfo_Size(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:9299
std::unique_ptr< cling::MetaProcessor > fMetaProcessor
Definition: TCling.h:129
virtual const char * TypedefInfo_Name(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:9315
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:7885
virtual int DisplayClass(FILE *fout, const char *name, int base, int start) const
Definition: TCling.cxx:7257
const char * GetClassSharedLibs(const char *cls)
Get the list of shared libraries containing the code for class cls.
Definition: TCling.cxx:6949
Bool_t IsErrorMessagesEnabled() const
If error messages are disabled, the interpreter should suppress its failures and warning messages fro...
Definition: TCling.cxx:7189
ULong64_t fTransactionCount
Definition: TCling.h:146
virtual Bool_t FuncTempInfo_IsValid(FuncTempInfo_t *) const
Check validity of a FuncTempInfo_t.
Definition: TCling.cxx:8658
virtual BaseClassInfo_t * BaseClassInfo_Factory(ClassInfo_t *info) const
Definition: TCling.cxx:8292
virtual bool TypedefInfo_IsValid(TypedefInfo_t *tinfo) const
Definition: TCling.cxx:9275
virtual MethodInfo_t * MethodInfo_Factory() const
Definition: TCling.cxx:8837
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:6286
virtual EReturnType MethodInfo_MethodCallReturnType(MethodInfo_t *minfo) const
Definition: TCling.cxx:8997
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:4889
virtual TypeInfo_t * TypeInfo_Factory() const
Definition: TCling.cxx:9149
std::map< size_t, std::vector< const char * > > fClassesHeadersMap
Definition: TCling.h:117
virtual int MethodInfo_NDefaultArg(MethodInfo_t *minfo) const
Definition: TCling.cxx:8893
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:4503
virtual void CallFunc_SetFunc(CallFunc_t *func, ClassInfo_t *info, const char *method, const char *params, Long_t *Offset) const
Definition: TCling.cxx:7858
void CreateListOfMethods(TClass *cl) const
Create list of pointers to methods for TClass cl.
Definition: TCling.cxx:4282
void UpdateListOfMethods(TClass *cl) const
Update the list of pointers to method for TClass cl This is now a nop.
Definition: TCling.cxx:4291
void RegisterRdictForLoadPCM(const std::string &pcmFileNameFullPath, llvm::StringRef *pcmContent)
Register Rdict data for future loading by LoadPCM;.
Definition: TCling.cxx:1622
virtual int ClassInfo_Size(ClassInfo_t *info) const
Definition: TCling.cxx:8220
static void UpdateAllCanvases()
Update all canvases at end the terminal input command.
Definition: TCling.cxx:6611
void LibraryUnloaded(const void *dyLibHandle, const char *canonicalName)
Definition: TCling.cxx:6838
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:91
Basic data type descriptor (datatype information is obtained from CINT).
Definition: TDataType.h:44
Int_t GetType() const
Definition: TDataType.h:68
EMemberSelection
Kinds of members to include in lists.
Definition: TDictionary.h:214
const void * DeclId_t
Definition: TDictionary.h:222
TList * GetListOfKeys() const override
Small helper to keep current directory context.
Definition: TDirectory.h:47
void GetObject(const char *namecycle, T *&ptr)
Definition: TDirectory.h:155
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:60
static TEnum * GetEnum(const std::type_info &ti, ESearchAction sa=kALoadAndInterpLookup)
Definition: TEnum.cxx:132
DeclId_t GetDeclId() const
Definition: TEnum.cxx:103
@ kNone
Definition: TEnum.h:48
@ kAutoload
Definition: TEnum.h:49
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:53
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:61
virtual bool RegisterPrebuiltModulePath(const std::string &FullPath, const std::string &ModuleMapName="module.modulemap") const =0
virtual Bool_t HasPCMForLibrary(const char *libname) const =0
virtual Int_t AutoParse(const char *cls)=0
int(* AutoLoadCallBack_t)(const char *)
Definition: TInterpreter.h:133
virtual const char * GetClassSharedLibs(const char *cls)=0
friend class SuspendAutoParsing
Definition: TInterpreter.h:67
virtual Bool_t Declare(const char *code)=0
std::vector< std::pair< std::string, int > > FwdDeclArgsToKeepCollection_t
Definition: TInterpreter.h:134
TDictionary::DeclId_t DeclId_t
Definition: TInterpreter.h:284
virtual TObjArray * GetRootMapFiles() const =0
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:28
A collection of TDataMember objects designed for fast access given a DeclId_t and for keep track of T...
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:356
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
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:387
void Add(TObject *obj)
Definition: TObjArray.h:74
virtual void Compress()
Remove empty slots from array.
Definition: TObjArray.cxx:334
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:523
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
Definition: TObjArray.cxx:415
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:719
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:187
R__ALWAYS_INLINE Bool_t IsOnHeap() const
Definition: TObject.h:148
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:877
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:891
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:919
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:186
@ 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:865
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:2929
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition: TROOT.cxx:2693
virtual ~TROOT()
Clean up and free resources used by ROOT (files, network sockets, shared memory segments,...
Definition: TROOT.cxx:856
static const std::vector< std::string > & AddExtraInterpreterArgs(const std::vector< std::string > &args)
Provide command line arguments to the interpreter construction.
Definition: TROOT.cxx:2850
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition: TROOT.cxx:2939
static const char **& GetExtraInterpreterArgs()
INTERNAL function! Used by rootcling to inject interpreter arguments through a C-interface layer.
Definition: TROOT.cxx:2860
static const TString & GetLibDir()
Get the library directory in the installation. Static utility function.
Definition: TROOT.cxx:2908
Int_t LastIndex() const
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:46
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 void FreeDirectory(void *dirp)
Free a directory.
Definition: TSystem.cxx:841
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition: TSystem.cxx:832
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1658
virtual const char * GetIncludePath()
Get the list of include path.
Definition: TSystem.cxx:3941
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition: TSystem.cxx:4220
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition: TSystem.cxx:1066
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1531
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1850
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:1393
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition: TSystem.cxx:1076
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:1291
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition: TSystem.cxx:849
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition: TSystem.cxx:2490
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:930
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition: TSystem.cxx:1788
virtual const char * FindDynamicLibrary(TString &lib, Bool_t quiet=kFALSE)
Find a dynamic library using the system search paths.
Definition: TSystem.cxx:2027
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition: TSystem.cxx:435
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:2831
virtual const char * WorkingDirectory()
Return working directory.
Definition: TSystem.cxx:867
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1541
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition: TSystem.cxx:1642
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition: TSystem.cxx:883
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:1027
virtual void StackTrace()
Print a stack trace.
Definition: TSystem.cxx:730
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
Definition: TSystem.cxx:2013
virtual Int_t UnLock()=0
virtual Int_t Lock()=0
virtual TVirtualMutex * Factory(Bool_t=kFALSE)=0
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:51
virtual void Update()=0
static void SetFactory(TVirtualStreamerInfo *factory)
static function: Set the StreamerInfo factory
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)
RPY_EXPORTED TCppMethod_t GetMethod(TCppScope_t scope, TCppIndex_t imeth)
const std::string & GetPathSeparator()
const char & GetEnvPathSeparator()
R__EXTERN TROOT * gROOTLocal
Definition: TROOT.h:379
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
static const std::string transient("transient")
static const std::string ioname("ioname")
const T * GetAnnotatedRedeclarable(const T *Redecl)
Definition: TClingUtils.h:638
int GetClassVersion(const clang::RecordDecl *cl, const cling::Interpreter &interp)
Return the version number of the class or -1 if the function Class_Version does not exist.
void GetNormalizedName(std::string &norm_name, const clang::QualType &type, const cling::Interpreter &interpreter, const TNormalizedCtxt &normCtxt)
Return the type name normalized for ROOT, keeping only the ROOT opaque typedef (Double32_t,...
std::string GetModuleFileName(const char *moduleName)
Return the dictionary file name for a module.
clang::QualType ReSubstTemplateArg(clang::QualType input, const clang::Type *instance)
Check if 'input' or any of its template parameter was substituted when instantiating the class templa...
void GetCppName(std::string &output, const char *input)
Return (in the argument 'output') a mangled version of the C++ symbol/type (pass as 'input') that can...
std::pair< bool, int > GetTrivialIntegralReturnValue(const clang::FunctionDecl *funcCV, const cling::Interpreter &interp)
If the function contains 'just': return SomeValue; this routine will extract this value and return it...
std::string GetRealPath(const std::string &path)
Definition: TClingUtils.cxx:73
void GetQualifiedName(std::string &qual_name, const clang::QualType &type, const clang::NamedDecl &forcontext)
Main implementation relying on GetFullyQualifiedTypeName All other GetQualifiedName functions leverag...
void SetPathsForRelocatability(std::vector< std::string > &clingArgs)
Organise the parameters for cling in order to guarantee relocatability It treats the gcc toolchain an...
void ReplaceAll(std::string &str, const std::string &from, const std::string &to, bool recurse=false)
const clang::Type * GetUnderlyingType(clang::QualType type)
Return the base/underlying type of a chain of array or pointers type.
ROOT::ESTLType IsSTLCont(const clang::RecordDecl &cl)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container abs(result):...
bool ExtractAttrPropertyFromName(const clang::Decl &decl, const std::string &propName, std::string &propValue)
This routine counts on the "propName<separator>propValue" format.
llvm::StringRef GetComment(const clang::Decl &decl, clang::SourceLocation *loc=0)
Returns the comment (// striped away), annotating declaration in a meaningful for ROOT IO way.
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:939
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Definition: StringConv.hxx:21
R__EXTERN TVirtualRWMutex * gCoreMutex
EFunctionMatchMode
Definition: TDictionary.h:159
@ kExactMatch
Definition: TDictionary.h:160
V GetOffset(E val1, E val2, V iso)
RooArgSet S(const RooAbsArg &v1)
bool IsStdPairBase(std::string_view name)
Definition: TClassEdit.h:195
bool IsStdArray(std::string_view name)
Definition: TClassEdit.h:188
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
bool IsStdPair(std::string_view name)
Definition: TClassEdit.h:190
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:887
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:921
void Init(TClassEdit::TInterpreterLookupHelper *helper)
Definition: TClassEdit.cxx:154
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:217
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.
@ kDropTrailStar
Definition: TClassEdit.h:76
@ kDropStlDefault
Definition: TClassEdit.h:81
EComplexType GetComplexType(const char *)
Definition: TClassEdit.cxx:120
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
static const char * what
Definition: stlLoader.cc:6
Int_t fMode
Definition: TSystem.h:126
Long_t fMemVirtual
Definition: TSystem.h:195
Long_t fMemResident
Definition: TSystem.h:194
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:243
std::string fScopeName
Name of the scope qualification of the function, possibly empty.
Definition: TClassEdit.h:248
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:233
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